r312467 - Implement Itanium name mangling support for C++ Modules TS.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Sun Sep 3 22:37:53 PDT 2017


Author: rsmith
Date: Sun Sep  3 22:37:53 2017
New Revision: 312467

URL: http://llvm.org/viewvc/llvm-project?rev=312467&view=rev
Log:
Implement Itanium name mangling support for C++ Modules TS.

This follows the scheme agreed with Nathan Sidwell, which can be found here:

  https://gcc.gnu.org/wiki/cxx-modules?action=AttachFile

This will be proposed to the itanium-cxx-abi list once we have some experience
with how well it works; the ABI for this TS should be considered unstable until
it is part of the Itanium C++ ABI.

Modified:
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/AST/DeclBase.h
    cfe/trunk/include/clang/Basic/Module.h
    cfe/trunk/include/clang/Lex/ModuleMap.h
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/ItaniumMangle.cpp
    cfe/trunk/lib/Lex/ModuleMap.cpp
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp
    cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cppm
    cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp
    cfe/trunk/test/CXX/modules-ts/codegen-basics.cppm
    cfe/trunk/test/SemaCXX/modules-ts.cppm

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=312467&r1=312466&r2=312467&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Sun Sep  3 22:37:53 2017
@@ -372,6 +372,10 @@ public:
     return hasCachedLinkage();
   }
 
+  /// Get the module that owns this declaration for linkage purposes.
+  /// There only ever is such a module under the C++ Modules TS.
+  Module *getOwningModuleForLinkage() const;
+
   /// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for
   /// the underlying named decl.
   NamedDecl *getUnderlyingDecl() {

Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=312467&r1=312466&r2=312467&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Sun Sep  3 22:37:53 2017
@@ -733,7 +733,7 @@ public:
     return getModuleOwnershipKind() != ModuleOwnershipKind::Unowned;
   }
 
-  /// Get the module that owns this declaration.
+  /// Get the module that owns this declaration (for visibility purposes).
   Module *getOwningModule() const {
     return isFromASTFile() ? getImportedOwningModule() : getLocalOwningModule();
   }

Modified: cfe/trunk/include/clang/Basic/Module.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Module.h?rev=312467&r1=312466&r2=312467&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Module.h (original)
+++ cfe/trunk/include/clang/Basic/Module.h Sun Sep  3 22:37:53 2017
@@ -68,7 +68,11 @@ public:
     ModuleMapModule,
 
     /// \brief This is a C++ Modules TS module interface unit.
-    ModuleInterfaceUnit
+    ModuleInterfaceUnit,
+
+    /// \brief This is a fragment of the global module within some C++ Modules
+    /// TS module.
+    GlobalModuleFragment,
   };
 
   /// \brief The kind of this module.
@@ -391,6 +395,15 @@ public:
     return IsFramework && Parent && Parent->isPartOfFramework();
   }
 
+  /// Set the parent of this module. This should only be used if the parent
+  /// could not be set during module creation.
+  void setParent(Module *M) {
+    assert(!Parent);
+    Parent = M;
+    Parent->SubModuleIndex[Name] = Parent->SubModules.size();
+    Parent->SubModules.push_back(this);
+  }
+
   /// \brief Retrieve the full name of this module, including the path from
   /// its top-level module.
   /// \param AllowStringLiterals If \c true, components that might not be

Modified: cfe/trunk/include/clang/Lex/ModuleMap.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/ModuleMap.h?rev=312467&r1=312466&r2=312467&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/ModuleMap.h (original)
+++ cfe/trunk/include/clang/Lex/ModuleMap.h Sun Sep  3 22:37:53 2017
@@ -472,6 +472,14 @@ public:
                                                bool IsFramework,
                                                bool IsExplicit);
 
+  /// \brief Create a 'global module' for a C++ Modules TS module interface
+  /// unit.
+  ///
+  /// We model the global module as a submodule of the module interface unit.
+  /// Unfortunately, we can't create the module interface unit's Module until
+  /// later, because we don't know what it will be called.
+  Module *createGlobalModuleForInterfaceUnit(SourceLocation Loc);
+
   /// \brief Create a new module for a C++ Modules TS module interface unit.
   /// The module must not already exist, and will be configured for the current
   /// compilation.
@@ -479,7 +487,8 @@ public:
   /// Note that this also sets the current module to the newly-created module.
   ///
   /// \returns The newly-created module.
