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 <rich...@metafoo.co.uk> wrote: > > On Thu, Oct 13, 2016 at 11:52 AM, Manman via cfe-commits > <cfe-commits@lists.llvm.org <mailto:cfe-commits@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@lists.llvm.org <mailto:cfe-commits@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@a.h:5 {{definition has no member 'e2'}} > > -// expected-note@b.h:3 {{declaration of 'f' does not match}} > > -// expected-note@b.h:1 {{definition has no member 'n'}} > > +// expected-note@a.h:3 {{declaration of 'f' does not match}} > > +// expected-note@a.h:1 {{definition has no member 'm'}} > > > > // expected-error@b.h:5 {{'E::e2' from module 'b' is not present in > > definition of 'E' in module 'a'}} > > -// expected-error@a.h:3 {{'Y::f' from module 'a' is not present in > > definition of 'Y' in module 'b'}} > > -// expected-error@a.h:2 {{'Y::n' from module 'a' is not present in > > definition of 'Y' in module 'b'}} > > +// expected-error@b.h:3 {{'Y::f' from module 'b' is not present in > > definition of 'Y' in module 'a'}} > > +// expected-error@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@lists.llvm.org <mailto:cfe-commits@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@lists.llvm.org <mailto:cfe-commits@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@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits