dblaikie created this revision.
dblaikie added a reviewer: rsmith.
dblaikie added a subscriber: cfe-commits.

While there wasn't much use of "return Diag(...) << x" outside Sema (one
each in ARCMigrate, Lex, Parse, and 5 in ClangTidy - which were all just
changed to use named local variables, then stream, then return), in Sema
there were quite a few uses. So this extends Sema::Diag to be a variadic
template allowing the extra parameters to be passed directly rather than
via streaming on the resulting temporary expression.

http://reviews.llvm.org/D12131

Files:
  include/clang/Basic/Diagnostic.h
  include/clang/Sema/Sema.h
  lib/ARCMigrate/TransformActions.cpp
  lib/Lex/LiteralSupport.cpp
  lib/Parse/Parser.cpp
  lib/Sema/SemaDeclObjC.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaExprCXX.cpp
  lib/Sema/SemaExprObjC.cpp
  lib/Sema/SemaObjCProperty.cpp
  lib/Sema/SemaOpenMP.cpp
  lib/Sema/SemaStmt.cpp
  lib/Sema/SemaStmtAsm.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp

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<unsigned>(pointerKind);
+    auto diag = state.getSema().Diag(
+        attr.getLoc(), diag::warn_nullability_declspec,
+        DiagNullabilityKind(mapNullabilityAttrKind(attr.getKind()),
+                            attr.isContextSensitiveKeywordAttribute()),
+        type, static_cast<unsigned>(pointerKind));
 
     // FIXME: MemberPointer chunks don't carry the location of the *.
     if (chunk.Kind != DeclaratorChunk::MemberPointer) {
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/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/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/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/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/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/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/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/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<unsigned>(newTypeParam->getVariance())
-                        << newTypeParam->getDeclName()
-                        << static_cast<unsigned>(prevTypeParam->getVariance())
-                        << prevTypeParam->getDeclName();
+          auto diag =
+              S.Diag(diagLoc, diag::err_objc_type_param_variance_conflict,
+                     static_cast<unsigned>(newTypeParam->getVariance()),
+                     newTypeParam->getDeclName(),
+                     static_cast<unsigned>(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/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/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/ARCMigrate/TransformActions.cpp
===================================================================
--- lib/ARCMigrate/TransformActions.cpp
+++ lib/ARCMigrate/TransformActions.cpp
@@ -675,7 +675,9 @@
                                            SourceRange range) {
   assert(!static_cast<TransformActionsImpl *>(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: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -1051,16 +1051,16 @@
     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
     // possible to conveniently express this as actual move construction). So
     // 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 <typename T, typename... Args>
+  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 <typename... Args>
+  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: 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;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to