r315251 - [Modules TS] Module ownership semantics for redeclarations.
Eric Liu via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 10 06:27:25 PDT 2017
I think it should be benign with/without this commit.
On Tue, Oct 10, 2017 at 3:18 PM NAKAMURA Takumi <geek4civic at gmail.com>
wrote:
> FYI, I tweaked the tree in rL315283. Shall we restore it?
>
> On Tue, Oct 10, 2017 at 9:41 PM 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.
>>
>> 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/13065c45/attachment-0001.html>
More information about the cfe-commits
mailing list