Revert r145244. It causes us to create broken ASTs with missing type information

for some cast expressions.

Original commit message:

Removed useless ImplicitCast nodes in explicit cstyle and static casts

llvm-svn: 145447
This commit is contained in:
Richard Smith 2011-11-29 22:48:16 +00:00
parent 8b9ccfe270
commit 507840dbff
9 changed files with 110 additions and 209 deletions

View File

@ -178,11 +178,9 @@ public:
/// \brief Retrieve the location of the cast operator keyword, e.g., /// \brief Retrieve the location of the cast operator keyword, e.g.,
/// "static_cast". /// "static_cast".
SourceLocation getOperatorLoc() const { return Loc; } SourceLocation getOperatorLoc() const { return Loc; }
void setOperatorLoc(SourceLocation const& OpLoc) { Loc = OpLoc; }
/// \brief Retrieve the location of the closing parenthesis. /// \brief Retrieve the location of the closing parenthesis.
SourceLocation getRParenLoc() const { return RParenLoc; } SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation const& Loc) { RParenLoc = Loc; }
SourceRange getSourceRange() const { SourceRange getSourceRange() const {
return SourceRange(Loc, RParenLoc); return SourceRange(Loc, RParenLoc);

View File

@ -340,7 +340,7 @@ private:
SIK_Default = IK_Default, ///< Default initialization SIK_Default = IK_Default, ///< Default initialization
SIK_Value = IK_Value, ///< Value initialization SIK_Value = IK_Value, ///< Value initialization
SIK_ImplicitValue, ///< Implicit value initialization SIK_ImplicitValue, ///< Implicit value initialization
SIK_DirectStaticCast, ///< Direct initialization due to a static cast SIK_DirectCast, ///< Direct initialization due to a cast
/// \brief Direct initialization due to a C-style cast. /// \brief Direct initialization due to a C-style cast.
SIK_DirectCStyleCast, SIK_DirectCStyleCast,
/// \brief Direct initialization due to a functional-style cast. /// \brief Direct initialization due to a functional-style cast.
@ -372,8 +372,8 @@ public:
/// \brief Create a direct initialization due to a cast that isn't a C-style /// \brief Create a direct initialization due to a cast that isn't a C-style
/// or functional cast. /// or functional cast.
static InitializationKind CreateStaticCast(SourceRange TypeRange) { static InitializationKind CreateCast(SourceRange TypeRange) {
return InitializationKind(SIK_DirectStaticCast, return InitializationKind(SIK_DirectCast,
TypeRange.getBegin(), TypeRange.getBegin(), TypeRange.getBegin(), TypeRange.getBegin(),
TypeRange.getEnd()); TypeRange.getEnd());
} }
@ -425,7 +425,7 @@ public:
/// \brief Determine whether this initialization is an explicit cast. /// \brief Determine whether this initialization is an explicit cast.
bool isExplicitCast() const { bool isExplicitCast() const {
return Kind == SIK_DirectStaticCast || return Kind == SIK_DirectCast ||
Kind == SIK_DirectCStyleCast || Kind == SIK_DirectCStyleCast ||
Kind == SIK_DirectFunctionalCast; Kind == SIK_DirectFunctionalCast;
} }
@ -440,11 +440,6 @@ public:
return Kind == SIK_DirectCStyleCast; return Kind == SIK_DirectCStyleCast;
} }
/// brief Determine whether this is a static cast.
bool isStaticCast() const {
return Kind == SIK_DirectStaticCast;
}
/// brief Determine whether this is a functional-style cast. /// brief Determine whether this is a functional-style cast.
bool isFunctionalCast() const { bool isFunctionalCast() const {
return Kind == SIK_DirectFunctionalCast; return Kind == SIK_DirectFunctionalCast;

View File

@ -5557,26 +5557,18 @@ public:
CCK_CStyleCast, CCK_CStyleCast,
/// \brief A functional-style cast. /// \brief A functional-style cast.
CCK_FunctionalCast, CCK_FunctionalCast,
/// \breif A static cast
CCK_StaticCast,
/// \brief A cast other than a C-style cast. /// \brief A cast other than a C-style cast.
CCK_OtherCast CCK_OtherCast
}; };
/// CastExprToType - If Expr is not of type 'Type', insert a cast of the /// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit
/// specified kind. /// cast. If there is already an implicit cast, merge into the existing one.
/// Redundant implicit casts are merged together. /// If isLvalue, the result of the cast is an lvalue.
ExprResult CastExprToType(Expr *E, QualType Ty,
CastKind Kind, ExprValueKind VK,
const CXXCastPath *BasePath,
CheckedConversionKind CCK);
/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
/// If there is already an implicit cast, merge into the existing one.
/// The result is of the given category.
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK,
ExprValueKind VK = VK_RValue, ExprValueKind VK = VK_RValue,
const CXXCastPath *BasePath = 0); const CXXCastPath *BasePath = 0,
CheckedConversionKind CCK
= CCK_ImplicitConversion);
/// ScalarTypeToBooleanCastKind - Returns the cast kind corresponding /// ScalarTypeToBooleanCastKind - Returns the cast kind corresponding
/// to the conversion from scalar type ScalarTy to the Boolean type. /// to the conversion from scalar type ScalarTy to the Boolean type.
@ -5765,7 +5757,7 @@ public:
AssignmentAction Action, AssignmentAction Action,
CheckedConversionKind CCK CheckedConversionKind CCK
= CCK_ImplicitConversion); = CCK_ImplicitConversion);
ExprResult PerformConversion(Expr *From, QualType ToType, ExprResult PerformImplicitConversion(Expr *From, QualType ToType,
const StandardConversionSequence& SCS, const StandardConversionSequence& SCS,
AssignmentAction Action, AssignmentAction Action,
CheckedConversionKind CCK); CheckedConversionKind CCK);

