[cfe-commits] r111636 - in /cfe/trunk: include/clang/AST/DeclContextInternals.h include/clang/AST/ExternalASTSource.h include/clang/Serialization/ASTReader.h include/clang/Serialization/ASTWriter.h lib/AST/DeclBase.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriter.cpp lib/Serialization/ASTWriterDecl.cpp

Argyrios Kyrtzidis akyrtzi at gmail.com
Fri Aug 20 09:04:35 PDT 2010


Author: akirtzidis
Date: Fri Aug 20 11:04:35 2010
New Revision: 111636

URL: http://llvm.org/viewvc/llvm-project?rev=111636&view=rev
Log:
Use the AST on-disk hash table for name lookup inside a DeclContext.

*Huge* improvement over the amount of deserializing that we do for C++ lookup.
e.g, if he have the Carbon header precompiled and include it on a file containing this:

int x;

these are the before/after stats:

BEFORE:

*** AST File Statistics:
  578 stat cache hits
  4 stat cache misses
  548/30654 source location entries read (1.787695%)
  15907/16501 types read (96.400223%)
  53525/59955 declarations read (89.275291%)
  33993/43525 identifiers read (78.099945%)
  41516/51891 statements read (80.006165%)
  77/5317 macros read (1.448185%)
  0/6335 lexical declcontexts read (0.000000%)
  1/5424 visible declcontexts read (0.018437%)

AFTER using the on-disk table:

*** AST File Statistics:
  578 stat cache hits
  4 stat cache misses
  548/30654 source location entries read (1.787695%)
  10/16501 types read (0.060602%)
  9/59955 declarations read (0.015011%)
  161/43525 identifiers read (0.369902%)
  20/51891 statements read (0.038542%)
  6/5317 macros read (0.112846%)
  0/6335 lexical declcontexts read (0.000000%)
  2/5424 visible declcontexts read (0.036873%)

There's only one issue affecting mostly the precompiled preambles which I will address soon.

Modified:
    cfe/trunk/include/clang/AST/DeclContextInternals.h
    cfe/trunk/include/clang/AST/ExternalASTSource.h
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/include/clang/Serialization/ASTWriter.h
    cfe/trunk/lib/AST/DeclBase.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp

