]> granicus.if.org Git - clang/commitdiff
If a visibility update record is found for a DeclContext after that Decl has
authorRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 11 Mar 2014 03:10:46 +0000 (03:10 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 11 Mar 2014 03:10:46 +0000 (03:10 +0000)
already been loaded, apply that update record to the Decl immediately, rather
than adding it to a pending list and never applying it.

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

include/clang/Serialization/Module.h
lib/Serialization/ASTReader.cpp
lib/Serialization/ASTReaderDecl.cpp
lib/Serialization/Module.cpp
test/Modules/Inputs/update-after-load/a.h [new file with mode: 0644]
test/Modules/Inputs/update-after-load/b.h [new file with mode: 0644]
test/Modules/Inputs/update-after-load/module.map [new file with mode: 0644]
test/Modules/Inputs/update-after-load/modules.timestamp [new file with mode: 0644]
test/Modules/update-after-load.cpp [new file with mode: 0644]

index 469785de7c45e2dbe11cc9ffe061fedfc280b1b3..caa2c286c4fb3411d19996ae80684b60e7775576 100644 (file)
@@ -44,13 +44,21 @@ enum ModuleKind {
   MK_MainFile  ///< File is a PCH file treated as the actual main file.
 };
 
+/// A custom deleter for DeclContextInfo::NameLookupTableData, to allow
+/// an incomplete type to be used there.
+struct NameLookupTableDataDeleter {
+  void operator()(
+      OnDiskChainedHashTable<reader::ASTDeclContextNameLookupTrait> *Ptr) const;
+};
+
 /// \brief Information about the contents of a DeclContext.
 struct DeclContextInfo {
   DeclContextInfo()
-    : NameLookupTableData(), LexicalDecls(), NumLexicalDecls() {}
+      : NameLookupTableData(), LexicalDecls(), NumLexicalDecls() {}
 
-  OnDiskChainedHashTable<reader::ASTDeclContextNameLookupTrait>
-    *NameLookupTableData; // an ASTDeclContextNameLookupTable.
+  /// An ASTDeclContextNameLookupTable.
+  std::unique_ptr<OnDiskChainedHashTable<reader::ASTDeclContextNameLookupTrait>,
+                  NameLookupTableDataDeleter> NameLookupTableData;
   const KindDeclIDPair *LexicalDecls;
   unsigned NumLexicalDecls;
 };
index 6f4dc9bfb5808bc254b2599c070e537d33d72537..487283c421cd71159e3f55bac1cb2399b866a762 100644 (file)
@@ -457,6 +457,11 @@ ASTReader::setDeserializationListener(ASTDeserializationListener *Listener) {
 }
 
 
+void NameLookupTableDataDeleter::
+operator()(ASTDeclContextNameLookupTable *Ptr) const {
+  delete Ptr;
+}
+
 
 unsigned ASTSelectorLookupTrait::ComputeHash(Selector Sel) {
   return serialization::ComputeHash(Sel);
@@ -836,11 +841,10 @@ bool ASTReader::ReadDeclContextStorage(ModuleFile &M,
       Error("Expected visible lookup table block");
       return true;
     }
-    Info.NameLookupTableData
-      = ASTDeclContextNameLookupTable::Create(
-                    (const unsigned char *)Blob.data() + Record[0],
-                    (const unsigned char *)Blob.data(),
-                    ASTDeclContextNameLookupTrait(*this, M));
+    Info.NameLookupTableData.reset(ASTDeclContextNameLookupTable::Create(
+        (const unsigned char *)Blob.data() + Record[0],
+        (const unsigned char *)Blob.data(),
+        ASTDeclContextNameLookupTrait(*this, M)));
   }
 
   return false;
@@ -2493,8 +2497,12 @@ bool ASTReader::ReadASTBlock(ModuleFile &F) {
                         ASTDeclContextNameLookupTrait(*this, F));
       if (ID == PREDEF_DECL_TRANSLATION_UNIT_ID) { // Is it the TU?
         DeclContext *TU = Context.getTranslationUnitDecl();
-        F.DeclContextInfos[TU].NameLookupTableData = Table;
+        F.DeclContextInfos[TU].NameLookupTableData.reset(Table);
         TU->setHasExternalVisibleStorage(true);
+      } else if (Decl *D = DeclsLoaded[ID - NUM_PREDEF_DECL_IDS]) {
+        auto *DC = cast<DeclContext>(D);
+        DC->getPrimaryContext()->setHasExternalVisibleStorage(true);
+        F.DeclContextInfos[DC].NameLookupTableData.reset(Table);
       } else
         PendingVisibleUpdates[ID].push_back(std::make_pair(Table, &F));
       break;
@@ -6078,7 +6086,7 @@ namespace {
         return false;
       
       // Look for this name within this module.
-      ASTDeclContextNameLookupTable *LookupTable =
+      const auto &LookupTable =
         Info->second.NameLookupTableData;
       ASTDeclContextNameLookupTable::iterator Pos
         = LookupTable->find(This->Name);
@@ -6208,7 +6216,7 @@ namespace {
       if (!FoundInfo)
         return false;
 
-      ASTDeclContextNameLookupTable *LookupTable =
+      const auto &LookupTable =
         Info->second.NameLookupTableData;
       bool FoundAnything = false;
       for (ASTDeclContextNameLookupTable::data_iterator
index b9034f951f511313a22d0215ada18211833d4266..fef5f7b88901036730f71bec7c669327286110cb 100644 (file)
@@ -2609,13 +2609,9 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
       // There are updates. This means the context has external visible
       // storage, even if the original stored version didn't.
       LookupDC->setHasExternalVisibleStorage(true);
-      DeclContextVisibleUpdates &U = I->second;
-      for (DeclContextVisibleUpdates::iterator UI = U.begin(), UE = U.end();
-           UI != UE; ++UI) {
-        DeclContextInfo &Info = UI->second->DeclContextInfos[DC];
-        delete Info.NameLookupTableData;
-        Info.NameLookupTableData = UI->first;
-      }
+      for (const auto &Update : I->second)
+        Update.second->DeclContextInfos[DC].NameLookupTableData.reset(
+            Update.first);
       PendingVisibleUpdates.erase(I);
     }
   }
index 2eb397176a1293cdd0976a9bd2beebf6c8b9d251..77dcc4f99e3b6f66045c1abc7ac5fd544d641fd1 100644 (file)
@@ -45,13 +45,6 @@ ModuleFile::ModuleFile(ModuleKind Kind, unsigned Generation)
 {}
 
 ModuleFile::~ModuleFile() {
-  for (DeclContextInfosMap::iterator I = DeclContextInfos.begin(),
-       E = DeclContextInfos.end();
-       I != E; ++I) {
-    if (I->second.NameLookupTableData)
-      delete I->second.NameLookupTableData;
-  }
-  
   delete static_cast<ASTIdentifierLookupTable *>(IdentifierLookupTable);
   delete static_cast<HeaderFileInfoLookupTable *>(HeaderFileInfoTable);
   delete static_cast<ASTSelectorLookupTable *>(SelectorLookupTable);
diff --git a/test/Modules/Inputs/update-after-load/a.h b/test/Modules/Inputs/update-after-load/a.h
new file mode 100644 (file)
index 0000000..0ebcf3e
--- /dev/null
@@ -0,0 +1 @@
+namespace llvm {}
diff --git a/test/Modules/Inputs/update-after-load/b.h b/test/Modules/Inputs/update-after-load/b.h
new file mode 100644 (file)
index 0000000..64e9bfd
--- /dev/null
@@ -0,0 +1,2 @@
+#include "a.h"
+namespace llvm { void f(); }
diff --git a/test/Modules/Inputs/update-after-load/module.map b/test/Modules/Inputs/update-after-load/module.map
new file mode 100644 (file)
index 0000000..21e160e
--- /dev/null
@@ -0,0 +1 @@
+module a { header "a.h" } module b { header "b.h" }
diff --git a/test/Modules/Inputs/update-after-load/modules.timestamp b/test/Modules/Inputs/update-after-load/modules.timestamp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/test/Modules/update-after-load.cpp b/test/Modules/update-after-load.cpp
new file mode 100644 (file)
index 0000000..f497ea4
--- /dev/null
@@ -0,0 +1,8 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -I %S/Inputs/update-after-load -verify -fmodules-cache-path=%t %s
+
+// expected-no-diagnostics
+#include "a.h"
+namespace llvm {}
+#include "b.h"
+void llvm::f() {}