<div dir="ltr">Added regression test for the failure in r315366.<br></div><div class="gmail_extra"><br><div class="gmail_quote">On 10 October 2017 at 09:47, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">OK, and you got the errors with r315256 applied too, I assume. Looking...</div><div class="gmail_quote"><br></div><div class="gmail_quote">Thanks for the revert! :)</div><div><div class="h5"><div class="gmail_quote"><br></div><div class="gmail_quote">On 10 October 2017 at 09:12, Eric Liu 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"><div dir="ltr">No :( I tried reverting only <span style="color:rgb(33,33,33)">r315256 but still got the errors.</span></div><div class="m_2217847900692737799HOEnZb"><div class="m_2217847900692737799h5"><br><div class="gmail_quote"><div dir="ltr">On Tue, Oct 10, 2017 at 6:10 PM Richard Smith <<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><div><div class="gmail_extra"><div class="gmail_quote">On 10 Oct 2017 05:41, "Eric Liu via cfe-commits" <<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>> wrote:<br type="attribution"><blockquote class="m_2217847900692737799m_-6517784701816689369m_-4035918138908654097quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Richard, <div><br></div><div>This is breaking the boostrap stage in the internal integration. I'm seeing "<span style="white-space:pre-wrap">unsupported: typedef changes linkage of anonymous type, but linkage was already computed</span>" error for many `struct`s defined with typedef. I'm not sure if it is user code or clang that needs fixing; however, as there are likely many more struct definitions that would cause the same failure, I'll revert this commit as well as r315256, which depends on this. Sorry about that.</div></div></blockquote></div></div></div><div dir="auto"><br></div></div><div dir="auto"><div dir="auto">r315256 should have fixed those errors. Did it not?</div></div><div dir="auto"><div dir="auto"><br></div><div dir="auto"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="m_2217847900692737799m_-6517784701816689369m_-4035918138908654097quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div>I'll also send you the repros separately. </div></div><div><br></div><div>Regards,</div><div>Eric</div></div><div class="m_2217847900692737799m_-6517784701816689369m_-4035918138908654097elided-text"><br><div class="gmail_quote"><div dir="ltr">On Tue, Oct 10, 2017 at 1:42 AM Richard Smith via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rsmith<br>
Date: Mon Oct  9 16:42:09 2017<br>
New Revision: 315251<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=315251&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject?rev=315251&view=rev</a><br>
Log:<br>
[Modules TS] Module ownership semantics for redeclarations.<br>
<br>
When declaring an entity in the "purview" of a module, it's never a<br>
redeclaration of an entity in the purview of a default module or in no module<br>
("in the global module"). Don't consider those other declarations as possible<br>
redeclaration targets if they're not visible, and reject any cases where we<br>
pick a prior visible declaration that violates this rule.<br>
<br>
Added:<br>
    cfe/trunk/test/CXX/modules-ts/<wbr>basic/basic.def.odr/p6/<br>
    cfe/trunk/test/CXX/modules-ts/<wbr>basic/basic.def.odr/p6/global-<wbr>vs-module.cpp<br>
    cfe/trunk/test/CXX/modules-ts/<wbr>basic/basic.def.odr/p6/module-<wbr>vs-global.cpp<br>
    cfe/trunk/test/CXX/modules-ts/<wbr>basic/basic.def.odr/p6/module-<wbr>vs-module.cpp<br>
Modified:<br>
    cfe/trunk/include/clang/AST/De<wbr>cl.h<br>
    cfe/trunk/include/clang/AST/De<wbr>clBase.h<br>
    cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td<br>
    cfe/trunk/include/clang/Sema/L<wbr>ookup.h<br>
    cfe/trunk/include/clang/Sema/S<wbr>ema.h<br>
    cfe/trunk/lib/AST/Decl.cpp<br>
    cfe/trunk/lib/AST/DeclBase.cpp<br>
    cfe/trunk/lib/AST/DeclCXX.cpp<br>
    cfe/trunk/lib/Sema/SemaDecl.cp<wbr>p<br>
    cfe/trunk/lib/Sema/SemaDeclCXX<wbr>.cpp<br>
    cfe/trunk/lib/Sema/SemaDeclObj<wbr>C.cpp<br>
    cfe/trunk/lib/Sema/SemaExprMem<wbr>ber.cpp<br>
    cfe/trunk/lib/Sema/SemaLookup.<wbr>cpp<br>
    cfe/trunk/lib/Sema/SemaOpenMP.<wbr>cpp<br>
    cfe/trunk/lib/Sema/SemaTemplat<wbr>e.cpp<br>
    cfe/trunk/lib/Sema/SemaTemplat<wbr>eInstantiateDecl.cpp<br>
    cfe/trunk/test/SemaCXX/modules<wbr>-ts.cppm<br>
<br>
Modified: cfe/trunk/include/clang/AST/De<wbr>cl.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=315251&r1=315250&r2=315251&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/include/clang/<wbr>AST/Decl.h?rev=315251&r1=<wbr>315250&r2=315251&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/AST/De<wbr>cl.h (original)<br>
+++ cfe/trunk/include/clang/AST/De<wbr>cl.h Mon Oct  9 16:42:09 2017<br>
@@ -339,6 +339,12 @@ public:<br>
     return clang::isExternallyVisible(get<wbr>LinkageInternal());<br>
   }<br>
<br>
+  /// Determine whether this declaration can be redeclared in a<br>
+  /// different translation unit.<br>
+  bool isExternallyDeclarable() const {<br>
+    return isExternallyVisible() && !getOwningModuleForLinkage();<br>
+  }<br>
+<br>
   /// \brief Determines the visibility of this entity.<br>
   Visibility getVisibility() const {<br>
     return getLinkageAndVisibility().getV<wbr>isibility();<br>
@@ -379,10 +385,6 @@ public:<br>
     return hasCachedLinkage();<br>
   }<br>
<br>
-  /// Get the module that owns this declaration for linkage purposes.<br>
-  /// There only ever is such a module under the C++ Modules TS.<br>
-  Module *getOwningModuleForLinkage() const;<br>
-<br>
   /// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for<br>
   /// the underlying named decl.<br>
   NamedDecl *getUnderlyingDecl() {<br>
<br>
Modified: cfe/trunk/include/clang/AST/De<wbr>clBase.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=315251&r1=315250&r2=315251&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/include/clang/<wbr>AST/DeclBase.h?rev=315251&r1=<wbr>315250&r2=315251&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/AST/De<wbr>clBase.h (original)<br>
+++ cfe/trunk/include/clang/AST/De<wbr>clBase.h Mon Oct  9 16:42:09 2017<br>
@@ -738,6 +738,10 @@ public:<br>
     return isFromASTFile() ? getImportedOwningModule() : getLocalOwningModule();<br>
   }<br>
<br>
+  /// Get the module that owns this declaration for linkage purposes.<br>
+  /// There only ever is such a module under the C++ Modules TS.<br>
+  Module *getOwningModuleForLinkage() const;<br>
+<br>
   /// \brief Determine whether this declaration might be hidden from name<br>
   /// lookup. Note that the declaration might be visible even if this returns<br>
   /// \c false, if the owning module is visible within the query context.<br>
<br>
Modified: cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=315251&r1=315250&r2=315251&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/include/clang/<wbr>Basic/DiagnosticSemaKinds.td?<wbr>rev=315251&r1=315250&r2=<wbr>315251&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td Mon Oct  9 16:42:09 2017<br>
@@ -4801,6 +4801,9 @@ def err_thread_non_thread : Error<<br>
 def err_thread_thread_different_ki<wbr>nd : Error<<br>
   "thread-local declaration of %0 with %select{static|dynamic}1 initialization "<br>
   "follows declaration with %select{dynamic|static}1 initialization">;<br>
+def err_mismatched_owning_module : Error<<br>
+  "declaration of %0 in %select{the global module|module %2}1 follows "<br>
+  "declaration in %select{the global module|module %4}3">;<br>
 def err_redefinition_different_typ<wbr>e : Error<<br>
   "redefinition of %0 with a different type%diff{: $ vs $|}1,2">;<br>
 def err_redefinition_different_kin<wbr>d : Error<<br>
<br>
Modified: cfe/trunk/include/clang/Sema/L<wbr>ookup.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Lookup.h?rev=315251&r1=315250&r2=315251&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/include/clang/<wbr>Sema/Lookup.h?rev=315251&r1=<wbr>315250&r2=315251&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Sema/L<wbr>ookup.h (original)<br>
+++ cfe/trunk/include/clang/Sema/L<wbr>ookup.h Mon Oct  9 16:42:09 2017<br>
@@ -139,6 +139,7 @@ public:<br>
       LookupKind(LookupKind),<br>
       IDNS(0),<br>
       Redecl(Redecl != Sema::NotForRedeclaration),<br>
+      ExternalRedecl(Redecl == Sema::ForExternalRedeclaration<wbr>),<br>
       HideTags(true),<br>
       Diagnose(Redecl == Sema::NotForRedeclaration),<br>
       AllowHidden(false),<br>
