// 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;
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;
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;
break;
}
- if (DC->isFunctionOrMethod())
- return false;
}
return false;
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 &&
break;
}
-
- if (DC->isRecord())
- break;
}
return isMain();
// 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 {
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(