[cfe-commits] r88843 - in /cfe/trunk: lib/CodeGen/CGCXXExpr.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CodeGenFunction.h lib/CodeGen/Mangle.cpp test/CodeGenCXX/rtti.cpp

Mike Stump mrs at apple.com
Sun Nov 15 00:09:41 PST 2009


Author: mrs
Date: Sun Nov 15 02:09:41 2009
New Revision: 88843

URL: http://llvm.org/viewvc/llvm-project?rev=88843&view=rev
Log:
Implement typeid for class types.

Modified:
    cfe/trunk/lib/CodeGen/CGCXXExpr.cpp
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/lib/CodeGen/Mangle.cpp
    cfe/trunk/test/CodeGenCXX/rtti.cpp

Modified: cfe/trunk/lib/CodeGen/CGCXXExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXExpr.cpp?rev=88843&r1=88842&r2=88843&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXXExpr.cpp Sun Nov 15 02:09:41 2009
@@ -334,3 +334,39 @@
   
   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;
+}

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=88843&r1=88842&r2=88843&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Sun Nov 15 02:09:41 2009
@@ -271,6 +271,8 @@
     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));
@@ -1465,6 +1467,12 @@
 }
 
 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());
   PushCXXTemporary(E->getTemporary(), LV.getAddress());

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=88843&r1=88842&r2=88843&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Sun Nov 15 02:09:41 2009
@@ -663,6 +663,8 @@
   llvm::Value *EmitCXXNewExpr(const CXXNewExpr *E);
   void EmitCXXDeleteExpr(const CXXDeleteExpr *E);
 
+  llvm::Value* EmitCXXTypeidExpr(const CXXTypeidExpr *E);
+
   //===--------------------------------------------------------------------===//
   //                            Declaration Emission
   //===--------------------------------------------------------------------===//
@@ -856,6 +858,7 @@
   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 @@
                                     bool IsInitializer = false);
 
   void EmitCXXThrowExpr(const CXXThrowExpr *E);
-  
+
   //===--------------------------------------------------------------------===//
   //                             Internal Helpers
   //===--------------------------------------------------------------------===//

Modified: cfe/trunk/lib/CodeGen/Mangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/Mangle.cpp?rev=88843&r1=88842&r2=88843&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/Mangle.cpp (original)
+++ cfe/trunk/lib/CodeGen/Mangle.cpp Sun Nov 15 02:09:41 2009
@@ -1286,6 +1286,8 @@
 
 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";

Modified: cfe/trunk/test/CodeGenCXX/rtti.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/rtti.cpp?rev=88843&r1=88842&r2=88843&view=diff

==============================================================================
--- cfe/trunk/test/CodeGenCXX/rtti.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/rtti.cpp Sun Nov 15 02:09:41 2009
@@ -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 @@
 // 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"*))





More information about the cfe-commits mailing list