@@ -161,6 +162,7 @@ public:<br>
       LookupKind(LookupKind),<br>
       IDNS(0),<br>
       Redecl(Redecl != Sema::NotForRedeclaration),<br>
+      ExternalRedecl(Redecl == Sema::ForExternalRedeclaration<wbr>),<br>
       HideTags(true),<br>
       Diagnose(Redecl == Sema::NotForRedeclaration),<br>
       AllowHidden(false),<br>
@@ -181,6 +183,7 @@ public:<br>
       LookupKind(Other.LookupKind),<br>
       IDNS(Other.IDNS),<br>
       Redecl(Other.Redecl),<br>
+      ExternalRedecl(Other.ExternalR<wbr>edecl),<br>
       HideTags(Other.HideTags),<br>
       Diagnose(false),<br>
       AllowHidden(Other.AllowHidden<wbr>),<br>
@@ -201,7 +204,9 @@ public:<br>
         SemaPtr(std::move(Other.SemaP<wbr>tr)), NameInfo(std::move(Other.NameI<wbr>nfo)),<br>
         NameContextRange(std::move(Ot<wbr>her.NameContextRange)),<br>
         LookupKind(std::move(Other.Lo<wbr>okupKind)), IDNS(std::move(Other.IDNS)),<br>
-        Redecl(std::move(Other.Redecl)<wbr>), HideTags(std::move(Other.HideT<wbr>ags)),<br>
+        Redecl(std::move(Other.Redecl)<wbr>),<br>
+        ExternalRedecl(std::move(Other<wbr>.ExternalRedecl)),<br>
+        HideTags(std::move(Other.HideT<wbr>ags)),<br>
         Diagnose(std::move(Other.Diag<wbr>nose)),<br>
         AllowHidden(std::move(Other.A<wbr>llowHidden)),<br>
         Shadowed(std::move(Other.Shad<wbr>owed)) {<br>
@@ -221,6 +226,7 @@ public:<br>
     LookupKind = std::move(Other.LookupKind);<br>
     IDNS = std::move(Other.IDNS);<br>
     Redecl = std::move(Other.Redecl);<br>
+    ExternalRedecl = std::move(Other.ExternalRedecl<wbr>);<br>
     HideTags = std::move(Other.HideTags);<br>
     Diagnose = std::move(Other.Diagnose);<br>
     AllowHidden = std::move(Other.AllowHidden);<br>
@@ -265,6 +271,17 @@ public:<br>
     return Redecl;<br>
   }<br>
<br>
+  /// True if this lookup is just looking for an existing declaration to link<br>
+  /// against a declaration with external linkage.<br>
+  bool isForExternalRedeclaration() const {<br>
+    return ExternalRedecl;<br>
+  }<br>
+<br>
+  Sema::RedeclarationKind redeclarationKind() const {<br>
+    return ExternalRedecl ? Sema::ForExternalRedeclaration :<br>
+           Redecl ? Sema::ForVisibleRedeclaration : Sema::NotForRedeclaration;<br>
+  }<br>
+<br>
   /// \brief Specify whether hidden declarations are visible, e.g.,<br>
   /// for recovery reasons.<br>
   void setAllowHidden(bool AH) {<br>
@@ -275,7 +292,7 @@ public:<br>
   /// declarations, such as those in modules that have not yet been imported.<br>
   bool isHiddenDeclarationVisible(Nam<wbr>edDecl *ND) const {<br>
     return AllowHidden ||<br>
-           (isForRedeclaration() && ND->hasExternalFormalLinkage()<wbr>);<br>
+           (isForExternalRedeclaration() && ND->isExternallyDeclarable());<br>
   }<br>
<br>
   /// Sets whether tag declarations should be hidden by non-tag<br>
@@ -556,7 +573,8 @@ public:<br>
<br>
   /// \brief Change this lookup's redeclaration kind.<br>
   void setRedeclarationKind(Sema::Red<wbr>eclarationKind RK) {<br>
-    Redecl = RK;<br>
+    Redecl = (RK != Sema::NotForRedeclaration);<br>
+    ExternalRedecl = (RK == Sema::ForExternalRedeclaration<wbr>);<br>
     configure();<br>
   }<br>
<br>
@@ -719,6 +737,7 @@ private:<br>
   unsigned IDNS; // set by configure()<br>
<br>
   bool Redecl;<br>
+  bool ExternalRedecl;<br>
<br>
   /// \brief True if tag declarations should be hidden if non-tags<br>
   ///   are present<br>
<br>
Modified: cfe/trunk/include/clang/Sema/S<wbr>ema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=315251&r1=315250&r2=315251&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/include/clang/<wbr>Sema/Sema.h?rev=315251&r1=<wbr>315250&r2=315251&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Sema/S<wbr>ema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/S<wbr>ema.h Mon Oct  9 16:42:09 2017<br>
@@ -285,15 +285,21 @@ class Sema {<br>
<br>
   bool isVisibleSlow(const NamedDecl *D);<br>
<br>
+  /// Determine whether two declarations should be linked together, given that<br>
+  /// the old declaration might not be visible and the new declaration might<br>
+  /// not have external linkage.<br>
   bool shouldLinkPossiblyHiddenDecl(c<wbr>onst NamedDecl *Old,<br>
                                     const NamedDecl *New) {<br>
-    // We are about to link these. It is now safe to compute the linkage of<br>
-    // the new decl. If the new decl has external linkage, we will<br>
-    // link it with the hidden decl (which also has external linkage) and<br>
-    // it will keep having external linkage. If it has internal linkage, we<br>
-    // will not link it. Since it has no previous decls, it will remain<br>
-    // with internal linkage.<br>
-    return isVisible(Old) || New->isExternallyVisible();<br>
+    if (isVisible(Old))<br>
+     return true;<br>
+    // See comment in below overload for why it's safe to compute the linkage<br>
+    // of the new declaration here.<br>
+    if (New->isExternallyDeclarable()<wbr>) {<br>
+      assert(Old->isExternallyDeclar<wbr>able() &&<br>
+             "should not have found a non-externally-declarable previous decl");<br>
+      return true;<br>
+    }<br>
+    return false;<br>
   }<br>
   bool shouldLinkPossiblyHiddenDecl(L<wbr>ookupResult &Old, const NamedDecl *New);<br>
<br>
@@ -3035,10 +3041,22 @@ public:<br>
     /// purpose of redeclaring the name.<br>
     NotForRedeclaration = 0,<br>
     /// \brief The lookup results will be used for redeclaration of a name,<br>
-    /// if an entity by that name already exists.<br>
-    ForRedeclaration<br>
+    /// if an entity by that name already exists and is visible.<br>
+    ForVisibleRedeclaration,<br>
+    /// \brief The lookup results will be used for redeclaration of a name<br>
+    /// with external linkage; non-visible lookup results with external linkage<br>
+    /// may also be found.<br>
+    ForExternalRedeclaration<br>
   };<br>
<br>
+  RedeclarationKind forRedeclarationInCurContext() {<br>
+    // A declaration with an owning module for linkage can never link against<br>
+    // anything that is not visible.<br>
+    if (cast<Decl>(CurContext)->getOw<wbr>ningModuleForLinkage())<br>
+      return ForVisibleRedeclaration;<br>
+    return ForExternalRedeclaration;<br>
+  }<br>
+<br>
   /// \brief The possible outcomes of name lookup for a literal operator.<br>
   enum LiteralOperatorLookupResult {<br>
     /// \brief The lookup resulted in an error.<br>
@@ -3266,6 +3284,8 @@ public:<br>
   void FilterLookupForScope(LookupRes<wbr>ult &R, DeclContext *Ctx, Scope *S,<br>
                             bool ConsiderLinkage, bool AllowInlineNamespace);<br>
<br>
+  bool CheckRedeclarationModuleOwners<wbr>hip(NamedDecl *New, NamedDecl *Old);<br>
+<br>
   void DiagnoseAmbiguousLookup(Lookup<wbr>Result &Result);<br>
   //@}<br>
<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=315251&r1=315250&r2=315251&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/AST/Decl.<wbr>cpp?rev=315251&r1=315250&r2=<wbr>315251&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/AST/Decl.cpp (original)<br>
+++ cfe/trunk/lib/AST/Decl.cpp Mon Oct  9 16:42:09 2017<br>
@@ -515,6 +515,7 @@ static bool isSingleLineLanguageLinkage(<br>
 }<br>
<br>
 static bool isExportedFromModuleIntefaceUn<wbr>it(const NamedDecl *D) {<br>
+  // FIXME: Handle isModulePrivate.<br>
   switch (D->getModuleOwnershipKind()) {<br>
   case Decl::ModuleOwnershipKind::Uno<wbr>wned:<br>
   case Decl::ModuleOwnershipKind::Mod<wbr>ulePrivate:<br>
@@ -546,7 +547,8 @@ static LinkageInfo getExternalLinkageFor<br>
   //     declaration has module linkage.<br>
   if (auto *M = D->getOwningModule())<br>
     if (M->Kind == Module::ModuleInterfaceUnit)<br>
-      if (!isExportedFromModuleInteface<wbr>Unit(D))<br>
+      if (!isExportedFromModuleInteface<wbr>Unit(<br>
+              cast<NamedDecl>(D->getCanonica<wbr>lDecl())))<br>
         return LinkageInfo(ModuleLinkage, DefaultVisibility, false);<br>
<br>
   return LinkageInfo::external();<br>
@@ -1393,7 +1395,7 @@ LinkageInfo LinkageComputer::getDeclLink<br>
                                             : NamedDecl::VisibilityForValue)<wbr>);<br>
 }<br>
<br>
-Module *NamedDecl::getOwningModuleFor<wbr>Linkage() const {<br>
+Module *Decl::getOwningModuleForLinka<wbr>ge() const {<br>
   Module *M = getOwningModule();<br>
   if (!M)<br>
     return nullptr;<br>
@@ -1411,7 +1413,15 @@ Module *NamedDecl::getOwningModuleFor<wbr>Lin<br>
     // for linkage purposes. But internal linkage declarations in the global<br>
     // module fragment of a particular module are owned by that module for<br>
     // linkage purposes.<br>
-    return hasExternalFormalLinkage() ? nullptr : M->Parent;<br>
+    bool InternalLinkage;<br>
+    if (auto *ND = dyn_cast<NamedDecl>(this))<br>
+      InternalLinkage = !ND->hasExternalFormalLinkage(<wbr>);<br>
+    else {<br>
+      auto *NSD = dyn_cast<NamespaceDecl>(this);<br>
+      InternalLinkage = (NSD && NSD->isAnonymousNamespace()) ||<br>
+                        isInAnonymousNamespace();<br>
+    }<br>
+    return InternalLinkage ? M->Parent : nullptr;<br>
   }<br>
<br>
   llvm_unreachable("unknown module kind");<br>
<br>
Modified: cfe/trunk/lib/AST/DeclBase.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=315251&r1=315250&r2=315251&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/AST/DeclBa<wbr>se.cpp?rev=315251&r1=315250&<wbr>r2=315251&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/AST/DeclBase.cpp (original)<br>
+++ cfe/trunk/lib/AST/DeclBase.cpp Mon Oct  9 16:42:09 2017<br>
@@ -315,12 +315,11 @@ bool Decl::isLexicallyWithinFunctio<wbr>nOrMe<br>
 }<br>
<br>
 bool Decl::isInAnonymousNamespace() const {<br>
-  const DeclContext *DC = getDeclContext();<br>
-  do {<br>
+  for (const DeclContext *DC = getDeclContext(); DC; DC = DC->getParent()) {<br>
     if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC))<br>
       if (ND->isAnonymousNamespace())<br>
         return true;<br>
-  } while ((DC = DC->getParent()));<br>
+  }<br>
<br>
   return false;<br>
 }<br>
