r313957 - Closure types have no name (and can't have a typedef name for linkage
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 21 21:33:20 PDT 2017
Author: rsmith
Date: Thu Sep 21 21:33:20 2017
New Revision: 313957
URL: http://llvm.org/viewvc/llvm-project?rev=313957&view=rev
Log:
Closure types have no name (and can't have a typedef name for linkage
purposes), so they never formally have linkage.
Modified:
cfe/trunk/lib/AST/Decl.cpp
cfe/trunk/test/CXX/basic/basic.link/p8.cpp
Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=313957&r1=313956&r2=313957&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Thu Sep 21 21:33:20 2017
@@ -1104,24 +1104,25 @@ LinkageInfo LinkageComputer::getLVForClo
else
Owner = cast<NamedDecl>(ContextDecl);
- // FIXME: If there is no owner, the closure should have no linkage.
if (!Owner)
- return LinkageInfo::external();
+ return LinkageInfo::none();
// If the owner has a deduced type, we need to skip querying the linkage and
// visibility of that type, because it might involve this closure type. The
// only effect of this is that we might give a lambda VisibleNoLinkage rather
// than NoLinkage when we don't strictly need to, which is benign.
auto *VD = dyn_cast<VarDecl>(Owner);
- LinkageInfo OwnerLinkage =
+ LinkageInfo OwnerLV =
VD && VD->getType()->getContainedDeducedType()
? computeLVForDecl(Owner, computation, /*IgnoreVarTypeLinkage*/true)
: getLVForDecl(Owner, computation);
- // FIXME: This is wrong. A lambda never formally has linkage; if this
- // calculation determines a lambda has external linkage, it should be
- // downgraded to VisibleNoLinkage.
- return OwnerLinkage;
+ // A lambda never formally has linkage. But if the owner is externally
+ // visible, then the lambda is too. We apply the same rules to blocks.
+ if (!isExternallyVisible(OwnerLV.getLinkage()))
+ return LinkageInfo::none();
+ return LinkageInfo(VisibleNoLinkage, OwnerLV.getVisibility(),
+ OwnerLV.isVisibilityExplicit());
}
LinkageInfo LinkageComputer::getLVForLocalDecl(const NamedDecl *D,
Modified: cfe/trunk/test/CXX/basic/basic.link/p8.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.link/p8.cpp?rev=313957&r1=313956&r2=313957&view=diff
==============================================================================
--- cfe/trunk/test/CXX/basic/basic.link/p8.cpp (original)
+++ cfe/trunk/test/CXX/basic/basic.link/p8.cpp Thu Sep 21 21:33:20 2017
@@ -14,7 +14,7 @@ typedef decltype(f()) NoLinkage3;
inline auto g() { return [] {}; }
typedef decltype(g()) VisibleNoLinkage1;
inline auto y = [] {};
-typedef decltype(x) VisibleNoLinkage2;
+typedef decltype(y) VisibleNoLinkage2;
inline auto h() { struct {} x; return x; }
typedef decltype(h()) VisibleNoLinkage3;
@@ -42,19 +42,12 @@ void use_no_linkage() {
no_linkage3(); // expected-note {{used here}}
}
-// FIXME: This should emit an extension warning. It does not because we
-// incorrectly give the lambda external linkage.
-extern VisibleNoLinkage1 visible_no_linkage1();
-
-// FIXME: We should accept this as an extension. We don't because we
-// incorrectly give the lambda no linkage instead of "VisibleNoLinkage".
-extern VisibleNoLinkage2 visible_no_linkage2(); // expected-error {{used but not defined}}
-
-// This case is correctly accepted as an extension.
+extern VisibleNoLinkage1 visible_no_linkage1(); // expected-warning {{ISO C++ requires a definition}}
+extern VisibleNoLinkage2 visible_no_linkage2(); // expected-warning {{ISO C++ requires a definition}}
extern VisibleNoLinkage3 visible_no_linkage3(); // expected-warning {{ISO C++ requires a definition}}
void use_visible_no_linkage() {
- visible_no_linkage1();
+ visible_no_linkage1(); // expected-note {{used here}}
visible_no_linkage2(); // expected-note {{used here}}
visible_no_linkage3(); // expected-note {{used here}}
}
More information about the cfe-commits
mailing list