/// 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.
"EnumDecl not matched with TTK_Enum");
TagDeclKind = TK;
IsDefinition = false;
+ IsBeingDefined = false;
IsEmbeddedInDeclarator = false;
setPreviousDeclaration(PrevDecl);
}
return IsDefinition;
}
+ /// isBeingDefined - Return true if this decl is currently being defined.
+ bool isBeingDefined() const {
+ return IsBeingDefined;
+ }
+
bool isEmbeddedInDeclarator() const {
return IsEmbeddedInDeclarator;
}
};
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);
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;
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.
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); }
}
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);
"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 {
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());