Index: include/clang/Basic/Diagnostic.h =================================================================== --- include/clang/Basic/Diagnostic.h +++ include/clang/Basic/Diagnostic.h @@ -935,7 +935,7 @@ public: /// Copy constructor. When copied, this "takes" the diagnostic info from the /// input and neuters it. - DiagnosticBuilder(const DiagnosticBuilder &D) { + DiagnosticBuilder(DiagnosticBuilder &&D) { DiagObj = D.DiagObj; IsActive = D.IsActive; IsForceEmit = D.IsForceEmit; Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -1051,8 +1051,8 @@ unsigned DiagID; public: - SemaDiagnosticBuilder(DiagnosticBuilder &DB, Sema &SemaRef, unsigned DiagID) - : DiagnosticBuilder(DB), SemaRef(SemaRef), DiagID(DiagID) { } + SemaDiagnosticBuilder(DiagnosticBuilder DB, Sema &SemaRef, unsigned DiagID) + : DiagnosticBuilder(std::move(DB)), SemaRef(SemaRef), DiagID(DiagID) { } // This is a cunning lie. DiagnosticBuilder actually performs move // construction in its copy constructor (but due to varied uses, it's not @@ -1060,7 +1060,7 @@ // the default copy ctor here is fine, because the base class disables the // source anyway, so the user-defined ~SemaDiagnosticBuilder is a safe no-op // in that case anwyay. - SemaDiagnosticBuilder(const SemaDiagnosticBuilder&) = default; + SemaDiagnosticBuilder(SemaDiagnosticBuilder&&) = default; ~SemaDiagnosticBuilder() { // If we aren't active, there is nothing to do. @@ -1092,10 +1092,22 @@ } }; + void apply(SemaDiagnosticBuilder &D) { + } + + template + void apply(SemaDiagnosticBuilder &D, const T &t, const Args& ...args) { + D << t; + apply(D, args...); + } + /// \brief Emit a diagnostic. - SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) { - DiagnosticBuilder DB = Diags.Report(Loc, DiagID); - return SemaDiagnosticBuilder(DB, *this, DiagID); + template + SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, + const Args &... args) { + auto D = SemaDiagnosticBuilder(Diags.Report(Loc, DiagID), *this, DiagID); + apply(D, args...); + return D; } /// \brief Emit a partial diagnostic. Index: lib/ARCMigrate/TransformActions.cpp =================================================================== --- lib/ARCMigrate/TransformActions.cpp +++ lib/ARCMigrate/TransformActions.cpp @@ -675,7 +675,9 @@ SourceRange range) { assert(!static_cast(Impl)->isInTransaction() && "Errors should be emitted out of a transaction"); - return Diags.Report(loc, diagId) << range; + auto D = Diags.Report(loc, diagId); + D << range; + return D; } void TransformActions::reportError(StringRef message, SourceLocation loc, Index: lib/Lex/LiteralSupport.cpp =================================================================== --- lib/Lex/LiteralSupport.cpp +++ lib/Lex/LiteralSupport.cpp @@ -69,8 +69,10 @@ SourceLocation Begin = Lexer::AdvanceToTokenCharacter(TokLoc, TokRangeBegin - TokBegin, TokLoc.getManager(), Features); - return Diags->Report(Begin, DiagID) << - MakeCharSourceRange(Features, TokLoc, TokBegin, TokRangeBegin, TokRangeEnd); + auto D = Diags->Report(Begin, DiagID); + D << MakeCharSourceRange(Features, TokLoc, TokBegin, TokRangeBegin, + TokRangeEnd); + return D; } /// ProcessCharEscape - Parse a standard C escape sequence, which can occur in Index: lib/Parse/Parser.cpp =================================================================== --- lib/Parse/Parser.cpp +++ lib/Parse/Parser.cpp @@ -160,10 +160,15 @@ if (EndLoc.isValid()) Spelling = tok::getPunctuatorSpelling(ExpectedTok); - DiagnosticBuilder DB = - Spelling - ? Diag(EndLoc, DiagID) << FixItHint::CreateInsertion(EndLoc, Spelling) - : Diag(Tok, DiagID); + DiagnosticBuilder DB = [&]() { + if (!Spelling) + return Diag(Tok, DiagID); + + auto D = Diag(EndLoc, DiagID); + D << FixItHint::CreateInsertion(EndLoc, Spelling); + return D; + }(); + if (DiagID == diag::err_expected) DB << ExpectedTok; else if (DiagID == diag::err_expected_after) Index: lib/Sema/SemaDeclObjC.cpp =================================================================== --- lib/Sema/SemaDeclObjC.cpp +++ lib/Sema/SemaDeclObjC.cpp @@ -776,12 +776,12 @@ if (diagLoc.isInvalid()) diagLoc = newTypeParam->getLocStart(); - auto diag = S.Diag(diagLoc, - diag::err_objc_type_param_variance_conflict) - << static_cast(newTypeParam->getVariance()) - << newTypeParam->getDeclName() - << static_cast(prevTypeParam->getVariance()) - << prevTypeParam->getDeclName(); + auto diag = + S.Diag(diagLoc, diag::err_objc_type_param_variance_conflict, + static_cast(newTypeParam->getVariance()), + newTypeParam->getDeclName(), + static_cast(prevTypeParam->getVariance()), + prevTypeParam->getDeclName()); switch (prevTypeParam->getVariance()) { case ObjCTypeParamVariance::Invariant: diag << FixItHint::CreateRemoval(newTypeParam->getVarianceLoc()); @@ -2209,17 +2209,15 @@ *MethodImpl->getReturnType()->getNullability(S.Context); auto nullabilityMethodDecl = *MethodDecl->getReturnType()->getNullability(S.Context); - S.Diag(MethodImpl->getLocation(), - diag::warn_conflicting_nullability_attr_overriding_ret_types) - << DiagNullabilityKind( - nullabilityMethodImpl, - ((MethodImpl->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability) - != 0)) - << DiagNullabilityKind( - nullabilityMethodDecl, - ((MethodDecl->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability) - != 0)); - S.Diag(MethodDecl->getLocation(), diag::note_previous_declaration); + S.Diag(MethodImpl->getLocation(), + diag::warn_conflicting_nullability_attr_overriding_ret_types) + << DiagNullabilityKind(nullabilityMethodImpl, + ((MethodImpl->getObjCDeclQualifier() & + Decl::OBJC_TQ_CSNullability) != 0)) + << DiagNullabilityKind(nullabilityMethodDecl, + ((MethodDecl->getObjCDeclQualifier() & + Decl::OBJC_TQ_CSNullability) != 0)); + S.Diag(MethodDecl->getLocation(), diag::note_previous_declaration); } if (S.Context.hasSameUnqualifiedType(MethodImpl->getReturnType(), Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -11880,34 +11880,34 @@ SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, QualType T) override { - return S.Diag(Loc, diag::err_ice_not_integral) << T; + return S.Diag(Loc, diag::err_ice_not_integral, T); } SemaDiagnosticBuilder diagnoseIncomplete( Sema &S, SourceLocation Loc, QualType T) override { - return S.Diag(Loc, diag::err_ice_incomplete_type) << T; + return S.Diag(Loc, diag::err_ice_incomplete_type, T); } SemaDiagnosticBuilder diagnoseExplicitConv( Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override { - return S.Diag(Loc, diag::err_ice_explicit_conversion) << T << ConvTy; + return S.Diag(Loc, diag::err_ice_explicit_conversion, T, ConvTy); } SemaDiagnosticBuilder noteExplicitConv( Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override { - return S.Diag(Conv->getLocation(), diag::note_ice_conversion_here) - << ConvTy->isEnumeralType() << ConvTy; + return S.Diag(Conv->getLocation(), diag::note_ice_conversion_here, + ConvTy->isEnumeralType(), ConvTy); } SemaDiagnosticBuilder diagnoseAmbiguous( Sema &S, SourceLocation Loc, QualType T) override { - return S.Diag(Loc, diag::err_ice_ambiguous_conversion) << T; + return S.Diag(Loc, diag::err_ice_ambiguous_conversion, T); } SemaDiagnosticBuilder noteAmbiguous( Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override { - return S.Diag(Conv->getLocation(), diag::note_ice_conversion_here) - << ConvTy->isEnumeralType() << ConvTy; + return S.Diag(Conv->getLocation(), diag::note_ice_conversion_here, + ConvTy->isEnumeralType(), ConvTy); } SemaDiagnosticBuilder diagnoseConversion( Index: lib/Sema/SemaExprCXX.cpp =================================================================== --- lib/Sema/SemaExprCXX.cpp +++ lib/Sema/SemaExprCXX.cpp @@ -1385,46 +1385,45 @@ SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, QualType T) override { - return S.Diag(Loc, diag::err_array_size_not_integral) - << S.getLangOpts().CPlusPlus11 << T; + return S.Diag(Loc, diag::err_array_size_not_integral, + S.getLangOpts().CPlusPlus11, T); } SemaDiagnosticBuilder diagnoseIncomplete( Sema &S, SourceLocation Loc, QualType T) override { - return S.Diag(Loc, diag::err_array_size_incomplete_type) - << T << ArraySize->getSourceRange(); + return S.Diag(Loc, diag::err_array_size_incomplete_type, T, + ArraySize->getSourceRange()); } SemaDiagnosticBuilder diagnoseExplicitConv( Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override { - return S.Diag(Loc, diag::err_array_size_explicit_conversion) << T << ConvTy; + return S.Diag(Loc, diag::err_array_size_explicit_conversion, T, ConvTy); } SemaDiagnosticBuilder noteExplicitConv( Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override { - return S.Diag(Conv->getLocation(), diag::note_array_size_conversion) - << ConvTy->isEnumeralType() << ConvTy; + return S.Diag(Conv->getLocation(), diag::note_array_size_conversion, + ConvTy->isEnumeralType(), ConvTy); } SemaDiagnosticBuilder diagnoseAmbiguous( Sema &S, SourceLocation Loc, QualType T) override { - return S.Diag(Loc, diag::err_array_size_ambiguous_conversion) << T; + return S.Diag(Loc, diag::err_array_size_ambiguous_conversion, T); } SemaDiagnosticBuilder noteAmbiguous( Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override { - return S.Diag(Conv->getLocation(), diag::note_array_size_conversion) - << ConvTy->isEnumeralType() << ConvTy; + return S.Diag(Conv->getLocation(), diag::note_array_size_conversion, + ConvTy->isEnumeralType(), ConvTy); } SemaDiagnosticBuilder diagnoseConversion(Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override { - return S.Diag(Loc, - S.getLangOpts().CPlusPlus11 - ? diag::warn_cxx98_compat_array_size_conversion - : diag::ext_array_size_conversion) - << T << ConvTy->isEnumeralType() << ConvTy; + return S.Diag(Loc, S.getLangOpts().CPlusPlus11 + ? diag::warn_cxx98_compat_array_size_conversion + : diag::ext_array_size_conversion, + T, ConvTy->isEnumeralType(), ConvTy); } } SizeDiagnoser(ArraySize); @@ -2634,35 +2633,34 @@ SemaDiagnosticBuilder diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) override { - return S.Diag(Loc, diag::err_delete_operand) << T; + return S.Diag(Loc, diag::err_delete_operand, T); } SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) override { - return S.Diag(Loc, diag::err_delete_incomplete_class_type) << T; + return S.Diag(Loc, diag::err_delete_incomplete_class_type, T); } SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override { - return S.Diag(Loc, diag::err_delete_explicit_conversion) << T << ConvTy; + return S.Diag(Loc, diag::err_delete_explicit_conversion, T, ConvTy); } SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override { - return S.Diag(Conv->getLocation(), diag::note_delete_conversion) - << ConvTy; + return S.Diag(Conv->getLocation(), diag::note_delete_conversion, ConvTy); } SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) override { - return S.Diag(Loc, diag::err_ambiguous_delete_operand) << T; + return S.Diag(Loc, diag::err_ambiguous_delete_operand, T); } SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override { - return S.Diag(Conv->getLocation(), diag::note_delete_conversion) - << ConvTy; + return S.Diag(Conv->getLocation(), diag::note_delete_conversion, + ConvTy); } SemaDiagnosticBuilder diagnoseConversion(Sema &S, SourceLocation Loc, Index: lib/Sema/SemaExprObjC.cpp =================================================================== --- lib/Sema/SemaExprObjC.cpp +++ lib/Sema/SemaExprObjC.cpp @@ -2214,8 +2214,8 @@ SourceManager &SM = S.SourceMgr; edit::Commit ECommit(SM, S.LangOpts); if (refactor(Msg,*S.NSAPIObj, ECommit)) { - DiagnosticBuilder Builder = S.Diag(MsgLoc, DiagID) - << Msg->getSelector() << Msg->getSourceRange(); + DiagnosticBuilder Builder = + S.Diag(MsgLoc, DiagID, Msg->getSelector(), Msg->getSourceRange()); // FIXME: Don't emit diagnostic at all if fixits are non-commitable. if (!ECommit.isCommitable()) return; @@ -3529,11 +3529,11 @@ if (CreateRule != ACC_plusZero) { DiagnosticBuilder DiagB = - (CCK == Sema::CCK_OtherCast && !br) ? - S.Diag(noteLoc, diag::note_arc_cstyle_bridge_transfer) << castExprType : - S.Diag(br ? castExpr->getExprLoc() : noteLoc, - diag::note_arc_bridge_transfer) - << castExprType << br; + (CCK == Sema::CCK_OtherCast && !br) + ? S.Diag(noteLoc, diag::note_arc_cstyle_bridge_transfer, + castExprType) + : S.Diag(br ? castExpr->getExprLoc() : noteLoc, + diag::note_arc_bridge_transfer, castExprType, br); addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen, castType, castExpr, realCast, "__bridge_transfer ", @@ -3569,11 +3569,10 @@ if (CreateRule != ACC_plusZero) { DiagnosticBuilder DiagB = - (CCK == Sema::CCK_OtherCast && !br) ? - S.Diag(noteLoc, diag::note_arc_cstyle_bridge_retained) << castType : - S.Diag(br ? castExpr->getExprLoc() : noteLoc, - diag::note_arc_bridge_retained) - << castType << br; + (CCK == Sema::CCK_OtherCast && !br) + ? S.Diag(noteLoc, diag::note_arc_cstyle_bridge_retained, castType) + : S.Diag(br ? castExpr->getExprLoc() : noteLoc, + diag::note_arc_bridge_retained, castType, br); addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen, castType, castExpr, realCast, "__bridge_retained ", Index: lib/Sema/SemaObjCProperty.cpp =================================================================== --- lib/Sema/SemaObjCProperty.cpp +++ lib/Sema/SemaObjCProperty.cpp @@ -1919,8 +1919,8 @@ if (!macroName.empty()) spelling = macroName; - auto noteDiag = Diag(noteLoc, diag::note_cocoa_naming_declare_family) - << method->getDeclName() << spelling; + auto noteDiag = Diag(noteLoc, diag::note_cocoa_naming_declare_family, + method->getDeclName(), spelling); if (fixItLoc.isValid()) { SmallString<64> fixItText(" "); fixItText += spelling; Index: lib/Sema/SemaOpenMP.cpp =================================================================== --- lib/Sema/SemaOpenMP.cpp +++ lib/Sema/SemaOpenMP.cpp @@ -4768,30 +4768,30 @@ : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, QualType T) override { - return S.Diag(Loc, diag::err_omp_not_integral) << T; + return S.Diag(Loc, diag::err_omp_not_integral, T); } SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) override { - return S.Diag(Loc, diag::err_omp_incomplete_type) << T; + return S.Diag(Loc, diag::err_omp_incomplete_type, T); } SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override { - return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; + return S.Diag(Loc, diag::err_omp_explicit_conversion, T, ConvTy); } SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override { - return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) - << ConvTy->isEnumeralType() << ConvTy; + return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here, + ConvTy->isEnumeralType(), ConvTy); } SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) override { - return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; + return S.Diag(Loc, diag::err_omp_ambiguous_conversion, T); } SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override { - return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) - << ConvTy->isEnumeralType() << ConvTy; + return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here, + ConvTy->isEnumeralType(), ConvTy); } SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, QualType) override { Index: lib/Sema/SemaStmt.cpp =================================================================== --- lib/Sema/SemaStmt.cpp +++ lib/Sema/SemaStmt.cpp @@ -604,35 +604,35 @@ SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, QualType T) override { - return S.Diag(Loc, diag::err_typecheck_statement_requires_integer) << T; + return S.Diag(Loc, diag::err_typecheck_statement_requires_integer, T); } SemaDiagnosticBuilder diagnoseIncomplete( Sema &S, SourceLocation Loc, QualType T) override { - return S.Diag(Loc, diag::err_switch_incomplete_class_type) - << T << Cond->getSourceRange(); + return S.Diag(Loc, diag::err_switch_incomplete_class_type, T, + Cond->getSourceRange()); } SemaDiagnosticBuilder diagnoseExplicitConv( Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override { - return S.Diag(Loc, diag::err_switch_explicit_conversion) << T << ConvTy; + return S.Diag(Loc, diag::err_switch_explicit_conversion , T , ConvTy); } SemaDiagnosticBuilder noteExplicitConv( Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override { - return S.Diag(Conv->getLocation(), diag::note_switch_conversion) - << ConvTy->isEnumeralType() << ConvTy; + return S.Diag(Conv->getLocation(), diag::note_switch_conversion, + ConvTy->isEnumeralType(), ConvTy); } SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) override { - return S.Diag(Loc, diag::err_switch_multiple_conversions) << T; + return S.Diag(Loc, diag::err_switch_multiple_conversions, T); } SemaDiagnosticBuilder noteAmbiguous( Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override { - return S.Diag(Conv->getLocation(), diag::note_switch_conversion) - << ConvTy->isEnumeralType() << ConvTy; + return S.Diag(Conv->getLocation(), diag::note_switch_conversion, + ConvTy->isEnumeralType(), ConvTy); } SemaDiagnosticBuilder diagnoseConversion( @@ -1141,8 +1141,8 @@ if (!UnhandledNames.empty()) { DiagnosticBuilder DB = Diag(CondExpr->getExprLoc(), TheDefaultStmt ? diag::warn_def_missing_case - : diag::warn_missing_case) - << (int)UnhandledNames.size(); + : diag::warn_missing_case, + (int)UnhandledNames.size()); for (size_t I = 0, E = std::min(UnhandledNames.size(), (size_t)3); I != E; ++I) Index: lib/Sema/SemaStmtAsm.cpp =================================================================== --- lib/Sema/SemaStmtAsm.cpp +++ lib/Sema/SemaStmtAsm.cpp @@ -393,9 +393,9 @@ diag::warn_asm_mismatched_size_modifier); if (!SuggestedModifier.empty()) { - auto B = Diag(Piece.getRange().getBegin(), - diag::note_asm_missing_constraint_modifier) - << SuggestedModifier; + auto B = + Diag(Piece.getRange().getBegin(), + diag::note_asm_missing_constraint_modifier, SuggestedModifier); SuggestedModifier = "%" + SuggestedModifier + Piece.getString(); B.AddFixItHint(FixItHint::CreateReplacement(Piece.getRange(), SuggestedModifier)); Index: lib/Sema/SemaTemplateVariadic.cpp =================================================================== --- lib/Sema/SemaTemplateVariadic.cpp +++ lib/Sema/SemaTemplateVariadic.cpp @@ -251,8 +251,8 @@ Locations.push_back(Unexpanded[I].second); } - DiagnosticBuilder DB = Diag(Loc, diag::err_unexpanded_parameter_pack) - << (int)UPPC << (int)Names.size(); + DiagnosticBuilder DB = Diag(Loc, diag::err_unexpanded_parameter_pack, + (int)UPPC, (int)Names.size()); for (size_t I = 0, E = std::min(Names.size(), (size_t)2); I != E; ++I) DB << Names[I]; Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -5611,12 +5611,11 @@ : chunk.Kind == DeclaratorChunk::BlockPointer ? PK_BlockPointer : inFunction? PK_MemberFunctionPointer : PK_MemberPointer; - auto diag = state.getSema().Diag(attr.getLoc(), - diag::warn_nullability_declspec) - << DiagNullabilityKind(mapNullabilityAttrKind(attr.getKind()), - attr.isContextSensitiveKeywordAttribute()) - << type - << static_cast(pointerKind); + auto diag = state.getSema().Diag( + attr.getLoc(), diag::warn_nullability_declspec, + DiagNullabilityKind(mapNullabilityAttrKind(attr.getKind()), + attr.isContextSensitiveKeywordAttribute()), + type, static_cast(pointerKind)); // FIXME: MemberPointer chunks don't carry the location of the *. if (chunk.Kind != DeclaratorChunk::MemberPointer) {