diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-08-28 15:11:24 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-08-28 15:11:24 +0000 |
commit | 4fc7ab364110d6ad1c10dd38dbeb0597fed7e2f5 (patch) | |
tree | 7123cf844cf6971d011973cfa5775bf6f6bb5229 | |
parent | 7e8f8189d0876e03ebc5018f6a22e41f5aaa20d9 (diff) |
ir-gen related patch for type conversion
with class type conversion methods. WIP.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80365 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGCXX.cpp | 23 | ||||
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaCXXCast.cpp | 17 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 7 | ||||
-rw-r--r-- | test/SemaTemplate/instantiate-cast.cpp | 4 |
5 files changed, 27 insertions, 29 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 3c7115d683..04dbe9760a 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -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() { diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 0d45ce9185..24442c3a73 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -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) diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp index b07635779b..b528cc421f 100644 --- a/lib/Sema/SemaCXXCast.cpp +++ b/lib/Sema/SemaCXXCast.cpp @@ -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; } diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index cdda6ab32f..061ac8d2c3 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -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>()) { diff --git a/test/SemaTemplate/instantiate-cast.cpp b/test/SemaTemplate/instantiate-cast.cpp index fc492edaaf..6b3fc6e125 100644 --- a/test/SemaTemplate/instantiate-cast.cpp +++ b/test/SemaTemplate/instantiate-cast.cpp @@ -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}} } }; |