r315251 - [Modules TS] Module ownership semantics for redeclarations.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 10 09:10:00 PDT 2017


On 10 Oct 2017 05:41, "Eric Liu via cfe-commits" <cfe-commits at lists.llvm.org>
wrote:

Hi Richard,

This is breaking the boostrap stage in the internal integration. I'm seeing
"unsupported: typedef changes linkage of anonymous type, but linkage was
already computed" 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.


r315256 should have fixed those errors. Did it not?

I'll also send you the repros separately.

Regards,
Eric

On Tue, Oct 10, 2017 at 1:42 AM Richard Smith via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> Author: rsmith
> Date: Mon Oct  9 16:42:09 2017
> New Revision: 315251
>
> URL: http://llvm.org/viewvc/llvm-project?rev=315251&view=rev
> Log:
> [Modules TS] Module ownership semantics for redeclarations.
>
> When declaring an entity in the "purview" of a module, it's never a
> redeclaration of an entity in the purview of a default module or in no
> module
> ("in the global module"). Don't consider those other declarations as
> possible
> redeclaration targets if they're not visible, and reject any cases where we
> pick a prior visible declaration that violates this rule.
>
> Added:
>     cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p6/
>     cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p6/global-
> vs-module.cpp
>     cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p6/module-
> vs-global.cpp
>     cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p6/module-
> vs-module.cpp
> Modified:
>     cfe/trunk/include/clang/AST/Decl.h
>     cfe/trunk/include/clang/AST/DeclBase.h
>     cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>     cfe/trunk/include/clang/Sema/Lookup.h
>     cfe/trunk/include/clang/Sema/Sema.h
>     cfe/trunk/lib/AST/Decl.cpp
>     cfe/trunk/lib/AST/DeclBase.cpp
>     cfe/trunk/lib/AST/DeclCXX.cpp
>     cfe/trunk/lib/Sema/SemaDecl.cpp
>     cfe/trunk/lib/Sema/SemaDeclCXX.cpp
>     cfe/trunk/lib/Sema/SemaDeclObjC.cpp
>     cfe/trunk/lib/Sema/SemaExprMember.cpp
>     cfe/trunk/lib/Sema/SemaLookup.cpp
>     cfe/trunk/lib/Sema/SemaOpenMP.cpp
>     cfe/trunk/lib/Sema/SemaTemplate.cpp
>     cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
>     cfe/trunk/test/SemaCXX/modules-ts.cppm
>
> Modified: cfe/trunk/include/clang/AST/Decl.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/AST/Decl.h?rev=315251&r1=315250&r2=315251&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/AST/Decl.h (original)
> +++ cfe/trunk/include/clang/AST/Decl.h Mon Oct  9 16:42:09 2017
> @@ -339,6 +339,12 @@ public:
>      return clang::isExternallyVisible(getLinkageInternal());
>    }
>
> +  /// Determine whether this declaration can be redeclared in a
> +  /// different translation unit.
> +  bool isExternallyDeclarable() const {
> +    return isExternallyVisible() && !getOwningModuleForLinkage();
> +  }
> +
>    /// \brief Determines the visibility of this entity.
>    Visibility getVisibility() const {
>      return getLinkageAndVisibility().getVisibility();
> @@ -379,10 +385,6 @@ public:
>      return hasCachedLinkage();
>    }
>
> -  /// Get the module that owns this declaration for linkage purposes.
> -  /// There only ever is such a module under the C++ Modules TS.
> -  Module *getOwningModuleForLinkage() const;
> -
>    /// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for
>    /// the underlying named decl.
>    NamedDecl *getUnderlyingDecl() {
>
> Modified: cfe/trunk/include/clang/AST/DeclBase.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/AST/DeclBase.h?rev=315251&r1=315250&r2=315251&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/AST/DeclBase.h (original)
> +++ cfe/trunk/include/clang/AST/DeclBase.h Mon Oct  9 16:42:09 2017
> @@ -738,6 +738,10 @@ public:
>      return isFromASTFile() ? getImportedOwningModule() :
> getLocalOwningModule();
>    }
>
> +  /// Get the module that owns this declaration for linkage purposes.
> +  /// There only ever is such a module under the C++ Modules TS.
> +  Module *getOwningModuleForLinkage() const;
> +
>    /// \brief Determine whether this declaration might be hidden from name
>    /// lookup. Note that the declaration might be visible even if this
> returns
>    /// \c false, if the owning module is visible within the query context.
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/
> DiagnosticSemaKinds.td?rev=315251&r1=315250&r2=315251&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Oct  9
> 16:42:09 2017
> @@ -4801,6 +4801,9 @@ def err_thread_non_thread : Error<
>  def err_thread_thread_different_kind : Error<
>    "thread-local declaration of %0 with %select{static|dynamic}1
> initialization "
>    "follows declaration with %select{dynamic|static}1 initialization">;
> +def err_mismatched_owning_module : Error<
> +  "declaration of %0 in %select{the global module|module %2}1 follows "
> +  "declaration in %select{the global module|module %4}3">;
>  def err_redefinition_different_type : Error<
>    "redefinition of %0 with a different type%diff{: $ vs $|}1,2">;
>  def err_redefinition_different_kind : Error<
>
> Modified: cfe/trunk/include/clang/Sema/Lookup.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/Sema/Lookup.h?rev=315251&r1=315250&r2=315251&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/Sema/Lookup.h (original)
> +++ cfe/trunk/include/clang/Sema/Lookup.h Mon Oct  9 16:42:09 2017
> @@ -139,6 +139,7 @@ public:
>        LookupKind(LookupKind),
>        IDNS(0),
>        Redecl(Redecl != Sema::NotForRedeclaration),
> +      ExternalRedecl(Redecl == Sema::ForExternalRedeclaration),
>        HideTags(true),
>        Diagnose(Redecl == Sema::NotForRedeclaration),
>        AllowHidden(false),
> @@ -161,6 +162,7 @@ public:
>        LookupKind(LookupKind),
>        IDNS(0),
>        Redecl(Redecl != Sema::NotForRedeclaration),
> +      ExternalRedecl(Redecl == Sema::ForExternalRedeclaration),
>        HideTags(true),
>        Diagnose(Redecl == Sema::NotForRedeclaration),
>        AllowHidden(false),
> @@ -181,6 +183,7 @@ public:
>        LookupKind(Other.LookupKind),
>        IDNS(Other.IDNS),
>        Redecl(Other.Redecl),
> +      ExternalRedecl(Other.ExternalRedecl),
>        HideTags(Other.HideTags),
>        Diagnose(false),
>        AllowHidden(Other.AllowHidden),
> @@ -201,7 +204,9 @@ public:
>          SemaPtr(std::move(Other.SemaPtr)), NameInfo(std::move(Other.
> NameInfo)),
>          NameContextRange(std::move(Other.NameContextRange)),
>          LookupKind(std::move(Other.LookupKind)),
> IDNS(std::move(Other.IDNS)),
> -        Redecl(std::move(Other.Redecl)), HideTags(std::move(Other.
> HideTags)),
> +        Redecl(std::move(Other.Redecl)),
> +        ExternalRedecl(std::move(Other.ExternalRedecl)),
> +        HideTags(std::move(Other.HideTags)),
>          Diagnose(std::move(Other.Diagnose)),
>          AllowHidden(std::move(Other.AllowHidden)),
>          Shadowed(std::move(Other.Shadowed)) {
> @@ -221,6 +226,7 @@ public:
>      LookupKind = std::move(Other.LookupKind);
>      IDNS = std::move(Other.IDNS);
>      Redecl = std::move(Other.Redecl);
> +    ExternalRedecl = std::move(Other.ExternalRedecl);
>      HideTags = std::move(Other.HideTags);
>      Diagnose = std::move(Other.Diagnose);
>      AllowHidden = std::move(Other.AllowHidden);
> @@ -265,6 +271,17 @@ public:
>      return Redecl;
>    }
>
> +  /// True if this lookup is just looking for an existing declaration to
> link
> +  /// against a declaration with external linkage.
> +  bool isForExternalRedeclaration() const {
> +    return ExternalRedecl;
> +  }
> +
> +  Sema::RedeclarationKind redeclarationKind() const {
> +    return ExternalRedecl ? Sema::ForExternalRedeclaration :
> +           Redecl ? Sema::ForVisibleRedeclaration :
> Sema::NotForRedeclaration;
> +  }
> +
>    /// \brief Specify whether hidden declarations are visible, e.g.,
>    /// for recovery reasons.
>    void setAllowHidden(bool AH) {
> @@ -275,7 +292,7 @@ public:
>    /// declarations, such as those in modules that have not yet been
> imported.
>    bool isHiddenDeclarationVisible(NamedDecl *ND) const {
>      return AllowHidden ||
> -           (isForRedeclaration() && ND->hasExternalFormalLinkage());
> +           (isForExternalRedeclaration() && ND->isExternallyDeclarable());
>    }
>
>    /// Sets whether tag declarations should be hidden by non-tag
> @@ -556,7 +573,8 @@ public:
>
>    /// \brief Change this lookup's redeclaration kind.
>    void setRedeclarationKind(Sema::RedeclarationKind RK) {
> -    Redecl = RK;
> +    Redecl = (RK != Sema::NotForRedeclaration);
> +    ExternalRedecl = (RK == Sema::ForExternalRedeclaration);
>      configure();
>    }
>
> @@ -719,6 +737,7 @@ private:
>    unsigned IDNS; // set by configure()
>
>    bool Redecl;
> +  bool ExternalRedecl;
>
>    /// \brief True if tag declarations should be hidden if non-tags
>    ///   are present
>
> Modified: cfe/trunk/include/clang/Sema/Sema.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/Sema/Sema.h?rev=315251&r1=315250&r2=315251&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/Sema/Sema.h (original)
> +++ cfe/trunk/include/clang/Sema/Sema.h Mon Oct  9 16:42:09 2017
> @@ -285,15 +285,21 @@ class Sema {
>
>    bool isVisibleSlow(const NamedDecl *D);
>
> +  /// Determine whether two declarations should be linked together, given
> that
> +  /// the old declaration might not be visible and the new declaration
> might
> +  /// not have external linkage.
>    bool shouldLinkPossiblyHiddenDecl(const NamedDecl *Old,
>                                      const NamedDecl *New) {
> -    // We are about to link these. It is now safe to compute the linkage
> of
> -    // the new decl. If the new decl has external linkage, we will
> -    // link it with the hidden decl (which also has external linkage) and
> -    // it will keep having external linkage. If it has internal linkage,
> we
> -    // will not link it. Since it has no previous decls, it will remain
> -    // with internal linkage.
> -    return isVisible(Old) || New->isExternallyVisible();
> +    if (isVisible(Old))
> +     return true;
> +    // See comment in below overload for why it's safe to compute the
> linkage
> +    // of the new declaration here.
> +    if (New->isExternallyDeclarable()) {
> +      assert(Old->isExternallyDeclarable() &&
> +             "should not have found a non-externally-declarable previous
> decl");
> +      return true;
> +    }
> +    return false;
>    }
>    bool shouldLinkPossiblyHiddenDecl(LookupResult &Old, const NamedDecl
> *New);
>
> @@ -3035,10 +3041,22 @@ public:
>      /// purpose of redeclaring the name.
>      NotForRedeclaration = 0,
>      /// \brief The lookup results will be used for redeclaration of a
> name,
> -    /// if an entity by that name already exists.
> -    ForRedeclaration
> +    /// if an entity by that name already exists and is visible.
> +    ForVisibleRedeclaration,
> +    /// \brief The lookup results will be used for redeclaration of a name
> +    /// with external linkage; non-visible lookup results with external
> linkage
> +    /// may also be found.
> +    ForExternalRedeclaration
>    };
>
> +  RedeclarationKind forRedeclarationInCurContext() {
> +    // A declaration with an owning module for linkage can never link
> against
> +    // anything that is not visible.
> +    if (cast<Decl>(CurContext)->getOwningModuleForLinkage())
> +      return ForVisibleRedeclaration;
> +    return ForExternalRedeclaration;
> +  }
> +
>    /// \brief The possible outcomes of name lookup for a literal operator.
>    enum LiteralOperatorLookupResult {
>      /// \brief The lookup resulted in an error.
> @@ -3266,6 +3284,8 @@ public:
>    void FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S,
>                              bool ConsiderLinkage, bool
> AllowInlineNamespace);
>
> +  bool CheckRedeclarationModuleOwnership(NamedDecl *New, NamedDecl *Old);
> +
>    void DiagnoseAmbiguousLookup(LookupResult &Result);
>    //@}
>
>
> Modified: cfe/trunk/lib/AST/Decl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/
> Decl.cpp?rev=315251&r1=315250&r2=315251&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/AST/Decl.cpp (original)
> +++ cfe/trunk/lib/AST/Decl.cpp Mon Oct  9 16:42:09 2017
> @@ -515,6 +515,7 @@ static bool isSingleLineLanguageLinkage(
>  }
>
>  static bool isExportedFromModuleIntefaceUnit(const NamedDecl *D) {
> +  // FIXME: Handle isModulePrivate.
>    switch (D->getModuleOwnershipKind()) {
>    case Decl::ModuleOwnershipKind::Unowned:
>    case Decl::ModuleOwnershipKind::ModulePrivate:
> @@ -546,7 +547,8 @@ static LinkageInfo getExternalLinkageFor
>    //     declaration has module linkage.
>    if (auto *M = D->getOwningModule())
>      if (M->Kind == Module::ModuleInterfaceUnit)
> -      if (!isExportedFromModuleIntefaceUnit(D))
> +      if (!isExportedFromModuleIntefaceUnit(
> +              cast<NamedDecl>(D->getCanonicalDecl())))
>          return LinkageInfo(ModuleLinkage, DefaultVisibility, false);
>
>    return LinkageInfo::external();
> @@ -1393,7 +1395,7 @@ LinkageInfo LinkageComputer::getDeclLink
>                                              :
> NamedDecl::VisibilityForValue));
>  }
>
> -Module *NamedDecl::getOwningModuleForLinkage() const {
> +Module *Decl::getOwningModuleForLinkage() const {
>    Module *M = getOwningModule();
>    if (!M)
>      return nullptr;
> @@ -1411,7 +1413,15 @@ Module *NamedDecl::getOwningModuleForLin
>      // for linkage purposes. But internal linkage declarations in the
> global
>      // module fragment of a particular module are owned by that module for
>      // linkage purposes.
> -    return hasExternalFormalLinkage() ? nullptr : M->Parent;
> +    bool InternalLinkage;
> +    if (auto *ND = dyn_cast<NamedDecl>(this))
> +      InternalLinkage = !ND->hasExternalFormalLinkage();
> +    else {
> +      auto *NSD = dyn_cast<NamespaceDecl>(this);
> +      InternalLinkage = (NSD && NSD->isAnonymousNamespace()) ||
> +                        isInAnonymousNamespace();
> +    }
> +    return InternalLinkage ? M->Parent : nullptr;
>    }
>
>    llvm_unreachable("unknown module kind");
>
> Modified: cfe/trunk/lib/AST/DeclBase.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/
> DeclBase.cpp?rev=315251&r1=315250&r2=315251&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/AST/DeclBase.cpp (original)
> +++ cfe/trunk/lib/AST/DeclBase.cpp Mon Oct  9 16:42:09 2017
> @@ -315,12 +315,11 @@ bool Decl::isLexicallyWithinFunctionOrMe
>  }
>
>  bool Decl::isInAnonymousNamespace() const {
> -  const DeclContext *DC = getDeclContext();
> -  do {
> +  for (const DeclContext *DC = getDeclContext(); DC; DC =
> DC->getParent()) {
>      if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC))
>        if (ND->isAnonymousNamespace())
>          return true;
> -  } while ((DC = DC->getParent()));
> +  }
>
>    return false;
>  }
>
> Modified: cfe/trunk/lib/AST/DeclCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/
> DeclCXX.cpp?rev=315251&r1=315250&r2=315251&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/AST/DeclCXX.cpp (original)
> +++ cfe/trunk/lib/AST/DeclCXX.cpp Mon Oct  9 16:42:09 2017
> @@ -100,7 +100,7 @@ CXXRecordDecl::CXXRecordDecl(Kind K, Tag
>  CXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK,
>                                       DeclContext *DC, SourceLocation
> StartLoc,
>                                       SourceLocation IdLoc, IdentifierInfo
> *Id,
> -                                     CXXRecordDecl* PrevDecl,
> +                                     CXXRecordDecl *PrevDecl,
>                                       bool DelayTypeCreation) {
>    CXXRecordDecl *R = new (C, DC) CXXRecordDecl(CXXRecord, TK, C, DC,
> StartLoc,
>                                                 IdLoc, Id, PrevDecl);
>
> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
> SemaDecl.cpp?rev=315251&r1=315250&r2=315251&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Oct  9 16:42:09 2017
> @@ -1448,6 +1448,46 @@ void Sema::FilterLookupForScope(LookupRe
>    F.done();
>  }
>
> +/// We've determined that \p New is a redeclaration of \p Old. Check that
> they
> +/// have compatible owning modules.
> +bool Sema::CheckRedeclarationModuleOwnership(NamedDecl *New, NamedDecl
> *Old) {
> +  // FIXME: The Modules TS is not clear about how friend declarations are
> +  // to be treated. It's not meaningful to have different owning modules
> for
> +  // linkage in redeclarations of the same entity, so for now allow the
> +  // redeclaration and change the owning modules to match.
> +  if (New->getFriendObjectKind() &&
> +      Old->getOwningModuleForLinkage() != New->getOwningModuleForLinkage())
> {
> +    New->setLocalOwningModule(Old->getOwningModule());
> +    makeMergedDefinitionVisible(New);
> +    return false;
> +  }
> +
> +  Module *NewM = New->getOwningModule();
> +  Module *OldM = Old->getOwningModule();
> +  if (NewM == OldM)
> +    return false;
> +
> +  // FIXME: Check proclaimed-ownership-declarations here too.
> +  bool NewIsModuleInterface = NewM && NewM->Kind ==
> Module::ModuleInterfaceUnit;
> +  bool OldIsModuleInterface = OldM && OldM->Kind ==
> Module::ModuleInterfaceUnit;
> +  if (NewIsModuleInterface || OldIsModuleInterface) {
> +    // C++ Modules TS [basic.def.odr] 6.2/6.7 [sic]:
> +    //   if a declaration of D [...] appears in the purview of a module,
> all
> +    //   other such declarations shall appear in the purview of the same
> module
> +    Diag(New->getLocation(), diag::err_mismatched_owning_module)
> +      << New
> +      << NewIsModuleInterface
> +      << (NewIsModuleInterface ? NewM->getFullModuleName() : "")
> +      << OldIsModuleInterface
> +      << (OldIsModuleInterface ? OldM->getFullModuleName() : "");
> +    Diag(Old->getLocation(), diag::note_previous_declaration);
> +    New->setInvalidDecl();
> +    return true;
> +  }
> +
> +  return false;
> +}
> +
>  static bool isUsingDecl(NamedDecl *D) {
>    return isa<UsingShadowDecl>(D) ||
>           isa<UnresolvedUsingTypenameDecl>(D) ||
> @@ -2962,6 +3002,9 @@ bool Sema::MergeFunctionDecl(FunctionDec
>      New->dropAttr<InternalLinkageAttr>();
>    }
>
> +  if (CheckRedeclarationModuleOwnership(New, Old))
> +    return true;
> +
>    if (!getLangOpts().CPlusPlus) {
>      bool OldOvl = Old->hasAttr<OverloadableAttr>();
>      if (OldOvl != New->hasAttr<OverloadableAttr>() &&
> !Old->isImplicit()) {
> @@ -3831,6 +3874,9 @@ void Sema::MergeVarDecl(VarDecl *New, Lo
>      return New->setInvalidDecl();
>    }
>
> +  if (CheckRedeclarationModuleOwnership(New, Old))
> +    return;
> +
>    // Variables with external linkage are analyzed in
> FinalizeDeclaratorGroup.
>
>    // FIXME: The test for external storage here seems wrong? We still
> @@ -4382,7 +4428,7 @@ static bool CheckAnonMemberRedeclaration
>                                           SourceLocation NameLoc,
>                                           bool IsUnion) {
>    LookupResult R(SemaRef, Name, NameLoc, Sema::LookupMemberName,
> -                 Sema::ForRedeclaration);
> +                 Sema::ForVisibleRedeclaration);
>    if (!SemaRef.LookupName(R, S)) return false;
>
>    // Pick a representative declaration.
> @@ -5321,7 +5367,7 @@ NamedDecl *Sema::HandleDeclarator(Scope
>      D.setInvalidType();
>
>    LookupResult Previous(*this, NameInfo, LookupOrdinaryName,
> -                        ForRedeclaration);
> +                        forRedeclarationInCurContext());
>
>    // See if this is a redefinition of a variable in the same scope.
>    if (!D.getCXXScopeSpec().isSet()) {
> @@ -5347,8 +5393,10 @@ NamedDecl *Sema::HandleDeclarator(Scope
>                 D.getDeclSpec().getStorageClassSpec() !=
> DeclSpec::SCS_static)
>        CreateBuiltins = true;
>
> -    if (IsLinkageLookup)
> +    if (IsLinkageLookup) {
>        Previous.clear(LookupRedeclarationWithLinkage);
> +      Previous.setRedeclarationKind(ForExternalRedeclaration);
> +    }
>
>      LookupName(Previous, S, CreateBuiltins);
>    } else { // Something like "int foo::x;"
> @@ -7096,7 +7144,7 @@ void Sema::CheckShadow(Scope *S, VarDecl
>      return;
>
>    LookupResult R(*this, D->getDeclName(), D->getLocation(),
> -                 Sema::LookupOrdinaryName, Sema::ForRedeclaration);
> +                 Sema::LookupOrdinaryName, Sema::ForVisibleRedeclaration)
> ;
>    LookupName(R, S);
>    if (NamedDecl *ShadowedDecl = getShadowedDeclaration(D, R))
>      CheckShadow(D, ShadowedDecl, R);
> @@ -7672,7 +7720,7 @@ static NamedDecl *DiagnoseInvalidRedecla
>    LookupResult Prev(SemaRef, Name, NewFD->getLocation(),
>                      IsLocalFriend ? Sema::LookupLocalFriendName
>                                    : Sema::LookupOrdinaryName,
> -                    Sema::ForRedeclaration);
> +                    Sema::ForVisibleRedeclaration);
>
>    NewFD->setInvalidDecl();
>    if (IsLocalFriend)
> @@ -11708,7 +11756,7 @@ Decl *Sema::ActOnParamDeclarator(Scope *
>    // Check for redeclaration of parameters, e.g. int foo(int x, int x);
>    if (II) {
>      LookupResult R(*this, II, D.getIdentifierLoc(), LookupOrdinaryName,
> -                   ForRedeclaration);
> +                   ForVisibleRedeclaration);
>      LookupName(R, S);
>      if (R.isSingleResult()) {
>        NamedDecl *PrevDecl = R.getFoundDecl();
> @@ -13268,7 +13316,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned
>    bool isStdBadAlloc = false;
>    bool isStdAlignValT = false;
>
> -  RedeclarationKind Redecl = ForRedeclaration;
> +  RedeclarationKind Redecl = forRedeclarationInCurContext();
>    if (TUK == TUK_Friend || TUK == TUK_Reference)
>      Redecl = NotForRedeclaration;
>
> @@ -13546,10 +13594,10 @@ Decl *Sema::ActOnTag(Scope *S, unsigned
>      // type declared by an elaborated-type-specifier.  In C that is not
> correct
>      // and we should instead merge compatible types found by lookup.
>      if (getLangOpts().CPlusPlus) {
> -      Previous.setRedeclarationKind(ForRedeclaration);
> +      Previous.setRedeclarationKind(forRedeclarationInCurContext());
>        LookupQualifiedName(Previous, SearchDC);
>      } else {
> -      Previous.setRedeclarationKind(ForRedeclaration);
> +      Previous.setRedeclarationKind(forRedeclarationInCurContext());
>        LookupName(Previous, S);
>      }
>    }
> @@ -14047,6 +14095,9 @@ CreateNewDecl:
>    if (!Invalid && SearchDC->isRecord())
>      SetMemberAccessSpecifier(New, PrevDecl, AS);
>
> +  if (PrevDecl)
> +    CheckRedeclarationModuleOwnership(New, PrevDecl);
> +
>    if (TUK == TUK_Definition)
>      New->startDefinition();
>
> @@ -14400,7 +14451,8 @@ FieldDecl *Sema::HandleField(Scope *S, R
>
>    // Check to see if this name was declared as a member previously
>    NamedDecl *PrevDecl = nullptr;
> -  LookupResult Previous(*this, II, Loc, LookupMemberName,
> ForRedeclaration);
> +  LookupResult Previous(*this, II, Loc, LookupMemberName,
> +                        ForVisibleRedeclaration);
>    LookupName(Previous, S);
>    switch (Previous.getResultKind()) {
>      case LookupResult::Found:
> @@ -14788,7 +14840,7 @@ Decl *Sema::ActOnIvar(Scope *S,
>
>    if (II) {
>      NamedDecl *PrevDecl = LookupSingleName(S, II, Loc, LookupMemberName,
> -                                           ForRedeclaration);
> +                                           ForVisibleRedeclaration);
>      if (PrevDecl && isDeclInScope(PrevDecl, EnclosingContext, S)
>          && !isa<TagDecl>(PrevDecl)) {
>        Diag(Loc, diag::err_duplicate_member) << II;
> @@ -15509,7 +15561,7 @@ Sema::SkipBodyInfo Sema::shouldSkipAnonE
>    // determine if we should merge the definition with an existing one and
>    // skip the body.
>    NamedDecl *PrevDecl = LookupSingleName(S, II, IILoc, LookupOrdinaryName,
> -                                         ForRedeclaration);
> +                                         forRedeclarationInCurContext());
>    auto *PrevECD = dyn_cast_or_null<EnumConstantDecl>(PrevDecl);
>    if (!PrevECD)
>      return SkipBodyInfo();
> @@ -15540,7 +15592,7 @@ Decl *Sema::ActOnEnumConstant(Scope *S,
>    // Verify that there isn't already something declared with this name in
> this
>    // scope.
>    NamedDecl *PrevDecl = LookupSingleName(S, Id, IdLoc, LookupOrdinaryName,
> -                                         ForRedeclaration);
> +                                         ForVisibleRedeclaration);
>    if (PrevDecl && PrevDecl->isTemplateParameter()) {
>      // Maybe we will complain about the shadowed template parameter.
>      DiagnoseTemplateParameterShadow(IdLoc, PrevDecl);
> @@ -15567,8 +15619,7 @@ Decl *Sema::ActOnEnumConstant(Scope *S,
>      // enum constant will 'hide' the tag.
>      assert((getLangOpts().CPlusPlus || !isa<TagDecl>(PrevDecl)) &&
>             "Received TagDecl when not in C++!");
> -    if (!isa<TagDecl>(PrevDecl) && isDeclInScope(PrevDecl, CurContext, S)
> &&
> -        shouldLinkPossiblyHiddenDecl(PrevDecl, New)) {
> +    if (!isa<TagDecl>(PrevDecl) && isDeclInScope(PrevDecl, CurContext,
> S)) {
>        if (isa<EnumConstantDecl>(PrevDecl))
>          Diag(IdLoc, diag::err_redefinition_of_enumerator) << Id;
>        else
> @@ -16150,7 +16201,8 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDe
>        else if (const auto *FE = M->getASTFile())
>          Diag(M->DefinitionLoc, diag::note_prev_module_
> definition_from_ast_file)
>              << FE->getName();
> -      return nullptr;
> +      Mod = M;
> +      break;
>      }
>
>      // Create a Module for the module that we're defining.
> @@ -16169,6 +16221,7 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDe
>          PP.getIdentifierInfo(ModuleName), Path[0].second);
>      Mod = getModuleLoader().loadModule(ModuleLoc, Path,
> Module::AllVisible,
>                                         /*IsIncludeDirective=*/false);
> +    // FIXME: Produce an error in this case.
>      if (!Mod)
>        return nullptr;
>      break;
>
> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
> SemaDeclCXX.cpp?rev=315251&r1=315250&r2=315251&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Oct  9 16:42:09 2017
> @@ -790,7 +790,7 @@ Sema::ActOnDecompositionDeclarator(Scope
>      // Check for name conflicts.
>      DeclarationNameInfo NameInfo(B.Name, B.NameLoc);
>      LookupResult Previous(*this, NameInfo, LookupOrdinaryName,
> -                          ForRedeclaration);
> +                          ForVisibleRedeclaration);
>      LookupName(Previous, S,
>                 /*CreateBuiltins*/DC->getRedeclContext()->
> isTranslationUnit());
>
> @@ -822,7 +822,8 @@ Sema::ActOnDecompositionDeclarator(Scope
>    // is unnamed.
>    DeclarationNameInfo NameInfo((IdentifierInfo *)nullptr,
>                                 Decomp.getLSquareLoc());
> -  LookupResult Previous(*this, NameInfo, LookupOrdinaryName,
> ForRedeclaration);
> +  LookupResult Previous(*this, NameInfo, LookupOrdinaryName,
> +                        ForVisibleRedeclaration);
>
>    // Build the variable that holds the non-decomposed object.
>    bool AddToScope = true;
> @@ -8465,7 +8466,8 @@ Decl *Sema::ActOnStartNamespaceDef(Scope
>      // Since namespace names are unique in their scope, and we don't
>      // look through using directives, just look for any ordinary names
>      // as if by qualified name lookup.
> -    LookupResult R(*this, II, IdentLoc, LookupOrdinaryName,
> ForRedeclaration);
> +    LookupResult R(*this, II, IdentLoc, LookupOrdinaryName,
> +                   ForExternalRedeclaration);
>      LookupQualifiedName(R, CurContext->getRedeclContext());
>      NamedDecl *PrevDecl =
>          R.isSingleResult() ? R.getRepresentativeDecl() : nullptr;
> @@ -9402,7 +9404,7 @@ NamedDecl *Sema::BuildUsingDeclaration(S
>
>    // Do the redeclaration lookup in the current scope.
>    LookupResult Previous(*this, UsingName, LookupUsingDeclName,
> -                        ForRedeclaration);
> +                        ForVisibleRedeclaration);
>    Previous.setHideTags(false);
>    if (S) {
>      LookupName(Previous, S);
> @@ -9982,7 +9984,10 @@ Decl *Sema::ActOnAliasDeclaration(Scope
>                                               TInfo->getTypeLoc().
> getBeginLoc());
>    }
>
> -  LookupResult Previous(*this, NameInfo, LookupOrdinaryName,
> ForRedeclaration);
> +  LookupResult Previous(*this, NameInfo, LookupOrdinaryName,
> +                        TemplateParamLists.size()
> +                            ? forRedeclarationInCurContext()
> +                            : ForVisibleRedeclaration);
>    LookupName(Previous, S);
>
>    // Warn about shadowing the name of a template parameter.
> @@ -10085,8 +10090,10 @@ Decl *Sema::ActOnAliasDeclaration(Scope
>
>      if (Invalid)
>        NewDecl->setInvalidDecl();
> -    else if (OldDecl)
> +    else if (OldDecl) {
>        NewDecl->setPreviousDecl(OldDecl);
> +      CheckRedeclarationModuleOwnership(NewDecl, OldDecl);
> +    }
>
>      NewND = NewDecl;
>    } else {
> @@ -10127,7 +10134,7 @@ Decl *Sema::ActOnNamespaceAliasDef(Scope
>
>    // Check if we have a previous declaration with the same name.
>    LookupResult PrevR(*this, Alias, AliasLoc, LookupOrdinaryName,
> -                     ForRedeclaration);
> +                     ForVisibleRedeclaration);
>    LookupName(PrevR, S);
>
>    // Check we're not shadowing a template parameter.
> @@ -10340,7 +10347,8 @@ void Sema::CheckImplicitSpecialMemberDec
>    // implicit special members with this name.
>    DeclarationName Name = FD->getDeclName();
>    LookupResult R(*this, Name, SourceLocation(), LookupOrdinaryName,
> -                 ForRedeclaration);
> +                 FD->isExternallyDeclarable() ? ForExternalRedeclaration
> +                                              : ForVisibleRedeclaration);
>    for (auto *D : FD->getParent()->lookup(Name))
>      if (auto *Acceptable = R.getAcceptableDecl(D))
>        R.addDecl(Acceptable);
> @@ -13224,7 +13232,7 @@ Decl *Sema::ActOnExceptionDeclarator(Sco
>    IdentifierInfo *II = D.getIdentifier();
>    if (NamedDecl *PrevDecl = LookupSingleName(S, II, D.getIdentifierLoc(),
>                                               LookupOrdinaryName,
> -                                             ForRedeclaration)) {
> +                                             ForVisibleRedeclaration)) {
>      // The scope should be freshly made just for us. There is just no way
>      // it contains any previous declaration, except for function
> parameters in
>      // a function-try-block's catch statement.
> @@ -13673,7 +13681,7 @@ NamedDecl *Sema::ActOnFriendFunctionDecl
>    DeclContext *DC;
>    Scope *DCScope = S;
>    LookupResult Previous(*this, NameInfo, LookupOrdinaryName,
> -                        ForRedeclaration);
> +                        ForExternalRedeclaration);
>
>    // There are five cases here.
>    //   - There's no scope specifier and we're in a local class. Only look
> @@ -14947,7 +14955,8 @@ MSPropertyDecl *Sema::HandleMSProperty(S
>
>    // Check to see if this name was declared as a member previously
>    NamedDecl *PrevDecl = nullptr;
> -  LookupResult Previous(*this, II, Loc, LookupMemberName,
> ForRedeclaration);
> +  LookupResult Previous(*this, II, Loc, LookupMemberName,
> +                        ForVisibleRedeclaration);
>    LookupName(Previous, S);
>    switch (Previous.getResultKind()) {
>    case LookupResult::Found:
>
> Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
> SemaDeclObjC.cpp?rev=315251&r1=315250&r2=315251&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Mon Oct  9 16:42:09 2017
> @@ -943,8 +943,9 @@ ActOnStartClassInterface(Scope *S, Sourc
>    assert(ClassName && "Missing class identifier");
>
>    // Check for another declaration kind with the same name.
> -  NamedDecl *PrevDecl = LookupSingleName(TUScope, ClassName, ClassLoc,
> -                                         LookupOrdinaryName,
> ForRedeclaration);
> +  NamedDecl *PrevDecl =
> +      LookupSingleName(TUScope, ClassName, ClassLoc, LookupOrdinaryName,
> +                       forRedeclarationInCurContext());
>
>    if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
>      Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
> @@ -1095,16 +1096,18 @@ Decl *Sema::ActOnCompatibilityAlias(Sour
>                                      IdentifierInfo *ClassName,
>                                      SourceLocation ClassLocation) {
>    // Look for previous declaration of alias name
> -  NamedDecl *ADecl = LookupSingleName(TUScope, AliasName, AliasLocation,
> -                                      LookupOrdinaryName,
> ForRedeclaration);
> +  NamedDecl *ADecl =
> +      LookupSingleName(TUScope, AliasName, AliasLocation,
> LookupOrdinaryName,
> +                       forRedeclarationInCurContext());
>    if (ADecl) {
>      Diag(AliasLocation, diag::err_conflicting_aliasing_type) <<
> AliasName;
>      Diag(ADecl->getLocation(), diag::note_previous_declaration);
>      return nullptr;
>    }
>    // Check for class declaration
> -  NamedDecl *CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation,
> -                                       LookupOrdinaryName,
> ForRedeclaration);
> +  NamedDecl *CDeclU =
> +      LookupSingleName(TUScope, ClassName, ClassLocation,
> LookupOrdinaryName,
> +                       forRedeclarationInCurContext());
>    if (const TypedefNameDecl *TDecl =
>          dyn_cast_or_null<TypedefNameDecl>(CDeclU)) {
>      QualType T = TDecl->getUnderlyingType();
> @@ -1112,7 +1115,8 @@ Decl *Sema::ActOnCompatibilityAlias(Sour
>        if (NamedDecl *IDecl = T->getAs<ObjCObjectType>()->getInterface())
> {
>          ClassName = IDecl->getIdentifier();
>          CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation,
> -                                  LookupOrdinaryName, ForRedeclaration);
> +                                  LookupOrdinaryName,
> +                                  forRedeclarationInCurContext());
>        }
>      }
>    }
> @@ -1174,7 +1178,7 @@ Sema::ActOnStartProtocolInterface(Source
>    // FIXME: Deal with AttrList.
>    assert(ProtocolName && "Missing protocol identifier");
>    ObjCProtocolDecl *PrevDecl = LookupProtocol(ProtocolName, ProtocolLoc,
> -                                              ForRedeclaration);
> +
> forRedeclarationInCurContext());
>    ObjCProtocolDecl *PDecl = nullptr;
>    if (ObjCProtocolDecl *Def = PrevDecl? PrevDecl->getDefinition() :
> nullptr) {
>      // If we already have a definition, complain.
> @@ -1730,7 +1734,7 @@ Sema::ActOnForwardProtocolDeclaration(So
>    for (const IdentifierLocPair &IdentPair : IdentList) {
>      IdentifierInfo *Ident = IdentPair.first;
>      ObjCProtocolDecl *PrevDecl = LookupProtocol(Ident, IdentPair.second,
> -                                                ForRedeclaration);
> +
> forRedeclarationInCurContext());
>      ObjCProtocolDecl *PDecl
>        = ObjCProtocolDecl::Create(Context, CurContext, Ident,
>                                   IdentPair.second, AtProtocolLoc,
> @@ -1921,7 +1925,7 @@ Decl *Sema::ActOnStartClassImplementatio
>    // Check for another declaration kind with the same name.
>    NamedDecl *PrevDecl
>      = LookupSingleName(TUScope, ClassName, ClassLoc, LookupOrdinaryName,
> -                       ForRedeclaration);
> +                       forRedeclarationInCurContext());
>    if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
>      Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
>      Diag(PrevDecl->getLocation(), diag::note_previous_definition);
> @@ -2997,7 +3001,7 @@ Sema::ActOnForwardClassDeclaration(Sourc
>      // Check for another declaration kind with the same name.
>      NamedDecl *PrevDecl
>        = LookupSingleName(TUScope, IdentList[i], IdentLocs[i],
> -                         LookupOrdinaryName, ForRedeclaration);
> +                         LookupOrdinaryName,
> forRedeclarationInCurContext());
>      if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
>        // GCC apparently allows the following idiom:
>        //
> @@ -4443,7 +4447,7 @@ Decl *Sema::ActOnMethodDeclaration(
>      }
>
>      LookupResult R(*this, ArgInfo[i].Name, ArgInfo[i].NameLoc,
> -                   LookupOrdinaryName, ForRedeclaration);
> +                   LookupOrdinaryName, forRedeclarationInCurContext());
>      LookupName(R, S);
>      if (R.isSingleResult()) {
>        NamedDecl *PrevDecl = R.getFoundDecl();
>
> Modified: cfe/trunk/lib/Sema/SemaExprMember.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
> SemaExprMember.cpp?rev=315251&r1=315250&r2=315251&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaExprMember.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExprMember.cpp Mon Oct  9 16:42:09 2017
> @@ -693,8 +693,7 @@ static bool LookupMemberExprInRecord(Sem
>      Sema::RedeclarationKind Redecl;
>    };
>    QueryState Q = {R.getSema(), R.getLookupNameInfo(), R.getLookupKind(),
> -                  R.isForRedeclaration() ? Sema::ForRedeclaration
> -                                         : Sema::NotForRedeclaration};
> +                  R.redeclarationKind()};
>    TE = SemaRef.CorrectTypoDelayed(
>        R.getLookupNameInfo(), R.getLookupKind(), nullptr, &SS,
>        llvm::make_unique<RecordMemberExprValidatorCCC>(RTy),
>
> Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
> SemaLookup.cpp?rev=315251&r1=315250&r2=315251&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaLookup.cpp Mon Oct  9 16:42:09 2017
> @@ -1609,11 +1609,39 @@ bool Sema::isVisibleSlow(const NamedDecl
>  }
>
>  bool Sema::shouldLinkPossiblyHiddenDecl(LookupResult &R, const NamedDecl
> *New) {
> +  // FIXME: If there are both visible and hidden declarations, we need to
> take
> +  // into account whether redeclaration is possible. Example:
> +  //
> +  // Non-imported module:
> +  //   int f(T);        // #1
> +  // Some TU:
> +  //   static int f(U); // #2, not a redeclaration of #1
> +  //   int f(T);        // #3, finds both, should link with #1 if T != U,
> but
> +  //                    // with #2 if T == U; neither should be ambiguous.
>    for (auto *D : R) {
>      if (isVisible(D))
>        return true;
> +    assert(D->isExternallyDeclarable() &&
> +           "should not have hidden, non-externally-declarable result
> here");
>    }
> -  return New->isExternallyVisible();
> +
> +  // This function is called once "New" is essentially complete, but
> before a
> +  // previous declaration is attached. We can't query the linkage of
> "New" in
> +  // general, because attaching the previous declaration can change the
> +  // linkage of New to match the previous declaration.
> +  //
> +  // However, because we've just determined that there is no *visible*
> prior
> +  // declaration, we can compute the linkage here. There are two
> possibilities:
> +  //
> +  //  * This is not a redeclaration; it's safe to compute the linkage now.
> +  //
> +  //  * This is a redeclaration of a prior declaration that is externally
> +  //    redeclarable. In that case, the linkage of the declaration is not
> +  //    changed by attaching the prior declaration, because both are
> externally
> +  //    declarable (and thus ExternalLinkage or VisibleNoLinkage).
> +  //
> +  // FIXME: This is subtle and fragile.
> +  return New->isExternallyDeclarable();
>  }
>
>  /// \brief Retrieve the visible declaration corresponding to D, if any.
>
> Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
> SemaOpenMP.cpp?rev=315251&r1=315250&r2=315251&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Mon Oct  9 16:42:09 2017
> @@ -11539,7 +11539,7 @@ Sema::DeclGroupPtrTy Sema::ActOnOpenMPDe
>    Decls.reserve(ReductionTypes.size());
>
>    LookupResult Lookup(*this, Name, SourceLocation(),
> LookupOMPReductionName,
> -                      ForRedeclaration);
> +                      forRedeclarationInCurContext());
>    // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
>    // A reduction-identifier may not be re-declared in the current scope
> for the
>    // same type or for a type that is compatible according to the base
> language
>
> Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
> SemaTemplate.cpp?rev=315251&r1=315250&r2=315251&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon Oct  9 16:42:09 2017
> @@ -778,7 +778,7 @@ static void maybeDiagnoseTemplateParamet
>                                                   SourceLocation Loc,
>                                                   IdentifierInfo *Name) {
>    NamedDecl *PrevDecl = SemaRef.LookupSingleName(
> -      S, Name, Loc, Sema::LookupOrdinaryName, Sema::ForRedeclaration);
> +      S, Name, Loc, Sema::LookupOrdinaryName,
> Sema::ForVisibleRedeclaration);
>    if (PrevDecl && PrevDecl->isTemplateParameter())
>      SemaRef.DiagnoseTemplateParameterShadow(Loc, PrevDecl);
>  }
> @@ -1133,7 +1133,7 @@ Sema::CheckClassTemplate(Scope *S, unsig
>    LookupResult Previous(*this, Name, NameLoc,
>                          (SS.isEmpty() && TUK == TUK_Friend)
>                            ? LookupTagName : LookupOrdinaryName,
> -                        ForRedeclaration);
> +                        forRedeclarationInCurContext());
>    if (SS.isNotEmpty() && !SS.isInvalid()) {
>      SemanticContext = computeDeclContext(SS, true);
>      if (!SemanticContext) {
> @@ -1192,8 +1192,8 @@ Sema::CheckClassTemplate(Scope *S, unsig
>
>    // If there is a previous declaration with the same name, check
>    // whether this is a valid redeclaration.
> -  ClassTemplateDecl *PrevClassTemplate
> -    = dyn_cast_or_null<ClassTemplateDecl>(PrevDecl);
> +  ClassTemplateDecl *PrevClassTemplate =
> +      dyn_cast_or_null<ClassTemplateDecl>(PrevDecl);
>
>    // We may have found the injected-class-name of a class template,
>    // class template partial specialization, or class template
> specialization.
> @@ -1484,6 +1484,9 @@ Sema::CheckClassTemplate(Scope *S, unsig
>      CurContext->addDecl(Friend);
>    }
>
> +  if (PrevClassTemplate)
> +    CheckRedeclarationModuleOwnership(NewTemplate, PrevClassTemplate);
> +
>    if (Invalid) {
>      NewTemplate->setInvalidDecl();
>      NewClass->setInvalidDecl();
> @@ -3677,7 +3680,7 @@ DeclResult Sema::ActOnVarTemplateSpecial
>      // Check that this isn't a redefinition of this specialization,
>      // merging with previous declarations.
>      LookupResult PrevSpec(*this, GetNameForDeclarator(D),
> LookupOrdinaryName,
> -                          ForRedeclaration);
> +                          forRedeclarationInCurContext());
>      PrevSpec.addDecl(PrevDecl);
>      D.setRedeclaration(CheckVariableDeclaration(Specialization,
> PrevSpec));
>    } else if (Specialization->isStaticDataMember() &&
>
> Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
> SemaTemplateInstantiateDecl.cpp?rev=315251&r1=315250&r2=315251&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon Oct  9
> 16:42:09 2017
> @@ -1195,7 +1195,8 @@ Decl *TemplateDeclInstantiator::VisitCla
>      // Look for a previous declaration of the template in the owning
>      // context.
>      LookupResult R(SemaRef, Pattern->getDeclName(),
> Pattern->getLocation(),
> -                   Sema::LookupOrdinaryName, Sema::ForRedeclaration);
> +                   Sema::LookupOrdinaryName,
> +                   SemaRef.forRedeclarationInCurContext());
>      SemaRef.LookupQualifiedName(R, DC);
>
>      if (R.isSingleResult()) {
> @@ -1735,7 +1736,8 @@ Decl *TemplateDeclInstantiator::VisitFun
>        SemaRef, Function->getDeclName(), SourceLocation(),
>        D->isLocalExternDecl() ? Sema::LookupRedeclarationWithLinkage
>                               : Sema::LookupOrdinaryName,
> -      Sema::ForRedeclaration);
> +      D->isLocalExternDecl() ? Sema::ForExternalRedeclaration
> +                             : SemaRef.forRedeclarationInCurContext());
>
>    if (DependentFunctionTemplateSpecializationInfo *Info
>          = D->getDependentSpecializationInfo()) {
> @@ -2053,7 +2055,7 @@ TemplateDeclInstantiator::VisitCXXMethod
>      Method->setInvalidDecl();
>
>    LookupResult Previous(SemaRef, NameInfo, Sema::LookupOrdinaryName,
> -                        Sema::ForRedeclaration);
> +                        Sema::ForExternalRedeclaration);
>
>    if (!FunctionTemplate || TemplateParams || isFriend) {
>      SemaRef.LookupQualifiedName(Previous, Record);
> @@ -2492,7 +2494,7 @@ Decl *TemplateDeclInstantiator::VisitUsi
>    bool CheckRedeclaration = Owner->isRecord();
>
>    LookupResult Prev(SemaRef, NameInfo, Sema::LookupUsingDeclName,
> -                    Sema::ForRedeclaration);
> +                    Sema::ForVisibleRedeclaration);
>
>    UsingDecl *NewUD = UsingDecl::Create(SemaRef.Context, Owner,
>                                         D->getUsingLoc(),
> @@ -2711,7 +2713,7 @@ Decl *TemplateDeclInstantiator::VisitCla
>      return nullptr;
>
>    LookupResult Previous(SemaRef, NewFD->getNameInfo(),
> Sema::LookupOrdinaryName,
> -                        Sema::ForRedeclaration);
> +                        Sema::ForExternalRedeclaration);
>
>    TemplateArgumentListInfo TemplateArgs;
>    TemplateArgumentListInfo *TemplateArgsPtr = nullptr;
> @@ -4074,7 +4076,8 @@ void Sema::BuildVariableInstantiation(
>        *this, NewVar->getDeclName(), NewVar->getLocation(),
>        NewVar->isLocalExternDecl() ? Sema::LookupRedeclarationWithLinkage
>                                    : Sema::LookupOrdinaryName,
> -      Sema::ForRedeclaration);
> +      NewVar->isLocalExternDecl() ? Sema::ForExternalRedeclaration
> +                                  : forRedeclarationInCurContext());
>
>    if (NewVar->isLocalExternDecl() && OldVar->getPreviousDecl() &&
>        (!OldVar->getPreviousDecl()->getDeclContext()->isDependentContext()
> ||
> @@ -4432,7 +4435,7 @@ void Sema::InstantiateVariableDefinition
>
>        // Merge the definition with the declaration.
>        LookupResult R(*this, Var->getDeclName(), Var->getLocation(),
> -                     LookupOrdinaryName, ForRedeclaration);
> +                     LookupOrdinaryName, forRedeclarationInCurContext());
>        R.addDecl(OldVar);
>        MergeVarDecl(Var, R);
>
>
> Added: cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p6/global-
> vs-module.cpp
> URL: 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
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p6/global-vs-module.cpp
> (added)
> +++ cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p6/global-vs-module.cpp
> Mon Oct  9 16:42:09 2017
> @@ -0,0 +1,55 @@
> +// RUN: %clang_cc1 -fmodules-ts -verify -std=c++17 %s
> +// RUN: %clang_cc1 -fmodules-ts -verify -std=c++17 %s -DEXPORT
> +// RUN: %clang_cc1 -fmodules-ts -verify -std=c++17 %s -DUSING
> +
> +#ifndef NO_GLOBAL
> +extern int var; // expected-note {{previous declaration is here}}
> +int func(); // expected-note {{previous declaration is here}}
> +struct str; // expected-note {{previous declaration is here}}
> +using type = int;
> +
> +template<typename> extern int var_tpl; // expected-note {{previous
> declaration is here}}
> +template<typename> int func_tpl(); // expected-note-re {{{{previous
> declaration is here|target of using declaration}}}}
> +template<typename> struct str_tpl; // expected-note {{previous
> declaration is here}}
> +template<typename> using type_tpl = int; // expected-note {{previous
> declaration is here}}
> +
> +typedef int type;
> +namespace ns { using ::func; }
> +namespace ns_alias = ns;
> +#endif
> +
> +export module M;
> +
> +#ifdef USING
> +using ::var;
> +using ::func;
> +using ::str;
> +using ::type;
> +using ::var_tpl;
> +using ::func_tpl; // expected-note {{using declaration}}
> +using ::str_tpl;
> +using ::type_tpl;
> +#endif
> +
> +#ifdef EXPORT
> +export {
> +#endif
> +
> +extern int var; // expected-error {{declaration of 'var' in module M
> follows declaration in the global module}}
> +int func(); // expected-error {{declaration of 'func' in module M follows
> declaration in the global module}}
> +struct str; // expected-error {{declaration of 'str' in module M follows
> declaration in the global module}}
> +using type = int;
> +
> +template<typename> extern int var_tpl; // expected-error {{declaration of
> 'var_tpl' in module M follows declaration in the global module}}
> +// FIXME: Is this the right diagnostic in the -DUSING case?
> +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}}}}
> +template<typename> struct str_tpl; // expected-error {{declaration of
> 'str_tpl' in module M follows declaration in the global module}}
> +template<typename> using type_tpl = int; // expected-error {{declaration
> of 'type_tpl' in module M follows declaration in the global module}}
> +
> +typedef int type;
> +namespace ns { using ::func; }
> +namespace ns_alias = ns;
> +
> +#ifdef EXPORT
> +}
> +#endif
>
> Added: cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p6/module-
> vs-global.cpp
> URL: 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
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p6/module-vs-global.cpp
> (added)
> +++ cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p6/module-vs-global.cpp
> Mon Oct  9 16:42:09 2017
> @@ -0,0 +1,19 @@
> +// RUN: rm -rf %t
> +// RUN: %clang_cc1 -fmodules-ts -emit-module-interface -std=c++17
> %S/global-vs-module.cpp -o %t -DNO_GLOBAL -DEXPORT
> +// RUN: %clang_cc1 -fmodules-ts -verify -std=c++17 %s -fmodule-file=%t
> +
> +import M;
> +
> +extern int var; // expected-error {{declaration of 'var' in the global
> module follows declaration in module M}} expected-note at global-vs-module.cpp:38
> {{previous}}
> +int func(); // expected-error {{declaration of 'func' in the global
> module follows declaration in module M}} expected-note at global-vs-module.cpp:39
> {{previous}}
> +struct str; // expected-error {{declaration of 'str' in the global module
> follows declaration in module M}} expected-note at global-vs-module.cpp:40
> {{previous}}
> +using type = int;
> +
> +template<typename> extern int var_tpl; // expected-error {{declaration of
> 'var_tpl' in the global module follows declaration in module M}}
> expected-note at global-vs-module.cpp:43 {{previous}}
> +template<typename> int func_tpl(); // expected-error {{declaration of
> 'func_tpl' in the global module follows declaration in module M}}
> expected-note at global-vs-module.cpp:45 {{previous}}
> +template<typename> struct str_tpl; // expected-error {{declaration of
> 'str_tpl' in the global module follows declaration in module M}}
> expected-note at global-vs-module.cpp:46 {{previous}}
> +template<typename> using type_tpl = int; // expected-error {{declaration
> of 'type_tpl' in the global module follows declaration in module M}}
> expected-note at global-vs-module.cpp:47 {{previous}}
> +
> +typedef int type;
> +namespace ns { using ::func; }
> +namespace ns_alias = ns;
>
> Added: cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p6/module-
> vs-module.cpp
> URL: 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
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p6/module-vs-module.cpp
> (added)
> +++ cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p6/module-vs-module.cpp
> Mon Oct  9 16:42:09 2017
> @@ -0,0 +1,44 @@
> +// RUN: rm -rf %t
> +// RUN: mkdir %t
> +//
> +// Some of the following tests intentionally have no -verify in their RUN
> +// lines; we are testing that those cases do not produce errors.
> +//
> +// RUN: %clang_cc1 -fmodules-ts -std=c++17 %S/global-vs-module.cpp
> -emit-module-interface -o %t/M.pcm -DNO_GLOBAL -DEXPORT
> +// RUN: %clang_cc1 -fmodules-ts -std=c++17 %s -fmodule-file=%t/M.pcm
> -DMODULE_INTERFACE -verify
> +// RUN: %clang_cc1 -fmodules-ts -std=c++17 %s -fmodule-file=%t/M.pcm
> -DMODULE_INTERFACE -DNO_IMPORT
> +//
> +// 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
> +// RUN: %clang_cc1 -fmodules-ts -std=c++17 %s -fmodule-file=%t/N.pcm
> -verify
> +// FIXME: Once we start importing "import" declarations properly, this
> should
> +// be rejected (-verify should be added to the following line).
> +// RUN: %clang_cc1 -fmodules-ts -std=c++17 %s -fmodule-file=%t/N.pcm
> -DNO_IMPORT
> +//
> +// 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
> +// RUN: %clang_cc1 -fmodules-ts -std=c++17 %s -fmodule-file=%t/N-no-M.pcm
> -verify
> +// RUN: %clang_cc1 -fmodules-ts -std=c++17 %s -fmodule-file=%t/N-no-M.pcm
> -DNO_IMPORT
> +
> +#ifdef MODULE_INTERFACE
> +export
> +#endif
> +module N;
> +
> +#ifndef NO_IMPORT
> +import M;
> +#endif
> +
> +#ifndef NO_ERRORS
> +extern int var; // expected-error {{declaration of 'var' in module N
> follows declaration in module M}} expected-note at global-vs-module.cpp:38
> {{previous}}
> +int func(); // expected-error {{declaration of 'func' in module N follows
> declaration in module M}} expected-note at global-vs-module.cpp:39
> {{previous}}
> +struct str; // expected-error {{declaration of 'str' in module N follows
> declaration in module M}} expected-note at global-vs-module.cpp:40
> {{previous}}
> +using type = int;
> +
> +template<typename> extern int var_tpl; // expected-error {{declaration of
> 'var_tpl' in module N follows declaration in module M}}
> expected-note at global-vs-module.cpp:43 {{previous}}
> +template<typename> int func_tpl(); // expected-error {{declaration of
> 'func_tpl' in module N follows declaration in module M}}
> expected-note at global-vs-module.cpp:45 {{previous}}
> +template<typename> struct str_tpl; // expected-error {{declaration of
> 'str_tpl' in module N follows declaration in module M}}
> expected-note at global-vs-module.cpp:46 {{previous}}
> +template<typename> using type_tpl = int; // expected-error {{declaration
> of 'type_tpl' in module N follows declaration in module M}}
> expected-note at global-vs-module.cpp:47 {{previous}}
> +
> +typedef int type;
> +namespace ns { using ::func; }
> +namespace ns_alias = ns;
> +#endif
>
> Modified: cfe/trunk/test/SemaCXX/modules-ts.cppm
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/
> SemaCXX/modules-ts.cppm?rev=315251&r1=315250&r2=315251&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/SemaCXX/modules-ts.cppm (original)
> +++ cfe/trunk/test/SemaCXX/modules-ts.cppm Mon Oct  9 16:42:09 2017
> @@ -14,7 +14,7 @@ export module foo;
>  #endif
>
>  static int m;
> -#if TEST == 2 // FIXME: 'm' has internal linkage, so there should be no
> error here
> +#if TEST == 2
>  // expected-error at -2 {{redefinition of '}}
>  // expected-note at -3 {{unguarded header; consider using #ifdef guards or
> #pragma once}}
>  // FIXME: We should drop the "header from" in this diagnostic.
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>

_______________________________________________
cfe-commits mailing list
cfe-commits at lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20171010/2e35b281/attachment-0001.html>


More information about the cfe-commits mailing list