[cfe-commits] r81383 - in /cfe/trunk: include/clang/AST/ExprCXX.h lib/CodeGen/CGCXX.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CGExprAgg.cpp lib/CodeGen/CGExprScalar.cpp lib/CodeGen/CodeGenFunction.cpp lib/CodeGen/CodeGenFunction.h lib/Sema/Sema.h lib/Sema/SemaCXXCast.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp

Anders Carlsson andersca at mac.com
Wed Sep 9 14:33:22 PDT 2009


Author: andersca
Date: Wed Sep  9 16:33:21 2009
New Revision: 81383

URL: http://llvm.org/viewvc/llvm-project?rev=81383&view=rev
Log:
If a cast expression needs either a conversion function or a constructor to be called, generate implicit child expressions that call them.

Modified:
    cfe/trunk/include/clang/AST/ExprCXX.h
    cfe/trunk/lib/CodeGen/CGCXX.cpp
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CGExprAgg.cpp
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaCXXCast.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp

Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=81383&r1=81382&r2=81383&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Wed Sep  9 16:33:21 2009
@@ -550,20 +550,16 @@
 /// that uses "functional" notion (C++ [expr.type.conv]). Example: @c
 /// x = int(0.5);
 class CXXFunctionalCastExpr : public ExplicitCastExpr {
-  CXXMethodDecl *TypeConversionMethod;
   SourceLocation TyBeginLoc;
   SourceLocation RParenLoc;
 public:
   CXXFunctionalCastExpr(QualType ty, QualType writtenTy,
                         SourceLocation tyBeginLoc, CastKind kind,
-                        Expr *castExpr, CXXMethodDecl *typeConversionMethod,
-                        SourceLocation rParenLoc) :
-    ExplicitCastExpr(CXXFunctionalCastExprClass, ty, kind, castExpr, writtenTy),
-    TypeConversionMethod(typeConversionMethod),
-    TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
+                        Expr *castExpr, SourceLocation rParenLoc) 
+    : ExplicitCastExpr(CXXFunctionalCastExprClass, ty, kind, castExpr, 
+                       writtenTy),
+      TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
 
-  CXXMethodDecl *getTypeConversionMethod() const
-  { return TypeConversionMethod; }
   SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
   SourceLocation getRParenLoc() const { return RParenLoc; }
 

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Wed Sep  9 16:33:21 2009
@@ -264,28 +264,6 @@
                            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();
-  assert(MD && "EmitCXXFunctionalCastExpr - null conversion method");
-  assert(isa<CXXConversionDecl>(MD) && "EmitCXXFunctionalCastExpr - not"
-         " method decl");
-  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
-
-  const llvm::Type *Ty =
-    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
-                                   FPT->isVariadic());
-  llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty);
-  llvm::Value *This = EmitLValue(E->getSubExpr()).getAddress();
-  RValue RV = EmitCXXMemberCall(MD, Callee, This, 0, 0);
-  if (RV.isAggregate())
-    RV = RValue::get(RV.getAggregateAddr());
-  return RV;
-}
-
 llvm::Value *CodeGenFunction::LoadCXXThis() {
   assert(isa<CXXMethodDecl>(CurFuncDecl) &&
          "Must be in a C++ member function decl to load 'this'");

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Wed Sep  9 16:33:21 2009
@@ -1158,19 +1158,11 @@
 /// all the reasons that casts are permitted with aggregate result, including
 /// noop aggregate casts, and cast from scalar to union.
 LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
-  if (E->getCastKind() == CastExpr::CK_UserDefinedConversion) {
-    if (const CXXFunctionalCastExpr *CXXFExpr =
-          dyn_cast<CXXFunctionalCastExpr>(E))
-      return  LValue::MakeAddr(
-                EmitCXXFunctionalCastExpr(CXXFExpr).getScalarVal(), 0);
-    assert(isa<CStyleCastExpr>(E) &&
-           "EmitCastLValue - Expected CStyleCastExpr");
-    return EmitLValue(E->getSubExpr());
-  }
-
   // If this is an aggregate-to-aggregate cast, just use the input's address as
   // the lvalue.
-  if (E->getCastKind() == CastExpr::CK_NoOp)
+  if (E->getCastKind() == CastExpr::CK_NoOp ||
+      E->getCastKind() == CastExpr::CK_ConstructorConversion ||
+      E->getCastKind() == CastExpr::CK_UserDefinedConversion)
     return EmitLValue(E->getSubExpr());
 
   // If this is an lvalue cast, treat it as a no-op.

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Wed Sep  9 16:33:21 2009
@@ -184,19 +184,12 @@
                                LValue::MakeAddr(CastPtr, 0));
     return;
   }
