From 97fe2e8a4faa9cca9cee1f31a74acbb52d19ce0a Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Fri, 15 Jul 2016 21:33:46 +0000 Subject: [PATCH] Revert r275481, r275490. This broke modules bootstrap. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@275624 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Serialization/ASTReader.h | 28 +----- lib/Serialization/ASTReader.cpp | 90 ------------------- lib/Serialization/ASTReaderDecl.cpp | 17 ++-- lib/Serialization/ASTWriterDecl.cpp | 2 +- test/Modules/Inputs/unused-global-init/init.h | 1 - .../unused-global-init/module.modulemap | 3 - .../Modules/Inputs/unused-global-init/other.h | 1 - .../Inputs/unused-global-init/unused.h | 1 - test/Modules/Inputs/unused-global-init/used.h | 2 - test/Modules/unused-global-init.cpp | 36 -------- 10 files changed, 10 insertions(+), 171 deletions(-) delete mode 100644 test/Modules/Inputs/unused-global-init/init.h delete mode 100644 test/Modules/Inputs/unused-global-init/module.modulemap delete mode 100644 test/Modules/Inputs/unused-global-init/other.h delete mode 100644 test/Modules/Inputs/unused-global-init/unused.h delete mode 100644 test/Modules/Inputs/unused-global-init/used.h delete mode 100644 test/Modules/unused-global-init.cpp diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index 883defc8c6..1b40494fd4 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -613,7 +613,7 @@ private: /// \brief A mapping from each of the hidden submodules to the deserialized /// declarations in that submodule that could be made visible. HiddenNamesMapType HiddenNamesMap; - + /// \brief A module import, export, or conflict that hasn't yet been resolved. struct UnresolvedModuleRef { @@ -947,24 +947,6 @@ private: /// Objective-C protocols. std::deque InterestingDecls; - /// \brief Contains imported interesting declarations from modules that have - /// not yet themselves been imported, even indirectly. - typedef llvm::SmallVector ModuleInterestingDecls; - - /// Map from top-level modules to their list of interesting declarations. - /// Each map entry may be in one of three states: no entry means we've never - /// seen this module and never transitively imported it. A null pointer means - /// we're not tracking interesting decls: they should be handed straight to - /// the consumer because we've transitively imported this module already. - /// Otherwise, a list of pending interesting decls. - /// - /// As an added twist, declarations that are re-exported are listed against - /// the owning module and the re-exporting one, but the owning module's list - /// is definitive: the decl is there if and only if it has not been handed to - /// the consumer already. - llvm::DenseMap - UnimportedModuleInterestingDecls; - /// \brief The list of redeclaration chains that still need to be /// reconstructed, and the local offset to the corresponding list /// of redeclarations. @@ -1267,9 +1249,6 @@ private: llvm::iterator_range getModuleFileLevelDecls(ModuleFile &Mod); - void addInterestingDecl(Decl *D, - llvm::Optional OwnerOverride = llvm::None); - void PassInterestingDeclsToConsumer(); void PassInterestingDeclToConsumer(Decl *D); @@ -1407,11 +1386,6 @@ public: /// \brief Make the names within this set of hidden names visible. void makeNamesVisible(const HiddenNames &Names, Module *Owner); - /// \brief Mark a module as "used". This implies that any global initializers - /// of declarations contained transitively within it should be run as part of - /// the current compilation. - void markModuleUsed(Module *M); - /// \brief Take the AST callbacks listener. std::unique_ptr takeListener() { return std::move(Listener); diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index d4bcdac598..b35bd7bd32 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -2691,8 +2691,6 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { case EAGERLY_DESERIALIZED_DECLS: // FIXME: Skip reading this record if our ASTConsumer doesn't care // about "interesting" decls (for instance, if we're building a module). - // FIXME: Store this somewhere per-module and defer until - // markModuleReferenced is called. for (unsigned I = 0, N = Record.size(); I != N; ++I) EagerlyDeserializedDecls.push_back(getGlobalDeclID(F, Record[I])); break; @@ -3363,9 +3361,6 @@ void ASTReader::makeNamesVisible(const HiddenNames &Names, Module *Owner) { void ASTReader::makeModuleVisible(Module *Mod, Module::NameVisibilityKind NameVisibility, SourceLocation ImportLoc) { - // If we import anything from the module in any way, then it is used. - markModuleUsed(Mod); - llvm::SmallPtrSet Visited; SmallVector Stack; Stack.push_back(Mod); @@ -6732,95 +6727,10 @@ void ASTReader::PassInterestingDeclsToConsumer() { Decl *D = InterestingDecls.front(); InterestingDecls.pop_front(); - // If we have found an interesting ImportDecl, then its imported module - // is considered used. - if (auto *ID = dyn_cast(D)) - markModuleUsed(ID->getImportedModule()); - PassInterestingDeclToConsumer(D); } } -void ASTReader::markModuleUsed(Module *M) { - M = M->getTopLevelModule(); - // Mark that interesting decls in this module should now be passed to the - // consumer, and pass any pending decls. - auto MInterestingDecls = - UnimportedModuleInterestingDecls.insert(std::make_pair(M, nullptr)).first; - if (auto *Decls = MInterestingDecls->second) { - MInterestingDecls->second = nullptr; - for (auto *D : *Decls) { - Module *Owner = D->getImportedOwningModule(); - if (Owner) - Owner = Owner->getTopLevelModule(); - if (Owner != M) { - // Mark that this decl has been handed to the consumer in its original - // module, and stop if it's already been removed from there. - auto OwnerIt = UnimportedModuleInterestingDecls.find(Owner); - if (OwnerIt == UnimportedModuleInterestingDecls.end() || - !OwnerIt->second) - continue; - auto NewEnd = - std::remove(OwnerIt->second->begin(), OwnerIt->second->end(), D); - if (NewEnd == OwnerIt->second->end()) - continue; - OwnerIt->second->erase(NewEnd, OwnerIt->second->end()); - } - InterestingDecls.push_back(D); - } - } -} - -void ASTReader::addInterestingDecl(Decl *D, - llvm::Optional OwnerOverride) { - Module *Owner = D->getImportedOwningModule(); - if (Owner) - Owner = Owner->getTopLevelModule(); - Module *ExportedBy = OwnerOverride ? *OwnerOverride : Owner; - if (ExportedBy) - ExportedBy = ExportedBy->getTopLevelModule(); - - auto It = ExportedBy ? UnimportedModuleInterestingDecls.find(ExportedBy) - : UnimportedModuleInterestingDecls.end(); - if (It == UnimportedModuleInterestingDecls.end()) - It = UnimportedModuleInterestingDecls.insert( - std::make_pair(ExportedBy, new (Context) ModuleInterestingDecls)) - .first; - ModuleInterestingDecls *Interesting = It->second; - - // If this declaration's module has been imported, hand it to the consumer. - if (!ExportedBy || !Interesting) { - if (Owner != ExportedBy) { - // Mark that this decl has been handed to the consumer in its original - // module, and stop if it's already been removed from there. - auto OwnerIt = UnimportedModuleInterestingDecls.find(Owner); - if (OwnerIt == UnimportedModuleInterestingDecls.end() || !OwnerIt->second) - return; - auto NewEnd = - std::remove(OwnerIt->second->begin(), OwnerIt->second->end(), D); - if (NewEnd == OwnerIt->second->end()) - return; - OwnerIt->second->erase(NewEnd, OwnerIt->second->end()); - } - InterestingDecls.push_back(D); - return; - } - assert(Owner && "re-export of unowned decl"); - - // If this is a re-export of another module's decl, check whether the decl - // has already been handed to the consumer. - if (Owner != ExportedBy) { - auto OwnerIt = UnimportedModuleInterestingDecls.find(Owner); - if (OwnerIt != UnimportedModuleInterestingDecls.end() && - (!OwnerIt->second || - std::find(OwnerIt->second->begin(), OwnerIt->second->end(), D) == - OwnerIt->second->end())) - return; - } - - Interesting->push_back(D); -} - void ASTReader::PassInterestingDeclToConsumer(Decl *D) { if (ObjCImplDecl *ImplD = dyn_cast(D)) PassObjCImplDeclToConsumer(ImplD, Consumer); diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index d9ed39a501..4fd7aeb83a 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -3462,13 +3462,6 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { } assert(Idx == Record.size()); - // If we have deserialized a declaration that has a definition the - // AST consumer might need to know about, queue it. - // We don't pass it to the consumer immediately because we may be in recursive - // loading, and some declarations may still be initializing. - if (isConsumerInterestedIn(D, Reader.hasPendingBody())) - addInterestingDecl(D); - // Load any relevant update records. PendingUpdateRecords.push_back(std::make_pair(ID, D)); @@ -3477,6 +3470,13 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { if (Class->isThisDeclarationADefinition()) loadObjCCategories(ID, Class); + // If we have deserialized a declaration that has a definition the + // AST consumer might need to know about, queue it. + // We don't pass it to the consumer immediately because we may be in recursive + // loading, and some declarations may still be initializing. + if (isConsumerInterestedIn(D, Reader.hasPendingBody())) + InterestingDecls.push_back(D); + return D; } @@ -3511,7 +3511,7 @@ void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) { // we need to hand it off to the consumer. if (!WasInteresting && isConsumerInterestedIn(D, Reader.hasPendingBody())) { - addInterestingDecl(D); + InterestingDecls.push_back(D); WasInteresting = true; } } @@ -3945,7 +3945,6 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile, // The declaration is now visible. Exported->Hidden = false; } - Reader.addInterestingDecl(Exported, Owner); break; } diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp index 8a54d9e163..23d18540e8 100644 --- a/lib/Serialization/ASTWriterDecl.cpp +++ b/lib/Serialization/ASTWriterDecl.cpp @@ -2126,7 +2126,7 @@ static bool isRequiredDecl(const Decl *D, ASTContext &Context, // ImportDecl is used by codegen to determine the set of imported modules to // search for inputs for automatic linking; include it if it has a semantic // effect. - if (isa(D)) + if (isa(D) && !WritingModule) return true; return Context.DeclMustBeEmitted(D); diff --git a/test/Modules/Inputs/unused-global-init/init.h b/test/Modules/Inputs/unused-global-init/init.h deleted file mode 100644 index 29a932ae65..0000000000 --- a/test/Modules/Inputs/unused-global-init/init.h +++ /dev/null @@ -1 +0,0 @@ -struct Init { Init(); ~Init(); } init; diff --git a/test/Modules/Inputs/unused-global-init/module.modulemap b/test/Modules/Inputs/unused-global-init/module.modulemap deleted file mode 100644 index c40f0efeb5..0000000000 --- a/test/Modules/Inputs/unused-global-init/module.modulemap +++ /dev/null @@ -1,3 +0,0 @@ -module used { header "used.h" } -module unused { header "unused.h" } -module init { module a { header "init.h" } module b { header "other.h" } } diff --git a/test/Modules/Inputs/unused-global-init/other.h b/test/Modules/Inputs/unused-global-init/other.h deleted file mode 100644 index c6be1ad4c4..0000000000 --- a/test/Modules/Inputs/unused-global-init/other.h +++ /dev/null @@ -1 +0,0 @@ -// other.h diff --git a/test/Modules/Inputs/unused-global-init/unused.h b/test/Modules/Inputs/unused-global-init/unused.h deleted file mode 100644 index 06c2a44ba2..0000000000 --- a/test/Modules/Inputs/unused-global-init/unused.h +++ /dev/null @@ -1 +0,0 @@ -// unused.h diff --git a/test/Modules/Inputs/unused-global-init/used.h b/test/Modules/Inputs/unused-global-init/used.h deleted file mode 100644 index e51725c6a9..0000000000 --- a/test/Modules/Inputs/unused-global-init/used.h +++ /dev/null @@ -1,2 +0,0 @@ -// used.h -#include "other.h" diff --git a/test/Modules/unused-global-init.cpp b/test/Modules/unused-global-init.cpp deleted file mode 100644 index bf26b595ad..0000000000 --- a/test/Modules/unused-global-init.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// RUN: rm -rf %t -// -// RUN: %clang_cc1 -fmodules -fno-implicit-modules -x c++ -I %S/Inputs/unused-global-init -triple %itanium_abi_triple -emit-module %S/Inputs/unused-global-init/module.modulemap -fmodule-name=init -o %t/init.pcm -// RUN: %clang_cc1 -fmodules -fno-implicit-modules -x c++ -I %S/Inputs/unused-global-init -triple %itanium_abi_triple -emit-module %S/Inputs/unused-global-init/module.modulemap -fmodule-name=unused -o %t/unused.pcm -fmodule-file=%t/init.pcm -// RUN: %clang_cc1 -fmodules -fno-implicit-modules -x c++ -I %S/Inputs/unused-global-init -triple %itanium_abi_triple -emit-module %S/Inputs/unused-global-init/module.modulemap -fmodule-name=used -o %t/used.pcm -fmodule-file=%t/init.pcm -// -// No module file: init.h performs init. -// RUN: %clang_cc1 -fmodules -fno-implicit-modules -x c++ -I %S/Inputs/unused-global-init -triple %itanium_abi_triple -emit-llvm -o - %s -DINIT | FileCheck --check-prefix=CHECK-INIT %s -// RUN: %clang_cc1 -fmodules -fno-implicit-modules -x c++ -I %S/Inputs/unused-global-init -triple %itanium_abi_triple -emit-llvm -o - %s -DOTHER -DUSED -DUNUSED | FileCheck --check-prefix=CHECK-NO-INIT %s -// -// With module files: if there is a transitive import of any part of the -// module, we run its global initializers (even if the imported piece is not -// visible here). -// RUN: %clang_cc1 -fmodules -fno-implicit-modules -x c++ -I %S/Inputs/unused-global-init -triple %itanium_abi_triple -emit-llvm -o - %s -fmodule-file=%t/used.pcm -fmodule-file=%t/unused.pcm -DINIT | FileCheck --check-prefix=CHECK-INIT %s -// RUN: %clang_cc1 -fmodules -fno-implicit-modules -x c++ -I %S/Inputs/unused-global-init -triple %itanium_abi_triple -emit-llvm -o - %s -fmodule-file=%t/used.pcm -fmodule-file=%t/unused.pcm -DOTHER | FileCheck --check-prefix=CHECK-INIT %s -// RUN: %clang_cc1 -fmodules -fno-implicit-modules -x c++ -I %S/Inputs/unused-global-init -triple %itanium_abi_triple -emit-llvm -o - %s -fmodule-file=%t/used.pcm -fmodule-file=%t/unused.pcm -DUSED | FileCheck --check-prefix=CHECK-INIT %s -// RUN: %clang_cc1 -fmodules -fno-implicit-modules -x c++ -I %S/Inputs/unused-global-init -triple %itanium_abi_triple -emit-llvm -o - %s -fmodule-file=%t/used.pcm -fmodule-file=%t/unused.pcm -DUNUSED | FileCheck --check-prefix=CHECK-NO-INIT %s - -#ifdef INIT -#include "init.h" -#endif - -#ifdef OTHER -#include "other.h" -#endif - -#ifdef USED -#include "used.h" -#endif - -#ifdef UNUSED -#include "unused.h" -#endif - -// CHECK-INIT: call {{.*}}@_ZN4InitC -// CHECK-NO-INIT-NOT: call {{.*}}@_ZN4InitC -- 2.40.0