]> granicus.if.org Git - clang/commitdiff
Add typeid for the builtin types. WIP.
authorMike Stump <mrs@apple.com>
Tue, 17 Nov 2009 02:16:21 +0000 (02:16 +0000)
committerMike Stump <mrs@apple.com>
Tue, 17 Nov 2009 02:16:21 +0000 (02:16 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89028 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGCXXExpr.cpp
lib/CodeGen/CGRtti.cpp
lib/CodeGen/CodeGenModule.h
test/CodeGenCXX/rtti.cpp

index 75740af0744fa18283a387c2135f57e016b83d12..71ddca7eec935053623d3afad095461a7c9d350b 100644 (file)
@@ -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,
index ce8f2c89f3a554c44f234f72e668f4ef6933ad2f..5ac2095c251496c994874890043ed6c5537cb23b 100644 (file)
@@ -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);
+}
index 85e4d3d0739d008ebc5654e47474b208b99dd7f6..c8562d6745ebc292cccee8cda93279a343c989ca 100644 (file)
@@ -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,
index 76f571ede2823261268a716e83aef64ef4e61e37..adb9d2e20f7a3fc8bba14dcab05298178c5baa12 100644 (file)
@@ -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]