View File

@ -234,13 +234,10 @@ void Sema::PrintStats() const {
AnalysisWarnings.PrintStats(); AnalysisWarnings.PrintStats();
} }
/// CastExprToType - If Expr is not of type 'Type', insert a cast of the /// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
/// specified kind. /// If there is already an implicit cast, merge into the existing one.
/// Redundant implicit casts are merged together. /// The result is of the given category.
/// Pay attention: if CCK != CCK_ImplicitConversion, ExprResult Sema::ImpCastExprToType(Expr *E, QualType Ty,
/// users of this function must fill
/// SourceTypeInfos and SourceLocations later
ExprResult Sema::CastExprToType(Expr *E, QualType Ty,
CastKind Kind, ExprValueKind VK, CastKind Kind, ExprValueKind VK,
const CXXCastPath *BasePath, const CXXCastPath *BasePath,
CheckedConversionKind CCK) { CheckedConversionKind CCK) {
@ -280,10 +277,6 @@ ExprResult Sema::CastExprToType(Expr *E, QualType Ty,
cast<CXXRecordDecl>(RecordTy->getDecl())); cast<CXXRecordDecl>(RecordTy->getDecl()));
} }
switch(CCK) {
default:
llvm_unreachable("Unexpected CheckedConversionKind");
case CCK_ImplicitConversion:
if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(E)) { if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(E)) {
if (ImpCast->getCastKind() == Kind && (!BasePath || BasePath->empty())) { if (ImpCast->getCastKind() == Kind && (!BasePath || BasePath->empty())) {
ImpCast->setType(Ty); ImpCast->setType(Ty);
@ -291,29 +284,8 @@ ExprResult Sema::CastExprToType(Expr *E, QualType Ty,
return Owned(E); return Owned(E);
} }
} }
return Owned(ImplicitCastExpr::Create(Context, Ty, Kind, E, BasePath, VK)); return Owned(ImplicitCastExpr::Create(Context, Ty, Kind, E, BasePath, VK));
case CCK_CStyleCast:
return Owned(CStyleCastExpr::Create(Context, Ty, VK, Kind, E, BasePath,
0, SourceLocation(), SourceLocation()));
case CCK_FunctionalCast:
return Owned(CXXFunctionalCastExpr::Create(Context, Ty, VK, 0,
SourceLocation(), Kind, E,
BasePath, SourceLocation()));
case CCK_StaticCast:
return Owned(CXXStaticCastExpr::Create(Context, Ty, VK, Kind, E, BasePath,
0, SourceLocation(),
SourceLocation()));
}
}
/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
/// If there is already an implicit cast, merge into the existing one.
/// The result is of the given category.
ExprResult Sema::ImpCastExprToType(Expr *E, QualType Ty,
CastKind Kind, ExprValueKind VK,
const CXXCastPath *BasePath) {
return CastExprToType(E, Ty, Kind, VK, BasePath, CCK_ImplicitConversion);
} }
/// ScalarTypeToBooleanCastKind - Returns the cast kind corresponding /// ScalarTypeToBooleanCastKind - Returns the cast kind corresponding

View File

