<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 7 July 2017 at 13:04, Richard Smith via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rsmith<br>
Date: Fri Jul  7 13:04:28 2017<br>
New Revision: 307434<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=307434&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=307434&view=rev</a><br>
Log:<br>
[modules ts] Basic for module linkage.<br></blockquote><div><br></div><div>Sorry, that should say "Basic *support* for module linkage."</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
In addition to the formal linkage rules, the Modules TS includes cases where<br>
internal-linkage symbols within a module interface unit can be referenced from<br>
outside the module via exported inline functions / templates. We give such<br>
declarations "module-internal linkage", which is formally internal linkage, but<br>
results in an externally-visible symbol.<br>
<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/<wbr>Linkage.h<br>
    cfe/trunk/lib/AST/Decl.cpp<br>
    cfe/trunk/lib/CodeGen/<wbr>CodeGenModule.cpp<br>
    cfe/trunk/lib/CodeGen/<wbr>ItaniumCXXABI.cpp<br>
    cfe/trunk/lib/CodeGen/<wbr>MicrosoftCXXABI.cpp<br>
    cfe/trunk/lib/Index/<wbr>IndexSymbol.cpp<br>
    cfe/trunk/test/CXX/modules-ts/<wbr>basic/basic.def.odr/p4/module.<wbr>cpp<br>
    cfe/trunk/test/CXX/modules-ts/<wbr>basic/basic.def.odr/p4/module.<wbr>cppm<br>
    cfe/trunk/test/CXX/modules-ts/<wbr>basic/basic.def.odr/p4/user.<wbr>cpp<br>
