|  | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" | 
|  | "http://www.w3.org/TR/html4/strict.dtd"> | 
|  | <html> | 
|  | <head> | 
|  | <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"> | 
|  | <title>Clang - Expressive Diagnostics</title> | 
|  | <link type="text/css" rel="stylesheet" href="menu.css"> | 
|  | <link type="text/css" rel="stylesheet" href="content.css"> | 
|  | <style type="text/css"> | 
|  | .warn { color:magenta; } | 
|  | .err { color:red; } | 
|  | .snip { color:darkgreen; } | 
|  | .point { color:blue; } | 
|  | </style> | 
|  | </head> | 
|  | <body> | 
|  |  | 
|  | <!--#include virtual="menu.html.incl"--> | 
|  |  | 
|  | <div id="content"> | 
|  |  | 
|  |  | 
|  | <!--=======================================================================--> | 
|  | <h1>Expressive Diagnostics</h1> | 
|  | <!--=======================================================================--> | 
|  |  | 
|  | <p>In addition to being fast and functional, we aim to make Clang extremely user | 
|  | friendly.  As far as a command-line compiler goes, this basically boils down to | 
|  | making the diagnostics (error and warning messages) generated by the compiler | 
|  | be as useful as possible.  There are several ways that we do this.  This section | 
|  | talks about the experience provided by the command line compiler, contrasting | 
|  | Clang output to GCC 4.2's output in several examples. | 
|  | <!-- | 
|  | Other clients | 
|  | that embed Clang and extract equivalent information through internal APIs.--> | 
|  | </p> | 
|  |  | 
|  | <h2>Column Numbers and Caret Diagnostics</h2> | 
|  |  | 
|  | <p>First, all diagnostics produced by clang include full column number | 
|  | information. The clang command-line compiler driver uses this information | 
|  | to print "point diagnostics". | 
|  | (IDEs can use the information to display in-line error markup.) | 
|  | Precise error location in the source is a feature provided by many commercial | 
|  | compilers, but is generally missing from open source | 
|  | compilers.  This is nice because it makes it very easy to understand exactly | 
|  | what is wrong in a particular piece of code</p> | 
|  |  | 
|  | <p>The point (the blue "^" character) exactly shows where the problem is, even | 
|  | inside of a string.  This makes it really easy to jump to the problem and | 
|  | helps when multiple instances of the same character occur on a line. (We'll | 
|  | revisit this more in following examples.)</p> | 
|  |  | 
|  | <pre> | 
|  | $ <b>gcc-4.2 -fsyntax-only -Wformat format-strings.c</b> | 
|  | format-strings.c:91: warning: too few arguments for format | 
|  | $ <b>clang -fsyntax-only format-strings.c</b> | 
|  | format-strings.c:91:13: <span class="warn">warning:</span> '.*' specified field precision is missing a matching 'int' argument | 
|  | <span class="snip">  printf("%.*d");</span> | 
|  | <span class="point">            ^</span> | 
|  | </pre> | 
|  |  | 
|  | <h2>Range Highlighting for Related Text</h2> | 
|  |  | 
|  | <p>Clang captures and accurately tracks range information for expressions, | 
|  | statements, and other constructs in your program and uses this to make | 
|  | diagnostics highlight related information.  In the following somewhat | 
|  | nonsensical example you can see that you don't even need to see the original source code to | 
|  | understand what is wrong based on the Clang error. Because clang prints a | 
|  | point, you know exactly <em>which</em> plus it is complaining about.  The range | 
|  | information highlights the left and right side of the plus which makes it | 
|  | immediately obvious what the compiler is talking about. | 
|  | Range information is very useful for | 
|  | cases involving precedence issues and many other cases.</p> | 
|  |  | 
|  | <pre> | 
|  | $ <b>gcc-4.2 -fsyntax-only t.c</b> | 
|  | t.c:7: error: invalid operands to binary + (have 'int' and 'struct A') | 
|  | $ <b>clang -fsyntax-only t.c</b> | 
|  | t.c:7:39: <span class="err">error:</span> invalid operands to binary expression ('int' and 'struct A') | 
|  | <span class="snip">  return y + func(y ? ((SomeA.X + 40) + SomeA) / 42 + SomeA.X : SomeA.X);</span> | 
|  | <span class="point">                       ~~~~~~~~~~~~~~ ^ ~~~~~</span> | 
|  | </pre> | 
|  |  | 
|  | <h2>Precision in Wording</h2> | 
|  |  | 
|  | <p>A detail is that we have tried really hard to make the diagnostics that come | 
|  | out of clang contain exactly the pertinent information about what is wrong and | 
|  | why.  In the example above, we tell you what the inferred types are for | 
|  | the left and right hand sides, and we don't repeat what is obvious from the | 
|  | point (e.g., that this is a "binary +").</p> | 
|  |  | 
|  | <p>Many other examples abound. In the following example, not only do we tell you that there is a problem with the * | 
|  | and point to it, we say exactly why and tell you what the type is (in case it is | 
|  | a complicated subexpression, such as a call to an overloaded function).  This | 
|  | sort of attention to detail makes it much easier to understand and fix problems | 
|  | quickly.</p> | 
|  |  | 
|  | <pre> | 
|  | $ <b>gcc-4.2 -fsyntax-only t.c</b> | 
|  | t.c:5: error: invalid type argument of 'unary *' | 
|  | $ <b>clang -fsyntax-only t.c</b> | 
|  | t.c:5:11: <span class="err">error:</span> indirection requires pointer operand ('int' invalid) | 
|  | <span class="snip">  int y = *SomeA.X;</span> | 
|  | <span class="point">          ^~~~~~~~</span> | 
|  | </pre> | 
|  |  | 
|  | <h2>No Pretty Printing of Expressions in Diagnostics</h2> | 
|  |  | 
|  | <p>Since Clang has range highlighting, it never needs to pretty print your code | 
|  | back out to you.  GCC can produce inscrutible error messages in some cases when | 
|  | it tries to do this.  In this example P and Q have type "int*":</p> | 
|  |  | 
|  | <pre> | 
|  | $ <b>gcc-4.2 -fsyntax-only t.c</b> | 
|  | #'exact_div_expr' not supported by pp_c_expression#'t.c:12: error: called object  is not a function | 
|  | $ <b>clang -fsyntax-only t.c</b> | 
|  | t.c:12:8: <span class="err">error:</span> called object type 'int' is not a function or function pointer | 
|  | <span class="snip">  (P-Q)();</span> | 
|  | <span class="point">  ~~~~~^</span> | 
|  | </pre> | 
|  |  | 
|  | <p>This can be particularly bad in G++, which often emits errors | 
|  | containing lowered vtable references.  For example:</p> | 
|  |  | 
|  | <pre> | 
|  | $ <b>cat t.cc</b> | 
|  | struct a { | 
|  | virtual int bar(); | 
|  | }; | 
|  |  | 
|  | struct foo : public virtual a { | 
|  | }; | 
|  |  | 
|  | void test(foo *P) { | 
|  | return P->bar() + *P; | 
|  | } | 
|  | $ <b>gcc-4.2 t.cc</b> | 
|  | t.cc: In function 'void test(foo*)': | 
|  | t.cc:9: error: no match for 'operator+' in '(((a*)P) + (*(long int*)(P->foo::<anonymous>.a::_vptr$a + -0x00000000000000020)))->a::bar() + * P' | 
|  | t.cc:9: error: return-statement with a value, in function returning 'void' | 
|  | $ <b>clang t.cc</b> | 
|  | t.cc:9:18: <span class="err">error:</span> invalid operands to binary expression ('int' and 'foo') | 
|  | <span class="snip">  return P->bar() + *P;</span> | 
|  | <span class="point">         ~~~~~~~~ ^ ~~</span> | 
|  | </pre> | 
|  |  | 
|  |  | 
|  | <h2>Typedef Preservation and Selective Unwrapping</h2> | 
|  |  | 
|  | <p>Many programmers use high-level user defined types, typedefs, and other | 
|  | syntactic sugar to refer to types in their program.  This is useful because they | 
|  | can abbreviate otherwise very long types and it is useful to preserve the | 
|  | typename in diagnostics.  However, sometimes very simple typedefs can wrap | 
|  | trivial types and it is important to strip off the typedef to understand what | 
|  | is going on.  Clang aims to handle both cases well.<p> | 
|  |  | 
|  | <p>The following example shows where it is important to preserve | 
|  | a typedef in C. Here the type printed by GCC isn't even valid, but if the error | 
|  | were about a very long and complicated type (as often happens in C++) the error | 
|  | message would be ugly just because it was long and hard to read.</p> | 
|  |  | 
|  | <pre> | 
|  | $ <b>gcc-4.2 -fsyntax-only t.c</b> | 
|  | t.c:15: error: invalid operands to binary / (have 'float __vector__' and 'const int *') | 
|  | $ <b>clang -fsyntax-only t.c</b> | 
|  | t.c:15:11: <span class="err">error:</span> can't convert between vector values of different size ('__m128' and 'int const *') | 
|  | <span class="snip">  myvec[1]/P;</span> | 
|  | <span class="point">  ~~~~~~~~^~</span> | 
|  | </pre> | 
|  |  | 
|  | <p>The following example shows where it is useful for the compiler to expose | 
|  | underlying details of a typedef. If the user was somehow confused about how the | 
|  | system "pid_t" typedef is defined, Clang helpfully displays it with "aka".</p> | 
|  |  | 
|  | <pre> | 
|  | $ <b>gcc-4.2 -fsyntax-only t.c</b> | 
|  | t.c:13: error: request for member 'x' in something not a structure or union | 
|  | $ <b>clang -fsyntax-only t.c</b> | 
|  | t.c:13:9: <span class="err">error:</span> member reference base type 'pid_t' (aka 'int') is not a structure or union | 
|  | <span class="snip">  myvar = myvar.x;</span> | 
|  | <span class="point">          ~~~~~ ^</span> | 
|  | </pre> | 
|  |  | 
|  | <p>In C++, type preservation includes retaining any qualification written into type names. For example, if we take a small snippet of code such as: | 
|  |  | 
|  | <blockquote> | 
|  | <pre> | 
|  | namespace services { | 
|  | struct WebService {  }; | 
|  | } | 
|  | namespace myapp { | 
|  | namespace servers { | 
|  | struct Server {  }; | 
|  | } | 
|  | } | 
|  |  | 
|  | using namespace myapp; | 
|  | void addHTTPService(servers::Server const &server, ::services::WebService const *http) { | 
|  | server += http; | 
|  | } | 
|  | </pre> | 
|  | </blockquote> | 
|  |  | 
|  | <p>and then compile it, we see that Clang is both providing more accurate information and is retaining the types as written by the user (e.g., "servers::Server", "::services::WebService"): | 
|  |  | 
|  | <pre> | 
|  | $ <b>g++-4.2 -fsyntax-only t.cpp</b> | 
|  | t.cpp:9: error: no match for 'operator+=' in 'server += http' | 
|  | $ <b>clang -fsyntax-only t.cpp</b> | 
|  | t.cpp:9:10: <span class="err">error:</span> invalid operands to binary expression ('servers::Server const' and '::services::WebService const *') | 
|  | <span class="snip">server += http;</span> | 
|  | <span class="point">~~~~~~ ^  ~~~~</span> | 
|  | </pre> | 
|  |  | 
|  | <p>Naturally, type preservation extends to uses of templates, and Clang retains information about how a particular template specialization (like <code>std::vector<Real></code>) was spelled within the source code. For example:</p> | 
|  |  | 
|  | <pre> | 
|  | $ <b>g++-4.2 -fsyntax-only t.cpp</b> | 
|  | t.cpp:12: error: no match for 'operator=' in 'str = vec' | 
|  | $ <b>clang -fsyntax-only t.cpp</b> | 
|  | t.cpp:12:7: <span class="err">error:</span> incompatible type assigning 'vector<Real>', expected 'std::string' (aka 'class std::basic_string<char>') | 
|  | <span class="snip">str = vec</span>; | 
|  | <span class="point">^ ~~~</span> | 
|  | </pre> | 
|  |  | 
|  | <h2>Fix-it Hints</h2> | 
|  |  | 
|  | <p>"Fix-it" hints provide advice for fixing small, localized problems | 
|  | in source code. When Clang produces a diagnostic about a particular | 
|  | problem that it can work around (e.g., non-standard or redundant | 
|  | syntax, missing keywords, common mistakes, etc.), it may also provide | 
|  | specific guidance in the form of a code transformation to correct the | 
|  | problem. In the following example, Clang warns about the use of a GCC | 
|  | extension that has been considered obsolete since 1993. The underlined | 
|  | code should be removed, then replaced with the code below the | 
|  | point line (".x =" or ".y =", respectively).</p> | 
|  |  | 
|  | <pre> | 
|  | $ <b>clang t.c</b> | 
|  | t.c:5:28: <span class="warn">warning:</span> use of GNU old-style field designator extension | 
|  | <span class="snip">struct point origin = { x: 0.0, y: 0.0 };</span> | 
|  | <span class="err">~~</span> <span class="point">^</span> | 
|  | <span class="snip">.x = </span> | 
|  | t.c:5:36: <span class="warn">warning:</span> use of GNU old-style field designator extension | 
|  | <span class="snip">struct point origin = { x: 0.0, y: 0.0 };</span> | 
|  | <span class="err">~~</span> <span class="point">^</span> | 
|  | <span class="snip">.y = </span> | 
|  | </pre> | 
|  |  | 
|  | <p>"Fix-it" hints are most useful for | 
|  | working around common user errors and misconceptions. For example, C++ users | 
|  | commonly forget the syntax for explicit specialization of class templates, | 
|  | as in the error in the following example. Again, after describing the problem, | 
|  | Clang provides the fix--add <code>template<></code>--as part of the | 
|  | diagnostic.<p> | 
|  |  | 
|  | <pre> | 
|  | $ <b>clang t.cpp</b> | 
|  | t.cpp:9:3: <span class="err">error:</span> template specialization requires 'template<>' | 
|  | struct iterator_traits<file_iterator> { | 
|  | <span class="point">^</span> | 
|  | <span class="snip">template<> </span> | 
|  | </pre> | 
|  |  | 
|  | <h2>Template Type Diffing</h2> | 
|  |  | 
|  | <p>Templates types can be long and difficult to read.  Moreso when part of an | 
|  | error message.  Instead of just printing out the type name, Clang has enough | 
|  | information to remove the common elements and highlight the differences.  To | 
|  | show the template structure more clearly, the templated type can also be | 
|  | printed as an indented text tree.</p> | 
|  |  | 
|  | Default: template diff with type elision | 
|  | <pre> | 
|  | t.cc:4:5: <span class="note">note:</span> candidate function not viable: no known conversion from 'vector<map<[...], <span class="template-highlight">float</span>>>' to 'vector<map<[...], <span class="template-highlight">double</span>>>' for 1st argument; | 
|  | </pre> | 
|  | -fno-elide-type: template diff without elision | 
|  | <pre> | 
|  | t.cc:4:5: <span class="note">note:</span> candidate function not viable: no known conversion from 'vector<map<int, <span class="template-highlight">float</span>>>' to 'vector<map<int, <span class="template-highlight">double</span>>>' for 1st argument; | 
|  | </pre> | 
|  | -fdiagnostics-show-template-tree: template tree printing with elision | 
|  | <pre> | 
|  | t.cc:4:5: <span class="note">note:</span> candidate function not viable: no known conversion for 1st argument; | 
|  | vector< | 
|  | map< | 
|  | [...], | 
|  | [<span class="template-highlight">float</span> != <span class="template-highlight">double</span>]>> | 
|  | </pre> | 
|  | -fdiagnostics-show-template-tree -fno-elide-type: template tree printing with no elision | 
|  | <pre> | 
|  | t.cc:4:5: <span class="note">note:M</span> candidate function not viable: no known conversion for 1st argument; | 
|  | vector< | 
|  | map< | 
|  | int, | 
|  | [<span class="template-highlight">float</span> != <span class="template-highlight">double</span>]>> | 
|  | </pre> | 
|  |  | 
|  | <h2>Automatic Macro Expansion</h2> | 
|  |  | 
|  | <p>Many errors happen in macros that are sometimes deeply nested.  With | 
|  | traditional compilers, you need to dig deep into the definition of the macro to | 
|  | understand how you got into trouble.  The following simple example shows how | 
|  | Clang helps you out by automatically printing instantiation information and | 
|  | nested range information for diagnostics as they are instantiated through macros | 
|  | and also shows how some of the other pieces work in a bigger example.</p> | 
|  |  | 
|  | <pre> | 
|  | $ <b>gcc-4.2 -fsyntax-only t.c</b> | 
|  | t.c: In function 'test': | 
|  | t.c:80: error: invalid operands to binary < (have 'struct mystruct' and 'float') | 
|  | $ <b>clang -fsyntax-only t.c</b> | 
|  | t.c:80:3: <span class="err">error:</span> invalid operands to binary expression ('typeof(P)' (aka 'struct mystruct') and 'typeof(F)' (aka 'float')) | 
|  | <span class="snip">  X = MYMAX(P, F);</span> | 
|  | <span class="point">      ^~~~~~~~~~~</span> | 
|  | t.c:76:94: note: instantiated from: | 
|  | <span class="snip">#define MYMAX(A,B)    __extension__ ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __b : __a; })</span> | 
|  | <span class="point">                                                                                         ~~~ ^ ~~~</span> | 
|  | </pre> | 
|  |  | 
|  | <p>Here's another real world warning that occurs in the "window" Unix package (which | 
|  | implements the "wwopen" class of APIs):</p> | 
|  |  | 
|  | <pre> | 
|  | $ <b>clang -fsyntax-only t.c</b> | 
|  | t.c:22:2: <span class="warn">warning:</span> type specifier missing, defaults to 'int' | 
|  | <span class="snip">        ILPAD();</span> | 
|  | <span class="point">        ^</span> | 
|  | t.c:17:17: note: instantiated from: | 
|  | <span class="snip">#define ILPAD() PAD((NROW - tt.tt_row) * 10)    /* 1 ms per char */</span> | 
|  | <span class="point">                ^</span> | 
|  | t.c:14:2: note: instantiated from: | 
|  | <span class="snip">        register i; \</span> | 
|  | <span class="point">        ^</span> | 
|  | </pre> | 
|  |  | 
|  | <p>In practice, we've found that Clang's treatment of macros is actually more useful in multiply nested | 
|  | macros that in simple ones.</p> | 
|  |  | 
|  | <h2>Quality of Implementation and Attention to Detail</h2> | 
|  |  | 
|  | <p>Finally, we have put a lot of work polishing the little things, because | 
|  | little things add up over time and contribute to a great user experience.</p> | 
|  |  | 
|  | <p>The following example shows a trivial little tweak, where we tell you to put the semicolon at | 
|  | the end of the line that is missing it (line 4) instead of at the beginning of | 
|  | the following line (line 5).  This is particularly important with fixit hints | 
|  | and point diagnostics, because otherwise you don't get the important context. | 
|  | </p> | 
|  |  | 
|  | <pre> | 
|  | $ <b>gcc-4.2 t.c</b> | 
|  | t.c: In function 'foo': | 
|  | t.c:5: error: expected ';' before '}' token | 
|  | $ <b>clang t.c</b> | 
|  | t.c:4:8: <span class="err">error:</span> expected ';' after expression | 
|  | <span class="snip">  bar()</span> | 
|  | <span class="point">       ^</span> | 
|  | <span class="point">       ;</span> | 
|  | </pre> | 
|  |  | 
|  | <p>The following example shows much better error recovery than GCC. The message coming out | 
|  | of GCC is completely useless for diagnosing the problem. Clang tries much harder | 
|  | and produces a much more useful diagnosis of the problem.</p> | 
|  |  | 
|  | <pre> | 
|  | $ <b>gcc-4.2 t.c</b> | 
|  | t.c:3: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*' token | 
|  | $ <b>clang t.c</b> | 
|  | t.c:3:1: <span class="err">error:</span> unknown type name 'foo_t' | 
|  | <span class="snip">foo_t *P = 0;</span> | 
|  | <span class="point">^</span> | 
|  | </pre> | 
|  |  | 
|  | <p>The following example shows that we recover from the simple case of | 
|  | forgetting a ; after a struct definition much better than GCC.</p> | 
|  |  | 
|  | <pre> | 
|  | $ <b>cat t.cc</b> | 
|  | template<class T> | 
|  | class a {} | 
|  | class temp {}; | 
|  | a<temp> b; | 
|  | struct b { | 
|  | } | 
|  | $ <b>gcc-4.2 t.cc</b> | 
|  | t.cc:3: error: multiple types in one declaration | 
|  | t.cc:4: error: non-template type 'a' used as a template | 
|  | t.cc:4: error: invalid type in declaration before ';' token | 
|  | t.cc:6: error: expected unqualified-id at end of input | 
|  | $ <b>clang t.cc</b> | 
|  | t.cc:2:11: <span class="err">error:</span> expected ';' after class | 
|  | <span class="snip">class a {}</span> | 
|  | <span class="point">          ^</span> | 
|  | <span class="point">          ;</span> | 
|  | t.cc:6:2: <span class="err">error:</span> expected ';' after struct | 
|  | <span class="snip">}</span> | 
|  | <span class="point"> ^</span> | 
|  | <span class="point"> ;</span> | 
|  | </pre> | 
|  |  | 
|  | <p>While each of these details is minor, we feel that they all add up to provide | 
|  | a much more polished experience.</p> | 
|  |  | 
|  | </div> | 
|  | </body> | 
|  | </html> |