]> granicus.if.org Git - clang/commitdiff
Update the %diff modifer to have an alternate string print when a template tree
authorRichard Trieu <rtrieu@google.com>
Fri, 29 Jun 2012 21:12:16 +0000 (21:12 +0000)
committerRichard Trieu <rtrieu@google.com>
Fri, 29 Jun 2012 21:12:16 +0000 (21:12 +0000)
is selected.  This will allow more flexibility when converting diagnostics to
use template type diffing.

Also updated the internal manual and test cases for correctly keeping the bold
attribute and for tree printing.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159463 91177308-0d34-0410-b5e6-96231b3b80d8

docs/InternalsManual.html
include/clang/Basic/DiagnosticSemaKinds.td
lib/Basic/Diagnostic.cpp
test/Misc/diag-template-diffing-color.cpp

index 76b0c676446820a2c6e2b77b55b6a07a174e6c9d..6a6736891687d19b071431d3d524a7541d0d98fb 100644 (file)
@@ -361,7 +361,8 @@ Clang:</p>
 <tr><td colspan="2"><b>"diff" format</b></td></tr>
 <tr><td>Example:</td><td><tt>"no known conversion %diff{from | to | }1,2"</tt></td></tr>
 <tr><td>Class:</td><td>QualType</td></tr>
-<tr><td>Description</td><td><p>This formatter takes two QualTypes and attempts to print a template difference between the two.  If tree printing is off, the entire text inside the the braces is printed, with the formatted text replacing the pipes.  If tree printing is on, the text is not printed and a type tree is printed after the diagnostic message.</p></td></tr>
+<tr><td>Description</td><td><p>This formatter takes two QualTypes and attempts to print a template difference between the two.  If tree printing is off, the text inside the the braces before the pipe is printed, with the formatted text replacing the $.  If tree printing is on, the text after the pipe is printed and a type tree is printed after the diagnostic message.
+</p></td></tr>
     
 </table>
 
index 6ba2353b341fcaa0f2108d06590815da3c94c206..4ebceed5bf03a6df90ce012a373148db26635cfe 100644 (file)
@@ -1150,22 +1150,21 @@ def err_init_conversion_failed : Error<
   "%select{none|const|restrict|const and restrict|volatile|const and volatile|"
   "volatile and restrict|const, volatile, and restrict}6)}4">;
 
-def err_lvalue_to_rvalue_ref : Error<"rvalue reference to type %0 cannot bind "
-  "to lvalue of type %1">;
+def err_lvalue_to_rvalue_ref : Error<"rvalue reference %diff{to type $ cannot "
+  "bind to lvalue of type $|cannot bind to incompatible lvalue}0,1">;
 def err_lvalue_reference_bind_to_initlist : Error<
   "%select{non-const|volatile}0 lvalue reference to type %1 cannot bind to an "
   "initializer list temporary">;
 def err_lvalue_reference_bind_to_temporary : Error<
-  "%select{non-const|volatile}0 lvalue reference to type %1 cannot bind to a "
-  "temporary of type %2">;
+  "%select{non-const|volatile}0 lvalue reference %diff{to type $ cannot bind "
+  "to a temporary of type $|cannot bind to incompatible temporary}1,2">;
 def err_lvalue_reference_bind_to_unrelated : Error<
-  "%select{non-const|volatile}0 lvalue reference to type %1 cannot bind to a "
-  "value of unrelated type %2">;
+  "%select{non-const|volatile}0 lvalue reference %diff{to type $ cannot bind to a value of unrelated type $|cannot bind to a value of related type}1,2">;
 def err_reference_bind_drops_quals : Error<
-  "binding of reference to type %0 to a value of type %1 drops qualifiers">;
+  "binding of reference %diff{to type $ to a value of type $ drops "
+  "qualifiers|drops qualifiers}0,1">;
 def err_reference_bind_failed : Error<
-  "reference to type %0 could not bind to an %select{rvalue|lvalue}1 of type "
-  "%2">;
+  "reference %diff{to type $ could not bind to an %select{rvalue|lvalue}1 of type $|could not bing to %select{rvalue|lvalue}}0,2">;
 def err_reference_bind_init_list : Error<
   "reference to type %0 cannot bind to an initializer list">;
 def warn_temporary_array_to_pointer_decay : Warning<
@@ -2169,7 +2168,7 @@ def note_ovl_candidate_bad_conv : Note<"candidate "
     "function (the implicit copy assignment operator)|"
     "function (the implicit move assignment operator)|"
     "constructor (inherited)}0%1"