<br>
Modified: cfe/trunk/include/clang/Basic/<wbr>Linkage.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Linkage.h?rev=307434&r1=307433&r2=307434&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Basic/Linkage.h?rev=<wbr>307434&r1=307433&r2=307434&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Basic/<wbr>Linkage.h (original)<br>
+++ cfe/trunk/include/clang/Basic/<wbr>Linkage.h Fri Jul  7 13:04:28 2017<br>
@@ -45,6 +45,17 @@ enum Linkage : unsigned char {<br>
   /// translation units because of types defined in a inline function.<br>
   VisibleNoLinkage,<br>
<br>
+  /// \brief Internal linkage according to the Modules TS, but can be referred<br>
+  /// to from other translation units indirectly through inline functions and<br>
+  /// templates in the module interface.<br>
+  ModuleInternalLinkage,<br>
+<br>
+  /// \brief Module linkage, which indicates that the entity can be referred<br>
+  /// to from other translation units within the same module, and indirectly<br>
+  /// from arbitrary other translation units through inline functions and<br>
+  /// templates in the module interface.<br>
+  ModuleLinkage,<br>
+<br>
   /// \brief External linkage, which indicates that the entity can<br>
   /// be referred to from other translation units.<br>
   ExternalLinkage<br>
@@ -74,15 +85,20 @@ inline bool isDiscardableGVALinkage(GVAL<br>
 }<br>
<br>
 inline bool isExternallyVisible(Linkage L) {<br>
-  return L == ExternalLinkage || L == VisibleNoLinkage;<br>
+  return L >= VisibleNoLinkage;<br>
 }<br>
<br>
 inline Linkage getFormalLinkage(Linkage L) {<br>
-  if (L == UniqueExternalLinkage)<br>
+  switch (L) {<br>
+  case UniqueExternalLinkage:<br>
     return ExternalLinkage;<br>
-  if (L == VisibleNoLinkage)<br>
+  case VisibleNoLinkage:<br>
     return NoLinkage;<br>
-  return L;<br>
+  case ModuleInternalLinkage:<br>
+    return InternalLinkage;<br>
+  default:<br>
+    return L;<br>
+  }<br>
 }<br>
<br>
 inline bool isExternalFormalLinkage(<wbr>Linkage L) {<br>
<br>
Modified: cfe/trunk/lib/AST/Decl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=307434&r1=307433&r2=307434&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/AST/<wbr>Decl.cpp?rev=307434&r1=307433&<wbr>r2=307434&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/AST/Decl.cpp (original)<br>
+++ cfe/trunk/lib/AST/Decl.cpp Fri Jul  7 13:04:28 2017<br>
@@ -573,6 +573,44 @@ static bool isSingleLineLanguageLinkage(<br>
   return false;<br>
 }<br>
<br>
+static bool isExportedFromModuleIntefaceUn<wbr>it(const NamedDecl *D) {<br>
+  switch (D->getModuleOwnershipKind()) {<br>
+  case Decl::ModuleOwnershipKind::<wbr>Unowned:<br>
+  case Decl::ModuleOwnershipKind::<wbr>ModulePrivate:<br>
+    return false;<br>
+  case Decl::ModuleOwnershipKind::<wbr>Visible:<br>
+  case Decl::ModuleOwnershipKind::<wbr>VisibleWhenImported:<br>
+    if (auto *M = D->getOwningModule())<br>
+      return M->Kind == Module::ModuleInterfaceUnit;<br>
+  }<br>
+  llvm_unreachable("unexpected module ownership kind");<br>
+}<br>
+<br>
+static LinkageInfo getInternalLinkageFor(const NamedDecl *D) {<br>
+  // Internal linkage declarations within a module interface unit are modeled<br>
+  // as "module-internal linkage", which means that they have internal linkage<br>
+  // formally but can be indirectly accessed from outside the module via inline<br>
+  // functions and templates defined within the module.<br>
+  if (auto *M = D->getOwningModule())<br>
+    if (M->Kind == Module::ModuleInterfaceUnit)<br>
+      return LinkageInfo(<wbr>ModuleInternalLinkage, DefaultVisibility, false);<br>
+<br>
+  return LinkageInfo::internal();<br>
+}<br>
+<br>
+static LinkageInfo getExternalLinkageFor(const NamedDecl *D) {<br>
+  // C++ Modules TS [basic.link]/6.8:<br>
+  //   - A name declared at namespace scope that does not have internal linkage<br>
+  //     by the previous rules and that is introduced by a non-exported<br>
+  //     declaration has module linkage.<br>
+  if (auto *M = D->getOwningModule())<br>
+    if (M->Kind == Module::ModuleInterfaceUnit)<br>
+      if (!<wbr>isExportedFromModuleIntefaceUn<wbr>it(D))<br>
+        return LinkageInfo(ModuleLinkage, DefaultVisibility, false);<br>
+<br>
+  return LinkageInfo::external();<br>
+}<br>
+<br>
 static LinkageInfo getLVForNamespaceScopeDecl(<wbr>const NamedDecl *D,<br>
                                               LVComputationKind computation) {<br>
   assert(D->getDeclContext()-><wbr>getRedeclContext()-><wbr>isFileContext() &&<br>
@@ -588,16 +626,18 @@ static LinkageInfo getLVForNamespaceScop<br>
   if (const auto *Var = dyn_cast<VarDecl>(D)) {<br>
     // Explicitly declared static.<br>
     if (Var->getStorageClass() == SC_Static)<br>
-      return LinkageInfo::internal();<br>
+      return getInternalLinkageFor(Var);<br>
<br>
     // - a non-inline, non-volatile object or reference that is explicitly<br>
     //   declared const or constexpr and neither explicitly declared extern<br>
     //   nor previously declared to have external linkage; or (there is no<br>
     //   equivalent in C99)<br>
+    // The C++ modules TS adds "non-exported" to this list.<br>
     if (Context.getLangOpts().<wbr>CPlusPlus &&<br>
         Var->getType().<wbr>isConstQualified() &&<br>
         !Var->getType().<wbr>isVolatileQualified() &&<br>
-        !Var->isInline()) {<br>
+        !Var->isInline() &&<br>
+        !<wbr>isExportedFromModuleIntefaceUn<wbr>it(Var)) {<br>
       const VarDecl *PrevVar = Var->getPreviousDecl();<br>
       if (PrevVar)<br>
         return getLVForDecl(PrevVar, computation);<br>
@@ -605,7 +645,7 @@ static LinkageInfo getLVForNamespaceScop<br>
       if (Var->getStorageClass() != SC_Extern &&<br>
           Var->getStorageClass() != SC_PrivateExtern &&<br>
           !isSingleLineLanguageLinkage(*<wbr>Var))<br>
-        return LinkageInfo::internal();<br>
+        return getInternalLinkageFor(Var);<br>
     }<br>
<br>
     for (const VarDecl *PrevVar = Var->getPreviousDecl(); PrevVar;<br>
@@ -615,7 +655,7 @@ static LinkageInfo getLVForNamespaceScop<br>
         return PrevVar-><wbr>getLinkageAndVisibility();<br>
       // Explicitly declared static.<br>
       if (PrevVar->getStorageClass() == SC_Static)<br>
-        return LinkageInfo::internal();<br>
+        return getInternalLinkageFor(Var);<br>
     }<br>
   } else if (const FunctionDecl *Function = D->getAsFunction()) {<br>
     // C++ [temp]p4:<br>
@@ -624,7 +664,7 @@ static LinkageInfo getLVForNamespaceScop<br>
<br>
     // Explicitly declared static.<br>
     if (Function->getCanonicalDecl()-<wbr>>getStorageClass() == SC_Static)<br>
-      return LinkageInfo(InternalLinkage, DefaultVisibility, false);<br>
+      return getInternalLinkageFor(<wbr>Function);<br>
   } else if (const auto *IFD = dyn_cast<IndirectFieldDecl>(D)<wbr>) {<br>
     //   - a data member of an anonymous union.<br>
     const VarDecl *VD = IFD->getVarDecl();<br>
@@ -637,7 +677,12 @@ static LinkageInfo getLVForNamespaceScop<br>
     const auto *Var = dyn_cast<VarDecl>(D);<br>
     const auto *Func = dyn_cast<FunctionDecl>(D);<br>
     // FIXME: In C++11 onwards, anonymous namespaces should give decls<br>
-    // within them internal linkage, not unique external linkage.<br>
+    // within them (including those inside extern "C" contexts) internal<br>
+    // linkage, not unique external linkage:<br>
+    //<br>
+    // C++11 [basic.link]p4:<br>
+    //   An unnamed namespace or a namespace declared directly or indirectly<br>
+    //   within an unnamed namespace has internal linkage.<br>
     if ((!Var || !isFirstInExternCContext(Var)) &&<br>
         (!Func || !isFirstInExternCContext(Func)<wbr>))<br>
       return LinkageInfo::uniqueExternal();<br>
@@ -718,7 +763,8 @@ static LinkageInfo getLVForNamespaceScop<br>
     // because of this, but unique-external linkage suits us.<br>
     if (Context.getLangOpts().<wbr>CPlusPlus && !isFirstInExternCContext(Var)) {<br>
       LinkageInfo TypeLV = getLVForType(*Var->getType(), computation);<br>
-      if (TypeLV.getLinkage() != ExternalLinkage)<br>
+      if (TypeLV.getLinkage() != ExternalLinkage &&<br>
+          TypeLV.getLinkage() != ModuleLinkage)<br>
         return LinkageInfo::uniqueExternal();<br>
       if (!LV.isVisibilityExplicit())<br>
         LV.mergeVisibility(TypeLV);<br>
@@ -816,7 +862,9 @@ static LinkageInfo getLVForNamespaceScop<br>
<br>
   //     - a namespace (7.3), unless it is declared within an unnamed<br>
   //       namespace.<br>
-  } else if (isa<NamespaceDecl>(D) && !D->isInAnonymousNamespace()) {<br>
+  //<br>
+  // We handled names in anonymous namespaces above.<br>
+  } else if (isa<NamespaceDecl>(D)) {<br>
     return LV;<br>
<br>
   // By extension, we assign external linkage to Objective-C<br>
@@ -1125,6 +1173,8 @@ static LinkageInfo getLVForClosure(const<br>
   if (const auto *ND = dyn_cast<NamedDecl>(DC))<br>
     return getLVForDecl(ND, computation);<br>
<br>
+  // FIXME: We have a closure at TU scope with no context declaration. This<br>
+  // should probably have no linkage.<br>
   return LinkageInfo::external();<br>
 }<br>
<br>
@@ -1137,7 +1187,7 @@ static LinkageInfo getLVForLocalDecl(con<br>
<br>
     // This is a "void f();" which got merged with a file static.<br>
     if (Function->getCanonicalDecl()-<wbr>>getStorageClass() == SC_Static)<br>
-      return LinkageInfo::internal();<br>
+      return getInternalLinkageFor(<wbr>Function);<br>
<br>
     LinkageInfo LV;<br>
     if (!<wbr>hasExplicitVisibilityAlready(<wbr>computation)) {<br>
@@ -1226,7 +1276,7 @@ static LinkageInfo computeLVForDecl(cons<br>
                                     LVComputationKind computation) {<br>
   // Internal_linkage attribute overrides other considerations.<br>
   if (D->hasAttr<<wbr>InternalLinkageAttr>())<br>
-    return LinkageInfo::internal();<br>
+    return getInternalLinkageFor(D);<br>
<br>
   // Objective-C: treat all Objective-C declarations as having external<br>
   // linkage.<br>
@@ -1275,14 +1325,14 @@ static LinkageInfo computeLVForDecl(cons<br>
     case Decl::ObjCProperty:<br>
     case Decl::ObjCPropertyImpl:<br>
     case Decl::ObjCProtocol:<br>
-      return LinkageInfo::external();<br>
+      return getExternalLinkageFor(D);<br>
<br>
     case Decl::CXXRecord: {<br>
       const auto *Record = cast<CXXRecordDecl>(D);<br>
       if (Record->isLambda()) {<br>
         if (!Record-><wbr>getLambdaManglingNumber()) {<br>
           // This lambda has no mangling number, so it's internal.<br>
-          return LinkageInfo::internal();<br>
+          return getInternalLinkageFor(D);<br>
         }<br>
<br>
         // This lambda has its linkage/visibility determined:<br>
@@ -1298,7 +1348,7 @@ static LinkageInfo computeLVForDecl(cons<br>
         const CXXRecordDecl *OuterMostLambda =<br>
             getOutermostEnclosingLambda(<wbr>Record);<br>
         if (!OuterMostLambda-><wbr>getLambdaManglingNumber())<br>
-          return LinkageInfo::internal();<br>
+          return getInternalLinkageFor(D);<br>
<br>
         return getLVForClosure(<br>
                   OuterMostLambda-><wbr>getDeclContext()-><wbr>getRedeclContext(),<br>
@@ -1349,7 +1399,7 @@ public:<br>
                                   LVComputationKind computation) {<br>
     // Internal_linkage attribute overrides other considerations.<br>
     if (D->hasAttr<<wbr>InternalLinkageAttr>())<br>
-      return LinkageInfo::internal();<br>
+      return getInternalLinkageFor(D);<br>
<br>
     if (computation == LVForLinkageOnly && D->hasCachedLinkage())<br>
       return LinkageInfo(D-><wbr>getCachedLinkage(), DefaultVisibility, false);<br>
<br>
Modified: cfe/trunk/lib/CodeGen/<wbr>CodeGenModule.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=307434&r1=307433&r2=307434&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/CodeGen/<wbr>CodeGenModule.cpp?rev=307434&<wbr>r1=307433&r2=307434&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/CodeGen/<wbr>CodeGenModule.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/<wbr>CodeGenModule.cpp Fri Jul  7 13:04:28 2017<br>
@@ -1098,7 +1098,7 @@ static void setLinkageAndVisibilityForGV<br>
                                          const NamedDecl *ND) {<br>
   // Set linkage and visibility in case we never see a definition.<br>
   LinkageInfo LV = ND->getLinkageAndVisibility();<br>
-  if (LV.getLinkage() != ExternalLinkage) {<br>
+  if (!isExternallyVisible(LV.<wbr>getLinkage())) {<br>
     // Don't set internal linkage on declarations.<br>
   } else {<br>
     if (ND->hasAttr<DLLImportAttr>()) {<br>
<br>
Modified: cfe/trunk/lib/CodeGen/<wbr>ItaniumCXXABI.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=307434&r1=307433&r2=307434&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/CodeGen/<wbr>ItaniumCXXABI.cpp?rev=307434&<wbr>r1=307433&r2=307434&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/CodeGen/<wbr>ItaniumCXXABI.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/<wbr>ItaniumCXXABI.cpp Fri Jul  7 13:04:28 2017<br>
@@ -2959,6 +2959,8 @@ static llvm::GlobalVariable::<wbr>LinkageType<br>
     return llvm::GlobalValue::<wbr>InternalLinkage;<br>
<br>
   case VisibleNoLinkage:<br>
+  case ModuleInternalLinkage:<br>
+  case ModuleLinkage:<br>
   case ExternalLinkage:<br>
     // RTTI is not enabled, which means that this type info struct is going<br>
     // to be used for exception handling. Give it linkonce_odr linkage.<br>
<br>
Modified: cfe/trunk/lib/CodeGen/<wbr>MicrosoftCXXABI.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=307434&r1=307433&r2=307434&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/CodeGen/<wbr>MicrosoftCXXABI.cpp?rev=<wbr>307434&r1=307433&r2=307434&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/CodeGen/<wbr>MicrosoftCXXABI.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/<wbr>MicrosoftCXXABI.cpp Fri Jul  7 13:04:28 2017<br>
@@ -3425,6 +3425,8 @@ static llvm::GlobalValue::<wbr>LinkageTypes g<br>
     return llvm::GlobalValue::<wbr>InternalLinkage;<br>
<br>
   case VisibleNoLinkage:<br>
+  case ModuleInternalLinkage:<br>
+  case ModuleLinkage:<br>
   case ExternalLinkage:<br>
     return llvm::GlobalValue::<wbr>LinkOnceODRLinkage;<br>
   }<br>
<br>
Modified: cfe/trunk/lib/Index/<wbr>IndexSymbol.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/IndexSymbol.cpp?rev=307434&r1=307433&r2=307434&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Index/<wbr>IndexSymbol.cpp?rev=307434&r1=<wbr>307433&r2=307434&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Index/<wbr>IndexSymbol.cpp (original)<br>
+++ cfe/trunk/lib/Index/<wbr>IndexSymbol.cpp Fri Jul  7 13:04:28 2017<br>
@@ -69,11 +69,13 @@ bool index::isFunctionLocalSymbol(<wbr>const<br>
   if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {<br>
     switch (ND->getFormalLinkage()) {<br>
       case NoLinkage:<br>
-      case VisibleNoLinkage:<br>
       case InternalLinkage:<br>
         return true;<br>
+      case VisibleNoLinkage:<br>
       case UniqueExternalLinkage:<br>
+      case ModuleInternalLinkage:<br>
         llvm_unreachable("Not a sema linkage");<br>
+      case ModuleLinkage:<br>
       case ExternalLinkage:<br>
         return false;<br>
     }<br>
<br>
Modified: cfe/trunk/test/CXX/modules-ts/<wbr>basic/basic.def.odr/p4/module.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp?rev=307434&r1=307433&r2=307434&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/CXX/<wbr>modules-ts/basic/basic.def.<wbr>odr/p4/module.cpp?rev=307434&<wbr>r1=307433&r2=307434&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/CXX/modules-ts/<wbr>basic/basic.def.odr/p4/module.<wbr>cpp (original)<br>
+++ cfe/trunk/test/CXX/modules-ts/<wbr>basic/basic.def.odr/p4/module.<wbr>cpp Fri Jul  7 13:04:28 2017<br>
@@ -1,6 +1,19 @@<br>
 // RUN: %clang_cc1 -fmodules-ts %S/module.cppm -triple %itanium_abi_triple -emit-module-interface -o %t<br>
 // RUN: %clang_cc1 -fmodules-ts %s -triple %itanium_abi_triple -fmodule-file=%t -emit-llvm -o - | FileCheck %s --implicit-check-not=unused --implicit-check-not=global_<wbr>module<br>
<br>
+// CHECK-DAG: @extern_var_exported = external global<br>
+// FIXME: Should this be 'external global'?<br>
+// CHECK-DAG: @inline_var_exported = linkonce_odr global<br>
+// CHECK-DAG: @_ZL19static_var_exported = external global<br>
+// CHECK-DAG: @const_var_exported = external constant<br>
+//<br>
+// FIXME: The module name should be mangled into all of these.<br>
+// CHECK-DAG: @extern_var_module_linkage = external global<br>
+// FIXME: Should this be 'external global'?<br>
+// CHECK-DAG: @inline_var_module_linkage = linkonce_odr global<br>
+// CHECK-DAG: @_ZL25static_var_module_<wbr>linkage = external global<br>
+// CHECK-DAG: @_ZL24const_var_module_linkage = external constant<br>
+<br>
 module Module;<br>
<br>
 void use() {<br>
@@ -9,8 +22,13 @@ void use() {<br>
   // CHECK: declare {{.*}}@_Z18noninline_exportedv<br>
   noninline_exported();<br>
<br>
+  (void)&extern_var_exported;<br>
+  (void)&inline_var_exported;<br>
+  (void)&static_var_exported; // FIXME: Should not be exported.<br>
+  (void)&const_var_exported;<br>
+<br>
   // FIXME: This symbol should not be visible here.<br>
-  // CHECK: define internal {{.*}}@_ZL26used_static_<wbr>module_linkagev<br>
+  // CHECK: declare {{.*}}@_ZL26used_static_<wbr>module_linkagev<br>
   used_static_module_linkage();<br>
<br>
   // FIXME: The module name should be mangled into the name of this function.<br>
@@ -20,4 +38,9 @@ void use() {<br>
   // FIXME: The module name should be mangled into the name of this function.<br>
   // CHECK: declare {{.*}}@_Z24noninline_module_<wbr>linkagev<br>
   noninline_module_linkage();<br>
+<br>
+  (void)&extern_var_module_<wbr>linkage;<br>
+  (void)&inline_var_module_<wbr>linkage;<br>
+  (void)&static_var_module_<wbr>linkage; // FIXME: Should not be visible here.<br>
+  (void)&const_var_module_<wbr>linkage;<br>
 }<br>
<br>
Modified: cfe/trunk/test/CXX/modules-ts/<wbr>basic/basic.def.odr/p4/module.<wbr>cppm<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cppm?rev=307434&r1=307433&r2=307434&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/CXX/<wbr>modules-ts/basic/basic.def.<wbr>odr/p4/module.cppm?rev=307434&<wbr>r1=307433&r2=307434&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/CXX/modules-ts/<wbr>basic/basic.def.odr/p4/module.<wbr>cppm (original)<br>
+++ cfe/trunk/test/CXX/modules-ts/<wbr>basic/basic.def.odr/p4/module.<wbr>cppm Fri Jul  7 13:04:28 2017<br>
@@ -1,9 +1,39 @@<br>
-// RUN: %clang_cc1 -fmodules-ts %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s --implicit-check-not=unused<br>
+// RUN: %clang_cc1 -fmodules-ts %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s --implicit-check-not unused_inline --implicit-check-not unused_stastic_global_module<br>
+<br>
+// CHECK-DAG: @extern_var_global_module = external global<br>
+// CHECK-DAG: @inline_var_global_module = linkonce_odr global<br>
+// CHECK-DAG: @_ZL24static_var_global_module = internal global<br>
+// CHECK-DAG: @_ZL23const_var_global_module = internal constant<br>
+//<br>
+// For ABI compatibility, these symbols do not include the module name.<br>
+// CHECK-DAG: @extern_var_exported = external global<br>
+// FIXME: Should this be 'weak_odr global'? Presumably it must be, since we<br>
+// can discard this global and its initializer (if any), and other TUs are not<br>
+// permitted to run the initializer for this variable.<br>
+// CHECK-DAG: @inline_var_exported = linkonce_odr global<br>
+// CHECK-DAG: @_ZL19static_var_exported = global<br>
+// CHECK-DAG: @const_var_exported = constant<br>
+//<br>
+// FIXME: The module name should be mangled into all of these.<br>
+// CHECK-DAG: @extern_var_module_linkage = external global<br>
+// FIXME: Should this be 'weak_odr global'? Presumably it must be, since we<br>
+// can discard this global and its initializer (if any), and other TUs are not<br>
+// permitted to run the initializer for this variable.<br>
+// CHECK-DAG: @inline_var_module_linkage = linkonce_odr global<br>
+// CHECK-DAG: @_ZL25static_var_module_<wbr>linkage = global<br>
+// CHECK-DAG: @_ZL24const_var_module_linkage = constant<br>
<br>
 static void unused_static_global_module() {}<br>
 static void used_static_global_module() {}<br>
+<br>
 inline void unused_inline_global_module() {}<br>
 inline void used_inline_global_module() {}<br>
+<br>
+extern int extern_var_global_module;<br>
+inline int inline_var_global_module;<br>
+static int static_var_global_module;<br>
+const int const_var_global_module = 3;<br>
+<br>
 // CHECK: define void {{.*}}@_Z23noninline_global_<wbr>modulev<br>
 void noninline_global_module() {<br>
   // FIXME: This should be promoted to module linkage and given a<br>
@@ -15,6 +45,11 @@ void noninline_global_module() {<br>
   used_static_global_module();<br>
   // CHECK: define linkonce_odr {{.*}}@_Z25used_inline_global_<wbr>modulev<br>
   used_inline_global_module();<br>
+<br>
+  (void)&extern_var_global_<wbr>module;<br>
+  (void)&inline_var_global_<wbr>module;<br>
+  (void)&static_var_global_<wbr>module;<br>
+  (void)&const_var_global_<wbr>module;<br>
 }<br>
<br>
 export module Module;<br>
@@ -22,33 +57,62 @@ export module Module;<br>
 export {<br>
   // FIXME: These should be ill-formed: you can't export an internal linkage<br>
   // symbol, per [dcl.module.interface]p2.<br>
+  // CHECK: define void {{.*}}@_ZL22unused_static_<wbr>exportedv<br>
   static void unused_static_exported() {}<br>
+  // CHECK: define void {{.*}}@_ZL20used_static_<wbr>exportedv<br>
   static void used_static_exported() {}<br>
<br>
   inline void unused_inline_exported() {}<br>
   inline void used_inline_exported() {}<br>
+<br>
+  extern int extern_var_exported;<br>
+  inline int inline_var_exported;<br>
+  // FIXME: This should be ill-formed: you can't export an internal linkage<br>
+  // symbol.<br>
+  static int static_var_exported;<br>
+  const int const_var_exported = 3;<br>
+<br>
   // CHECK: define void {{.*}}@_Z18noninline_exportedv<br>
   void noninline_exported() {<br>
-    // CHECK: define internal {{.*}}@_ZL20used_static_<wbr>exportedv<br>
     used_static_exported();<br>
     // CHECK: define linkonce_odr {{.*}}@_Z20used_inline_<wbr>exportedv<br>
     used_inline_exported();<br>
+<br>
+    (void)&extern_var_exported;<br>
+    (void)&inline_var_exported;<br>
+    (void)&static_var_exported;<br>
+    (void)&const_var_exported;<br>
   }<br>
 }<br>
<br>
+// FIXME: Ideally we wouldn't emit this as its name is not visible outside this<br>
+// TU, but this module interface might contain a template that can use this<br>
+// function so we conservatively emit it for now.<br>
+// FIXME: The module name should be mangled into the name of this function.<br>
+// CHECK: define void {{.*}}@_ZL28unused_static_<wbr>module_linkagev<br>
 static void unused_static_module_linkage() {}<br>
+// FIXME: The module name should be mangled into the name of this function.<br>
+// CHECK: define void {{.*}}@_ZL26used_static_<wbr>module_linkagev<br>
 static void used_static_module_linkage() {}<br>
+<br>
 inline void unused_inline_module_linkage() {}<br>
 inline void used_inline_module_linkage() {}<br>
+<br>
+extern int extern_var_module_linkage;<br>
+inline int inline_var_module_linkage;<br>
+static int static_var_module_linkage;<br>
+const int const_var_module_linkage = 3;<br>
+<br>
 // FIXME: The module name should be mangled into the name of this function.<br>
 // CHECK: define void {{.*}}@_Z24noninline_module_<wbr>linkagev<br>
 void noninline_module_linkage() {<br>
-  // FIXME: This should be promoted to module linkage and given a<br>
-  // module-mangled name, if it's called from an inline function within<br>
-  // the module interface.<br>
-  // CHECK: define internal {{.*}}@_ZL26used_static_<wbr>module_linkagev<br>
   used_static_module_linkage();<br>
   // FIXME: The module name should be mangled into the name of this function.<br>
   // CHECK: define linkonce_odr {{.*}}@_Z26used_inline_module_<wbr>linkagev<br>
   used_inline_module_linkage();<br>
+<br>
+  (void)&extern_var_module_<wbr>linkage;<br>
+  (void)&inline_var_module_<wbr>linkage;<br>
+  (void)&static_var_module_<wbr>linkage;<br>
+  (void)&const_var_module_<wbr>linkage;<br>
 }<br>
<br>
Modified: cfe/trunk/test/CXX/modules-ts/<wbr>basic/basic.def.odr/p4/user.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp?rev=307434&r1=307433&r2=307434&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/CXX/<wbr>modules-ts/basic/basic.def.<wbr>odr/p4/user.cpp?rev=307434&r1=<wbr>307433&r2=307434&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/CXX/modules-ts/<wbr>basic/basic.def.odr/p4/user.<wbr>cpp (original)<br>
+++ cfe/trunk/test/CXX/modules-ts/<wbr>basic/basic.def.odr/p4/user.<wbr>cpp Fri Jul  7 13:04:28 2017<br>
@@ -1,6 +1,13 @@<br>
 // RUN: %clang_cc1 -fmodules-ts %S/module.cppm -triple %itanium_abi_triple -emit-module-interface -o %t<br>
 // RUN: %clang_cc1 -fmodules-ts %s -triple %itanium_abi_triple -fmodule-file=%t -emit-llvm -o - | FileCheck %s --implicit-check-not=unused --implicit-check-not=global_<wbr>module<br>
<br>
+// CHECK-DAG: @extern_var_exported = external global<br>
+// FIXME: Should this be 'external global'?<br>
+// CHECK-DAG: @inline_var_exported = linkonce_odr global<br>
+// FIXME: These should be 'extern global' and 'extern constant'.<br>
+// CHECK-DAG: @_ZL19static_var_exported = global<br>
+// CHECK-DAG: @const_var_exported = constant<br>
+<br>
 import Module;<br>
<br>
 void use() {<br>
@@ -9,5 +16,10 @@ void use() {<br>
   // CHECK: declare {{.*}}@_Z18noninline_exportedv<br>
   noninline_exported();<br>
<br>
+  (void)&extern_var_exported;<br>
+  (void)&inline_var_exported;<br>
+  (void)&static_var_exported;<br>
+  (void)&const_var_exported;<br>
+<br>
   // Module-linkage declarations are not visible here.<br>
 }<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>