aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Sema/Initialization.h2
-rw-r--r--include/clang/Sema/Sema.h164
-rw-r--r--lib/Sema/Sema.cpp20
-rw-r--r--lib/Sema/SemaCXXCast.cpp226
-rw-r--r--lib/Sema/SemaChecking.cpp38
-rw-r--r--lib/Sema/SemaCodeComplete.cpp8
-rw-r--r--lib/Sema/SemaDecl.cpp6
-rw-r--r--lib/Sema/SemaDeclCXX.cpp24
-rw-r--r--lib/Sema/SemaExpr.cpp1454
-rw-r--r--lib/Sema/SemaExprCXX.cpp515
-rw-r--r--lib/Sema/SemaExprObjC.cpp65
-rw-r--r--lib/Sema/SemaInit.cpp157
-rw-r--r--lib/Sema/SemaOverload.cpp338
-rw-r--r--lib/Sema/SemaStmt.cpp56
-rw-r--r--lib/Sema/SemaTemplate.cpp124
-rw-r--r--lib/Sema/SemaType.cpp9
-rw-r--r--lib/Sema/TreeTransform.h56
17 files changed, 1856 insertions, 1406 deletions
diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h
index 7ccd27201c..a7caf00ce4 100644
--- a/include/clang/Sema/Initialization.h
+++ b/include/clang/Sema/Initialization.h
@@ -597,6 +597,8 @@ public:
FK_ReferenceInitFailed,
/// \brief Implicit conversion failed.
FK_ConversionFailed,
+ /// \brief Implicit conversion failed.
+ FK_ConversionFromPropertyFailed,
/// \brief Too many initializers for scalar
FK_TooManyInitsForScalar,
/// \brief Reference initialization from an initializer list
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 356ffed694..ccf99671a5 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -1161,13 +1161,13 @@ public:
ExprResult PerformCopyInitialization(const InitializedEntity &Entity,
SourceLocation EqualLoc,
ExprResult Init);
- bool PerformObjectArgumentInitialization(Expr *&From,
- NestedNameSpecifier *Qualifier,
- NamedDecl *FoundDecl,
- CXXMethodDecl *Method);
+ ExprResult PerformObjectArgumentInitialization(Expr *From,
+ NestedNameSpecifier *Qualifier,
+ NamedDecl *FoundDecl,
+ CXXMethodDecl *Method);
- bool PerformContextuallyConvertToBool(Expr *&From);
- bool PerformContextuallyConvertToObjCId(Expr *&From);
+ ExprResult PerformContextuallyConvertToBool(Expr *From);
+ ExprResult PerformContextuallyConvertToObjCId(Expr *From);
ExprResult
ConvertToIntegralOrEnumerationType(SourceLocation Loc, Expr *FromE,
@@ -1179,10 +1179,10 @@ public:
const PartialDiagnostic &AmbigNote,
const PartialDiagnostic &ConvDiag);
- bool PerformObjectMemberConversion(Expr *&From,
- NestedNameSpecifier *Qualifier,
- NamedDecl *FoundDecl,
- NamedDecl *Member);
+ ExprResult PerformObjectMemberConversion(Expr *From,
+ NestedNameSpecifier *Qualifier,
+ NamedDecl *FoundDecl,
+ NamedDecl *Member);
// Members have to be NamespaceDecl* or TranslationUnitDecl*.
// TODO: make this is a typesafe union.
@@ -2049,7 +2049,7 @@ public:
const TemplateArgumentListInfo *TemplateArgs,
bool SuppressQualifierCheck = false);
- ExprResult LookupMemberExpr(LookupResult &R, Expr *&Base,
+ ExprResult LookupMemberExpr(LookupResult &R, ExprResult &Base,
bool &IsArrow, SourceLocation OpLoc,
CXXScopeSpec &SS,
Decl *ObjCImpDecl,
@@ -2474,7 +2474,7 @@ public:
//// ActOnCXXThrow - Parse throw expressions.
ExprResult ActOnCXXThrow(SourceLocation OpLoc, Expr *expr);
- bool CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *&E);
+ ExprResult CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *E);
/// ActOnCXXTypeConstructExpr - Parse construction of a specified type.
/// Can be interpreted either as function-style casting ("int(x)")
@@ -3387,10 +3387,10 @@ public:
TypeSourceInfo *Arg);
bool CheckTemplateArgumentPointerToMember(Expr *Arg,
TemplateArgument &Converted);
- bool CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
- QualType InstantiatedParamType, Expr *&Arg,
- TemplateArgument &Converted,
- CheckTemplateArgumentKind CTAK = CTAK_Specified);
+ ExprResult CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
+ QualType InstantiatedParamType, Expr *Arg,
+ TemplateArgument &Converted,
+ CheckTemplateArgumentKind CTAK = CTAK_Specified);
bool CheckTemplateArgument(TemplateTemplateParmDecl *Param,
const TemplateArgumentLoc &Arg);
@@ -4745,9 +4745,9 @@ public:
/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit
/// cast. If there is already an implicit cast, merge into the existing one.
/// If isLvalue, the result of the cast is an lvalue.
- void ImpCastExprToType(Expr *&Expr, QualType Type, CastKind CK,
- ExprValueKind VK = VK_RValue,
- const CXXCastPath *BasePath = 0);
+ ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK,
+ ExprValueKind VK = VK_RValue,
+ const CXXCastPath *BasePath = 0);
/// ScalarTypeToBooleanCastKind - Returns the cast kind corresponding
/// to the conversion from scalar type ScalarTy to the Boolean type.
@@ -4756,31 +4756,31 @@ public:
/// IgnoredValueConversions - Given that an expression's result is
/// syntactically ignored, perform any conversions that are
/// required.
- void IgnoredValueConversions(Expr *&expr);
+ ExprResult IgnoredValueConversions(Expr *E);
// UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
// functions and arrays to their respective pointers (C99 6.3.2.1).
- Expr *UsualUnaryConversions(Expr *&expr);
+ ExprResult UsualUnaryConversions(Expr *E);
// DefaultFunctionArrayConversion - converts functions and arrays
// to their respective pointers (C99 6.3.2.1).
- void DefaultFunctionArrayConversion(Expr *&expr);
+ ExprResult DefaultFunctionArrayConversion(Expr *E);
// DefaultFunctionArrayLvalueConversion - converts functions and
// arrays to their respective pointers and performs the
// lvalue-to-rvalue conversion.
- void DefaultFunctionArrayLvalueConversion(Expr *&expr);
+ ExprResult DefaultFunctionArrayLvalueConversion(Expr *E);
// DefaultLvalueConversion - performs lvalue-to-rvalue conversion on
// the operand. This is DefaultFunctionArrayLvalueConversion,
// except that it assumes the operand isn't of function or array
// type.
- void DefaultLvalueConversion(Expr *&expr);
+ ExprResult DefaultLvalueConversion(Expr *E);
// DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that
// do not have a prototype. Integer promotions are performed on each
// argument, and arguments that have type float are promoted to double.
- void DefaultArgumentPromotion(Expr *&Expr);
+ ExprResult DefaultArgumentPromotion(Expr *E);
// Used for emitting the right warning by DefaultVariadicArgumentPromotion
enum VariadicCallType {
@@ -4803,15 +4803,15 @@ public:
// DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but
// will warn if the resulting type is not a POD type.
- bool DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT,
- FunctionDecl *FDecl);
+ ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT,
+ FunctionDecl *FDecl);
// UsualArithmeticConversions - performs the UsualUnaryConversions on it's
// operands and then handles various conversions that are common to binary
// operators (C99 6.3.1.8). If both operands aren't arithmetic, this
// routine returns the first non-arithmetic type found. The client is
// responsible for emitting appropriate error diagnostics.
- QualType UsualArithmeticConversions(Expr *&lExpr, Expr *&rExpr,
+ QualType UsualArithmeticConversions(ExprResult &lExpr, ExprResult &rExpr,
bool isCompAssign = false);
/// AssignConvertType - All of the 'assignment' semantic checks return this
@@ -4899,94 +4899,102 @@ public:
/// Check assignment constraints and prepare for a conversion of the
/// RHS to the LHS type.
- AssignConvertType CheckAssignmentConstraints(QualType lhs, Expr *&rhs,
+ AssignConvertType CheckAssignmentConstraints(QualType lhs, ExprResult &rhs,
CastKind &Kind);
// CheckSingleAssignmentConstraints - Currently used by
// CheckAssignmentOperands, and ActOnReturnStmt. Prior to type checking,
// this routine performs the default function/array converions.
AssignConvertType CheckSingleAssignmentConstraints(QualType lhs,
- Expr *&rExpr);
+ ExprResult &rExprRes);
// \brief If the lhs type is a transparent union, check whether we
// can initialize the transparent union with the given expression.
AssignConvertType CheckTransparentUnionArgumentConstraints(QualType lhs,
- Expr *&rExpr);
+ ExprResult &rExpr);
bool IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType);
bool CheckExceptionSpecCompatibility(Expr *From, QualType ToType);
- bool PerformImplicitConversion(Expr *&From, QualType ToType,
- AssignmentAction Action,
- bool AllowExplicit = false);
- bool PerformImplicitConversion(Expr *&From, QualType ToType,
- AssignmentAction Action,
- bool AllowExplicit,
- ImplicitConversionSequence& ICS);
- bool PerformImplicitConversion(Expr *&From, QualType ToType,
- const ImplicitConversionSequence& ICS,
- AssignmentAction Action,
- bool CStyle = false);
- bool PerformImplicitConversion(Expr *&From, QualType ToType,
- const StandardConversionSequence& SCS,
- AssignmentAction Action,
- bool CStyle);
+ ExprResult PerformImplicitConversion(Expr *From, QualType ToType,
+ AssignmentAction Action,
+ bool AllowExplicit = false);
+ ExprResult PerformImplicitConversion(Expr *From, QualType ToType,
+ AssignmentAction Action,
+ bool AllowExplicit,
+ ImplicitConversionSequence& ICS);
+ ExprResult PerformImplicitConversion(Expr *From, QualType ToType,
+ const ImplicitConversionSequence& ICS,
+ AssignmentAction Action,
+ bool CStyle = false);
+ ExprResult PerformImplicitConversion(Expr *From, QualType ToType,
+ const StandardConversionSequence& SCS,
+ AssignmentAction Action,
+ bool CStyle);
/// the following "Check" methods will return a valid/converted QualType
/// or a null QualType (indicating an error diagnostic was issued).
/// type checking binary operators (subroutines of CreateBuiltinBinOp).
- QualType InvalidOperands(SourceLocation l, Expr *&lex, Expr *&rex);
+ QualType InvalidOperands(SourceLocation l, ExprResult &lex, ExprResult &rex);
QualType CheckPointerToMemberOperands( // C++ 5.5
- Expr *&lex, Expr *&rex, ExprValueKind &VK,
+ ExprResult &lex, ExprResult &rex, ExprValueKind &VK,
SourceLocation OpLoc, bool isIndirect);
QualType CheckMultiplyDivideOperands( // C99 6.5.5
- Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign,
+ ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, bool isCompAssign,
bool isDivide);
QualType CheckRemainderOperands( // C99 6.5.5
- Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
+ ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, bool isCompAssign = false);
QualType CheckAdditionOperands( // C99 6.5.6
- Expr *&lex, Expr *&rex, SourceLocation OpLoc, QualType* CompLHSTy = 0);
+ ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, QualType* CompLHSTy = 0);
QualType CheckSubtractionOperands( // C99 6.5.6
- Expr *&lex, Expr *&rex, SourceLocation OpLoc, QualType* CompLHSTy = 0);
+ ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, QualType* CompLHSTy = 0);
QualType CheckShiftOperands( // C99 6.5.7
- Expr *&lex, Expr *&rex, SourceLocation OpLoc, unsigned Opc,
+ ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, unsigned Opc,
bool isCompAssign = false);
QualType CheckCompareOperands( // C99 6.5.8/9
- Expr *&lex, Expr *&rex, SourceLocation OpLoc, unsigned Opc,
+ ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, unsigned Opc,
bool isRelational);
QualType CheckBitwiseOperands( // C99 6.5.[10...12]
- Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
+ ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, bool isCompAssign = false);
QualType CheckLogicalOperands( // C99 6.5.[13,14]
- Expr *&lex, Expr *&rex, SourceLocation OpLoc, unsigned Opc);
+ ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, unsigned Opc);
// CheckAssignmentOperands is used for both simple and compound assignment.
// For simple assignment, pass both expressions and a null converted type.
// For compound assignment, pass both expressions and the converted type.
QualType CheckAssignmentOperands( // C99 6.5.16.[1,2]
- Expr *lex, Expr *&rex, SourceLocation OpLoc, QualType convertedType);
+ Expr *lex, ExprResult &rex, SourceLocation OpLoc, QualType convertedType);
- void ConvertPropertyForRValue(Expr *&E);
- void ConvertPropertyForLValue(Expr *&LHS, Expr *&RHS, QualType& LHSTy);
+ void ConvertPropertyForLValue(ExprResult &LHS, ExprResult &RHS, QualType& LHSTy);
+ ExprResult ConvertPropertyForRValue(Expr *E);
QualType CheckConditionalOperands( // C99 6.5.15
- Expr *&cond, Expr *&lhs, Expr *&rhs,
+ ExprResult &cond, ExprResult &lhs, ExprResult &rhs,
ExprValueKind &VK, ExprObjectKind &OK, SourceLocation questionLoc);
QualType CXXCheckConditionalOperands( // C++ 5.16
- Expr *&cond, Expr *&lhs, Expr *&rhs,
+ ExprResult &cond, ExprResult &lhs, ExprResult &rhs,
ExprValueKind &VK, ExprObjectKind &OK, SourceLocation questionLoc);
QualType FindCompositePointerType(SourceLocation Loc, Expr *&E1, Expr *&E2,
bool *NonStandardCompositeType = 0);
+ QualType FindCompositePointerType(SourceLocation Loc, ExprResult &E1, ExprResult &E2,
+ bool *NonStandardCompositeType = 0) {
+ Expr *E1Tmp = E1.take(), *E2Tmp = E2.take();
+ QualType Composite = FindCompositePointerType(Loc, E1Tmp, E2Tmp, NonStandardCompositeType);
+ E1 = Owned(E1Tmp);
+ E2 = Owned(E2Tmp);
+ return Composite;
+ }
- QualType FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS,
+ QualType FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS,
SourceLocation questionLoc);
bool DiagnoseConditionalForNull(Expr *LHS, Expr *RHS,
SourceLocation QuestionLoc);
/// type checking for vector binary operators.
- QualType CheckVectorOperands(SourceLocation l, Expr *&lex, Expr *&rex);
- QualType CheckVectorCompareOperands(Expr *&lex, Expr *&rx,
+ QualType CheckVectorOperands(SourceLocation l, ExprResult &lex, ExprResult &rex);
+ QualType CheckVectorCompareOperands(ExprResult &lex, ExprResult &rx,
SourceLocation l, bool isRel);
/// type checking declaration initializers (C99 6.7.8)
@@ -5024,13 +5032,13 @@ public:
/// CheckCastTypes - Check type constraints for casting between types under
/// C semantics, or forward to CXXCheckCStyleCast in C++.
- bool CheckCastTypes(SourceRange TyRange, QualType CastTy, Expr *&CastExpr,
- CastKind &Kind, ExprValueKind &VK, CXXCastPath &BasePath,
- bool FunctionalStyle = false);
+ ExprResult CheckCastTypes(SourceRange TyRange, QualType CastTy, Expr *CastExpr,
+ CastKind &Kind, ExprValueKind &VK, CXXCastPath &BasePath,
+ bool FunctionalStyle = false);
- bool checkUnknownAnyCast(SourceRange TyRange, QualType castType,
- Expr *&castExpr, CastKind &castKind,
- ExprValueKind &valueKind, CXXCastPath &BasePath);
+ ExprResult checkUnknownAnyCast(SourceRange TyRange, QualType castType,
+ Expr *castExpr, CastKind &castKind,
+ ExprValueKind &valueKind, CXXCastPath &BasePath);
// CheckVectorCast - check type constraints for vectors.
// Since vectors are an extension, there are no C standard reference for this.
@@ -5043,15 +5051,15 @@ public:
// Since vectors are an extension, there are no C standard reference for this.
// We allow casting between vectors and integer datatypes of the same size,
// or vectors and the element type of that vector.
- // returns true if the cast is invalid
- bool CheckExtVectorCast(SourceRange R, QualType VectorTy, Expr *&CastExpr,
- CastKind &Kind);
+ // returns the cast expr
+ ExprResult CheckExtVectorCast(SourceRange R, QualType VectorTy, Expr *CastExpr,
+ CastKind &Kind);
/// CXXCheckCStyleCast - Check constraints of a C-style or function-style
/// cast under C++ semantics.
- bool CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK,
- Expr *&CastExpr, CastKind &Kind,
- CXXCastPath &BasePath, bool FunctionalStyle);
+ ExprResult CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK,
+ Expr *CastExpr, CastKind &Kind,
+ CXXCastPath &BasePath, bool FunctionalStyle);
/// CheckMessageArgumentTypes - Check types in an Obj-C message send.
/// \param Method - May be null.
@@ -5070,7 +5078,7 @@ public:
/// \param Loc - A location associated with the condition, e.g. the
/// 'if' keyword.
/// \return true iff there were any errors
- bool CheckBooleanCondition(Expr *&CondExpr, SourceLocation Loc);
+ ExprResult CheckBooleanCondition(Expr *CondExpr, SourceLocation Loc);
ExprResult ActOnBooleanCondition(Scope *S, SourceLocation Loc,
Expr *SubExpr);
@@ -5084,7 +5092,7 @@ public:
void DiagnoseEqualityWithExtraParens(ParenExpr *parenE);
/// CheckCXXBooleanCondition - Returns true if conversion to bool is invalid.
- bool CheckCXXBooleanCondition(Expr *&CondExpr);
+ ExprResult CheckCXXBooleanCondition(Expr *CondExpr);
/// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have
/// the specified width and sign. If an overflow occurs, detect it and emit
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 0e783018ec..a83722d824 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -203,36 +203,36 @@ Sema::~Sema() {
/// 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.
-void Sema::ImpCastExprToType(Expr *&Expr, QualType Ty,
- CastKind Kind, ExprValueKind VK,
- const CXXCastPath *BasePath) {
- QualType ExprTy = Context.getCanonicalType(Expr->getType());
+ExprResult Sema::ImpCastExprToType(Expr *E, QualType Ty,
+ CastKind Kind, ExprValueKind VK,
+ const CXXCastPath *BasePath) {
+ QualType ExprTy = Context.getCanonicalType(E->getType());
QualType TypeTy = Context.getCanonicalType(Ty);
if (ExprTy == TypeTy)
- return;
+ return Owned(E);
// If this is a derived-to-base cast to a through a virtual base, we
// need a vtable.
if (Kind == CK_DerivedToBase &&
BasePathInvolvesVirtualBase(*BasePath)) {
- QualType T = Expr->getType();
+ QualType T = E->getType();
if (const PointerType *Pointer = T->getAs<PointerType>())
T = Pointer->getPointeeType();
if (const RecordType *RecordTy = T->getAs<RecordType>())
- MarkVTableUsed(Expr->getLocStart(),
+ MarkVTableUsed(E->getLocStart(),
cast<CXXRecordDecl>(RecordTy->getDecl()));
}
- if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(Expr)) {
+ if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(E)) {
if (ImpCast->getCastKind() == Kind && (!BasePath || BasePath->empty())) {
ImpCast->setType(Ty);
ImpCast->setValueKind(VK);
- return;
+ return Owned(E);
}
}
- Expr = ImplicitCastExpr::Create(Context, Ty, Kind, Expr, BasePath, VK);
+ return Owned(ImplicitCastExpr::Create(Context, Ty, Kind, E, BasePath, VK));
}
/// ScalarTypeToBooleanCastKind - Returns the cast kind corresponding
diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp
index e519d1db17..989be96d21 100644
--- a/lib/Sema/SemaCXXCast.cpp
+++ b/lib/Sema/SemaCXXCast.cpp
@@ -42,21 +42,21 @@ enum CastType {
-static void CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
+static void CheckConstCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
ExprValueKind &VK,
const SourceRange &OpRange,
const SourceRange &DestRange);
-static void CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
+static void CheckReinterpretCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
ExprValueKind &VK,
const SourceRange &OpRange,
const SourceRange &DestRange,
CastKind &Kind);
-static void CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
+static void CheckStaticCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
ExprValueKind &VK,
const SourceRange &OpRange,
CastKind &Kind,
CXXCastPath &BasePath);
-static void CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
+static void CheckDynamicCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
ExprValueKind &VK,
const SourceRange &OpRange,
const SourceRange &DestRange,
@@ -100,7 +100,7 @@ static TryCastResult TryStaticDowncast(Sema &Self, CanQualType SrcType,
QualType OrigDestType, unsigned &msg,
CastKind &Kind,
CXXCastPath &BasePath);
-static TryCastResult TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr,
+static TryCastResult TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr,
QualType SrcType,
QualType DestType,bool CStyle,
const SourceRange &OpRange,
@@ -108,12 +108,12 @@ static TryCastResult TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr,
CastKind &Kind,
CXXCastPath &BasePath);
-static TryCastResult TryStaticImplicitCast(Sema &Self, Expr *&SrcExpr,
+static TryCastResult TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr,
QualType DestType, bool CStyle,
const SourceRange &OpRange,
unsigned &msg,
CastKind &Kind);
-static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
+static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr,
QualType DestType, bool CStyle,
const SourceRange &OpRange,
unsigned &msg,
@@ -121,7 +121,7 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
CXXCastPath &BasePath);
static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType,
bool CStyle, unsigned &msg);
-static TryCastResult TryReinterpretCast(Sema &Self, Expr *&SrcExpr,
+static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr,
QualType DestType, bool CStyle,
const SourceRange &OpRange,
unsigned &msg,
@@ -148,8 +148,9 @@ Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
ExprResult
Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
- TypeSourceInfo *DestTInfo, Expr *Ex,
+ TypeSourceInfo *DestTInfo, Expr *E,
SourceRange AngleBrackets, SourceRange Parens) {
+ ExprResult Ex = Owned(E);
QualType DestType = DestTInfo->getType();
SourceRange OpRange(OpLoc, Parens.getEnd());
@@ -157,11 +158,11 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
// 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->isTypeDependent();
+ bool TypeDependent = DestType->isDependentType() || Ex.get()->isTypeDependent();
- if (Ex->isBoundMemberFunction(Context))
- Diag(Ex->getLocStart(), diag::err_invalid_use_of_bound_member_func)
- << Ex->getSourceRange();
+ if (Ex.get()->isBoundMemberFunction(Context))
+ Diag(Ex.get()->getLocStart(), diag::err_invalid_use_of_bound_member_func)
+ << Ex.get()->getSourceRange();
ExprValueKind VK = VK_RValue;
if (TypeDependent)
@@ -171,42 +172,54 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
default: llvm_unreachable("Unknown C++ cast!");
case tok::kw_const_cast:
- if (!TypeDependent)
+ if (!TypeDependent) {
CheckConstCast(*this, Ex, DestType, VK, OpRange, DestRange);
+ if (Ex.isInvalid())
+ return ExprError();
+ }
return Owned(CXXConstCastExpr::Create(Context,
DestType.getNonLValueExprType(Context),
- VK, Ex, DestTInfo, OpLoc,
+ VK, Ex.take(), DestTInfo, OpLoc,
Parens.getEnd()));
case tok::kw_dynamic_cast: {
CastKind Kind = CK_Dependent;
CXXCastPath BasePath;
- if (!TypeDependent)
+ if (!TypeDependent) {
CheckDynamicCast(*this, Ex, DestType, VK, OpRange, DestRange,
Kind, BasePath);
+ if (Ex.isInvalid())
+ return ExprError();
+ }
return Owned(CXXDynamicCastExpr::Create(Context,
DestType.getNonLValueExprType(Context),
- VK, Kind, Ex, &BasePath, DestTInfo,
+ VK, Kind, Ex.take(), &BasePath, DestTInfo,
OpLoc, Parens.getEnd()));
}
case tok::kw_reinterpret_cast: {
CastKind Kind = CK_Dependent;
- if (!TypeDependent)
+ if (!TypeDependent) {
CheckReinterpretCast(*this, Ex, DestType, VK, OpRange, DestRange, Kind);
+ if (Ex.isInvalid())
+ return ExprError();
+ }
return Owned(CXXReinterpretCastExpr::Create(Context,
DestType.getNonLValueExprType(Context),
- VK, Kind, Ex, 0,
+ VK, Kind, Ex.take(), 0,
DestTInfo, OpLoc, Parens.getEnd()));
}
case tok::kw_static_cast: {
CastKind Kind = CK_Dependent;
CXXCastPath BasePath;
- if (!TypeDependent)
+ if (!TypeDependent) {
CheckStaticCast(*this, Ex, DestType, VK, OpRange, Kind, BasePath);
+ if (Ex.isInvalid())
+ return ExprError();
+ }
return Owned(CXXStaticCastExpr::Create(Context,
DestType.getNonLValueExprType(Context),
- VK, Kind, Ex, &BasePath,
+ VK, Kind, Ex.take(), &BasePath,
DestTInfo, OpLoc, Parens.getEnd()));
}
}
@@ -413,11 +426,11 @@ CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType) {
/// 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, Expr *&SrcExpr, QualType DestType,
+CheckDynamicCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
ExprValueKind &VK, const SourceRange &OpRange,
const SourceRange &DestRange, CastKind &Kind,
CXXCastPath &BasePath) {
- QualType OrigDestType = DestType, OrigSrcType = SrcExpr->getType();
+ QualType OrigDestType = DestType, OrigSrcType = SrcExpr.get()->getType();
DestType = Self.Context.getCanonicalType(DestType);
// C++ 5.2.7p1: T shall be a pointer or reference to a complete class type,
@@ -464,11 +477,11 @@ CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
SrcPointee = SrcPointer->getPointeeType();
} else {
Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ptr)
- << OrigSrcType << SrcExpr->getSourceRange();
+ << OrigSrcType << SrcExpr.get()->getSourceRange();
return;
}
} else if (DestReference->isLValueReferenceType()) {
- if (!SrcExpr->isLValue()) {
+ if (!SrcExpr.get()->isLValue()) {
Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_rvalue)
<< CT_Dynamic << OrigSrcType << OrigDestType << OpRange;
}
@@ -481,11 +494,11 @@ CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
if (SrcRecord) {
if (Self.RequireCompleteType(OpRange.getBegin(), SrcPointee,
Self.PDiag(diag::err_bad_dynamic_cast_incomplete)
- << SrcExpr->getSourceRange()))
+ << SrcExpr.get()->getSourceRange()))
return;
} else {
Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)
- << SrcPointee.getUnqualifiedType() << SrcExpr->getSourceRange();
+ << SrcPointee.getUnqualifiedType() << SrcExpr.get()->getSourceRange();
return;
}
@@ -532,7 +545,7 @@ CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
assert(SrcDecl && "Definition missing");
if (!cast<CXXRecordDecl>(SrcDecl)->isPolymorphic()) {
Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_polymorphic)
- << SrcPointee.getUnqualifiedType() << SrcExpr->getSourceRange();
+ << SrcPointee.getUnqualifiedType() << SrcExpr.get()->getSourceRange();
}
Self.MarkVTableUsed(OpRange.getBegin(),
cast<CXXRecordDecl>(SrcRecord->getDecl()));
@@ -547,17 +560,20 @@ CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
/// const char *str = "literal";
/// legacy_function(const_cast\<char*\>(str));
void
-CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType, ExprValueKind &VK,
+CheckConstCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, ExprValueKind &VK,
const SourceRange &OpRange, const SourceRange &DestRange) {
VK = Expr::getValueKindForType(DestType);
- if (VK == VK_RValue)
- Self.DefaultFunctionArrayLvalueConversion(SrcExpr);
+ if (VK == VK_RValue) {
+ SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
+ if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
+ return;
+ }
unsigned msg = diag::err_bad_cxx_cast_generic;
- if (TryConstCast(Self, SrcExpr, DestType, /*CStyle*/false, msg) != TC_Success
+ if (TryConstCast(Self, SrcExpr.get(), DestType, /*CStyle*/false, msg) != TC_Success
&& msg != 0)
Self.Diag(OpRange.getBegin(), msg) << CT_Const
- << SrcExpr->getType() << DestType << OpRange;
+ << SrcExpr.get()->getType() << DestType << OpRange;
}
/// CheckReinterpretCast - Check that a reinterpret_cast\<DestType\>(SrcExpr) is
@@ -566,27 +582,32 @@ CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType, ExprValueKind &VK,
/// like this:
/// char *bytes = reinterpret_cast\<char*\>(int_ptr);
void
-CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
+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)
- Self.DefaultFunctionArrayLvalueConversion(SrcExpr);
+ if (VK == VK_RValue) {
+ SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
+ if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
+ return;
+ }
unsigned msg = diag::err_bad_cxx_cast_generic;
if (TryReinterpretCast(Self, SrcExpr, DestType, /*CStyle*/false, OpRange,
msg, Kind)
!= TC_Success && msg != 0)
{
- if (SrcExpr->getType() == Self.Context.OverloadTy) {
+ if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
+ return;
+ if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
//FIXME: &f<int>; is overloaded and resolvable
Self.Diag(OpRange.getBegin(), diag::err_bad_reinterpret_cast_overload)
- << OverloadExpr::find(SrcExpr).Expression->getName()
+ << OverloadExpr::find(SrcExpr.get()).Expression->getName()
<< DestType << OpRange;
- Self.NoteAllOverloadCandidates(SrcExpr);
+ Self.NoteAllOverloadCandidates(SrcExpr.get());
} else {
- diagnoseBadCast(Self, msg, CT_Reinterpret, OpRange, SrcExpr, DestType);
+ diagnoseBadCast(Self, msg, CT_Reinterpret, OpRange, SrcExpr.get(), DestType);
}
}
}
@@ -596,23 +617,25 @@ CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
/// 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, Expr *&SrcExpr, QualType DestType,
+CheckStaticCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
ExprValueKind &VK, const SourceRange &OpRange,
CastKind &Kind, CXXCastPath &BasePath) {
// 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 (DestType->isVoidType()) {
- Self.IgnoredValueConversions(SrcExpr);
- if (SrcExpr->getType() == Self.Context.OverloadTy) {
+ SrcExpr = Self.IgnoredValueConversions(SrcExpr.take());
+ if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
+ return;
+ if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
ExprResult SingleFunctionExpression =
- Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr,
+ Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr.get(),
false, // Decay Function to ptr
true, // Complain