-    " not viable: no known conversion %diff{from | to | }2,3for "
+    " not viable: no known conversion %diff{from $ to $ |}2,3for "
     "%select{%ordinal5 argument|object argument}4"
     "%select{|; dereference the argument with *|"
     "; take the address of the argument with &|"
index 6bf3102b1de01a628c490cacf0a03cbdae70836d..d5ccd64f875bed7cee5e3d1fb5590fc7c0beb66c 100644 (file)
@@ -823,6 +823,9 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
       TDT.ShowColors = getDiags()->ShowColors;
       intptr_t val = reinterpret_cast<intptr_t>(&TDT);
 
+      const char *ArgumentEnd = Argument + ArgumentLen;
+      const char *Pipe = ScanFormat(Argument, ArgumentEnd, '|');
+
       // Print the tree.
       if (getDiags()->PrintTemplateTree) {
         TDT.PrintFromType = true;
@@ -834,18 +837,19 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
                                        FormattedArgs.size(),
                                        Tree, QualTypeVals);
         // If there is no tree information, fall back to regular printing.
-        if (!Tree.empty())
+        if (!Tree.empty()) {
+          FormatDiagnostic(Pipe + 1, ArgumentEnd, OutStr);
           break;
+        }
       }
 
       // Non-tree printing, also the fall-back when tree printing fails.
       // The fall-back is triggered when the types compared are not templates.
-      const char *ArgumentEnd = Argument + ArgumentLen;
-      const char *FirstPipe = ScanFormat(Argument, ArgumentEnd, '|');
-      const char *SecondPipe = ScanFormat(FirstPipe + 1, ArgumentEnd, '|');
+      const char *FirstDollar = ScanFormat(Argument, ArgumentEnd, '$');
+      const char *SecondDollar = ScanFormat(FirstDollar + 1, ArgumentEnd, '$');
 
       // Append before text
-      FormatDiagnostic(Argument, FirstPipe, OutStr);
+      FormatDiagnostic(Argument, FirstDollar, OutStr);
 
       // Append first type
       TDT.PrintTree = false;
@@ -856,7 +860,7 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
                                      FormattedArgs.data(), FormattedArgs.size(),
                                      OutStr, QualTypeVals);
       // Append middle text
-      FormatDiagnostic(FirstPipe + 1, SecondPipe, OutStr);
+      FormatDiagnostic(FirstDollar + 1, SecondDollar, OutStr);
 
       // Append second type
       TDT.PrintFromType = false;
@@ -866,7 +870,7 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
                                      FormattedArgs.data(), FormattedArgs.size(),
                                      OutStr, QualTypeVals);
       // Append end text
-      FormatDiagnostic(SecondPipe + 1, ArgumentEnd, OutStr);
+      FormatDiagnostic(SecondDollar + 1, Pipe, OutStr);
       break;
     }
     
index 502f6843af737e9cdb0b3c9c11d9780a0f1d153e..b944ef2bb0c74241a3562dec5dfd01a9e1efd11d 100644 (file)
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -fcolor-diagnostics %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -fsyntax-only -fcolor-diagnostics -fdiagnostics-show-template-tree %s 2>&1 | FileCheck %s -check-prefix=TREE
 // XFAIL: mingw32,win32
 template<typename> struct foo {};
 void func(foo<int>);
@@ -6,3 +7,13 @@ int main() {
   func(foo<double>());
 }
 // CHECK: {{.*}}candidate function not viable: no known conversion from 'foo<{{.}}[0;1;36mdouble{{.}}[0m>' to 'foo<{{.}}[0;1;36mint{{.}}[0m>' for 1st argument{{.}}[0m
+// TREE: candidate function not viable: no known conversion for 1st argument
+// TREE:  foo<
+// TREE:    [{{.}}[0;1;36mdouble{{.}}[0m != {{.}}[0;1;36mint{{.}}[0m]>{{.}}[0m
+
+foo<int> A;
+foo<double> &B = A;
+// CHECK: {{.*}}non-const lvalue reference to type 'foo<{{.}}[0;1;36mdouble{{.}}[0m{{.}}[1m>' cannot bind to a value of unrelated type 'foo<{{.}}[0;1;36mint{{.}}[0m{{.}}[1m>'{{.}}[0m
+// TREE: non-const lvalue reference cannot bind to a value of related type
+// TREE:   foo<
+// TREE:     [{{.}}[0;1;36mdouble{{.}}[0m{{.}}[1m != {{.}}[0;1;36mint{{.}}[0m{{.}}[1m]>{{.}}[0m