[cfe-commits] r147660 - in /cfe/trunk: include/clang/AST/Decl.h include/clang/AST/DeclBase.h lib/AST/DeclBase.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriterDecl.cpp

Douglas Gregor dgregor at apple.com
Fri Jan 6 08:59:54 PST 2012


Author: dgregor
Date: Fri Jan  6 10:59:53 2012
New Revision: 147660

URL: http://llvm.org/viewvc/llvm-project?rev=147660&view=rev
Log:
Stash Decl's TopLevelDeclInObjCContainer and ModulePrivate bits
into the two unused lower bits of the NextDeclInContext link, dropping
the number of bits in Decl down to 32, and saving 8 bytes per
declaration on x86-64.

Modified:
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/AST/DeclBase.h
    cfe/trunk/lib/AST/DeclBase.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=147660&r1=147659&r2=147660&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Fri Jan  6 10:59:53 2012
@@ -185,16 +185,9 @@
   /// \brief Determine whether this declaration has linkage.
   bool hasLinkage() const;
 
-  /// \brief Whether this declaration was marked as being private to the
-  /// module in which it was defined.
-  bool isModulePrivate() const { return ModulePrivate; }
-
-  /// \brief Specify whether this declaration was marked as being private
-  /// to the module in which it was defined.
-  void setModulePrivate(bool MP = true) {
-    ModulePrivate = MP;
-  }
-
+  using Decl::isModulePrivate;
+  using Decl::setModulePrivate;
+  
   /// \brief Determine whether this declaration is hidden from name lookup.
   bool isHidden() const { return Hidden; }
   

Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=147660&r1=147659&r2=147660&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Fri Jan  6 10:59:53 2012
@@ -180,12 +180,28 @@
     OBJC_TQ_Oneway = 0x20
   };
 
-private:
-  /// NextDeclInContext - The next declaration within the same lexical
+protected:
+  // Enumeration values used in the bits stored in NextInContextAndBits.
+  enum {
+    /// \brief Whether this declaration is a top-level declaration (function,
+    /// global variable, etc.) that is lexically inside an objc container
+    /// definition.
+    TopLevelDeclInObjCContainerFlag = 0x01,
+    
+    /// \brief Whether this declaration is private to the module in which it was
+    /// defined.
+    ModulePrivateFlag = 0x02
+  };
+  
+  /// \brief The next declaration within the same lexical
   /// DeclContext. These pointers form the linked list that is
   /// traversed via DeclContext's decls_begin()/decls_end().
-  Decl *NextDeclInContext;
+  ///
+  /// The extra two bits are used for the TopLevelDeclInObjCContainer and
+  /// ModulePrivate bits.
+  llvm::PointerIntPair<Decl *, 2, unsigned> NextInContextAndBits;
 
+private:
   friend class DeclContext;
 
   struct MultipleDC {
@@ -244,12 +260,6 @@
   /// are regarded as "referenced" but not "used".
   unsigned Referenced : 1;
 
-  /// \brief Whether this declaration is a top-level declaration (function,
-  /// global variable, etc.) that is lexically inside an objc container
-  /// definition.
-  /// FIXME: Consider setting the lexical context to the objc container.
-  unsigned TopLevelDeclInObjCContainer : 1;
-
 protected:
   /// Access - Used by C++ decls for the access specifier.
   // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
@@ -259,10 +269,6 @@
   /// \brief Whether this declaration was loaded from an AST file.
   unsigned FromASTFile : 1;
 
-  /// \brief Whether this declaration is private to the module in which it was
-  /// defined.
-  unsigned ModulePrivate : 1;
-
   /// \brief Whether this declaration is hidden from normal name lookup, e.g.,
   /// because it is was loaded from an AST file is either module-private or
   /// because its submodule has not been made visible.
@@ -291,11 +297,10 @@
 protected:
 
   Decl(Kind DK, DeclContext *DC, SourceLocation L)
-    : NextDeclInContext(0), DeclCtx(DC),
+    : NextInContextAndBits(), DeclCtx(DC),
       Loc(L), DeclKind(DK), InvalidDecl(0),
       HasAttrs(false), Implicit(false), Used(false), Referenced(false),
-      TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0),
-      ModulePrivate(0), Hidden(0),
+      Access(AS_none), FromASTFile(0), Hidden(0),
       IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
       HasCachedLinkage(0)
   {
@@ -303,10 +308,9 @@
   }
 
   Decl(Kind DK, EmptyShell Empty)
