aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2009-08-28 15:11:24 +0000
committerFariborz Jahanian <fjahanian@apple.com>2009-08-28 15:11:24 +0000
commit4fc7ab364110d6ad1c10dd38dbeb0597fed7e2f5 (patch)
tree7123cf844cf6971d011973cfa5775bf6f6bb5229
parent7e8f8189d0876e03ebc5018f6a22e41f5aaa20d9 (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.cpp23
-rw-r--r--lib/CodeGen/CGExpr.cpp5
-rw-r--r--lib/Sema/SemaCXXCast.cpp17
-rw-r--r--lib/Sema/SemaExprCXX.cpp7
-rw-r--r--test/SemaTemplate/instantiate-cast.cpp4
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}}
}
};