diff options
author | Mike Stump <mrs@apple.com> | 2009-11-17 02:16:21 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2009-11-17 02:16:21 +0000 |
commit | ea2c0b5dec07c28222856e66177f0922c9f508b1 (patch) | |
tree | 393c9976d660328c2d79e4cb9595c02fca242353 | |
parent | a24dc2e38c7fb0f7f138b3d14b5f0f241fd0eccf (diff) |
Add typeid for the builtin types. WIP.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89028 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGCXXExpr.cpp | 15 | ||||
-rw-r--r-- | lib/CodeGen/CGRtti.cpp | 33 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 3 | ||||
-rw-r--r-- | test/CodeGenCXX/rtti.cpp | 4 |
4 files changed, 44 insertions, 11 deletions
diff --git a/lib/CodeGen/CGCXXExpr.cpp b/lib/CodeGen/CGCXXExpr.cpp index 75740af074..71ddca7eec 100644 --- a/lib/CodeGen/CGCXXExpr.cpp +++ b/lib/CodeGen/CGCXXExpr.cpp @@ -347,7 +347,7 @@ 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(); + Ty = E->getTypeOperand(); CanQualType CanTy = CGM.getContext().getCanonicalType(Ty); Ty = CanTy.getUnqualifiedType().getNonReferenceType(); if (const RecordType *RT = Ty->getAs<RecordType>()) { @@ -356,9 +356,7 @@ llvm::Value * CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) { 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; + return Builder.CreateBitCast(CGM.GenerateRttiNonClass(Ty), LTy); } Expr *subE = E->getExprOperand(); if (const RecordType *RT = Ty->getAs<RecordType>()) { @@ -397,11 +395,12 @@ llvm::Value * CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) { V = Builder.CreateLoad(V); return V; } - return CGM.GenerateRtti(RD); + return Builder.CreateBitCast(CGM.GenerateRtti(RD), LTy); } - // FIXME: return rtti for the non-class static type. - ErrorUnsupported(E, "typeid expression"); - return 0; + Ty = subE->getType(); + CanQualType CanTy = CGM.getContext().getCanonicalType(Ty); + Ty = CanTy.getUnqualifiedType().getNonReferenceType(); + return Builder.CreateBitCast(CGM.GenerateRttiNonClass(Ty), LTy); } llvm::Value *CodeGenFunction::EmitDynamicCast(llvm::Value *V, diff --git a/lib/CodeGen/CGRtti.cpp b/lib/CodeGen/CGRtti.cpp index ce8f2c89f3..5ac2095c25 100644 --- a/lib/CodeGen/CGRtti.cpp +++ b/lib/CodeGen/CGRtti.cpp @@ -76,7 +76,7 @@ public: return llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), c); } - llvm::Constant *Buildclass_type_infoRef(const CXXRecordDecl *RD) { + llvm::Constant *BuildTypeRef(QualType Ty) { const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext); llvm::Constant *C; @@ -85,8 +85,7 @@ public: llvm::SmallString<256> OutName; llvm::raw_svector_ostream Out(OutName); - mangleCXXRtti(CGM.getMangleContext(), CGM.getContext().getTagDeclType(RD), - Out); + mangleCXXRtti(CGM.getMangleContext(), Ty, Out); C = CGM.getModule().getGlobalVariable(Out.str()); if (C) @@ -100,6 +99,10 @@ public: return llvm::ConstantExpr::getBitCast(C, Int8PtrTy); } + llvm::Constant *Buildclass_type_infoRef(const CXXRecordDecl *RD) { + return BuildTypeRef(CGM.getContext().getTagDeclType(RD)); + } + /// CalculateFlags - Calculate the flags for the __vmi_class_type_info /// datastructure. 1 for non-diamond repeated inheritance, 2 for a dimond /// shaped class. @@ -234,6 +237,24 @@ public: return Rtti; #endif } + + llvm::Constant *BuildType(QualType Ty) { + const clang::Type &Type + = *CGM.getContext().getCanonicalType(Ty).getTypePtr(); + switch (Type.getTypeClass()) { + default: { + // FIXME: Add all the missing types, such as pointer, array... + assert(0 && "typeid expression"); + const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext); + return llvm::Constant::getNullValue(Int8PtrTy); + } + + case Type::Builtin: { + // We expect all type_info objects for builtin types to be in the library. + return BuildTypeRef(Ty); + } + } + } }; llvm::Constant *CodeGenModule::GenerateRttiRef(const CXXRecordDecl *RD) { @@ -247,3 +268,9 @@ llvm::Constant *CodeGenModule::GenerateRtti(const CXXRecordDecl *RD) { return b.Buildclass_type_info(RD); } + +llvm::Constant *CodeGenModule::GenerateRttiNonClass(QualType Ty) { + RttiBuilder b(*this); + + return b.BuildType(Ty); +} diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 85e4d3d073..c8562d6745 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -229,6 +229,9 @@ public: /// GenerateRttiRef - Generate a reference to the rtti information for the /// given type. llvm::Constant *GenerateRttiRef(const CXXRecordDecl *RD); + /// GenerateRttiNonClass - Generate the rtti information for the given + /// non-class type. + llvm::Constant *GenerateRttiNonClass(QualType Ty); /// BuildThunk - Build a thunk for the given method llvm::Constant *BuildThunk(const CXXMethodDecl *MD, bool Extern, int64_t nv, diff --git a/test/CodeGenCXX/rtti.cpp b/test/CodeGenCXX/rtti.cpp index 76f571ede2..adb9d2e20f 100644 --- a/test/CodeGenCXX/rtti.cpp +++ b/test/CodeGenCXX/rtti.cpp @@ -104,6 +104,8 @@ void test2_2(test1_D *dp) { test2_1(); if (typeid(((*(dp)))) == typeid(test1_D)) test2_1(); + if (typeid(int) == typeid(float)) + test2_1(); } // CHECK-LL:define void @_Z7test2_2P7test1_D(%class.test1_B7* %dp) nounwind { @@ -127,3 +129,5 @@ void test2_2(test1_D *dp) { // CHECK-LL-NEXT: %7 = getelementptr inbounds %"class.std::type_info"** %vtable6, i64 -1 // CHECK-LL-NEXT: %8 = load %"class.std::type_info"** %7 // CHECK-LL-NEXT: %call7 = call zeroext i1 @_ZNKSt9type_infoeqERKS_(%"class.std::type_info"* %8, %"class.std::type_info"* bitcast (%1* @_ZTI7test1_D to %"class.std::type_info"*)) + +// CHECK-LL: %call10 = call zeroext i1 @_ZNKSt9type_infoeqERKS_(%"class.std::type_info"* bitcast (i8** @_ZTIi to %"class.std::type_info"*), %"class.std::type_info"* bitcast (i8** @_ZTIf to %"class.std::type_info"*)) ; <i1> [#uses=1] |