[cfe-commits] r110051 - in /cfe/trunk: include/clang/AST/Decl.h include/clang/AST/Type.h lib/AST/Decl.cpp lib/AST/Type.cpp

Sebastian Redl sebastian.redl at getdesigned.at
Mon Aug 2 11:27:06 PDT 2010


Author: cornedbee
Date: Mon Aug  2 13:27:05 2010
New Revision: 110051

URL: http://llvm.org/viewvc/llvm-project?rev=110051&view=rev
Log:
Remove mutable data on TagType and InjectedClassNameType, by instead walking the declaration chain in search of a definition. This is necessary for a sane chained PCH implementation. No observable performance change on Carbon.h syntax-only, and bootstraps cleanly.

Modified:
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/Type.cpp

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=110051&r1=110050&r2=110051&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Mon Aug  2 13:27:05 2010
@@ -1814,6 +1814,9 @@
   /// 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 @@
            "EnumDecl not matched with TTK_Enum");
     TagDeclKind = TK;
     IsDefinition = false;
+    IsBeingDefined = false;
     IsEmbeddedInDeclarator = false;
     setPreviousDeclaration(PrevDecl);
   }
@@ -1896,6 +1900,11 @@
     return IsDefinition;
   }
 
+  /// isBeingDefined - Return true if this decl is currently being defined.
+  bool isBeingDefined() const {
+    return IsBeingDefined;
+  }
+
   bool isEmbeddedInDeclarator() const {
     return IsEmbeddedInDeclarator;
   }

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=110051&r1=110050&r2=110051&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Mon Aug  2 13:27:05 2010
@@ -2267,14 +2267,9 @@
 };
 
 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 @@
   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 @@
   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 @@
     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); }

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=110051&r1=110050&r2=110051&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Mon Aug  2 13:27:05 2010
@@ -1534,14 +1534,7 @@
 }
 
 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 @@
          "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 {

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=110051&r1=110050&r2=110051&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Mon Aug  2 13:27:05 2010
@@ -1072,7 +1072,30 @@
 
 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());





More information about the cfe-commits mailing list