diff options
Diffstat (limited to 'include/clang/AST')
-rw-r--r-- | include/clang/AST/CanonicalType.h | 70 | ||||
-rw-r--r-- | include/clang/AST/DeclBase.h | 267 | ||||
-rw-r--r-- | include/clang/AST/ExternalASTSource.h | 103 | ||||
-rw-r--r-- | include/clang/AST/PrettyPrinter.h | 76 | ||||
-rw-r--r-- | include/clang/AST/QualTypeNames.h | 90 |
5 files changed, 391 insertions, 215 deletions
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h index 023456e2e3..6487613200 100644 --- a/include/clang/AST/CanonicalType.h +++ b/include/clang/AST/CanonicalType.h @@ -1,4 +1,4 @@ -//===-- CanonicalType.h - C Language Family Type Representation -*- C++ -*-===// +//===- CanonicalType.h - C Language Family Type Representation --*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -16,13 +16,29 @@ #define LLVM_CLANG_AST_CANONICALTYPE_H #include "clang/AST/Type.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/iterator.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/PointerLikeTypeTraits.h" +#include <cassert> +#include <iterator> +#include <type_traits> namespace clang { template<typename T> class CanProxy; template<typename T> struct CanProxyAdaptor; +class CXXRecordDecl; +class EnumDecl; +class Expr; +class IdentifierInfo; +class ObjCInterfaceDecl; +class RecordDecl; +class TagDecl; +class TemplateTypeParmDecl; //----------------------------------------------------------------------------// // Canonical, qualified type template @@ -46,8 +62,6 @@ template<typename T> struct CanProxyAdaptor; /// converted to @c CanQual<ReferenceType>. Note that any @c CanQual type can /// be implicitly converted to a QualType, but the reverse operation requires /// a call to ASTContext::getCanonicalType(). -/// -/// template<typename T = Type> class CanQual { /// \brief The actual, canonical type. @@ -55,7 +69,7 @@ class CanQual { public: /// \brief Constructs a NULL canonical type. - CanQual() : Stored() { } + CanQual() = default; /// \brief Converting constructor that permits implicit upcasting of /// canonical type pointers. @@ -66,12 +80,11 @@ public: /// \brief Retrieve the underlying type pointer, which refers to a /// canonical type. /// - /// The underlying pointer must not be NULL. + /// The underlying pointer must not be nullptr. const T *getTypePtr() const { return cast<T>(Stored.getTypePtr()); } /// \brief Retrieve the underlying type pointer, which refers to a - /// canonical type, or NULL. - /// + /// canonical type, or nullptr. const T *getTypePtrOrNull() const { return cast_or_null<T>(Stored.getTypePtrOrNull()); } @@ -125,9 +138,11 @@ public: bool isConstQualified() const { return Stored.isLocalConstQualified(); } + bool isVolatileQualified() const { return Stored.isLocalVolatileQualified(); } + bool isRestrictQualified() const { return Stored.isLocalRestrictQualified(); } @@ -195,7 +210,7 @@ inline bool operator!=(CanQual<T> x, CanQual<U> y) { } /// \brief Represents a canonical, potentially-qualified type. -typedef CanQual<Type> CanQualType; +using CanQualType = CanQual<Type>; inline CanQualType Type::getCanonicalTypeUnqualified() const { return CanQualType::CreateUnsafe(getCanonicalTypeInternal()); @@ -320,7 +335,7 @@ public: /// than the more typical @c QualType, to propagate the notion of "canonical" /// through the system. template<typename T> -struct CanProxyAdaptor : CanProxyBase<T> { }; +struct CanProxyAdaptor : CanProxyBase<T> {}; /// \brief Canonical proxy type returned when retrieving the members of a /// canonical type or as the result of the @c CanQual<T>::getAs member @@ -333,7 +348,7 @@ template<typename T> class CanProxy : public CanProxyAdaptor<T> { public: /// \brief Build a NULL proxy. - CanProxy() { } + CanProxy() = default; /// \brief Build a proxy to the given canonical type. CanProxy(CanQual<T> Stored) { this->Stored = Stored; } @@ -342,7 +357,7 @@ public: operator CanQual<T>() const { return this->Stored; } }; -} // end namespace clang +} // namespace clang namespace llvm { @@ -350,8 +365,9 @@ namespace llvm { /// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc. /// to return smart pointer (proxies?). template<typename T> -struct simplify_type< ::clang::CanQual<T> > { - typedef const T *SimpleType; +struct simplify_type< ::clang::CanQual<T>> { + using SimpleType = const T *; + static SimpleType getSimplifiedValue(::clang::CanQual<T> Val) { return Val.getTypePtr(); } @@ -359,18 +375,20 @@ struct simplify_type< ::clang::CanQual<T> > { // Teach SmallPtrSet that CanQual<T> is "basically a pointer". template<typename T> -struct PointerLikeTypeTraits<clang::CanQual<T> > { - static inline void *getAsVoidPointer(clang::CanQual<T> P) { +struct PointerLikeTypeTraits<clang::CanQual<T>> { + static void *getAsVoidPointer(clang::CanQual<T> P) { return P.getAsOpaquePtr(); } - static inline clang::CanQual<T> getFromVoidPointer(void *P) { + + static clang::CanQual<T> getFromVoidPointer(void *P) { return clang::CanQual<T>::getFromOpaquePtr(P); } + // qualifier information is encoded in the low bits. enum { NumLowBitsAvailable = 0 }; }; -} // end namespace llvm +} // namespace llvm namespace clang { @@ -388,7 +406,7 @@ struct CanTypeIterator CanQualType, typename std::iterator_traits<InputIterator>::difference_type, CanProxy<Type>, CanQualType> { - CanTypeIterator() {} + CanTypeIterator() = default; explicit CanTypeIterator(InputIterator Iter) : CanTypeIterator::iterator_adaptor_base(std::move(Iter)) {} @@ -486,6 +504,7 @@ struct CanProxyAdaptor<FunctionProtoType> LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasExtParameterInfos) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR( ArrayRef<FunctionProtoType::ExtParameterInfo>, getExtParameterInfos) + CanQualType getParamType(unsigned i) const { return CanQualType::CreateUnsafe(this->getTypePtr()->getParamType(i)); } @@ -493,8 +512,8 @@ struct CanProxyAdaptor<FunctionProtoType> LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals) - typedef CanTypeIterator<FunctionProtoType::param_type_iterator> - param_type_iterator; + using param_type_iterator = + CanTypeIterator<FunctionProtoType::param_type_iterator>; param_type_iterator param_type_begin() const { return param_type_iterator(this->getTypePtr()->param_type_begin()); @@ -566,7 +585,8 @@ struct CanProxyAdaptor<ObjCObjectType> LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass) - typedef ObjCObjectPointerType::qual_iterator qual_iterator; + using qual_iterator = ObjCObjectPointerType::qual_iterator; + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty) @@ -584,7 +604,8 @@ struct CanProxyAdaptor<ObjCObjectPointerType> LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType) - typedef ObjCObjectPointerType::qual_iterator qual_iterator; + using qual_iterator = ObjCObjectPointerType::qual_iterator; + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty) @@ -661,7 +682,6 @@ CanProxy<Type> CanTypeIterator<InputIterator>::operator->() const { return CanProxy<Type>(*this); } -} - +} // namespace clang -#endif +#endif // LLVM_CLANG_AST_CANONICALTYPE_H diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 47515a848a..f93c9f0b9a 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -1,4 +1,4 @@ -//===-- DeclBase.h - Base Classes for representing declarations -*- C++ -*-===// +//===- DeclBase.h - Base Classes for representing declarations --*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -16,33 +16,40 @@ #include "clang/AST/AttrIterator.h" #include "clang/AST/DeclarationName.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" #include "clang/Basic/VersionTuple.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator_range.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/PrettyStackTrace.h" +#include <algorithm> +#include <cassert> +#include <cstddef> +#include <iterator> +#include <string> +#include <type_traits> +#include <utility> namespace clang { + +class ASTContext; class ASTMutationListener; -class BlockDecl; -class CXXRecordDecl; -class CompoundStmt; +class Attr; class DeclContext; -class DeclarationName; -class DependentDiagnostic; -class EnumDecl; -class ExportDecl; class ExternalSourceSymbolAttr; class FunctionDecl; class FunctionType; +class IdentifierInfo; enum Linkage : unsigned char; -class LinkageComputer; class LinkageSpecDecl; class Module; class NamedDecl; -class NamespaceDecl; class ObjCCategoryDecl; class ObjCCategoryImplDecl; class ObjCContainerDecl; @@ -53,23 +60,21 @@ class ObjCMethodDecl; class ObjCProtocolDecl; struct PrintingPolicy; class RecordDecl; +class SourceManager; class Stmt; class StoredDeclsMap; class TemplateDecl; class TranslationUnitDecl; class UsingDirectiveDecl; -} -namespace clang { - - /// \brief Captures the result of checking the availability of a - /// declaration. - enum AvailabilityResult { - AR_Available = 0, - AR_NotYetIntroduced, - AR_Deprecated, - AR_Unavailable - }; +/// \brief Captures the result of checking the availability of a +/// declaration. +enum AvailabilityResult { + AR_Available = 0, + AR_NotYetIntroduced, + AR_Deprecated, + AR_Unavailable +}; /// Decl - This represents one declaration (or definition), e.g. a variable, /// typedef, function, struct, etc. @@ -94,7 +99,7 @@ public: /// \brief A placeholder type used to construct an empty shell of a /// decl-derived type that will be filled in later (e.g., by some /// deserialization method). - struct EmptyShell { }; + struct EmptyShell {}; /// IdentifierNamespace - The different namespaces in which /// declarations may appear. According to C99 6.2.3, there are @@ -208,15 +213,18 @@ public: enum class ModuleOwnershipKind : unsigned { /// This declaration is not owned by a module. Unowned, + /// This declaration has an owning module, but is globally visible /// (typically because its owning module is visible and we know that /// modules cannot later become hidden in this compilation). /// After serialization and deserialization, this will be converted /// to VisibleWhenImported. Visible, + /// This declaration has an owning module, and is visible when that /// module is imported. VisibleWhenImported, + /// This declaration has an owning module, but is only visible to /// lookups that occur within that module. ModulePrivate @@ -238,7 +246,6 @@ private: DeclContext *LexicalDC; }; - /// DeclCtx - Holds either a DeclContext* or a MultipleDC*. /// For declarations that don't contain C++ scope specifiers, it contains /// the DeclContext where the Decl was declared. @@ -254,12 +261,14 @@ private: /// // LexicalDC == global namespace llvm::PointerUnion<DeclContext*, MultipleDC*> DeclCtx; - inline bool isInSemaDC() const { return DeclCtx.is<DeclContext*>(); } - inline bool isOutOfSemaDC() const { return DeclCtx.is<MultipleDC*>(); } - inline MultipleDC *getMultipleDC() const { + bool isInSemaDC() const { return DeclCtx.is<DeclContext*>(); } + bool isOutOfSemaDC() const { return DeclCtx.is<MultipleDC*>(); } + + MultipleDC *getMultipleDC() const { return DeclCtx.get<MultipleDC*>(); } - inline DeclContext *getSemanticDC() const { + + DeclContext *getSemanticDC() const { return DeclCtx.get<DeclContext*>(); } @@ -298,10 +307,16 @@ private: static bool StatisticsEnabled; protected: + friend class ASTDeclReader; + friend class ASTDeclWriter; + friend class ASTReader; + friend class CXXClassMemberWrapper; + friend class LinkageComputer; + template<typename decl_type> friend class Redeclarable; + /// Access - Used by C++ decls for the access specifier. // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum unsigned Access : 2; - friend class CXXClassMemberWrapper; /// \brief Whether this declaration was loaded from an AST file. unsigned FromASTFile : 1; @@ -313,13 +328,6 @@ protected: /// Otherwise, it is the linkage + 1. mutable unsigned CacheValidAndLinkage : 3; - friend class ASTDeclWriter; - friend class ASTDeclReader; - friend class ASTReader; - friend class LinkageComputer; - - template<typename decl_type> friend class Redeclarable; - /// \brief Allocate memory for a deserialized declaration. /// /// This routine must be used to allocate memory for any declaration that is @@ -357,7 +365,7 @@ private: protected: Decl(Kind DK, DeclContext *DC, SourceLocation L) : NextInContextAndBits(nullptr, getModuleOwnershipKindForChildOf(DC)), - DeclCtx(DC), Loc(L), DeclKind(DK), InvalidDecl(0), HasAttrs(false), + DeclCtx(DC), Loc(L), DeclKind(DK), InvalidDecl(false), HasAttrs(false), Implicit(false), Used(false), Referenced(false), TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0), IdentifierNamespace(getIdentifierNamespaceForKind(DK)), @@ -366,9 +374,9 @@ protected: } Decl(Kind DK, EmptyShell Empty) - : NextInContextAndBits(), DeclKind(DK), InvalidDecl(0), HasAttrs(false), - Implicit(false), Used(false), Referenced(false), - TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0), + : DeclKind(DK), InvalidDecl(false), HasAttrs(false), Implicit(false), + Used(false), Referenced(false), TopLevelDeclInObjCContainer(false), + Access(AS_none), FromASTFile(0), IdentifierNamespace(getIdentifierNamespaceForKind(DK)), CacheValidAndLinkage(0) { if (StatisticsEnabled) add(DK); @@ -392,14 +400,15 @@ protected: } public: - /// \brief Source range that this declaration covers. virtual SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(getLocation(), getLocation()); } + SourceLocation getLocStart() const LLVM_READONLY { return getSourceRange().getBegin(); } + SourceLocation getLocEnd() const LLVM_READONLY { return getSourceRange().getEnd(); } @@ -460,12 +469,15 @@ public: } bool hasAttrs() const { return HasAttrs; } + void setAttrs(const AttrVec& Attrs) { return setAttrsImpl(Attrs, getASTContext()); } + AttrVec &getAttrs() { return const_cast<AttrVec&>(const_cast<const Decl*>(this)->getAttrs()); } + const AttrVec &getAttrs() const; void dropAttrs(); @@ -476,8 +488,8 @@ public: setAttrs(AttrVec(1, A)); } - typedef AttrVec::const_iterator attr_iterator; - typedef llvm::iterator_range<attr_iterator> attr_range; + using attr_iterator = AttrVec::const_iterator; + using attr_range = llvm::iterator_range<attr_iterator>; attr_range attrs() const { return attr_range(attr_begin(), attr_end()); @@ -510,6 +522,7 @@ public: specific_attr_iterator<T> specific_attr_begin() const { return specific_attr_iterator<T>(attr_begin()); } + template <typename T> specific_attr_iterator<T> specific_attr_end() const { return specific_attr_iterator<T>(attr_end()); @@ -518,6 +531,7 @@ public: template<typename T> T *getAttr() const { return hasAttrs() ? getSpecificAttr<T>(getAttrs()) : nullptr; } + template<typename T> bool hasAttr() const { return hasAttrs() && hasSpecificAttr<T>(getAttrs()); } @@ -616,7 +630,6 @@ protected: } public: - /// \brief Determine the availability of the given declaration. /// /// This routine will determine the most restrictive availability of @@ -698,6 +711,7 @@ public: private: Module *getOwningModuleSlow() const; + protected: bool hasLocalOwningModuleStorage() const; @@ -777,14 +791,17 @@ public: unsigned getIdentifierNamespace() const { return IdentifierNamespace; } + bool isInIdentifierNamespace(unsigned NS) const { return getIdentifierNamespace() & NS; } + static unsigned getIdentifierNamespaceForKind(Kind DK); bool hasTagIdentifierNamespace() const { return isTagIdentifierNamespace(getIdentifierNamespace()); } + static bool isTagIdentifierNamespace(unsigned NS) { // TagDecls have Tag and Type set and may also have TagFriend. return (NS & ~IDNS_TagFriend) == (IDNS_Tag | IDNS_Type); @@ -872,18 +889,18 @@ public: /// \brief Iterates through all the redeclarations of the same decl. class redecl_iterator { /// Current - The current declaration. - Decl *Current; + Decl *Current = nullptr; Decl *Starter; public: - typedef Decl *value_type; - typedef const value_type &reference; - typedef const value_type *pointer; - typedef std::forward_iterator_tag iterator_category; - typedef std::ptrdiff_t difference_type; + using value_type = Decl *; + using reference = const value_type &; + using pointer = const value_type *; + using iterator_category = std::forward_iterator_tag; + using difference_type = std::ptrdiff_t; - redecl_iterator() : Current(nullptr) { } - explicit redecl_iterator(Decl *C) : Current(C), Starter(C) { } + redecl_iterator() = default; + explicit redecl_iterator(Decl *C) : Current(C), Starter(C) {} reference operator*() const { return Current; } value_type operator->() const { return Current; } @@ -906,12 +923,13 @@ public: friend bool operator==(redecl_iterator x, redecl_iterator y) { return x.Current == y.Current; } + friend bool operator!=(redecl_iterator x, redecl_iterator y) { return x.Current != y.Current; } }; - typedef llvm::iterator_range<redecl_iterator> redecl_range; + using redecl_range = llvm::iterator_range<redecl_iterator>; /// \brief Returns an iterator range for all the redeclarations of the same /// decl. It will iterate at least once (when this decl is the only one). @@ -922,6 +940,7 @@ public: redecl_iterator redecls_begin() const { return redecl_iterator(const_cast<Decl *>(this)); } + redecl_iterator redecls_end() const { return redecl_iterator(); } /// \brief Retrieve the previous declaration that declares the same entity @@ -1103,10 +1122,13 @@ public: static void printGroup(Decl** Begin, unsigned NumDecls, raw_ostream &Out, const PrintingPolicy &Policy, unsigned Indentation = 0); + // Debuggers don't usually respect default arguments. void dump() const; + // Same as dump(), but forces color printing. void dumpColor() const; + void dump(raw_ostream &Out, bool Deserialize = false) const; /// \brief Looks through the Decl's underlying type to extract a FunctionType @@ -1141,10 +1163,11 @@ class PrettyStackTraceDecl : public llvm::PrettyStackTraceEntry { SourceLocation Loc; SourceManager &SM; const char *Message; + public: PrettyStackTraceDecl(const Decl *theDecl, SourceLocation L, SourceManager &sm, const char *Msg) - : TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {} + : TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {} void print(raw_ostream &OS) const override; }; @@ -1153,30 +1176,35 @@ public: /// single result (with no stable storage) or a collection of results (with /// stable storage provided by the lookup table). class DeclContextLookupResult { - typedef ArrayRef<NamedDecl *> ResultTy; + using ResultTy = ArrayRef<NamedDecl *>; + ResultTy Result; + // If there is only one lookup result, it would be invalidated by // reallocations of the name table, so store it separately. - NamedDecl *Single; + NamedDecl *Single = nullptr; static NamedDecl *const SingleElementDummyList; public: - DeclContextLookupResult() : Result(), Single() {} + DeclContextLookupResult() = default; DeclContextLookupResult(ArrayRef<NamedDecl *> Result) - : Result(Result), Single() {} + : Result(Result) {} DeclContextLookupResult(NamedDecl *Single) : Result(SingleElementDummyList), Single(Single) {} class iterator; - typedef llvm::iterator_adaptor_base<iterator, ResultTy::iterator, - std::random_access_iterator_tag, - NamedDecl *const> IteratorBase; + + using IteratorBase = + llvm::iterator_adaptor_base<iterator, ResultTy::iterator, + std::random_access_iterator_tag, + NamedDecl *const>; + class iterator : public IteratorBase { value_type SingleElement; public: - iterator() : IteratorBase(), SingleElement() {} + iterator() = default; explicit iterator(pointer Pos, value_type Single = nullptr) : IteratorBase(Pos), SingleElement(Single) {} @@ -1184,9 +1212,10 @@ public: return SingleElement ? SingleElement : IteratorBase::operator*(); } }; - typedef iterator const_iterator; - typedef iterator::pointer pointer; - typedef iterator::reference reference; + + using const_iterator = iterator; + using pointer = iterator::pointer; + using reference = iterator::reference; iterator begin() const { return iterator(Result.begin(), Single); } iterator end() const { return iterator(Result.end(), Single); } @@ -1220,7 +1249,6 @@ public: /// ExportDecl /// BlockDecl /// OMPDeclareReductionDecl -/// class DeclContext { /// DeclKind - This indicates which class this is. unsigned DeclKind : 8; @@ -1260,22 +1288,22 @@ class DeclContext { /// contains an entry for a DeclarationName (and we haven't lazily /// omitted anything), then it contains all relevant entries for that /// name (modulo the hasExternalDecls() flag). - mutable StoredDeclsMap *LookupPtr; + mutable StoredDeclsMap *LookupPtr = nullptr; protected: + friend class ASTDeclReader; + friend class ASTWriter; + friend class ExternalASTSource; + /// FirstDecl - The first declaration stored within this declaration /// context. - mutable Decl *FirstDecl; + mutable Decl *FirstDecl = nullptr; /// LastDecl - The last declaration stored within this declaration /// context. FIXME: We could probably cache this value somewhere /// outside of the DeclContext, to reduce the size of DeclContext by /// another pointer. - mutable Decl *LastDecl; - - friend class ExternalASTSource; - friend class ASTDeclReader; - friend class ASTWriter; + mutable Decl *LastDecl = nullptr; /// \brief Build up a chain of declarations. /// @@ -1288,8 +1316,7 @@ protected: ExternalVisibleStorage(false), NeedToReconcileExternalVisibleStorage(false), HasLazyLocalLexicalLookups(false), HasLazyExternalLexicalLookups(false), - UseQualifiedLookup(false), - LookupPtr(nullptr), FirstDecl(nullptr), LastDecl(nullptr) {} + UseQualifiedLookup(false) {} public: ~DeclContext(); @@ -1297,6 +1324,7 @@ public: Decl::Kind getDeclKind() const { return static_cast<Decl::Kind>(DeclKind); } + const char *getDeclKindName() const; /// getParent - Returns the containing DeclContext. @@ -1504,19 +1532,20 @@ public: /// within this context. class decl_iterator { /// Current - The current declaration. - Decl *Current; + Decl *Current = nullptr; public: - typedef Decl *value_type; - typedef const value_type &reference; - typedef const value_type *pointer; - typedef std::forward_iterator_tag iterator_category; - typedef std::ptrdiff_t difference_type; + using value_type = Decl *; + using reference = const value_type &; + using pointer = const value_type *; + using iterator_category = std::forward_iterator_tag; + using difference_type = std::ptrdiff_t; - decl_iterator() : Current(nullptr) { } - explicit decl_iterator(Decl *C) : Current(C) { } + decl_iterator() = default; + explicit decl_iterator(Decl *C) : Current(C) {} reference operator*() const { return Current; } + // This doesn't meet the iterator requirements, but it's convenient value_type operator->() const { return Current; } @@ -1534,12 +1563,13 @@ public: friend bool operator==(decl_iterator x, decl_iterator y) { return x.Current == y.Current; } + friend bool operator!=(decl_iterator x, decl_iterator y) { return x.Current != y.Current; } }; - typedef llvm::iterator_range<decl_iterator> decl_range; + using decl_range = llvm::iterator_range<decl_iterator>; /// decls_begin/decls_end - Iterate over the declarations stored in /// this context. @@ -1578,16 +1608,16 @@ public: } public: - typedef SpecificDecl *value_type; - // TODO: Add reference and pointer typedefs (with some appropriate proxy - // type) if we ever have a need for them. - typedef void reference; - typedef void pointer; - typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type - difference_type; - typedef std::forward_iterator_tag iterator_category; + using value_type = SpecificDecl *; + // TODO: Add reference and pointer types (with some appropriate proxy type) + // if we ever have a need for them. + using reference = void; + using pointer = void; + using difference_type = + std::iterator_traits<DeclContext::decl_iterator>::difference_type; + using iterator_category = std::forward_iterator_tag; - specific_decl_iterator() : Current() { } + specific_decl_iterator() = default; /// specific_decl_iterator - Construct a new iterator over a /// subset of the declarations the range [C, @@ -1602,6 +1632,7 @@ public: } value_type operator*() const { return cast<SpecificDecl>(*Current); } + // This doesn't meet the iterator requirements, but it's convenient value_type operator->() const { return **this; } @@ -1655,16 +1686,16 @@ public: } public: - typedef SpecificDecl *value_type; - // TODO: Add reference and pointer typedefs (with some appropriate proxy - // type) if we ever have a need for them. - typedef void reference; - typedef void pointer; - typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type - difference_type; - typedef std::forward_iterator_tag iterator_category; + using value_type = SpecificDecl *; + // TODO: Add reference and pointer types (with some appropriate proxy type) + // if we ever have a need for them. + using reference = void; + using pointer = void; + using difference_type = + std::iterator_traits<DeclContext::decl_iterator>::difference_type; + using iterator_category = std::forward_iterator_tag; - filtered_decl_iterator() : Current() { } + filtered_decl_iterator() = default; /// filtered_decl_iterator - Construct a new iterator over a /// subset of the declarations the range [C, @@ -1742,8 +1773,8 @@ public: /// @brief Checks whether a declaration is in this context. bool containsDecl(Decl *D) const; - typedef DeclContextLookupResult lookup_result; - typedef lookup_result::iterator lookup_iterator; + using lookup_result = DeclContextLookupResult; + using lookup_iterator = lookup_result::iterator; /// lookup - Find the declarations (if any) with the given Name in /// this context. Returns a range of iterators that contains all of @@ -1789,7 +1820,7 @@ public: /// of looking up every possible name. class all_lookups_iterator; - typedef llvm::iterator_range<all_lookups_iterator> lookups_range; + using lookups_range = llvm::iterator_range<all_lookups_iterator>; lookups_range lookups() const; lookups_range noload_lookups() const; @@ -1805,21 +1836,26 @@ public: all_lookups_iterator noload_lookups_end() const; struct udir_iterator; - typedef llvm::iterator_adaptor_base<udir_iterator, lookup_iterator, - std::random_access_iterator_tag, - UsingDirectiveDecl *> udir_iterator_base; + + using udir_iterator_base = + llvm::iterator_adaptor_base<udir_iterator, lookup_iterator, + std::random_access_iterator_tag, + UsingDirectiveDecl *>; + struct udir_iterator : udir_iterator_base { udir_iterator(lookup_iterator I) : udir_iterator_base(I) {} + UsingDirectiveDecl *operator*() const; }; - typedef llvm::iterator_range<udir_iterator> udir_range; + using udir_range = llvm::iterator_range<udir_iterator>; udir_range using_directives() const; // These are all defined in DependentDiagnostic.h. class ddiag_iterator; - typedef llvm::iterator_range<DeclContext::ddiag_iterator> ddiag_range; + + using ddiag_range = llvm::iterator_range<DeclContext::ddiag_iterator>; inline ddiag_range ddiags() const; @@ -1892,6 +1928,8 @@ public: bool Deserialize = false) const; private: + friend class DependentDiagnostic; + void reconcileExternalVisibleStorage() const; bool LoadLexicalDeclsFromExternalStorage() const; @@ -1903,7 +1941,6 @@ private: /// use of addDeclInternal(). void makeDeclVisibleInContextInternal(NamedDecl *D); - friend class DependentDiagnostic; StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const; void buildLookupImpl(DeclContext *DCtx, bool Internal); @@ -1942,8 +1979,7 @@ struct cast_convert_decl_context<ToTy, true> { } }; - -} // end clang. +} // namespace clang namespace llvm { @@ -1963,12 +1999,14 @@ struct cast_convert_val<ToTy, return *::clang::cast_convert_decl_context<ToTy>::doit(&Val); } }; + template<class ToTy> struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext> { static ToTy &doit(::clang::DeclContext &Val) { return *::clang::cast_convert_decl_context<ToTy>::doit(&Val); } }; + template<class ToTy> struct cast_convert_val<ToTy, const ::clang::DeclContext*, const ::clang::DeclContext*> { @@ -1976,6 +2014,7 @@ struct cast_convert_val<ToTy, return ::clang::cast_convert_decl_context<ToTy>::doit(Val); } }; + template<class ToTy> struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*> { static ToTy *doit(::clang::DeclContext *Val) { @@ -2012,6 +2051,6 @@ struct cast_convert_val< const ::clang::DeclContext, FromTy*, FromTy*> { } }; -} // end namespace llvm +} // namespace llvm -#endif +#endif // LLVM_CLANG_AST_DECLBASE_H diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h index d8dd18ecb8..be013c5d6b 100644 --- a/include/clang/AST/ExternalASTSource.h +++ b/include/clang/AST/ExternalASTSource.h @@ -1,4 +1,4 @@ -//===--- ExternalASTSource.h - Abstract External AST Interface --*- C++ -*-===// +//===- ExternalASTSource.h - Abstract External AST Interface ----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -11,24 +11,44 @@ // construction of AST nodes from some external source. // //===----------------------------------------------------------------------===// + #ifndef LLVM_CLANG_AST_EXTERNALASTSOURCE_H #define LLVM_CLANG_AST_EXTERNALASTSOURCE_H #include "clang/AST/CharUnits.h" #include "clang/AST/DeclBase.h" +#include "clang/Basic/LLVM.h" #include "clang/Basic/Module.h" +#include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/PointerUnion.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator.h" +#include "llvm/Support/PointerLikeTypeTraits.h" +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <iterator> +#include <string> +#include <utility> namespace clang { class ASTConsumer; +class ASTContext; class CXXBaseSpecifier; class CXXCtorInitializer; +class CXXRecordDecl; class DeclarationName; -class ExternalSemaSource; // layering violation required for downcasting class FieldDecl; -class Module; +class IdentifierInfo; class NamedDecl; +class ObjCInterfaceDecl; class RecordDecl; class Selector; class Stmt; @@ -42,30 +62,31 @@ class TagDecl; /// actual type and declaration nodes, and read parts of declaration /// contexts. class ExternalASTSource : public RefCountedBase<ExternalASTSource> { + friend class ExternalSemaSource; + /// Generation number for this external AST source. Must be increased /// whenever we might have added new redeclarations for existing decls. - uint32_t CurrentGeneration; + uint32_t CurrentGeneration = 0; /// \brief Whether this AST source also provides information for /// semantic analysis. - bool SemaSource; - - friend class ExternalSemaSource; + bool SemaSource = false; public: - ExternalASTSource() : CurrentGeneration(0), SemaSource(false) { } - + ExternalASTSource() = default; virtual ~ExternalASTSource(); /// \brief RAII class for safely pairing a StartedDeserializing call /// with FinishedDeserializing. class Deserializing { ExternalASTSource *Source; + public: explicit Deserializing(ExternalASTSource *source) : Source(source) { assert(Source); Source->StartedDeserializing(); } + ~Deserializing() { Source->FinishedDeserializing(); } @@ -122,7 +143,7 @@ public: virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset); /// \brief Update an out-of-date identifier. - virtual void updateOutOfDateIdentifier(IdentifierInfo &II) { } + virtual void updateOutOfDateIdentifier(IdentifierInfo &II) {} /// \brief Find all declarations with the given name in the given context, /// and add them to the context by calling SetExternalVisibleDeclsForName @@ -154,12 +175,13 @@ public: const Module *ClangModule = nullptr; public: - ASTSourceDescriptor(){}; + ASTSourceDescriptor() = default; ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile, ASTFileSignature Signature) : PCHModuleName(std::move(Name)), Path(std::move(Path)), - ASTFile(std::move(ASTFile)), Signature(Signature){}; + ASTFile(std::move(ASTFile)), Signature(Signature) {} ASTSourceDescriptor(const Module &M); + std::string getModuleName() const; StringRef getPath() const { return Path; } StringRef getASTFile() const { return ASTFile; } @@ -246,7 +268,6 @@ public: /// The default implementation of this method is a no-op. virtual void PrintStats(); - /// \brief Perform layout on the given record. /// /// This routine allows the external AST source to provide an specific @@ -289,7 +310,7 @@ public: size_t mmap_bytes; MemoryBufferSizes(size_t malloc_bytes, size_t mmap_bytes) - : malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {} + : malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {} }; /// Return the amount of memory used by memory buffers, breaking down @@ -329,12 +350,12 @@ struct LazyOffsetPtr { /// /// If the low bit is clear, a pointer to the AST node. If the low /// bit is set, the upper 63 bits are the offset. - mutable uint64_t Ptr; + mutable uint64_t Ptr = 0; public: - LazyOffsetPtr() : Ptr(0) { } + LazyOffsetPtr() = default; + explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) {} - explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) { } explicit LazyOffsetPtr(uint64_t Offset) : Ptr((Offset << 1) | 0x01) { assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits"); if (Offset == 0) @@ -392,15 +413,16 @@ struct LazyGenerationalUpdatePtr { /// A cache of the value of this pointer, in the most recent generation in /// which we queried it. struct LazyData { - LazyData(ExternalASTSource *Source, T Value) - : ExternalSource(Source), LastGeneration(0), LastValue(Value) {} ExternalASTSource *ExternalSource; - uint32_t LastGeneration; + uint32_t LastGeneration = 0; T LastValue; + + LazyData(ExternalASTSource *Source, T Value) + : ExternalSource(Source), LastValue(Value) {} }; // Our value is represented as simply T if there is no external AST source. - typedef llvm::PointerUnion<T, LazyData*> ValueType; + using ValueType = llvm::PointerUnion<T, LazyData*>; ValueType Value; LazyGenerationalUpdatePtr(ValueType V) : Value(V) {} @@ -459,25 +481,31 @@ public: return LazyGenerationalUpdatePtr(ValueType::getFromOpaqueValue(Ptr)); } }; -} // end namespace clang + +} // namespace clang /// Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be /// placed into a PointerUnion. namespace llvm { + template<typename Owner, typename T, void (clang::ExternalASTSource::*Update)(Owner)> struct PointerLikeTypeTraits< clang::LazyGenerationalUpdatePtr<Owner, T, Update>> { - typedef clang::LazyGenerationalUpdatePtr<Owner, T, Update> Ptr; + using Ptr = clang::LazyGenerationalUpdatePtr<Owner, T, Update>; + static void *getAsVoidPointer(Ptr P) { return P.getOpaqueValue(); } static Ptr getFromVoidPointer(void *P) { return Ptr::getFromOpaqueValue(P); } + enum { NumLowBitsAvailable = PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1 }; }; -} + +} // namespace llvm namespace clang { + /// \brief Represents a lazily-loaded vector of data. /// /// The lazily-loaded vector of data contains data that is partially loaded @@ -511,13 +539,14 @@ public: class iterator : public llvm::iterator_adaptor_base< iterator, int, std::random_access_iterator_tag, T, int, T *, T &> { + friend class LazyVector; + LazyVector *Self; iterator(LazyVector *Self, int Position) : iterator::iterator_adaptor_base(Position), Self(Self) {} bool isLoaded() const { return this->I < 0; } - friend class LazyVector; public: iterator() : iterator(nullptr, 0) {} @@ -562,23 +591,23 @@ public: }; /// \brief A lazy pointer to a statement. -typedef LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt> - LazyDeclStmtPtr; +using LazyDeclStmtPtr = + LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt>; /// \brief A lazy pointer to a declaration. -typedef LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl> - LazyDeclPtr; +using LazyDeclPtr = + LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl>; /// \brief A lazy pointer to a set of CXXCtorInitializers. -typedef LazyOffsetPtr<CXXCtorInitializer *, uint64_t, - &ExternalASTSource::GetExternalCXXCtorInitializers> - LazyCXXCtorInitializersPtr; +using LazyCXXCtorInitializersPtr = + LazyOffsetPtr<CXXCtorInitializer *, uint64_t, + &ExternalASTSource::GetExternalCXXCtorInitializers>; /// \brief A lazy pointer to a set of CXXBaseSpecifiers. -typedef LazyOffsetPtr<CXXBaseSpecifier, uint64_t, - &ExternalASTSource::GetExternalCXXBaseSpecifiers> - LazyCXXBaseSpecifiersPtr; +using LazyCXXBaseSpecifiersPtr = + LazyOffsetPtr<CXXBaseSpecifier, uint64_t, + &ExternalASTSource::GetExternalCXXBaseSpecifiers>; -} // end namespace clang +} // namespace clang -#endif +#endif // LLVM_CLANG_AST_EXTERNALASTSOURCE_H diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h index 953ecada6c..2c0564335b 100644 --- a/include/clang/AST/PrettyPrinter.h +++ b/include/clang/AST/PrettyPrinter.h @@ -30,8 +30,8 @@ public: virtual bool handledStmt(Stmt* E, raw_ostream& OS) = 0; }; -/// \brief Describes how types, statements, expressions, and -/// declarations should be printed. +/// Describes how types, statements, expressions, and declarations should be +/// printed. /// /// This type is intended to be small and suitable for passing by value. /// It is very frequently copied. @@ -53,20 +53,20 @@ struct PrintingPolicy { IncludeNewlines(true), MSVCFormatting(false), ConstantsAsWritten(false), SuppressImplicitBase(false) { } - /// \brief Adjust this printing policy for cases where it's known that - /// we're printing C++ code (for instance, if AST dumping reaches a - /// C++-only construct). This should not be used if a real LangOptions - /// object is available. + /// Adjust this printing policy for cases where it's known that we're + /// printing C++ code (for instance, if AST dumping reaches a C++-only + /// construct). This should not be used if a real LangOptions object is + /// available. void adjustForCPlusPlus() { SuppressTagKeyword = true; Bool = true; UseVoidForZeroParams = false; } - /// \brief The number of spaces to use to indent each line. + /// The number of spaces to use to indent each line. unsigned Indentation : 8; - /// \brief Whether we should suppress printing of the actual specifiers for + /// Whether we should suppress printing of the actual specifiers for /// the given type or declaration. /// /// This flag is only used when we are printing declarators beyond @@ -82,7 +82,7 @@ struct PrintingPolicy { /// "const int" type specifier and instead only print the "*y". bool SuppressSpecifiers : 1; - /// \brief Whether type printing should skip printing the tag keyword. + /// Whether type printing should skip printing the tag keyword. /// /// This is used when printing the inner type of elaborated types, /// (as the tag keyword is part of the elaborated type): @@ -92,7 +92,7 @@ struct PrintingPolicy { /// \endcode bool SuppressTagKeyword : 1; - /// \brief When true, include the body of a tag definition. + /// When true, include the body of a tag definition. /// /// This is used to place the definition of a struct /// in the middle of another declaration as with: @@ -102,14 +102,14 @@ struct PrintingPolicy { /// \endcode bool IncludeTagDefinition : 1; - /// \brief Suppresses printing of scope specifiers. + /// Suppresses printing of scope specifiers. bool SuppressScope : 1; - /// \brief Suppress printing parts of scope specifiers that don't need + /// Suppress printing parts of scope specifiers that don't need /// to be written, e.g., for inline or anonymous namespaces. bool SuppressUnwrittenScope : 1; - /// \brief Suppress printing of variable initializers. + /// Suppress printing of variable initializers. /// /// This flag is used when printing the loop variable in a for-range /// statement. For example, given: @@ -122,8 +122,8 @@ struct PrintingPolicy { /// internal initializer constructed for x will not be printed. bool SuppressInitializers : 1; - /// \brief Whether we should print the sizes of constant array expressions - /// as written in the sources. + /// Whether we should print the sizes of constant array expressions as written + /// in the sources. /// /// This flag determines whether array types declared as /// @@ -140,69 +140,67 @@ struct PrintingPolicy { /// \endcode bool ConstantArraySizeAsWritten : 1; - /// \brief When printing an anonymous tag name, also print the location of - /// that entity (e.g., "enum <anonymous at t.h:10:5>"). Otherwise, just - /// prints "(anonymous)" for the name. + /// When printing an anonymous tag name, also print the location of that + /// entity (e.g., "enum <anonymous at t.h:10:5>"). Otherwise, just prints + /// "(anonymous)" for the name. bool AnonymousTagLocations : 1; - /// \brief When true, suppress printing of the __strong lifetime qualifier in - /// ARC. + /// When true, suppress printing of the __strong lifetime qualifier in ARC. unsigned SuppressStrongLifetime : 1; - /// \brief When true, suppress printing of lifetime qualifier in - /// ARC. + /// When true, suppress printing of lifetime qualifier in ARC. unsigned SuppressLifetimeQualifiers : 1; /// When true, suppresses printing template arguments in names of C++ /// constructors. unsigned SuppressTemplateArgsInCXXConstructors : 1; - /// \brief Whether we can use 'bool' rather than '_Bool' (even if the language + /// Whether we can use 'bool' rather than '_Bool' (even if the language /// doesn't actually have 'bool', because, e.g., it is defined as a macro). unsigned Bool : 1; - /// \brief Whether we can use 'restrict' rather than '__restrict'. + /// Whether we can use 'restrict' rather than '__restrict'. unsigned Restrict : 1; - /// \brief Whether we can use 'alignof' rather than '__alignof'. + /// Whether we can use 'alignof' rather than '__alignof'. unsigned Alignof : 1; - /// \brief Whether we can use '_Alignof' rather than '__alignof'. + /// Whether we can use '_Alignof' rather than '__alignof'. unsigned UnderscoreAlignof : 1; - /// \brief Whether we should use '(void)' rather than '()' for a function - /// prototype with zero parameters. + /// Whether we should use '(void)' rather than '()' for a function prototype + /// with zero parameters. unsigned UseVoidForZeroParams : 1; - /// \brief Provide a 'terse' output. + /// Provide a 'terse' output. /// /// For example, in this mode we don't print function bodies, class members, /// declarations inside namespaces etc. Effectively, this should print /// only the requested declaration. unsigned TerseOutput : 1; - /// \brief When true, do certain refinement needed for producing proper - /// declaration tag; such as, do not print attributes attached to the declaration. + /// When true, do certain refinement needed for producing proper declaration + /// tag; such as, do not print attributes attached to the declaration. /// unsigned PolishForDeclaration : 1; - /// \brief When true, print the half-precision floating-point type as 'half' + /// When true, print the half-precision floating-point type as 'half' /// instead of '__fp16' unsigned Half : 1; - /// \brief When true, print the built-in wchar_t type as __wchar_t. For use in + /// When true, print the built-in wchar_t type as __wchar_t. For use in /// Microsoft mode when wchar_t is not available. unsigned MSWChar : 1; - /// \brief When true, include newlines after statements like "break", etc. + /// When true, include newlines after statements like "break", etc. unsigned IncludeNewlines : 1; - /// \brief Use whitespace and punctuation like MSVC does. In particular, this - /// prints anonymous namespaces as `anonymous namespace' and does not insert - /// spaces after template arguments. + /// Use whitespace and punctuation like MSVC does. In particular, this prints + /// anonymous namespaces as `anonymous namespace' and does not insert spaces + /// after template arguments. bool MSVCFormatting : 1; - /// \brief Whether we should print the constant expressions as written in the + /// Whether we should print the constant expressions as written in the /// sources. /// /// This flag determines whether constants expressions like @@ -220,7 +218,7 @@ struct PrintingPolicy { /// \endcode bool ConstantsAsWritten : 1; - /// \brief When true, don't print the implicit 'self' or 'this' expressions. + /// When true, don't print the implicit 'self' or 'this' expressions. bool SuppressImplicitBase : 1; }; diff --git a/include/clang/AST/QualTypeNames.h b/include/clang/AST/QualTypeNames.h new file mode 100644 index 0000000000..86d805feee --- /dev/null +++ b/include/clang/AST/QualTypeNames.h @@ -0,0 +1,90 @@ +//===--- QualTypeNames.h - Generate Complete QualType Names ----*- C++ -*-===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +// ===----------------------------------------------------------------------===// +// +// \file +// Functionality to generate the fully-qualified names of QualTypes, +// including recursively expanding any subtypes and template +// parameters. +// +// More precisely: Generates a name that can be used to name the same +// type if used at the end of the current translation unit--with +// certain limitations. See below. +// +// This code desugars names only very minimally, so in this code: +// +// namespace A { +// struct X {}; +// } +// using A::X; +// namespace B { +// using std::tuple; +// typedef tuple<X> TX; +// TX t; +// } +// +// B::t's type is reported as "B::TX", rather than std::tuple<A::X>. +// +// Also, this code replaces types found via using declarations with +// their more qualified name, so for the code: +// +// using std::tuple; +// tuple<int> TInt; +// +// TInt's type will be named, "std::tuple<int>". +// +// Limitations: +// +// Some types have ambiguous names at the end of a translation unit, +// are not namable at all there, or are special cases in other ways. +// +// 1) Types with only local scope will have their local names: +// +// void foo() { +// struct LocalType {} LocalVar; +// } +// +// LocalVar's type will be named, "struct LocalType", without any +// qualification. +// +// 2) Types that have been shadowed are reported normally, but a +// client using that name at the end of the translation unit will be +// referring to a different type. +// +// ===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_QUALTYPENAMES_H +#define LLVM_CLANG_AST_QUALTYPENAMES_H + +#include "clang/AST/ASTContext.h" + +namespace clang { +namespace TypeName { +/// \brief Get the fully qualified name for a type. This includes full +/// qualification of all template parameters etc. +/// +/// \param[in] QT - the type for which the fully qualified name will be +/// returned. +/// \param[in] Ctx - the ASTContext to be used. +/// \param[in] WithGlobalNsPrefix - If true, then the global namespace +/// specifier "::" will be prepended to the fully qualified name. +std::string getFullyQualifiedName(QualType QT, const ASTContext &Ctx, + bool WithGlobalNsPrefix = false); + +/// \brief Generates a QualType that can be used to name the same type +/// if used at the end of the current translation unit. This ignores +/// issues such as type shadowing. +/// +/// \param[in] QT - the type for which the fully qualified type will be +/// returned. +/// \param[in] Ctx - the ASTContext to be used. +/// \param[in] WithGlobalNsPrefix - Indicate whether the global namespace +/// specifier "::" should be prepended or not. +QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx, + bool WithGlobalNsPrefix = false); +} // end namespace TypeName +} // end namespace clang +#endif // LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H |