Modified: cfe/trunk/include/clang/AST/DeclContextInternals.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclContextInternals.h?rev=111636&r1=111635&r2=111636&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclContextInternals.h (original)
+++ cfe/trunk/include/clang/AST/DeclContextInternals.h Fri Aug 20 11:04:35 2010
@@ -29,108 +29,54 @@
 /// StoredDeclsList - This is an array of decls optimized a common case of only
 /// containing one entry.
 struct StoredDeclsList {
-  /// The kind of data encoded in this list.
-  enum DataKind {
-    /// \brief The data is a NamedDecl*.
-    DK_Decl = 0,
-    /// \brief The data is a declaration ID (an unsigned value),
-    /// shifted left by 2 bits.
-    DK_DeclID = 1,
-    /// \brief The data is a pointer to a vector (of type VectorTy)
-    /// that contains declarations.
-    DK_Decl_Vector = 2,
-    /// \brief The data is a pointer to a vector (of type VectorTy)
-    /// that contains declaration ID.
-    DK_ID_Vector = 3
-  };
-
-  /// VectorTy - When in vector form, this is what the Data pointer points to.
-  typedef llvm::SmallVector<uintptr_t, 4> VectorTy;
-
-  /// \brief The stored data, which will be either a declaration ID, a
-  /// pointer to a NamedDecl, or a pointer to a vector.
-  uintptr_t Data;
+
+  /// DeclsTy - When in vector form, this is what the Data pointer points to.
+  typedef llvm::SmallVector<NamedDecl *, 4> DeclsTy;
+
+  /// \brief The stored data, which will be either a pointer to a NamedDecl,
+  /// or a pointer to a vector.
+  llvm::PointerUnion<NamedDecl *, DeclsTy *> Data;
 
 public:
-  StoredDeclsList() : Data(0) {}
+  StoredDeclsList() {}
 
   StoredDeclsList(const StoredDeclsList &RHS) : Data(RHS.Data) {
-    if (VectorTy *RHSVec = RHS.getAsVector()) {
-      VectorTy *New = new VectorTy(*RHSVec);
-      Data = reinterpret_cast<uintptr_t>(New) | (Data & 0x03);
-    }
+    if (DeclsTy *RHSVec = RHS.getAsVector())
+      Data = new DeclsTy(*RHSVec);
   }
 
   ~StoredDeclsList() {
     // If this is a vector-form, free the vector.
-    if (VectorTy *Vector = getAsVector())
+    if (DeclsTy *Vector = getAsVector())
       delete Vector;
   }
 
   StoredDeclsList &operator=(const StoredDeclsList &RHS) {
-    if (VectorTy *Vector = getAsVector())
+    if (DeclsTy *Vector = getAsVector())
       delete Vector;
     Data = RHS.Data;
-    if (VectorTy *RHSVec = RHS.getAsVector()) {
-      VectorTy *New = new VectorTy(*RHSVec);
-      Data = reinterpret_cast<uintptr_t>(New) | (Data & 0x03);
-    }
+    if (DeclsTy *RHSVec = RHS.getAsVector())
+      Data = new DeclsTy(*RHSVec);
     return *this;
   }
 
-  bool isNull() const { return (Data & ~0x03) == 0; }
+  bool isNull() const { return Data.isNull(); }
 
   NamedDecl *getAsDecl() const {
-    if ((Data & 0x03) != DK_Decl)
-      return 0;
-
-    return reinterpret_cast<NamedDecl *>(Data & ~0x03);
+    return Data.dyn_cast<NamedDecl *>();
   }
 
-  VectorTy *getAsVector() const {
-    if ((Data & 0x03) != DK_ID_Vector && (Data & 0x03) != DK_Decl_Vector)
-      return 0;
-
-    return reinterpret_cast<VectorTy *>(Data & ~0x03);
+  DeclsTy *getAsVector() const {
+    return Data.dyn_cast<DeclsTy *>();
   }
 
   void setOnlyValue(NamedDecl *ND) {
     assert(!getAsVector() && "Not inline");
-    Data = reinterpret_cast<uintptr_t>(ND);
-  }
-
-  void setFromDeclIDs(const llvm::SmallVectorImpl<unsigned> &Vec) {
-    if (Vec.size() > 1) {
-      VectorTy *Vector = getAsVector();
-      if (!Vector) {
-        Vector = new VectorTy;
-        Data = reinterpret_cast<uintptr_t>(Vector) | DK_ID_Vector;
-      }
-
-      Vector->resize(Vec.size());
-      std::copy(Vec.begin(), Vec.end(), Vector->begin());
-      return;
-    }
-
-    if (VectorTy *Vector = getAsVector())
-      delete Vector;
-
-    if (Vec.empty())
-      Data = 0;
-    else
-      Data = (Vec[0] << 2) | DK_DeclID;
-  }
-
-  /// \brief Force the stored declarations list to contain actual
-  /// declarations.
-  ///
-  /// This routine will resolve any declaration IDs for declarations
-  /// that may not yet have been loaded from external storage.
-  void materializeDecls(ASTContext &Context);
-
-  bool hasDeclarationIDs() const {
-    DataKind DK = (DataKind)(Data & 0x03);
-    return DK == DK_DeclID || DK == DK_ID_Vector;
+    Data = ND;
+    // Make sure that Data is a plain NamedDecl* so we can use its address
+    // at getLookupResult.
+    assert(*(NamedDecl **)&Data == ND &&
+           "PointerUnion mangles the NamedDecl pointer!");
   }
 
   void remove(NamedDecl *D) {
@@ -138,30 +84,26 @@
     if (NamedDecl *Singleton = getAsDecl()) {
       assert(Singleton == D && "list is different singleton");
       (void)Singleton;
-      Data = 0;
+      Data = (NamedDecl *)0;
       return;
     }
 
-    VectorTy &Vec = *getAsVector();
-    VectorTy::iterator I = std::find(Vec.begin(), Vec.end(),
-                                     reinterpret_cast<uintptr_t>(D));
+    DeclsTy &Vec = *getAsVector();
+    DeclsTy::iterator I = std::find(Vec.begin(), Vec.end(), D);
     assert(I != Vec.end() && "list does not contain decl");
     Vec.erase(I);
 
-    assert(std::find(Vec.begin(), Vec.end(), reinterpret_cast<uintptr_t>(D))
+    assert(std::find(Vec.begin(), Vec.end(), D)
              == Vec.end() && "list still contains decl");
   }
 
   /// getLookupResult - Return an array of all the decls that this list
   /// represents.
-  DeclContext::lookup_result getLookupResult(ASTContext &Context) {
+  DeclContext::lookup_result getLookupResult() {
     if (isNull())
       return DeclContext::lookup_result(DeclContext::lookup_iterator(0),
                                         DeclContext::lookup_iterator(0));
 
-    if (hasDeclarationIDs())
-      materializeDecls(Context);
-
     // If we have a single NamedDecl, return it.
     if (getAsDecl()) {
       assert(!isNull() && "Empty list isn't allowed");
@@ -172,19 +114,15 @@
     }
 
     assert(getAsVector() && "Must have a vector at this point");
-    VectorTy &Vector = *getAsVector();
+    DeclsTy &Vector = *getAsVector();
 
     // Otherwise, we have a range result.
-    return DeclContext::lookup_result((NamedDecl **)&Vector[0],
-                                      (NamedDecl **)&Vector[0]+Vector.size());
+    return DeclContext::lookup_result(&Vector[0], &Vector[0]+Vector.size());
   }
 
   /// HandleRedeclaration - If this is a redeclaration of an existing decl,
   /// replace the old one with D and return true.  Otherwise return false.
-  bool HandleRedeclaration(ASTContext &Context, NamedDecl *D) {
-    if (hasDeclarationIDs())
-      materializeDecls(Context);
-
+  bool HandleRedeclaration(NamedDecl *D) {
     // Most decls only have one entry in their list, special case it.
     if (NamedDecl *OldD = getAsDecl()) {
       if (!D->declarationReplaces(OldD))
@@ -194,12 +132,12 @@
     }
 
     // Determine if this declaration is actually a redeclaration.
-    VectorTy &Vec = *getAsVector();
-    for (VectorTy::iterator OD = Vec.begin(), ODEnd = Vec.end();
+    DeclsTy &Vec = *getAsVector();
+    for (DeclsTy::iterator OD = Vec.begin(), ODEnd = Vec.end();
          OD != ODEnd; ++OD) {
-      NamedDecl *OldD = reinterpret_cast<NamedDecl *>(*OD);
+      NamedDecl *OldD = *OD;
       if (D->declarationReplaces(OldD)) {
-        *OD = reinterpret_cast<uintptr_t>(D);
+        *OD = D;
         return true;
       }
     }
@@ -211,17 +149,15 @@
   /// not a redeclaration to merge it into the appropriate place in our list.
   ///
   void AddSubsequentDecl(NamedDecl *D) {
-    assert(!hasDeclarationIDs() && "Must materialize before adding decls");
-
     // If this is the second decl added to the list, convert this to vector
     // form.
     if (NamedDecl *OldD = getAsDecl()) {
-      VectorTy *VT = new VectorTy();
-      VT->push_back(reinterpret_cast<uintptr_t>(OldD));
-      Data = reinterpret_cast<uintptr_t>(VT) | DK_Decl_Vector;
+      DeclsTy *VT = new DeclsTy();
+      VT->push_back(OldD);
+      Data = VT;
     }
 
-    VectorTy &Vec = *getAsVector();
+    DeclsTy &Vec = *getAsVector();
 
     // Using directives end up in a special entry which contains only
     // other using directives, so all this logic is wasted for them.
@@ -232,32 +168,30 @@
     // iterator which points at the first tag will start a span of
     // decls that only contains tags.
     if (D->hasTagIdentifierNamespace())
-      Vec.push_back(reinterpret_cast<uintptr_t>(D));
+      Vec.push_back(D);
 
     // Resolved using declarations go at the front of the list so that
     // they won't show up in other lookup results.  Unresolved using
     // declarations (which are always in IDNS_Using | IDNS_Ordinary)
     // follow that so that the using declarations will be contiguous.
     else if (D->getIdentifierNamespace() & Decl::IDNS_Using) {
-      VectorTy::iterator I = Vec.begin();
+      DeclsTy::iterator I = Vec.begin();
       if (D->getIdentifierNamespace() != Decl::IDNS_Using) {
         while (I != Vec.end() &&
-               reinterpret_cast<NamedDecl *>(*I)
-                 ->getIdentifierNamespace() == Decl::IDNS_Using)
+               (*I)->getIdentifierNamespace() == Decl::IDNS_Using)
           ++I;
       }
-      Vec.insert(I, reinterpret_cast<uintptr_t>(D));
+      Vec.insert(I, D);
 
     // All other declarations go at the end of the list, but before any
     // tag declarations.  But we can be clever about tag declarations
     // because there can only ever be one in a scope.
-    } else if (reinterpret_cast<NamedDecl *>(Vec.back())
-                 ->hasTagIdentifierNamespace()) {
-      uintptr_t TagD = Vec.back();
-      Vec.back() = reinterpret_cast<uintptr_t>(D);
+    } else if (Vec.back()->hasTagIdentifierNamespace()) {
+      NamedDecl *TagD = Vec.back();
+      Vec.back() = D;
       Vec.push_back(TagD);
     } else
-      Vec.push_back(reinterpret_cast<uintptr_t>(D));
+      Vec.push_back(D);
   }
 };
 

Modified: cfe/trunk/include/clang/AST/ExternalASTSource.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExternalASTSource.h?rev=111636&r1=111635&r2=111636&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExternalASTSource.h (original)
+++ cfe/trunk/include/clang/AST/ExternalASTSource.h Fri Aug 20 11:04:35 2010
@@ -27,18 +27,6 @@
 class ExternalSemaSource; // layering violation required for downcasting
 class Stmt;
 
-/// \brief The deserialized representation of a set of declarations
-/// with the same name that are visible in a given context.
-struct VisibleDeclaration {
-  /// \brief The name of the declarations.
-  DeclarationName Name;
-
-  /// \brief The ID numbers of all of the declarations with this name.
-  ///
-  /// These declarations have not necessarily been de-serialized.
-  llvm::SmallVector<unsigned, 4> Declarations;
-};
-
 /// \brief Abstract interface for external sources of AST nodes.
 ///
 /// External AST sources provide AST nodes constructed from some
@@ -140,22 +128,6 @@
   virtual void PrintStats();
 
 protected:
-  /// \brief Initialize the context's lookup map with the given decls.
-  /// It is assumed that none of the declarations are redeclarations of
-  /// each other.
-  static void SetExternalVisibleDecls(const DeclContext *DC,
-                  const llvm::SmallVectorImpl<VisibleDeclaration> &Decls);
-
-  /// \brief Initialize the context's lookup map with the given decls.
-  /// It is assumed that none of the declarations are redeclarations of
-  /// each other.
-  static void SetExternalVisibleDecls(const DeclContext *DC,
-                              const llvm::SmallVectorImpl<NamedDecl*> &Decls);
-
-  static DeclContext::lookup_result
-  SetExternalVisibleDeclsForName(const DeclContext *DC,
-                                 const VisibleDeclaration &VD);
-
   static DeclContext::lookup_result
   SetExternalVisibleDeclsForName(const DeclContext *DC,
                                  DeclarationName Name,

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=111636&r1=111635&r2=111636&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Fri Aug 20 11:04:35 2010
@@ -339,8 +339,7 @@
 
   /// \brief Information about the contents of a DeclContext.
   struct DeclContextInfo {
-    llvm::BitstreamCursor *Stream;
-    uint64_t OffsetToVisibleDecls;
+    void *NameLookupTableData; // a ASTDeclContextNameLookupTable.
     const serialization::DeclID *LexicalDecls;
     unsigned NumLexicalDecls;
   };

Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=111636&r1=111635&r2=111636&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTWriter.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTWriter.h Fri Aug 20 11:04:35 2010
@@ -268,6 +268,7 @@
 
   unsigned ParmVarDeclAbbrev;
   unsigned DeclContextLexicalAbbrev;
+  unsigned DeclContextVisibleLookupAbbrev;
   void WriteDeclsBlockAbbrevs();
   void WriteDecl(ASTContext &Context, Decl *D);
 

Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=111636&r1=111635&r2=111636&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Fri Aug 20 11:04:35 2010
@@ -648,19 +648,6 @@
 
 DeclContext::lookup_result
 ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC,
-                                          const VisibleDeclaration &VD) {
-  ASTContext &Context = DC->getParentASTContext();
-  StoredDeclsMap *Map;
-  if (!(Map = DC->LookupPtr))
-    Map = DC->CreateStoredDeclsMap(Context);
-
-  StoredDeclsList &List = (*Map)[VD.Name];
-  List.setFromDeclIDs(VD.Declarations);
-  return List.getLookupResult(Context);
-}
-
-DeclContext::lookup_result
-ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC,
                                                   DeclarationName Name,
                                     llvm::SmallVectorImpl<NamedDecl*> &Decls) {
   ASTContext &Context = DC->getParentASTContext();;
@@ -677,35 +664,7 @@
       List.AddSubsequentDecl(Decls[I]);
   }
 
-  return List.getLookupResult(Context);
-}
-
-void ExternalASTSource::SetExternalVisibleDecls(const DeclContext *DC,
-                    const llvm::SmallVectorImpl<VisibleDeclaration> &Decls) {
-  // There is no longer any visible storage in this context.
-  DC->ExternalVisibleStorage = false;
-
-  assert(!DC->LookupPtr && "Have a lookup map before de-serialization?");
-  StoredDeclsMap *Map = DC->CreateStoredDeclsMap(DC->getParentASTContext());
-  for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
-    (*Map)[Decls[I].Name].setFromDeclIDs(Decls[I].Declarations);
-  }
-}
-
-void ExternalASTSource::SetExternalVisibleDecls(const DeclContext *DC,
-                            const llvm::SmallVectorImpl<NamedDecl*> &Decls) {
-  // There is no longer any visible storage in this context.
-  DC->ExternalVisibleStorage = false;
-
-  assert(!DC->LookupPtr && "Have a lookup map before de-serialization?");
-  StoredDeclsMap &Map = *DC->CreateStoredDeclsMap(DC->getParentASTContext());
-  for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
-    StoredDeclsList &List = Map[Decls[I]->getDeclName()];
-    if (List.isNull())
-      List.setOnlyValue(Decls[I]);
-    else
-      List.AddSubsequentDecl(Decls[I]);
-  }
+  return List.getLookupResult();
 }
 
 DeclContext::decl_iterator DeclContext::noload_decls_begin() const {
@@ -841,7 +800,7 @@
     if (LookupPtr) {
       StoredDeclsMap::iterator I = LookupPtr->find(Name);
       if (I != LookupPtr->end())
-        return I->second.getLookupResult(getParentASTContext());
+        return I->second.getLookupResult();
     }
 
     ExternalASTSource *Source = getParentASTContext().getExternalSource();
@@ -861,7 +820,7 @@
   StoredDeclsMap::iterator Pos = LookupPtr->find(Name);
   if (Pos == LookupPtr->end())
     return lookup_result(lookup_iterator(0), lookup_iterator(0));
-  return Pos->second.getLookupResult(getParentASTContext());
+  return Pos->second.getLookupResult();
 }
 
 DeclContext::lookup_const_result
@@ -925,18 +884,21 @@
   if (isa<ClassTemplateSpecializationDecl>(D))
     return;
 
-  // If there is an external AST source, load any declarations it knows about
-  // with this declaration's name.
-  if (ExternalASTSource *Source = getParentASTContext().getExternalSource())
-    if (hasExternalVisibleStorage())
-      Source->FindExternalVisibleDeclsByName(this, D->getDeclName());
-
   ASTContext *C = 0;
   if (!LookupPtr) {
     C = &getParentASTContext();
     CreateStoredDeclsMap(*C);
   }
 
+  // If there is an external AST source, load any declarations it knows about
+  // with this declaration's name.
+  // If the lookup table contains an entry about this name it means that we
+  // have already checked the external source.
+  if (ExternalASTSource *Source = getParentASTContext().getExternalSource())
+    if (hasExternalVisibleStorage() &&
+        LookupPtr->find(D->getDeclName()) == LookupPtr->end())
+      Source->FindExternalVisibleDeclsByName(this, D->getDeclName());
+
   // Insert this declaration into the map.
   StoredDeclsList &DeclNameEntries = (*LookupPtr)[D->getDeclName()];
   if (DeclNameEntries.isNull()) {
@@ -947,10 +909,7 @@
   // If it is possible that this is a redeclaration, check to see if there is
   // already a decl for which declarationReplaces returns true.  If there is
   // one, just replace it and return.
-  if (!C)
-    C = &getParentASTContext();
-  
-  if (DeclNameEntries.HandleRedeclaration(*C, D))
+  if (DeclNameEntries.HandleRedeclaration(D))
     return;
 
   // Put this declaration into the appropriate slot.
@@ -966,43 +925,6 @@
                              reinterpret_cast<udir_iterator>(Result.second));
 }
 
