diff options
-rw-r--r-- | include/clang/AST/Decl.h | 9 | ||||
-rw-r--r-- | include/clang/AST/Type.h | 19 | ||||
-rw-r--r-- | lib/AST/Decl.cpp | 21 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 25 |
4 files changed, 41 insertions, 33 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 9647d0145e..169b74e01b 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -1814,6 +1814,9 @@ private: /// it is a declaration ("struct foo;"). bool IsDefinition : 1; + /// IsBeingDefined - True if this is currently being defined. + bool IsBeingDefined : 1; + /// IsEmbeddedInDeclarator - True if this tag declaration is /// "embedded" (i.e., defined or declared for the very first time) /// in the syntax of a declarator. @@ -1855,6 +1858,7 @@ protected: "EnumDecl not matched with TTK_Enum"); TagDeclKind = TK; IsDefinition = false; + IsBeingDefined = false; IsEmbeddedInDeclarator = false; setPreviousDeclaration(PrevDecl); } @@ -1896,6 +1900,11 @@ public: return IsDefinition; } + /// isBeingDefined - Return true if this decl is currently being defined. + bool isBeingDefined() const { + return IsBeingDefined; + } + bool isEmbeddedInDeclarator() const { return IsEmbeddedInDeclarator; } diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index a49c83cf1d..f1e7dfe3e9 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -2267,14 +2267,9 @@ public: }; class TagType : public Type { - /// Stores the TagDecl associated with this type. The decl will - /// point to the TagDecl that actually defines the entity (or is a - /// definition in progress), if there is such a definition. The - /// single-bit value will be non-zero when this tag is in the - /// process of being defined. - mutable llvm::PointerIntPair<TagDecl *, 1> decl; - friend class ASTContext; - friend class TagDecl; + /// Stores the TagDecl associated with this type. The decl may point to any + /// TagDecl that declares the entity. + TagDecl * decl; protected: TagType(TypeClass TC, const TagDecl *D, QualType can); @@ -2282,12 +2277,11 @@ protected: virtual Linkage getLinkageImpl() const; public: - TagDecl *getDecl() const { return decl.getPointer(); } + TagDecl *getDecl() const; /// @brief Determines whether this type is in the process of being /// defined. - bool isBeingDefined() const { return decl.getInt(); } - void setBeingDefined(bool Def) const { decl.setInt(Def? 1 : 0); } + bool isBeingDefined() const; static bool classof(const Type *T) { return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast; @@ -2580,7 +2574,6 @@ class InjectedClassNameType : public Type { QualType InjectedType; friend class ASTContext; // ASTContext creates these. - friend class TagDecl; // TagDecl mutilates the Decl friend class PCHReader; // FIXME: ASTContext::getInjectedClassNameType is not // currently suitable for PCH reading, too much // interdependencies. @@ -2598,7 +2591,7 @@ public: return cast<TemplateSpecializationType>(InjectedType.getTypePtr()); } - CXXRecordDecl *getDecl() const { return Decl; } + CXXRecordDecl *getDecl() const; bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index a30a430382..0e0bbf34a1 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -1534,14 +1534,7 @@ void TagDecl::setTypedefForAnonDecl(TypedefDecl *TDD) { } void TagDecl::startDefinition() { - if (TagType *TagT = const_cast<TagType *>(TypeForDecl->getAs<TagType>())) { - TagT->decl.setPointer(this); - TagT->decl.setInt(1); - } else if (InjectedClassNameType *Injected - = const_cast<InjectedClassNameType *>( - TypeForDecl->getAs<InjectedClassNameType>())) { - Injected->Decl = cast<CXXRecordDecl>(this); - } + IsBeingDefined = true; if (isa<CXXRecordDecl>(this)) { CXXRecordDecl *D = cast<CXXRecordDecl>(this); @@ -1558,17 +1551,7 @@ void TagDecl::completeDefinition() { "definition completed but not started"); IsDefinition = true; - if (TagType *TagT = const_cast<TagType *>(TypeForDecl->getAs<TagType>())) { - assert(TagT->decl.getPointer() == this && - "Attempt to redefine a tag definition?"); - TagT->decl.setInt(0); - } else if (InjectedClassNameType *Injected - = const_cast<InjectedClassNameType *>( - TypeForDecl->getAs<InjectedClassNameType>())) { - assert(Injected->Decl == this && - "Attempt to redefine a class template definition?"); - (void)Injected; - } + IsBeingDefined = false; } TagDecl* TagDecl::getDefinition() const { diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 49d579f4a0..1085efec19 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -1072,7 +1072,30 @@ void DependentDecltypeType::Profile(llvm::FoldingSetNodeID &ID, TagType::TagType(TypeClass TC, const TagDecl *D, QualType can) : Type(TC, can, D->isDependentType()), - decl(const_cast<TagDecl*>(D), 0) {} + decl(const_cast<TagDecl*>(D)) {} + +static TagDecl *getInterestingTagDecl(TagDecl *decl) { + for (TagDecl::redecl_iterator I = decl->redecls_begin(), + E = decl->redecls_end(); + I != E; ++I) { + if (I->isDefinition() || I->isBeingDefined()) + return *I; + } + // If there's no definition (not even in progress), return what we have. + return decl; +} + +TagDecl *TagType::getDecl() const { + return getInterestingTagDecl(decl); +} + +bool TagType::isBeingDefined() const { + return getDecl()->isBeingDefined(); +} + +CXXRecordDecl *InjectedClassNameType::getDecl() const { + return cast<CXXRecordDecl>(getInterestingTagDecl(Decl)); +} bool RecordType::classof(const TagType *TT) { return isa<RecordDecl>(TT->getDecl()); |