-  if (E->getCastKind() == CastExpr::CK_UserDefinedConversion) {
-    if (const CXXFunctionalCastExpr *CXXFExpr =
-          dyn_cast<CXXFunctionalCastExpr>(E))
-      CGF.EmitCXXFunctionalCastExpr(CXXFExpr);
-    else
-      if (isa<CStyleCastExpr>(E))
-        Visit(E->getSubExpr());
-    return;
-  }
 
   // FIXME: Remove the CK_Unknown check here.
   assert((E->getCastKind() == CastExpr::CK_NoOp ||
-          E->getCastKind() == CastExpr::CK_Unknown) &&
+          E->getCastKind() == CastExpr::CK_Unknown ||
+          E->getCastKind() == CastExpr::CK_UserDefinedConversion ||
+          E->getCastKind() == CastExpr::CK_ConstructorConversion) &&
          "Only no-op casts allowed!");
   assert(CGF.getContext().hasSameUnqualifiedType(E->getSubExpr()->getType(),
                                                  E->getType()) &&

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Wed Sep  9 16:33:21 2009
@@ -227,14 +227,6 @@
     return llvm::Constant::getNullValue(ConvertType(E->getType()));
   }
   Value *VisitCastExpr(const CastExpr *E) {
-    if (E->getCastKind() == CastExpr::CK_UserDefinedConversion) {
-      if (const CXXFunctionalCastExpr *CXXFExpr =
-            dyn_cast<CXXFunctionalCastExpr>(E))
-        return CGF.EmitCXXFunctionalCastExpr(CXXFExpr).getScalarVal();
-      assert(isa<CStyleCastExpr>(E) &&
-             "VisitCastExpr - missing CStyleCastExpr");
-    }
-
     // Make sure to evaluate VLA bounds now so that we have them for later.
     if (E->getType()->isVariablyModifiedType())
       CGF.EmitVLASize(E->getType());

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Wed Sep  9 16:33:21 2009
@@ -324,17 +324,6 @@
                                            llvm::BasicBlock *FalseBlock) {
   if (const ParenExpr *PE = dyn_cast<ParenExpr>(Cond))
     return EmitBranchOnBoolExpr(PE->getSubExpr(), TrueBlock, FalseBlock);
-  if (const CastExpr *E = dyn_cast<CastExpr>(Cond))
-    if (E->getCastKind() == CastExpr::CK_UserDefinedConversion) {
-      if (const CXXFunctionalCastExpr *CXXFExpr =
-            dyn_cast<CXXFunctionalCastExpr>(E)) {
-          EmitCXXFunctionalCastExpr(CXXFExpr);
-        return;
-      }
-      else if (isa<CStyleCastExpr>(E))
-        return EmitBranchOnBoolExpr(E->getSubExpr(), TrueBlock, FalseBlock);
-      assert(false && "EmitBranchOnBoolExpr - Expected CStyleCastExpr");
-    }
 
   if (const BinaryOperator *CondBOp = dyn_cast<BinaryOperator>(Cond)) {
     // Handle X && Y in a condition.

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Wed Sep  9 16:33:21 2009
@@ -841,8 +841,6 @@
   RValue EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E,
                                        const CXXMethodDecl *MD);
 
-  RValue EmitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *E);
-
   RValue EmitBuiltinExpr(const FunctionDecl *FD,
                          unsigned BuiltinID, const CallExpr *E);
 

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=81383&r1=81382&r2=81383&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Wed Sep  9 16:33:21 2009
@@ -1834,6 +1834,12 @@
                                                MultiExprArg Args,
                                                SourceLocation rParenLoc);
 
