diff options
| author | Fariborz Jahanian <fjahanian@apple.com> | 2011-10-21 22:27:12 +0000 |
|---|---|---|
| committer | Fariborz Jahanian <fjahanian@apple.com> | 2011-10-21 22:27:12 +0000 |
| commit | 47f9a73f519939adff9193c0ed325e2b6185e4f6 (patch) | |
| tree | 6808a18628cdbe524e4ca22a90e8e16b90e86f84 | |
| parent | 197ca87e7e4076bcf7ff8b920a64c02370f26061 (diff) | |
| download | bcm5719-llvm-47f9a73f519939adff9193c0ed325e2b6185e4f6.tar.gz bcm5719-llvm-47f9a73f519939adff9193c0ed325e2b6185e4f6.zip | |
c++: support gcc's application of weak attribute on
class declaration which forces any such class and any
class that inherits from such a class to have their
typeinfo symbols be marked as weak.
// rdar://10246395
A test/CodeGenCXX/weak-extern-typeinfo.cpp
M lib/Sema/SemaDeclCXX.cpp
M lib/Sema/SemaDeclAttr.cpp
M lib/CodeGen/CGRTTI.cpp
llvm-svn: 142693
| -rw-r--r-- | clang/lib/CodeGen/CGRTTI.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 4 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 4 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/weak-extern-typeinfo.cpp | 47 |
4 files changed, 57 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGRTTI.cpp b/clang/lib/CodeGen/CGRTTI.cpp index 1b3cb08284f..d9790d0b9e7 100644 --- a/clang/lib/CodeGen/CGRTTI.cpp +++ b/clang/lib/CodeGen/CGRTTI.cpp @@ -336,6 +336,8 @@ getTypeInfoLinkage(CodeGenModule &CGM, QualType Ty) { if (const RecordType *Record = dyn_cast<RecordType>(Ty)) { const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl()); + if (RD->hasAttr<WeakAttr>()) + return llvm::GlobalValue::WeakODRLinkage; if (RD->isDynamicClass()) return CGM.getVTableLinkage(RD); } diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index b83b716fdf0..d801664ad63 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -1914,6 +1914,10 @@ static void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) { } if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) { + if (isa<CXXRecordDecl>(D)) { + D->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context)); + return; + } S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) << Attr.getName() << ExpectedVariableOrFunction; return; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index f445e9ff5b1..2896e9f585e 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1151,6 +1151,10 @@ bool Sema::AttachBaseSpecifiers(CXXRecordDecl *Class, CXXBaseSpecifier **Bases, // Okay, add this new base class. KnownBaseTypes[NewBaseType] = Bases[idx]; Bases[NumGoodBases++] = Bases[idx]; + if (const RecordType *Record = dyn_cast<RecordType>(NewBaseType)) + if (const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl())) + if (RD->hasAttr<WeakAttr>()) + Class->addAttr(::new (Context) WeakAttr(SourceRange(), Context)); } } diff --git a/clang/test/CodeGenCXX/weak-extern-typeinfo.cpp b/clang/test/CodeGenCXX/weak-extern-typeinfo.cpp new file mode 100644 index 00000000000..3c3406e5597 --- /dev/null +++ b/clang/test/CodeGenCXX/weak-extern-typeinfo.cpp @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +// rdar://10246395 + +#define WEAK __attribute__ ((weak)) + +class WEAK A { + virtual void foo(); +}; + +class B : public A { + virtual void foo(); +}; +void A::foo() { } +void B::foo() { } + +class T {}; +class T1 {}; + +class C : public T1, public B, public T { + virtual void foo(); +}; +void C::foo() { } + +class V1 : public virtual A { + virtual void foo(); +}; + +class V2 : public virtual V1 { + virtual void foo(); +}; +void V1::foo() { } +void V2::foo() { } + +// CHECK: @_ZTS1A = weak_odr constant +// CHECK: @_ZTI1A = weak_odr unnamed_addr constant +// CHECK: @_ZTS1B = weak_odr constant +// CHECK: @_ZTI1B = weak_odr unnamed_addr constant +// CHECK: @_ZTS1C = weak_odr constant +// CHECK: @_ZTS2T1 = linkonce_odr constant +// CHECK: @_ZTI2T1 = linkonce_odr unnamed_addr constant +// CHECK: @_ZTS1T = linkonce_odr constant +// CHECK: @_ZTI1T = linkonce_odr unnamed_addr constant +// CHECK: @_ZTI1C = weak_odr unnamed_addr constant +// CHECK: @_ZTS2V1 = weak_odr constant +// CHECK: @_ZTI2V1 = weak_odr unnamed_addr constant +// CHECK: @_ZTS2V2 = weak_odr constant +// CHECK: @_ZTI2V2 = weak_odr unnamed_addr constant |