-  Module *createModuleForInterfaceUnit(SourceLocation Loc, StringRef Name);
+  Module *createModuleForInterfaceUnit(SourceLocation Loc, StringRef Name,
+                                       Module *GlobalModule);
 
   /// \brief Infer the contents of a framework module map from the given
   /// framework directory.

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=312467&r1=312466&r2=312467&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Sun Sep  3 22:37:53 2017
@@ -652,7 +652,7 @@ LinkageComputer::getLVForNamespaceScopeD
   //   If the declaration of an identifier for an object has file
   //   scope and no storage-class specifier, its linkage is
   //   external.
-  LinkageInfo LV;
+  LinkageInfo LV = getExternalLinkageFor(D);
 
   if (!hasExplicitVisibilityAlready(computation)) {
     if (Optional<Visibility> Vis = getExplicitVisibility(D, computation)) {
@@ -1399,6 +1399,30 @@ LinkageInfo LinkageComputer::getDeclLink
   return getLVForDecl(D, usesTypeVisibility(D) ? LVForType : LVForValue);
 }
 
+Module *NamedDecl::getOwningModuleForLinkage() const {
+  Module *M = getOwningModule();
+  if (!M)
+    return nullptr;
+
+  switch (M->Kind) {
+  case Module::ModuleMapModule:
+    // Module map modules have no special linkage semantics.
+    return nullptr;
+
+  case Module::ModuleInterfaceUnit:
+    return M;
+
+  case Module::GlobalModuleFragment:
+    // External linkage declarations in the global module have no owning module
+    // for linkage purposes. But internal linkage declarations in the global
+    // module fragment of a particular module are owned by that module for
+    // linkage purposes.
+    return hasExternalFormalLinkage() ? nullptr : M->Parent;
+  }
+
+  llvm_unreachable("unknown module kind");
+}
+
 void NamedDecl::printName(raw_ostream &os) const {
   os << Name;
 }

Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=312467&r1=312466&r2=312467&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Sun Sep  3 22:37:53 2017
@@ -381,6 +381,7 @@ class CXXNameMangler {
   AbiTagState AbiTagsRoot;
 
   llvm::DenseMap<uintptr_t, unsigned> Substitutions;
+  llvm::DenseMap<StringRef, unsigned> ModuleSubstitutions;
 
   ASTContext &getASTContext() const { return Context.getASTContext(); }
 
@@ -475,6 +476,8 @@ private:
 
   void mangleNameWithAbiTags(const NamedDecl *ND,
                              const AbiTagList *AdditionalAbiTags);
+  void mangleModuleName(const Module *M);
+  void mangleModuleNamePrefix(StringRef Name);
   void mangleTemplateName(const TemplateDecl *TD,
                           const TemplateArgument *TemplateArgs,
                           unsigned NumTemplateArgs);
@@ -845,9 +848,9 @@ void CXXNameMangler::mangleName(const Na
 
 void CXXNameMangler::mangleNameWithAbiTags(const NamedDecl *ND,
                                            const AbiTagList *AdditionalAbiTags) {
-  //  <name> ::= <nested-name>
-  //         ::= <unscoped-name>
-  //         ::= <unscoped-template-name> <template-args>
+  //  <name> ::= [<module-name>] <nested-name>
+  //         ::= [<module-name>] <unscoped-name>
+  //         ::= [<module-name>] <unscoped-template-name> <template-args>
   //         ::= <local-name>
   //
   const DeclContext *DC = getEffectiveDeclContext(ND);
@@ -866,6 +869,19 @@ void CXXNameMangler::mangleNameWithAbiTa
 
   DC = IgnoreLinkageSpecDecls(DC);
 
+  if (isLocalContainerContext(DC)) {
+    mangleLocalName(ND, AdditionalAbiTags);
+    return;
+  }
+
+  // Do not mangle the owning module for an external linkage declaration.
+  // This enables backwards-compatibility with non-modular code, and is
+  // a valid choice since conflicts are not permitted by C++ Modules TS
+  // [basic.def.odr]/6.2.
+  if (!ND->hasExternalFormalLinkage())
+    if (Module *M = ND->getOwningModuleForLinkage())
+      mangleModuleName(M);
+
   if (DC->isTranslationUnit() || isStdNamespace(DC)) {
     // Check if we have a template.
     const TemplateArgumentList *TemplateArgs = nullptr;
@@ -879,12 +895,42 @@ void CXXNameMangler::mangleNameWithAbiTa
     return;
   }
 
-  if (isLocalContainerContext(DC)) {
-    mangleLocalName(ND, AdditionalAbiTags);
+  mangleNestedName(ND, DC, AdditionalAbiTags);
+}
+
+void CXXNameMangler::mangleModuleName(const Module *M) {
+  // Implement the C++ Modules TS name mangling proposal; see
+  //     https://gcc.gnu.org/wiki/cxx-modules?action=AttachFile
+  //
+  //   <module-name> ::= W <unscoped-name>+ E
+  //                 ::= W <module-subst> <unscoped-name>* E
+  Out << 'W';
+  mangleModuleNamePrefix(M->Name);
+  Out << 'E';
+}
+
+void CXXNameMangler::mangleModuleNamePrefix(StringRef Name) {
+  //  <module-subst> ::= _ <seq-id>          # 0 < seq-id < 10
+  //                 ::= W <seq-id - 10> _   # otherwise
+  auto It = ModuleSubstitutions.find(Name);
+  if (It != ModuleSubstitutions.end()) {
+    if (It->second < 10)
+      Out << '_' << static_cast<char>('0' + It->second);
+    else
+      Out << 'W' << (It->second - 10) << '_';
     return;
   }
 
-  mangleNestedName(ND, DC, AdditionalAbiTags);
+  // FIXME: Preserve hierarchy in module names rather than flattening
+  // them to strings; use Module*s as substitution keys.
+  auto Parts = Name.rsplit('.');
+  if (Parts.second.empty())
+    Parts.second = Parts.first;
+  else
+    mangleModuleNamePrefix(Parts.first);
+
+  Out << Parts.second.size() << Parts.second;
+  ModuleSubstitutions.insert({Name, ModuleSubstitutions.size()});
 }
 
 void CXXNameMangler::mangleTemplateName(const TemplateDecl *TD,
@@ -1233,13 +1279,16 @@ void CXXNameMangler::mangleUnqualifiedNa
     }
 
     if (II) {
-      // We must avoid conflicts between internally- and externally-
-      // linked variable and function declaration names in the same TU:
+      // Match GCC's naming convention for internal linkage symbols, for
+      // symbols that are not actually visible outside of this TU. GCC
+      // distinguishes between internal and external linkage symbols in
+      // its mangling, to support cases like this that were valid C++ prior
+      // to DR426:
+      //
       //   void test() { extern void foo(); }
       //   static void foo();
-      // This naming convention is the same as that followed by GCC,
-      // though it shouldn't actually matter.
       if (ND && ND->getFormalLinkage() == InternalLinkage &&
+          !ND->isExternallyVisible() &&
           getEffectiveDeclContext(ND)->isFileContext())
         Out << 'L';
 

Modified: cfe/trunk/lib/Lex/ModuleMap.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ModuleMap.cpp?rev=312467&r1=312466&r2=312467&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/ModuleMap.cpp (original)
+++ cfe/trunk/lib/Lex/ModuleMap.cpp Sun Sep  3 22:37:53 2017
@@ -746,8 +746,16 @@ std::pair<Module *, bool> ModuleMap::fin
   return std::make_pair(Result, true);
 }
 
+Module *ModuleMap::createGlobalModuleForInterfaceUnit(SourceLocation Loc) {
+  auto *Result = new Module("<global>", Loc, nullptr, /*IsFramework*/ false,
+                            /*IsExplicit*/ true, NumCreatedModules++);
+  Result->Kind = Module::GlobalModuleFragment;
+  return Result;
+}
+
 Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc,
-                                                StringRef Name) {
+                                                StringRef Name,
+                                                Module *GlobalModule) {
   assert(LangOpts.CurrentModule == Name && "module name mismatch");
   assert(!Modules[Name] && "redefining existing module");
 
@@ -757,6 +765,9 @@ Module *ModuleMap::createModuleForInterf
   Result->Kind = Module::ModuleInterfaceUnit;
   Modules[Name] = SourceModule = Result;
 
+  // Reparent the current global module fragment as a submodule of this module.
+  GlobalModule->setParent(Result);
+
   // Mark the main source file as being within the newly-created module so that
   // declarations and macros are properly visibility-restricted to it.
   auto *MainFile = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID());

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=312467&r1=312466&r2=312467&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Sun Sep  3 22:37:53 2017
@@ -766,10 +766,24 @@ void Sema::emitAndClearUnusedLocalTypede
 /// declarations.
 void Sema::ActOnStartOfTranslationUnit() {
   if (getLangOpts().ModulesTS) {
+    SourceLocation StartOfTU =
+        SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
+
     // We start in the global module; all those declarations are implicitly
     // module-private (though they do not have module linkage).
-    Context.getTranslationUnitDecl()->setModuleOwnershipKind(
-        Decl::ModuleOwnershipKind::ModulePrivate);
+    auto &Map = PP.getHeaderSearchInfo().getModuleMap();
+    auto *GlobalModule = Map.createGlobalModuleForInterfaceUnit(StartOfTU);
+    assert(GlobalModule && "module creation should not fail");
+
+    // Enter the scope of the global module.
+    ModuleScopes.push_back({});
+    ModuleScopes.back().Module = GlobalModule;
+    VisibleModules.setVisible(GlobalModule, StartOfTU);
+
+    // All declarations created from now on are owned by the global module.
+    auto *TU = Context.getTranslationUnitDecl();
+    TU->setModuleOwnershipKind(Decl::ModuleOwnershipKind::Visible);
+    TU->setLocalOwningModule(GlobalModule);
   }
 }
 

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=312467&r1=312466&r2=312467&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sun Sep  3 22:37:53 2017
@@ -16052,6 +16052,9 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDe
                                            SourceLocation ModuleLoc,
                                            ModuleDeclKind MDK,
                                            ModuleIdPath Path) {
+  assert(getLangOpts().ModulesTS &&
+         "should only have module decl in modules TS");
+
   // A module implementation unit requires that we are not compiling a module
   // of any kind. A module interface unit requires that we are not compiling a
   // module map.
@@ -16104,10 +16107,10 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDe
   auto &Map = PP.getHeaderSearchInfo().getModuleMap();
   Module *Mod;
 
+  assert(ModuleScopes.size() == 1 && "expected to be at global module scope");
+
   switch (MDK) {
   case ModuleDeclKind::Module: {
-    // FIXME: Check we're not in a submodule.
-
     // We can't have parsed or imported a definition of this module or parsed a
     // module map defining it already.
     if (auto *M = Map.findModule(ModuleName)) {
@@ -16121,7 +16124,8 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDe
     }
 
     // Create a Module for the module that we're defining.
-    Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName);
+    Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName,
+                                           ModuleScopes.front().Module);
     assert(Mod && "module creation should not fail");
     break;
   }
@@ -16140,16 +16144,16 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDe
     break;
   }
 
-  // Enter the semantic scope of the module.
-  ModuleScopes.push_back({});
+  // Switch from the global module to the named module.
   ModuleScopes.back().Module = Mod;
-  ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules);
   VisibleModules.setVisible(Mod, ModuleLoc);
 
   // From now on, we have an owning module for all declarations we see.
   // However, those declarations are module-private unless explicitly
   // exported.
