summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2011-02-25 00:05:02 +0000
committerChandler Carruth <chandlerc@gmail.com>2011-02-25 00:05:02 +0000
commit4322a2864e866e3cbc3f65bfbef5315acf66c56f (patch)
tree50c467d522acb9eab53c9dd3ce2c36979b55ec10 /clang/lib
parentdfdca1a14db80a508bfec8062d670a9ed9853cb1 (diff)
downloadbcm5719-llvm-4322a2864e866e3cbc3f65bfbef5315acf66c56f.tar.gz
bcm5719-llvm-4322a2864e866e3cbc3f65bfbef5315acf66c56f.zip
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. llvm-svn: 126453
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/Decl.cpp23
1 files changed, 12 insertions, 11 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index b482a032994..c0300c50cd9 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/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();
OpenPOWER on IntegriCloud