-void StoredDeclsList::materializeDecls(ASTContext &Context) {
-  if (isNull())
-    return;
-
-  switch ((DataKind)(Data & 0x03)) {
-  case DK_Decl:
-  case DK_Decl_Vector:
-    break;
-
-  case DK_DeclID: {
-    // Resolve this declaration ID to an actual declaration by
-    // querying the external AST source.
-    unsigned DeclID = Data >> 2;
-
-    ExternalASTSource *Source = Context.getExternalSource();
-    assert(Source && "No external AST source available!");
-
-    Data = reinterpret_cast<uintptr_t>(Source->GetExternalDecl(DeclID));
-    break;
-  }
-
-  case DK_ID_Vector: {
-    // We have a vector of declaration IDs. Resolve all of them to
-    // actual declarations.
-    VectorTy &Vector = *getAsVector();
-    ExternalASTSource *Source = Context.getExternalSource();
-    assert(Source && "No external AST source available!");
-
-    for (unsigned I = 0, N = Vector.size(); I != N; ++I)
-      Vector[I] = reinterpret_cast<uintptr_t>(Source->GetExternalDecl(Vector[I]));
-
-    Data = (Data & ~0x03) | DK_Decl_Vector;
-    break;
-  }
-  }
-}
-
 //===----------------------------------------------------------------------===//
 // Creation and Destruction of StoredDeclsMaps.                               //
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=111636&r1=111635&r2=111636&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Fri Aug 20 11:04:35 2010
@@ -846,6 +846,54 @@
 typedef OnDiskChainedHashTable<ASTDeclContextNameLookupTrait>
   ASTDeclContextNameLookupTable;
 
