parent
c473cbb3b2
commit
c9b231c8d1
|
@ -334,3 +334,39 @@ void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) {
|
|||
|
||||
EmitBlock(DeleteEnd);
|
||||
}
|
||||
|
||||
llvm::Value * CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) {
|
||||
QualType Ty = E->getType();
|
||||
const llvm::Type *LTy = ConvertType(Ty)->getPointerTo();
|
||||
if (E->isTypeOperand()) {
|
||||
QualType Ty = E->getTypeOperand();
|
||||
if (const RecordType *RT = Ty->getAs<RecordType>()) {
|
||||
const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
|
||||
if (RD->isPolymorphic())
|
||||
return Builder.CreateBitCast(CGM.GenerateRttiRef(RD), LTy);
|
||||
return Builder.CreateBitCast(CGM.GenerateRtti(RD), LTy);
|
||||
}
|
||||
// FIXME: return the rtti for the non-class static type.
|
||||
ErrorUnsupported(E, "typeid expression");
|
||||
return 0;
|
||||
}
|
||||
Expr *subE = E->getExprOperand();
|
||||
if (const RecordType *RT = Ty->getAs<RecordType>()) {
|
||||
const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
|
||||
if (RD->isPolymorphic()) {
|
||||
// FIXME: if subE is an lvalue do
|
||||
LValue Obj = EmitLValue(subE);
|
||||
llvm::Value *This = Obj.getAddress();
|
||||
// FIXME: need to do a 0 check here for *p on This
|
||||
llvm::Value *V = Builder.CreateBitCast(This, LTy->getPointerTo()->getPointerTo());
|
||||
V = Builder.CreateLoad(V, "vtable");
|
||||
V = Builder.CreateConstInBoundsGEP1_64(V, -1ULL);
|
||||
V = Builder.CreateLoad(V);
|
||||
return V;
|
||||
}
|
||||
return CGM.GenerateRtti(RD);
|
||||
}
|
||||
// FIXME: return rtti for the non-class static type.
|
||||
ErrorUnsupported(E, "typeid expression");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -271,6 +271,8 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
|
|||
return EmitNullInitializationLValue(cast<CXXZeroInitValueExpr>(E));
|
||||
case Expr::CXXDefaultArgExprClass:
|
||||
return EmitLValue(cast<CXXDefaultArgExpr>(E)->getExpr());
|
||||
case Expr::CXXTypeidExprClass:
|
||||
return EmitCXXTypeidLValue(cast<CXXTypeidExpr>(E));
|
||||
|
||||
case Expr::ObjCMessageExprClass:
|
||||
return EmitObjCMessageExprLValue(cast<ObjCMessageExpr>(E));
|
||||
|
@ -1464,6 +1466,12 @@ LValue CodeGenFunction::EmitCXXConstructLValue(const CXXConstructExpr *E) {
|
|||
return LValue::MakeAddr(Temp, MakeQualifiers(E->getType()));
|
||||
}
|
||||
|
||||
LValue
|
||||
CodeGenFunction::EmitCXXTypeidLValue(const CXXTypeidExpr *E) {
|
||||
llvm::Value *Temp = EmitCXXTypeidExpr(E);
|
||||
return LValue::MakeAddr(Temp, MakeQualifiers(E->getType()));
|
||||
}
|
||||
|
||||
LValue
|
||||
CodeGenFunction::EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E) {
|
||||
LValue LV = EmitLValue(E->getSubExpr());
|
||||
|
|
|
@ -663,6 +663,8 @@ public:
|
|||
llvm::Value *EmitCXXNewExpr(const CXXNewExpr *E);
|
||||
void EmitCXXDeleteExpr(const CXXDeleteExpr *E);
|
||||
|
||||
llvm::Value* EmitCXXTypeidExpr(const CXXTypeidExpr *E);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Declaration Emission
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
@ -856,6 +858,7 @@ public:
|
|||
LValue EmitCXXConstructLValue(const CXXConstructExpr *E);
|
||||
LValue EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E);
|
||||
LValue EmitCXXExprWithTemporariesLValue(const CXXExprWithTemporaries *E);
|
||||
LValue EmitCXXTypeidLValue(const CXXTypeidExpr *E);
|
||||
|
||||
LValue EmitObjCMessageExprLValue(const ObjCMessageExpr *E);
|
||||
LValue EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E);
|
||||
|
@ -1022,7 +1025,7 @@ public:
|
|||
bool IsInitializer = false);
|
||||
|
||||
void EmitCXXThrowExpr(const CXXThrowExpr *E);
|
||||
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Internal Helpers
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
|
|
@ -1286,6 +1286,8 @@ static bool isCharSpecialization(QualType T, const char *Name) {
|
|||
|
||||
bool CXXNameMangler::mangleStandardSubstitution(const NamedDecl *ND) {
|
||||
// <substitution> ::= St # ::std::
|
||||
// FIXME: type_info == comes out as __ZNK3std9type_infoeqERKS0_ instead of
|
||||
// __ZNKSt9type_infoeqERKS_
|
||||
if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
|
||||
if (isStdNamespace(NS)) {
|
||||
Out << "St";
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
// RUN: clang-cc -triple x86_64-apple-darwin -std=c++0x -O0 -S %s -o %t.s
|
||||
// RUN: FileCheck --input-file=%t.s %s
|
||||
|
||||
// RUN: clang-cc -triple x86_64-apple-darwin -std=c++0x -emit-llvm %s -o %t.ll
|
||||
// RUN: FileCheck -check-prefix LL --input-file=%t.ll %s
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
class test1_B1 {
|
||||
virtual void foo() { }
|
||||
};
|
||||
|
@ -87,3 +92,24 @@ class test1_D : public test1_B7 {
|
|||
// CHECK-NEXT: .quad (__ZTVN10__cxxabiv120__si_class_type_infoE) + 16
|
||||
// CHECK-NEXT: .quad __ZTS8test1_B2
|
||||
// CHECK-NEXT: .quad __ZTI8test1_B1
|
||||
|
||||
|
||||
class NP { };
|
||||
void test2_1();
|
||||
void test2_2(test1_D *dp) {
|
||||
test1_D &d = *dp;
|
||||
if (typeid(d) == typeid(test1_D))
|
||||
test2_1();
|
||||
if (typeid(NP) == typeid(test1_D))
|
||||
test2_1();
|
||||
}
|
||||
|
||||
// CHECK-LL:define void @_Z7test2_2P7test1_D(%class.test1_B7* %dp) nounwind {
|
||||
// CHECK-LL: %tmp1 = load %class.test1_B7** %d
|
||||
// CHECK-LL-NEXT: %0 = bitcast %class.test1_B7* %tmp1 to %"class.std::type_info"***
|
||||
// CHECK-LL-NEXT: %vtable = load %"class.std::type_info"*** %0
|
||||
// CHECK-LL-NEXT: %1 = getelementptr inbounds %"class.std::type_info"** %vtable, i64 -1
|
||||
// CHECK-LL-NEXT: %2 = load %"class.std::type_info"** %1
|
||||
// CHECK-LL-NEXT: %call = call zeroext i1 @_ZNK3std9type_infoeqERKS0_(%"class.std::type_info"* %2, %"class.std::type_info"* bitcast (%1* @_ZTI7test1_D to %"class.std::type_info"*))
|
||||
|
||||
// CHECK-LL: %call2 = call zeroext i1 @_ZNK3std9type_infoeqERKS0_(%"class.std::type_info"* bitcast (%0* @_ZTI2NP to %"class.std::type_info"*), %"class.std::type_info"* bitcast (%1* @_ZTI7test1_D to %"class.std::type_info"*))
|
||||
|
|
Loading…
Reference in New Issue