diff options
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 12 | ||||
-rw-r--r-- | test/CodeGenCXX/pragma-weak.cpp | 31 |
2 files changed, 41 insertions, 2 deletions
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index d7f423fd32..25202b1b3c 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -19,6 +19,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" +#include "clang/AST/Mangle.h" #include "clang/Basic/CharInfo.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" @@ -5096,11 +5097,18 @@ void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD, if (Inheritable) { LoadExternalWeakUndeclaredIdentifiers(); if (!WeakUndeclaredIdentifiers.empty()) { - if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { + NamedDecl *ND = NULL; + if (VarDecl *VD = dyn_cast<VarDecl>(D)) + if (VD->isExternC()) + ND = VD; + if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) + if (FD->isExternC()) + ND = FD; + if (ND) { if (IdentifierInfo *Id = ND->getIdentifier()) { llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I = WeakUndeclaredIdentifiers.find(Id); - if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) { + if (I != WeakUndeclaredIdentifiers.end()) { WeakInfo W = I->second; DeclApplyPragmaWeak(S, ND, W); WeakUndeclaredIdentifiers[Id] = W; diff --git a/test/CodeGenCXX/pragma-weak.cpp b/test/CodeGenCXX/pragma-weak.cpp new file mode 100644 index 0000000000..ed537ffcd2 --- /dev/null +++ b/test/CodeGenCXX/pragma-weak.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +#pragma weak zex +int zex; +// GCC produces a weak symbol for this because it matches mangled names. +// Different c++ ABIs may or may not mangle this, so we produce a strong +// symbol. +// CHECK: @zex = global i32 + +#pragma weak foo +struct S { void foo(); }; +void S::foo() {} +// CHECK: define void @_ZN1S3fooEv( + +#pragma weak zed +namespace bar { void zed() {} } +// CHECK: define void @_ZN3bar3zedEv( + +#pragma weak bah +void bah() {} +// CHECK: define void @_Z3bahv( + +#pragma weak baz +extern "C" void baz() {} +// CHECK: define weak void @baz( + +#pragma weak _Z3baxv +void bax() {} +// GCC produces a weak symbol for this one, but it doesn't look like a good +// idea to expose the mangling to the pragma unless we really have to. +// CHECK: define void @_Z3baxv( |