+  OwningExprResult BuildCXXCastArgument(SourceLocation CastLoc,
+                                        QualType Ty,
+                                        CastExpr::CastKind Kind,
+                                        CXXMethodDecl *Method,
+                                        ExprArg Arg);
+
   /// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating
   /// the default expr if needed.
   OwningExprResult BuildCXXDefaultArgExpr(SourceLocation CallLoc,

Modified: cfe/trunk/lib/Sema/SemaCXXCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXCast.cpp?rev=81383&r1=81382&r2=81383&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXCast.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXCast.cpp Wed Sep  9 16:33:21 2009
@@ -44,7 +44,8 @@
                                  const SourceRange &DestRange);
 static void CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
                             const SourceRange &OpRange,
-                            CastExpr::CastKind &Kind);
+                            CastExpr::CastKind &Kind,
+                            CXXMethodDecl *&ConversionDecl);
 static void CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
                              const SourceRange &OpRange,
                              const SourceRange &DestRange,
@@ -143,8 +144,22 @@
 
   case tok::kw_static_cast: {
     CastExpr::CastKind Kind = CastExpr::CK_Unknown;
-    if (!TypeDependent)
-      CheckStaticCast(*this, Ex, DestType, OpRange, Kind);
+    if (!TypeDependent) {
+      CXXMethodDecl *Method = 0;
+      
+      CheckStaticCast(*this, Ex, DestType, OpRange, Kind, Method);
+      
+      if (Method) {
+        OwningExprResult CastArg 
+          = BuildCXXCastArgument(OpLoc, DestType.getNonReferenceType(), 
+                                 Kind, Method, Owned(Ex));
+          if (CastArg.isInvalid())
+            return ExprError();
+          
+          Ex = CastArg.takeAs<Expr>();
+      }
+    }
+    
     return Owned(new (Context) CXXStaticCastExpr(DestType.getNonReferenceType(),
                                                  Kind, Ex, DestType, OpLoc));
   }
@@ -359,7 +374,8 @@
 /// implicit conversions explicit and getting rid of data loss warnings.
 void
 CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
-                const SourceRange &OpRange, CastExpr::CastKind &Kind) {
+                const SourceRange &OpRange, CastExpr::CastKind &Kind,
+                CXXMethodDecl *&ConversionDecl) {
   // This test is outside everything else because it's the only case where
   // a non-lvalue-reference target type does not lead to decay.
   // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".
@@ -371,7 +387,6 @@
     Self.DefaultFunctionArrayConversion(SrcExpr);
 
   unsigned msg = diag::err_bad_cxx_cast_generic;
-  CXXMethodDecl *ConversionDecl = 0;
   if (TryStaticCast(Self, SrcExpr, DestType, /*CStyle*/false, Kind,
                     OpRange, msg, ConversionDecl)
       != TC_Success && msg != 0)
@@ -421,9 +436,16 @@
   //   [...] if the declaration "T t(e);" is well-formed, [...].
   tcr = TryStaticImplicitCast(Self, SrcExpr, DestType, CStyle, OpRange, msg,
                               ConversionDecl);
-  if (tcr != TC_NotApplicable)
+  if (tcr != TC_NotApplicable) {
+    if (ConversionDecl) {
+      if (isa<CXXConstructorDecl>(ConversionDecl))
+        Kind = CastExpr::CK_ConstructorConversion;
+      else if (isa<CXXConversionDecl>(ConversionDecl))
+        Kind = CastExpr::CK_UserDefinedConversion;
+    }
     return tcr;
-
+  }
+  
   // C++ 5.2.9p6: May apply the reverse of any standard conversion, except
   // lvalue-to-rvalue, array-to-pointer, function-to-pointer, and boolean
   // conversions, subject to further restrictions.
@@ -787,10 +809,12 @@
                                /*ForceRValue=*/false,
                                /*InOverloadResolution=*/false);
 
