Skip to content

Commit 6bbe311

Browse files
committedOct 10, 2017
[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. This reinstates r315251 and r315256, reverted in r315309 and r315308 respectively, tweaked to avoid triggering a linkage calculation when declaring implicit special members (this exposed our pre-existing issue with typedef names for linkage changing the linkage of types whose linkage has already been computed and cached in more cases). A testcase for that regression has been added in r315366. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@315379 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 2e86b2e commit 6bbe311

21 files changed

+372
-79
lines changed
 

‎include/clang/AST/Decl.h

+6-4
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,12 @@ class NamedDecl : public Decl {
339339
return clang::isExternallyVisible(getLinkageInternal());
340340
}
341341

342+
/// Determine whether this declaration can be redeclared in a
343+
/// different translation unit.
344+
bool isExternallyDeclarable() const {
345+
return isExternallyVisible() && !getOwningModuleForLinkage();
346+
}
347+
342348
/// \brief Determines the visibility of this entity.
343349
Visibility getVisibility() const {
344350
return getLinkageAndVisibility().getVisibility();
@@ -379,10 +385,6 @@ class NamedDecl : public Decl {
379385
return hasCachedLinkage();
380386
}
381387

382-
/// Get the module that owns this declaration for linkage purposes.
383-
/// There only ever is such a module under the C++ Modules TS.
384-
Module *getOwningModuleForLinkage() const;
385-
386388
/// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for
387389
/// the underlying named decl.
388390
NamedDecl *getUnderlyingDecl() {

‎include/clang/AST/DeclBase.h

+7
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,13 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
738738
return isFromASTFile() ? getImportedOwningModule() : getLocalOwningModule();
739739
}
740740

741+
/// Get the module that owns this declaration for linkage purposes.
742+
/// There only ever is such a module under the C++ Modules TS.
743+
///
744+
/// \param IgnoreLinkage Ignore the linkage of the entity; assume that
745+
/// all declarations in a global module fragment are unowned.
746+
Module *getOwningModuleForLinkage(bool IgnoreLinkage = false) const;
747+
741748
/// \brief Determine whether this declaration might be hidden from name
742749
/// lookup. Note that the declaration might be visible even if this returns
743750
/// \c false, if the owning module is visible within the query context.

‎include/clang/Basic/DiagnosticSemaKinds.td

+3
Original file line numberDiff line numberDiff line change
@@ -4801,6 +4801,9 @@ def err_thread_non_thread : Error<
48014801
def err_thread_thread_different_kind : Error<
48024802
"thread-local declaration of %0 with %select{static|dynamic}1 initialization "
48034803
"follows declaration with %select{dynamic|static}1 initialization">;
4804+
def err_mismatched_owning_module : Error<
4805+
"declaration of %0 in %select{the global module|module %2}1 follows "
4806+
"declaration in %select{the global module|module %4}3">;
48044807
def err_redefinition_different_type : Error<
48054808
"redefinition of %0 with a different type%diff{: $ vs $|}1,2">;
48064809
def err_redefinition_different_kind : Error<

‎include/clang/Sema/Lookup.h

+22-3
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ class LookupResult {
139139
LookupKind(LookupKind),
140140
IDNS(0),
141141
Redecl(Redecl != Sema::NotForRedeclaration),
142+
ExternalRedecl(Redecl == Sema::ForExternalRedeclaration),
142143
HideTags(true),
143144
Diagnose(Redecl == Sema::NotForRedeclaration),
144145
AllowHidden(false),
@@ -161,6 +162,7 @@ class LookupResult {
161162
LookupKind(LookupKind),
162163
IDNS(0),
163164
Redecl(Redecl != Sema::NotForRedeclaration),
165+
ExternalRedecl(Redecl == Sema::ForExternalRedeclaration),
164166
HideTags(true),
165167
Diagnose(Redecl == Sema::NotForRedeclaration),
166168
AllowHidden(false),
@@ -181,6 +183,7 @@ class LookupResult {
181183
LookupKind(Other.LookupKind),
182184
IDNS(Other.IDNS),
183185
Redecl(Other.Redecl),
186+
ExternalRedecl(Other.ExternalRedecl),
184187
HideTags(Other.HideTags),
185188
Diagnose(false),
186189
AllowHidden(Other.AllowHidden),
@@ -201,7 +204,9 @@ class LookupResult {
201204
SemaPtr(std::move(Other.SemaPtr)), NameInfo(std::move(Other.NameInfo)),
202205
NameContextRange(std::move(Other.NameContextRange)),
203206
LookupKind(std::move(Other.LookupKind)), IDNS(std::move(Other.IDNS)),
204-
Redecl(std::move(Other.Redecl)), HideTags(std::move(Other.HideTags)),
207+
Redecl(std::move(Other.Redecl)),
208+
ExternalRedecl(std::move(Other.ExternalRedecl)),
209+
HideTags(std::move(Other.HideTags)),
205210
Diagnose(std::move(Other.Diagnose)),
206211
AllowHidden(std::move(Other.AllowHidden)),
207212
Shadowed(std::move(Other.Shadowed)) {
@@ -221,6 +226,7 @@ class LookupResult {
221226
LookupKind = std::move(Other.LookupKind);
222227
IDNS = std::move(Other.IDNS);
223228
Redecl = std::move(Other.Redecl);
229+
ExternalRedecl = std::move(Other.ExternalRedecl);
224230
HideTags = std::move(Other.HideTags);
225231
Diagnose = std::move(Other.Diagnose);
226232
AllowHidden = std::move(Other.AllowHidden);
@@ -265,6 +271,17 @@ class LookupResult {
265271
return Redecl;
266272
}
267273

274+
/// True if this lookup is just looking for an existing declaration to link
275+
/// against a declaration with external linkage.
276+
bool isForExternalRedeclaration() const {
277+
return ExternalRedecl;
278+
}
279+
280+
Sema::RedeclarationKind redeclarationKind() const {
281+
return ExternalRedecl ? Sema::ForExternalRedeclaration :
282+
Redecl ? Sema::ForVisibleRedeclaration : Sema::NotForRedeclaration;
283+
}
284+
268285
/// \brief Specify whether hidden declarations are visible, e.g.,
269286
/// for recovery reasons.
270287
void setAllowHidden(bool AH) {
@@ -275,7 +292,7 @@ class LookupResult {
275292
/// declarations, such as those in modules that have not yet been imported.
276293
bool isHiddenDeclarationVisible(NamedDecl *ND) const {
277294
return AllowHidden ||
278-
(isForRedeclaration() && ND->hasExternalFormalLinkage());
295+
(isForExternalRedeclaration() && ND->isExternallyDeclarable());
279296
}
280297

281298
/// Sets whether tag declarations should be hidden by non-tag
@@ -556,7 +573,8 @@ class LookupResult {
556573

557574
/// \brief Change this lookup's redeclaration kind.
558575
void setRedeclarationKind(Sema::RedeclarationKind RK) {
559-
Redecl = RK;
576+
Redecl = (RK != Sema::NotForRedeclaration);
577+
ExternalRedecl = (RK == Sema::ForExternalRedeclaration);
560578
configure();
561579
}
562580

@@ -719,6 +737,7 @@ class LookupResult {
719737
unsigned IDNS; // set by configure()
720738

721739
bool Redecl;
740+
bool ExternalRedecl;
722741

723742
/// \brief True if tag declarations should be hidden if non-tags
724743
/// are present

‎include/clang/Sema/Sema.h

+32-9
Original file line numberDiff line numberDiff line change
@@ -285,15 +285,21 @@ class Sema {
285285

286286
bool isVisibleSlow(const NamedDecl *D);
287287

288+
/// Determine whether two declarations should be linked together, given that
289+
/// the old declaration might not be visible and the new declaration might
290+
/// not have external linkage.
288291
bool shouldLinkPossiblyHiddenDecl(const NamedDecl *Old,
289292
const NamedDecl *New) {
290-
// We are about to link these. It is now safe to compute the linkage of
291-
// the new decl. If the new decl has external linkage, we will
292-
// link it with the hidden decl (which also has external linkage) and
293-
// it will keep having external linkage. If it has internal linkage, we
294-
// will not link it. Since it has no previous decls, it will remain
295-
// with internal linkage.
296-
return isVisible(Old) || New->isExternallyVisible();
293+
if (isVisible(Old))
294+
return true;
295+
// See comment in below overload for why it's safe to compute the linkage
296+
// of the new declaration here.
297+
if (New->isExternallyDeclarable()) {
298+
assert(Old->isExternallyDeclarable() &&
299+
"should not have found a non-externally-declarable previous decl");
300+
return true;
301+
}
302+
return false;
297303
}
298304
bool shouldLinkPossiblyHiddenDecl(LookupResult &Old, const NamedDecl *New);
299305

@@ -3035,10 +3041,25 @@ class Sema {
30353041
/// purpose of redeclaring the name.
30363042
NotForRedeclaration = 0,
30373043
/// \brief The lookup results will be used for redeclaration of a name,
3038-
/// if an entity by that name already exists.
3039-
ForRedeclaration
3044+
/// if an entity by that name already exists and is visible.
3045+
ForVisibleRedeclaration,
3046+
/// \brief The lookup results will be used for redeclaration of a name
3047+
/// with external linkage; non-visible lookup results with external linkage
3048+
/// may also be found.
3049+
ForExternalRedeclaration
30403050
};
30413051

3052+
RedeclarationKind forRedeclarationInCurContext() {
3053+
// A declaration with an owning module for linkage can never link against
3054+
// anything that is not visible. We don't need to check linkage here; if
3055+
// the context has internal linkage, redeclaration lookup won't find things
3056+
// from other TUs, and we can't safely compute linkage yet in general.
3057+
if (cast<Decl>(CurContext)
3058+
->getOwningModuleForLinkage(/*IgnoreLinkage*/true))
3059+
return ForVisibleRedeclaration;
3060+
return ForExternalRedeclaration;
3061+
}
3062+
30423063
/// \brief The possible outcomes of name lookup for a literal operator.
30433064
enum LiteralOperatorLookupResult {
30443065
/// \brief The lookup resulted in an error.
@@ -3266,6 +3287,8 @@ class Sema {
32663287
void FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S,
32673288
bool ConsiderLinkage, bool AllowInlineNamespace);
32683289

3290+
bool CheckRedeclarationModuleOwnership(NamedDecl *New, NamedDecl *Old);
3291+
32693292
void DiagnoseAmbiguousLookup(LookupResult &Result);
32703293
//@}
32713294

‎lib/AST/Decl.cpp

+15-3
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,7 @@ static bool isSingleLineLanguageLinkage(const Decl &D) {
515515
}
516516

517517
static bool isExportedFromModuleIntefaceUnit(const NamedDecl *D) {
518+
// FIXME: Handle isModulePrivate.
518519
switch (D->getModuleOwnershipKind()) {
519520
case Decl::ModuleOwnershipKind::Unowned:
520521
case Decl::ModuleOwnershipKind::ModulePrivate:
@@ -546,7 +547,8 @@ static LinkageInfo getExternalLinkageFor(const NamedDecl *D) {
546547
// declaration has module linkage.
547548
if (auto *M = D->getOwningModule())
548549
if (M->Kind == Module::ModuleInterfaceUnit)
549-
if (!isExportedFromModuleIntefaceUnit(D))
550+
if (!isExportedFromModuleIntefaceUnit(
551+
cast<NamedDecl>(D->getCanonicalDecl())))
550552
return LinkageInfo(ModuleLinkage, DefaultVisibility, false);
551553

552554
return LinkageInfo::external();
@@ -1393,7 +1395,7 @@ LinkageInfo LinkageComputer::getDeclLinkageAndVisibility(const NamedDecl *D) {
13931395
: NamedDecl::VisibilityForValue));
13941396
}
13951397

1396-
Module *NamedDecl::getOwningModuleForLinkage() const {
1398+
Module *Decl::getOwningModuleForLinkage(bool IgnoreLinkage) const {
13971399
Module *M = getOwningModule();
13981400
if (!M)
13991401
return nullptr;
@@ -1411,7 +1413,17 @@ Module *NamedDecl::getOwningModuleForLinkage() const {
14111413
// for linkage purposes. But internal linkage declarations in the global
14121414
// module fragment of a particular module are owned by that module for
14131415
// linkage purposes.
1414-
return hasExternalFormalLinkage() ? nullptr : M->Parent;
1416+
if (IgnoreLinkage)
1417+
return nullptr;
1418+
bool InternalLinkage;
1419+
if (auto *ND = dyn_cast<NamedDecl>(this))
1420+
InternalLinkage = !ND->hasExternalFormalLinkage();
1421+
else {
1422+
auto *NSD = dyn_cast<NamespaceDecl>(this);
1423+
InternalLinkage = (NSD && NSD->isAnonymousNamespace()) ||
1424+
isInAnonymousNamespace();
1425+
}
1426+
return InternalLinkage ? M->Parent : nullptr;
14151427
}
14161428

14171429
llvm_unreachable("unknown module kind");

‎lib/AST/DeclBase.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -315,12 +315,11 @@ bool Decl::isLexicallyWithinFunctionOrMethod() const {
315315
}
316316

317317
bool Decl::isInAnonymousNamespace() const {
318-
const DeclContext *DC = getDeclContext();
319-
do {
318+
for (const DeclContext *DC = getDeclContext(); DC; DC = DC->getParent()) {
320319
if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC))
321320
if (ND->isAnonymousNamespace())
322321
return true;
323-
} while ((DC = DC->getParent()));
322+
}
324323

325324
return false;
326325
}

‎lib/AST/DeclCXX.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C,
100100
CXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK,
101101
DeclContext *DC, SourceLocation StartLoc,
102102
SourceLocation IdLoc, IdentifierInfo *Id,
103-
CXXRecordDecl* PrevDecl,
103+
CXXRecordDecl *PrevDecl,
104104
bool DelayTypeCreation) {
105105
CXXRecordDecl *R = new (C, DC) CXXRecordDecl(CXXRecord, TK, C, DC, StartLoc,
106106
IdLoc, Id, PrevDecl);

0 commit comments

Comments
 (0)
Please sign in to comment.