+bool ASTReader::ReadDeclContextStorage(llvm::BitstreamCursor &Cursor,
+                                   const std::pair<uint64_t, uint64_t> &Offsets,
+                                       DeclContextInfo &Info) {
+  SavedStreamPosition SavedPosition(Cursor);
+  // First the lexical decls.
+  if (Offsets.first != 0) {
+    Cursor.JumpToBit(Offsets.first);
+
+    RecordData Record;
+    const char *Blob;
+    unsigned BlobLen;
+    unsigned Code = Cursor.ReadCode();
+    unsigned RecCode = Cursor.ReadRecord(Code, Record, &Blob, &BlobLen);
+    if (RecCode != DECL_CONTEXT_LEXICAL) {
+      Error("Expected lexical block");
+      return true;
+    }
+
+    Info.LexicalDecls = reinterpret_cast<const DeclID*>(Blob);
+    Info.NumLexicalDecls = BlobLen / sizeof(DeclID);
+  } else {
+    Info.LexicalDecls = 0;
+    Info.NumLexicalDecls = 0;
+  }
+
+  // Now the lookup table.
+  if (Offsets.second != 0) {
+    Cursor.JumpToBit(Offsets.second);
+
+    RecordData Record;
+    const char *Blob;
+    unsigned BlobLen;
+    unsigned Code = Cursor.ReadCode();
+    unsigned RecCode = Cursor.ReadRecord(Code, Record, &Blob, &BlobLen);
+    if (RecCode != DECL_CONTEXT_VISIBLE) {
+      Error("Expected visible lookup table block");
+      return true;
+    }
+    Info.NameLookupTableData
+      = ASTDeclContextNameLookupTable::Create(
+                    (const unsigned char *)Blob + Record[0],
+                    (const unsigned char *)Blob,
+                    ASTDeclContextNameLookupTrait(*this));
+  }
+
+  return false;
+}
+
 void ASTReader::Error(const char *Msg) {
   Diag(diag::err_fe_pch_malformed) << Msg;
 }
