summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Serialization/Module.h14
-rw-r--r--clang/lib/Serialization/ASTReader.cpp24
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp10
-rw-r--r--clang/lib/Serialization/Module.cpp7
-rw-r--r--clang/test/Modules/Inputs/update-after-load/a.h1
-rw-r--r--clang/test/Modules/Inputs/update-after-load/b.h2
-rw-r--r--clang/test/Modules/Inputs/update-after-load/module.map1
-rw-r--r--clang/test/Modules/Inputs/update-after-load/modules.timestamp0
-rw-r--r--clang/test/Modules/update-after-load.cpp8
9 files changed, 42 insertions, 25 deletions
diff --git a/clang/include/clang/Serialization/Module.h b/clang/include/clang/Serialization/Module.h
index 469785de7c4..caa2c286c4f 100644
--- a/clang/include/clang/Serialization/Module.h
+++ b/clang/include/clang/Serialization/Module.h
@@ -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;
};
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 6f4dc9bfb58..487283c421c 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -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
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index b9034f951f5..fef5f7b8890 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -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);
}
}
diff --git a/clang/lib/Serialization/Module.cpp b/clang/lib/Serialization/Module.cpp
index 2eb397176a1..77dcc4f99e3 100644
--- a/clang/lib/Serialization/Module.cpp
+++ b/clang/lib/Serialization/Module.cpp
@@ -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/clang/test/Modules/Inputs/update-after-load/a.h b/clang/test/Modules/Inputs/update-after-load/a.h
new file mode 100644
index 00000000000..0ebcf3e34a7
--- /dev/null
+++ b/clang/test/Modules/Inputs/update-after-load/a.h
@@ -0,0 +1 @@
+namespace llvm {}
diff --git a/clang/test/Modules/Inputs/update-after-load/b.h b/clang/test/Modules/Inputs/update-after-load/b.h
new file mode 100644
index 00000000000..64e9bfd4bc7
--- /dev/null
+++ b/clang/test/Modules/Inputs/update-after-load/b.h
@@ -0,0 +1,2 @@
+#include "a.h"
+namespace llvm { void f(); }
diff --git a/clang/test/Modules/Inputs/update-after-load/module.map b/clang/test/Modules/Inputs/update-after-load/module.map
new file mode 100644
index 00000000000..21e160ea051
--- /dev/null
+++ b/clang/test/Modules/Inputs/update-after-load/module.map
@@ -0,0 +1 @@
+module a { header "a.h" } module b { header "b.h" }
diff --git a/clang/test/Modules/Inputs/update-after-load/modules.timestamp b/clang/test/Modules/Inputs/update-after-load/modules.timestamp
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/clang/test/Modules/Inputs/update-after-load/modules.timestamp
diff --git a/clang/test/Modules/update-after-load.cpp b/clang/test/Modules/update-after-load.cpp
new file mode 100644
index 00000000000..f497ea47945
--- /dev/null
+++ b/clang/test/Modules/update-after-load.cpp
@@ -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() {}
OpenPOWER on IntegriCloud