diff options
Diffstat (limited to 'include/clang/AST/Decl.h')
-rw-r--r-- | include/clang/AST/Decl.h | 367 |
1 files changed, 256 insertions, 111 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index a0c76c0..244a7b8 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -24,6 +24,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/raw_ostream.h" namespace clang { struct ASTTemplateArgumentListInfo; @@ -43,6 +44,7 @@ class TemplateArgumentList; class TemplateParameterList; class TypeLoc; class UnresolvedSetImpl; +class VarTemplateDecl; /// \brief A container of type source information. /// @@ -109,7 +111,6 @@ class NamedDecl : public Decl { private: NamedDecl *getUnderlyingDeclImpl(); - void verifyLinkage() const; protected: NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N) @@ -142,7 +143,7 @@ public: // FIXME: Deprecated, move clients to getName(). std::string getNameAsString() const { return Name.getAsString(); } - void printName(raw_ostream &os) const { return Name.printName(os); } + void printName(raw_ostream &os) const { os << Name; } /// getDeclName - Get the actual, stored name of the declaration, /// which may be a special name. @@ -189,10 +190,13 @@ public: using Decl::isModulePrivate; using Decl::setModulePrivate; - + /// \brief Determine whether this declaration is hidden from name lookup. bool isHidden() const { return Hidden; } - + + /// \brief Set whether this declaration is hidden from name lookup. + void setHidden(bool Hide) { Hidden = Hide; } + /// \brief Determine whether this declaration is a C++ class member. bool isCXXClassMember() const { const DeclContext *DC = getDeclContext(); @@ -212,11 +216,24 @@ public: bool isCXXInstanceMember() const; /// \brief Determine what kind of linkage this entity has. - Linkage getLinkage() const; + /// This is not the linkage as defined by the standard or the codegen notion + /// of linkage. It is just an implementation detail that is used to compute + /// those. + Linkage getLinkageInternal() const; + + /// \brief Get the linkage from a semantic point of view. Entities in + /// anonymous namespaces are external (in c++98). + Linkage getFormalLinkage() const { + return clang::getFormalLinkage(getLinkageInternal()); + } /// \brief True if this decl has external linkage. - bool hasExternalLinkage() const { - return getLinkage() == ExternalLinkage; + bool hasExternalFormalLinkage() const { + return isExternalFormalLinkage(getLinkageInternal()); + } + + bool isExternallyVisible() const { + return clang::isExternallyVisible(getLinkageInternal()); } /// \brief Determines the visibility of this entity. @@ -256,6 +273,13 @@ public: return const_cast<NamedDecl*>(this)->getUnderlyingDecl(); } + NamedDecl *getMostRecentDecl() { + return cast<NamedDecl>(static_cast<Decl *>(this)->getMostRecentDecl()); + } + const NamedDecl *getMostRecentDecl() const { + return const_cast<NamedDecl*>(this)->getMostRecentDecl(); + } + static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K >= firstNamed && K <= lastNamed; } }; @@ -351,6 +375,7 @@ public: using redeclarable_base::redecls_end; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; + using redeclarable_base::isFirstDecl; /// \brief Returns true if this is an anonymous namespace declaration. /// @@ -377,7 +402,7 @@ public: /// \brief Get the original (first) namespace declaration. NamespaceDecl *getOriginalNamespace() { - if (isFirstDeclaration()) + if (isFirstDecl()) return this; return AnonOrFirstNamespaceAndInline.getPointer(); @@ -385,7 +410,7 @@ public: /// \brief Get the original (first) namespace declaration. const NamespaceDecl *getOriginalNamespace() const { - if (isFirstDeclaration()) + if (isFirstDecl()) return this; return AnonOrFirstNamespaceAndInline.getPointer(); @@ -394,9 +419,7 @@ public: /// \brief Return true if this declaration is an original (first) declaration /// of the namespace. This is false for non-original (subsequent) namespace /// declarations and anonymous namespaces. - bool isOriginalNamespace() const { - return isFirstDeclaration(); - } + bool isOriginalNamespace() const { return isFirstDecl(); } /// \brief Retrieve the anonymous namespace nested inside this namespace, /// if any. @@ -689,11 +712,21 @@ private: /// \brief Whether this variable is (C++0x) constexpr. unsigned IsConstexpr : 1; + + /// \brief Whether this variable is the implicit variable for a lambda + /// init-capture. + unsigned IsInitCapture : 1; + + /// \brief Whether this local extern variable's previous declaration was + /// declared in the same block scope. This controls whether we should merge + /// the type of this declaration with its previous declaration. + unsigned PreviousDeclInSameBlockScope : 1; }; - enum { NumVarDeclBits = 12 }; + enum { NumVarDeclBits = 14 }; friend class ASTDeclReader; friend class StmtIteratorBase; + friend class ASTNodeImporter; protected: enum { NumParameterIndexBits = 8 }; @@ -732,15 +765,8 @@ protected: }; VarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, - SourceLocation IdLoc, IdentifierInfo *Id, - QualType T, TypeSourceInfo *TInfo, StorageClass SC) - : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), Init() { - assert(sizeof(VarDeclBitfields) <= sizeof(unsigned)); - assert(sizeof(ParmVarDeclBitfields) <= sizeof(unsigned)); - AllBits = 0; - VarDeclBits.SClass = SC; - // Everything else is implicitly initialized to false. - } + SourceLocation IdLoc, IdentifierInfo *Id, QualType T, + TypeSourceInfo *TInfo, StorageClass SC); typedef Redeclarable<VarDecl> redeclarable_base; virtual VarDecl *getNextRedeclaration() { return RedeclLink.getNext(); } @@ -757,6 +783,7 @@ public: using redeclarable_base::redecls_end; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; + using redeclarable_base::isFirstDecl; static VarDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, @@ -797,7 +824,8 @@ public: /// is a non-static local variable. bool hasLocalStorage() const { if (getStorageClass() == SC_None) - return !isFileVarDecl(); + // Second check is for C++11 [dcl.stc]p4. + return !isFileVarDecl() && getTSCSpec() == TSCS_unspecified; // Return true for: Auto, Register. // Return false for: Extern, Static, PrivateExtern, OpenCLWorkGroupLocal. @@ -808,7 +836,10 @@ public: /// isStaticLocal - Returns true if a variable with function scope is a /// static local variable. bool isStaticLocal() const { - return getStorageClass() == SC_Static && !isFileVarDecl(); + return (getStorageClass() == SC_Static || + // C++11 [dcl.stc]p4 + (getStorageClass() == SC_None && getTSCSpec() == TSCS_thread_local)) + && !isFileVarDecl(); } /// \brief Returns true if a variable has extern or __private_extern__ @@ -818,12 +849,19 @@ public: getStorageClass() == SC_PrivateExtern; } - /// hasGlobalStorage - Returns true for all variables that do not - /// have local storage. This includs all global variables as well - /// as static variables declared within a function. + /// \brief Returns true for all variables that do not have local storage. + /// + /// This includes all global variables as well as static variables declared + /// within a function. bool hasGlobalStorage() const { return !hasLocalStorage(); } - /// Compute the language linkage. + /// \brief Get the storage duration of this variable, per C++ [basic.stc]. + StorageDuration getStorageDuration() const { + return hasLocalStorage() ? SD_Automatic : + getTSCSpec() ? SD_Thread : SD_Static; + } + + /// \brief Compute the language linkage. LanguageLinkage getLanguageLinkage() const; /// \brief Determines whether this variable is a variable with @@ -847,7 +885,7 @@ public: bool isLocalVarDecl() const { if (getKind() != Decl::Var) return false; - if (const DeclContext *DC = getDeclContext()) + if (const DeclContext *DC = getLexicalDeclContext()) return DC->getRedeclContext()->isFunctionOrMethod(); return false; } @@ -857,7 +895,7 @@ public: bool isFunctionOrMethodVarDecl() const { if (getKind() != Decl::Var) return false; - const DeclContext *DC = getDeclContext()->getRedeclContext(); + const DeclContext *DC = getLexicalDeclContext()->getRedeclContext(); return DC->isFunctionOrMethod() && DC->getDeclKind() != Decl::Block; } @@ -908,10 +946,6 @@ public: return const_cast<VarDecl*>(this)->getActingDefinition(); } - /// \brief Determine whether this is a tentative definition of a - /// variable in C. - bool isTentativeDefinitionNow() const; - /// \brief Get the real (not just tentative) definition for this declaration. VarDecl *getDefinition(ASTContext &); const VarDecl *getDefinition(ASTContext &C) const { @@ -933,10 +967,11 @@ public: /// isFileVarDecl - Returns true for file scoped variable declaration. bool isFileVarDecl() const { - if (getKind() != Decl::Var) + Kind K = getKind(); + if (K == ParmVar || K == ImplicitParam) return false; - if (getDeclContext()->getRedeclContext()->isFileContext()) + if (getLexicalDeclContext()->getRedeclContext()->isFileContext()) return true; if (isStaticDataMember()) @@ -1000,20 +1035,6 @@ public: void setInit(Expr *I); - /// \brief Determine whether this variable is a reference that - /// extends the lifetime of its temporary initializer. - /// - /// A reference extends the lifetime of its temporary initializer if - /// it's initializer is an rvalue that would normally go out of scope - /// at the end of the initializer (a full expression). In such cases, - /// the reference itself takes ownership of the temporary, which will - /// be destroyed when the reference goes out of scope. For example: - /// - /// \code - /// const int &r = 1.0; // creates a temporary of type 'int' - /// \endcode - bool extendsLifetimeOfTemporary() const; - /// \brief Determine whether this variable's value can be used in a /// constant expression, according to the relevant language standard. /// This only checks properties of the declaration, and does not check @@ -1123,15 +1144,34 @@ public: bool isConstexpr() const { return VarDeclBits.IsConstexpr; } void setConstexpr(bool IC) { VarDeclBits.IsConstexpr = IC; } + /// Whether this variable is the implicit variable for a lambda init-capture. + bool isInitCapture() const { return VarDeclBits.IsInitCapture; } + void setInitCapture(bool IC) { VarDeclBits.IsInitCapture = IC; } + + /// Whether this local extern variable declaration's previous declaration + /// was declared in the same block scope. Only correct in C++. + bool isPreviousDeclInSameBlockScope() const { + return VarDeclBits.PreviousDeclInSameBlockScope; + } + void setPreviousDeclInSameBlockScope(bool Same) { + VarDeclBits.PreviousDeclInSameBlockScope = Same; + } + /// \brief If this variable is an instantiated static data member of a /// class template specialization, returns the templated static data member /// from which it was instantiated. VarDecl *getInstantiatedFromStaticDataMember() const; - /// \brief If this variable is a static data member, determine what kind of + /// \brief If this variable is an instantiation of a variable template or a + /// static data member of a class template, determine what kind of /// template specialization or instantiation this is. TemplateSpecializationKind getTemplateSpecializationKind() const; + /// \brief If this variable is an instantiation of a variable template or a + /// static data member of a class template, determine its point of + /// instantiation. + SourceLocation getPointOfInstantiation() const; + /// \brief If this variable is an instantiation of a static data member of a /// class template specialization, retrieves the member specialization /// information. @@ -1142,6 +1182,26 @@ public: void setTemplateSpecializationKind(TemplateSpecializationKind TSK, SourceLocation PointOfInstantiation = SourceLocation()); + /// \brief Specify that this variable is an instantiation of the + /// static data member VD. + void setInstantiationOfStaticDataMember(VarDecl *VD, + TemplateSpecializationKind TSK); + + /// \brief Retrieves the variable template that is described by this + /// variable declaration. + /// + /// Every variable template is represented as a VarTemplateDecl and a + /// VarDecl. The former contains template properties (such as + /// the template parameter lists) while the latter contains the + /// actual description of the template's + /// contents. VarTemplateDecl::getTemplatedDecl() retrieves the + /// VarDecl that from a VarTemplateDecl, while + /// getDescribedVarTemplate() retrieves the VarTemplateDecl from + /// a VarDecl. + VarTemplateDecl *getDescribedVarTemplate() const; + + void setDescribedVarTemplate(VarTemplateDecl *Template); + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K >= firstVar && K <= lastVar; } @@ -1314,11 +1374,7 @@ public: ParmVarDeclBits.HasInheritedDefaultArg = I; } - QualType getOriginalType() const { - if (getTypeSourceInfo()) - return getTypeSourceInfo()->getType(); - return getType(); - } + QualType getOriginalType() const; /// \brief Determine whether this parameter is actually a function /// parameter pack. @@ -1517,6 +1573,7 @@ public: using redeclarable_base::redecls_end; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; + using redeclarable_base::isFirstDecl; static FunctionDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, @@ -1701,6 +1758,10 @@ public: /// entry point into an executable program. bool isMain() const; + /// \brief Determines whether this function is a MSVCRT user defined entry + /// point. + bool isMSVCRTEntryPoint() const; + /// \brief Determines whether this operator new or delete is one /// of the reserved global placement operators: /// void *operator new(size_t, void *); @@ -1716,6 +1777,28 @@ public: /// This function must be an allocation or deallocation function. bool isReservedGlobalPlacementOperator() const; + /// \brief Determines whether this function is one of the replaceable + /// global allocation functions: + /// void *operator new(size_t); + /// void *operator new(size_t, const std::nothrow_t &) noexcept; + /// void *operator new[](size_t); + /// void *operator new[](size_t, const std::nothrow_t &) noexcept; + /// void operator delete(void *) noexcept; + /// void operator delete(void *, std::size_t) noexcept; [C++1y] + /// void operator delete(void *, const std::nothrow_t &) noexcept; + /// void operator delete[](void *) noexcept; + /// void operator delete[](void *, std::size_t) noexcept; [C++1y] + /// void operator delete[](void *, const std::nothrow_t &) noexcept; + /// These functions have special behavior under C++1y [expr.new]: + /// An implementation is allowed to omit a call to a replaceable global + /// allocation function. [...] + bool isReplaceableGlobalAllocationFunction() const; + + /// \brief Determine whether this function is a sized global deallocation + /// function in C++1y. If so, find and return the corresponding unsized + /// deallocation function. + FunctionDecl *getCorrespondingUnsizedGlobalDeallocationFunction() const; + /// Compute the language linkage. LanguageLinkage getLanguageLinkage() const; @@ -2039,7 +2122,7 @@ public: /// FieldDecl - An instance of this class is created by Sema::ActOnField to /// represent a member of a struct/union/class. -class FieldDecl : public DeclaratorDecl { +class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> { // FIXME: This can be packed into the bitfields in Decl. bool Mutable : 1; mutable unsigned CachedFieldIndex : 31; @@ -2153,6 +2236,10 @@ public: SourceRange getSourceRange() const LLVM_READONLY; + /// Retrieves the canonical declaration of this field. + FieldDecl *getCanonicalDecl() { return getFirstDecl(); } + const FieldDecl *getCanonicalDecl() const { return getFirstDecl(); } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K >= firstField && K <= lastField; } @@ -2165,7 +2252,7 @@ public: /// that is defined. For example, in "enum X {a,b}", each of a/b are /// EnumConstantDecl's, X is an instance of EnumDecl, and the type of a/b is a /// TagType for the X EnumDecl. -class EnumConstantDecl : public ValueDecl { +class EnumConstantDecl : public ValueDecl, public Mergeable<EnumConstantDecl> { Stmt *Init; // an integer constant expression llvm::APSInt Val; // The value. protected: @@ -2191,6 +2278,10 @@ public: SourceRange getSourceRange() const LLVM_READONLY; + /// Retrieves the canonical declaration of this enumerator. + EnumConstantDecl *getCanonicalDecl() { return getFirstDecl(); } + const EnumConstantDecl *getCanonicalDecl() const { return getFirstDecl(); } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == EnumConstant; } @@ -2289,14 +2380,14 @@ public: /// Base class for declarations which introduce a typedef-name. class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> { virtual void anchor(); - /// UnderlyingType - This is the type the typedef is set to. - TypeSourceInfo *TInfo; + typedef std::pair<TypeSourceInfo*, QualType> ModedTInfo; + llvm::PointerUnion<TypeSourceInfo*, ModedTInfo*> MaybeModedTInfo; protected: TypedefNameDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo) - : TypeDecl(DK, DC, IdLoc, Id, StartLoc), TInfo(TInfo) {} + : TypeDecl(DK, DC, IdLoc, Id, StartLoc), MaybeModedTInfo(TInfo) {} typedef Redeclarable<TypedefNameDecl> redeclarable_base; virtual TypedefNameDecl *getNextRedeclaration() { @@ -2315,26 +2406,31 @@ public: using redeclarable_base::redecls_end; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; + using redeclarable_base::isFirstDecl; - TypeSourceInfo *getTypeSourceInfo() const { - return TInfo; - } + bool isModed() const { return MaybeModedTInfo.is<ModedTInfo*>(); } - /// Retrieves the canonical declaration of this typedef-name. - TypedefNameDecl *getCanonicalDecl() { - return getFirstDeclaration(); - } - const TypedefNameDecl *getCanonicalDecl() const { - return getFirstDeclaration(); + TypeSourceInfo *getTypeSourceInfo() const { + return isModed() + ? MaybeModedTInfo.get<ModedTInfo*>()->first + : MaybeModedTInfo.get<TypeSourceInfo*>(); } - QualType getUnderlyingType() const { - return TInfo->getType(); + return isModed() + ? MaybeModedTInfo.get<ModedTInfo*>()->second + : MaybeModedTInfo.get<TypeSourceInfo*>()->getType(); } void setTypeSourceInfo(TypeSourceInfo *newType) { - TInfo = newType; + MaybeModedTInfo = newType; + } + void setModedTypeSourceInfo(TypeSourceInfo *unmodedTSI, QualType modedTy) { + MaybeModedTInfo = new (getASTContext()) ModedTInfo(unmodedTSI, modedTy); } + /// Retrieves the canonical declaration of this typedef-name. + TypedefNameDecl *getCanonicalDecl() { return getFirstDecl(); } + const TypedefNameDecl *getCanonicalDecl() const { return getFirstDecl(); } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { @@ -2436,6 +2532,9 @@ protected: /// This option is only enabled when modules are enabled. bool MayHaveOutOfDateDef : 1; + /// Has the full definition of this type been required by a use somewhere in + /// the TU. + bool IsCompleteDefinitionRequired : 1; private: SourceLocation RBraceLoc; @@ -2443,33 +2542,33 @@ private: // to be used for the (uncommon) case of out-of-line declarations. typedef QualifierInfo ExtInfo; - /// TypedefNameDeclOrQualifier - If the (out-of-line) tag declaration name + /// \brief If the (out-of-line) tag declaration name /// is qualified, it points to the qualifier info (nns and range); /// otherwise, if the tag declaration is anonymous and it is part of /// a typedef or alias, it points to the TypedefNameDecl (used for mangling); + /// otherwise, if the tag declaration is anonymous and it is used as a + /// declaration specifier for variables, it points to the first VarDecl (used + /// for mangling); /// otherwise, it is a null (TypedefNameDecl) pointer. - llvm::PointerUnion<TypedefNameDecl*, ExtInfo*> TypedefNameDeclOrQualifier; + llvm::PointerUnion<NamedDecl *, ExtInfo *> NamedDeclOrQualifier; - bool hasExtInfo() const { return TypedefNameDeclOrQualifier.is<ExtInfo*>(); } - ExtInfo *getExtInfo() { return TypedefNameDeclOrQualifier.get<ExtInfo*>(); } + bool hasExtInfo() const { return NamedDeclOrQualifier.is<ExtInfo *>(); } + ExtInfo *getExtInfo() { return NamedDeclOrQualifier.get<ExtInfo *>(); } const ExtInfo *getExtInfo() const { - return TypedefNameDeclOrQualifier.get<ExtInfo*>(); + return NamedDeclOrQualifier.get<ExtInfo *>(); } protected: - TagDecl(Kind DK, TagKind TK, DeclContext *DC, - SourceLocation L, IdentifierInfo *Id, - TagDecl *PrevDecl, SourceLocation StartL) - : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), - TypedefNameDeclOrQualifier((TypedefNameDecl*) 0) { + TagDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L, + IdentifierInfo *Id, TagDecl *PrevDecl, SourceLocation StartL) + : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), TagDeclKind(TK), + IsCompleteDefinition(false), IsBeingDefined(false), + IsEmbeddedInDeclarator(false), IsFreeStanding(false), + IsCompleteDefinitionRequired(false), + NamedDeclOrQualifier((NamedDecl *)0) { assert((DK != Enum || TK == TTK_Enum) && "EnumDecl not matched with TTK_Enum"); - TagDeclKind = TK; - IsCompleteDefinition = false; - IsBeingDefined = false; - IsEmbeddedInDeclarator = false; - IsFreeStanding = false; - setPreviousDeclaration(PrevDecl); + setPreviousDecl(PrevDecl); } typedef Redeclarable<TagDecl> redeclarable_base; @@ -2492,6 +2591,7 @@ public: using redeclarable_base::redecls_end; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; + using redeclarable_base::isFirstDecl; SourceLocation getRBraceLoc() const { return RBraceLoc; } void setRBraceLoc(SourceLocation L) { RBraceLoc = L; } @@ -2522,6 +2622,12 @@ public: return IsCompleteDefinition; } + /// \brief Return true if this complete decl is + /// required to be complete for some existing use. + bool isCompleteDefinitionRequired() const { + return IsCompleteDefinitionRequired; + } + /// isBeingDefined - Return true if this decl is currently being defined. bool isBeingDefined() const { return IsBeingDefined; @@ -2563,6 +2669,10 @@ public: void setCompleteDefinition(bool V) { IsCompleteDefinition = V; } + void setCompleteDefinitionRequired(bool V = true) { + IsCompleteDefinitionRequired = V; + } + // FIXME: Return StringRef; const char *getKindName() const { return TypeWithKeyword::getTagTypeKindName(getTagKind()); @@ -2599,11 +2709,22 @@ public: return (getDeclName() || getTypedefNameForAnonDecl()); } + bool hasDeclaratorForAnonDecl() const { + return dyn_cast_or_null<DeclaratorDecl>( + NamedDeclOrQualifier.get<NamedDecl *>()); + } + DeclaratorDecl *getDeclaratorForAnonDecl() const { + return hasExtInfo() ? 0 : dyn_cast_or_null<DeclaratorDecl>( + NamedDeclOrQualifier.get<NamedDecl *>()); + } + TypedefNameDecl *getTypedefNameForAnonDecl() const { - return hasExtInfo() ? 0 : - TypedefNameDeclOrQualifier.get<TypedefNameDecl*>(); + return hasExtInfo() ? 0 : dyn_cast_or_null<TypedefNameDecl>( + NamedDeclOrQualifier.get<NamedDecl *>()); } + void setDeclaratorForAnonDecl(DeclaratorDecl *DD) { NamedDeclOrQualifier = DD; } + void setTypedefNameForAnonDecl(TypedefNameDecl *TDD); /// \brief Retrieve the nested-name-specifier that qualifies the name of this @@ -2702,21 +2823,22 @@ public: return cast<EnumDecl>(TagDecl::getCanonicalDecl()); } const EnumDecl *getCanonicalDecl() const { - return cast<EnumDecl>(TagDecl::getCanonicalDecl()); + return const_cast<EnumDecl*>(this)->getCanonicalDecl(); } - const EnumDecl *getPreviousDecl() const { - return cast_or_null<EnumDecl>(TagDecl::getPreviousDecl()); - } EnumDecl *getPreviousDecl() { - return cast_or_null<EnumDecl>(TagDecl::getPreviousDecl()); + return cast_or_null<EnumDecl>( + static_cast<TagDecl *>(this)->getPreviousDecl()); } - - const EnumDecl *getMostRecentDecl() const { - return cast<EnumDecl>(TagDecl::getMostRecentDecl()); + const EnumDecl *getPreviousDecl() const { + return const_cast<EnumDecl*>(this)->getPreviousDecl(); } + EnumDecl *getMostRecentDecl() { - return cast<EnumDecl>(TagDecl::getMostRecentDecl()); + return cast<EnumDecl>(static_cast<TagDecl *>(this)->getMostRecentDecl()); + } + const EnumDecl *getMostRecentDecl() const { + return const_cast<EnumDecl*>(this)->getMostRecentDecl(); } EnumDecl *getDefinition() const { @@ -2912,18 +3034,19 @@ public: IdentifierInfo *Id, RecordDecl* PrevDecl = 0); static RecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID); - const RecordDecl *getPreviousDecl() const { - return cast_or_null<RecordDecl>(TagDecl::getPreviousDecl()); - } RecordDecl *getPreviousDecl() { - return cast_or_null<RecordDecl>(TagDecl::getPreviousDecl()); + return cast_or_null<RecordDecl>( + static_cast<TagDecl *>(this)->getPreviousDecl()); } - - const RecordDecl *getMostRecentDecl() const { - return cast<RecordDecl>(TagDecl::getMostRecentDecl()); + const RecordDecl *getPreviousDecl() const { + return const_cast<RecordDecl*>(this)->getPreviousDecl(); } + RecordDecl *getMostRecentDecl() { - return cast<RecordDecl>(TagDecl::getMostRecentDecl()); + return cast<RecordDecl>(static_cast<TagDecl *>(this)->getMostRecentDecl()); + } + const RecordDecl *getMostRecentDecl() const { + return const_cast<RecordDecl*>(this)->getMostRecentDecl(); } bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; } @@ -3106,13 +3229,17 @@ private: Capture *Captures; unsigned NumCaptures; + unsigned ManglingNumber; + Decl *ManglingContextDecl; + protected: BlockDecl(DeclContext *DC, SourceLocation CaretLoc) : Decl(Block, DC, CaretLoc), DeclContext(Block), IsVariadic(false), CapturesCXXThis(false), BlockMissingReturnType(true), IsConversionFromLambda(false), ParamInfo(0), NumParams(0), Body(0), - SignatureAsWritten(0), Captures(0), NumCaptures(0) {} + SignatureAsWritten(0), Captures(0), NumCaptures(0), + ManglingNumber(0), ManglingContextDecl(0) {} public: static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L); @@ -3182,6 +3309,18 @@ public: const Capture *end, bool capturesCXXThis); + unsigned getBlockManglingNumber() const { + return ManglingNumber; + } + Decl *getBlockManglingContextDecl() const { + return ManglingContextDecl; + } + + void setBlockMangling(unsigned Number, Decl *Ctx) { + ManglingNumber = Number; + ManglingContextDecl = Ctx; + } + virtual SourceRange getSourceRange() const LLVM_READONLY; // Implement isa/cast/dyncast/etc. @@ -3354,7 +3493,7 @@ inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, } template<typename decl_type> -void Redeclarable<decl_type>::setPreviousDeclaration(decl_type *PrevDecl) { +void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) { // Note: This routine is implemented here because we need both NamedDecl // and Redeclarable to be defined. @@ -3364,10 +3503,16 @@ void Redeclarable<decl_type>::setPreviousDeclaration(decl_type *PrevDecl) { // Point to previous. Make sure that this is actually the most recent // redeclaration, or we can build invalid chains. If the most recent // redeclaration is invalid, it won't be PrevDecl, but we want it anyway. - First = PrevDecl->getFirstDeclaration(); + First = PrevDecl->getFirstDecl(); assert(First->RedeclLink.NextIsLatest() && "Expected first"); decl_type *MostRecent = First->RedeclLink.getNext(); RedeclLink = PreviousDeclLink(cast<decl_type>(MostRecent)); + + // If the declaration was previously visible, a redeclaration of it remains + // visible even if it wouldn't be visible by itself. + static_cast<decl_type*>(this)->IdentifierNamespace |= + MostRecent->getIdentifierNamespace() & + (Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Type); } else { // Make this first. First = static_cast<decl_type*>(this); |