-  Context.getTranslationUnitDecl()->setLocalOwningModule(Mod);
+  auto *TU = Context.getTranslationUnitDecl();
+  TU->setModuleOwnershipKind(Decl::ModuleOwnershipKind::ModulePrivate);
+  TU->setLocalOwningModule(Mod);
 
   // FIXME: Create a ModuleDecl.
   return nullptr;
@@ -16327,7 +16331,7 @@ Decl *Sema::ActOnStartExportDecl(Scope *
   // C++ Modules TS draft:
   //   An export-declaration shall appear in the purview of a module other than
   //   the global module.
-  if (ModuleScopes.empty() || !ModuleScopes.back().Module ||
+  if (ModuleScopes.empty() ||
       ModuleScopes.back().Module->Kind != Module::ModuleInterfaceUnit)
     Diag(ExportLoc, diag::err_export_not_in_module_interface);
 

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=312467&r1=312466&r2=312467&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Sun Sep  3 22:37:53 2017
@@ -4871,7 +4871,6 @@ ASTReader::ReadSubmoduleBlock(ModuleFile
   ModuleMap &ModMap = PP.getHeaderSearchInfo().getModuleMap();
   bool First = true;
   Module *CurrentModule = nullptr;
-  Module::ModuleKind ModuleKind = Module::ModuleMapModule;
   RecordData Record;
   while (true) {
     llvm::BitstreamEntry Entry = F.Stream.advanceSkippingSubblocks();
@@ -4919,6 +4918,7 @@ ASTReader::ReadSubmoduleBlock(ModuleFile
       unsigned Idx = 0;
       SubmoduleID GlobalID = getGlobalSubmoduleID(F, Record[Idx++]);
       SubmoduleID Parent = getGlobalSubmoduleID(F, Record[Idx++]);
+      Module::ModuleKind Kind = (Module::ModuleKind)Record[Idx++];
       bool IsFramework = Record[Idx++];
       bool IsExplicit = Record[Idx++];
       bool IsSystem = Record[Idx++];
@@ -4965,7 +4965,7 @@ ASTReader::ReadSubmoduleBlock(ModuleFile
         CurrentModule->PresumedModuleMapFile = F.ModuleMapPath;
       }
 
-      CurrentModule->Kind = ModuleKind;
+      CurrentModule->Kind = Kind;
       CurrentModule->Signature = F.Signature;
       CurrentModule->IsFromModuleFile = true;
       CurrentModule->IsSystem = IsSystem || CurrentModule->IsSystem;
@@ -5064,7 +5064,6 @@ ASTReader::ReadSubmoduleBlock(ModuleFile
 
         SubmodulesLoaded.resize(SubmodulesLoaded.size() + F.LocalNumSubmodules);
       }
-      ModuleKind = (Module::ModuleKind)Record[2];
       break;
     }
 

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=312467&r1=312466&r2=312467&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Sun Sep  3 22:37:53 2017
@@ -2716,6 +2716,7 @@ void ASTWriter::WriteSubmodules(Module *
   Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_DEFINITION));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ID
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Parent
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Kind
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFramework
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsExplicit
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsSystem
@@ -2793,8 +2794,7 @@ void ASTWriter::WriteSubmodules(Module *
   // Write the submodule metadata block.
   RecordData::value_type Record[] = {
       getNumberOfModules(WritingModule),
-      FirstSubmoduleID - NUM_PREDEF_SUBMODULE_IDS,
-      (unsigned)WritingModule->Kind};
+      FirstSubmoduleID - NUM_PREDEF_SUBMODULE_IDS};
   Stream.EmitRecord(SUBMODULE_METADATA, Record);
   
   // Write all of the submodules.
@@ -2816,6 +2816,7 @@ void ASTWriter::WriteSubmodules(Module *
       RecordData::value_type Record[] = {SUBMODULE_DEFINITION,
                                          ID,
                                          ParentID,
+                                         Mod->Kind,
                                          Mod->IsFramework,
                                          Mod->IsExplicit,
                                          Mod->IsSystem,

Modified: cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp?rev=312467&r1=312466&r2=312467&view=diff
==============================================================================
--- cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp (original)
+++ cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp Sun Sep  3 22:37:53 2017
@@ -4,15 +4,15 @@
 // CHECK-DAG: @extern_var_exported = external global
 // FIXME: Should this be 'external global'?
 // CHECK-DAG: @inline_var_exported = linkonce_odr global
-// CHECK-DAG: @_ZL19static_var_exported = external global
+// CHECK-DAG: @_ZW6ModuleE19static_var_exported = external global
 // CHECK-DAG: @const_var_exported = external constant
 //
 // FIXME: The module name should be mangled into all of these.
 // CHECK-DAG: @extern_var_module_linkage = external global
 // FIXME: Should this be 'external global'?
 // CHECK-DAG: @inline_var_module_linkage = linkonce_odr global
-// CHECK-DAG: @_ZL25static_var_module_linkage = external global
-// CHECK-DAG: @_ZL24const_var_module_linkage = external constant
+// CHECK-DAG: @_ZW6ModuleE25static_var_module_linkage = external global
+// CHECK-DAG: @_ZW6ModuleE24const_var_module_linkage = external constant
 
 module Module;
 
@@ -28,15 +28,13 @@ void use() {
   (void)&const_var_exported;
 
   // FIXME: This symbol should not be visible here.
-  // CHECK: declare {{.*}}@_ZL26used_static_module_linkagev
+  // CHECK: declare {{.*}}@_ZW6ModuleE26used_static_module_linkagev
   used_static_module_linkage();
 
-  // FIXME: The module name should be mangled into the name of this function.
-  // CHECK: define linkonce_odr {{.*}}@_Z26used_inline_module_linkagev
+  // CHECK: define linkonce_odr {{.*}}@_ZW6ModuleE26used_inline_module_linkagev
   used_inline_module_linkage();
 
-  // FIXME: The module name should be mangled into the name of this function.
-  // CHECK: declare {{.*}}@_Z24noninline_module_linkagev
+  // CHECK: declare {{.*}}@_ZW6ModuleE24noninline_module_linkagev
   noninline_module_linkage();
 
   (void)&extern_var_module_linkage;

Modified: cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cppm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cppm?rev=312467&r1=312466&r2=312467&view=diff
==============================================================================
--- cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cppm (original)
+++ cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cppm Sun Sep  3 22:37:53 2017
@@ -11,7 +11,7 @@
 // can discard this global and its initializer (if any), and other TUs are not
 // permitted to run the initializer for this variable.
 // CHECK-DAG: @inline_var_exported = linkonce_odr global
-// CHECK-DAG: @_ZL19static_var_exported = global
+// CHECK-DAG: @_ZW6ModuleE19static_var_exported = global
 // CHECK-DAG: @const_var_exported = constant
 //
 // FIXME: The module name should be mangled into all of these.
@@ -20,8 +20,8 @@
 // can discard this global and its initializer (if any), and other TUs are not
 // permitted to run the initializer for this variable.
 // CHECK-DAG: @inline_var_module_linkage = linkonce_odr global
-// CHECK-DAG: @_ZL25static_var_module_linkage = global
-// CHECK-DAG: @_ZL24const_var_module_linkage = constant
+// CHECK-DAG: @_ZW6ModuleE25static_var_module_linkage = global
+// CHECK-DAG: @_ZW6ModuleE24const_var_module_linkage = constant
 
 static void unused_static_global_module() {}
 static void used_static_global_module() {}
@@ -57,9 +57,9 @@ export module Module;
 export {
   // FIXME: These should be ill-formed: you can't export an internal linkage
   // symbol, per [dcl.module.interface]p2.
-  // CHECK: define void {{.*}}@_ZL22unused_static_exportedv
+  // CHECK: define void {{.*}}@_ZW6ModuleE22unused_static_exportedv
   static void unused_static_exported() {}
-  // CHECK: define void {{.*}}@_ZL20used_static_exportedv
+  // CHECK: define void {{.*}}@_ZW6ModuleE20used_static_exportedv
   static void used_static_exported() {}
 
   inline void unused_inline_exported() {}
@@ -88,11 +88,9 @@ export {
 // FIXME: Ideally we wouldn't emit this as its name is not visible outside this
 // TU, but this module interface might contain a template that can use this
 // function so we conservatively emit it for now.
-// FIXME: The module name should be mangled into the name of this function.
-// CHECK: define void {{.*}}@_ZL28unused_static_module_linkagev
+// CHECK: define void {{.*}}@_ZW6ModuleE28unused_static_module_linkagev
 static void unused_static_module_linkage() {}
-// FIXME: The module name should be mangled into the name of this function.
-// CHECK: define void {{.*}}@_ZL26used_static_module_linkagev
+// CHECK: define void {{.*}}@_ZW6ModuleE26used_static_module_linkagev
 static void used_static_module_linkage() {}
 
 inline void unused_inline_module_linkage() {}
@@ -103,12 +101,10 @@ inline int inline_var_module_linkage;
 static int static_var_module_linkage;
 const int const_var_module_linkage = 3;
 
-// FIXME: The module name should be mangled into the name of this function.
-// CHECK: define void {{.*}}@_Z24noninline_module_linkagev
+// CHECK: define void {{.*}}@_ZW6ModuleE24noninline_module_linkagev
 void noninline_module_linkage() {
   used_static_module_linkage();
-  // FIXME: The module name should be mangled into the name of this function.
-  // CHECK: define linkonce_odr {{.*}}@_Z26used_inline_module_linkagev
+  // CHECK: define linkonce_odr {{.*}}@_ZW6ModuleE26used_inline_module_linkagev
   used_inline_module_linkage();
 
   (void)&extern_var_module_linkage;
@@ -116,3 +112,10 @@ void noninline_module_linkage() {
   (void)&static_var_module_linkage;
   (void)&const_var_module_linkage;
 }
+
+struct a {
+  struct b {};
+  struct c {};
+};
+// CHECK: define void @_ZW6ModuleE1fW_0EN1a1bEW_0ENS_1cE(
+void f(a::b, a::c) {}

Modified: cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp?rev=312467&r1=312466&r2=312467&view=diff
==============================================================================
--- cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp (original)
+++ cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp Sun Sep  3 22:37:53 2017
@@ -5,7 +5,7 @@
 // FIXME: Should this be 'external global'?
 // CHECK-DAG: @inline_var_exported = linkonce_odr global
 // FIXME: These should be 'extern global' and 'extern constant'.
-// CHECK-DAG: @_ZL19static_var_exported = global
+// CHECK-DAG: @_ZW6ModuleE19static_var_exported = global
 // CHECK-DAG: @const_var_exported = constant
 
 import Module;

Modified: cfe/trunk/test/CXX/modules-ts/codegen-basics.cppm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/modules-ts/codegen-basics.cppm?rev=312467&r1=312466&r2=312467&view=diff
==============================================================================
--- cfe/trunk/test/CXX/modules-ts/codegen-basics.cppm (original)
+++ cfe/trunk/test/CXX/modules-ts/codegen-basics.cppm Sun Sep  3 22:37:53 2017
@@ -4,20 +4,18 @@
 export module FooBar;
 
 export {
-  // CHECK-LABEL: define i32 @_Z1fv(
+  // CHECK-DAG: define i32 @_Z1fv(
   int f() { return 0; }
 }
 
-// CHECK-LABEL: define weak_odr void @_Z2f2v(
+// CHECK-DAG: define weak_odr void @_ZW6FooBarE2f2v(
 inline void f2() { }
 
-// FIXME: Emit global variables and their initializers with this TU.
-// Emit an initialization function that other TUs can call, with guard variable.
-
-// FIXME: Mangle non-exported symbols so they don't collide with
-// non-exported symbols from other modules?
+// CHECK-DAG: define void @_ZW6FooBarE2f3v(
+static void f3() {}
+export void use_f3() { f3(); }
 
-// FIXME: Formally-internal-linkage symbols that are used from an exported
-// symbol need a mangled name and external linkage.
+// FIXME: Emit global variables and their initializers with this TU.
+// Emit an initialization function that other TUs can call, with guard variable?
 
 // FIXME: const-qualified variables don't have implicit internal linkage when owned by a module.

Modified: cfe/trunk/test/SemaCXX/modules-ts.cppm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/modules-ts.cppm?rev=312467&r1=312466&r2=312467&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/modules-ts.cppm (original)
+++ cfe/trunk/test/SemaCXX/modules-ts.cppm Sun Sep  3 22:37:53 2017
@@ -1,7 +1,7 @@
-// RUN:     %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -o %t.pcm -verify -DTEST=0
-// RUN:     %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -o %t.pcm -verify -DTEST=1
-// RUN:     %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -fmodule-file=%t.pcm -o %t.pcm -verify -DTEST=2
-// RUN:     %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -fmodule-file=%t.pcm -o %t.pcm -verify -Dfoo=bar -DTEST=3
+// RUN:     %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -o %t.0.pcm -verify -DTEST=0
+// RUN:     %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -o %t.1.pcm -verify -DTEST=1
+// RUN:     %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -fmodule-file=%t.0.pcm -o %t.2.pcm -verify -DTEST=2
+// RUN:     %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -fmodule-file=%t.0.pcm -o %t.3.pcm -verify -Dfoo=bar -DTEST=3
 
 #if TEST == 0
 // expected-no-diagnostics
@@ -21,7 +21,7 @@ static int m;
 // expected-note-re at modules-ts.cppm:1 {{'{{.*}}modules-ts.cppm' included multiple times, additional include site in header from module 'foo'}}
 #endif
 int n;
-#if TEST >= 2
+#if TEST == 2
 // expected-error at -2 {{redefinition of '}}
 // expected-note at -3 {{unguarded header; consider using #ifdef guards or #pragma once}}
 // FIXME: We should drop the "header from" in this diagnostic.
@@ -60,7 +60,7 @@ int use_b = b;
 int use_n = n; // FIXME: this should not be visible, because it is not exported
 
 extern int n;
-static_assert(&n == p); // FIXME: these are not the same entity
+static_assert(&n != p);
 #endif
 
 




More information about the cfe-commits mailing list