mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-10 19:34:29 +00:00
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
This commit is contained in:
parent
197ca87e7e
commit
47f9a73f51
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
47
clang/test/CodeGenCXX/weak-extern-typeinfo.cpp
Normal file
47
clang/test/CodeGenCXX/weak-extern-typeinfo.cpp
Normal file
@ -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
|
Loading…
x
Reference in New Issue
Block a user