diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-10-10 22:33:17 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-10-10 22:33:17 +0000 |
commit | becb92dec85924969ac0c3b049e0a74def431453 (patch) | |
tree | 747fe6a7cb5c4e17f630e94e65bf22f650170a47 /clang/lib/Sema/SemaLookup.cpp | |
parent | 0dfdb44797fa2ce4273e38f13403b62a5ce0a9b0 (diff) | |
download | bcm5719-llvm-becb92dec85924969ac0c3b049e0a74def431453.tar.gz bcm5719-llvm-becb92dec85924969ac0c3b049e0a74def431453.zip |
[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.
llvm-svn: 315379
Diffstat (limited to 'clang/lib/Sema/SemaLookup.cpp')
-rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 30 |
1 files changed, 29 insertions, 1 deletions
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. |