diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-09-22 22:21:44 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-09-22 22:21:44 +0000 |
commit | dd94e045be9b18d4a967fb747522b6da743aa18d (patch) | |
tree | 7edf530a9764889e0d1af3e0c43b6514c3ea79c3 /lib/AST/Decl.cpp | |
parent | 945869ef7ba9f6a64f4ed7ec218c75b0a8ed7edb (diff) |
DR1113: anonymous namespaces formally give their contents internal linkage.
This doesn't affect our code generation in any material way -- we already give
such declarations internal linkage from a codegen perspective -- but it has
some subtle effects on code validity.
We suppress the 'L' (internal linkage) marker for mangled names in anonymous
namespaces, because it is redundant (the information is already carried by the
namespace); this deviates from GCC's behavior if a variable or function in an
anonymous namespace is redundantly declared 'static' (where GCC does include
the 'L'), but GCC's behavior is incoherent because such a declaration can be
validly declared with or without the 'static'.
We still deviate from the standard in one regard here: extern "C" declarations
in anonymous namespaces are still granted external linkage. Changing those does
not appear to have been an intentional consequence of the standard change in
DR1113.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@314037 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/Decl.cpp')
-rw-r--r-- | lib/AST/Decl.cpp | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 19fbf878e7..3f9eaf28ef 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -619,16 +619,16 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D, if (D->isInAnonymousNamespace()) { const auto *Var = dyn_cast<VarDecl>(D); const auto *Func = dyn_cast<FunctionDecl>(D); - // FIXME: In C++11 onwards, anonymous namespaces should give decls - // within them (including those inside extern "C" contexts) internal - // linkage, not unique external linkage: + // FIXME: The check for extern "C" here is not justified by the standard + // wording, but we retain it from the pre-DR1113 model to avoid breaking + // code. // // C++11 [basic.link]p4: // An unnamed namespace or a namespace declared directly or indirectly // within an unnamed namespace has internal linkage. if ((!Var || !isFirstInExternCContext(Var)) && (!Func || !isFirstInExternCContext(Func))) - return LinkageInfo::uniqueExternal(); + return getInternalLinkageFor(D); } // Set up the defaults. @@ -1130,7 +1130,7 @@ LinkageInfo LinkageComputer::getLVForLocalDecl(const NamedDecl *D, if (const auto *Function = dyn_cast<FunctionDecl>(D)) { if (Function->isInAnonymousNamespace() && !Function->isInExternCContext()) - return LinkageInfo::uniqueExternal(); + return getInternalLinkageFor(Function); // This is a "void f();" which got merged with a file static. if (Function->getCanonicalDecl()->getStorageClass() == SC_Static) @@ -1153,7 +1153,7 @@ LinkageInfo LinkageComputer::getLVForLocalDecl(const NamedDecl *D, if (const auto *Var = dyn_cast<VarDecl>(D)) { if (Var->hasExternalStorage()) { if (Var->isInAnonymousNamespace() && !Var->isInExternCContext()) - return LinkageInfo::uniqueExternal(); + return getInternalLinkageFor(Var); LinkageInfo LV; if (Var->getStorageClass() == SC_PrivateExtern) |