]> granicus.if.org Git - clang/commitdiff
Patch for code gen. for c-style cast which ends in
authorFariborz Jahanian <fjahanian@apple.com>
Sat, 29 Aug 2009 19:15:16 +0000 (19:15 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Sat, 29 Aug 2009 19:15:16 +0000 (19:15 +0000)
using class's conversion functions [12.3.2-p2]

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80433 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGExprAgg.cpp
lib/CodeGen/CGExprScalar.cpp
lib/Sema/SemaExpr.cpp
lib/Sema/SemaExprCXX.cpp
test/CodeGenCXX/conversion-function.cpp

index 24442c3a73374f30238882d8fbc45a1da035127f..400d45ffe562757319f6bd077416cbc876c76eb5 100644 (file)
@@ -1173,8 +1173,13 @@ LValue CodeGenFunction::EmitConditionalOperator(const ConditionalOperator* E) {
 /// noop aggregate casts, and cast from scalar to union.
 LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
   if (E->getCastKind() == CastExpr::CK_UserDefinedConversion) {
-    const CXXFunctionalCastExpr *CXXFExpr = cast<CXXFunctionalCastExpr>(E);
-    return  LValue::MakeAddr(EmitCXXFunctionalCastExpr(CXXFExpr).getScalarVal(), 0);
+    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
@@ -1188,10 +1193,6 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
     if (ICE->isLvalueCast())
       return EmitLValue(E->getSubExpr());
 
-  // FIXME: Implement this properly!
-  if (E->getCastKind() == CastExpr::CK_UserDefinedConversion)
-    return EmitUnsupportedLValue(E, "user-defined conversion");
-
   // Otherwise, we must have a cast from scalar to union.
   assert(E->getCastKind() == CastExpr::CK_ToUnion &&
          "Expected scalar-to-union cast");
index 002c77430f8b806b4077e3c031290dded610e09b..4155738a22f01cee3fe15607cd91a5b3a0e1b528 100644 (file)
@@ -178,8 +178,12 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) {
     return;
   }
   if (E->getCastKind() == CastExpr::CK_UserDefinedConversion) {
-    CXXFunctionalCastExpr *CXXFExpr = cast<CXXFunctionalCastExpr>(E);
-    CGF.EmitCXXFunctionalCastExpr(CXXFExpr);
+    if (const CXXFunctionalCastExpr *CXXFExpr = 
+          dyn_cast<CXXFunctionalCastExpr>(E))
+      CGF.EmitCXXFunctionalCastExpr(CXXFExpr);
+    else 
+      if (isa<CStyleCastExpr>(E))
+        Visit(E->getSubExpr());
     return;
   }
   
index 299296a63396371d01a360996a74a20096359721..f3a841dbb2ff30a44368e195609eb7839f4ced60 100644 (file)
@@ -228,8 +228,11 @@ public:
   }
   Value *VisitCastExpr(const CastExpr *E) {
     if (E->getCastKind() == CastExpr::CK_UserDefinedConversion) {
-      const CXXFunctionalCastExpr *CXXFExpr = cast<CXXFunctionalCastExpr>(E);
-      return CGF.EmitCXXFunctionalCastExpr(CXXFExpr).getScalarVal();
+      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.
index 474ddf06355e932a7ac5bc864bbd77f974eb07c3..cfb9eb658deee2294555df58d5566e927d13ec22 100644 (file)
@@ -3060,6 +3060,19 @@ Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, TypeTy *Ty,
   if (CheckCastTypes(SourceRange(LParenLoc, RParenLoc), castType, castExpr, 
                      Kind, ConversionDecl))
     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).
+  }
   
   Op.release();
   return Owned(new (Context) CStyleCastExpr(castType.getNonReferenceType(),
index fe67ec6faced53f169bf07a0406a7afb575547b4..16e83e6514f9f4e1e31a7dbfc4bdee0dc6cbe526 100644 (file)
@@ -939,6 +939,7 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
         OwningExprResult InitResult = 
           BuildCXXConstructExpr(ToType.getNonReferenceType(), 
                                 CD, &From, 1);
+        // Take ownership of this expression.
         From = InitResult.takeAs<Expr>();
         CastKind = CastExpr::CK_ConstructorConversion ;
       }
index 5961157951ace5ee46d9bee4098850869d7617b5..f3c0e33bf12ce1e3574f1a1b1ac0ec6542adf2df 100644 (file)
@@ -49,6 +49,15 @@ int main() {
     i = int(X(Z(y)));
     f = float(X(Z(y)));
     printf("i = %d float = %f\n", i,f);
+    f = (float)x;
+    i = (int)x;
+    printf("i = %d float = %f\n", i,f);
+
+    int d = (X)((Z)y);
+    printf("d = %d\n", d);
+
+    int e = (int)((X)((Z)y));
+    printf("e = %d\n", e);
 }
 // CHECK-LP64: .globl  __ZN1ScviEv
 // CHECK-LP64-NEXT: __ZN1ScviEv: