diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-08-26 23:31:30 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-08-26 23:31:30 +0000 |
commit | 64e690ecf7ba7ad560b0af631bb6f323c38f6da4 (patch) | |
tree | 4b06e8af2201f522ef3c8ea417ef71965ac076c7 | |
parent | e9f8eb64ed2d41c23db4a9774768613d4e07a865 (diff) |
ir-gen for type convesion of class objects. WIP.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80178 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGCXX.cpp | 21 | ||||
-rw-r--r-- | lib/CodeGen/CGExprAgg.cpp | 7 | ||||
-rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 5 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 2 | ||||
-rw-r--r-- | lib/Sema/SemaCXXCast.cpp | 4 |
5 files changed, 38 insertions, 1 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 680d7357b9..c72eca278c 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -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'"); diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index 6f6daa79d0..002c77430f 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -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) && diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index e8b7304552..299296a633 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -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()); diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index e8f0cc5de5..2815939517 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -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); diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp index 2dee71308b..66767ad1ba 100644 --- a/lib/Sema/SemaCXXCast.cpp +++ b/lib/Sema/SemaCXXCast.cpp @@ -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; } |