]> granicus.if.org Git - clang/commitdiff
[modules] Stop walking all modules when looking for lexical decls for a
authorRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 6 Aug 2015 22:07:25 +0000 (22:07 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 6 Aug 2015 22:07:25 +0000 (22:07 +0000)
DeclContext. These only ever come from the owning module file for the Decl.

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

include/clang/Serialization/ASTBitCodes.h
include/clang/Serialization/ASTReader.h
include/clang/Serialization/Module.h
lib/Serialization/ASTReader.cpp
lib/Serialization/ASTWriter.cpp

index 3d46225e7c79e90fd4318c97b615646b07b69d27..ea3a9c203b284333be67db68ab4dc78711e61325 100644 (file)
@@ -61,9 +61,6 @@ namespace clang {
     /// used for the translation unit declaration.
     typedef uint32_t DeclID;
 
-    /// \brief a Decl::Kind/DeclID pair.
-    typedef std::pair<uint32_t, DeclID> KindDeclIDPair;
-
     // FIXME: Turn these into classes so we can have some type safety when
     // we go from local ID to global and vice-versa.
     typedef DeclID LocalDeclID;
index 227ac50d8fa0d517e362bfb20bc16aa037127c20..b01070edb4e0811637b29e9dc1c70b987fafc08e 100644 (file)
@@ -494,6 +494,16 @@ private:
   /// \brief Map from a FileID to the file-level declarations that it contains.
   llvm::DenseMap<FileID, FileDeclsInfo> FileDeclIDs;
 
+  /// \brief An array of lexical contents of a declaration context, as a sequence of
+  /// Decl::Kind, DeclID pairs.
+  typedef ArrayRef<llvm::support::unaligned_uint32_t> LexicalContents;
+
+  /// \brief Map from a DeclContext to its lexical contents.
+  llvm::DenseMap<const DeclContext*, LexicalContents> LexicalDecls;
+
+  /// \brief Map from the TU to its lexical contents from each module file.
+  std::vector<std::pair<ModuleFile*, LexicalContents>> TULexicalDecls;
+
   // Updates for visible decls can occur for other contexts than just the
   // TU, and when we read those update records, the actual context may not
   // be available yet, so have this pending map using the ID as a key. It
index 1d9fb0bfe8d455a542ef23d875b34178ad39c4d5..0740cd025ec6e885624313e1c5879162af7eda7a 100644 (file)
@@ -52,12 +52,10 @@ enum ModuleKind {
 
 /// \brief Information about the contents of a DeclContext.
 struct DeclContextInfo {
-  DeclContextInfo()
-    : NameLookupTableData(), LexicalDecls() {}
+  DeclContextInfo() : NameLookupTableData() {}
 
   llvm::OnDiskIterableChainedHashTable<reader::ASTDeclContextNameLookupTrait>
     *NameLookupTableData; // an ASTDeclContextNameLookupTable.
-  ArrayRef<KindDeclIDPair> LexicalDecls;
 };
 
 /// \brief The input file that has been loaded from this AST file, along with
index c12894d773fce70caaa16a79897617f87d0597a8..acb19a2cc7ef4a01f908692087efd98e21724d5d 100644 (file)
@@ -973,9 +973,13 @@ bool ASTReader::ReadLexicalDeclContextStorage(ModuleFile &M,
     return true;
   }
 
-  M.DeclContextInfos[DC].LexicalDecls = llvm::makeArrayRef(
-      reinterpret_cast<const KindDeclIDPair *>(Blob.data()),
-      Blob.size() / sizeof(KindDeclIDPair));
+  assert(!isa<TranslationUnitDecl>(DC) &&
+         "expected a TU_UPDATE_LEXICAL record for TU");
+  // FIXME: Once we remove RewriteDecl, assert that we didn't already have
+  // lexical decls for this context.
+  LexicalDecls[DC] = llvm::makeArrayRef(
+      reinterpret_cast<const llvm::support::unaligned_uint32_t *>(Blob.data()),
+      Blob.size() / 4);
   DC->setHasExternalLexicalStorage(true);
   return false;
 }
@@ -2498,10 +2502,11 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
         
     case TU_UPDATE_LEXICAL: {
       DeclContext *TU = Context.getTranslationUnitDecl();
-      DeclContextInfo &Info = F.DeclContextInfos[TU];
-      Info.LexicalDecls = llvm::makeArrayRef(
-          reinterpret_cast<const KindDeclIDPair *>(Blob.data()),
-          static_cast<unsigned int>(Blob.size() / sizeof(KindDeclIDPair)));
+      LexicalContents Contents(
+          reinterpret_cast<const llvm::support::unaligned_uint32_t *>(
+              Blob.data()),
+          static_cast<unsigned int>(Blob.size() / 4));
+      TULexicalDecls.push_back(std::make_pair(&F, Contents));
       TU->setHasExternalLexicalStorage(true);
       break;
     }
@@ -6175,69 +6180,45 @@ Stmt *ASTReader::GetExternalDeclStmt(uint64_t Offset) {
   return ReadStmtFromStream(*Loc.F);
 }
 
-namespace {
-  class FindExternalLexicalDeclsVisitor {
-    ASTReader &Reader;
-    const DeclContext *DC;
-    llvm::function_ref<bool(Decl::Kind)> IsKindWeWant;
-    
-    SmallVectorImpl<Decl*> &Decls;
-    bool PredefsVisited[NUM_PREDEF_DECL_IDS];
-
-  public:
-    FindExternalLexicalDeclsVisitor(
-        ASTReader &Reader, const DeclContext *DC,
-        llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
-        SmallVectorImpl<Decl *> &Decls)
-        : Reader(Reader), DC(DC), IsKindWeWant(IsKindWeWant), Decls(Decls) {
-      for (unsigned I = 0; I != NUM_PREDEF_DECL_IDS; ++I)
-        PredefsVisited[I] = false;
-    }
+void ASTReader::FindExternalLexicalDecls(
+    const DeclContext *DC, llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
+    SmallVectorImpl<Decl *> &Decls) {
+  bool PredefsVisited[NUM_PREDEF_DECL_IDS] = {};
 
-    static bool visitPostorder(ModuleFile &M, void *UserData) {
-      return (*static_cast<FindExternalLexicalDeclsVisitor*>(UserData))(M);
-    }
+  auto Visit = [&] (ModuleFile *M, const LexicalContents &LexicalDecls) {
+    assert(LexicalDecls.size() % 2 == 0 && "expected an even number of entries");
+    for (int I = 0, N = LexicalDecls.size(); I != N; I += 2) {
+      auto K = (Decl::Kind)+LexicalDecls[I];
+      if (!IsKindWeWant(K))
+        continue;
 
-    bool operator()(ModuleFile &M) {
-      ModuleFile::DeclContextInfosMap::iterator Info =
-          M.DeclContextInfos.find(DC);
-      if (Info == M.DeclContextInfos.end() || Info->second.LexicalDecls.empty())
-        return false;
+      auto ID = (serialization::DeclID)+LexicalDecls[I + 1];
 
-      // Load all of the declaration IDs
-      for (const KindDeclIDPair &P : Info->second.LexicalDecls) {
-        if (!IsKindWeWant((Decl::Kind)P.first))
+      // Don't add predefined declarations to the lexical context more
+      // than once.
+      if (ID < NUM_PREDEF_DECL_IDS) {
+        if (PredefsVisited[ID])
           continue;
 
-        // Don't add predefined declarations to the lexical context more
-        // than once.
-        if (P.second < NUM_PREDEF_DECL_IDS) {
-          if (PredefsVisited[P.second])
-            continue;
-
-          PredefsVisited[P.second] = true;
-        }
-
-        if (Decl *D = Reader.GetLocalDecl(M, P.second)) {
-          if (!DC->isDeclInLexicalTraversal(D))
-            Decls.push_back(D);
-        }
+        PredefsVisited[ID] = true;
       }
 
-      return false;
+      if (Decl *D = GetLocalDecl(*M, ID)) {
+        if (!DC->isDeclInLexicalTraversal(D))
+          Decls.push_back(D);
+      }
     }
   };
-}
 
-void ASTReader::FindExternalLexicalDecls(
-    const DeclContext *DC, llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
-    SmallVectorImpl<Decl *> &Decls) {
-  // There might be lexical decls in multiple modules, for the TU at
-  // least. FIXME: Only look in multiple module files in the very rare
-  // cases where this can actually happen.
-  FindExternalLexicalDeclsVisitor Visitor(*this, DC, IsKindWeWant, Decls);
-  ModuleMgr.visitDepthFirst(
-      nullptr, &FindExternalLexicalDeclsVisitor::visitPostorder, &Visitor);
+  if (isa<TranslationUnitDecl>(DC)) {
+    for (auto Lexical : TULexicalDecls)
+      Visit(Lexical.first, Lexical.second);
+  } else {
+    auto I = LexicalDecls.find(DC);
+    if (I != LexicalDecls.end())
+      Visit(getOwningModuleFile(cast<Decl>(DC)), I->second);
+  }
+
   ++NumLexicalDeclContextsRead;
 }
 
index 1199803a9c082cea327475d6df7f80f004a473a2..366d4b39fc50d44a6c453ccd8f4fce0b1b9f8073 100644 (file)
@@ -2738,12 +2738,15 @@ uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context,
   uint64_t Offset = Stream.GetCurrentBitNo();
   RecordData Record;
   Record.push_back(DECL_CONTEXT_LEXICAL);
-  SmallVector<KindDeclIDPair, 64> Decls;
-  for (const auto *D : DC->decls())
-    Decls.push_back(std::make_pair(D->getKind(), GetDeclRef(D)));
+  SmallVector<uint32_t, 128> KindDeclPairs;
+  for (const auto *D : DC->decls()) {
+    KindDeclPairs.push_back(D->getKind());
+    KindDeclPairs.push_back(GetDeclRef(D));
+  }
 
   ++NumLexicalDeclContexts;
-  Stream.EmitRecordWithBlob(DeclContextLexicalAbbrev, Record, bytes(Decls));
+  Stream.EmitRecordWithBlob(DeclContextLexicalAbbrev, Record,
+                            bytes(KindDeclPairs));
   return Offset;
 }
 
@@ -4288,10 +4291,12 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,
   // Create a lexical update block containing all of the declarations in the
   // translation unit that do not come from other AST files.
   const TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
-  SmallVector<KindDeclIDPair, 64> NewGlobalDecls;
-  for (const auto *I : TU->noload_decls()) {
-    if (!I->isFromASTFile())
-      NewGlobalDecls.push_back(std::make_pair(I->getKind(), GetDeclRef(I)));
+  SmallVector<uint32_t, 128> NewGlobalKindDeclPairs;
+  for (const auto *D : TU->noload_decls()) {
+    if (!D->isFromASTFile()) {
+      NewGlobalKindDeclPairs.push_back(D->getKind());
+      NewGlobalKindDeclPairs.push_back(GetDeclRef(D));
+    }
   }
   
   llvm::BitCodeAbbrev *Abv = new llvm::BitCodeAbbrev();
@@ -4301,7 +4306,7 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,
   Record.clear();
   Record.push_back(TU_UPDATE_LEXICAL);
   Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record,
-                            bytes(NewGlobalDecls));
+                            bytes(NewGlobalKindDeclPairs));
   
   // And a visible updates block for the translation unit.
   Abv = new llvm::BitCodeAbbrev();