<br>
Modified: cfe/trunk/lib/AST/DeclCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=315251&r1=315250&r2=315251&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/AST/DeclCX<wbr>X.cpp?rev=315251&r1=315250&r2=<wbr>315251&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)<br>
+++ cfe/trunk/lib/AST/DeclCXX.cpp Mon Oct  9 16:42:09 2017<br>
@@ -100,7 +100,7 @@ CXXRecordDecl::CXXRecordDecl(K<wbr>ind K, Tag<br>
 CXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK,<br>
                                      DeclContext *DC, SourceLocation StartLoc,<br>
                                      SourceLocation IdLoc, IdentifierInfo *Id,<br>
-                                     CXXRecordDecl* PrevDecl,<br>
+                                     CXXRecordDecl *PrevDecl,<br>
                                      bool DelayTypeCreation) {<br>
   CXXRecordDecl *R = new (C, DC) CXXRecordDecl(CXXRecord, TK, C, DC, StartLoc,<br>
                                                IdLoc, Id, PrevDecl);<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDecl.cp<wbr>p<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=315251&r1=315250&r2=315251&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/Sema/SemaD<wbr>ecl.cpp?rev=315251&r1=315250&<wbr>r2=315251&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/SemaDecl.cp<wbr>p (original)<br>
+++ cfe/trunk/lib/Sema/SemaDecl.cp<wbr>p Mon Oct  9 16:42:09 2017<br>
@@ -1448,6 +1448,46 @@ void Sema::FilterLookupForScope(Loo<wbr>kupRe<br>
   F.done();<br>
 }<br>
<br>
+/// We've determined that \p New is a redeclaration of \p Old. Check that they<br>
+/// have compatible owning modules.<br>
+bool Sema::CheckRedeclarationModule<wbr>Ownership(NamedDecl *New, NamedDecl *Old) {<br>
+  // FIXME: The Modules TS is not clear about how friend declarations are<br>
+  // to be treated. It's not meaningful to have different owning modules for<br>
+  // linkage in redeclarations of the same entity, so for now allow the<br>
+  // redeclaration and change the owning modules to match.<br>
+  if (New->getFriendObjectKind() &&<br>
+      Old->getOwningModuleForLinkage<wbr>() != New->getOwningModuleForLinkage<wbr>()) {<br>
+    New->setLocalOwningModule(Old-<wbr>>getOwningModule());<br>
+    makeMergedDefinitionVisible(Ne<wbr>w);<br>
+    return false;<br>
+  }<br>
+<br>
+  Module *NewM = New->getOwningModule();<br>
+  Module *OldM = Old->getOwningModule();<br>
+  if (NewM == OldM)<br>
+    return false;<br>
+<br>
+  // FIXME: Check proclaimed-ownership-declarati<wbr>ons here too.<br>
+  bool NewIsModuleInterface = NewM && NewM->Kind == Module::ModuleInterfaceUnit;<br>
+  bool OldIsModuleInterface = OldM && OldM->Kind == Module::ModuleInterfaceUnit;<br>
+  if (NewIsModuleInterface || OldIsModuleInterface) {<br>
+    // C++ Modules TS [basic.def.odr] 6.2/6.7 [sic]:<br>
+    //   if a declaration of D [...] appears in the purview of a module, all<br>
+    //   other such declarations shall appear in the purview of the same module<br>
+    Diag(New->getLocation(), diag::err_mismatched_owning_mo<wbr>dule)<br>
+      << New<br>
+      << NewIsModuleInterface<br>
+      << (NewIsModuleInterface ? NewM->getFullModuleName() : "")<br>
+      << OldIsModuleInterface<br>
+      << (OldIsModuleInterface ? OldM->getFullModuleName() : "");<br>
+    Diag(Old->getLocation(), diag::note_previous_declaratio<wbr>n);<br>
+    New->setInvalidDecl();<br>
+    return true;<br>
+  }<br>
+<br>
+  return false;<br>
+}<br>
+<br>
 static bool isUsingDecl(NamedDecl *D) {<br>
   return isa<UsingShadowDecl>(D) ||<br>
          isa<UnresolvedUsingTypenameDec<wbr>l>(D) ||<br>
@@ -2962,6 +3002,9 @@ bool Sema::MergeFunctionDecl(Functi<wbr>onDec<br>
     New->dropAttr<InternalLinkage<wbr>Attr>();<br>
   }<br>
<br>
+  if (CheckRedeclarationModuleOwner<wbr>ship(New, Old))<br>
+    return true;<br>
+<br>
   if (!getLangOpts().CPlusPlus) {<br>
     bool OldOvl = Old->hasAttr<OverloadableAttr><wbr>();<br>
     if (OldOvl != New->hasAttr<OverloadableAttr><wbr>() && !Old->isImplicit()) {<br>
@@ -3831,6 +3874,9 @@ void Sema::MergeVarDecl(VarDecl *New, Lo<br>
     return New->setInvalidDecl();<br>
   }<br>
<br>
+  if (CheckRedeclarationModuleOwner<wbr>ship(New, Old))<br>
+    return;<br>
+<br>
   // Variables with external linkage are analyzed in FinalizeDeclaratorGroup.<br>
<br>
   // FIXME: The test for external storage here seems wrong? We still<br>
@@ -4382,7 +4428,7 @@ static bool CheckAnonMemberRedeclaration<br>
                                          SourceLocation NameLoc,<br>
                                          bool IsUnion) {<br>
   LookupResult R(SemaRef, Name, NameLoc, Sema::LookupMemberName,<br>
-                 Sema::ForRedeclaration);<br>
+                 Sema::ForVisibleRedeclaration<wbr>);<br>
   if (!SemaRef.LookupName(R, S)) return false;<br>
<br>
   // Pick a representative declaration.<br>
@@ -5321,7 +5367,7 @@ NamedDecl *Sema::HandleDeclarator(Scope<br>
     D.setInvalidType();<br>
<br>
   LookupResult Previous(*this, NameInfo, LookupOrdinaryName,<br>
-                        ForRedeclaration);<br>
+                        forRedeclarationInCurContext()<wbr>);<br>
<br>
   // See if this is a redefinition of a variable in the same scope.<br>
   if (!D.getCXXScopeSpec().isSet()) {<br>
@@ -5347,8 +5393,10 @@ NamedDecl *Sema::HandleDeclarator(Scope<br>
                D.getDeclSpec().getStorageClas<wbr>sSpec() != DeclSpec::SCS_static)<br>
       CreateBuiltins = true;<br>
<br>
-    if (IsLinkageLookup)<br>
+    if (IsLinkageLookup) {<br>
       Previous.clear(LookupRedeclar<wbr>ationWithLinkage);<br>
+      Previous.setRedeclarationKind(<wbr>ForExternalRedeclaration);<br>
+    }<br>
<br>
     LookupName(Previous, S, CreateBuiltins);<br>
   } else { // Something like "int foo::x;"<br>
@@ -7096,7 +7144,7 @@ void Sema::CheckShadow(Scope *S, VarDecl<br>
     return;<br>
<br>
   LookupResult R(*this, D->getDeclName(), D->getLocation(),<br>
-                 Sema::LookupOrdinaryName, Sema::ForRedeclaration);<br>
+                 Sema::LookupOrdinaryName, Sema::ForVisibleRedeclaration)<wbr>;<br>
   LookupName(R, S);<br>
   if (NamedDecl *ShadowedDecl = getShadowedDeclaration(D, R))<br>
     CheckShadow(D, ShadowedDecl, R);<br>
@@ -7672,7 +7720,7 @@ static NamedDecl *DiagnoseInvalidRedecla<br>
   LookupResult Prev(SemaRef, Name, NewFD->getLocation(),<br>
                     IsLocalFriend ? Sema::LookupLocalFriendName<br>
                                   : Sema::LookupOrdinaryName,<br>
-                    Sema::ForRedeclaration);<br>
+                    Sema::ForVisibleRedeclaration)<wbr>;<br>
<br>
   NewFD->setInvalidDecl();<br>
   if (IsLocalFriend)<br>
@@ -11708,7 +11756,7 @@ Decl *Sema::ActOnParamDeclarator(Sc<wbr>ope *<br>
   // Check for redeclaration of parameters, e.g. int foo(int x, int x);<br>
   if (II) {<br>
     LookupResult R(*this, II, D.getIdentifierLoc(), LookupOrdinaryName,<br>
-                   ForRedeclaration);<br>
+                   ForVisibleRedeclaration);<br>
     LookupName(R, S);<br>
     if (R.isSingleResult()) {<br>
       NamedDecl *PrevDecl = R.getFoundDecl();<br>
@@ -13268,7 +13316,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned<br>
   bool isStdBadAlloc = false;<br>
   bool isStdAlignValT = false;<br>
<br>
-  RedeclarationKind Redecl = ForRedeclaration;<br>
+  RedeclarationKind Redecl = forRedeclarationInCurContext()<wbr>;<br>
   if (TUK == TUK_Friend || TUK == TUK_Reference)<br>
     Redecl = NotForRedeclaration;<br>
<br>
@@ -13546,10 +13594,10 @@ Decl *Sema::ActOnTag(Scope *S, unsigned<br>
     // type declared by an elaborated-type-specifier.  In C that is not correct<br>
     // and we should instead merge compatible types found by lookup.<br>
     if (getLangOpts().CPlusPlus) {<br>
-      Previous.setRedeclarationKind(<wbr>ForRedeclaration);<br>
+      Previous.setRedeclarationKind(<wbr>forRedeclarationInCurContext()<wbr>);<br>
       LookupQualifiedName(Previous, SearchDC);<br>
     } else {<br>
-      Previous.setRedeclarationKind(<wbr>ForRedeclaration);<br>
+      Previous.setRedeclarationKind(<wbr>forRedeclarationInCurContext()<wbr>);<br>
       LookupName(Previous, S);<br>
     }<br>
   }<br>
@@ -14047,6 +14095,9 @@ CreateNewDecl:<br>
   if (!Invalid && SearchDC->isRecord())<br>
     SetMemberAccessSpecifier(New, PrevDecl, AS);<br>
<br>
+  if (PrevDecl)<br>
+    CheckRedeclarationModuleOwners<wbr>hip(New, PrevDecl);<br>
+<br>
   if (TUK == TUK_Definition)<br>
     New->startDefinition();<br>
<br>
@@ -14400,7 +14451,8 @@ FieldDecl *Sema::HandleField(Scope *S, R<br>
<br>
   // Check to see if this name was declared as a member previously<br>
   NamedDecl *PrevDecl = nullptr;<br>
-  LookupResult Previous(*this, II, Loc, LookupMemberName, ForRedeclaration);<br>
+  LookupResult Previous(*this, II, Loc, LookupMemberName,<br>
+                        ForVisibleRedeclaration);<br>
   LookupName(Previous, S);<br>
   switch (Previous.getResultKind()) {<br>
     case LookupResult::Found:<br>
@@ -14788,7 +14840,7 @@ Decl *Sema::ActOnIvar(Scope *S,<br>
<br>
   if (II) {<br>
     NamedDecl *PrevDecl = LookupSingleName(S, II, Loc, LookupMemberName,<br>
-                                           ForRedeclaration);<br>
+                                           ForVisibleRedeclaration);<br>
     if (PrevDecl && isDeclInScope(PrevDecl, EnclosingContext, S)<br>
         && !isa<TagDecl>(PrevDecl)) {<br>
       Diag(Loc, diag::err_duplicate_member) << II;<br>
@@ -15509,7 +15561,7 @@ Sema::SkipBodyInfo Sema::shouldSkipAnonE<br>
   // determine if we should merge the definition with an existing one and<br>
   // skip the body.<br>
   NamedDecl *PrevDecl = LookupSingleName(S, II, IILoc, LookupOrdinaryName,<br>
-                                         ForRedeclaration);<br>
+                                         forRedeclarationInCurContext(<wbr>));<br>
   auto *PrevECD = dyn_cast_or_null<EnumConstantD<wbr>ecl>(PrevDecl);<br>
   if (!PrevECD)<br>
     return SkipBodyInfo();<br>
@@ -15540,7 +15592,7 @@ Decl *Sema::ActOnEnumConstant(Scope *S,<br>
   // Verify that there isn't already something declared with this name in this<br>
   // scope.<br>
   NamedDecl *PrevDecl = LookupSingleName(S, Id, IdLoc, LookupOrdinaryName,<br>
-                                         ForRedeclaration);<br>
+                                         ForVisibleRedeclaration);<br>
   if (PrevDecl && PrevDecl->isTemplateParameter(<wbr>)) {<br>
     // Maybe we will complain about the shadowed template parameter.<br>
     DiagnoseTemplateParameterShad<wbr>ow(IdLoc, PrevDecl);<br>
@@ -15567,8 +15619,7 @@ Decl *Sema::ActOnEnumConstant(Scope *S,<br>
     // enum constant will 'hide' the tag.<br>
     assert((getLangOpts().CPlusPl<wbr>us || !isa<TagDecl>(PrevDecl)) &&<br>
            "Received TagDecl when not in C++!");<br>
-    if (!isa<TagDecl>(PrevDecl) && isDeclInScope(PrevDecl, CurContext, S) &&<br>
-        shouldLinkPossiblyHiddenDecl(P<wbr>revDecl, New)) {<br>
+    if (!isa<TagDecl>(PrevDecl) && isDeclInScope(PrevDecl, CurContext, S)) {<br>
       if (isa<EnumConstantDecl>(PrevDec<wbr>l))<br>
         Diag(IdLoc, diag::err_redefinition_of_enum<wbr>erator) << Id;<br>
       else<br>
@@ -16150,7 +16201,8 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDe<br>
       else if (const auto *FE = M->getASTFile())<br>
         Diag(M->DefinitionLoc, diag::note_prev_module_definit<wbr>ion_from_ast_file)<br>
             << FE->getName();<br>
-      return nullptr;<br>
+      Mod = M;<br>
+      break;<br>
     }<br>
<br>
     // Create a Module for the module that we're defining.<br>
@@ -16169,6 +16221,7 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDe<br>
         PP.getIdentifierInfo(ModuleNa<wbr>me), Path[0].second);<br>
     Mod = getModuleLoader().loadModule(M<wbr>oduleLoc, Path, Module::AllVisible,<br>
                                        /*IsIncludeDirective=*/false);<br>
+    // FIXME: Produce an error in this case.<br>
     if (!Mod)<br>
       return nullptr;<br>
     break;<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDeclCXX<wbr>.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=315251&r1=315250&r2=315251&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/Sema/SemaD<wbr>eclCXX.cpp?rev=315251&r1=31525<wbr>0&r2=315251&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/SemaDeclCXX<wbr>.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDeclCXX<wbr>.cpp Mon Oct  9 16:42:09 2017<br>
@@ -790,7 +790,7 @@ Sema::ActOnDecompositionDeclar<wbr>ator(Scope<br>
     // Check for name conflicts.<br>
     DeclarationNameInfo NameInfo(B.Name, B.NameLoc);<br>
     LookupResult Previous(*this, NameInfo, LookupOrdinaryName,<br>
-                          ForRedeclaration);<br>
+                          ForVisibleRedeclaration);<br>
     LookupName(Previous, S,<br>
                /*CreateBuiltins*/DC->getRedec<wbr>lContext()->isTranslationUnit(<wbr>));<br>
<br>
@@ -822,7 +822,8 @@ Sema::ActOnDecompositionDeclar<wbr>ator(Scope<br>
   // is unnamed.<br>
   DeclarationNameInfo NameInfo((IdentifierInfo *)nullptr,<br>
                                Decomp.getLSquareLoc());<br>
-  LookupResult Previous(*this, NameInfo, LookupOrdinaryName, ForRedeclaration);<br>
+  LookupResult Previous(*this, NameInfo, LookupOrdinaryName,<br>
+                        ForVisibleRedeclaration);<br>
<br>
   // Build the variable that holds the non-decomposed object.<br>
   bool AddToScope = true;<br>
@@ -8465,7 +8466,8 @@ Decl *Sema::ActOnStartNamespaceDef(<wbr>Scope<br>
     // Since namespace names are unique in their scope, and we don't<br>
     // look through using directives, just look for any ordinary names<br>
     // as if by qualified name lookup.<br>
-    LookupResult R(*this, II, IdentLoc, LookupOrdinaryName, ForRedeclaration);<br>
+    LookupResult R(*this, II, IdentLoc, LookupOrdinaryName,<br>
+                   ForExternalRedeclaration);<br>
     LookupQualifiedName(R, CurContext->getRedeclContext()<wbr>);<br>
     NamedDecl *PrevDecl =<br>
         R.isSingleResult() ? R.getRepresentativeDecl() : nullptr;<br>
@@ -9402,7 +9404,7 @@ NamedDecl *Sema::BuildUsingDeclaration(S<br>
<br>
   // Do the redeclaration lookup in the current scope.<br>
   LookupResult Previous(*this, UsingName, LookupUsingDeclName,<br>
-                        ForRedeclaration);<br>
+                        ForVisibleRedeclaration);<br>
   Previous.setHideTags(false);<br>
   if (S) {<br>
     LookupName(Previous, S);<br>
@@ -9982,7 +9984,10 @@ Decl *Sema::ActOnAliasDeclaration(S<wbr>cope<br>
                                              TInfo->getTypeLoc().getBeginLo<wbr>c());<br>
   }<br>
<br>
-  LookupResult Previous(*this, NameInfo, LookupOrdinaryName, ForRedeclaration);<br>
+  LookupResult Previous(*this, NameInfo, LookupOrdinaryName,<br>
+                        TemplateParamLists.size()<br>
+                            ? forRedeclarationInCurContext()<br>
+                            : ForVisibleRedeclaration);<br>
   LookupName(Previous, S);<br>
<br>
   // Warn about shadowing the name of a template parameter.<br>
@@ -10085,8 +10090,10 @@ Decl *Sema::ActOnAliasDeclaration(S<wbr>cope<br>
<br>
     if (Invalid)<br>
       NewDecl->setInvalidDecl();<br>
-    else if (OldDecl)<br>
+    else if (OldDecl) {<br>
       NewDecl->setPreviousDecl(OldD<wbr>ecl);<br>
+      CheckRedeclarationModuleOwners<wbr>hip(NewDecl, OldDecl);<br>
+    }<br>
<br>
     NewND = NewDecl;<br>
   } else {<br>
@@ -10127,7 +10134,7 @@ Decl *Sema::ActOnNamespaceAliasDef(<wbr>Scope<br>
<br>
   // Check if we have a previous declaration with the same name.<br>
   LookupResult PrevR(*this, Alias, AliasLoc, LookupOrdinaryName,<br>
-                     ForRedeclaration);<br>
+                     ForVisibleRedeclaration);<br>
   LookupName(PrevR, S);<br>
<br>
   // Check we're not shadowing a template parameter.<br>
@@ -10340,7 +10347,8 @@ void Sema::CheckImplicitSpecialMemb<wbr>erDec<br>
   // implicit special members with this name.<br>
   DeclarationName Name = FD->getDeclName();<br>
   LookupResult R(*this, Name, SourceLocation(), LookupOrdinaryName,<br>
-                 ForRedeclaration);<br>
+                 FD->isExternallyDeclarable() ? ForExternalRedeclaration<br>
+                                              : ForVisibleRedeclaration);<br>
   for (auto *D : FD->getParent()->lookup(Name))<br>
     if (auto *Acceptable = R.getAcceptableDecl(D))<br>
       R.addDecl(Acceptable);<br>
@@ -13224,7 +13232,7 @@ Decl *Sema::ActOnExceptionDeclarato<wbr>r(Sco<br>
   IdentifierInfo *II = D.getIdentifier();<br>
   if (NamedDecl *PrevDecl = LookupSingleName(S, II, D.getIdentifierLoc(),<br>
                                              LookupOrdinaryName,<br>
-                                             ForRedeclaration)) {<br>
+                                             ForVisibleRedeclaration)) {<br>
     // The scope should be freshly made just for us. There is just no way<br>
     // it contains any previous declaration, except for function parameters in<br>
     // a function-try-block's catch statement.<br>
@@ -13673,7 +13681,7 @@ NamedDecl *Sema::ActOnFriendFunctionDecl<br>
   DeclContext *DC;<br>
   Scope *DCScope = S;<br>
   LookupResult Previous(*this, NameInfo, LookupOrdinaryName,<br>
-                        ForRedeclaration);<br>
+                        ForExternalRedeclaration);<br>
<br>
   // There are five cases here.<br>
   //   - There's no scope specifier and we're in a local class. Only look<br>
@@ -14947,7 +14955,8 @@ MSPropertyDecl *Sema::HandleMSProperty(S<br>
<br>
   // Check to see if this name was declared as a member previously<br>
   NamedDecl *PrevDecl = nullptr;<br>
-  LookupResult Previous(*this, II, Loc, LookupMemberName, ForRedeclaration);<br>
+  LookupResult Previous(*this, II, Loc, LookupMemberName,<br>
+                        ForVisibleRedeclaration);<br>
   LookupName(Previous, S);<br>
   switch (Previous.getResultKind()) {<br>
   case LookupResult::Found:<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDeclObj<wbr>C.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=315251&r1=315250&r2=315251&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/Sema/SemaD<wbr>eclObjC.cpp?rev=315251&r1=<wbr>315250&r2=315251&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/SemaDeclObj<wbr>C.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDeclObj<wbr>C.cpp Mon Oct  9 16:42:09 2017<br>
@@ -943,8 +943,9 @@ ActOnStartClassInterface(Scope *S, Sourc<br>
   assert(ClassName && "Missing class identifier");<br>
<br>
   // Check for another declaration kind with the same name.<br>
-  NamedDecl *PrevDecl = LookupSingleName(TUScope, ClassName, ClassLoc,<br>
-                                         LookupOrdinaryName, ForRedeclaration);<br>
+  NamedDecl *PrevDecl =<br>
+      LookupSingleName(TUScope, ClassName, ClassLoc, LookupOrdinaryName,<br>
+                       forRedeclarationInCurContext(<wbr>));<br>
<br>
   if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDe<wbr>cl)) {<br>
     Diag(ClassLoc, diag::err_redefinition_differe<wbr>nt_kind) << ClassName;<br>
@@ -1095,16 +1096,18 @@ Decl *Sema::ActOnCompatibilityAlias<wbr>(Sour<br>
                                     IdentifierInfo *ClassName,<br>
                                     SourceLocation ClassLocation) {<br>
   // Look for previous declaration of alias name<br>
-  NamedDecl *ADecl = LookupSingleName(TUScope, AliasName, AliasLocation,<br>
-                                      LookupOrdinaryName, ForRedeclaration);<br>
+  NamedDecl *ADecl =<br>
+      LookupSingleName(TUScope, AliasName, AliasLocation, LookupOrdinaryName,<br>
+                       forRedeclarationInCurContext(<wbr>));<br>
   if (ADecl) {<br>
     Diag(AliasLocation, diag::err_conflicting_aliasing<wbr>_type) << AliasName;<br>
     Diag(ADecl->getLocation(), diag::note_previous_declaratio<wbr>n);<br>
     return nullptr;<br>
   }<br>
   // Check for class declaration<br>
-  NamedDecl *CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation,<br>
-                                       LookupOrdinaryName, ForRedeclaration);<br>
+  NamedDecl *CDeclU =<br>
+      LookupSingleName(TUScope, ClassName, ClassLocation, LookupOrdinaryName,<br>
+                       forRedeclarationInCurContext(<wbr>));<br>
   if (const TypedefNameDecl *TDecl =<br>
         dyn_cast_or_null<TypedefNameD<wbr>ecl>(CDeclU)) {<br>
     QualType T = TDecl->getUnderlyingType();<br>
@@ -1112,7 +1115,8 @@ Decl *Sema::ActOnCompatibilityAlias<wbr>(Sour<br>
       if (NamedDecl *IDecl = T->getAs<ObjCObjectType>()->ge<wbr>tInterface()) {<br>
         ClassName = IDecl->getIdentifier();<br>
         CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation,<br>
-                                  LookupOrdinaryName, ForRedeclaration);<br>
+                                  LookupOrdinaryName,<br>
+                                  forRedeclarationInCurContext()<wbr>);<br>
       }<br>
     }<br>
   }<br>
@@ -1174,7 +1178,7 @@ Sema::ActOnStartProtocolInterf<wbr>ace(Source<br>
   // FIXME: Deal with AttrList.<br>
   assert(ProtocolName && "Missing protocol identifier");<br>
   ObjCProtocolDecl *PrevDecl = LookupProtocol(ProtocolName, ProtocolLoc,<br>
-                                              ForRedeclaration);<br>
+                                              forRedeclarationInCurContext()<wbr>);<br>
   ObjCProtocolDecl *PDecl = nullptr;<br>
   if (ObjCProtocolDecl *Def = PrevDecl? PrevDecl->getDefinition() : nullptr) {<br>
     // If we already have a definition, complain.<br>
@@ -1730,7 +1734,7 @@ Sema::ActOnForwardProtocolDecl<wbr>aration(So<br>
   for (const IdentifierLocPair &IdentPair : IdentList) {<br>
     IdentifierInfo *Ident = IdentPair.first;<br>
     ObjCProtocolDecl *PrevDecl = LookupProtocol(Ident, IdentPair.second,<br>
-                                                ForRedeclaration);<br>
+                                                forRedeclarationInCurContext()<wbr>);<br>
     ObjCProtocolDecl *PDecl<br>
       = ObjCProtocolDecl::Create(Conte<wbr>xt, CurContext, Ident,<br>
                                  IdentPair.second, AtProtocolLoc,<br>
@@ -1921,7 +1925,7 @@ Decl *Sema::ActOnStartClassImplemen<wbr>tatio<br>
   // Check for another declaration kind with the same name.<br>
   NamedDecl *PrevDecl<br>
     = LookupSingleName(TUScope, ClassName, ClassLoc, LookupOrdinaryName,<br>
-                       ForRedeclaration);<br>
+                       forRedeclarationInCurContext(<wbr>));<br>
   if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDe<wbr>cl)) {<br>
     Diag(ClassLoc, diag::err_redefinition_differe<wbr>nt_kind) << ClassName;<br>
     Diag(PrevDecl->getLocation(), diag::note_previous_definition<wbr>);<br>
@@ -2997,7 +3001,7 @@ Sema::ActOnForwardClassDeclara<wbr>tion(Sourc<br>
     // Check for another declaration kind with the same name.<br>
     NamedDecl *PrevDecl<br>
       = LookupSingleName(TUScope, IdentList[i], IdentLocs[i],<br>
-                         LookupOrdinaryName, ForRedeclaration);<br>
+                         LookupOrdinaryName, forRedeclarationInCurContext()<wbr>);<br>
     if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDe<wbr>cl)) {<br>
       // GCC apparently allows the following idiom:<br>
       //<br>
@@ -4443,7 +4447,7 @@ Decl *Sema::ActOnMethodDeclaration(<br>
     }<br>
<br>
     LookupResult R(*this, ArgInfo[i].Name, ArgInfo[i].NameLoc,<br>
-                   LookupOrdinaryName, ForRedeclaration);<br>
+                   LookupOrdinaryName, forRedeclarationInCurContext()<wbr>);<br>
     LookupName(R, S);<br>
     if (R.isSingleResult()) {<br>
       NamedDecl *PrevDecl = R.getFoundDecl();<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExprMem<wbr>ber.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprMember.cpp?rev=315251&r1=315250&r2=315251&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/Sema/SemaE<wbr>xprMember.cpp?rev=315251&r1=<wbr>315250&r2=315251&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/SemaExprMem<wbr>ber.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExprMem<wbr>ber.cpp Mon Oct  9 16:42:09 2017<br>
@@ -693,8 +693,7 @@ static bool LookupMemberExprInRecord(Sem<br>
     Sema::RedeclarationKind Redecl;<br>
   };<br>
   QueryState Q = {R.getSema(), R.getLookupNameInfo(), R.getLookupKind(),<br>
-                  R.isForRedeclaration() ? Sema::ForRedeclaration<br>
-                                         : Sema::NotForRedeclaration};<br>
+                  R.redeclarationKind()};<br>
   TE = SemaRef.CorrectTypoDelayed(<br>
       R.getLookupNameInfo(), R.getLookupKind(), nullptr, &SS,<br>
       llvm::make_unique<RecordMembe<wbr>rExprValidatorCCC>(RTy),<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaLookup.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=315251&r1=315250&r2=315251&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/Sema/SemaL<wbr>ookup.cpp?rev=315251&r1=315250<wbr>&r2=315251&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/SemaLookup.<wbr>cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaLookup.<wbr>cpp Mon Oct  9 16:42:09 2017<br>
@@ -1609,11 +1609,39 @@ bool Sema::isVisibleSlow(const NamedDecl<br>
 }<br>
<br>
 bool Sema::shouldLinkPossiblyHidden<wbr>Decl(LookupResult &R, const NamedDecl *New) {<br>
+  // FIXME: If there are both visible and hidden declarations, we need to take<br>
+  // into account whether redeclaration is possible. Example:<br>
+  //<br>
+  // Non-imported module:<br>
+  //   int f(T);        // #1<br>
+  // Some TU:<br>
+  //   static int f(U); // #2, not a redeclaration of #1<br>
+  //   int f(T);        // #3, finds both, should link with #1 if T != U, but<br>
+  //                    // with #2 if T == U; neither should be ambiguous.<br>
   for (auto *D : R) {<br>
     if (isVisible(D))<br>
       return true;<br>
+    assert(D->isExternallyDeclarab<wbr>le() &&<br>
+           "should not have hidden, non-externally-declarable result here");<br>
   }<br>
-  return New->isExternallyVisible();<br>
+<br>
+  // This function is called once "New" is essentially complete, but before a<br>
+  // previous declaration is attached. We can't query the linkage of "New" in<br>
+  // general, because attaching the previous declaration can change the<br>
+  // linkage of New to match the previous declaration.<br>
+  //<br>
+  // However, because we've just determined that there is no *visible* prior<br>
+  // declaration, we can compute the linkage here. There are two possibilities:<br>
+  //<br>
+  //  * This is not a redeclaration; it's safe to compute the linkage now.<br>
+  //<br>
+  //  * This is a redeclaration of a prior declaration that is externally<br>
+  //    redeclarable. In that case, the linkage of the declaration is not<br>
+  //    changed by attaching the prior declaration, because both are externally<br>
+  //    declarable (and thus ExternalLinkage or VisibleNoLinkage).<br>
+  //<br>
+  // FIXME: This is subtle and fragile.<br>
+  return New->isExternallyDeclarable();<br>
 }<br>
<br>
 /// \brief Retrieve the visible declaration corresponding to D, if any.<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaOpenMP.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=315251&r1=315250&r2=315251&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/Sema/SemaO<wbr>penMP.cpp?rev=315251&r1=315250<wbr>&r2=315251&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/SemaOpenMP.<wbr>cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaOpenMP.<wbr>cpp Mon Oct  9 16:42:09 2017<br>
@@ -11539,7 +11539,7 @@ Sema::DeclGroupPtrTy Sema::ActOnOpenMPDe<br>
   Decls.reserve(ReductionTypes.<wbr>size());<br>
<br>
   LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,<br>
-                      ForRedeclaration);<br>
+                      forRedeclarationInCurContext()<wbr>);<br>
   // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions<br>
   // A reduction-identifier may not be re-declared in the current scope for the<br>
   // same type or for a type that is compatible according to the base language<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaTemplat<wbr>e.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=315251&r1=315250&r2=315251&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/Sema/SemaT<wbr>emplate.cpp?rev=315251&r1=<wbr>315250&r2=315251&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/SemaTemplat<wbr>e.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaTemplat<wbr>e.cpp Mon Oct  9 16:42:09 2017<br>
@@ -778,7 +778,7 @@ static void maybeDiagnoseTemplateParamet<br>
                                                  SourceLocation Loc,<br>
                                                  IdentifierInfo *Name) {<br>
   NamedDecl *PrevDecl = SemaRef.LookupSingleName(<br>
-      S, Name, Loc, Sema::LookupOrdinaryName, Sema::ForRedeclaration);<br>
+      S, Name, Loc, Sema::LookupOrdinaryName, Sema::ForVisibleRedeclaration)<wbr>;<br>
   if (PrevDecl && PrevDecl->isTemplateParameter(<wbr>))<br>
     SemaRef.DiagnoseTemplateParam<wbr>eterShadow(Loc, PrevDecl);<br>
 }<br>
@@ -1133,7 +1133,7 @@ Sema::CheckClassTemplate(Scope *S, unsig<br>
   LookupResult Previous(*this, Name, NameLoc,<br>
                         (SS.isEmpty() && TUK == TUK_Friend)<br>
                           ? LookupTagName : LookupOrdinaryName,<br>
-                        ForRedeclaration);<br>
+                        forRedeclarationInCurContext()<wbr>);<br>
   if (SS.isNotEmpty() && !SS.isInvalid()) {<br>
     SemanticContext = computeDeclContext(SS, true);<br>
     if (!SemanticContext) {<br>
@@ -1192,8 +1192,8 @@ Sema::CheckClassTemplate(Scope *S, unsig<br>
<br>
   // If there is a previous declaration with the same name, check<br>
   // whether this is a valid redeclaration.<br>
-  ClassTemplateDecl *PrevClassTemplate<br>
-    = dyn_cast_or_null<ClassTemplate<wbr>Decl>(PrevDecl);<br>
+  ClassTemplateDecl *PrevClassTemplate =<br>
+      dyn_cast_or_null<ClassTemplate<wbr>Decl>(PrevDecl);<br>
<br>
   // We may have found the injected-class-name of a class template,<br>
   // class template partial specialization, or class template specialization.<br>
@@ -1484,6 +1484,9 @@ Sema::CheckClassTemplate(Scope *S, unsig<br>
     CurContext->addDecl(Friend);<br>
   }<br>
<br>
+  if (PrevClassTemplate)<br>
+    CheckRedeclarationModuleOwners<wbr>hip(NewTemplate, PrevClassTemplate);<br>
+<br>
   if (Invalid) {<br>
     NewTemplate->setInvalidDecl()<wbr>;<br>
     NewClass->setInvalidDecl();<br>
@@ -3677,7 +3680,7 @@ DeclResult Sema::ActOnVarTemplateSpecial<br>
     // Check that this isn't a redefinition of this specialization,<br>
     // merging with previous declarations.<br>
     LookupResult PrevSpec(*this, GetNameForDeclarator(D), LookupOrdinaryName,<br>
-                          ForRedeclaration);<br>
+                          forRedeclarationInCurContext()<wbr>);<br>
     PrevSpec.addDecl(PrevDecl);<br>
     D.setRedeclaration(CheckVaria<wbr>bleDeclaration(Specialization, PrevSpec));<br>
   } else if (Specialization->isStaticDataM<wbr>ember() &&<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaTemplat<wbr>eInstantiateDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=315251&r1=315250&r2=315251&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/Sema/SemaT<wbr>emplateInstantiateDecl.cpp?<wbr>rev=315251&r1=315250&r2=315251<wbr>&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/SemaTemplat<wbr>eInstantiateDecl.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaTemplat<wbr>eInstantiateDecl.cpp Mon Oct  9 16:42:09 2017<br>
@@ -1195,7 +1195,8 @@ Decl *TemplateDeclInstantiator::Vis<wbr>itCla<br>
     // Look for a previous declaration of the template in the owning<br>
     // context.<br>
     LookupResult R(SemaRef, Pattern->getDeclName(), Pattern->getLocation(),<br>
-                   Sema::LookupOrdinaryName, Sema::ForRedeclaration);<br>
+                   Sema::LookupOrdinaryName,<br>
+                   SemaRef.forRedeclarationInCur<wbr>Context());<br>
     SemaRef.LookupQualifiedName(R<wbr>, DC);<br>
<br>
     if (R.isSingleResult()) {<br>
@@ -1735,7 +1736,8 @@ Decl *TemplateDeclInstantiator::Vis<wbr>itFun<br>
       SemaRef, Function->getDeclName(), SourceLocation(),<br>
       D->isLocalExternDecl() ? Sema::LookupRedeclarationWithL<wbr>inkage<br>
                              : Sema::LookupOrdinaryName,<br>
-      Sema::ForRedeclaration);<br>
+      D->isLocalExternDecl() ? Sema::ForExternalRedeclaration<br>
+                             : SemaRef.forRedeclarationInCurC<wbr>ontext());<br>
<br>
   if (DependentFunctionTemplateSpec<wbr>ializationInfo *Info<br>
         = D->getDependentSpecializationI<wbr>nfo()) {<br>
@@ -2053,7 +2055,7 @@ TemplateDeclInstantiator::Visi<wbr>tCXXMethod<br>
     Method->setInvalidDecl();<br>
<br>
   LookupResult Previous(SemaRef, NameInfo, Sema::LookupOrdinaryName,<br>
-                        Sema::ForRedeclaration);<br>
+                        Sema::ForExternalRedeclaration<wbr>);<br>
<br>
   if (!FunctionTemplate || TemplateParams || isFriend) {<br>
     SemaRef.LookupQualifiedName(P<wbr>revious, Record);<br>
@@ -2492,7 +2494,7 @@ Decl *TemplateDeclInstantiator::Vis<wbr>itUsi<br>
   bool CheckRedeclaration = Owner->isRecord();<br>
<br>
   LookupResult Prev(SemaRef, NameInfo, Sema::LookupUsingDeclName,<br>
-                    Sema::ForRedeclaration);<br>
+                    Sema::ForVisibleRedeclaration)<wbr>;<br>
<br>
   UsingDecl *NewUD = UsingDecl::Create(SemaRef.Cont<wbr>ext, Owner,<br>
                                        D->getUsingLoc(),<br>
@@ -2711,7 +2713,7 @@ Decl *TemplateDeclInstantiator::Vis<wbr>itCla<br>
     return nullptr;<br>
<br>
   LookupResult Previous(SemaRef, NewFD->getNameInfo(), Sema::LookupOrdinaryName,<br>
-                        Sema::ForRedeclaration);<br>
+                        Sema::ForExternalRedeclaration<wbr>);<br>
<br>
   TemplateArgumentListInfo TemplateArgs;<br>
   TemplateArgumentListInfo *TemplateArgsPtr = nullptr;<br>
@@ -4074,7 +4076,8 @@ void Sema::BuildVariableInstantiati<wbr>on(<br>
       *this, NewVar->getDeclName(), NewVar->getLocation(),<br>
       NewVar->isLocalExternDecl() ? Sema::LookupRedeclarationWithL<wbr>inkage<br>
                                   : Sema::LookupOrdinaryName,<br>
-      Sema::ForRedeclaration);<br>
+      NewVar->isLocalExternDecl() ? Sema::ForExternalRedeclaration<br>
+                                  : forRedeclarationInCurContext()<wbr>);<br>
<br>
   if (NewVar->isLocalExternDecl() && OldVar->getPreviousDecl() &&<br>
       (!OldVar->getPreviousDecl()-><wbr>getDeclContext()->isDependentC<wbr>ontext() ||<br>
@@ -4432,7 +4435,7 @@ void Sema::InstantiateVariableDefin<wbr>ition<br>
<br>
       // Merge the definition with the declaration.<br>
       LookupResult R(*this, Var->getDeclName(), Var->getLocation(),<br>
-                     LookupOrdinaryName, ForRedeclaration);<br>
+                     LookupOrdinaryName, forRedeclarationInCurContext()<wbr>);<br>
       R.addDecl(OldVar);<br>
       MergeVarDecl(Var, R);<br>
<br>
<br>
Added: cfe/trunk/test/CXX/modules-ts/<wbr>basic/basic.def.odr/p6/global-<wbr>vs-module.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p6/global-vs-module.cpp?rev=315251&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/test/CXX/modul<wbr>es-ts/basic/basic.def.odr/p6/<wbr>global-vs-module.cpp?rev=<wbr>315251&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/CXX/modules-ts/<wbr>basic/basic.def.odr/p6/global-<wbr>vs-module.cpp (added)<br>
+++ cfe/trunk/test/CXX/modules-ts/<wbr>basic/basic.def.odr/p6/global-<wbr>vs-module.cpp Mon Oct  9 16:42:09 2017<br>
@@ -0,0 +1,55 @@<br>
+// RUN: %clang_cc1 -fmodules-ts -verify -std=c++17 %s<br>
+// RUN: %clang_cc1 -fmodules-ts -verify -std=c++17 %s -DEXPORT<br>
+// RUN: %clang_cc1 -fmodules-ts -verify -std=c++17 %s -DUSING<br>
+<br>
+#ifndef NO_GLOBAL<br>
+extern int var; // expected-note {{previous declaration is here}}<br>
+int func(); // expected-note {{previous declaration is here}}<br>
+struct str; // expected-note {{previous declaration is here}}<br>
+using type = int;<br>
+<br>
+template<typename> extern int var_tpl; // expected-note {{previous declaration is here}}<br>
+template<typename> int func_tpl(); // expected-note-re {{{{previous declaration is here|target of using declaration}}}}<br>
+template<typename> struct str_tpl; // expected-note {{previous declaration is here}}<br>
+template<typename> using type_tpl = int; // expected-note {{previous declaration is here}}<br>
+<br>
+typedef int type;<br>
+namespace ns { using ::func; }<br>
+namespace ns_alias = ns;<br>
+#endif<br>
+<br>
+export module M;<br>
+<br>
+#ifdef USING<br>
+using ::var;<br>
+using ::func;<br>
+using ::str;<br>
+using ::type;<br>
+using ::var_tpl;<br>
+using ::func_tpl; // expected-note {{using declaration}}<br>
+using ::str_tpl;<br>
+using ::type_tpl;<br>
+#endif<br>
+<br>
+#ifdef EXPORT<br>
+export {<br>
+#endif<br>
+<br>
+extern int var; // expected-error {{declaration of 'var' in module M follows declaration in the global module}}<br>
+int func(); // expected-error {{declaration of 'func' in module M follows declaration in the global module}}<br>
+struct str; // expected-error {{declaration of 'str' in module M follows declaration in the global module}}<br>
+using type = int;<br>
+<br>
+template<typename> extern int var_tpl; // expected-error {{declaration of 'var_tpl' in module M follows declaration in the global module}}<br>
+// FIXME: Is this the right diagnostic in the -DUSING case?<br>
+template<typename> int func_tpl(); // expected-error-re {{{{declaration of 'func_tpl' in module M follows declaration in the global module|conflicts with target of using declaration}}}}<br>
+template<typename> struct str_tpl; // expected-error {{declaration of 'str_tpl' in module M follows declaration in the global module}}<br>
+template<typename> using type_tpl = int; // expected-error {{declaration of 'type_tpl' in module M follows declaration in the global module}}<br>
+<br>
+typedef int type;<br>
+namespace ns { using ::func; }<br>
+namespace ns_alias = ns;<br>
+<br>
+#ifdef EXPORT<br>
+}<br>
+#endif<br>
<br>
Added: cfe/trunk/test/CXX/modules-ts/<wbr>basic/basic.def.odr/p6/module-<wbr>vs-global.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p6/module-vs-global.cpp?rev=315251&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/test/CXX/modul<wbr>es-ts/basic/basic.def.odr/p6/<wbr>module-vs-global.cpp?rev=<wbr>315251&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/CXX/modules-ts/<wbr>basic/basic.def.odr/p6/module-<wbr>vs-global.cpp (added)<br>
+++ cfe/trunk/test/CXX/modules-ts/<wbr>basic/basic.def.odr/p6/module-<wbr>vs-global.cpp Mon Oct  9 16:42:09 2017<br>
@@ -0,0 +1,19 @@<br>
+// RUN: rm -rf %t<br>
+// RUN: %clang_cc1 -fmodules-ts -emit-module-interface -std=c++17 %S/global-vs-module.cpp -o %t -DNO_GLOBAL -DEXPORT<br>
+// RUN: %clang_cc1 -fmodules-ts -verify -std=c++17 %s -fmodule-file=%t<br>
+<br>
+import M;<br>
+<br>
+extern int var; // expected-error {{declaration of 'var' in the global module follows declaration in module M}} expected-note@global-vs-module<wbr>.cpp:38 {{previous}}<br>
+int func(); // expected-error {{declaration of 'func' in the global module follows declaration in module M}} expected-note@global-vs-module<wbr>.cpp:39 {{previous}}<br>
+struct str; // expected-error {{declaration of 'str' in the global module follows declaration in module M}} expected-note@global-vs-module<wbr>.cpp:40 {{previous}}<br>
+using type = int;<br>
+<br>
+template<typename> extern int var_tpl; // expected-error {{declaration of 'var_tpl' in the global module follows declaration in module M}} expected-note@global-vs-module<wbr>.cpp:43 {{previous}}<br>
+template<typename> int func_tpl(); // expected-error {{declaration of 'func_tpl' in the global module follows declaration in module M}} expected-note@global-vs-module<wbr>.cpp:45 {{previous}}<br>
+template<typename> struct str_tpl; // expected-error {{declaration of 'str_tpl' in the global module follows declaration in module M}} expected-note@global-vs-module<wbr>.cpp:46 {{previous}}<br>
+template<typename> using type_tpl = int; // expected-error {{declaration of 'type_tpl' in the global module follows declaration in module M}} expected-note@global-vs-module<wbr>.cpp:47 {{previous}}<br>
+<br>
+typedef int type;<br>
+namespace ns { using ::func; }<br>
+namespace ns_alias = ns;<br>
<br>
Added: cfe/trunk/test/CXX/modules-ts/<wbr>basic/basic.def.odr/p6/module-<wbr>vs-module.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p6/module-vs-module.cpp?rev=315251&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/test/CXX/modul<wbr>es-ts/basic/basic.def.odr/p6/<wbr>module-vs-module.cpp?rev=<wbr>315251&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/CXX/modules-ts/<wbr>basic/basic.def.odr/p6/module-<wbr>vs-module.cpp (added)<br>
+++ cfe/trunk/test/CXX/modules-ts/<wbr>basic/basic.def.odr/p6/module-<wbr>vs-module.cpp Mon Oct  9 16:42:09 2017<br>
@@ -0,0 +1,44 @@<br>
+// RUN: rm -rf %t<br>
+// RUN: mkdir %t<br>
+//<br>
+// Some of the following tests intentionally have no -verify in their RUN<br>
+// lines; we are testing that those cases do not produce errors.<br>
+//<br>
+// RUN: %clang_cc1 -fmodules-ts -std=c++17 %S/global-vs-module.cpp -emit-module-interface -o %t/M.pcm -DNO_GLOBAL -DEXPORT<br>
+// RUN: %clang_cc1 -fmodules-ts -std=c++17 %s -fmodule-file=%t/M.pcm -DMODULE_INTERFACE -verify<br>
+// RUN: %clang_cc1 -fmodules-ts -std=c++17 %s -fmodule-file=%t/M.pcm -DMODULE_INTERFACE -DNO_IMPORT<br>
+//<br>
+// RUN: %clang_cc1 -fmodules-ts -std=c++17 %s -fmodule-file=%t/M.pcm -emit-module-interface -o %t/N.pcm -DMODULE_INTERFACE -DNO_ERRORS<br>
+// RUN: %clang_cc1 -fmodules-ts -std=c++17 %s -fmodule-file=%t/N.pcm -verify<br>
+// FIXME: Once we start importing "import" declarations properly, this should<br>
+// be rejected (-verify should be added to the following line).<br>
+// RUN: %clang_cc1 -fmodules-ts -std=c++17 %s -fmodule-file=%t/N.pcm -DNO_IMPORT<br>
+//<br>
+// RUN: %clang_cc1 -fmodules-ts -std=c++17 %s -fmodule-file=%t/M.pcm -emit-module-interface -o %t/N-no-M.pcm -DMODULE_INTERFACE -DNO_ERRORS -DNO_IMPORT<br>
+// RUN: %clang_cc1 -fmodules-ts -std=c++17 %s -fmodule-file=%t/N-no-M.pcm -verify<br>
+// RUN: %clang_cc1 -fmodules-ts -std=c++17 %s -fmodule-file=%t/N-no-M.pcm -DNO_IMPORT<br>
+<br>
+#ifdef MODULE_INTERFACE<br>
+export<br>
+#endif<br>
+module N;<br>
+<br>
+#ifndef NO_IMPORT<br>
+import M;<br>
+#endif<br>
+<br>
+#ifndef NO_ERRORS<br>
+extern int var; // expected-error {{declaration of 'var' in module N follows declaration in module M}} expected-note@global-vs-module<wbr>.cpp:38 {{previous}}<br>
+int func(); // expected-error {{declaration of 'func' in module N follows declaration in module M}} expected-note@global-vs-module<wbr>.cpp:39 {{previous}}<br>
+struct str; // expected-error {{declaration of 'str' in module N follows declaration in module M}} expected-note@global-vs-module<wbr>.cpp:40 {{previous}}<br>
+using type = int;<br>
+<br>
+template<typename> extern int var_tpl; // expected-error {{declaration of 'var_tpl' in module N follows declaration in module M}} expected-note@global-vs-module<wbr>.cpp:43 {{previous}}<br>
+template<typename> int func_tpl(); // expected-error {{declaration of 'func_tpl' in module N follows declaration in module M}} expected-note@global-vs-module<wbr>.cpp:45 {{previous}}<br>
+template<typename> struct str_tpl; // expected-error {{declaration of 'str_tpl' in module N follows declaration in module M}} expected-note@global-vs-module<wbr>.cpp:46 {{previous}}<br>
+template<typename> using type_tpl = int; // expected-error {{declaration of 'type_tpl' in module N follows declaration in module M}} expected-note@global-vs-module<wbr>.cpp:47 {{previous}}<br>
+<br>
+typedef int type;<br>
+namespace ns { using ::func; }<br>
+namespace ns_alias = ns;<br>
+#endif<br>
<br>
Modified: cfe/trunk/test/SemaCXX/modules<wbr>-ts.cppm<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/modules-ts.cppm?rev=315251&r1=315250&r2=315251&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/test/SemaCXX/<wbr>modules-ts.cppm?rev=315251&r1=<wbr>315250&r2=315251&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/SemaCXX/modules<wbr>-ts.cppm (original)<br>
+++ cfe/trunk/test/SemaCXX/modules<wbr>-ts.cppm Mon Oct  9 16:42:09 2017<br>
@@ -14,7 +14,7 @@ export module foo;<br>
 #endif<br>
<br>
 static int m;<br>
-#if TEST == 2 // FIXME: 'm' has internal linkage, so there should be no error here<br>
+#if TEST == 2<br>
 // expected-error@-2 {{redefinition of '}}<br>
 // expected-note@-3 {{unguarded header; consider using #ifdef guards or #pragma once}}<br>
 // FIXME: We should drop the "header from" in this diagnostic.<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">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>
</div><br>______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">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>
<br></blockquote></div><br></div></div></div></blockquote></div>
</div></div><br>______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">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>
<br></blockquote></div><br></div></div></div></div>
</blockquote></div><br></div>