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
This commit is contained in:
Chandler Carruth 2011-02-25 00:05:02 +00:00
Родитель b43e8ad893
Коммит 10aad449df
2 изменённых файлов: 36 добавлений и 12 удалений

Просмотреть файл

@ -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();

Просмотреть файл

@ -3,7 +3,7 @@
// compared against the earlier cached value. If we had a way of
// testing linkage directly in Sema, that would be better.
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -Werror -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s
// PR8926
namespace test0 {
@ -69,5 +69,28 @@ namespace {
extern "C" void test4(void) {}
}
// PR9316: Ensure that even non-namespace-scope function declarations in
// a C declaration context respect that over the anonymous namespace.
extern "C" {
namespace {
struct X {
int f() {
extern int g();
extern int a;
// Test both for mangling in the code generation and warnings from use
// of internal, undefined names via -Werror.
// CHECK: call i32 @g(
// CHECK: load i32* @a,
return g() + a;
}
};
}
// Force the above function to be emitted by codegen.
int test(X& x) {
return x.f();
}
}
// CHECK: define linkonce_odr i8* @_ZN5test21A1BILj0EE3fooEv(
// CHECK: define linkonce_odr i8* @_ZN5test11A3fooILj0EEEPvv(