@@ -1674,7 +1722,7 @@
 
     case TU_UPDATE_LEXICAL: {
       DeclContextInfo Info = {
-        /* No visible information */ 0, 0,
+        /* No visible information */ 0,
         reinterpret_cast<const DeclID *>(BlobStart),
         BlobLen / sizeof(DeclID)
       };
@@ -3119,54 +3167,33 @@
                                           DeclarationName Name) {
   assert(DC->hasExternalVisibleStorage() &&
          "DeclContext has no visible decls in storage");
+  if (!Name)
+    return DeclContext::lookup_result(DeclContext::lookup_iterator(0),
+                                      DeclContext::lookup_iterator(0));
 
-  llvm::SmallVector<VisibleDeclaration, 64> Decls;
+  llvm::SmallVector<NamedDecl *, 64> Decls;
   // There might be lexical decls in multiple parts of the chain, for the TU
   // and namespaces.
   DeclContextInfos &Infos = DeclContextOffsets[DC];
   for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end();
        I != E; ++I) {
-    uint64_t Offset = I->OffsetToVisibleDecls;
-    if (Offset == 0)
+    if (!I->NameLookupTableData)
       continue;
 
-    llvm::BitstreamCursor &DeclsCursor = *I->Stream;
-
-    // Keep track of where we are in the stream, then jump back there
-    // after reading this context.
-    SavedStreamPosition SavedPosition(DeclsCursor);
-
-    // Load the record containing all of the declarations visible in
-    // this context.
-    DeclsCursor.JumpToBit(Offset);
-    RecordData Record;
-    unsigned Code = DeclsCursor.ReadCode();
-    unsigned RecCode = DeclsCursor.ReadRecord(Code, Record);
-    if (RecCode != DECL_CONTEXT_VISIBLE) {
-      Error("Expected visible block");
-      return DeclContext::lookup_result(DeclContext::lookup_iterator(),
-                                        DeclContext::lookup_iterator());
-    }
-
-    if (Record.empty())
+    ASTDeclContextNameLookupTable *LookupTable =
+        (ASTDeclContextNameLookupTable*)I->NameLookupTableData;
+    ASTDeclContextNameLookupTable::iterator Pos = LookupTable->find(Name);
+    if (Pos == LookupTable->end())
       continue;
 
-    unsigned Idx = 0;
-    while (Idx < Record.size()) {
-      Decls.push_back(VisibleDeclaration());
-      Decls.back().Name = ReadDeclarationName(Record, Idx);
-
-      unsigned Size = Record[Idx++];
-      llvm::SmallVector<unsigned, 4> &LoadedDecls = Decls.back().Declarations;
-      LoadedDecls.reserve(Size);
-      for (unsigned J = 0; J < Size; ++J)
-        LoadedDecls.push_back(Record[Idx++]);
-    }
+    ASTDeclContextNameLookupTrait::data_type Data = *Pos;
+    for (; Data.first != Data.second; ++Data.first)
+      Decls.push_back(cast<NamedDecl>(GetDecl(*Data.first)));
   }
 
   ++NumVisibleDeclContextsRead;
 
