r276159 - [modules] Don't emit initializers for VarDecls within a module eagerly whenever

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 20 12:10:16 PDT 2016


Author: rsmith
Date: Wed Jul 20 14:10:16 2016
New Revision: 276159

URL: 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

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
==============================================================================
--- 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
==============================================================================
--- 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
==============================================================================
--- 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
==============================================================================
--- 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
==============================================================================
--- 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
==============================================================================
--- 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
==============================================================================
--- 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
==============================================================================
--- 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
==============================================================================
--- 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
==============================================================================
--- 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
==============================================================================
--- 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
==============================================================================
--- 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
==============================================================================
--- 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
URL: 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 (original)
+++ cfe/trunk/test/Modules/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
==============================================================================
--- 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
 




More information about the cfe-commits mailing list