diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2011-02-25 00:05:02 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2011-02-25 00:05:02 +0000 |
commit | 10aad449dfbb5b43611d45b99c88dfc26db7fac9 (patch) | |
tree | 88477bb4787dc8b711c6c8f08fd15ab252afe88d /lib/AST/Decl.cpp | |
parent | b43e8ad893706a2499c4901b8f5cb289553d66b1 (diff) |
Fix the rest of PR9316 along with some other bugs spotted by inspection.
I tried to add test cases for these, but I can't because variables
aren't warned on the way functions are and the codegen layer appears to
use different logic for determining that 'a' and 'g' in the test case
should receive C mangling. I've included the test so that if we ever
switch the codegen layer to use these functions, we won't regress due to
latent bugs.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126453 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/Decl.cpp')
-rw-r--r-- | lib/AST/Decl.cpp | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index b482a03299..c0300c50cd 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -708,7 +708,7 @@ static LinkageInfo getLVForDecl(const NamedDecl *D, LVFlags Flags) { // external linkage. if (D->getLexicalDeclContext()->isFunctionOrMethod()) { if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) { - if (Function->isInAnonymousNamespace()) + if (Function->isInAnonymousNamespace() && !Function->isExternC()) return LinkageInfo::uniqueExternal(); LinkageInfo LV; @@ -729,7 +729,7 @@ static LinkageInfo getLVForDecl(const NamedDecl *D, LVFlags Flags) { if (const VarDecl *Var = dyn_cast<VarDecl>(D)) if (Var->getStorageClass() == SC_Extern || Var->getStorageClass() == SC_PrivateExtern) { - if (Var->isInAnonymousNamespace()) + if (Var->isInAnonymousNamespace() && !Var->isExternC()) return LinkageInfo::uniqueExternal(); LinkageInfo LV; @@ -1041,8 +1041,11 @@ bool VarDecl::isExternC() const { getStorageClass() != SC_Static) || (getDeclContext()->isFunctionOrMethod() && hasExternalStorage()); - for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit(); - DC = DC->getParent()) { + const DeclContext *DC = getDeclContext(); + if (DC->isFunctionOrMethod()) + return false; + + for (; !DC->isTranslationUnit(); DC = DC->getParent()) { if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC)) { if (Linkage->getLanguage() == LinkageSpecDecl::lang_c) return getStorageClass() != SC_Static; @@ -1050,8 +1053,6 @@ bool VarDecl::isExternC() const { break; } - if (DC->isFunctionOrMethod()) - return false; } return false; @@ -1367,8 +1368,11 @@ bool FunctionDecl::isExternC() const { if (!Context.getLangOptions().CPlusPlus) return getStorageClass() != SC_Static && !getAttr<OverloadableAttr>(); - for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit(); - DC = DC->getParent()) { + const DeclContext *DC = getDeclContext(); + if (DC->isRecord()) + return false; + + for (; !DC->isTranslationUnit(); DC = DC->getParent()) { if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC)) { if (Linkage->getLanguage() == LinkageSpecDecl::lang_c) return getStorageClass() != SC_Static && @@ -1376,9 +1380,6 @@ bool FunctionDecl::isExternC() const { break; } - - if (DC->isRecord()) - break; } return isMain(); |