-  SetExternalVisibleDecls(DC, Decls);
+  SetExternalVisibleDeclsForName(DC, Name, Decls);
   return const_cast<DeclContext*>(DC)->lookup(Name);
 }
 

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=111636&r1=111635&r2=111636&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Fri Aug 20 11:04:35 2010
@@ -1413,35 +1413,3 @@
 
   return D;
 }
-
-bool ASTReader::ReadDeclContextStorage(llvm::BitstreamCursor &Cursor,
-                                   const std::pair<uint64_t, uint64_t> &Offsets,
-                                       DeclContextInfo &Info) {
-  SavedStreamPosition SavedPosition(Cursor);
-  // First the lexical decls.
-  if (Offsets.first != 0) {
-    Cursor.JumpToBit(Offsets.first);
-
-    RecordData Record;
-    const char *Blob;
-    unsigned BlobLen;
-    unsigned Code = Cursor.ReadCode();
-    unsigned RecCode = Cursor.ReadRecord(Code, Record, &Blob, &BlobLen);
-    if (RecCode != DECL_CONTEXT_LEXICAL) {
-      Error("Expected lexical block");
-      return true;
-    }
-
-    Info.LexicalDecls = reinterpret_cast<const DeclID*>(Blob);
-    Info.NumLexicalDecls = BlobLen / sizeof(DeclID);
-  } else {
-    Info.LexicalDecls = 0;
-    Info.NumLexicalDecls = 0;
-  }
-
-  // Now the visible decls.
-  Info.Stream = &Cursor;
-  Info.OffsetToVisibleDecls = Offsets.second;
-
-  return false;
-}

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=111636&r1=111635&r2=111636&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Fri Aug 20 11:04:35 2010
@@ -1466,59 +1466,6 @@
   return Offset;
 }
 
