ken-matsui created this revision.
Herald added a project: All.
ken-matsui requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay.
Herald added a project: clang.

I implemented a feature to show line numbers with left margins in diagnostics 
like GCC-9 does. Ref: 
https://developers.redhat.com/blog/2019/03/08/usability-improvements-in-gcc-9


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D125078

Files:
  clang/include/clang/Basic/DiagnosticOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/TextDiagnostic.cpp
  clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp
  clang/test/FixIt/fixit-newline-style.c
  clang/test/FixIt/fixit-unicode-with-utf8-output.c
  clang/test/FixIt/fixit-unicode.c
  clang/test/Frontend/diag-show-line-numbers.c
  clang/test/Frontend/source-col-map.c
  clang/test/Lexer/header.cpp
  clang/test/Lexer/string-literal-errors.cpp
  clang/test/Misc/caret-diags-macros.c
  clang/test/Misc/caret-diags-multiline.cpp
  clang/test/Misc/diag-macro-backtrace.c
  clang/test/Misc/message-length.c
  clang/test/Misc/tabstop.c
  clang/test/Misc/unnecessary-elipses.cpp
  clang/test/Misc/unprintable.c
  clang/test/Misc/wrong-encoding.c
  clang/test/Parser/brackets.c
  clang/test/Parser/brackets.cpp
  clang/test/Preprocessor/ucn-pp-identifier.c
  clang/test/SemaCXX/struct-class-redecl.cpp

Index: clang/test/SemaCXX/struct-class-redecl.cpp
===================================================================
--- clang/test/SemaCXX/struct-class-redecl.cpp
+++ clang/test/SemaCXX/struct-class-redecl.cpp
@@ -87,113 +87,113 @@
 /*
 *** 'X' messages ***
 CHECK: warning: struct 'X' was previously declared as a class
-CHECK: {{^}}typedef struct X * X_t;
-CHECK: {{^}}        ^{{$}}
+CHECK: {{^}}    4 | typedef struct X * X_t;
+CHECK: {{^}}      |         ^{{$}}
 CHECK: note: previous use is here
-CHECK: {{^}}class X;
-CHECK: {{^}}      ^{{$}}
+CHECK: {{^}}    3 | class X;
+CHECK: {{^}}      |       ^{{$}}
 CHECK: error: use of 'X' with tag type that does not match previous declaration
-CHECK: {{^}}union X { int x; float y; };
-CHECK: {{^}}^~~~~{{$}}
-CHECK: {{^}}class{{$}}
+CHECK: {{^}}    5 | union X { int x; float y; };
+CHECK: {{^}}      | ^~~~~{{$}}
+CHECK: {{^}}      | class{{$}}
 CHECK: note: previous use is here
-CHECK: {{^}}class X;
-CHECK: {{^}}      ^{{$}}
+CHECK: {{^}}    3 | class X;
+CHECK: {{^}}      |       ^{{$}}
 *** 'Y' messages ***
 CHECK: warning: 'Y' defined as a class template here but
       previously declared as a struct template
-CHECK: {{^}}template<class U> class Y { };
-CHECK: {{^}}                  ^{{$}}
+CHECK: {{^}}    8 | template<class U> class Y { };
+CHECK: {{^}}      |                   ^{{$}}
 CHECK: note: did you mean class here?
-CHECK: {{^}}template<typename T> struct Y;
-CHECK: {{^}}                     ^~~~~~{{$}}
-CHECK: {{^}}                     class{{$}}
+CHECK: {{^}}    7 | template<typename T> struct Y;
+CHECK: {{^}}      |                      ^~~~~~{{$}}
+CHECK: {{^}}      |                      class{{$}}
 *** 'A' messages ***
 CHECK: warning: struct 'A' was previously declared as a class
-CHECK: {{^}}struct A;
-CHECK: {{^}}^{{$}}
+CHECK: {{^}}   18 | struct A;
+CHECK: {{^}}      | ^{{$}}
 CHECK: note: previous use is here
-CHECK: {{^}}class A;
-CHECK: {{^}}      ^{{$}}
+CHECK: {{^}}   17 | class A;
+CHECK: {{^}}      |       ^{{$}}
 *** 'B' messages ***
 CHECK: warning: struct 'B' was previously declared as a class
-CHECK: {{^}}struct B;
-CHECK: {{^}}^{{$}}
+CHECK: {{^}}   23 | struct B;
+CHECK: {{^}}      | ^{{$}}
 CHECK: note: previous use is here
-CHECK: {{^}}class B;
-CHECK: {{^}}      ^{{$}}
+CHECK: {{^}}   21 | class B;
+CHECK: {{^}}      |       ^{{$}}
 CHECK: 'B' defined as a struct here but previously declared as a class
-CHECK: {{^}}struct B {};
-CHECK: {{^}}^{{$}}
+CHECK: {{^}}   24 | struct B {};
+CHECK: {{^}}      | ^{{$}}
 CHECK: note: did you mean struct here?
-CHECK: {{^}}class B;
-CHECK: {{^}}^~~~~{{$}}
-CHECK: {{^}}struct{{$}}
+CHECK: {{^}}   21 | class B;
+CHECK: {{^}}      | ^~~~~{{$}}
+CHECK: {{^}}      | struct{{$}}
 CHECK: note: did you mean struct here?
-CHECK: {{^}}class B;
-CHECK: {{^}}^~~~~{{$}}
-CHECK: {{^}}struct{{$}}
+CHECK: {{^}}   20 | class B;
+CHECK: {{^}}      | ^~~~~{{$}}
+CHECK: {{^}}      | struct{{$}}
 *** 'C' messages ***
 CHECK: warning: struct 'C' was previously declared as a class
-CHECK: {{^}}struct C;
-CHECK: {{^}}^{{$}}
+CHECK: {{^}}   27 | struct C;
+CHECK: {{^}}      | ^{{$}}
 CHECK: note: previous use is here
-CHECK: {{^}}class C;
-CHECK: {{^}}      ^{{$}}
+CHECK: {{^}}   26 | class C;
+CHECK: {{^}}      |       ^{{$}}
 CHECK: warning: class 'C' was previously declared as a struct
-CHECK: {{^}}class C;
-CHECK: {{^}}^{{$}}
+CHECK: {{^}}   30 | class C;
+CHECK: {{^}}      | ^{{$}}
 CHECK: note: previous use is here
-CHECK: {{^}}struct C;
-CHECK: {{^}}       ^{{$}}
+CHECK: {{^}}   27 | struct C;
+CHECK: {{^}}      |        ^{{$}}
 CHECK: warning: struct 'C' was previously declared as a class
-CHECK: {{^}}struct C;
-CHECK: {{^}}^{{$}}
+CHECK: {{^}}   32 | struct C;
+CHECK: {{^}}      | ^{{$}}
 CHECK: note: previous use is here
-CHECK: {{^}}class C;
-CHECK: {{^}}      ^{{$}}
+CHECK: {{^}}   30 | class C;
+CHECK: {{^}}      |       ^{{$}}
 CHECK: warning: 'C' defined as a class here but previously declared as a struct
-CHECK: {{^}}class C {};
-CHECK: {{^}}^{{$}}
+CHECK: {{^}}   34 | class C {};
+CHECK: {{^}}      | ^{{$}}
 CHECK: note: did you mean class here?
-CHECK: {{^}}struct C;
-CHECK: {{^}}^~~~~~{{$}}
-CHECK: {{^}}class{{$}}
+CHECK: {{^}}   32 | struct C;
+CHECK: {{^}}      | ^~~~~~{{$}}
+CHECK: {{^}}      | class{{$}}
 CHECK: note: did you mean class here?
-CHECK: {{^}}struct C;
-CHECK: {{^}}^~~~~~{{$}}
-CHECK: {{^}}class{{$}}
+CHECK: {{^}}   27 | struct C;
+CHECK: {{^}}      | ^~~~~~{{$}}
+CHECK: {{^}}      | class{{$}}
 *** 'D' messages ***
 CHECK: error: redefinition of 'D'
-CHECK: {{^}}class D {};
-CHECK: {{^}}      ^{{$}}
+CHECK: {{^}}   38 | class D {};
+CHECK: {{^}}      |       ^{{$}}
 CHECK: note: previous definition is here
-CHECK: {{^}}struct D {};
-CHECK: {{^}}       ^{{$}}
+CHECK: {{^}}   36 | struct D {};
+CHECK: {{^}}      |        ^{{$}}
 CHECK: warning: class 'D' was previously declared as a struct
-CHECK: {{^}}class D;
-CHECK: {{^}}^{{$}}
+CHECK: {{^}}   40 | class D;
+CHECK: {{^}}      | ^{{$}}
 CHECK: note: previous use is here
-CHECK: {{^}}struct D {};
-CHECK: {{^}}       ^{{$}}
+CHECK: {{^}}   36 | struct D {};
+CHECK: {{^}}      |        ^{{$}}
 CHECK: note: did you mean struct here?
-CHECK: {{^}}class D;
-CHECK: {{^}}^~~~~{{$}}
-CHECK: {{^}}struct{{$}}
+CHECK: {{^}}   40 | class D;
+CHECK: {{^}}      | ^~~~~{{$}}
+CHECK: {{^}}      | struct{{$}}
 *** 'E' messages ***
 *** 'F' messages ***
 *** 'G' messages ***
 CHECK: warning: struct template 'G' was previously declared as a class template
-CHECK: {{^}}template<class U> struct G;
-CHECK: {{^}}                  ^{{$}}
+CHECK: {{^}}   56 | template<class U> struct G;
+CHECK: {{^}}      |                   ^{{$}}
 CHECK: note: previous use is here
-CHECK: {{^}}template<class U> class G;
-CHECK: {{^}}                        ^{{$}}
+CHECK: {{^}}   54 | template<class U> class G;
+CHECK: {{^}}      |                         ^{{$}}
 CHECK: warning: 'G' defined as a struct template here but previously declared as a class template
-CHECK: {{^}}template<class U> struct G {};
-CHECK: {{^}}                  ^{{$}}
+CHECK: {{^}}   57 | template<class U> struct G {};
+CHECK: {{^}}      |                   ^{{$}}
 CHECK: note: did you mean struct here?
-CHECK: {{^}}template<class U> class G;
-CHECK: {{^}}                  ^~~~~
-CHECK: {{^}}                  struct
+CHECK: {{^}}   54 | template<class U> class G;
+CHECK: {{^}}      |                   ^~~~~
+CHECK: {{^}}      |                   struct
 */
