]> granicus.if.org Git - clang/commitdiff
ir-gen related patch for type conversion
authorFariborz Jahanian <fjahanian@apple.com>
Fri, 28 Aug 2009 15:11:24 +0000 (15:11 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Fri, 28 Aug 2009 15:11:24 +0000 (15:11 +0000)
with class type conversion methods. WIP.

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

lib/CodeGen/CGCXX.cpp
lib/CodeGen/CGExpr.cpp
lib/Sema/SemaCXXCast.cpp
lib/Sema/SemaExprCXX.cpp
test/SemaTemplate/instantiate-cast.cpp

index 3c7115d6836c346470e6d47f6e20e11149b0cd6c..04dbe9760a2cf0e0eca438bb9ceb2c8f7e562035 100644 (file)
@@ -262,19 +262,20 @@ CodeGenFunction::EmitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *E) {
          "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();
-  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);
+  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() {
index 0d45ce91853b004df66bb5fc831c5b06011a7bec..24442c3a73374f30238882d8fbc45a1da035127f 100644 (file)
@@ -1172,6 +1172,11 @@ LValue CodeGenFunction::EmitConditionalOperator(const ConditionalOperator* E) {
 /// 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) {
+    const CXXFunctionalCastExpr *CXXFExpr = cast<CXXFunctionalCastExpr>(E);
+    return  LValue::MakeAddr(EmitCXXFunctionalCastExpr(CXXFExpr).getScalarVal(), 0);
+  }
+  
   // If this is an aggregate-to-aggregate cast, just use the input's address as
   // the lvalue.
   if (E->getCastKind() == CastExpr::CK_NoOp)
index b07635779bd465828eb4cfde7d8406f3865a8c7b..b528cc421fed11ab8409da8933f3c9f88a016b86 100644 (file)
@@ -776,17 +776,6 @@ TryStaticImplicitCast(Sema &Self, Expr *SrcExpr, QualType DestType,
     msg = 0;
     return TC_Failed;
   }
-  if (DestType->isRecordType()) {
-    // There are no further possibilities for the target type being a class,
-    // neither in static_cast nor in a C-style cast. So we can fail here.
-    if ((ConversionDecl = 
-          Self.PerformInitializationByConstructor(DestType, &SrcExpr, 1,
-              OpRange.getBegin(), OpRange, DeclarationName(), Sema::IK_Direct)))
-      return TC_Success;
-    // The function already emitted an error.
-    msg = 0;
-    return TC_Failed;
-  }
 
   // FIXME: To get a proper error from invalid conversions here, we need to
   // reimplement more of this.
@@ -799,9 +788,9 @@ TryStaticImplicitCast(Sema &Self, Expr *SrcExpr, QualType DestType,
                                /*ForceRValue=*/false);
   
   if (ICS.ConversionKind  == ImplicitConversionSequence::UserDefinedConversion)
-    if (CXXConversionDecl *CV = 
-          dyn_cast<CXXConversionDecl>(ICS.UserDefined.ConversionFunction))
-      ConversionDecl = CV;
+    if (CXXMethodDecl *MD = 
+          dyn_cast<CXXMethodDecl>(ICS.UserDefined.ConversionFunction))
+      ConversionDecl = MD;
   return ICS.ConversionKind == ImplicitConversionSequence::BadConversion ?
     TC_NotApplicable : TC_Success;
 }
index cdda6ab32ffe9e0ab450bbffab4326ddce0d16e8..061ac8d2c3333f416638969bee26ed0795fffd47 100644 (file)
@@ -228,12 +228,15 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
     if (CheckCastTypes(TypeRange, Ty, Exprs[0], Kind, ConversionDecl,
                        /*functional-style*/true))
       return ExprError();
-    exprs.release();
-    return Owned(new (Context) CXXFunctionalCastExpr(Ty.getNonReferenceType(),
+    // 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));
+    }
   }
 
   if (const RecordType *RT = Ty->getAs<RecordType>()) {
index fc492edaaf296dd05c59a96152ba8fb15730dcc4..6b3fc6e1253409e61ff5c4fe34d77155df3eeaa1 100644 (file)
@@ -1,6 +1,6 @@
 // RUN: clang-cc -fsyntax-only -verify %s
 
-struct A { int x; }; // expected-note 2 {{candidate}}
+struct A { int x; }; 
 
 class Base { 
 public:
@@ -36,7 +36,7 @@ template struct CStyleCast0<A, int>; // expected-note{{instantiation}}
 template<typename T, typename U>
 struct StaticCast0 {
   void f(T t) {
-    (void)static_cast<U>(t); // expected-error{{initialization of 'struct A'}}
+    (void)static_cast<U>(t); // expected-error{{static_cast from 'int' to 'struct A' is not allowed}}
   }
 };