-    : NextDeclInContext(0), DeclKind(DK), InvalidDecl(0),
+    : NextInContextAndBits(), DeclKind(DK), InvalidDecl(0),
       HasAttrs(false), Implicit(false), Used(false), Referenced(false),
-      TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0),
-      ModulePrivate(0), Hidden(0),
+      Access(AS_none), FromASTFile(0), Hidden(0),
       IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
       HasCachedLinkage(0)
   {
@@ -342,8 +346,8 @@
   Kind getKind() const { return static_cast<Kind>(DeclKind); }
   const char *getDeclKindName() const;
 
-  Decl *getNextDeclInContext() { return NextDeclInContext; }
-  const Decl *getNextDeclInContext() const { return NextDeclInContext; }
+  Decl *getNextDeclInContext() { return NextInContextAndBits.getPointer(); }
+  const Decl *getNextDeclInContext() const {return NextInContextAndBits.getPointer();}
 
   DeclContext *getDeclContext() {
     if (isInSemaDC())
@@ -480,13 +484,38 @@
   /// global variable, etc.) that is lexically inside an objc container
   /// definition.
   bool isTopLevelDeclInObjCContainer() const {
-    return TopLevelDeclInObjCContainer;
+    return NextInContextAndBits.getInt() & TopLevelDeclInObjCContainerFlag;
   }
 
   void setTopLevelDeclInObjCContainer(bool V = true) {
-    TopLevelDeclInObjCContainer = V;
+    unsigned Bits = NextInContextAndBits.getInt();
+    if (V)
+      Bits |= TopLevelDeclInObjCContainerFlag;
+    else
+      Bits &= ~TopLevelDeclInObjCContainerFlag;
+    NextInContextAndBits.setInt(Bits);
+  }
+
+protected:
+  /// \brief Whether this declaration was marked as being private to the
+  /// module in which it was defined.
+  bool isModulePrivate() const { 
+    return NextInContextAndBits.getInt() & ModulePrivateFlag;
+  }
+  
+  /// \brief Specify whether this declaration was marked as being private
+  /// to the module in which it was defined.
+  void setModulePrivate(bool MP = true) {
+    unsigned Bits = NextInContextAndBits.getInt();
+    if (MP)
+      Bits |= ModulePrivateFlag;
+    else
+      Bits &= ~ModulePrivateFlag;
+    NextInContextAndBits.setInt(Bits);
   }
 
+public:
+  
   /// \brief Determine the availability of the given declaration.
   ///
   /// This routine will determine the most restrictive availability of
@@ -1396,7 +1425,8 @@
   /// \brief Determine whether the given declaration is stored in the list of
   /// declarations lexically within this context.
   bool isDeclInLexicalTraversal(const Decl *D) const {
-    return D && (D->NextDeclInContext || D == FirstDecl || D == LastDecl);
+    return D && (D->NextInContextAndBits.getPointer() || D == FirstDecl || 
+                 D == LastDecl);
   }
 
   static bool classof(const Decl *D);

Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=147660&r1=147659&r2=147660&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Fri Jan  6 10:59:53 2012
@@ -853,7 +853,7 @@
 std::pair<Decl *, Decl *>
 DeclContext::BuildDeclChain(const SmallVectorImpl<Decl*> &Decls,
                             bool FieldsAlreadyLoaded) {
-  // Build up a chain of declarations via the Decl::NextDeclInContext field.
+  // Build up a chain of declarations via the Decl::NextInContextAndBits field.
   Decl *FirstNewDecl = 0;
   Decl *PrevDecl = 0;
   for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
@@ -862,7 +862,7 @@
 
     Decl *D = Decls[I];
     if (PrevDecl)
-      PrevDecl->NextDeclInContext = D;
+      PrevDecl->NextInContextAndBits.setPointer(D);
     else
       FirstNewDecl = D;
 
@@ -908,7 +908,7 @@
   Decl *ExternalFirst, *ExternalLast;
   llvm::tie(ExternalFirst, ExternalLast) = BuildDeclChain(Decls,
                                                           FieldsAlreadyLoaded);
-  ExternalLast->NextDeclInContext = FirstDecl;
+  ExternalLast->NextInContextAndBits.setPointer(FirstDecl);
   FirstDecl = ExternalFirst;
   if (!LastDecl)
     LastDecl = ExternalLast;
@@ -983,7 +983,7 @@
 void DeclContext::removeDecl(Decl *D) {
   assert(D->getLexicalDeclContext() == this &&
          "decl being removed from non-lexical context");
-  assert((D->NextDeclInContext || D == LastDecl) &&
+  assert((D->NextInContextAndBits.getPointer() || D == LastDecl) &&
          "decl is not in decls list");
 
   // Remove D from the decl chain.  This is O(n) but hopefully rare.
@@ -991,12 +991,12 @@
     if (D == LastDecl)
       FirstDecl = LastDecl = 0;
     else
-      FirstDecl = D->NextDeclInContext;
+      FirstDecl = D->NextInContextAndBits.getPointer();
   } else {
-    for (Decl *I = FirstDecl; true; I = I->NextDeclInContext) {
+    for (Decl *I = FirstDecl; true; I = I->NextInContextAndBits.getPointer()) {
       assert(I && "decl not found in linked list");
-      if (I->NextDeclInContext == D) {
-        I->NextDeclInContext = D->NextDeclInContext;
+      if (I->NextInContextAndBits.getPointer() == D) {
+        I->NextInContextAndBits.setPointer(D->NextInContextAndBits.getPointer());
         if (D == LastDecl) LastDecl = I;
         break;
       }
@@ -1004,7 +1004,7 @@
   }
   
   // Mark that D is no longer in the decl chain.
-  D->NextDeclInContext = 0;
+  D->NextInContextAndBits.setPointer(0);
 
   // Remove D from the lookup table if necessary.
   if (isa<NamedDecl>(D)) {
@@ -1030,7 +1030,7 @@
          "Decl already inserted into a DeclContext");
 
   if (FirstDecl) {
-    LastDecl->NextDeclInContext = D;
+    LastDecl->NextInContextAndBits.setPointer(D);
     LastDecl = D;
   } else {
     FirstDecl = LastDecl = D;

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=147660&r1=147659&r2=147660&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Fri Jan  6 10:59:53 2012
@@ -360,17 +360,17 @@
   D->setImplicit(Record[Idx++]);
   D->setUsed(Record[Idx++]);
   D->setReferenced(Record[Idx++]);
-  D->TopLevelDeclInObjCContainer = Record[Idx++];
+  D->setTopLevelDeclInObjCContainer(Record[Idx++]);
   D->setAccess((AccessSpecifier)Record[Idx++]);
   D->FromASTFile = true;
-  D->ModulePrivate = Record[Idx++];
-  D->Hidden = D->ModulePrivate;
+  D->setModulePrivate(Record[Idx++]);
+  D->Hidden = D->isModulePrivate();
   
   // Determine whether this declaration is part of a (sub)module. If so, it
   // may not yet be visible.
   if (unsigned SubmoduleID = readSubmoduleID(Record, Idx)) {
     // Module-private declarations are never visible, so there is no work to do.
-    if (!D->ModulePrivate) {
+    if (!D->isModulePrivate()) {
       if (Module *Owner = Reader.getSubmodule(SubmoduleID)) {
         if (Owner->NameVisibility != Module::AllVisible) {
           // The owning module is not visible. Mark this declaration as hidden.

Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=147660&r1=147659&r2=147660&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Fri Jan  6 10:59:53 2012
@@ -154,9 +154,9 @@
   Record.push_back(D->isImplicit());
   Record.push_back(D->isUsed(false));
   Record.push_back(D->isReferenced());
-  Record.push_back(D->TopLevelDeclInObjCContainer);
+  Record.push_back(D->isTopLevelDeclInObjCContainer());
   Record.push_back(D->getAccess());
-  Record.push_back(D->ModulePrivate);
+  Record.push_back(D->isModulePrivate());
   Record.push_back(Writer.inferSubmoduleIDFromLocation(D->getLocation()));
 }
 





More information about the cfe-commits mailing list