@ -75,9 +75,9 @@ namespace {
// Top-level semantics-checking routines. // Top-level semantics-checking routines.
void CheckConstCast(); void CheckConstCast();
void CheckReinterpretCast(); void CheckReinterpretCast();
void CheckStaticCast(bool &CastNodesCreated); void CheckStaticCast();
void CheckDynamicCast(); void CheckDynamicCast();
void CheckCXXCStyleCast(bool FunctionalCast, bool &CastNodesCreated); void CheckCXXCStyleCast(bool FunctionalCast);
void CheckCStyleCast(); void CheckCStyleCast();
/// Complete an apparently-successful cast operation that yields /// Complete an apparently-successful cast operation that yields
@ -283,28 +283,12 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
Parens.getEnd())); Parens.getEnd()));
} }
case tok::kw_static_cast: { case tok::kw_static_cast: {
bool CastNodesCreated = false;
if (!TypeDependent) { if (!TypeDependent) {
Op.CheckStaticCast(CastNodesCreated); Op.CheckStaticCast();
if (Op.SrcExpr.isInvalid()) if (Op.SrcExpr.isInvalid())
return ExprError(); return ExprError();
} }
// CheckStaticCast _may_ have already created the cast node. Let's check
if (CastNodesCreated) {
if (CXXStaticCastExpr *Cast =
dyn_cast<CXXStaticCastExpr>(Op.SrcExpr.get())) {
assert(!Cast->getTypeInfoAsWritten() &&
"The explicit cast node created by CheckStaticCast "
"has source type infos!");
Cast->setTypeInfoAsWritten(DestTInfo);
Cast->setOperatorLoc(OpLoc);
Cast->setRParenLoc(Parens.getEnd());
return Op.complete(Cast);
}
}
return Op.complete(CXXStaticCastExpr::Create(Context, Op.ResultType, return Op.complete(CXXStaticCastExpr::Create(Context, Op.ResultType,
Op.ValueKind, Op.Kind, Op.SrcExpr.take(), Op.ValueKind, Op.Kind, Op.SrcExpr.take(),
&Op.BasePath, DestTInfo, &Op.BasePath, DestTInfo,
@ -343,7 +327,7 @@ static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT,
= (CT == CT_CStyle)? InitializationKind::CreateCStyleCast(range.getBegin(), = (CT == CT_CStyle)? InitializationKind::CreateCStyleCast(range.getBegin(),
range) range)
: (CT == CT_Functional)? InitializationKind::CreateFunctionalCast(range) : (CT == CT_Functional)? InitializationKind::CreateFunctionalCast(range)
: InitializationKind::CreateStaticCast(/*type range?*/ range); : InitializationKind::CreateCast(/*type range?*/ range);
InitializationSequence sequence(S, entity, initKind, &src, 1); InitializationSequence sequence(S, entity, initKind, &src, 1);
assert(sequence.Failed() && "initialization succeeded on second try?"); assert(sequence.Failed() && "initialization succeeded on second try?");
@ -730,7 +714,7 @@ void CastOperation::CheckReinterpretCast() {
/// CheckStaticCast - Check that a static_cast\<DestType\>(SrcExpr) is valid. /// 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 /// 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. /// implicit conversions explicit and getting rid of data loss warnings.
void CastOperation::CheckStaticCast(bool &CastNodesCreated) { void CastOperation::CheckStaticCast() {
if (isPlaceholder()) { if (isPlaceholder()) {
checkNonOverloadPlaceholders(); checkNonOverloadPlaceholders();
if (SrcExpr.isInvalid()) if (SrcExpr.isInvalid())
@ -763,10 +747,9 @@ void CastOperation::CheckStaticCast(bool &CastNodesCreated) {
return; return;
} }
Expr *SrcExprOrig = SrcExpr.get();
unsigned msg = diag::err_bad_cxx_cast_generic; unsigned msg = diag::err_bad_cxx_cast_generic;
TryCastResult tcr TryCastResult tcr
= TryStaticCast(Self, SrcExpr, DestType, Sema::CCK_StaticCast, OpRange, msg, = TryStaticCast(Self, SrcExpr, DestType, Sema::CCK_OtherCast, OpRange, msg,
Kind, BasePath); Kind, BasePath);
if (tcr != TC_Success && msg != 0) { if (tcr != TC_Success && msg != 0) {
if (SrcExpr.isInvalid()) if (SrcExpr.isInvalid())
@ -784,12 +767,10 @@ void CastOperation::CheckStaticCast(bool &CastNodesCreated) {
if (Kind == CK_BitCast) if (Kind == CK_BitCast)
checkCastAlign(); checkCastAlign();
if (Self.getLangOptions().ObjCAutoRefCount) if (Self.getLangOptions().ObjCAutoRefCount)
checkObjCARCConversion(Sema::CCK_StaticCast); checkObjCARCConversion(Sema::CCK_OtherCast);
} else if (Kind == CK_BitCast) { } else if (Kind == CK_BitCast) {
checkCastAlign(); checkCastAlign();
} }
CastNodesCreated = (SrcExpr.get() != SrcExprOrig);
} }
/// TryStaticCast - Check if a static cast can be performed, and do so if /// TryStaticCast - Check if a static cast can be performed, and do so if
@ -1327,7 +1308,7 @@ TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
? InitializationKind::CreateCStyleCast(OpRange.getBegin(), OpRange) ? InitializationKind::CreateCStyleCast(OpRange.getBegin(), OpRange)
: (CCK == Sema::CCK_FunctionalCast) : (CCK == Sema::CCK_FunctionalCast)
? InitializationKind::CreateFunctionalCast(OpRange) ? InitializationKind::CreateFunctionalCast(OpRange)
: InitializationKind::CreateStaticCast(OpRange); : InitializationKind::CreateCast(OpRange);
Expr *SrcExprRaw = SrcExpr.get(); Expr *SrcExprRaw = SrcExpr.get();
InitializationSequence InitSeq(Self, Entity, InitKind, &SrcExprRaw, 1); InitializationSequence InitSeq(Self, Entity, InitKind, &SrcExprRaw, 1);
@ -1761,9 +1742,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr,
return TC_Success; return TC_Success;
} }
void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle, void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle) {
bool &CastNodesCreated) {
CastNodesCreated = false;
// Handle placeholders. // Handle placeholders.
if (isPlaceholder()) { if (isPlaceholder()) {
// C-style casts can resolve __unknown_any types. // C-style casts can resolve __unknown_any types.
@ -1844,7 +1823,6 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle,
= FunctionalStyle? Sema::CCK_FunctionalCast = FunctionalStyle? Sema::CCK_FunctionalCast
: Sema::CCK_CStyleCast; : Sema::CCK_CStyleCast;
if (tcr == TC_NotApplicable) { if (tcr == TC_NotApplicable) {
Expr *SrcExprOrig = SrcExpr.get();
// ... or if that is not possible, a static_cast, ignoring const, ... // ... or if that is not possible, a static_cast, ignoring const, ...
tcr = TryStaticCast(Self, SrcExpr, DestType, CCK, OpRange, tcr = TryStaticCast(Self, SrcExpr, DestType, CCK, OpRange,
msg, Kind, BasePath); msg, Kind, BasePath);
@ -1858,8 +1836,6 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle,
if (SrcExpr.isInvalid()) if (SrcExpr.isInvalid())
return; return;
} }
CastNodesCreated = (SrcExpr.get() != SrcExprOrig);
} }
if (Self.getLangOptions().ObjCAutoRefCount && tcr == TC_Success) if (Self.getLangOptions().ObjCAutoRefCount && tcr == TC_Success)
@ -2077,9 +2053,8 @@ ExprResult Sema::BuildCStyleCastExpr(SourceLocation LPLoc,
Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange(); Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange();
Op.OpRange = SourceRange(LPLoc, CastExpr->getLocEnd()); Op.OpRange = SourceRange(LPLoc, CastExpr->getLocEnd());
bool CastNodesCreated = false;
if (getLangOptions().CPlusPlus) { if (getLangOptions().CPlusPlus) {
Op.CheckCXXCStyleCast(/*FunctionalStyle=*/ false, CastNodesCreated); Op.CheckCXXCStyleCast(/*FunctionalStyle=*/ false);
} else { } else {
Op.CheckCStyleCast(); Op.CheckCStyleCast();
} }
@ -2087,20 +2062,6 @@ ExprResult Sema::BuildCStyleCastExpr(SourceLocation LPLoc,
if (Op.SrcExpr.isInvalid()) if (Op.SrcExpr.isInvalid())
return ExprError(); return ExprError();
// CheckCXXCStyleCast _may_ have already created the CStyleCastExpr
// node. Let's check.
if (CastNodesCreated) {
if (CStyleCastExpr *Cast = dyn_cast<CStyleCastExpr>(Op.SrcExpr.get())){
assert(!Cast->getTypeInfoAsWritten() &&
"The explicit cast node created by CheckStaticCast "
"has source type infos!");
Cast->setTypeInfoAsWritten(CastTypeInfo);
Cast->setLParenLoc(LPLoc);
Cast->setRParenLoc(RPLoc);
return Op.complete(Cast);
}
}
return Op.complete(CStyleCastExpr::Create(Context, Op.ResultType, return Op.complete(CStyleCastExpr::Create(Context, Op.ResultType,
Op.ValueKind, Op.Kind, Op.SrcExpr.take(), Op.ValueKind, Op.Kind, Op.SrcExpr.take(),
&Op.BasePath, CastTypeInfo, LPLoc, RPLoc)); &Op.BasePath, CastTypeInfo, LPLoc, RPLoc));
@ -2114,28 +2075,11 @@ ExprResult Sema::BuildCXXFunctionalCastExpr(TypeSourceInfo *CastTypeInfo,
Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange(); Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange();
Op.OpRange = SourceRange(Op.DestRange.getBegin(), CastExpr->getLocEnd()); Op.OpRange = SourceRange(Op.DestRange.getBegin(), CastExpr->getLocEnd());
bool CastNodesCreated = false; Op.CheckCXXCStyleCast(/*FunctionalStyle=*/ true);
Op.CheckCXXCStyleCast(/*FunctionalStyle=*/ true, CastNodesCreated);
if (Op.SrcExpr.isInvalid()) if (Op.SrcExpr.isInvalid())
return ExprError(); return ExprError();
// CheckCXXCStyleCast _may_ have already created the CXXFunctionalCastExpr
// node. Let's check.
if (CastNodesCreated) {
if (CXXFunctionalCastExpr *Cast =
dyn_cast<CXXFunctionalCastExpr>(Op.SrcExpr.get())){
assert(!Cast->getTypeInfoAsWritten() &&
"The explicit cast node created by CheckStaticCast "
"has source type infos!");
Cast->setTypeInfoAsWritten(CastTypeInfo);
Cast->setTypeBeginLoc(Op.DestRange.getBegin());
Cast->setRParenLoc(RPLoc);
return Op.complete(Cast);
}
}
return Op.complete(CXXFunctionalCastExpr::Create(Context, Op.ResultType, return Op.complete(CXXFunctionalCastExpr::Create(Context, Op.ResultType,
Op.ValueKind, CastTypeInfo, Op.DestRange.getBegin(), Op.ValueKind, CastTypeInfo, Op.DestRange.getBegin(),
Op.Kind, Op.SrcExpr.take(), &Op.BasePath, RPLoc)); Op.Kind, Op.SrcExpr.take(), &Op.BasePath, RPLoc));
} }

View File

@ -2125,7 +2125,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
CheckedConversionKind CCK) { CheckedConversionKind CCK) {
switch (ICS.getKind()) { switch (ICS.getKind()) {
case ImplicitConversionSequence::StandardConversion: { case ImplicitConversionSequence::StandardConversion: {
ExprResult Res = PerformConversion(From, ToType, ICS.Standard, ExprResult Res = PerformImplicitConversion(From, ToType, ICS.Standard,
Action, CCK); Action, CCK);
if (Res.isInvalid()) if (Res.isInvalid())
return ExprError(); return ExprError();
@ -2160,8 +2160,9 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
// Watch out for elipsis conversion. // Watch out for elipsis conversion.
if (!ICS.UserDefined.EllipsisConversion) { if (!ICS.UserDefined.EllipsisConversion) {
ExprResult Res = ExprResult Res =
PerformConversion(From, BeforeToType, PerformImplicitConversion(From, BeforeToType,
ICS.UserDefined.Before, AA_Converting, CCK); ICS.UserDefined.Before, AA_Converting,
CCK);
if (Res.isInvalid()) if (Res.isInvalid())
return ExprError(); return ExprError();
From = Res.take(); From = Res.take();
@ -2181,7 +2182,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
From = CastArg.take(); From = CastArg.take();
return PerformConversion(From, ToType, ICS.UserDefined.After, return PerformImplicitConversion(From, ToType, ICS.UserDefined.After,
AA_Converting, CCK); AA_Converting, CCK);
} }
@ -2202,13 +2203,13 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
return Owned(From); return Owned(From);
} }
/// PerformConversion - Perform a conversion of the /// PerformImplicitConversion - Perform an implicit conversion of the
/// expression From to the type ToType by following the standard /// expression From to the type ToType by following the standard
/// conversion sequence SCS. Returns the converted /// conversion sequence SCS. Returns the converted
/// expression. Flavor is the context in which we're performing this /// expression. Flavor is the context in which we're performing this
/// conversion, for use in error messages. /// conversion, for use in error messages.
ExprResult ExprResult
Sema::PerformConversion(Expr *From, QualType ToType, Sema::PerformImplicitConversion(Expr *From, QualType ToType,
const StandardConversionSequence& SCS, const StandardConversionSequence& SCS,
AssignmentAction Action, AssignmentAction Action,
CheckedConversionKind CCK) { CheckedConversionKind CCK) {
@ -2262,7 +2263,7 @@ Sema::PerformConversion(Expr *From, QualType ToType,
FromType = From->getType(); FromType = From->getType();
} }
// Perform the first conversion step. // Perform the first implicit conversion.
switch (SCS.First) { switch (SCS.First) {
case ICK_Identity: case ICK_Identity:
// Nothing to do. // Nothing to do.
@ -2277,13 +2278,13 @@ Sema::PerformConversion(Expr *From, QualType ToType,
case ICK_Array_To_Pointer: case ICK_Array_To_Pointer:
FromType = Context.getArrayDecayedType(FromType); FromType = Context.getArrayDecayedType(FromType);
From = CastExprToType(From, FromType, CK_ArrayToPointerDecay, From = ImpCastExprToType(From, FromType, CK_ArrayToPointerDecay,
VK_RValue, /*BasePath=*/0, CCK).take(); VK_RValue, /*BasePath=*/0, CCK).take();
break; break;
case ICK_Function_To_Pointer: case ICK_Function_To_Pointer:
FromType = Context.getPointerType(FromType); FromType = Context.getPointerType(FromType);
From = CastExprToType(From, FromType, CK_FunctionToPointerDecay, From = ImpCastExprToType(From, FromType, CK_FunctionToPointerDecay,
VK_RValue, /*BasePath=*/0, CCK).take(); VK_RValue, /*BasePath=*/0, CCK).take();
break; break;
@ -2291,7 +2292,7 @@ Sema::PerformConversion(Expr *From, QualType ToType,
llvm_unreachable("Improper first standard conversion"); llvm_unreachable("Improper first standard conversion");
} }
// Perform the second conversion step // Perform the second implicit conversion
switch (SCS.Second) { switch (SCS.Second) {
case ICK_Identity: case ICK_Identity:
// If both sides are functions (or pointers/references to them), there could // If both sides are functions (or pointers/references to them), there could
@ -2307,19 +2308,19 @@ Sema::PerformConversion(Expr *From, QualType ToType,
if (CheckExceptionSpecCompatibility(From, ToType)) if (CheckExceptionSpecCompatibility(From, ToType))
return ExprError(); return ExprError();
From = CastExprToType(From, ToType, CK_NoOp, From = ImpCastExprToType(From, ToType, CK_NoOp,
VK_RValue, /*BasePath=*/0, CCK).take(); VK_RValue, /*BasePath=*/0, CCK).take();
break; break;
case ICK_Integral_Promotion: case ICK_Integral_Promotion:
case ICK_Integral_Conversion: case ICK_Integral_Conversion:
From = CastExprToType(From, ToType, CK_IntegralCast, From = ImpCastExprToType(From, ToType, CK_IntegralCast,
VK_RValue, /*BasePath=*/0, CCK).take(); VK_RValue, /*BasePath=*/0, CCK).take();
break; break;
case ICK_Floating_Promotion: case ICK_Floating_Promotion:
case ICK_Floating_Conversion: case ICK_Floating_Conversion:
From = CastExprToType(From, ToType, CK_FloatingCast, From = ImpCastExprToType(From, ToType, CK_FloatingCast,
VK_RValue, /*BasePath=*/0, CCK).take(); VK_RValue, /*BasePath=*/0, CCK).take();
break; break;
@ -2338,22 +2339,22 @@ Sema::PerformConversion(Expr *From, QualType ToType,
} else { } else {
CK = CK_IntegralComplexCast; CK = CK_IntegralComplexCast;
} }
From = CastExprToType(From, ToType, CK, From = ImpCastExprToType(From, ToType, CK,
VK_RValue, /*BasePath=*/0, CCK).take(); VK_RValue, /*BasePath=*/0, CCK).take();
break; break;
} }
case ICK_Floating_Integral: case ICK_Floating_Integral:
if (ToType->isRealFloatingType()) if (ToType->isRealFloatingType())
From = CastExprToType(From, ToType, CK_IntegralToFloating, From = ImpCastExprToType(From, ToType, CK_IntegralToFloating,
VK_RValue, /*BasePath=*/0, CCK).take(); VK_RValue, /*BasePath=*/0, CCK).take();
else else
From = CastExprToType(From, ToType, CK_FloatingToIntegral, From = ImpCastExprToType(From, ToType, CK_FloatingToIntegral,
VK_RValue, /*BasePath=*/0, CCK).take(); VK_RValue, /*BasePath=*/0, CCK).take();
break; break;
case ICK_Compatible_Conversion: case ICK_Compatible_Conversion:
From = CastExprToType(From, ToType, CK_NoOp, From = ImpCastExprToType(From, ToType, CK_NoOp,
VK_RValue, /*BasePath=*/0, CCK).take(); VK_RValue, /*BasePath=*/0, CCK).take();
break; break;
@ -2402,7 +2403,8 @@ Sema::PerformConversion(Expr *From, QualType ToType,
From = E.take(); From = E.take();
} }
From = CastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCK).take(); From = ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCK)
.take();
break; break;
} }
@ -2413,7 +2415,8 @@ Sema::PerformConversion(Expr *From, QualType ToType,
return ExprError(); return ExprError();
if (CheckExceptionSpecCompatibility(From, ToType)) if (CheckExceptionSpecCompatibility(From, ToType))
return ExprError(); return ExprError();
From = CastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCK).take(); From = ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCK)
.take();
break; break;
} }
@ -2424,7 +2427,7 @@ Sema::PerformConversion(Expr *From, QualType ToType,
FromType = Context.FloatTy; FromType = Context.FloatTy;
} }
From = CastExprToType(From, Context.BoolTy, From = ImpCastExprToType(From, Context.BoolTy,
ScalarTypeToBooleanCastKind(FromType), ScalarTypeToBooleanCastKind(FromType),
VK_RValue, /*BasePath=*/0, CCK).take(); VK_RValue, /*BasePath=*/0, CCK).take();
break; break;
@ -2439,19 +2442,19 @@ Sema::PerformConversion(Expr *From, QualType ToType,
CStyle)) CStyle))
return ExprError(); return ExprError();
From = CastExprToType(From, ToType.getNonReferenceType(), From = ImpCastExprToType(From, ToType.getNonReferenceType(),
CK_DerivedToBase, From->getValueKind(), CK_DerivedToBase, From->getValueKind(),
&BasePath, CCK).take(); &BasePath, CCK).take();
break; break;
} }
case ICK_Vector_Conversion: case ICK_Vector_Conversion:
From = CastExprToType(From, ToType, CK_BitCast, From = ImpCastExprToType(From, ToType, CK_BitCast,
VK_RValue, /*BasePath=*/0, CCK).take(); VK_RValue, /*BasePath=*/0, CCK).take();
break; break;
case ICK_Vector_Splat: case ICK_Vector_Splat:
From = CastExprToType(From, ToType, CK_VectorSplat, From = ImpCastExprToType(From, ToType, CK_VectorSplat,
VK_RValue, /*BasePath=*/0, CCK).take(); VK_RValue, /*BasePath=*/0, CCK).take();
break; break;
@ -2465,22 +2468,17 @@ Sema::PerformConversion(Expr *From, QualType ToType,
if (Context.hasSameUnqualifiedType(ElType, From->getType())) { if (Context.hasSameUnqualifiedType(ElType, From->getType())) {
// do nothing // do nothing
} else if (From->getType()->isRealFloatingType()) { } else if (From->getType()->isRealFloatingType()) {
From = CastExprToType(From, ElType, From = ImpCastExprToType(From, ElType,
isFloatingComplex ? CK_FloatingCast isFloatingComplex ? CK_FloatingCast : CK_FloatingToIntegral).take();
: CK_FloatingToIntegral,
VK_RValue, /*BasePath=*/0, CCK).take();
} else { } else {
assert(From->getType()->isIntegerType()); assert(From->getType()->isIntegerType());
From = CastExprToType(From, ElType, From = ImpCastExprToType(From, ElType,
isFloatingComplex ? CK_IntegralToFloating isFloatingComplex ? CK_IntegralToFloating : CK_IntegralCast).take();
: CK_IntegralCast,
VK_RValue, /*BasePath=*/0, CCK).take();
} }
// y -> _Complex y // y -> _Complex y
From = CastExprToType(From, ToType, From = ImpCastExprToType(From, ToType,
isFloatingComplex ? CK_FloatingRealToComplex isFloatingComplex ? CK_FloatingRealToComplex
: CK_IntegralRealToComplex, : CK_IntegralRealToComplex).take();
VK_RValue, /*BasePath=*/ 0, CCK).take();
// Case 2. _Complex x -> y // Case 2. _Complex x -> y
} else { } else {
@ -2491,7 +2489,7 @@ Sema::PerformConversion(Expr *From, QualType ToType,
bool isFloatingComplex = ElType->isRealFloatingType(); bool isFloatingComplex = ElType->isRealFloatingType();
// _Complex x -> x // _Complex x -> x
From = CastExprToType(From, ElType, From = ImpCastExprToType(From, ElType,
isFloatingComplex ? CK_FloatingComplexToReal isFloatingComplex ? CK_FloatingComplexToReal
: CK_IntegralComplexToReal, : CK_IntegralComplexToReal,
VK_RValue, /*BasePath=*/0, CCK).take(); VK_RValue, /*BasePath=*/0, CCK).take();
@ -2500,22 +2498,20 @@ Sema::PerformConversion(Expr *From, QualType ToType,
if (Context.hasSameUnqualifiedType(ElType, ToType)) { if (Context.hasSameUnqualifiedType(ElType, ToType)) {
// do nothing // do nothing
} else if (ToType->isRealFloatingType()) { } else if (ToType->isRealFloatingType()) {
From = CastExprToType(From, ToType, From = ImpCastExprToType(From, ToType,
isFloatingComplex ? CK_FloatingCast isFloatingComplex ? CK_FloatingCast : CK_IntegralToFloating,
: CK_IntegralToFloating,
VK_RValue, /*BasePath=*/0, CCK).take(); VK_RValue, /*BasePath=*/0, CCK).take();
} else { } else {
assert(ToType->isIntegerType()); assert(ToType->isIntegerType());
From = CastExprToType(From, ToType, From = ImpCastExprToType(From, ToType,
isFloatingComplex ? CK_FloatingToIntegral isFloatingComplex ? CK_FloatingToIntegral : CK_IntegralCast,
: CK_IntegralCast,
VK_RValue, /*BasePath=*/0, CCK).take(); VK_RValue, /*BasePath=*/0, CCK).take();
} }
} }
break; break;
case ICK_Block_Pointer_Conversion: { case ICK_Block_Pointer_Conversion: {
From = CastExprToType(From, ToType.getUnqualifiedType(), CK_BitCast, From = ImpCastExprToType(From, ToType.getUnqualifiedType(), CK_BitCast,
VK_RValue, /*BasePath=*/0, CCK).take(); VK_RValue, /*BasePath=*/0, CCK).take();
break; break;
} }
@ -2551,7 +2547,7 @@ Sema::PerformConversion(Expr *From, QualType ToType,
// target type isn't a reference. // target type isn't a reference.
ExprValueKind VK = ToType->isReferenceType() ? ExprValueKind VK = ToType->isReferenceType() ?
From->getValueKind() : VK_RValue; From->getValueKind() : VK_RValue;
From = CastExprToType(From, ToType.getNonLValueExprType(Context), From = ImpCastExprToType(From, ToType.getNonLValueExprType(Context),
CK_NoOp, VK, /*BasePath=*/0, CCK).take(); CK_NoOp, VK, /*BasePath=*/0, CCK).take();
if (SCS.DeprecatedStringLiteralToCharPtr && if (SCS.DeprecatedStringLiteralToCharPtr &&

View File

@ -4863,7 +4863,7 @@ InitializationSequence::Perform(Sema &S,
Sema::CheckedConversionKind CCK Sema::CheckedConversionKind CCK
= Kind.isCStyleCast()? Sema::CCK_CStyleCast = Kind.isCStyleCast()? Sema::CCK_CStyleCast
: Kind.isFunctionalCast()? Sema::CCK_FunctionalCast : Kind.isFunctionalCast()? Sema::CCK_FunctionalCast
: Kind.isStaticCast()? Sema::CCK_StaticCast : Kind.isExplicitCast()? Sema::CCK_OtherCast
: Sema::CCK_ImplicitConversion; : Sema::CCK_ImplicitConversion;
ExprResult CurInitExprRes = ExprResult CurInitExprRes =
S.PerformImplicitConversion(CurInit.get(), Step->Type, *Step->ICS, S.PerformImplicitConversion(CurInit.get(), Step->Type, *Step->ICS,

View File

@ -9,6 +9,7 @@ int main() { }
// CHECK: preamble_macro_template.h:4:16: CompoundStmt= Extent=[4:16 - 6:2] // CHECK: preamble_macro_template.h:4:16: CompoundStmt= Extent=[4:16 - 6:2]
// CHECK: preamble_macro_template.h:5:3: CStyleCastExpr= Extent=[5:3 - 5:27] // CHECK: preamble_macro_template.h:5:3: CStyleCastExpr= Extent=[5:3 - 5:27]
// CHECK: preamble_macro_template.h:1:21: CXXStaticCastExpr= Extent=[1:21 - 5:27] // CHECK: preamble_macro_template.h:1:21: CXXStaticCastExpr= Extent=[1:21 - 5:27]
// CHECK: preamble_macro_template.h:5:25: UnexposedExpr= Extent=[5:25 - 5:26]
// CHECK: preamble_macro_template.h:5:25: IntegerLiteral= Extent=[5:25 - 5:26] // CHECK: preamble_macro_template.h:5:25: IntegerLiteral= Extent=[5:25 - 5:26]
// CHECK: preamble_macro_template.cpp:3:5: FunctionDecl=main:3:5 (Definition) Extent=[3:1 - 3:15] // CHECK: preamble_macro_template.cpp:3:5: FunctionDecl=main:3:5 (Definition) Extent=[3:1 - 3:15]
// CHECK: preamble_macro_template.cpp:3:12: CompoundStmt= Extent=[3:12 - 3:15] // CHECK: preamble_macro_template.cpp:3:12: CompoundStmt= Extent=[3:12 - 3:15]

View File

@ -1632,6 +1632,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
// CHECK: 41:30: UnaryOperator= Extent=[41:30 - 41:40] // CHECK: 41:30: UnaryOperator= Extent=[41:30 - 41:40]
// CHECK: 41:31: CXXFunctionalCastExpr= Extent=[41:31 - 41:40] // CHECK: 41:31: CXXFunctionalCastExpr= Extent=[41:31 - 41:40]
// CHECK: 41:31: TypeRef=size_t:2:25 Extent=[41:31 - 41:37] // CHECK: 41:31: TypeRef=size_t:2:25 Extent=[41:31 - 41:37]
// CHECK: 41:38: UnexposedExpr= Extent=[41:38 - 41:39]
// CHECK: 41:38: IntegerLiteral= Extent=[41:38 - 41:39] // CHECK: 41:38: IntegerLiteral= Extent=[41:38 - 41:39]
// CHECK: 42:1: CXXAccessSpecifier=:42:1 (Definition) Extent=[42:1 - 42:9] // CHECK: 42:1: CXXAccessSpecifier=:42:1 (Definition) Extent=[42:1 - 42:9]
// CHECK: 43:15: FieldDecl=Data:43:15 (Definition) Extent=[43:3 - 43:19] // CHECK: 43:15: FieldDecl=Data:43:15 (Definition) Extent=[43:3 - 43:19]
@ -1803,6 +1804,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
// CHECK: 75:13: ParenExpr= Extent=[75:13 - 75:30] // CHECK: 75:13: ParenExpr= Extent=[75:13 - 75:30]
// CHECK: 75:14: CStyleCastExpr= Extent=[75:14 - 75:29] // CHECK: 75:14: CStyleCastExpr= Extent=[75:14 - 75:29]
// CHECK: 75:25: UnexposedExpr= Extent=[75:25 - 75:29] // CHECK: 75:25: UnexposedExpr= Extent=[75:25 - 75:29]
// CHECK: 75:25: UnexposedExpr= Extent=[75:25 - 75:29]
// CHECK: 75:25: ArraySubscriptExpr= Extent=[75:25 - 75:29] // CHECK: 75:25: ArraySubscriptExpr= Extent=[75:25 - 75:29]
// CHECK: 75:25: DeclRefExpr=p:74:17 Extent=[75:25 - 75:26] // CHECK: 75:25: DeclRefExpr=p:74:17 Extent=[75:25 - 75:26]
// CHECK: 75:27: IntegerLiteral= Extent=[75:27 - 75:28] // CHECK: 75:27: IntegerLiteral= Extent=[75:27 - 75:28]
@ -1811,6 +1813,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
// CHECK: 75:34: ParenExpr= Extent=[75:34 - 75:51] // CHECK: 75:34: ParenExpr= Extent=[75:34 - 75:51]
// CHECK: 75:35: CStyleCastExpr= Extent=[75:35 - 75:50] // CHECK: 75:35: CStyleCastExpr= Extent=[75:35 - 75:50]
// CHECK: 75:46: UnexposedExpr= Extent=[75:46 - 75:50] // CHECK: 75:46: UnexposedExpr= Extent=[75:46 - 75:50]
// CHECK: 75:46: UnexposedExpr= Extent=[75:46 - 75:50]
// CHECK: 75:46: ArraySubscriptExpr= Extent=[75:46 - 75:50] // CHECK: 75:46: ArraySubscriptExpr= Extent=[75:46 - 75:50]
// CHECK: 75:46: DeclRefExpr=p:74:17 Extent=[75:46 - 75:47] // CHECK: 75:46: DeclRefExpr=p:74:17 Extent=[75:46 - 75:47]
// CHECK: 75:48: IntegerLiteral= Extent=[75:48 - 75:49] // CHECK: 75:48: IntegerLiteral= Extent=[75:48 - 75:49]