diff options
-rw-r--r-- | clang/include/clang/Serialization/Module.h | 14 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 24 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Serialization/Module.cpp | 7 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/update-after-load/a.h | 1 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/update-after-load/b.h | 2 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/update-after-load/module.map | 1 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/update-after-load/modules.timestamp | 0 | ||||
-rw-r--r-- | clang/test/Modules/update-after-load.cpp | 8 |
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() {} |