Index: clang/test/Preprocessor/ucn-pp-identifier.c
===================================================================
--- clang/test/Preprocessor/ucn-pp-identifier.c
+++ clang/test/Preprocessor/ucn-pp-identifier.c
@@ -106,8 +106,8 @@
 // expected-warning@-1 {{incomplete universal character name}} expected-note@-1 {{did you mean to use '\u'?}} expected-warning@-1 {{whitespace}}
 // CHECK: note: did you mean to use '\u'?
 // CHECK-NEXT:   #define capital_u_\U00FC
-// CHECK-NEXT: {{^                   \^}}
-// CHECK-NEXT: {{^                   u}}
+// CHECK-NEXT: {{^      |                    \^}}
+// CHECK-NEXT: {{^      |                    u}}
 
 #define \u{}           // expected-warning {{empty delimited universal character name; treating as '\' 'u' '{' '}'}} expected-error {{macro name must be an identifier}}
 #define \u{123456789}  // expected-error {{hex escape sequence out of range}} expected-error {{macro name must be an identifier}}
Index: clang/test/Parser/brackets.cpp
===================================================================
--- clang/test/Parser/brackets.cpp
+++ clang/test/Parser/brackets.cpp
@@ -2,7 +2,7 @@
 // RUN: cp %s %t
 // RUN: not %clang_cc1 -fixit %t -x c++ -DFIXIT
 // RUN: %clang_cc1 -fsyntax-only %t -x c++ -DFIXIT
-// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s -strict-whitespace
+// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits -fno-diagnostics-show-line-numbers %s 2>&1 | FileCheck %s -strict-whitespace
 
 void test1() {
   int a[] = {0,1,1,2,3};
Index: clang/test/Parser/brackets.c
===================================================================
--- clang/test/Parser/brackets.c
+++ clang/test/Parser/brackets.c
@@ -2,7 +2,7 @@
 // RUN: cp %s %t
 // RUN: not %clang_cc1 -fixit %t -x c -DFIXIT
 // RUN: %clang_cc1 -fsyntax-only %t -x c -DFIXIT
-// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s -strict-whitespace
+// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits -fno-diagnostics-show-line-numbers %s 2>&1 | FileCheck %s -strict-whitespace
 
 void test1(void) {
   int a[] = {0,1,1,2,3};
Index: clang/test/Misc/unnecessary-elipses.cpp
===================================================================
--- clang/test/Misc/unnecessary-elipses.cpp
+++ clang/test/Misc/unnecessary-elipses.cpp
@@ -2,14 +2,14 @@
 
 int main() {
     "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
-// CHECK: {{^    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";}}
+// CHECK: {{^    4 |     "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";}}
 
         "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
-// CHECK: {{^  ..."xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";}}
+// CHECK: {{^    7 |   ..."xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";}}
 
 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"        ;
-// CHECK: {{^"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"...}}
+// CHECK: {{^   10 | "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"...}}
 
         "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"        ;
-// CHECK: {{^  ..."xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"...}}
+// CHECK: {{^   13 |   ..."xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"...}}
 }
Index: clang/test/Misc/tabstop.c
===================================================================
--- clang/test/Misc/tabstop.c
+++ clang/test/Misc/tabstop.c
@@ -14,20 +14,20 @@
 // tab at column 10
 void* d =	1;
 
-//CHECK-3: {{^   void\* a = 1;}}
-//CHECK-3: {{^      void\* b = 1;}}
-//CHECK-3: {{^      void\* c = 1;}}
-//CHECK-3: {{^void\* d =   1;}}
+//CHECK-3: {{^    6 |    void\* a = 1;}}
+//CHECK-3: {{^    9 |       void\* b = 1;}}
+//CHECK-3: {{^   12 |       void\* c = 1;}}
+//CHECK-3: {{^   15 | void\* d =   1;}}
 
-//CHECK-4: {{^    void\* a = 1;}}
-//CHECK-4: {{^        void\* b = 1;}}
-//CHECK-4: {{^    void\* c = 1;}}
-//CHECK-4: {{^void\* d =   1;}}
+//CHECK-4: {{^    6 |     void\* a = 1;}}
+//CHECK-4: {{^    9 |         void\* b = 1;}}
+//CHECK-4: {{^   12 |     void\* c = 1;}}
+//CHECK-4: {{^   15 | void\* d =   1;}}
 
-//CHECK-5: {{^     void\* a = 1;}}
-//CHECK-5: {{^          void\* b = 1;}}
-//CHECK-5: {{^     void\* c = 1;}}
-//CHECK-5: {{^void\* d = 1;}}
+//CHECK-5: {{^    6 |      void\* a = 1;}}
+//CHECK-5: {{^    9 |           void\* b = 1;}}
+//CHECK-5: {{^   12 |      void\* c = 1;}}
+//CHECK-5: {{^   15 | void\* d = 1;}}
 
 // Test code modification hints
 
@@ -40,17 +40,17 @@
 	{}
 }
 
-// CHECK-3: {{^   }}if (0 & 1   == 1)
-// CHECK-3: {{^   }}        (       )
-// CHECK-3: {{^   }}if (1 == 0  & 1)
-// CHECK-3: {{^   }}    (     )
+// CHECK-3: {{^   36 | }}if (0 & 1   == 1)
+// CHECK-3: {{^      | }}        (       )
+// CHECK-3: {{^   39 | }}if (1 == 0  & 1)
+// CHECK-3: {{^      | }}    (     )
 
-// CHECK-4: {{^    }}if (0   & 1 == 1)
-// CHECK-4: {{^    }}          (     )
-// CHECK-4: {{^    }}if (1 == 0  & 1)
-// CHECK-4: {{^    }}    (     )
+// CHECK-4: {{^   36 | }}if (0   & 1 == 1)
+// CHECK-4: {{^      | }}          (     )
+// CHECK-4: {{^   39 | }}if (1 == 0  & 1)
+// CHECK-4: {{^      | }}    (     )
 
-// CHECK-5: {{^     }}if (0     & 1  == 1)
-// CHECK-5: {{^     }}            (      )
-// CHECK-5: {{^     }}if (1 == 0     & 1)
-// CHECK-5: {{^     }}    (     )
+// CHECK-5: {{^   36 | }}if (0     & 1  == 1)
+// CHECK-5: {{^      | }}            (      )
+// CHECK-5: {{^   39 | }}if (1 == 0     & 1)
+// CHECK-5: {{^      | }}    (     )
Index: clang/test/Misc/message-length.c
===================================================================
--- clang/test/Misc/message-length.c
+++ clang/test/Misc/message-length.c
@@ -28,7 +28,7 @@
 #pragma STDC CX_LIMITED_RANGE    // some long comment text and a brace, eh {}
 
 // CHECK: FILE:23:78
-// CHECK: {{^  ...// some long comment text and a brace, eh {}}}
+// CHECK: {{^      |   ...// some long comment text and a brace, eh {}}}
 
 struct A { int x; };
 void h(struct A *a) {
Index: clang/test/Misc/diag-macro-backtrace.c
===================================================================
--- clang/test/Misc/diag-macro-backtrace.c
+++ clang/test/Misc/diag-macro-backtrace.c
@@ -55,12 +55,12 @@
 ADD(L, foo)
 // CHECK:    error: expected identifier or '('
 // CHECK:    ADD(L, foo)
-// CHECK: {{^\^}}
+// CHECK: {{^      | \^}}
 // CHECK:    note: expanded from macro 'ADD'
 // CHECK:    #define ADD(a, b) a ## #b
-// CHECK: {{^                  \^}}
+// CHECK: {{^      |                   \^}}
 // CHECK:    note: expanded from here
 // CHECK:    L"foo"
-// CHECK: {{^\^}}
+// CHECK: {{^      | \^}}
 
 // CHECK: 2 errors generated.
Index: clang/test/Misc/caret-diags-multiline.cpp
===================================================================
--- clang/test/Misc/caret-diags-multiline.cpp
+++ clang/test/Misc/caret-diags-multiline.cpp
@@ -5,18 +5,18 @@
 // Check we expand the range as much as possible within the limit.
 
 // CHECK:      warning: variable 'a' is used uninitialized whenever 'if' condition is true
-// CHECK-NEXT: {{^}}  if (cond) {
-// CHECK-NEXT: {{^}}      ^~~~{{$}}
+// CHECK-NEXT: {{^}}   23 |   if (cond) {
+// CHECK-NEXT: {{^}}      |       ^~~~{{$}}
 // CHECK-NEXT: note: uninitialized use occurs here
-// CHECK-NEXT: {{^}}  return a;
-// CHECK-NEXT: {{^}}         ^
+// CHECK-NEXT: {{^}}   28 |   return a;
+// CHECK-NEXT: {{^}}      |          ^
 // CHECK-NEXT: note: remove the 'if' if its condition is always false
-// CHECK-NEXT: {{^}}  if (cond) {
-// CHECK-NEXT: {{^}}  ^~~~~~~~~~~{{$}}
-// CHECK-NEXT: {{^}}    line(1);
-// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
-// CHECK-NEXT: {{^}}  } else {
-// CHECK-NEXT: {{^}}~~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}   23 |   if (cond) {
+// CHECK-NEXT: {{^}}      |   ^~~~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}   24 |     line(1);
+// CHECK-NEXT: {{^}}      | ~~~~~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}   25 |   } else {
+// CHECK-NEXT: {{^}}      | ~~~~~~~~~{{$}}
 // CHECK-NEXT: note: initialize the variable
 int f1(int cond) {
   int a;
@@ -29,20 +29,20 @@
 }
 
 // CHECK:      warning: variable 'a' is used uninitialized whenever 'if' condition is true
-// CHECK-NEXT: {{^}}  if (cond) {
-// CHECK-NEXT: {{^}}      ^~~~{{$}}
+// CHECK-NEXT: {{^}}   49 |   if (cond) {
+// CHECK-NEXT: {{^}}      |       ^~~~{{$}}
 // CHECK-NEXT: note: uninitialized use occurs here
-// CHECK-NEXT: {{^}}  return a;
-// CHECK-NEXT: {{^}}         ^
+// CHECK-NEXT: {{^}}   55 |   return a;
+// CHECK-NEXT: {{^}}      |          ^
 // CHECK-NEXT: note: remove the 'if' if its condition is always false
-// CHECK-NEXT: {{^}}  if (cond) {
-// CHECK-NEXT: {{^}}  ^~~~~~~~~~~{{$}}
-// CHECK-NEXT: {{^}}    line(1);
-// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
-// CHECK-NEXT: {{^}}    line(2);
-// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
-// CHECK-NEXT: {{^}}  } else {
-// CHECK-NEXT: {{^}}~~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}   49 |   if (cond) {
+// CHECK-NEXT: {{^}}      |   ^~~~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}   50 |     line(1);
+// CHECK-NEXT: {{^}}      | ~~~~~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}   51 |     line(2);
+// CHECK-NEXT: {{^}}      | ~~~~~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}   52 |   } else {
+// CHECK-NEXT: {{^}}      | ~~~~~~~~~{{$}}
 // CHECK-NEXT: note: initialize the variable
 int f2(int cond) {
   int a;
@@ -56,22 +56,22 @@
 }
 
 // CHECK:      warning: variable 'a' is used uninitialized whenever 'if' condition is true
-// CHECK-NEXT: {{^}}  if (cond) {
-// CHECK-NEXT: {{^}}      ^~~~{{$}}
+// CHECK-NEXT: {{^}}   78 |   if (cond) {
+// CHECK-NEXT: {{^}}      |       ^~~~{{$}}
 // CHECK-NEXT: note: uninitialized use occurs here
-// CHECK-NEXT: {{^}}  return a;
-// CHECK-NEXT: {{^}}         ^
+// CHECK-NEXT: {{^}}   85 |   return a;
+// CHECK-NEXT: {{^}}      |          ^
 // CHECK-NEXT: note: remove the 'if' if its condition is always false
-// CHECK-NEXT: {{^}}  if (cond) {
-// CHECK-NEXT: {{^}}  ^~~~~~~~~~~{{$}}
-// CHECK-NEXT: {{^}}    line(1);
-// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
-// CHECK-NEXT: {{^}}    line(2);
-// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
-// CHECK-NEXT: {{^}}    line(3);
-// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
-// CHECK-NEXT: {{^}}  } else {
-// CHECK-NEXT: {{^}}~~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}   78 |   if (cond) {
+// CHECK-NEXT: {{^}}      |   ^~~~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}   79 |     line(1);
+// CHECK-NEXT: {{^}}      | ~~~~~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}   80 |     line(2);
+// CHECK-NEXT: {{^}}      | ~~~~~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}   81 |     line(3);
+// CHECK-NEXT: {{^}}      | ~~~~~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}   82 |   } else {
+// CHECK-NEXT: {{^}}      | ~~~~~~~~~{{$}}
 // CHECK-NEXT: note: initialize the variable
 int f3(int cond) {
   int a;
@@ -86,22 +86,22 @@
 }
 
 // CHECK:      warning: variable 'a' is used uninitialized whenever 'if' condition is true
-// CHECK-NEXT: {{^}}  if (cond) {
-// CHECK-NEXT: {{^}}      ^~~~{{$}}
+// CHECK-NEXT: {{^}}  108 |   if (cond) {
+// CHECK-NEXT: {{^}}      |       ^~~~{{$}}
 // CHECK-NEXT: note: uninitialized use occurs here
-// CHECK-NEXT: {{^}}  return a;
-// CHECK-NEXT: {{^}}         ^
+// CHECK-NEXT: {{^}}  116 |   return a;
+// CHECK-NEXT: {{^}}      |          ^
 // CHECK-NEXT: note: remove the 'if' if its condition is always false
-// CHECK-NEXT: {{^}}  if (cond) {
-// CHECK-NEXT: {{^}}  ^~~~~~~~~~~{{$}}
-// CHECK-NEXT: {{^}}    line(1);
-// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
-// CHECK-NEXT: {{^}}    line(2);
-// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
-// CHECK-NEXT: {{^}}    line(3);
-// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
-// CHECK-NEXT: {{^}}    line(4);
-// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}  108 |   if (cond) {
+// CHECK-NEXT: {{^}}      |   ^~~~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}  109 |     line(1);
+// CHECK-NEXT: {{^}}      | ~~~~~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}  110 |     line(2);
+// CHECK-NEXT: {{^}}      | ~~~~~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}  111 |     line(3);
+// CHECK-NEXT: {{^}}      | ~~~~~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}  112 |     line(4);
+// CHECK-NEXT: {{^}}      | ~~~~~~~~~~~~{{$}}
 // CHECK-NEXT: note: initialize the variable
 int f4(int cond) {
   int a;
@@ -117,22 +117,22 @@
 }
 
 // CHECK:      warning: variable 'a' is used uninitialized whenever 'if' condition is true
-// CHECK-NEXT: {{^}}  if (cond) {
-// CHECK-NEXT: {{^}}      ^~~~{{$}}
+// CHECK-NEXT: {{^}}  139 |   if (cond) {
+// CHECK-NEXT: {{^}}      |       ^~~~{{$}}
 // CHECK-NEXT: note: uninitialized use occurs here
-// CHECK-NEXT: {{^}}  return a;
-// CHECK-NEXT: {{^}}         ^
+// CHECK-NEXT: {{^}}  148 |   return a;
+// CHECK-NEXT: {{^}}      |          ^
 // CHECK-NEXT: note: remove the 'if' if its condition is always false
-// CHECK-NEXT: {{^}}  if (cond) {
-// CHECK-NEXT: {{^}}  ^~~~~~~~~~~{{$}}
-// CHECK-NEXT: {{^}}    line(1);
-// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
-// CHECK-NEXT: {{^}}    line(2);
-// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
-// CHECK-NEXT: {{^}}    line(3);
-// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
-// CHECK-NEXT: {{^}}    line(4);
-// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}  139 |   if (cond) {
+// CHECK-NEXT: {{^}}      |   ^~~~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}  140 |     line(1);
+// CHECK-NEXT: {{^}}      | ~~~~~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}  141 |     line(2);
+// CHECK-NEXT: {{^}}      | ~~~~~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}  142 |     line(3);
+// CHECK-NEXT: {{^}}      | ~~~~~~~~~~~~{{$}}
+// CHECK-NEXT: {{^}}  143 |     line(4);
+// CHECK-NEXT: {{^}}      | ~~~~~~~~~~~~{{$}}
 // CHECK-NEXT: note: initialize the variable
 int f5(int cond) {
   int a;
@@ -155,13 +155,13 @@
 // CHECK:      error: no matching function for call to 'g
 
 // CHECK:      note: candidate template ignored: substitution failure
-// CHECK-NEXT: {{^}}decltype(T()
-// CHECK-NEXT: {{^}}         ~{{$}}
-// CHECK-NEXT: {{^}}    + 1
-// CHECK-NEXT: {{^}}    + 2
-// CHECK-NEXT: {{^}}    + 3
-// CHECK-NEXT: {{^}}void g();
-// CHECK-NEXT: {{^}}     ^{{$}}
+// CHECK-NEXT: {{^}}  166 | decltype(T()
+// CHECK-NEXT: {{^}}      |          ~{{$}}
+// CHECK-NEXT: {{^}}  167 |     + 1
+// CHECK-NEXT: {{^}}  168 |     + 2
+// CHECK-NEXT: {{^}}  169 |     + 3
+// CHECK-NEXT: {{^}}  170 | void g();
+// CHECK-NEXT: {{^}}      |      ^{{$}}
 template<typename T>
 decltype(T()
     + 1
@@ -170,8 +170,8 @@
 void g();
 
 // CHECK:      note: candidate template ignored: substitution failure
-// CHECK-NEXT: {{^}}void g();
-// CHECK-NEXT: {{^}}     ^{{$}}
+// CHECK-NEXT: {{^}}  181 | void g();
+// CHECK-NEXT: {{^}}      |      ^{{$}}
 template<typename T>
 decltype(T()
     + 1
Index: clang/test/Misc/caret-diags-macros.c
===================================================================
--- clang/test/Misc/caret-diags-macros.c
+++ clang/test/Misc/caret-diags-macros.c
@@ -42,7 +42,7 @@
   // Also check that the 'caret' printing agrees with the location here where
   // its easy to FileCheck.
   // CHECK-NEXT:      macro_args3(11);
-  // CHECK-NEXT: {{^              \^~}}
+  // CHECK-NEXT: {{^      |               \^~}}
 
   macro_many_args3(
     1,
@@ -71,7 +71,7 @@
   // This caret location needs to be printed *inside* a different macro's
   // arguments.
   // CHECK-NEXT:        macro_args2(22),
-  // CHECK-NEXT: {{^                \^~}}
+  // CHECK-NEXT: {{^      |                 \^~}}
   // CHECK: {{.*}}:32:36: note: expanded from macro 'macro_args2'
   // CHECK: {{.*}}:31:24: note: expanded from macro 'macro_args1'
   // CHECK: {{.*}}:37:55: note: expanded from macro 'macro_many_args3'
@@ -87,7 +87,7 @@
   variadic_args3(1, 22, 3, 4);
   // CHECK: {{.*}}:87:21: warning: expression result unused
   // CHECK-NEXT:      variadic_args3(1, 22, 3, 4);
-  // CHECK-NEXT: {{^                    \^~}}
+  // CHECK-NEXT: {{^      |                     \^~}}
   // CHECK: {{.*}}:84:53: note: expanded from macro 'variadic_args3'
   // CHECK: {{.*}}:83:50: note: expanded from macro 'variadic_args2'
   // CHECK: {{.*}}:82:35: note: expanded from macro 'variadic_args1'
@@ -109,29 +109,29 @@
   variadic_pasting_args3a(1, 2, 3, 4);
   // CHECK:        {{.*}}:109:3: warning: expression result unused
   // CHECK-NEXT:     variadic_pasting_args3a(1, 2, 3, 4);
-  // CHECK-NEXT: {{  \^~~~~~~~~~~~~~~~~~~~~~~}}
+  // CHECK-NEXT: {{      |   \^~~~~~~~~~~~~~~~~~~~~~~}}
   // CHECK:        {{.*}}:100:44: note: expanded from macro 'variadic_pasting_args3a'
   // CHECK-NEXT:   #define variadic_pasting_args3a(x, y, ...) variadic_pasting_args2a(x, y, __VA_ARGS__)
-  // CHECK-NEXT: {{                                           \^~~~~~~~~~~~~~~~~~~~~~~}}
+  // CHECK-NEXT: {{      |                                            \^~~~~~~~~~~~~~~~~~~~~~~}}
   // CHECK:        {{.*}}:98:70: note: expanded from macro 'variadic_pasting_args2a'
   // CHECK-NEXT:   #define variadic_pasting_args2a(x, y, ...) variadic_pasting_args1(x, y ## __VA_ARGS__)
-  // CHECK-NEXT: {{                                                                     \^~~~~~~~~~~~~~~~}}
+  // CHECK-NEXT: {{      |                                                                      \^~~~~~~~~~~~~~~~}}
   // CHECK:        {{.*}}:96:41: note: expanded from macro 'variadic_pasting_args1'
   // CHECK-NEXT:   #define variadic_pasting_args1(x, y, z) y
-  // CHECK-NEXT: {{                                        \^}}
+  // CHECK-NEXT: {{      |                                         \^}}
 }
 
 #define BAD_CONDITIONAL_OPERATOR (2<3)?2:3
 int test4 = BAD_CONDITIONAL_OPERATOR+BAD_CONDITIONAL_OPERATOR;
 // CHECK:         {{.*}}:124:39: note: expanded from macro 'BAD_CONDITIONAL_OPERATOR'
 // CHECK-NEXT:    #define BAD_CONDITIONAL_OPERATOR (2<3)?2:3
-// CHECK-NEXT: {{^                                      \^}}
+// CHECK-NEXT: {{^      |                                       \^}}
 // CHECK:         {{.*}}:124:39: note: expanded from macro 'BAD_CONDITIONAL_OPERATOR'
 // CHECK-NEXT:    #define BAD_CONDITIONAL_OPERATOR (2<3)?2:3
-// CHECK-NEXT: {{^                                      \^}}
+// CHECK-NEXT: {{^      |                                       \^}}
 // CHECK:         {{.*}}:124:39: note: expanded from macro 'BAD_CONDITIONAL_OPERATOR'
 // CHECK-NEXT:    #define BAD_CONDITIONAL_OPERATOR (2<3)?2:3
-// CHECK-NEXT: {{^                                 ~~~~~\^~~~}}
+// CHECK-NEXT: {{^      |                                  ~~~~~\^~~~}}
 
 #define QMARK ?
 #define TWOL (2<
@@ -139,32 +139,32 @@
 int x = X;
 // CHECK:         {{.*}}:139:9: note: place parentheses around the '+' expression to silence this warning
 // CHECK-NEXT:    int x = X;
-// CHECK-NEXT: {{^        \^}}
+// CHECK-NEXT: {{^      |         \^}}
 // CHECK-NEXT:    {{.*}}:138:21: note: expanded from macro 'X'
 // CHECK-NEXT:    #define X 1+TWOL 3) QMARK 4:5
-// CHECK-NEXT: {{^          ~~~~~~~~~ \^}}
+// CHECK-NEXT: {{^      |           ~~~~~~~~~ \^}}
 // CHECK-NEXT:    {{.*}}:136:15: note: expanded from macro 'QMARK'
 // CHECK-NEXT:    #define QMARK ?
-// CHECK-NEXT: {{^              \^}}
+// CHECK-NEXT: {{^      |               \^}}
 // CHECK-NEXT:    {{.*}}:139:9: note: place parentheses around the '?:' expression to evaluate it first
 // CHECK-NEXT:    int x = X;
-// CHECK-NEXT: {{^        \^}}
+// CHECK-NEXT: {{^      |         \^}}
 // CHECK-NEXT:    {{.*}}:138:21: note: expanded from macro 'X'
 // CHECK-NEXT:    #define X 1+TWOL 3) QMARK 4:5
-// CHECK-NEXT: {{^            ~~~~~~~~\^~~~~~~~~}}
+// CHECK-NEXT: {{^      |             ~~~~~~~~\^~~~~~~~~}}
 
 #define ONEPLUS 1+
 #define Y ONEPLUS (2<3) QMARK 4:5
 int y = Y;
 // CHECK:         {{.*}}:158:9: warning: operator '?:' has lower precedence than '+'; '+' will be evaluated first
 // CHECK-NEXT:    int y = Y;
-// CHECK-NEXT: {{^        \^}}
+// CHECK-NEXT: {{^      |         \^}}
 // CHECK-NEXT:    {{.*}}:157:25: note: expanded from macro 'Y'
 // CHECK-NEXT:    #define Y ONEPLUS (2<3) QMARK 4:5
-// CHECK-NEXT: {{^          ~~~~~~~~~~~~~ \^}}
+// CHECK-NEXT: {{^      |           ~~~~~~~~~~~~~ \^}}
 // CHECK-NEXT:    {{.*}}:136:15: note: expanded from macro 'QMARK'
 // CHECK-NEXT:    #define QMARK ?
-// CHECK-NEXT: {{^              \^}}
+// CHECK-NEXT: {{^      |               \^}}
 
 // PR14399
 void iequals(int,int,int);
@@ -175,10 +175,10 @@
 }
 // CHECK:         {{.*}}:174:21: warning: operator '?:' has lower precedence than '+'
 // CHECK-NEXT:      iequals(__LINE__, BARC(123, (456 < 345), 789), 8);
-// CHECK-NEXT: {{^                    \^~~~~~~~~~~~~~~~~~~~~~~~~~~}}
+// CHECK-NEXT: {{^      |                     \^~~~~~~~~~~~~~~~~~~~~~~~~~~}}
 // CHECK-NEXT:    {{.*}}:173:41: note: expanded from macro 'BARC'
 // CHECK-NEXT:    #define /* */ BARC(c, /* */b, a) (a + b ? c : c)
-// CHECK-NEXT: {{^                                  ~~~~~ \^}}
+// CHECK-NEXT: {{^      |                                   ~~~~~ \^}}
 
 #define APPEND2(NUM, SUFF) -1 != NUM ## SUFF
 #define APPEND(NUM, SUFF) APPEND2(NUM, SUFF)
@@ -189,16 +189,16 @@
 
 // CHECK:         {{.*}}:187:5: warning: left side of operator converted from negative value to unsigned: -1 to 18446744073709551615
 // CHECK-NEXT:    #if UTARG_MAX_U
-// CHECK-NEXT: {{^    \^~~~~~~~~~~}}
+// CHECK-NEXT: {{^      |     \^~~~~~~~~~~}}
 // CHECK-NEXT:    {{.*}}:185:21: note: expanded from macro 'UTARG_MAX_U'
 // CHECK-NEXT:    #define UTARG_MAX_U APPEND (MAX_UINT, UL)
-// CHECK-NEXT: {{^                    \^~~~~~~~~~~~~~~~~~~~~}}
+// CHECK-NEXT: {{^      |                     \^~~~~~~~~~~~~~~~~~~~~}}
 // CHECK-NEXT:    {{.*}}:184:27: note: expanded from macro 'APPEND'
 // CHECK-NEXT:    #define APPEND(NUM, SUFF) APPEND2(NUM, SUFF)
-// CHECK-NEXT: {{^                          \^~~~~~~~~~~~~~~~~~}}
+// CHECK-NEXT: {{^      |                           \^~~~~~~~~~~~~~~~~~}}
 // CHECK-NEXT:    {{.*}}:183:31: note: expanded from macro 'APPEND2'
 // CHECK-NEXT:    #define APPEND2(NUM, SUFF) -1 != NUM ## SUFF
-// CHECK-NEXT: {{^                           ~~ \^  ~~~~~~~~~~~}}
+// CHECK-NEXT: {{^      |                            ~~ \^  ~~~~~~~~~~~}}
 
 unsigned long strlen_test(const char *s);
 #define __darwin_obsz(object) __builtin_object_size (object, 1)
@@ -212,14 +212,14 @@
 }
 // CHECK:         {{.*}}:210:62: warning: format specifies type 'int' but the argument has type 'unsigned long'
 // CHECK-NEXT:    Csprintf(pMsgBuf,"\nEnter minimum anagram length (2-%1d): ", strlen_test(pKeepBuf));
-// CHECK-NEXT: {{^                                                    ~~~      \^~~~~~~~~~~~~~~~~~~~~}}
-// CHECK-NEXT: {{^                                                    %1lu}}
+// CHECK-NEXT: {{^      |                                                     ~~~      \^~~~~~~~~~~~~~~~~~~~~}}
+// CHECK-NEXT: {{^      |                                                     %1lu}}
 // CHECK-NEXT:    {{.*}}:208:21: note: expanded from macro 'Csprintf'
 // CHECK-NEXT:    #define Csprintf    sprintf2
-// CHECK-NEXT: {{^                    \^}}
+// CHECK-NEXT: {{^      |                     \^}}
 // CHECK-NEXT:    {{.*}}:206:56: note: expanded from macro 'sprintf2'
 // CHECK-NEXT:      __builtin___sprintf_chk (str, 0, __darwin_obsz(str), __VA_ARGS__)
-// CHECK-NEXT: {{^                                                       \^~~~~~~~~~~}}
+// CHECK-NEXT: {{^      |                                                        \^~~~~~~~~~~}}
 
 #define SWAP_AND_APPLY(arg, macro) macro arg
 #define APPLY(macro, arg) macro arg
Index: clang/test/Lexer/string-literal-errors.cpp
===================================================================
--- clang/test/Lexer/string-literal-errors.cpp
+++ clang/test/Lexer/string-literal-errors.cpp
@@ -2,26 +2,26 @@
 
 void foo() {
   (void)"\q \u123z \x \U \U123 \U12345 \u123 \xyzzy \777 \U"
-  // CHECK: {{^  \(void\)"\\q \\u123z \\x \\U \\U123 \\U12345 \\u123 \\xyzzy \\777 \\U"$}}
+  // CHECK: {{^    4 |   \(void\)"\\q \\u123z \\x \\U \\U123 \\U12345 \\u123 \\xyzzy \\777 \\U"$}}
   //
   //              (void)"\q \u123z \x \U \U123 \U12345 \u123 \xyzzy \777 \U"
-  // CHECK: {{^         \^~$}}
-  // CHECK: {{^            \^~~~~$}}
-  // CHECK: {{^                   \^~$}}
-  // CHECK: {{^                      \^~$}}
-  // CHECK: {{^                         \^~~~~$}}
-  // CHECK: {{^                               \^~~~~~~$}}
-  // CHECK: {{^                                       \^~~~~$}}
-  // CHECK: {{^                                             \^~$}}
-  // CHECK: {{^                                                    \^~~~$}}
-  // CHECK: {{^                                                         \^~$}}
+  // CHECK: {{^      |          \^~$}}
+  // CHECK: {{^      |             \^~~~~$}}
+  // CHECK: {{^      |                    \^~$}}
+  // CHECK: {{^      |                       \^~$}}
+  // CHECK: {{^      |                          \^~~~~$}}
+  // CHECK: {{^      |                                \^~~~~~~$}}
+  // CHECK: {{^      |                                        \^~~~~$}}
+  // CHECK: {{^      |                                              \^~$}}
+  // CHECK: {{^      |                                                     \^~~~$}}
+  // CHECK: {{^      |                                                          \^~$}}
 
   "123 \x \z";
-  // CHECK: {{^  "123 \\x \\z";$}}
+  // CHECK: {{^   19 |   "123 \\x \\z";$}}
   //
   //              "123 \x \z";
-  // CHECK: {{^       \^~$}}
-  // CHECK: {{^          \^~$}}
+  // CHECK: {{^      |        \^~$}}
+  // CHECK: {{^      |           \^~$}}
 }
 
 #define foo() lots and lots of tokens, need at least 8 to fill up the smallvector buffer #BadThingsHappenNow
Index: clang/test/Lexer/header.cpp
===================================================================
--- clang/test/Lexer/header.cpp
+++ clang/test/Lexer/header.cpp
@@ -11,22 +11,22 @@
 #include "Inputs/bad-header-guard.h"
 // CHECK: In file included from {{.*}}header.cpp:{{[0-9]*}}:
 // CHECK: {{.*}}bad-header-guard.h:1:9: warning: 'bad_header_guard' is used as a header guard here, followed by #define of a different macro
-// CHECK: {{^}}#ifndef bad_header_guard
-// CHECK: {{^}}        ^~~~~~~~~~~~~~~~
+// CHECK: {{^}}    1 | #ifndef bad_header_guard
+// CHECK: {{^}}      |         ^~~~~~~~~~~~~~~~
 // CHECK: {{.*}}bad-header-guard.h:2:9: note: 'bad_guard' is defined here; did you mean 'bad_header_guard'?
-// CHECK: {{^}}#define bad_guard
-// CHECK: {{^}}        ^~~~~~~~~
-// CHECK: {{^}}        bad_header_guard
+// CHECK: {{^}}    2 | #define bad_guard
+// CHECK: {{^}}      |         ^~~~~~~~~
+// CHECK: {{^}}      |         bad_header_guard
 
 #include "Inputs/bad-header-guard-defined.h"
 // CHECK: In file included from {{.*}}header.cpp:{{[0-9]*}}:
 // CHECK: {{.*}}bad-header-guard-defined.h:1:2: warning: 'foo' is used as a header guard here, followed by #define of a different macro
-// CHECK: {{^}}#if !defined(foo)
-// CHECK: {{^}} ^~
+// CHECK: {{^}}    1 | #if !defined(foo)
+// CHECK: {{^}}      |  ^~
 // CHECK: {{.*}}bad-header-guard-defined.h:2:9: note: 'goo' is defined here; did you mean 'foo'?
-// CHECK: {{^}}#define goo
-// CHECK: {{^}}        ^~~
-// CHECK: {{^}}        foo
+// CHECK: {{^}}    2 | #define goo
+// CHECK: {{^}}      |         ^~~
+// CHECK: {{^}}      |         foo
 
 #include "Inputs/multiple.h"
 #include "Inputs/multiple.h"
@@ -34,11 +34,11 @@
 #include "Inputs/multiple.h"
 // CHECK: In file included from {{.*}}header.cpp:{{[0-9]*}}:
 // CHECK: {{.*}}multiple.h:1:9: warning: 'multiple' is used as a header guard here, followed by #define of a different macro
-// CHECK: {{^}}#ifndef multiple
-// CHECK: {{^}}        ^~~~~~~~
+// CHECK: {{^}}    1 | #ifndef multiple
+// CHECK: {{^}}      |         ^~~~~~~~
 // CHECK: {{.*}}multiple.h:2:9: note: 'multi' is defined here; did you mean 'multiple'?
-// CHECK: {{^}}#define multi
-// CHECK: {{^}}        ^~~~~
-// CHECK: {{^}}        multiple
+// CHECK: {{^}}    2 | #define multi
+// CHECK: {{^}}      |         ^~~~~
+// CHECK: {{^}}      |         multiple
 
 // CHECK: 3 warnings generated.
Index: clang/test/Frontend/source-col-map.c
===================================================================
--- clang/test/Frontend/source-col-map.c
+++ clang/test/Frontend/source-col-map.c
@@ -21,13 +21,13 @@
 void test1(Unknown* b);  // αααα αααα αααα αααα αααα αααα αααα αααα αααα αααα αααα
 // CHECK: unknown type name 'Unknown'
 // CHECK-NEXT: void test1(Unknown* b);  // αααα αααα αααα αααα αααα αααα αααα ααα...
-// CHECK-NEXT: {{^           \^$}}
+// CHECK-NEXT: {{^      |            \^$}}
 
 void test2(Unknown* b);  // αααα αααα αααα αααα αααα αααα αααα αααα αααα
 
 // CHECK: unknown type name 'Unknown'
 // CHECK-NEXT: void test2(Unknown* b);  // αααα αααα αααα αααα αααα αααα αααα αααα αααα
-// CHECK-NEXT: {{^           \^$}}
+// CHECK-NEXT: {{^      |            \^$}}
 
 void test3() {
    /* αααα αααα αααα αααα αααα αααα αααα αααα αααα αααα */ printf("%d", "s");
@@ -35,5 +35,5 @@
 // CHECK:       format specifies type 'int' but the argument has
 // CHECK:       type 'char *'
 // CHECK-NEXT:   ...αααα αααα αααα αααα αααα αααα αααα αααα αααα */ printf("%d", "s");
-// CHECK-NEXT: {{^                                                             ~~   \^~~$}}
-// CHECK-NEXT: {{^                                                             %s$}}
+// CHECK-NEXT: {{^      |                                                              ~~   \^~~$}}
+// CHECK-NEXT: {{^      |                                                              %s$}}
Index: clang/test/Frontend/diag-show-line-numbers.c
===================================================================
--- /dev/null
+++ clang/test/Frontend/diag-show-line-numbers.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-1 -strict-whitespace %s
+// RUN: %clang_cc1 -fsyntax-only -fno-diagnostics-show-line-numbers %s 2>&1 | FileCheck -check-prefix=CHECK-2 -strict-whitespace %s
+
+void* a = 1;
+
+//CHECK-1: {{^    4 | void\* a = 1;}}
+//CHECK-2: {{^void\* a = 1;}}
Index: clang/test/FixIt/fixit-unicode.c
===================================================================
--- clang/test/FixIt/fixit-unicode.c
+++ clang/test/FixIt/fixit-unicode.c
@@ -14,7 +14,7 @@
   struct Foo foo;
   foo.bar = 42☃
   // CHECK: error: character <U+2603> not allowed in an identifier
-  // CHECK: {{^              \^}}
+  // CHECK: {{^      |               \^}}
   // Make sure we emit the fixit right in front of the snowman.
 
   // CHECK-MACHINE: fix-it:"{{.*}}":{[[@LINE-5]]:15-[[@LINE-5]]:18}:""
@@ -38,14 +38,14 @@
 void test3() {
   int กssss = 42;
   int a = กsss; // expected-error{{use of undeclared identifier 'กsss'; did you mean 'กssss'?}}
-// CHECK: {{^          \^}}
-// CHECK: {{^          [^ ]+ssss}}
+// CHECK: {{^      |           \^}}
+// CHECK: {{^      |           [^ ]+ssss}}
 // CHECK-MACHINE: fix-it:"{{.*}}":{[[@LINE-3]]:11-[[@LINE-3]]:17}:"\340\270\201ssss"
 
   int ssกss = 42;
   int b = ssกs; // expected-error{{use of undeclared identifier 'ssกs'; did you mean 'ssกss'?}}
-// CHECK: {{^          \^}}
-// CHECK: {{^          ss.+ss}}
+// CHECK: {{^      |           \^}}
+// CHECK: {{^      |           ss.+ss}}
 // CHECK-MACHINE: fix-it:"{{.*}}":{[[@LINE-3]]:11-[[@LINE-3]]:17}:"ss\340\270\201ss"
 
   int s一二三 = 42;
@@ -55,7 +55,7 @@
 
   int sssssssssก = 42;
   int c = sssssssss; // expected-error{{use of undeclared identifier 'sssssssss'; did you mean 'sssssssssก'?}}
-// CHECK: {{^          \^}}
-// CHECK: {{^          sssssssss.+}}
+// CHECK: {{^      |           \^}}
+// CHECK: {{^      |           sssssssss.+}}
 // CHECK-MACHINE: fix-it:"{{.*}}":{[[@LINE-3]]:11-[[@LINE-3]]:20}:"sssssssss\340\270\201"
 }
Index: clang/test/FixIt/fixit-unicode-with-utf8-output.c
===================================================================
--- clang/test/FixIt/fixit-unicode-with-utf8-output.c
+++ clang/test/FixIt/fixit-unicode-with-utf8-output.c
@@ -5,21 +5,21 @@
 // REQUIRES: utf8-capable-terminal
 
 // CHECK: warning: format specifies type 'int' but the argument has type 'long'
-// CHECK: {{^  printf\("∆: %d", 1L\);}}
-// CHECK: {{^             ~~   \^~}}
+// CHECK: {{^   26 |   printf\("∆: %d", 1L\);}}
+// CHECK: {{^      |              ~~   \^~}}
 
 // CHECK: error: use of undeclared identifier 'กsss'; did you mean 'กssss'?
-// CHECK: {{^          \^}}
-// CHECK: {{^          กssss}}
+// CHECK: {{^      |           \^}}
+// CHECK: {{^      |           กssss}}
 
 // CHECK: error: use of undeclared identifier 'ssกs'; did you mean 'ssกss'?
-// CHECK: {{^          \^}}
-// CHECK: {{^          ssกss}}
+// CHECK: {{^      |           \^}}
+// CHECK: {{^      |           ssกss}}
 
 // CHECK: error: use of undeclared identifier 'ss一二三'; did you mean 's一二三'?
-// CHECK: {{^                        \^~~~~~~~}}
-// CHECK: {{^                        s一二三}}
+// CHECK: {{^      |                         \^~~~~~~~}}
+// CHECK: {{^      |                         s一二三}}
 
 // CHECK: error: use of undeclared identifier 'sssssssss'; did you mean 'sssssssssก'?
-// CHECK: {{^          \^}}
-// CHECK: {{^          sssssssssก}}
+// CHECK: {{^      |           \^}}
+// CHECK: {{^      |           sssssssssก}}
Index: clang/test/FixIt/fixit-newline-style.c
===================================================================
--- clang/test/FixIt/fixit-newline-style.c
+++ clang/test/FixIt/fixit-newline-style.c
@@ -3,8 +3,8 @@
 // This file intentionally uses a CRLF newline style
 // <rdar://problem/12639047>
 // CHECK: warning: unused label 'ddd'
-// CHECK-NEXT: {{^  ddd:}}
-// CHECK-NEXT: {{^  \^~~~$}}
+// CHECK-NEXT: {{^    9 |   ddd:}}
+// CHECK-NEXT: {{^      |   \^~~~$}}
 void f(void) {
   ddd:
   ;
Index: clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp
===================================================================
--- clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp
+++ clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp
@@ -5,14 +5,14 @@
   RefCountable* ref_countable = nullptr;
   auto foo1 = [ref_countable](){};
   // CHECK: warning: Captured raw-pointer 'ref_countable' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]
-  // CHECK-NEXT:{{^}}  auto foo1 = [ref_countable](){};
-  // CHECK-NEXT:{{^}}               ^
+  // CHECK-NEXT:{{^}}    6 |   auto foo1 = [ref_countable](){};
+  // CHECK-NEXT:{{^}}      |                ^
   auto foo2 = [&ref_countable](){};
   // CHECK: warning: Captured raw-pointer 'ref_countable' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]
   auto foo3 = [&](){ ref_countable = nullptr; };
   // CHECK: warning: Implicitly captured raw-pointer 'ref_countable' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]
-  // CHECK-NEXT:{{^}}  auto foo3 = [&](){ ref_countable = nullptr; };
-  // CHECK-NEXT:{{^}}                     ^
+  // CHECK-NEXT:{{^}}   12 |   auto foo3 = [&](){ ref_countable = nullptr; };
+  // CHECK-NEXT:{{^}}      |                      ^
   auto foo4 = [=](){ (void) ref_countable; };
   // CHECK: warning: Implicitly captured raw-pointer 'ref_countable' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]
 }
Index: clang/lib/Frontend/TextDiagnostic.cpp
===================================================================
--- clang/lib/Frontend/TextDiagnostic.cpp
+++ clang/lib/Frontend/TextDiagnostic.cpp
@@ -20,6 +20,7 @@
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
+#include <iostream>
 
 using namespace clang;
 
@@ -1241,6 +1242,32 @@
       CaretLine = ' ' + CaretLine;
     }
 
+    // If we are in -fdiagnostics-show-line-numbers mode, show line numbers with
+    // left margins.
+    std::string AdditionalSpaces = "";
+    if (DiagOpts->ShowLineNumbers) {
+      size_t MaxSpaces = 5;
+      std::string LineNoStr = std::to_string(LineNo);
+      size_t LineNoStrSize = LineNoStr.size();
+
+      if (MaxSpaces > LineNoStrSize) {
+        // Source:        `    1 | `
+        // Caret & FixIt: `      | `
+        std::string Spaces(MaxSpaces - LineNoStr.size(), ' ');
+        SourceLine = Spaces + LineNoStr + " | " + SourceLine;
+      } else if (MaxSpaces == LineNoStrSize) {
+        // Source:        `12345 | `
+        // Caret & FixIt: `      | `
+        SourceLine = LineNoStr + " | " + SourceLine;
+      } else {
+        // Source:        `1234567 | `
+        // Caret & FixIt: `        | `
+        //                 ^~ AdditionalSpaces
+        SourceLine = LineNoStr + " | " + SourceLine;
+        AdditionalSpaces = std::string(LineNoStr.size() - MaxSpaces, ' ');
+      }
+    }
+
     // Finally, remove any blank spaces from the end of CaretLine.
     while (!CaretLine.empty() && CaretLine[CaretLine.size() - 1] == ' ')
       CaretLine.erase(CaretLine.end() - 1);
@@ -1249,6 +1276,10 @@
     emitSnippet(SourceLine);
 
     if (!CaretLine.empty()) {
+      if (DiagOpts->ShowLineNumbers) {
+        OS << AdditionalSpaces << "      | ";
+      }
+
       if (DiagOpts->ShowColors)
         OS.changeColor(caretColor, true);
       OS << CaretLine << '\n';
@@ -1257,6 +1288,10 @@
     }
 
     if (!FixItInsertionLine.empty()) {
+      if (DiagOpts->ShowLineNumbers) {
+        OS << AdditionalSpaces << "      | ";
+      }
+
       if (DiagOpts->ShowColors)
         // Print fixit line in color
         OS.changeColor(fixitColor, false);
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -3962,6 +3962,9 @@
       CmdArgs.push_back("-fno-diagnostics-show-note-include-stack");
   }
 
+  Args.addOptOutFlag(CmdArgs, options::OPT_fdiagnostics_show_line_numbers,
+                     options::OPT_fno_diagnostics_show_line_numbers);
+
   // Color diagnostics are parsed by the driver directly from argv and later
   // re-parsed to construct this job; claim any possible color diagnostic here
   // to avoid warn_drv_unused_argument and diagnose bad
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -1416,6 +1416,11 @@
     Group<f_clang_Group>,  Flags<[CC1Option]>,
     HelpText<"Print source range spans in numeric form">,
     MarshallingInfoFlag<DiagnosticOpts<"ShowSourceRanges">>;
+def fdiagnostics_show_line_numbers : Flag<["-"], "fdiagnostics-show-line-numbers">, Group<f_clang_Group>;
+def fno_diagnostics_show_line_numbers : Flag<["-"], "fno-diagnostics-show-line-numbers">,
+    Group<f_Group>, Flags<[CC1Option]>,
+    HelpText<"Do not show line numbers with left margins in diagnostics">,
+    MarshallingInfoNegativeFlag<DiagnosticOpts<"ShowLineNumbers">>;
 defm diagnostics_show_hotness : BoolFOption<"diagnostics-show-hotness",
   CodeGenOpts<"DiagnosticsWithHotness">, DefaultFalse,
   PosFlag<SetTrue, [CC1Option], "Enable profile hotness information in diagnostic line">,
Index: clang/include/clang/Basic/DiagnosticOptions.def
===================================================================
--- clang/include/clang/Basic/DiagnosticOptions.def
+++ clang/include/clang/Basic/DiagnosticOptions.def
@@ -55,6 +55,7 @@
 DIAGOPT(ShowCarets, 1, 1)       /// Show carets in diagnostics.
 DIAGOPT(ShowFixits, 1, 1)       /// Show fixit information.
 DIAGOPT(ShowSourceRanges, 1, 0) /// Show source ranges in numeric form.
+DIAGOPT(ShowLineNumbers, 1, 1)  /// Show line numbers with left margins.
 DIAGOPT(ShowParseableFixits, 1, 0) /// Show machine parseable fix-its.
 DIAGOPT(ShowPresumedLoc, 1, 0)  /// Show presumed location for diagnostics.
 DIAGOPT(ShowOptionNames, 1, 0)  /// Show the option name for mappable
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to