aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2009-11-17 02:16:21 +0000
committerMike Stump <mrs@apple.com>2009-11-17 02:16:21 +0000
commitea2c0b5dec07c28222856e66177f0922c9f508b1 (patch)
tree393c9976d660328c2d79e4cb9595c02fca242353
parenta24dc2e38c7fb0f7f138b3d14b5f0f241fd0eccf (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.cpp15
-rw-r--r--lib/CodeGen/CGRtti.cpp33
-rw-r--r--lib/CodeGen/CodeGenModule.h3
-rw-r--r--test/CodeGenCXX/rtti.cpp4
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]