r315251 - [Modules TS] Module ownership semantics for redeclarations.
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 10 14:08:25 PDT 2017
Added regression test for the failure in r315366.
On 10 October 2017 at 09:47, Richard Smith <richard at metafoo.co.uk> wrote:
> OK, and you got the errors with r315256 applied too, I assume. Looking...
>
> Thanks for the revert! :)
>
> On 10 October 2017 at 09:12, Eric Liu via cfe-commits <
> cfe-commits at lists.llvm.org> wrote:
>
>> 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/DeclBa
>>>> se.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/DeclCX
>>>> X.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/SemaD
>>>> ecl.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_definit
>>>> ion_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/SemaD
>>>> eclCXX.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->getRedec
>>>> lContext()->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/SemaD
>>>> eclObjC.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/SemaE
>>>> xprMember.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/SemaL
>>>> ookup.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/SemaO
>>>> penMP.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/SemaT
>>>> emplate.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/SemaT
>>>> emplateInstantiateDecl.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.forRedeclarationInCurC
>>>> ontext());
>>>>
>>>> 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::LookupRedeclarationWithL
>>>> inkage
>>>> : 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/modul
>>>> es-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/modul
>>>> es-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/modul
>>>> es-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
>>>
>>>
>>>
>> _______________________________________________
>> 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/35e3d0fe/attachment-0001.html>
More information about the cfe-commits
mailing list