From: Douglas Gregor Date: Wed, 16 Dec 2009 03:45:30 +0000 (+0000) Subject: Fix semantic diagnostics that embed English works, from Nicola Gigante! X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6864748fc9a780e6db0bb5a7bd20aa889882dc94;p=clang Fix semantic diagnostics that embed English works, from Nicola Gigante! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91503 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index ff23ec9b0e..9a2a334479 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1922,9 +1922,11 @@ def warn_value_always_zero : Warning< "%0 is always %select{zero|false|NULL}1 in this context">; // assignment related diagnostics (also for argument passing, returning, etc). -// FIXME: %2 is an english string here. +// In most of these diagnostics the %2 is a value from the +// Sema::AssignmentAction enumeration def err_typecheck_convert_incompatible : Error< - "incompatible type %2 %1, expected %0">; + "incompatible type %select{assigning|passing|returning|converting|initializing|sending|casting}2" + " %1, expected %0">; def err_typecheck_convert_ambiguous : Error< "ambiguity in initializing value of type %0 with initializer of type %1">; def err_cannot_initialize_decl_noname : Error< @@ -1933,31 +1935,43 @@ def err_cannot_initialize_decl_noname : Error< def err_cannot_initialize_decl : Error< "cannot initialize %0 with an %select{rvalue|lvalue}1 of type %2">; def warn_incompatible_qualified_id : Warning< - "incompatible type %2 %1, expected %0">; + "incompatible type %select{assigning|passing|returning|converting|initializing|sending|casting}2" + " %1, expected %0">; def ext_typecheck_convert_pointer_int : ExtWarn< - "incompatible pointer to integer conversion %2 %1, expected %0">; + "incompatible pointer to integer conversion " + "%select{assigning|passing|returning|converting|initializing|sending|casting}2 %1, expected %0">; def ext_typecheck_convert_int_pointer : ExtWarn< - "incompatible integer to pointer conversion %2 %1, expected %0">; + "incompatible integer to pointer conversion " + "%select{assigning|passing|returning|converting|initializing|sending|casting}2 %1, expected %0">; def ext_typecheck_convert_pointer_void_func : Extension< - "%2 %1 converts between void* and function pointer, expected %0">; + "%select{assigning|passing|returning|converting|initializing|sending|casting}2" + " %1 converts between void* and function pointer, expected %0">; def ext_typecheck_convert_incompatible_pointer_sign : ExtWarn< - "pointer types point to integer types with different sign %2 %1, expected %0">, + "pointer types point to integer types with different sign " + "%select{assigning|passing|returning|converting|initializing|sending|casting}2 %1, expected %0">, InGroup>; def ext_typecheck_convert_incompatible_pointer : ExtWarn< - "incompatible pointer types %2 %1, expected %0">; + "incompatible pointer types " + "%select{assigning|passing|returning|converting|initializing|sending|casting}2 %1, expected %0">; def ext_typecheck_convert_discards_qualifiers : ExtWarn< - "%2 %1 discards qualifiers, expected %0">; + "%select{assigning|passing|returning|converting|initializing|sending|casting}2" + " %1 discards qualifiers, expected %0">; def ext_nested_pointer_qualifier_mismatch : ExtWarn< - "%2, %0 and %1 have different qualifiers in nested pointer types">; + "%select{assigning|passing|returning|converting|initializing|sending|casting}2," + " %0 and %1 have different qualifiers in nested pointer types">; def warn_incompatible_vectors : Warning< - "incompatible vector types %2 %1, expected %0">, + "incompatible vector types %select{assigning|passing|returning|converting|initializing|sending|casting}2" + " %1, expected %0">, InGroup, DefaultIgnore; def err_int_to_block_pointer : Error< - "invalid conversion %2 integer %1, expected block pointer %0">; + "invalid conversion " + "%select{assigning|passing|returning|converting|initializing|sending|casting}2" + " integer %1, expected block pointer %0">; def err_typecheck_comparison_of_distinct_blocks : Error< "comparison of distinct block types (%0 and %1)">; def err_typecheck_convert_incompatible_block_pointer : Error< - "incompatible block pointer types %2 %1, expected %0">; + "incompatible block pointer types " + "%select{assigning|passing|returning|converting|initializing|sending|casting}2 %1, expected %0">; def err_typecheck_array_not_modifiable_lvalue : Error< "array type %0 is not assignable">; diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 88f290a9d8..c489b1ea41 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -842,6 +842,18 @@ public: void MergeVarDecl(VarDecl *New, LookupResult &OldDecls); bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old); + // AssignmentAction - This is used by all the assignment diagnostic functions + // to represent what is actually causing the operation + enum AssignmentAction { + AA_Assigning, + AA_Passing, + AA_Returning, + AA_Converting, + AA_Initializing, + AA_Sending, + AA_Casting + }; + /// C++ Overloading. enum OverloadKind { /// This is a legitimate overload: the existing declarations are @@ -918,8 +930,9 @@ public: TryCopyInitialization(Expr* From, QualType ToType, bool SuppressUserConversions, bool ForceRValue, bool InOverloadResolution); + bool PerformCopyInitialization(Expr *&From, QualType ToType, - const char *Flavor, bool Elidable = false); + AssignmentAction Action, bool Elidable = false); ImplicitConversionSequence TryObjectArgumentInitialization(QualType FromType, CXXMethodDecl *Method, @@ -3557,14 +3570,14 @@ public: /// represent it in the AST. Incompatible }; - + /// DiagnoseAssignmentResult - Emit a diagnostic, if required, for the /// assignment conversion type specified by ConvTy. This returns true if the /// conversion was invalid or false if the conversion was accepted. bool DiagnoseAssignmentResult(AssignConvertType ConvTy, SourceLocation Loc, QualType DstType, QualType SrcType, - Expr *SrcExpr, const char *Flavor); + Expr *SrcExpr, AssignmentAction Action); /// CheckAssignmentConstraints - Perform type checking for assignment, /// argument passing, variable initialization, and function return values. @@ -3599,25 +3612,24 @@ public: bool CheckExceptionSpecCompatibility(Expr *From, QualType ToType); bool PerformImplicitConversion(Expr *&From, QualType ToType, - const char *Flavor, + AssignmentAction Action, bool AllowExplicit = false, bool Elidable = false); bool PerformImplicitConversion(Expr *&From, QualType ToType, - const char *Flavor, + AssignmentAction Action, bool AllowExplicit, bool Elidable, ImplicitConversionSequence& ICS); bool PerformImplicitConversion(Expr *&From, QualType ToType, const ImplicitConversionSequence& ICS, - const char *Flavor, + AssignmentAction Action, bool IgnoreBaseAccess = false); bool PerformImplicitConversion(Expr *&From, QualType ToType, const StandardConversionSequence& SCS, - const char *Flavor, bool IgnoreBaseAccess); + AssignmentAction Action, bool IgnoreBaseAccess); bool BuildCXXDerivedToBaseExpr(Expr *&From, CastExpr::CastKind CastKind, - const ImplicitConversionSequence& ICS, - const char *Flavor); + const ImplicitConversionSequence& ICS); /// the following "Check" methods will return a valid/converted QualType /// or a null QualType (indicating an error diagnostic was issued). diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp index 814af9080d..92eb1740c9 100644 --- a/lib/Sema/SemaCXXCast.cpp +++ b/lib/Sema/SemaCXXCast.cpp @@ -899,7 +899,7 @@ TryStaticImplicitCast(Sema &Self, Expr *&SrcExpr, QualType DestType, // The conversion is possible, so commit to it. Kind = CastExpr::CK_NoOp; msg = 0; - return Self.PerformImplicitConversion(SrcExpr, DestType, ICS, "casting", + return Self.PerformImplicitConversion(SrcExpr, DestType, ICS, Sema::AA_Casting, /*IgnoreBaseAccess*/CStyle) ? TC_Failed : TC_Success; } diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 08edb117e8..7eb1d9ed0a 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1139,7 +1139,7 @@ Sema::BuildMemberInitializer(FieldDecl *Member, Expr **Args, } else NewExp = (Expr*)Args[0]; - if (PerformCopyInitialization(NewExp, FieldType, "passing")) + if (PerformCopyInitialization(NewExp, FieldType, AA_Passing)) return true; Args[0] = NewExp; } @@ -4566,7 +4566,7 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType, (T1->isRecordType() || T2->isRecordType())) { if (!ICS) Diag(DeclLoc, diag::err_typecheck_convert_incompatible) - << DeclType << Init->getType() << "initializing" << Init->getSourceRange(); + << DeclType << Init->getType() << AA_Initializing << Init->getSourceRange(); return true; } @@ -4600,7 +4600,7 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType, return ICS->ConversionKind == ImplicitConversionSequence::BadConversion; } else { ImplicitConversionSequence Conversions; - bool badConversion = PerformImplicitConversion(Init, T1, "initializing", + bool badConversion = PerformImplicitConversion(Init, T1, AA_Initializing, false, false, Conversions); if (badConversion) { diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 70646dd9ed..77c2636ca7 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -3155,7 +3155,7 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, return true; // Pass the argument. - if (PerformCopyInitialization(Arg, ProtoArgType, "passing")) + if (PerformCopyInitialization(Arg, ProtoArgType, AA_Passing)) return true; if (!ProtoArgType->isReferenceType()) @@ -4629,7 +4629,7 @@ Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) { // expression is implicitly converted (C++ 4) to the // cv-unqualified type of the left operand. if (PerformImplicitConversion(rExpr, lhsType.getUnqualifiedType(), - "assigning")) + AA_Assigning)) return Incompatible; return Compatible; } @@ -5500,7 +5500,7 @@ inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14] return InvalidOperands(Loc, lex, rex); if (PerformImplicitConversion(lex, Context.BoolTy, LHS, - "passing", /*IgnoreBaseAccess=*/false)) + AA_Passing, /*IgnoreBaseAccess=*/false)) return InvalidOperands(Loc, lex, rex); StandardConversionSequence RHS; @@ -5509,7 +5509,7 @@ inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14] return InvalidOperands(Loc, lex, rex); if (PerformImplicitConversion(rex, Context.BoolTy, RHS, - "passing", /*IgnoreBaseAccess=*/false)) + AA_Passing, /*IgnoreBaseAccess=*/false)) return InvalidOperands(Loc, lex, rex); // C++ [expr.log.and]p2 @@ -5651,7 +5651,7 @@ QualType Sema::CheckAssignmentOperands(Expr *LHS, Expr *&RHS, } if (DiagnoseAssignmentResult(ConvTy, Loc, LHSType, RHSType, - RHS, "assigning")) + RHS, AA_Assigning)) return QualType(); // C99 6.5.16p3: The type of an assignment expression is the type of the @@ -6847,7 +6847,7 @@ MakeObjCStringLiteralCodeModificationHint(Sema& SemaRef, bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, SourceLocation Loc, QualType DstType, QualType SrcType, - Expr *SrcExpr, const char *Flavor) { + Expr *SrcExpr, AssignmentAction Action) { // Decode the result (notice that AST's are still created for extensions). bool isInvalid = false; unsigned DiagKind; @@ -6910,7 +6910,7 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, break; } - Diag(Loc, DiagKind) << DstType << SrcType << Flavor + Diag(Loc, DiagKind) << DstType << SrcType << Action << SrcExpr->getSourceRange() << Hint; return isInvalid; } diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 4bcb0583c6..8870a59d13 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -627,10 +627,9 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range, // Whatch out for variadic allocator function. unsigned NumArgsInFnDecl = FnDecl->getNumParams(); for (unsigned i = 0; (i < NumArgs && i < NumArgsInFnDecl); ++i) { - // FIXME: Passing word to diagnostic. if (PerformCopyInitialization(Args[i], FnDecl->getParamDecl(i)->getType(), - "passing")) + AA_Passing)) return true; } Operator = FnDecl; @@ -872,7 +871,7 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, Operand.release(); if (!PerformImplicitConversion(Ex, ObjectPtrConversions.front()->getConversionType(), - "converting")) { + AA_Converting)) { Operand = Owned(Ex); Type = Ex->getType(); } @@ -1023,16 +1022,16 @@ Sema::IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType) { /// resolution works differently in that case. bool Sema::PerformImplicitConversion(Expr *&From, QualType ToType, - const char *Flavor, bool AllowExplicit, + AssignmentAction Action, bool AllowExplicit, bool Elidable) { ImplicitConversionSequence ICS; - return PerformImplicitConversion(From, ToType, Flavor, AllowExplicit, + return PerformImplicitConversion(From, ToType, Action, AllowExplicit, Elidable, ICS); } bool Sema::PerformImplicitConversion(Expr *&From, QualType ToType, - const char *Flavor, bool AllowExplicit, + AssignmentAction Action, bool AllowExplicit, bool Elidable, ImplicitConversionSequence& ICS) { ICS.ConversionKind = ImplicitConversionSequence::BadConversion; @@ -1050,7 +1049,7 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType, /*ForceRValue=*/false, /*InOverloadResolution=*/false); } - return PerformImplicitConversion(From, ToType, ICS, Flavor); + return PerformImplicitConversion(From, ToType, ICS, Action); } /// BuildCXXDerivedToBaseExpr - This routine generates the suitable AST @@ -1058,8 +1057,7 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType, /// necessary information is passed in ICS. bool Sema::BuildCXXDerivedToBaseExpr(Expr *&From, CastExpr::CastKind CastKind, - const ImplicitConversionSequence& ICS, - const char *Flavor) { + const ImplicitConversionSequence& ICS) { QualType BaseType = QualType::getFromOpaquePtr(ICS.UserDefined.After.ToTypePtr); // Must do additional defined to base conversion. @@ -1091,15 +1089,15 @@ Sema::BuildCXXDerivedToBaseExpr(Expr *&From, CastExpr::CastKind CastKind, /// expression From to the type ToType using the pre-computed implicit /// conversion sequence ICS. Returns true if there was an error, false /// otherwise. The expression From is replaced with the converted -/// expression. Flavor is the kind of conversion we're performing, +/// expression. Action is the kind of conversion we're performing, /// used in the error message. bool Sema::PerformImplicitConversion(Expr *&From, QualType ToType, const ImplicitConversionSequence &ICS, - const char* Flavor, bool IgnoreBaseAccess) { + AssignmentAction Action, bool IgnoreBaseAccess) { switch (ICS.ConversionKind) { case ImplicitConversionSequence::StandardConversion: - if (PerformImplicitConversion(From, ToType, ICS.Standard, Flavor, + if (PerformImplicitConversion(From, ToType, ICS.Standard, Action, IgnoreBaseAccess)) return true; break; @@ -1132,7 +1130,7 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType, // Whatch out for elipsis conversion. if (!ICS.UserDefined.EllipsisConversion) { if (PerformImplicitConversion(From, BeforeToType, - ICS.UserDefined.Before, "converting", + ICS.UserDefined.Before, AA_Converting, IgnoreBaseAccess)) return true; } @@ -1152,7 +1150,7 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType, // there's some nasty stuff involving MaybeBindToTemporary going on here. if (ICS.UserDefined.After.Second == ICK_Derived_To_Base && ICS.UserDefined.After.CopyConstructor) { - return BuildCXXDerivedToBaseExpr(From, CastKind, ICS, Flavor); + return BuildCXXDerivedToBaseExpr(From, CastKind, ICS); } if (ICS.UserDefined.After.CopyConstructor) { @@ -1163,7 +1161,7 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType, } return PerformImplicitConversion(From, ToType, ICS.UserDefined.After, - "converting", IgnoreBaseAccess); + AA_Converting, IgnoreBaseAccess); } case ImplicitConversionSequence::EllipsisConversion: @@ -1187,7 +1185,7 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType, bool Sema::PerformImplicitConversion(Expr *&From, QualType ToType, const StandardConversionSequence& SCS, - const char *Flavor, bool IgnoreBaseAccess) { + AssignmentAction Action, bool IgnoreBaseAccess) { // Overall FIXME: we are recomputing too many types here and doing far too // much extra work. What this means is that we need to keep track of more // information that is computed when we try the implicit conversion initially, @@ -1319,7 +1317,7 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType, // Diagnose incompatible Objective-C conversions Diag(From->getSourceRange().getBegin(), diag::ext_typecheck_convert_incompatible_pointer) - << From->getType() << ToType << Flavor + << From->getType() << ToType << Action << From->getSourceRange(); } @@ -1591,9 +1589,9 @@ static bool FindConditionalOverload(Sema &Self, Expr *&LHS, Expr *&RHS, case OR_Success: // We found a match. Perform the conversions on the arguments and move on. if (Self.PerformImplicitConversion(LHS, Best->BuiltinTypes.ParamTypes[0], - Best->Conversions[0], "converting") || + Best->Conversions[0], Sema::AA_Converting) || Self.PerformImplicitConversion(RHS, Best->BuiltinTypes.ParamTypes[1], - Best->Conversions[1], "converting")) + Best->Conversions[1], Sema::AA_Converting)) break; return false; @@ -1651,7 +1649,7 @@ static bool ConvertForConditional(Sema &Self, Expr *&E, /*AllowExplicit=*/false, /*ForceRValue=*/false); } - if (Self.PerformImplicitConversion(E, TargetType(ICS), ICS, "converting")) + if (Self.PerformImplicitConversion(E, TargetType(ICS), ICS, Sema::AA_Converting)) return true; return false; } @@ -1875,9 +1873,9 @@ QualType Sema::CXXCheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, LPointee = Context.getQualifiedType(LPointee, MergedQuals); QualType Common = Context.getMemberPointerType(LPointee, MoreDerived.getTypePtr()); - if (PerformImplicitConversion(LHS, Common, "converting")) + if (PerformImplicitConversion(LHS, Common, Sema::AA_Converting)) return QualType(); - if (PerformImplicitConversion(RHS, Common, "converting")) + if (PerformImplicitConversion(RHS, Common, Sema::AA_Converting)) return QualType(); return Common; } @@ -2042,13 +2040,13 @@ QualType Sema::FindCompositePointerType(Expr *&E1, Expr *&E2) { && E2ToC2.ConversionKind != ImplicitConversionSequence::BadConversion; if (ToC1Viable && !ToC2Viable) { - if (!PerformImplicitConversion(E1, Composite1, E1ToC1, "converting") && - !PerformImplicitConversion(E2, Composite1, E2ToC1, "converting")) + if (!PerformImplicitConversion(E1, Composite1, E1ToC1, Sema::AA_Converting) && + !PerformImplicitConversion(E2, Composite1, E2ToC1, Sema::AA_Converting)) return Composite1; } if (ToC2Viable && !ToC1Viable) { - if (!PerformImplicitConversion(E1, Composite2, E1ToC2, "converting") && - !PerformImplicitConversion(E2, Composite2, E2ToC2, "converting")) + if (!PerformImplicitConversion(E1, Composite2, E1ToC2, Sema::AA_Converting) && + !PerformImplicitConversion(E2, Composite2, E2ToC2, Sema::AA_Converting)) return Composite2; } return QualType(); diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index b78c10b0dd..2e31e47645 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -205,7 +205,7 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs, IsError |= DiagnoseAssignmentResult(Result, argExpr->getLocStart(), lhsType, rhsType, - argExpr, "sending"); + argExpr, AA_Sending); } // Promote additional arguments to variadic methods. diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index a732b07b9d..28e11a1010 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -73,7 +73,7 @@ static bool CheckSingleInitializer(Expr *&Init, QualType DeclType, if (S.getLangOptions().CPlusPlus) { // FIXME: I dislike this error message. A lot. if (S.PerformImplicitConversion(Init, DeclType, - "initializing", DirectInit)) { + Sema::AA_Initializing, DirectInit)) { ImplicitConversionSequence ICS; OverloadCandidateSet CandidateSet; if (S.IsUserDefinedConversion(Init, DeclType, ICS.UserDefined, @@ -81,7 +81,7 @@ static bool CheckSingleInitializer(Expr *&Init, QualType DeclType, true, false, false) != OR_Ambiguous) return S.Diag(Init->getSourceRange().getBegin(), diag::err_typecheck_convert_incompatible) - << DeclType << Init->getType() << "initializing" + << DeclType << Init->getType() << Sema::AA_Initializing << Init->getSourceRange(); S.Diag(Init->getSourceRange().getBegin(), diag::err_typecheck_convert_ambiguous) @@ -95,7 +95,7 @@ static bool CheckSingleInitializer(Expr *&Init, QualType DeclType, Sema::AssignConvertType ConvTy = S.CheckSingleAssignmentConstraints(DeclType, Init); return S.DiagnoseAssignmentResult(ConvTy, Init->getLocStart(), DeclType, - InitType, Init, "initializing"); + InitType, Init, Sema::AA_Initializing); } static void CheckStringInit(Expr *Str, QualType &DeclT, Sema &S) { @@ -279,7 +279,7 @@ bool Sema::CheckInitializerTypes(Expr *&Init, QualType &DeclType, // destination type. // FIXME: We're pretending to do copy elision here; return to this when we // have ASTs for such things. - if (!PerformImplicitConversion(Init, DeclType, "initializing")) + if (!PerformImplicitConversion(Init, DeclType, Sema::AA_Initializing)) return false; if (InitEntity) @@ -747,7 +747,7 @@ void InitListChecker::CheckSubElementType(InitListExpr *IList, if (ICS.ConversionKind != ImplicitConversionSequence::BadConversion) { if (SemaRef.PerformImplicitConversion(expr, ElemType, ICS, - "initializing")) + Sema::AA_Initializing)) hadError = true; UpdateStructuredListElement(StructuredList, StructuredIndex, expr); ++Index; @@ -787,7 +787,7 @@ void InitListChecker::CheckSubElementType(InitListExpr *IList, } else { // We cannot initialize this element, so let // PerformCopyInitialization produce the appropriate diagnostic. - SemaRef.PerformCopyInitialization(expr, ElemType, "initializing"); + SemaRef.PerformCopyInitialization(expr, ElemType, Sema::AA_Initializing); hadError = true; ++Index; ++StructuredIndex; @@ -3150,7 +3150,7 @@ InitializationSequence::Perform(Sema &S, break; case SK_ConversionSequence: - if (S.PerformImplicitConversion(CurInitExpr, Step->Type, "converting", + if (S.PerformImplicitConversion(CurInitExpr, Step->Type, Sema::AA_Converting, false, false, *Step->ICS)) return S.ExprError(); diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 561cfdb52e..23598bf605 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -2080,7 +2080,7 @@ Sema::TryCopyInitialization(Expr *From, QualType ToType, /// be true when the copy may be elided (C++ 12.8p15). Overload resolution works /// differently in C++0x for this case. bool Sema::PerformCopyInitialization(Expr *&From, QualType ToType, - const char* Flavor, bool Elidable) { + AssignmentAction Action, bool Elidable) { if (!getLangOptions().CPlusPlus) { // In C, argument passing is the same as performing an assignment. QualType FromType = From->getType(); @@ -2092,7 +2092,7 @@ bool Sema::PerformCopyInitialization(Expr *&From, QualType ToType, ConvTy = Compatible; return DiagnoseAssignmentResult(ConvTy, From->getLocStart(), ToType, - FromType, From, Flavor); + FromType, From, Action); } if (ToType->isReferenceType()) @@ -2102,13 +2102,13 @@ bool Sema::PerformCopyInitialization(Expr *&From, QualType ToType, /*AllowExplicit=*/false, /*ForceRValue=*/false); - if (!PerformImplicitConversion(From, ToType, Flavor, + if (!PerformImplicitConversion(From, ToType, Action, /*AllowExplicit=*/false, Elidable)) return false; if (!DiagnoseMultipleUserDefinedConversion(From, ToType)) return Diag(From->getSourceRange().getBegin(), diag::err_typecheck_convert_incompatible) - << ToType << From->getType() << Flavor << From->getSourceRange(); + << ToType << From->getType() << Action << From->getSourceRange(); return true; } @@ -2229,7 +2229,7 @@ ImplicitConversionSequence Sema::TryContextuallyConvertToBool(Expr *From) { /// of the expression From to bool (C++0x [conv]p3). bool Sema::PerformContextuallyConvertToBool(Expr *&From) { ImplicitConversionSequence ICS = TryContextuallyConvertToBool(From); - if (!PerformImplicitConversion(From, Context.BoolTy, ICS, "converting")) + if (!PerformImplicitConversion(From, Context.BoolTy, ICS, AA_Converting)) return false; if (!DiagnoseMultipleUserDefinedConversion(From, Context.BoolTy)) @@ -4789,7 +4789,7 @@ Sema::OwningExprResult Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, // Convert the arguments. if (PerformCopyInitialization(Input, FnDecl->getParamDecl(0)->getType(), - "passing")) + AA_Passing)) return ExprError(); } @@ -4817,7 +4817,7 @@ Sema::OwningExprResult Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, // break out so that we will build the appropriate built-in // operator node. if (PerformImplicitConversion(Input, Best->BuiltinTypes.ParamTypes[0], - Best->Conversions[0], "passing")) + Best->Conversions[0], AA_Passing)) return ExprError(); break; @@ -4956,14 +4956,14 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, if (CXXMethodDecl *Method = dyn_cast(FnDecl)) { if (PerformObjectArgumentInitialization(Args[0], Method) || PerformCopyInitialization(Args[1], FnDecl->getParamDecl(0)->getType(), - "passing")) + AA_Passing)) return ExprError(); } else { // Convert the arguments. if (PerformCopyInitialization(Args[0], FnDecl->getParamDecl(0)->getType(), - "passing") || + AA_Passing) || PerformCopyInitialization(Args[1], FnDecl->getParamDecl(1)->getType(), - "passing")) + AA_Passing)) return ExprError(); } @@ -4992,9 +4992,9 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, // break out so that we will build the appropriate built-in // operator node. if (PerformImplicitConversion(Args[0], Best->BuiltinTypes.ParamTypes[0], - Best->Conversions[0], "passing") || + Best->Conversions[0], AA_Passing) || PerformImplicitConversion(Args[1], Best->BuiltinTypes.ParamTypes[1], - Best->Conversions[1], "passing")) + Best->Conversions[1], AA_Passing)) return ExprError(); break; @@ -5106,7 +5106,7 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, if (PerformObjectArgumentInitialization(Args[0], Method) || PerformCopyInitialization(Args[1], FnDecl->getParamDecl(0)->getType(), - "passing")) + AA_Passing)) return ExprError(); // Determine the result type @@ -5136,9 +5136,9 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, // break out so that we will build the appropriate built-in // operator node. if (PerformImplicitConversion(Args[0], Best->BuiltinTypes.ParamTypes[0], - Best->Conversions[0], "passing") || + Best->Conversions[0], AA_Passing) || PerformImplicitConversion(Args[1], Best->BuiltinTypes.ParamTypes[1], - Best->Conversions[1], "passing")) + Best->Conversions[1], AA_Passing)) return ExprError(); break; @@ -5522,7 +5522,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object, // Pass the argument. QualType ProtoArgType = Proto->getArgType(i); - IsError |= PerformCopyInitialization(Arg, ProtoArgType, "passing"); + IsError |= PerformCopyInitialization(Arg, ProtoArgType, AA_Passing); } else { OwningExprResult DefArg = BuildCXXDefaultArgExpr(LParenLoc, Method, Method->getParamDecl(i)); diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index acf3e3aad7..10f0be6e67 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -902,7 +902,7 @@ Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc, AssignConvertType ConvTy = CheckSingleAssignmentConstraints(Context.VoidPtrTy, E); if (DiagnoseAssignmentResult(ConvTy, StarLoc, Context.VoidPtrTy, ETy, - E, "passing")) + E, AA_Passing)) return StmtError(); } return Owned(new (Context) IndirectGotoStmt(GotoLoc, StarLoc, E)); @@ -986,7 +986,7 @@ Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { // In C++ the return statement is handled via a copy initialization. // the C version of which boils down to CheckSingleAssignmentConstraints. // FIXME: Leaks RetValExp. - if (PerformCopyInitialization(RetValExp, FnRetType, "returning")) + if (PerformCopyInitialization(RetValExp, FnRetType, AA_Returning)) return StmtError(); if (RetValExp) CheckReturnStackAddr(RetValExp, FnRetType, ReturnLoc); @@ -1096,7 +1096,7 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, ExprArg rex) { // In C++ the return statement is handled via a copy initialization. // the C version of which boils down to CheckSingleAssignmentConstraints. // FIXME: Leaks RetValExp on error. - if (PerformCopyInitialization(RetValExp, FnRetType, "returning", Elidable)){ + if (PerformCopyInitialization(RetValExp, FnRetType, AA_Returning, Elidable)){ // We should still clean up our temporaries, even when we're failing! RetValExp = MaybeCreateCXXExprWithTemporaries(RetValExp); return StmtError();