CT_Functional ///< Type(expr)
};
+namespace {
+ struct CastOperation {
+ CastOperation(Sema &S, QualType destType, ExprResult src)
+ : Self(S), SrcExpr(src), DestType(destType),
+ ResultType(destType.getNonLValueExprType(S.Context)),
+ ValueKind(Expr::getValueKindForType(destType)),
+ Kind(CK_Dependent), IsARCUnbridgedCast(false) {}
+
+ Sema &Self;
+ ExprResult SrcExpr;
+ QualType DestType;
+ QualType ResultType;
+ ExprValueKind ValueKind;
+ CastKind Kind;
+ bool IsARCUnbridgedCast;
+ CXXCastPath BasePath;
+ SourceRange OpRange;
+ SourceRange DestRange;
+ void CheckConstCast();
+ void CheckReinterpretCast();
+ void CheckStaticCast();
+ void CheckDynamicCast();
+ void CheckCStyleCast(bool FunctionalCast);
-static void CheckConstCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
- ExprValueKind &VK,
- const SourceRange &OpRange,
- const SourceRange &DestRange);
-static void CheckReinterpretCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
- ExprValueKind &VK,
- const SourceRange &OpRange,
- const SourceRange &DestRange,
- CastKind &Kind);
-static void CheckStaticCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
- ExprValueKind &VK,
- const SourceRange &OpRange,
- CastKind &Kind,
- CXXCastPath &BasePath);
-static void CheckDynamicCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
- ExprValueKind &VK,
- const SourceRange &OpRange,
- const SourceRange &DestRange,
- CastKind &Kind,
- CXXCastPath &BasePath);
+ void checkCastAlign() {
+ Self.CheckCastAlign(SrcExpr.get(), DestType, OpRange);
+ }
+
+ void checkObjCARCConversion(Sema::CheckedConversionKind CCK) {
+ Expr *src = SrcExpr.get();
+ Self.CheckObjCARCConversion(OpRange, DestType, src, CCK);
+ SrcExpr = src;
+ }
+ };
+}
static bool CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType,
bool CheckCVR, bool CheckObjCLifetime);
ExprResult Ex = Owned(E);
QualType DestType = DestTInfo->getType();
- SourceRange OpRange(OpLoc, Parens.getEnd());
- SourceRange DestRange = AngleBrackets;
-
// If the type is dependent, we won't do the semantic analysis now.
// FIXME: should we check this in a more fine-grained manner?
bool TypeDependent = DestType->isDependentType() || Ex.get()->isTypeDependent();
- ExprValueKind VK = VK_RValue;
- if (TypeDependent)
- VK = Expr::getValueKindForType(DestType);
+ CastOperation Op(*this, DestType, E);
+ Op.OpRange = SourceRange(OpLoc, Parens.getEnd());
+ Op.DestRange = AngleBrackets;
switch (Kind) {
default: llvm_unreachable("Unknown C++ cast!");
case tok::kw_const_cast:
if (!TypeDependent) {
- CheckConstCast(*this, Ex, DestType, VK, OpRange, DestRange);
- if (Ex.isInvalid())
+ Op.CheckConstCast();
+ if (Op.SrcExpr.isInvalid())
return ExprError();
}
- return Owned(CXXConstCastExpr::Create(Context,
- DestType.getNonLValueExprType(Context),
- VK, Ex.take(), DestTInfo, OpLoc,
+ return Owned(CXXConstCastExpr::Create(Context, Op.ResultType, Op.ValueKind,
+ Op.SrcExpr.take(), DestTInfo, OpLoc,
Parens.getEnd()));
case tok::kw_dynamic_cast: {
- CastKind Kind = CK_Dependent;
- CXXCastPath BasePath;
if (!TypeDependent) {
- CheckDynamicCast(*this, Ex, DestType, VK, OpRange, DestRange,
- Kind, BasePath);
- if (Ex.isInvalid())
+ Op.CheckDynamicCast();
+ if (Op.SrcExpr.isInvalid())
return ExprError();
}
- return Owned(CXXDynamicCastExpr::Create(Context,
- DestType.getNonLValueExprType(Context),
- VK, Kind, Ex.take(), &BasePath, DestTInfo,
- OpLoc, Parens.getEnd()));
+ return Owned(CXXDynamicCastExpr::Create(Context, Op.ResultType,
+ Op.ValueKind, Op.Kind,
+ Op.SrcExpr.take(), &Op.BasePath,
+ DestTInfo, OpLoc, Parens.getEnd()));
}
case tok::kw_reinterpret_cast: {
- CastKind Kind = CK_Dependent;
if (!TypeDependent) {
- CheckReinterpretCast(*this, Ex, DestType, VK, OpRange, DestRange, Kind);
- if (Ex.isInvalid())
+ Op.CheckReinterpretCast();
+ if (Op.SrcExpr.isInvalid())
return ExprError();
}
- return Owned(CXXReinterpretCastExpr::Create(Context,
- DestType.getNonLValueExprType(Context),
- VK, Kind, Ex.take(), 0,
- DestTInfo, OpLoc, Parens.getEnd()));
+ return Owned(CXXReinterpretCastExpr::Create(Context, Op.ResultType,
+ Op.ValueKind, Op.Kind,
+ Op.SrcExpr.take(), 0,
+ DestTInfo, OpLoc,
+ Parens.getEnd()));
}
case tok::kw_static_cast: {
- CastKind Kind = CK_Dependent;
- CXXCastPath BasePath;
if (!TypeDependent) {
- CheckStaticCast(*this, Ex, DestType, VK, OpRange, Kind, BasePath);
- if (Ex.isInvalid())
+ Op.CheckStaticCast();
+ if (Op.SrcExpr.isInvalid())
return ExprError();
}
- return Owned(CXXStaticCastExpr::Create(Context,
- DestType.getNonLValueExprType(Context),
- VK, Kind, Ex.take(), &BasePath,
- DestTInfo, OpLoc, Parens.getEnd()));
+ return Owned(CXXStaticCastExpr::Create(Context, Op.ResultType, Op.ValueKind,
+ Op.Kind, Op.SrcExpr.take(),
+ &Op.BasePath, DestTInfo, OpLoc,
+ Parens.getEnd()));
}
}
/// CheckDynamicCast - Check that a dynamic_cast\<DestType\>(SrcExpr) is valid.
/// Refer to C++ 5.2.7 for details. Dynamic casts are used mostly for runtime-
/// checked downcasts in class hierarchies.
-static void
-CheckDynamicCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
- ExprValueKind &VK, const SourceRange &OpRange,
- const SourceRange &DestRange, CastKind &Kind,
- CXXCastPath &BasePath) {
- QualType OrigDestType = DestType, OrigSrcType = SrcExpr.get()->getType();
- DestType = Self.Context.getCanonicalType(DestType);
+void CastOperation::CheckDynamicCast() {
+ QualType OrigSrcType = SrcExpr.get()->getType();
+ QualType DestType = Self.Context.getCanonicalType(this->DestType);
// C++ 5.2.7p1: T shall be a pointer or reference to a complete class type,
// or "pointer to cv void".
DestPointee = DestPointer->getPointeeType();
} else if ((DestReference = DestType->getAs<ReferenceType>())) {
DestPointee = DestReference->getPointeeType();
- VK = isa<LValueReferenceType>(DestReference) ? VK_LValue
- : isa<RValueReferenceType>(DestReference) ? VK_XValue
- : VK_RValue;
} else {
Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ref_or_ptr)
- << OrigDestType << DestRange;
+ << this->DestType << DestRange;
return;
}
} else if (DestReference->isLValueReferenceType()) {
if (!SrcExpr.get()->isLValue()) {
Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_rvalue)
- << CT_Dynamic << OrigSrcType << OrigDestType << OpRange;
+ << CT_Dynamic << OrigSrcType << this->DestType << OpRange;
}
SrcPointee = SrcType;
} else {
// C++ 5.2.7p1: The dynamic_cast operator shall not cast away constness.
if (!DestPointee.isAtLeastAsQualifiedAs(SrcPointee)) {
Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_qualifiers_away)
- << CT_Dynamic << OrigSrcType << OrigDestType << OpRange;
+ << CT_Dynamic << OrigSrcType << this->DestType << OpRange;
return;
}
/// like this:
/// const char *str = "literal";
/// legacy_function(const_cast\<char*\>(str));
-void
-CheckConstCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, ExprValueKind &VK,
- const SourceRange &OpRange, const SourceRange &DestRange) {
- VK = Expr::getValueKindForType(DestType);
- if (VK == VK_RValue) {
+void CastOperation::CheckConstCast() {
+ if (ValueKind == VK_RValue) {
SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
return;
/// Refer to C++ 5.2.10 for details. reinterpret_cast is typically used in code
/// like this:
/// char *bytes = reinterpret_cast\<char*\>(int_ptr);
-void
-CheckReinterpretCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
- ExprValueKind &VK, const SourceRange &OpRange,
- const SourceRange &DestRange, CastKind &Kind) {
- VK = Expr::getValueKindForType(DestType);
- if (VK == VK_RValue) {
+void CastOperation::CheckReinterpretCast() {
+ if (ValueKind == VK_RValue) {
SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
return;
diagnoseBadCast(Self, msg, CT_Reinterpret, OpRange, SrcExpr.get(), DestType);
}
} else if (tcr == TC_Success && Self.getLangOptions().ObjCAutoRefCount) {
- Expr *Exp = SrcExpr.get();
- // Note that Exp does not change with CCK_OtherCast cast type
- Self.CheckObjCARCConversion(OpRange, DestType,
- Exp, Sema::CCK_OtherCast);
+ checkObjCARCConversion(Sema::CCK_OtherCast);
}
}
/// CheckStaticCast - Check that a static_cast\<DestType\>(SrcExpr) is valid.
/// Refer to C++ 5.2.9 for details. Static casts are mostly used for making
/// implicit conversions explicit and getting rid of data loss warnings.
-void
-CheckStaticCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
- ExprValueKind &VK, const SourceRange &OpRange,
- CastKind &Kind, CXXCastPath &BasePath) {
+void CastOperation::CheckStaticCast() {
// This test is outside everything else because it's the only case where
// a non-lvalue-reference target type does not lead to decay.
// C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".
return;
}
- VK = Expr::getValueKindForType(DestType);
- if (VK == VK_RValue && !DestType->isRecordType()) {
+ if (ValueKind == VK_RValue && !DestType->isRecordType()) {
SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
return;
}
} else if (tcr == TC_Success) {
if (Kind == CK_BitCast)
- Self.CheckCastAlign(SrcExpr.get(), DestType, OpRange);
- if (Self.getLangOptions().ObjCAutoRefCount) {
- Expr *Exp = SrcExpr.get();
- // Note that Exp does not change with CCK_OtherCast cast type
- Self.CheckObjCARCConversion(OpRange, DestType,
- Exp, Sema::CCK_OtherCast);
- }
+ checkCastAlign();
+ if (Self.getLangOptions().ObjCAutoRefCount)
+ checkObjCARCConversion(Sema::CCK_OtherCast);
+ } else if (Kind == CK_BitCast) {
+ checkCastAlign();
}
- else if (Kind == CK_BitCast)
- Self.CheckCastAlign(SrcExpr.get(), DestType, OpRange);
}
/// TryStaticCast - Check if a static cast can be performed, and do so if
return TC_Success;
}
-ExprResult
-Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK,
- Expr *CastExpr, CastKind &Kind,
- CXXCastPath &BasePath,
- bool FunctionalStyle) {
+void CastOperation::CheckCStyleCast(bool FunctionalStyle) {
+ // Check for casts from __unknown_any before anything else.
+ if (SrcExpr.get()->getType() == Self.Context.UnknownAnyTy) {
+ SrcExpr = Self.checkUnknownAnyCast(DestRange, DestType,
+ SrcExpr.get(), Kind,
+ ValueKind, BasePath);
+ return;
+ }
+
// This test is outside everything else because it's the only case where
// a non-lvalue-reference target type does not lead to decay.
// C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".
- if (CastTy->isVoidType()) {
+ if (DestType->isVoidType()) {
Kind = CK_ToVoid;
- ExprResult CastExprRes = IgnoredValueConversions(CastExpr);
- if (CastExprRes.isInvalid())
- return ExprError();
- CastExpr = CastExprRes.take();
-
- if (CastExpr->getType() == Context.BoundMemberTy)
- return CheckPlaceholderExpr(CastExpr); // will always fail
+ SrcExpr = Self.IgnoredValueConversions(SrcExpr.take());
+ if (SrcExpr.isInvalid())
+ return;
- if (CastExpr->getType() == Context.OverloadTy) {
- ExprResult SingleFunctionExpr =
- ResolveAndFixSingleFunctionTemplateSpecialization(
- CastExpr, /* Decay Function to ptr */ false,
- /* Complain */ true, R, CastTy,
+ if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
+ SrcExpr = Self.ResolveAndFixSingleFunctionTemplateSpecialization(
+ SrcExpr.take(), /* Decay Function to ptr */ false,
+ /* Complain */ true, DestRange, DestType,
diag::err_bad_cstyle_cast_overload);
- if (SingleFunctionExpr.isInvalid())
- return ExprError();
- CastExpr = SingleFunctionExpr.take();
+ if (SrcExpr.isInvalid())
+ return;
}
- assert(!CastExpr->getType()->isPlaceholderType());
+ if (SrcExpr.get()->getType() == Self.Context.BoundMemberTy) {
+ Self.CheckPlaceholderExpr(SrcExpr.take()); // will always fail
+ return;
+ }
- return Owned(CastExpr);
- }
+ assert(!SrcExpr.get()->getType()->isPlaceholderType());
- // Make sure we determine the value kind before we bail out for
- // dependent types.
- VK = Expr::getValueKindForType(CastTy);
+ return;
+ }
// If the type is dependent, we won't do any other semantic analysis now.
- if (CastTy->isDependentType() || CastExpr->isTypeDependent()) {
- Kind = CK_Dependent;
- return Owned(CastExpr);
+ if (DestType->isDependentType() || SrcExpr.get()->isTypeDependent()) {
+ assert(Kind == CK_Dependent);
+ return;
}
- if (VK == VK_RValue && !CastTy->isRecordType()) {
- ExprResult CastExprRes = DefaultFunctionArrayLvalueConversion(CastExpr);
- if (CastExprRes.isInvalid())
- return ExprError();
- CastExpr = CastExprRes.take();
+ if (ValueKind == VK_RValue && !DestType->isRecordType()) {
+ SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
+ if (SrcExpr.isInvalid())
+ return;
}
// AltiVec vector initialization with a single literal.
- if (const VectorType *vecTy = CastTy->getAs<VectorType>())
+ if (const VectorType *vecTy = DestType->getAs<VectorType>())
if (vecTy->getVectorKind() == VectorType::AltiVecVector
- && (CastExpr->getType()->isIntegerType()
- || CastExpr->getType()->isFloatingType())) {
+ && (SrcExpr.get()->getType()->isIntegerType()
+ || SrcExpr.get()->getType()->isFloatingType())) {
Kind = CK_VectorSplat;
- return Owned(CastExpr);
+ return;
}
// C++ [expr.cast]p5: The conversions performed by
// even if a cast resulting from that interpretation is ill-formed.
// In plain language, this means trying a const_cast ...
unsigned msg = diag::err_bad_cxx_cast_generic;
- TryCastResult tcr = TryConstCast(*this, CastExpr, CastTy, /*CStyle*/true,
- msg);
+ TryCastResult tcr = TryConstCast(Self, SrcExpr.get(), DestType,
+ /*CStyle*/true, msg);
if (tcr == TC_Success)
Kind = CK_NoOp;
: Sema::CCK_CStyleCast;
if (tcr == TC_NotApplicable) {
// ... or if that is not possible, a static_cast, ignoring const, ...
- ExprResult CastExprRes = Owned(CastExpr);
- tcr = TryStaticCast(*this, CastExprRes, CastTy, CCK, R, msg, Kind,
- BasePath);
- if (CastExprRes.isInvalid())
- return ExprError();
- CastExpr = CastExprRes.take();
+ tcr = TryStaticCast(Self, SrcExpr, DestType, CCK, OpRange,
+ msg, Kind, BasePath);
+ if (SrcExpr.isInvalid())
+ return;
+
if (tcr == TC_NotApplicable) {
// ... and finally a reinterpret_cast, ignoring const.
- CastExprRes = Owned(CastExpr);
- tcr = TryReinterpretCast(*this, CastExprRes, CastTy, /*CStyle*/true, R,
- msg, Kind);
- if (CastExprRes.isInvalid())
- return ExprError();
- CastExpr = CastExprRes.take();
+ tcr = TryReinterpretCast(Self, SrcExpr, DestType, /*CStyle*/true,
+ OpRange, msg, Kind);
+ if (SrcExpr.isInvalid())
+ return;
}
}
- if (getLangOptions().ObjCAutoRefCount && tcr == TC_Success)
- CheckObjCARCConversion(R, CastTy, CastExpr, CCK);
+ if (Self.getLangOptions().ObjCAutoRefCount && tcr == TC_Success)
+ checkObjCARCConversion(CCK);
if (tcr != TC_Success && msg != 0) {
- if (CastExpr->getType() == Context.OverloadTy) {
+ if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
DeclAccessPair Found;
- FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(CastExpr,
- CastTy,
- /* Complain */ true,
+ FunctionDecl *Fn = Self.ResolveAddressOfOverloadedFunction(SrcExpr.get(),
+ DestType,
+ /*Complain*/ true,
Found);
assert(!Fn && "cast failed but able to resolve overload expression!!");
(void)Fn;
} else {
- diagnoseBadCast(*this, msg, (FunctionalStyle ? CT_Functional : CT_CStyle),
- R, CastExpr, CastTy);
+ diagnoseBadCast(Self, msg, (FunctionalStyle ? CT_Functional : CT_CStyle),
+ OpRange, SrcExpr.get(), DestType);
}
+ } else if (Kind == CK_BitCast) {
+ checkCastAlign();
}
- else if (Kind == CK_BitCast)
- CheckCastAlign(CastExpr, CastTy, R);
+ // Clear out SrcExpr if there was a fatal error.
if (tcr != TC_Success)
+ SrcExpr = ExprError();
+}
+
+ExprResult Sema::CXXBuildCStyleCastExpr(SourceLocation LPLoc,
+ TypeSourceInfo *CastTypeInfo,
+ SourceLocation RPLoc,
+ Expr *CastExpr) {
+ CastOperation Op(*this, CastTypeInfo->getType(), CastExpr);
+ Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange();
+ Op.OpRange = SourceRange(LPLoc, CastExpr->getLocEnd());
+
+ Op.CheckCStyleCast(/*FunctionalStyle=*/ false);
+ if (Op.SrcExpr.isInvalid())
+ return ExprError();
+
+ return Owned(CStyleCastExpr::Create(Context, Op.ResultType, Op.ValueKind,
+ Op.Kind, Op.SrcExpr.take(), &Op.BasePath,
+ CastTypeInfo, LPLoc, RPLoc));
+}
+
+ExprResult Sema::BuildCXXFunctionalCastExpr(TypeSourceInfo *CastTypeInfo,
+ SourceLocation LPLoc,
+ Expr *CastExpr,
+ SourceLocation RPLoc) {
+ CastOperation Op(*this, CastTypeInfo->getType(), CastExpr);
+ Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange();
+ Op.OpRange = SourceRange(Op.DestRange.getBegin(), CastExpr->getLocEnd());
+
+ Op.CheckCStyleCast(/*FunctionalStyle=*/ true);
+ if (Op.SrcExpr.isInvalid())
return ExprError();
- return Owned(CastExpr);
+ return Owned(CXXFunctionalCastExpr::Create(Context, Op.ResultType,
+ Op.ValueKind, CastTypeInfo,
+ Op.DestRange.getBegin(),
+ Op.Kind, Op.SrcExpr.take(),
+ &Op.BasePath, RPLoc));
}
llvm_unreachable("Unhandled scalar cast");
}
-/// CheckCastTypes - Check type constraints for casting between types.
-ExprResult Sema::CheckCastTypes(SourceLocation CastStartLoc,
- SourceRange TypeRange, QualType CastType,
- Expr *CastExpr, CastKind &Kind,
- ExprValueKind &VK, CXXCastPath &BasePath,
- bool FunctionalStyle) {
- if (CastExpr->getType() == Context.UnknownAnyTy)
+/// CheckCastTypes - Check type constraints for casting between types in C.
+ExprResult Sema::CheckCCastTypes(SourceLocation CastStartLoc,
+ SourceRange TypeRange, QualType CastType,
+ Expr *CastExpr, CastKind &Kind) {
+ assert(!getLangOptions().CPlusPlus);
+
+ if (CastExpr->getType() == Context.UnknownAnyTy) {
+ // We can safely ignore these here because C never has base paths
+ // or casts to l-values.
+ CXXCastPath BasePath;
+ ExprValueKind VK = VK_RValue;
return checkUnknownAnyCast(TypeRange, CastType, CastExpr, Kind, VK,
BasePath);
+ }
- if (getLangOptions().CPlusPlus)
- return CXXCheckCStyleCast(SourceRange(CastStartLoc,
- CastExpr->getLocEnd()),
- CastType, VK, CastExpr, Kind, BasePath,
- FunctionalStyle);
+ ExprResult Result = CheckPlaceholderExpr(CastExpr);
+ if (Result.isInvalid())
+ return ExprError();
+ CastExpr = Result.take();
assert(!CastExpr->getType()->isPlaceholderType());
- // We only support r-value casts in C.
- VK = VK_RValue;
-
// C99 6.5.4p2: the cast type needs to be void or scalar and the expression
// type needs to be scalar.
if (CastType->isVoidType()) {
}
}
+ // ARC imposes extra restrictions on casts.
if (getLangOptions().ObjCAutoRefCount) {
- // Diagnose problems with Objective-C casts involving lifetime qualifiers.
- CheckObjCARCConversion(SourceRange(CastStartLoc, CastExpr->getLocEnd()),
+ CheckObjCARCConversion(SourceRange(CastStartLoc, CastExpr->getLocEnd()),
CastType, CastExpr, CCK_CStyleCast);
if (const PointerType *CastPtr = CastType->getAs<PointerType>()) {
ExprResult
Sema::BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty,
SourceLocation RParenLoc, Expr *CastExpr) {
+ if (getLangOptions().CPlusPlus)
+ return CXXBuildCStyleCastExpr(LParenLoc, Ty, RParenLoc, CastExpr);
+
CastKind Kind = CK_Invalid;
- ExprValueKind VK = VK_RValue;
- CXXCastPath BasePath;
ExprResult CastResult =
- CheckCastTypes(LParenLoc, SourceRange(LParenLoc, RParenLoc), Ty->getType(),
- CastExpr, Kind, VK, BasePath);
+ CheckCCastTypes(LParenLoc, SourceRange(LParenLoc, RParenLoc),
+ Ty->getType(), CastExpr, Kind);
if (CastResult.isInvalid())
return ExprError();
CastExpr = CastResult.take();
- return Owned(CStyleCastExpr::Create(
- Context, Ty->getType().getNonLValueExprType(Context), VK, Kind, CastExpr,
- &BasePath, Ty, LParenLoc, RParenLoc));
+ return Owned(CStyleCastExpr::Create(Context, Ty->getType(), VK_RValue, Kind,
+ CastExpr, /*base path*/ 0, Ty,
+ LParenLoc, RParenLoc));
}
ExprResult Sema::BuildVectorLiteral(SourceLocation LParenLoc,