summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/Decl.cpp16
-rw-r--r--clang/lib/AST/DeclBase.cpp5
-rw-r--r--clang/lib/AST/DeclCXX.cpp2
-rw-r--r--clang/lib/Sema/SemaDecl.cpp85
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp31
-rw-r--r--clang/lib/Sema/SemaDeclObjC.cpp28
-rw-r--r--clang/lib/Sema/SemaExprMember.cpp3
-rw-r--r--clang/lib/Sema/SemaLookup.cpp30
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp2
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp13
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp17
11 files changed, 170 insertions, 62 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 6e5f638bd55..cdd89d20e6b 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -515,6 +515,7 @@ static bool isSingleLineLanguageLinkage(const Decl &D) {
}
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(const NamedDecl *D) {
// 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::getDeclLinkageAndVisibility(const NamedDecl *D) {
: NamedDecl::VisibilityForValue));
}
-Module *NamedDecl::getOwningModuleForLinkage() const {
+Module *Decl::getOwningModuleForLinkage() const {
Module *M = getOwningModule();
if (!M)
return nullptr;
@@ -1411,7 +1413,15 @@ Module *NamedDecl::getOwningModuleForLinkage() const {
// 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");
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index 42f0ba0bd79..1e15ee98bbe 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -315,12 +315,11 @@ bool Decl::isLexicallyWithinFunctionOrMethod() const {
}
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;
}
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index a9759b4c0a2..26e5c4ffbed 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -100,7 +100,7 @@ CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C,
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);
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 78ceeedc3ac..85582d302de 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -1448,6 +1448,46 @@ void Sema::FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S,
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(FunctionDecl *New, NamedDecl *&OldD,
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, LookupResult &Previous) {
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(Sema &SemaRef,
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 *S, Declarator &D,
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 *S, Declarator &D,
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 *D) {
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 *DiagnoseInvalidRedeclaration(
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 *S, Declarator &D) {
// 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 TagSpec, TagUseKind TUK,
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 TagSpec, TagUseKind TUK,
// 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, RecordDecl *Record,
// 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::shouldSkipAnonEnumBody(Scope *S, IdentifierInfo *II,
// 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, Decl *theEnumDecl, Decl *lastEnumConst,
// 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, Decl *theEnumDecl, Decl *lastEnumConst,
// 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::ActOnModuleDecl(SourceLocation StartLoc,
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::ActOnModuleDecl(SourceLocation StartLoc,
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;
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 5d9a39c6772..8a82f07bddd 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -790,7 +790,7 @@ Sema::ActOnDecompositionDeclarator(Scope *S, Declarator &D,
// 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 *S, Declarator &D,
// 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 *NamespcScope,
// 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(Scope *S, AccessSpecifier AS,
// 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 *S,
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 *S,
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 *S, SourceLocation NamespaceLoc,
// 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::CheckImplicitSpecialMemberDeclaration(Scope *S, FunctionDecl *FD) {
// 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(Scope *S, Declarator &D) {
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(Scope *S, Declarator &D,
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(Scope *S, RecordDecl *Record,
// 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:
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index 6b33f7c64ce..5ab9d80c00b 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -943,8 +943,9 @@ ActOnStartClassInterface(Scope *S, SourceLocation AtInterfaceLoc,
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(SourceLocation AtLoc,
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(SourceLocation AtLoc,
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(SourceLocation AtProtoInterfaceLoc,
// 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(SourceLocation AtProtocolLoc,
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::ActOnStartClassImplementation(
// 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(SourceLocation AtClassLoc,
// 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();
diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp
index fc776e31a47..c3561f6400a 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -693,8 +693,7 @@ static bool LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R,
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),
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index a89d3ace244..6fb0260075f 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -1609,11 +1609,39 @@ bool Sema::isVisibleSlow(const NamedDecl *D) {
}
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.
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 4ab78f11abe..a024888fbf0 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -11539,7 +11539,7 @@ Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
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
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 1ce57e56c38..46cda5e9ac7 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -778,7 +778,7 @@ static void maybeDiagnoseTemplateParameterShadow(Sema &SemaRef, Scope *S,
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, unsigned TagSpec, TagUseKind TUK,
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, unsigned TagSpec, TagUseKind TUK,
// 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, unsigned TagSpec, TagUseKind TUK,
CurContext->addDecl(Friend);
}
+ if (PrevClassTemplate)
+ CheckRedeclarationModuleOwnership(NewTemplate, PrevClassTemplate);
+
if (Invalid) {
NewTemplate->setInvalidDecl();
NewClass->setInvalidDecl();
@@ -3677,7 +3680,7 @@ DeclResult Sema::ActOnVarTemplateSpecialization(
// 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() &&
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index b37ca664f79..3800ea6659b 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1195,7 +1195,8 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
// 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::VisitFunctionDecl(FunctionDecl *D,
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::VisitCXXMethodDecl(CXXMethodDecl *D,
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::VisitUsingDecl(UsingDecl *D) {
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::VisitClassScopeFunctionSpecializationDecl(
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(SourceLocation PointOfInstantiation,
// Merge the definition with the declaration.
LookupResult R(*this, Var->getDeclName(), Var->getLocation(),
- LookupOrdinaryName, ForRedeclaration);
+ LookupOrdinaryName, forRedeclarationInCurContext());
R.addDecl(OldVar);
MergeVarDecl(Var, R);
OpenPOWER on IntegriCloud