r315251 - [Modules TS] Module ownership semantics for redeclarations.
Eric Liu via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 10 09:12:26 PDT 2017
No :( I tried reverting only r315256 but still got the errors.
On Tue, Oct 10, 2017 at 6:10 PM Richard Smith <richard at metafoo.co.uk> wrote:
> 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/d895fca4/attachment-0001.html>
More information about the cfe-commits
mailing list