]> granicus.if.org Git - clang/commitdiff
Extend ObjCInterfaceDecl::DefinitionData to contain a pointer to the
authorDouglas Gregor <dgregor@apple.com>
Thu, 15 Dec 2011 18:17:27 +0000 (18:17 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 15 Dec 2011 18:17:27 +0000 (18:17 +0000)
definition, and implement ObjCInterfaceDecl::getDefinition()
efficiently based on that.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146669 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/DeclObjC.h
lib/AST/DeclObjC.cpp
lib/Serialization/ASTReaderDecl.cpp

index c172a92cb7c52d6e45e6fea7a4ec4177990fe28f..8fbee1f520c66f800c73a74bb0b94725b4877273 100644 (file)
@@ -548,6 +548,10 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
   friend class ASTContext;
   
   struct DefinitionData {
+    /// \brief The definition of this class, for quick access from any 
+    /// declaration.
+    ObjCInterfaceDecl *Definition;
+    
     /// Class's super class.
     ObjCInterfaceDecl *SuperClass;
 
@@ -574,7 +578,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
 
     SourceLocation SuperClassLoc; // location of the super class identifier.
     
-    DefinitionData() : SuperClass(), CategoryList(), IvarList(), 
+    DefinitionData() : Definition(), SuperClass(), CategoryList(), IvarList(), 
                        ExternallyCompleted() { }
   };
 
@@ -585,10 +589,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
 
   /// \brief Contains a pointer to the data associated with this class,
   /// which will be NULL if this class has not yet been defined.
-  ///
-  /// The boolean value indicates whether this particular declaration is 
-  /// also the definition.
-  llvm::PointerIntPair<DefinitionData *, 1, bool> Definition;
+  DefinitionData *Data;
 
   /// \brief The location of the last location in this declaration, e.g.,
   /// the '>', '}', or identifier.
@@ -602,8 +603,8 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
   bool InitiallyForwardDecl : 1;
 
   DefinitionData &data() const {
-    assert(Definition.getPointer() != 0 && "Declaration is not a definition!");
-    return *Definition.getPointer();
+    assert(Data != 0 && "Declaration has no definition!");
+    return *Data;
   }
 
   /// \brief Allocate the definition data for this class.
@@ -778,29 +779,30 @@ public:
     return InitiallyForwardDecl; 
   }
 
-  /// \brief Determine whether this declaration is a forward declaration of
-  /// the class.
-  bool isForwardDecl() const { return !Definition.getInt(); }
-
+  /// \brief Determine whether this class has only ever been forward-declared.
+  bool isForwardDecl() const { return Data == 0; }
+                          
   /// \brief Determine whether this particular declaration of this class is
   /// actually also a definition.
-  bool isThisDeclarationADefinition() const { return Definition.getInt(); }
+  bool isThisDeclarationADefinition() const { 
+    return Data == 0 || Data->Definition != this;
+  }
                           
   /// \brief Determine whether this class has been defined.
-  bool hasDefinition() const { return Definition.getPointer() != 0; }
+  bool hasDefinition() const { return Data; }
                         
   /// \brief Retrieve the definition of this class, or NULL if this class 
   /// has been forward-declared (with @class) but not yet defined (with 
   /// @interface).
   ObjCInterfaceDecl *getDefinition() {
-    return hasDefinition()? this : 0;
+    return hasDefinition()? Data->Definition : 0;
   }
 
   /// \brief Retrieve the definition of this class, or NULL if this class 
   /// has been forward-declared (with @class) but not yet defined (with 
   /// @interface).
   const ObjCInterfaceDecl *getDefinition() const {
-    return hasDefinition()? this : 0;
+    return hasDefinition()? Data->Definition : 0;
   }
 
   /// \brief Starts the definition of this Objective-C class, taking it from
index 1da0fab0ba4c671fce6be30eac959a2357cba1a3..e088c66229ba725e53bb6fc19ba54007c13aa1a7 100644 (file)
@@ -224,14 +224,14 @@ void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
 
 void ObjCInterfaceDecl::allocateDefinitionData() {
   assert(!hasDefinition() && "ObjC class already has a definition");
-  Definition.setPointer(new (getASTContext()) DefinitionData());
-  Definition.setInt(true);
+  Data = new (getASTContext()) DefinitionData();
+  Data->Definition = this;
   
   // Update all of the declarations with a pointer to the definition.
   for (redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
        RD != RDEnd; ++RD) {
     if (*RD != this)
-      RD->Definition.setPointer(Definition.getPointer());
+      RD->Data = Data;
   }
 }
 
@@ -684,7 +684,7 @@ ObjCInterfaceDecl::
 ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
                   SourceLocation CLoc, bool FD, bool isInternal)
   : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, atLoc),
-    TypeForDecl(0), Definition(), InitiallyForwardDecl(FD) 
+    TypeForDecl(0), Data(), InitiallyForwardDecl(FD) 
 {
   setImplicit(isInternal);
 }
index 6fc5764006c00810f26b501b2fca23478508c8e8..4dc960bdffbcbbcec2d549fbe9412541e11f42e2 100644 (file)
@@ -613,15 +613,15 @@ void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
       for (ASTReader::ForwardRefs::iterator I = Refs.begin(), 
                                             E = Refs.end(); 
            I != E; ++I)
-        cast<ObjCInterfaceDecl>(*I)->Definition = ID->Definition;
+        cast<ObjCInterfaceDecl>(*I)->Data = ID->Data;
 #ifndef NDEBUG
       // We later check whether PendingForwardRefs is empty to make sure all
       // pending references were linked.
       Reader.PendingForwardRefs.erase(ID);
 #endif
     } else if (Def) {
-      if (Def->Definition.getPointer()) {
-        ID->Definition.setPointer(Def->Definition.getPointer());
+      if (Def->Data) {
+        ID->Data = Def->Data;
       } else {
         // The definition is still initializing.
         Reader.PendingForwardRefs[Def].push_back(ID);
@@ -2072,8 +2072,8 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
       ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
       ObjCInterfaceDecl *Def
         = Reader.ReadDeclAs<ObjCInterfaceDecl>(ModuleFile, Record, Idx);
-      if (Def->Definition.getPointer()) {
-        ID->Definition.setPointer(Def->Definition.getPointer());
+      if (Def->Data) {
+        ID->Data = Def->Data;
       } else {
         // The definition is still initializing.
         Reader.PendingForwardRefs[Def].push_back(ID);