r276159 - [modules] Don't emit initializers for VarDecls within a module eagerly whenever
Manman via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 14 12:08:36 PDT 2016
Hi Richard,
Another follow-up commit r284263.
When we import the top-level module with “@import X;”, all the initializers in the submodule should be emitted.
Let me know if you see any problem,
Manman
> On Oct 13, 2016, at 4:03 PM, Richard Smith <richard at metafoo.co.uk> wrote:
>
> On Thu, Oct 13, 2016 at 11:52 AM, Manman via cfe-commits <cfe-commits at lists.llvm.org <mailto:cfe-commits at lists.llvm.org>> wrote:
> Hi Richard,
>
> I committed a follow-up patch in r284142 to fix issues with C/ObjC.
>
> Let me know if you see any problem.
>
> Looks good, thank you!
>
> Manman
>
> > On Jul 20, 2016, at 12:10 PM, Richard Smith via cfe-commits <cfe-commits at lists.llvm.org <mailto:cfe-commits at lists.llvm.org>> wrote:
> >
> > Author: rsmith
> > Date: Wed Jul 20 14:10:16 2016
> > New Revision: 276159
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=276159&view=rev <http://llvm.org/viewvc/llvm-project?rev=276159&view=rev>
> > Log:
> > [modules] Don't emit initializers for VarDecls within a module eagerly whenever
> > we first touch any part of that module. Instead, defer them until the first
> > time that module is (transitively) imported. The initializer step for a module
> > then recursively initializes modules that its own headers imported.
> >
> > For example, this avoids running the <iostream> global initializer in programs
> > that don't actually use iostreams, but do use other parts of the standard
> > library.
> >
> > Added:
> > cfe/trunk/test/Modules/Inputs/unused-global-init/
> > - copied from r275623, cfe/trunk/test/Modules/Inputs/unused-global-init/
> > cfe/trunk/test/Modules/unused-global-init.cpp
> > - copied, changed from r275623, cfe/trunk/test/Modules/unused-global-init.cpp
> > Modified:
> > cfe/trunk/include/clang/AST/ASTContext.h
> > cfe/trunk/include/clang/Sema/Sema.h
> > cfe/trunk/include/clang/Serialization/ASTBitCodes.h
> > cfe/trunk/lib/AST/ASTContext.cpp
> > cfe/trunk/lib/CodeGen/CodeGenModule.cpp
> > cfe/trunk/lib/Sema/SemaDecl.cpp
> > cfe/trunk/lib/Sema/SemaLookup.cpp
> > cfe/trunk/lib/Serialization/ASTReader.cpp
> > cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
> > cfe/trunk/lib/Serialization/ASTWriter.cpp
> > cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
> > cfe/trunk/test/Modules/Inputs/unused-global-init/used.h
> > cfe/trunk/test/Modules/odr.cpp
> > cfe/trunk/test/Modules/templates.mm <http://templates.mm/>
> >
> > Modified: cfe/trunk/include/clang/AST/ASTContext.h
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=276159&r1=276158&r2=276159&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=276159&r1=276158&r2=276159&view=diff>
> > ==============================================================================
> > --- cfe/trunk/include/clang/AST/ASTContext.h (original)
> > +++ cfe/trunk/include/clang/AST/ASTContext.h Wed Jul 20 14:10:16 2016
> > @@ -312,6 +312,18 @@ class ASTContext : public RefCountedBase
> > /// definitions of that entity.
> > llvm::DenseMap<NamedDecl*, llvm::TinyPtrVector<Module*>> MergedDefModules;
> >
> > + /// \brief Initializers for a module, in order. Each Decl will be either
> > + /// something that has a semantic effect on startup (such as a variable with
> > + /// a non-constant initializer), or an ImportDecl (which recursively triggers
> > + /// initialization of another module).
> > + struct PerModuleInitializers {
> > + llvm::SmallVector<Decl*, 4> Initializers;
> > + llvm::SmallVector<uint32_t, 4> LazyInitializers;
> > +
> > + void resolve(ASTContext &Ctx);
> > + };
> > + llvm::DenseMap<Module*, PerModuleInitializers*> ModuleInitializers;
> > +
> > public:
> > /// \brief A type synonym for the TemplateOrInstantiation mapping.
> > typedef llvm::PointerUnion<VarTemplateDecl *, MemberSpecializationInfo *>
> > @@ -883,6 +895,17 @@ public:
> > return MergedIt->second;
> > }
> >
> > + /// Add a declaration to the list of declarations that are initialized
> > + /// for a module. This will typically be a global variable (with internal
> > + /// linkage) that runs module initializers, such as the iostream initializer,
> > + /// or an ImportDecl nominating another module that has initializers.
> > + void addModuleInitializer(Module *M, Decl *Init);
> > +
> > + void addLazyModuleInitializers(Module *M, ArrayRef<uint32_t> IDs);
> > +
> > + /// Get the initializations to perform when importing a module, if any.
> > + ArrayRef<Decl*> getModuleInitializers(Module *M);
> > +
> > TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
> >
> > ExternCContextDecl *getExternCContextDecl() const;
> >
> > Modified: cfe/trunk/include/clang/Sema/Sema.h
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=276159&r1=276158&r2=276159&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=276159&r1=276158&r2=276159&view=diff>
> > ==============================================================================
> > --- cfe/trunk/include/clang/Sema/Sema.h (original)
> > +++ cfe/trunk/include/clang/Sema/Sema.h Wed Jul 20 14:10:16 2016
> > @@ -1390,8 +1390,14 @@ private:
> > bool RequireCompleteTypeImpl(SourceLocation Loc, QualType T,
> > TypeDiagnoser *Diagnoser);
> >
> > + struct ModuleScope {
> > + clang::Module *Module;
> > + VisibleModuleSet OuterVisibleModules;
> > + };
> > + /// The modules we're currently parsing.
> > + llvm::SmallVector<ModuleScope, 16> ModuleScopes;
> > +
> > VisibleModuleSet VisibleModules;
> > - llvm::SmallVector<VisibleModuleSet, 16> VisibleModulesStack;
> >
> > Module *CachedFakeTopLevelModule;
> >
> >
> > Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=276159&r1=276158&r2=276159&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=276159&r1=276158&r2=276159&view=diff>
> > ==============================================================================
> > --- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
> > +++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Wed Jul 20 14:10:16 2016
> > @@ -684,6 +684,9 @@ namespace clang {
> > /// \brief Specifies a header that is private to this submodule but
> > /// must be textually included.
> > SUBMODULE_PRIVATE_TEXTUAL_HEADER = 15,
> > + /// \brief Specifies some declarations with initializers that must be
> > + /// emitted to initialize the module.
> > + SUBMODULE_INITIALIZERS = 16,
> > };
> >
> > /// \brief Record types used within a comments block.
> >
> > Modified: cfe/trunk/lib/AST/ASTContext.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=276159&r1=276158&r2=276159&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=276159&r1=276158&r2=276159&view=diff>
> > ==============================================================================
> > --- cfe/trunk/lib/AST/ASTContext.cpp (original)
> > +++ cfe/trunk/lib/AST/ASTContext.cpp Wed Jul 20 14:10:16 2016
> > @@ -901,6 +901,67 @@ void ASTContext::deduplicateMergedDefini
> > Merged.erase(std::remove(Merged.begin(), Merged.end(), nullptr), Merged.end());
> > }
> >
> > +void ASTContext::PerModuleInitializers::resolve(ASTContext &Ctx) {
> > + if (LazyInitializers.empty())
> > + return;
> > +
> > + auto *Source = Ctx.getExternalSource();
> > + assert(Source && "lazy initializers but no external source");
> > +
> > + auto LazyInits = std::move(LazyInitializers);
> > + LazyInitializers.clear();
> > +
> > + for (auto ID : LazyInits)
> > + Initializers.push_back(Source->GetExternalDecl(ID));
> > +
> > + assert(LazyInitializers.empty() &&
> > + "GetExternalDecl for lazy module initializer added more inits");
> > +}
> > +
> > +void ASTContext::addModuleInitializer(Module *M, Decl *D) {
> > + // One special case: if we add a module initializer that imports another
> > + // module, and that module's only initializer is an ImportDecl, simplify.
> > + if (auto *ID = dyn_cast<ImportDecl>(D)) {
> > + auto It = ModuleInitializers.find(ID->getImportedModule());
> > +
> > + // Maybe the ImportDecl does nothing at all. (Common case.)
> > + if (It == ModuleInitializers.end())
> > + return;
> > +
> > + // Maybe the ImportDecl only imports another ImportDecl.
> > + auto &Imported = *It->second;
> > + if (Imported.Initializers.size() + Imported.LazyInitializers.size() == 1) {
> > + Imported.resolve(*this);
> > + auto *OnlyDecl = Imported.Initializers.front();
> > + if (isa<ImportDecl>(OnlyDecl))
> > + D = OnlyDecl;
> > + }
> > + }
> > +
> > + auto *&Inits = ModuleInitializers[M];
> > + if (!Inits)
> > + Inits = new (*this) PerModuleInitializers;
> > + Inits->Initializers.push_back(D);
> > +}
> > +
> > +void ASTContext::addLazyModuleInitializers(Module *M, ArrayRef<uint32_t> IDs) {
> > + auto *&Inits = ModuleInitializers[M];
> > + if (!Inits)
> > + Inits = new (*this) PerModuleInitializers;
> > + Inits->LazyInitializers.insert(Inits->LazyInitializers.end(),
> > + IDs.begin(), IDs.end());
> > +}
> > +
> > +ArrayRef<Decl*> ASTContext::getModuleInitializers(Module *M) {
> > + auto It = ModuleInitializers.find(M);
> > + if (It == ModuleInitializers.end())
> > + return None;
> > +
> > + auto *Inits = It->second;
> > + Inits->resolve(*this);
> > + return Inits->Initializers;
> > +}
> > +
> > ExternCContextDecl *ASTContext::getExternCContextDecl() const {
> > if (!ExternCContext)
> > ExternCContext = ExternCContextDecl::Create(*this, getTranslationUnitDecl());
> > @@ -8575,6 +8636,8 @@ bool ASTContext::DeclMustBeEmitted(const
> > return !D->getDeclContext()->isDependentContext();
> > else if (isa<OMPDeclareReductionDecl>(D))
> > return !D->getDeclContext()->isDependentContext();
> > + else if (isa<ImportDecl>(D))
> > + return true;
> > else
> > return false;
> >
> >
> > Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=276159&r1=276158&r2=276159&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=276159&r1=276158&r2=276159&view=diff>
> > ==============================================================================
> > --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
> > +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Wed Jul 20 14:10:16 2016
> > @@ -3910,13 +3910,19 @@ void CodeGenModule::EmitTopLevelDecl(Dec
> > case Decl::Import: {
> > auto *Import = cast<ImportDecl>(D);
> >
> > - // Ignore import declarations that come from imported modules.
> > - if (Import->getImportedOwningModule())
> > + // If we've already imported this module, we're done.
> > + if (!ImportedModules.insert(Import->getImportedModule()))
> > break;
> > - if (CGDebugInfo *DI = getModuleDebugInfo())
> > - DI->EmitImportDecl(*Import);
> >
> > - ImportedModules.insert(Import->getImportedModule());
> > + // Emit debug information for direct imports.
> > + if (!Import->getImportedOwningModule()) {
> > + if (CGDebugInfo *DI = getModuleDebugInfo())
> > + DI->EmitImportDecl(*Import);
> > + }
> > +
> > + // Emit the module initializers.
> > + for (auto *D : Context.getModuleInitializers(Import->getImportedModule()))
> > + EmitTopLevelDecl(D);
> > break;
> > }
> >
> >
> > Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=276159&r1=276158&r2=276159&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=276159&r1=276158&r2=276159&view=diff>
> > ==============================================================================
> > --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
> > +++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Jul 20 14:10:16 2016
> > @@ -10473,6 +10473,11 @@ void Sema::CheckCompleteVariableDeclarat
> > // Require the destructor.
> > if (const RecordType *recordType = baseType->getAs<RecordType>())
> > FinalizeVarWithDestructor(var, recordType);
> > +
> > + // If this variable must be emitted, add it as an initializer for the current
> > + // module.
> > + if (Context.DeclMustBeEmitted(var) && !ModuleScopes.empty())
> > + Context.addModuleInitializer(ModuleScopes.back().Module, var);
> > }
> >
> > /// \brief Determines if a variable's alignment is dependent.
> > @@ -15095,11 +15100,13 @@ DeclResult Sema::ActOnModuleImport(Sourc
> > IdentifierLocs.push_back(Path[I].second);
> > }
> >
> > - ImportDecl *Import = ImportDecl::Create(Context,
> > - Context.getTranslationUnitDecl(),
> > + TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl();
> > + ImportDecl *Import = ImportDecl::Create(Context, TU,
> > AtLoc.isValid()? AtLoc : ImportLoc,
> > Mod, IdentifierLocs);
> > - Context.getTranslationUnitDecl()->addDecl(Import);
> > + if (!ModuleScopes.empty())
> > + Context.addModuleInitializer(ModuleScopes.back().Module, Import);
> > + TU->addDecl(Import);
> > return Import;
> > }
> >
> > @@ -15115,13 +15122,7 @@ void Sema::ActOnModuleInclude(SourceLoca
> > TUKind == TU_Module &&
> > getSourceManager().isWrittenInMainFile(DirectiveLoc);
> >
> > - // Similarly, if we're in the implementation of a module, don't
> > - // synthesize an illegal module import. FIXME: Why not?
> > - bool ShouldAddImport =
> > - !IsInModuleIncludes &&
> > - (getLangOpts().CompilingModule ||
> > - getLangOpts().CurrentModule.empty() ||
> > - getLangOpts().CurrentModule != Mod->getTopLevelModuleName());
> > + bool ShouldAddImport = !IsInModuleIncludes;
> >
> > // If this module import was due to an inclusion directive, create an
> > // implicit import declaration to capture it in the AST.
> > @@ -15130,6 +15131,8 @@ void Sema::ActOnModuleInclude(SourceLoca
> > ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU,
> > DirectiveLoc, Mod,
> > DirectiveLoc);
> > + if (!ModuleScopes.empty())
> > + Context.addModuleInitializer(ModuleScopes.back().Module, ImportD);
> > TU->addDecl(ImportD);
> > Consumer.HandleImplicitImportDecl(ImportD);
> > }
> > @@ -15141,8 +15144,11 @@ void Sema::ActOnModuleInclude(SourceLoca
> > void Sema::ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod) {
> > checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext);
> >
> > + ModuleScopes.push_back({});
> > + ModuleScopes.back().Module = Mod;
> > if (getLangOpts().ModulesLocalVisibility)
> > - VisibleModulesStack.push_back(std::move(VisibleModules));
> > + ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules);
> > +
> > VisibleModules.setVisible(Mod, DirectiveLoc);
> > }
> >
> > @@ -15150,8 +15156,11 @@ void Sema::ActOnModuleEnd(SourceLocation
> > checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext);
> >
> > if (getLangOpts().ModulesLocalVisibility) {
> > - VisibleModules = std::move(VisibleModulesStack.back());
> > - VisibleModulesStack.pop_back();
> > + assert(!ModuleScopes.empty() && ModuleScopes.back().Module == Mod &&
> > + "left the wrong module scope");
> > + VisibleModules = std::move(ModuleScopes.back().OuterVisibleModules);
> > + ModuleScopes.pop_back();
> > +
> > VisibleModules.setVisible(Mod, DirectiveLoc);
> > // Leaving a module hides namespace names, so our visible namespace cache
> > // is now out of date.
> >
> > Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=276159&r1=276158&r2=276159&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=276159&r1=276158&r2=276159&view=diff>
> > ==============================================================================
> > --- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
> > +++ cfe/trunk/lib/Sema/SemaLookup.cpp Wed Jul 20 14:10:16 2016
> > @@ -1367,8 +1367,9 @@ Module *Sema::getOwningModule(Decl *Enti
> > auto &SrcMgr = PP.getSourceManager();
> > SourceLocation StartLoc =
> > SrcMgr.getLocForStartOfFile(SrcMgr.getMainFileID());
> > - auto &TopLevel =
> > - VisibleModulesStack.empty() ? VisibleModules : VisibleModulesStack[0];
> > + auto &TopLevel = ModuleScopes.empty()
> > + ? VisibleModules
> > + : ModuleScopes[0].OuterVisibleModules;
> > TopLevel.setVisible(CachedFakeTopLevelModule, StartLoc);
> > }
> >
> >
> > Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=276159&r1=276158&r2=276159&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=276159&r1=276158&r2=276159&view=diff>
> > ==============================================================================
> > --- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
> > +++ cfe/trunk/lib/Serialization/ASTReader.cpp Wed Jul 20 14:10:16 2016
> > @@ -4673,6 +4673,13 @@ ASTReader::ReadSubmoduleBlock(ModuleFile
> > UnresolvedModuleRefs.push_back(Unresolved);
> > break;
> > }
> > +
> > + case SUBMODULE_INITIALIZERS:
> > + SmallVector<uint32_t, 16> Inits;
> > + for (auto &ID : Record)
> > + Inits.push_back(getGlobalDeclID(F, ID));
> > + Context.addLazyModuleInitializers(CurrentModule, Inits);
> > + break;
> > }
> > }
> > }
> >
> > Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=276159&r1=276158&r2=276159&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=276159&r1=276158&r2=276159&view=diff>
> > ==============================================================================
> > --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
> > +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Wed Jul 20 14:10:16 2016
> > @@ -2493,10 +2493,16 @@ inline void ASTReader::LoadedDecl(unsign
> > /// This routine should return true for anything that might affect
> > /// code generation, e.g., inline function definitions, Objective-C
> > /// declarations with metadata, etc.
> > -static bool isConsumerInterestedIn(Decl *D, bool HasBody) {
> > +static bool isConsumerInterestedIn(ASTContext &Ctx, Decl *D, bool HasBody) {
> > // An ObjCMethodDecl is never considered as "interesting" because its
> > // implementation container always is.
> >
> > + // An ImportDecl or VarDecl imported from a module will get emitted when
> > + // we import the relevant module.
> > + if ((isa<ImportDecl>(D) || isa<VarDecl>(D)) && Ctx.DeclMustBeEmitted(D) &&
> > + D->getImportedOwningModule())
> > + return false;
> > +
> > if (isa<FileScopeAsmDecl>(D) ||
> > isa<ObjCProtocolDecl>(D) ||
> > isa<ObjCImplDecl>(D) ||
> > @@ -3473,7 +3479,7 @@ Decl *ASTReader::ReadDeclRecord(DeclID I
> > // 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()))
> > + if (isConsumerInterestedIn(Context, D, Reader.hasPendingBody()))
> > InterestingDecls.push_back(D);
> >
> > return D;
> > @@ -3488,7 +3494,7 @@ void ASTReader::loadDeclUpdateRecords(se
> > auto UpdateOffsets = std::move(UpdI->second);
> > DeclUpdateOffsets.erase(UpdI);
> >
> > - bool WasInteresting = isConsumerInterestedIn(D, false);
> > + bool WasInteresting = isConsumerInterestedIn(Context, D, false);
> > for (auto &FileAndOffset : UpdateOffsets) {
> > ModuleFile *F = FileAndOffset.first;
> > uint64_t Offset = FileAndOffset.second;
> > @@ -3509,7 +3515,7 @@ void ASTReader::loadDeclUpdateRecords(se
> > // We might have made this declaration interesting. If so, remember that
> > // we need to hand it off to the consumer.
> > if (!WasInteresting &&
> > - isConsumerInterestedIn(D, Reader.hasPendingBody())) {
> > + isConsumerInterestedIn(Context, D, Reader.hasPendingBody())) {
> > InterestingDecls.push_back(D);
> > WasInteresting = true;
> > }
> >
> > Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=276159&r1=276158&r2=276159&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=276159&r1=276158&r2=276159&view=diff>
> > ==============================================================================
> > --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
> > +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Wed Jul 20 14:10:16 2016
> > @@ -1017,6 +1017,7 @@ void ASTWriter::WriteBlockInfoBlock() {
> > RECORD(SUBMODULE_PRIVATE_HEADER);
> > RECORD(SUBMODULE_TEXTUAL_HEADER);
> > RECORD(SUBMODULE_PRIVATE_TEXTUAL_HEADER);
> > + RECORD(SUBMODULE_INITIALIZERS);
> >
> > // Comments Block.
> > BLOCK(COMMENTS_BLOCK);
> > @@ -2417,7 +2418,9 @@ unsigned ASTWriter::getLocalOrImportedSu
> > if (Known != SubmoduleIDs.end())
> > return Known->second;
> >
> > - if (Mod->getTopLevelModule() != WritingModule)
> > + auto *Top = Mod->getTopLevelModule();
> > + if (Top != WritingModule &&
> > + !Top->fullModuleNameIs(StringRef(getLangOpts().CurrentModule)))
> > return 0;
> >
> > return SubmoduleIDs[Mod] = NextSubmoduleID++;
> > @@ -2649,6 +2652,13 @@ void ASTWriter::WriteSubmodules(Module *
> > Stream.EmitRecordWithBlob(ConfigMacroAbbrev, Record, CM);
> > }
> >
> > + // Emit the initializers, if any.
> > + RecordData Inits;
> > + for (Decl *D : Context->getModuleInitializers(Mod))
> > + Inits.push_back(GetDeclRef(D));
> > + if (!Inits.empty())
> > + Stream.EmitRecord(SUBMODULE_INITIALIZERS, Inits);
> > +
> > // Queue up the submodules of this module.
> > for (auto *M : Mod->submodules())
> > Q.push(M);
> > @@ -4514,6 +4524,17 @@ uint64_t ASTWriter::WriteASTCore(Sema &S
> > // If we're emitting a module, write out the submodule information.
> > if (WritingModule)
> > WriteSubmodules(WritingModule);
> > + else if (!getLangOpts().CurrentModule.empty()) {
> > + // If we're building a PCH in the implementation of a module, we may need
> > + // the description of the current module.
> > + //
> > + // FIXME: We may need other modules that we did not load from an AST file,
> > + // such as if a module declares a 'conflicts' on a different module.
> > + Module *M = PP.getHeaderSearchInfo().getModuleMap().findModule(
> > + getLangOpts().CurrentModule);
> > + if (M && !M->IsFromModuleFile)
> > + WriteSubmodules(M);
> > + }
> >
> > Stream.EmitRecord(SPECIAL_TYPES, SpecialTypes);
> >
> >
> > Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=276159&r1=276158&r2=276159&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=276159&r1=276158&r2=276159&view=diff>
> > ==============================================================================
> > --- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
> > +++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Wed Jul 20 14:10:16 2016
> > @@ -2122,11 +2122,11 @@ static bool isRequiredDecl(const Decl *D
> > D->hasAttr<OMPDeclareTargetDeclAttr>())
> > return true;
> >
> > - // 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<ImportDecl>(D) && !WritingModule)
> > - return true;
> > + if (WritingModule && (isa<VarDecl>(D) || isa<ImportDecl>(D))) {
> > + // These declarations are part of the module initializer, and are emitted
> > + // if and when the module is imported, rather than being emitted eagerly.
> > + return false;
> > + }
> >
> > return Context.DeclMustBeEmitted(D);
> > }
> >
> > Modified: cfe/trunk/test/Modules/Inputs/unused-global-init/used.h
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/unused-global-init/used.h?rev=276159&r1=275623&r2=276159&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/unused-global-init/used.h?rev=276159&r1=275623&r2=276159&view=diff>
> > ==============================================================================
> > --- cfe/trunk/test/Modules/Inputs/unused-global-init/used.h (original)
> > +++ cfe/trunk/test/Modules/Inputs/unused-global-init/used.h Wed Jul 20 14:10:16 2016
> > @@ -1,2 +1,2 @@
> > // used.h
> > -#include "other.h"
> > +#include "init.h"
> >
> > Modified: cfe/trunk/test/Modules/odr.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr.cpp?rev=276159&r1=276158&r2=276159&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr.cpp?rev=276159&r1=276158&r2=276159&view=diff>
> > ==============================================================================
> > --- cfe/trunk/test/Modules/odr.cpp (original)
> > +++ cfe/trunk/test/Modules/odr.cpp Wed Jul 20 14:10:16 2016
> > @@ -15,9 +15,9 @@ bool b = F<int>{0} == F<int>{1};
> > int x = f() + g();
> >
> > // expected-note at a.h:5 {{definition has no member 'e2'}}
> > -// expected-note at b.h:3 {{declaration of 'f' does not match}}
> > -// expected-note at b.h:1 {{definition has no member 'n'}}
> > +// expected-note at a.h:3 {{declaration of 'f' does not match}}
> > +// expected-note at a.h:1 {{definition has no member 'm'}}
> >
> > // expected-error at b.h:5 {{'E::e2' from module 'b' is not present in definition of 'E' in module 'a'}}
> > -// expected-error at a.h:3 {{'Y::f' from module 'a' is not present in definition of 'Y' in module 'b'}}
> > -// expected-error at a.h:2 {{'Y::n' from module 'a' is not present in definition of 'Y' in module 'b'}}
> > +// expected-error at b.h:3 {{'Y::f' from module 'b' is not present in definition of 'Y' in module 'a'}}
> > +// expected-error at b.h:2 {{'Y::m' from module 'b' is not present in definition of 'Y' in module 'a'}}
> >
> > Modified: cfe/trunk/test/Modules/templates.mm <http://templates.mm/>
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/templates.mm?rev=276159&r1=276158&r2=276159&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/templates.mm?rev=276159&r1=276158&r2=276159&view=diff>
> > ==============================================================================
> > --- cfe/trunk/test/Modules/templates.mm <http://templates.mm/> (original)
> > +++ cfe/trunk/test/Modules/templates.mm <http://templates.mm/> Wed Jul 20 14:10:16 2016
> > @@ -12,10 +12,10 @@ void testInlineRedeclEarly() {
> >
> > @import templates_right;
> >
> > -// CHECK-DAG: @list_left = global %class.List { %"struct.List<int>::node"* null, i32 8 }, align 8
> > -// CHECK-DAG: @list_right = global %class.List { %"struct.List<int>::node"* null, i32 12 }, align 8
> > -// CHECK-DAG: @_ZZ15testMixedStructvE1l = {{.*}} constant %class.List { %{{.*}}* null, i32 1 }, align 8
> > -// CHECK-DAG: @_ZZ15testMixedStructvE1r = {{.*}} constant %class.List { %{{.*}}* null, i32 2 }, align 8
> > +// CHECK-DAG: @list_left = global %[[LIST:.*]] { %[[LISTNODE:.*]]* null, i32 8 }, align 8
> > +// CHECK-DAG: @list_right = global %[[LIST]] { %[[LISTNODE]]* null, i32 12 }, align 8
> > +// CHECK-DAG: @_ZZ15testMixedStructvE1l = {{.*}} constant %[[LIST]] { %{{.*}}* null, i32 1 }, align 8
> > +// CHECK-DAG: @_ZZ15testMixedStructvE1r = {{.*}} constant %[[LIST]] { %{{.*}}* null, i32 2 }, align 8
> > // CHECK-DAG: @_ZN29WithUndefinedStaticDataMemberIA_iE9undefinedE = external global
> >
> > void testTemplateClasses() {
> >
> > Copied: cfe/trunk/test/Modules/unused-global-init.cpp (from r275623, cfe/trunk/test/Modules/unused-global-init.cpp)
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/unused-global-init.cpp?p2=cfe/trunk/test/Modules/unused-global-init.cpp&p1=cfe/trunk/test/Modules/unused-global-init.cpp&r1=275623&r2=276159&rev=276159&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/unused-global-init.cpp?p2=cfe/trunk/test/Modules/unused-global-init.cpp&p1=cfe/trunk/test/Modules/unused-global-init.cpp&r1=275623&r2=276159&rev=276159&view=diff>
> > ==============================================================================
> > --- cfe/trunk/test/Modules/unused-global-init.cpp (original)
> > +++ cfe/trunk/test/Modules/unused-global-init.cpp Wed Jul 20 14:10:16 2016
> > @@ -6,13 +6,14 @@
> > //
> > // 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
> > +// RUN: %clang_cc1 -fmodules -fno-implicit-modules -x c++ -I %S/Inputs/unused-global-init -triple %itanium_abi_triple -emit-llvm -o - %s -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 -DOTHER -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 -DOTHER | FileCheck --check-prefix=CHECK-NO-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
> >
> >
> >
> > _______________________________________________
> > cfe-commits mailing list
> > cfe-commits at lists.llvm.org <mailto:cfe-commits at lists.llvm.org>
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org <mailto:cfe-commits at lists.llvm.org>
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20161014/f431bb5d/attachment-0001.html>
More information about the cfe-commits
mailing list