]> granicus.if.org Git - clang/commitdiff
ir-gen for type convesion of class objects. WIP.
authorFariborz Jahanian <fjahanian@apple.com>
Wed, 26 Aug 2009 23:31:30 +0000 (23:31 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Wed, 26 Aug 2009 23:31:30 +0000 (23:31 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80178 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGCXX.cpp
lib/CodeGen/CGExprAgg.cpp
lib/CodeGen/CGExprScalar.cpp
lib/CodeGen/CodeGenFunction.h
lib/Sema/SemaCXXCast.cpp

index 680d7357b9a434c2a112e4214ab756e349a4998c..c72eca278cb4b0c7174ebb6dcfb27f31b21a6cac 100644 (file)
@@ -256,6 +256,27 @@ CodeGenFunction::EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E,
                            E->arg_begin() + 1, E->arg_end());
 }
 
+RValue
+CodeGenFunction::EmitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *E) {
+  assert((E->getCastKind() == CastExpr::CK_UserDefinedConversion) &&
+         "EmitCXXFunctionalCastExpr - called with wrong cast");
+  
+  CXXMethodDecl *MD = E->getTypeConversionMethod();
+  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
+  llvm::Constant *Callee;
+  if (CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(MD))
+    Callee = CGM.GetAddrOfCXXConstructor(CD, Ctor_Complete); 
+  else {
+    const llvm::Type *Ty = 
+      CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 
+                                     FPT->isVariadic());
+    Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty);
+  }
+  llvm::Value *This = EmitLValue(E->getSubExpr()).getAddress();
+  
+  return EmitCXXMemberCall(MD, Callee, This, 0, 0);
+}
+
 llvm::Value *CodeGenFunction::LoadCXXThis() {
   assert(isa<CXXMethodDecl>(CurFuncDecl) && 
          "Must be in a C++ member function decl to load 'this'");
index 6f6daa79d0c7d896684a194e695e0a5772b33069..002c77430f8b806b4077e3c031290dded610e09b 100644 (file)
@@ -177,7 +177,12 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) {
                                LValue::MakeAddr(CastPtr, 0));
     return;
   }
-
+  if (E->getCastKind() == CastExpr::CK_UserDefinedConversion) {
+    CXXFunctionalCastExpr *CXXFExpr = cast<CXXFunctionalCastExpr>(E);
+    CGF.EmitCXXFunctionalCastExpr(CXXFExpr);
+    return;
+  }
+  
   // FIXME: Remove the CK_Unknown check here.
   assert((E->getCastKind() == CastExpr::CK_NoOp || 
           E->getCastKind() == CastExpr::CK_Unknown) && 
index e8b7304552bb33486b5a7641018373e430dc787d..299296a63396371d01a360996a74a20096359721 100644 (file)
@@ -227,6 +227,11 @@ public:
     return llvm::Constant::getNullValue(ConvertType(E->getType()));
   }
   Value *VisitCastExpr(const CastExpr *E) {
+    if (E->getCastKind() == CastExpr::CK_UserDefinedConversion) {
+      const CXXFunctionalCastExpr *CXXFExpr = cast<CXXFunctionalCastExpr>(E);
+      return CGF.EmitCXXFunctionalCastExpr(CXXFExpr).getScalarVal();
+    }
+      
     // Make sure to evaluate VLA bounds now so that we have them for later.
     if (E->getType()->isVariablyModifiedType())
       CGF.EmitVLASize(E->getType());
index e8f0cc5de5b79c3ab5ca69095d85e2502f923f5e..2815939517b8baa064d4a1b92618cdc3beb509e2 100644 (file)
@@ -838,6 +838,8 @@ public:
   RValue EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E,
                                        const CXXMethodDecl *MD);
   
+  RValue EmitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *E);
+  
   RValue EmitBuiltinExpr(const FunctionDecl *FD, 
                          unsigned BuiltinID, const CallExpr *E);
 
index 2dee71308b0a2e0507f76d5a139defd4a969a7e0..66767ad1bab56fd43ee6d048b1da8aa6fdc5660a 100644 (file)
@@ -789,6 +789,10 @@ TryStaticImplicitCast(Sema &Self, Expr *SrcExpr, QualType DestType,
   // check for ambiguity or access.
   ImplicitConversionSequence ICS = Self.TryImplicitConversion(
     SrcExpr, DestType);
+  if (ICS.ConversionKind  == ImplicitConversionSequence::UserDefinedConversion)
+    if (CXXConversionDecl *CV = 
+          dyn_cast<CXXConversionDecl>(ICS.UserDefined.ConversionFunction))
+      ConversionDecl = CV;
   return ICS.ConversionKind == ImplicitConversionSequence::BadConversion ?
     TC_NotApplicable : TC_Success;
 }