-  if (ICS.ConversionKind  == ImplicitConversionSequence::UserDefinedConversion)
+  if (ICS.ConversionKind == ImplicitConversionSequence::UserDefinedConversion) {
     if (CXXMethodDecl *MD =
           dyn_cast<CXXMethodDecl>(ICS.UserDefined.ConversionFunction))
       ConversionDecl = MD;
+  }
+  
   return ICS.ConversionKind == ImplicitConversionSequence::BadConversion ?
     TC_NotApplicable : TC_Success;
 }

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=81383&r1=81382&r2=81383&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Sep  9 16:33:21 2009
@@ -3171,25 +3171,23 @@
   // If the Expr being casted is a ParenListExpr, handle it specially.
   if (isa<ParenListExpr>(castExpr))
     return ActOnCastOfParenListExpr(S, LParenLoc, RParenLoc, move(Op),castType);
-  CXXMethodDecl *ConversionDecl = 0;
+  CXXMethodDecl *Method = 0;
   if (CheckCastTypes(SourceRange(LParenLoc, RParenLoc), castType, castExpr,
-                     Kind, ConversionDecl))
+                     Kind, Method))
     return ExprError();
-  if (ConversionDecl) {
-    // encounterred a c-style cast requiring a conversion function.
-    if (CXXConversionDecl *CD = dyn_cast<CXXConversionDecl>(ConversionDecl)) {
-      castExpr =
-        new (Context) CXXFunctionalCastExpr(castType.getNonReferenceType(),
-                                            castType, LParenLoc,
-                                            CastExpr::CK_UserDefinedConversion,
-                                            castExpr, CD,
-                                            RParenLoc);
-      Kind = CastExpr::CK_UserDefinedConversion;
-    }
-    // FIXME. AST for when dealing with conversion functions (FunctionDecl).
+
+  if (Method) {
+    OwningExprResult CastArg = BuildCXXCastArgument(LParenLoc, castType, Kind, 
+                                                    Method, move(Op));
+    
+    if (CastArg.isInvalid())
+      return ExprError();
+    
+    castExpr = CastArg.takeAs<Expr>();
+  } else {
+    Op.release();
   }
 
-  Op.release();
   return Owned(new (Context) CStyleCastExpr(castType.getNonReferenceType(),
                                             Kind, castExpr, castType,
                                             LParenLoc, RParenLoc));

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=81383&r1=81382&r2=81383&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Sep  9 16:33:21 2009
@@ -224,19 +224,25 @@
   //
   if (NumExprs == 1) {
     CastExpr::CastKind Kind = CastExpr::CK_Unknown;
-    CXXMethodDecl *ConversionDecl = 0;
-    if (CheckCastTypes(TypeRange, Ty, Exprs[0], Kind, ConversionDecl,
-                       /*functional-style*/true))
+    CXXMethodDecl *Method = 0;
+    if (CheckCastTypes(TypeRange, Ty, Exprs[0], Kind, Method,
+                       /*FunctionalStyle=*/true))
       return ExprError();
-    // We done't build this AST for X(i) where we are constructing an object.
-    if (!ConversionDecl || !isa<CXXConstructorDecl>(ConversionDecl)) {
-      exprs.release();
-      return Owned(new (Context) CXXFunctionalCastExpr(Ty.getNonReferenceType(),
-                                          Ty, TyBeginLoc,
-                                          CastExpr::CK_UserDefinedConversion,
-                                          Exprs[0], ConversionDecl,
-                                          RParenLoc));
+
+    exprs.release();
+    if (Method) {
+      OwningExprResult CastArg 
+        = BuildCXXCastArgument(TypeRange.getBegin(), Ty.getNonReferenceType(), 
+                               Kind, Method, Owned(Exprs[0]));
+      if (CastArg.isInvalid())
+        return ExprError();
+
+      Exprs[0] = CastArg.takeAs<Expr>();
     }
+
+    return Owned(new (Context) CXXFunctionalCastExpr(Ty.getNonReferenceType(),
+                                                     Ty, TyBeginLoc, Kind,
+                                                     Exprs[0], RParenLoc));
   }
 
   if (const RecordType *RT = Ty->getAs<RecordType>()) {
@@ -919,30 +925,25 @@
     {
       FunctionDecl *FD = ICS.UserDefined.ConversionFunction;
       CastExpr::CastKind CastKind = CastExpr::CK_Unknown;
-      if (CXXConversionDecl *CV = dyn_cast<CXXConversionDecl>(FD)) {
-        // FIXME. Get actual Source Location.
-        From =
-          new (Context) CXXFunctionalCastExpr(ToType.getNonReferenceType(),
-                                            ToType, SourceLocation(),
-                                            CastExpr::CK_UserDefinedConversion,
-                                            From, CV,
-                                            SourceLocation());
+      if (isa<CXXConversionDecl>(FD))
         CastKind = CastExpr::CK_UserDefinedConversion;
-      }
-      else if (CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) {
-        // FIXME. Do we need to check for isLValueReferenceType?
-        DefaultFunctionArrayConversion(From);
-        OwningExprResult InitResult =
-          BuildCXXConstructExpr(/*FIXME:ConstructLoc*/SourceLocation(),
-                                ToType.getNonReferenceType(), CD,
-                                MultiExprArg(*this, (void**)&From, 1));
-        // Take ownership of this expression.
-        From = InitResult.takeAs<Expr>();
-        CastKind = CastExpr::CK_ConstructorConversion ;
-      }
-      ImpCastExprToType(From, ToType.getNonReferenceType(),
-                        CastKind,
-                        ToType->isLValueReferenceType());
+      else if (isa<CXXConstructorDecl>(FD))
+        CastKind = CastExpr::CK_ConstructorConversion;
+      else
+        assert(0 && "Unknown conversion function kind!");
+
+      OwningExprResult CastArg 
+        = BuildCXXCastArgument(From->getLocStart(),
+                               ToType.getNonReferenceType(),
+                               CastKind, cast<CXXMethodDecl>(FD), 
+                               Owned(From));
+
+      if (CastArg.isInvalid())
+        return true;
+      
+      From = new (Context) ImplicitCastExpr(ToType.getNonReferenceType(),
+                                            CastKind, CastArg.takeAs<Expr>(), 
+                                            ToType->isLValueReferenceType());
       return false;
     }
 
@@ -1889,6 +1890,42 @@
                                   ConvName, DeclPtrTy(), SS);
 }
 
+Sema::OwningExprResult Sema::BuildCXXCastArgument(SourceLocation CastLoc,
+                                                  QualType Ty,
+                                                  CastExpr::CastKind Kind,
+                                                  CXXMethodDecl *Method,
+                                                  ExprArg Arg) {
+  Expr *From = Arg.takeAs<Expr>();
+
+  switch (Kind) {
+  default: assert(0 && "Unhandled cast kind!");
+  case CastExpr::CK_ConstructorConversion: {
+    DefaultFunctionArrayConversion(From);
+
+    return BuildCXXConstructExpr(CastLoc, Ty, cast<CXXConstructorDecl>(Method), 
+                                 MultiExprArg(*this, (void **)&From, 1));
+  }
+
+  case CastExpr::CK_UserDefinedConversion: {
+    // Create an implicit member expr to refer to the conversion operator.
+    MemberExpr *ME = 
+      new (Context) MemberExpr(From, From->getType()->isPointerType(), Method, 
+                               SourceLocation(), Method->getType());
+    
+
+    // And an implicit call expr that calls it.
+    QualType ResultType = Method->getResultType().getNonReferenceType();
+    CXXMemberCallExpr *CE =
+      new (Context) CXXMemberCallExpr(Context, ME, 0, 0, 
+                                      ResultType,
+                                      SourceLocation());
+
+    return Owned(CE);
+  }
+      
+  }
+}    
+
 Sema::OwningExprResult Sema::ActOnFinishFullExpr(ExprArg Arg) {
   Expr *FullExpr = Arg.takeAs<Expr>();
   if (FullExpr)





More information about the cfe-commits mailing list