-/// \brief Write the block containing all of the declaration IDs
-/// visible from the given DeclContext.
-///
-/// \returns the offset of the DECL_CONTEXT_VISIBLE block within the
-/// bistream, or 0 if no block was written.
-uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
-                                                 DeclContext *DC) {
-  if (DC->getPrimaryContext() != DC)
-    return 0;
-
-  // Since there is no name lookup into functions or methods, don't bother to
-  // build a visible-declarations table for these entities.
-  if (DC->isFunctionOrMethod())
-    return 0;
-
-  // If not in C++, we perform name lookup for the translation unit via the
-  // IdentifierInfo chains, don't bother to build a visible-declarations table.
-  // FIXME: In C++ we need the visible declarations in order to "see" the
-  // friend declarations, is there a way to do this without writing the table ?
-  if (DC->isTranslationUnit() && !Context.getLangOptions().CPlusPlus)
-    return 0;
-
-  // Force the DeclContext to build a its name-lookup table.
-  DC->lookup(DeclarationName());
-
-  // Serialize the contents of the mapping used for lookup. Note that,
-  // although we have two very different code paths, the serialized
-  // representation is the same for both cases: a declaration name,
-  // followed by a size, followed by references to the visible
-  // declarations that have that name.
-  uint64_t Offset = Stream.GetCurrentBitNo();
-  RecordData Record;
-  StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr());
-  if (!Map)
-    return 0;
-
-  for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end();
-       D != DEnd; ++D) {
-    AddDeclarationName(D->first, Record);
-    DeclContext::lookup_result Result = D->second.getLookupResult(Context);
-    Record.push_back(Result.second - Result.first);
-    for (; Result.first != Result.second; ++Result.first)
-      AddDeclRef(*Result.first, Record);
-  }
-
-  if (Record.size() == 0)
-    return 0;
-
-  Stream.EmitRecord(DECL_CONTEXT_VISIBLE, Record);
-  ++NumVisibleDeclContexts;
-  return Offset;
-}
-
 void ASTWriter::WriteTypeDeclOffsets() {
   using namespace llvm;
   RecordData Record;
@@ -2062,6 +2009,74 @@
 };
 } // end anonymous namespace
 
+/// \brief Write the block containing all of the declaration IDs
+/// visible from the given DeclContext.
+///
+/// \returns the offset of the DECL_CONTEXT_VISIBLE block within the
+/// bistream, or 0 if no block was written.
+uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
+                                                 DeclContext *DC) {
+  if (DC->getPrimaryContext() != DC)
+    return 0;
+
+  // Since there is no name lookup into functions or methods, don't bother to
+  // build a visible-declarations table for these entities.
+  if (DC->isFunctionOrMethod())
+    return 0;
+
+  // If not in C++, we perform name lookup for the translation unit via the
+  // IdentifierInfo chains, don't bother to build a visible-declarations table.
+  // FIXME: In C++ we need the visible declarations in order to "see" the
+  // friend declarations, is there a way to do this without writing the table ?
+  if (DC->isTranslationUnit() && !Context.getLangOptions().CPlusPlus)
+    return 0;
+
+  // Force the DeclContext to build a its name-lookup table.
+  DC->lookup(DeclarationName());
+
+  // Serialize the contents of the mapping used for lookup. Note that,
+  // although we have two very different code paths, the serialized
+  // representation is the same for both cases: a declaration name,
+  // followed by a size, followed by references to the visible
+  // declarations that have that name.
+  uint64_t Offset = Stream.GetCurrentBitNo();
+  StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr());
+  if (!Map || Map->empty())
+    return 0;
+
+  OnDiskChainedHashTableGenerator<ASTDeclContextNameLookupTrait> Generator;
+  ASTDeclContextNameLookupTrait Trait(*this);
+
+  // Create the on-disk hash table representation.
+  for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end();
+       D != DEnd; ++D) {
+    DeclarationName Name = D->first;
+    DeclContext::lookup_result Result = D->second.getLookupResult();
+    Generator.insert(Name, Result, Trait);
+  }
+
+  // Create the on-disk hash table in a buffer.
+  llvm::SmallString<4096> LookupTable;
+  uint32_t BucketOffset;
+  {
+    llvm::raw_svector_ostream Out(LookupTable);
+    // Make sure that no bucket is at offset 0
+    clang::io::Emit32(Out, 0);
+    BucketOffset = Generator.Emit(Out, Trait);
+  }
+
+  // Write the lookup table
+  RecordData Record;
+  Record.push_back(DECL_CONTEXT_VISIBLE);
+  Record.push_back(BucketOffset);
+  Stream.EmitRecordWithBlob(DeclContextVisibleLookupAbbrev, Record,
+                            LookupTable.str());
+
+  Stream.EmitRecord(DECL_CONTEXT_VISIBLE, Record);
+  ++NumVisibleDeclContexts;
+  return Offset;
+}
+
 //===----------------------------------------------------------------------===//
 // General Serialization Routines
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=111636&r1=111635&r2=111636&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Fri Aug 20 11:04:35 2010
@@ -1086,6 +1086,12 @@
   Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_LEXICAL));
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
   DeclContextLexicalAbbrev = Stream.EmitAbbrev(Abv);
+
+  Abv = new BitCodeAbbrev();
+  Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_VISIBLE));
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
+  DeclContextVisibleLookupAbbrev = Stream.EmitAbbrev(Abv);
 }
 
 /// isRequiredDecl - Check if this is a "required" Decl, which must be seen by





More information about the cfe-commits mailing list