1f4a2713aSLionel Sambuc<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 2f4a2713aSLionel Sambuc "http://www.w3.org/TR/html4/strict.dtd"> 3f4a2713aSLionel Sambuc<html> 4f4a2713aSLionel Sambuc<head> 5f4a2713aSLionel Sambuc <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"> 6f4a2713aSLionel Sambuc <title>Clang - Expressive Diagnostics</title> 7f4a2713aSLionel Sambuc <link type="text/css" rel="stylesheet" href="menu.css"> 8f4a2713aSLionel Sambuc <link type="text/css" rel="stylesheet" href="content.css"> 9f4a2713aSLionel Sambuc <style type="text/css"> 10*0a6a1f1dSLionel Sambuc .loc { font-weight: bold; } 11*0a6a1f1dSLionel Sambuc .err { color:red; font-weight: bold; } 12*0a6a1f1dSLionel Sambuc .warn { color:magenta; font-weight: bold; } 13*0a6a1f1dSLionel Sambuc .note { color:gray; font-weight: bold; } 14*0a6a1f1dSLionel Sambuc .msg { font-weight: bold; } 15*0a6a1f1dSLionel Sambuc .cmd { font-style: italic; } 16*0a6a1f1dSLionel Sambuc .snip { } 17*0a6a1f1dSLionel Sambuc .point { color:green; font-weight: bold; } 18f4a2713aSLionel Sambuc </style> 19f4a2713aSLionel Sambuc</head> 20f4a2713aSLionel Sambuc<body> 21f4a2713aSLionel Sambuc 22f4a2713aSLionel Sambuc<!--#include virtual="menu.html.incl"--> 23f4a2713aSLionel Sambuc 24f4a2713aSLionel Sambuc<div id="content"> 25f4a2713aSLionel Sambuc 26f4a2713aSLionel Sambuc 27f4a2713aSLionel Sambuc<!--=======================================================================--> 28f4a2713aSLionel Sambuc<h1>Expressive Diagnostics</h1> 29f4a2713aSLionel Sambuc<!--=======================================================================--> 30f4a2713aSLionel Sambuc 31f4a2713aSLionel Sambuc<p>In addition to being fast and functional, we aim to make Clang extremely user 32f4a2713aSLionel Sambucfriendly. As far as a command-line compiler goes, this basically boils down to 33f4a2713aSLionel Sambucmaking the diagnostics (error and warning messages) generated by the compiler 34f4a2713aSLionel Sambucbe as useful as possible. There are several ways that we do this. This section 35f4a2713aSLionel Sambuctalks about the experience provided by the command line compiler, contrasting 36*0a6a1f1dSLionel SambucClang output to GCC 4.9's output in some cases. 37f4a2713aSLionel Sambuc</p> 38f4a2713aSLionel Sambuc 39f4a2713aSLionel Sambuc<h2>Column Numbers and Caret Diagnostics</h2> 40f4a2713aSLionel Sambuc 41f4a2713aSLionel Sambuc<p>First, all diagnostics produced by clang include full column number 42f4a2713aSLionel Sambucinformation. The clang command-line compiler driver uses this information 43f4a2713aSLionel Sambucto print "point diagnostics". 44f4a2713aSLionel Sambuc(IDEs can use the information to display in-line error markup.) 45*0a6a1f1dSLionel SambucThis is nice because it makes it very easy to understand exactly 46*0a6a1f1dSLionel Sambucwhat is wrong in a particular piece of code.</p> 47f4a2713aSLionel Sambuc 48*0a6a1f1dSLionel Sambuc<p>The point (the green "^" character) exactly shows where the problem is, even 49f4a2713aSLionel Sambucinside of a string. This makes it really easy to jump to the problem and 50f4a2713aSLionel Sambuchelps when multiple instances of the same character occur on a line. (We'll 51f4a2713aSLionel Sambucrevisit this more in following examples.)</p> 52f4a2713aSLionel Sambuc 53f4a2713aSLionel Sambuc<pre> 54*0a6a1f1dSLionel Sambuc $ <span class="cmd">gcc-4.9 -fsyntax-only -Wformat format-strings.c</span> 55*0a6a1f1dSLionel Sambuc format-strings.c: In function 'void f()': 56*0a6a1f1dSLionel Sambuc format-strings.c:91:16: warning: field precision specifier '.*' expects a matching 'int' argument [-Wformat=] 57*0a6a1f1dSLionel Sambuc printf("%.*d"); 58*0a6a1f1dSLionel Sambuc ^ 59*0a6a1f1dSLionel Sambuc format-strings.c:91:16: warning: format '%d' expects a matching 'int' argument [-Wformat=] 60*0a6a1f1dSLionel Sambuc $ <span class="cmd">clang -fsyntax-only format-strings.c</span> 61*0a6a1f1dSLionel Sambuc <span class="loc">format-strings.c:91:13:</span> <span class="warn">warning:</span> <span class="msg">'.*' specified field precision is missing a matching 'int' argument</span> 62f4a2713aSLionel Sambuc <span class="snip" > printf("%.*d");</span> 63f4a2713aSLionel Sambuc <span class="point"> ^</span> 64f4a2713aSLionel Sambuc</pre> 65f4a2713aSLionel Sambuc 66*0a6a1f1dSLionel Sambuc<p>Note that modern versions of GCC have followed Clang's lead, and are 67*0a6a1f1dSLionel Sambucnow able to give a column for a diagnostic, and include a snippet of source 68*0a6a1f1dSLionel Sambuctext in the result. However, Clang's column number is much more accurate, 69*0a6a1f1dSLionel Sambucpointing at the problematic format specifier, rather than the <tt>)</tt> 70*0a6a1f1dSLionel Sambuccharacter the parser had reached when the problem was detected. 71*0a6a1f1dSLionel SambucAlso, Clang's diagnostic is colored by default, making it easier to 72*0a6a1f1dSLionel Sambucdistinguish from nearby text.</p> 73*0a6a1f1dSLionel Sambuc 74f4a2713aSLionel Sambuc<h2>Range Highlighting for Related Text</h2> 75f4a2713aSLionel Sambuc 76f4a2713aSLionel Sambuc<p>Clang captures and accurately tracks range information for expressions, 77f4a2713aSLionel Sambucstatements, and other constructs in your program and uses this to make 78f4a2713aSLionel Sambucdiagnostics highlight related information. In the following somewhat 79f4a2713aSLionel Sambucnonsensical example you can see that you don't even need to see the original source code to 80f4a2713aSLionel Sambucunderstand what is wrong based on the Clang error. Because clang prints a 81f4a2713aSLionel Sambucpoint, you know exactly <em>which</em> plus it is complaining about. The range 82f4a2713aSLionel Sambucinformation highlights the left and right side of the plus which makes it 83f4a2713aSLionel Sambucimmediately obvious what the compiler is talking about. 84f4a2713aSLionel SambucRange information is very useful for 85f4a2713aSLionel Sambuccases involving precedence issues and many other cases.</p> 86f4a2713aSLionel Sambuc 87f4a2713aSLionel Sambuc<pre> 88*0a6a1f1dSLionel Sambuc $ <span class="cmd">gcc-4.9 -fsyntax-only t.c</span> 89*0a6a1f1dSLionel Sambuc t.c: In function 'int f(int, int)': 90*0a6a1f1dSLionel Sambuc t.c:7:39: error: invalid operands to binary + (have 'int' and 'struct A') 91*0a6a1f1dSLionel Sambuc return y + func(y ? ((SomeA.X + 40) + SomeA) / 42 + SomeA.X : SomeA.X); 92*0a6a1f1dSLionel Sambuc ^ 93*0a6a1f1dSLionel Sambuc $ <span class="cmd">clang -fsyntax-only t.c</span> 94*0a6a1f1dSLionel Sambuc <span class="loc">t.c:7:39:</span> <span class="err">error:</span> <span class="msg">invalid operands to binary expression ('int' and 'struct A')</span> 95f4a2713aSLionel Sambuc <span class="snip" > return y + func(y ? ((SomeA.X + 40) + SomeA) / 42 + SomeA.X : SomeA.X);</span> 96f4a2713aSLionel Sambuc <span class="point"> ~~~~~~~~~~~~~~ ^ ~~~~~</span> 97f4a2713aSLionel Sambuc</pre> 98f4a2713aSLionel Sambuc 99f4a2713aSLionel Sambuc<h2>Precision in Wording</h2> 100f4a2713aSLionel Sambuc 101f4a2713aSLionel Sambuc<p>A detail is that we have tried really hard to make the diagnostics that come 102f4a2713aSLionel Sambucout of clang contain exactly the pertinent information about what is wrong and 103f4a2713aSLionel Sambucwhy. In the example above, we tell you what the inferred types are for 104f4a2713aSLionel Sambucthe left and right hand sides, and we don't repeat what is obvious from the 105f4a2713aSLionel Sambucpoint (e.g., that this is a "binary +").</p> 106f4a2713aSLionel Sambuc 107*0a6a1f1dSLionel Sambuc<p>Many other examples abound. In the following example, not only do we tell you 108*0a6a1f1dSLionel Sambucthat there is a problem with the <tt>*</tt> 109f4a2713aSLionel Sambucand point to it, we say exactly why and tell you what the type is (in case it is 110f4a2713aSLionel Sambuca complicated subexpression, such as a call to an overloaded function). This 111f4a2713aSLionel Sambucsort of attention to detail makes it much easier to understand and fix problems 112f4a2713aSLionel Sambucquickly.</p> 113f4a2713aSLionel Sambuc 114f4a2713aSLionel Sambuc<pre> 115*0a6a1f1dSLionel Sambuc $ <span class="cmd">gcc-4.9 -fsyntax-only t.c</span> 116*0a6a1f1dSLionel Sambuc t.c:5:11: error: invalid type argument of unary '*' (have 'int') 117*0a6a1f1dSLionel Sambuc return *SomeA.X; 118*0a6a1f1dSLionel Sambuc ^ 119*0a6a1f1dSLionel Sambuc $ <span class="cmd">clang -fsyntax-only t.c</span> 120*0a6a1f1dSLionel Sambuc <span class="loc">t.c:5:11:</span> <span class="err">error:</span> <span class="msg">indirection requires pointer operand ('int' invalid)</span> 121f4a2713aSLionel Sambuc <span class="snip" > int y = *SomeA.X;</span> 122f4a2713aSLionel Sambuc <span class="point"> ^~~~~~~~</span> 123f4a2713aSLionel Sambuc</pre> 124f4a2713aSLionel Sambuc 125f4a2713aSLionel Sambuc<h2>Typedef Preservation and Selective Unwrapping</h2> 126f4a2713aSLionel Sambuc 127f4a2713aSLionel Sambuc<p>Many programmers use high-level user defined types, typedefs, and other 128f4a2713aSLionel Sambucsyntactic sugar to refer to types in their program. This is useful because they 129f4a2713aSLionel Sambuccan abbreviate otherwise very long types and it is useful to preserve the 130f4a2713aSLionel Sambuctypename in diagnostics. However, sometimes very simple typedefs can wrap 131f4a2713aSLionel Sambuctrivial types and it is important to strip off the typedef to understand what 132f4a2713aSLionel Sambucis going on. Clang aims to handle both cases well.<p> 133f4a2713aSLionel Sambuc 134f4a2713aSLionel Sambuc<p>The following example shows where it is important to preserve 135*0a6a1f1dSLionel Sambuca typedef in C.</p> 136f4a2713aSLionel Sambuc 137f4a2713aSLionel Sambuc<pre> 138*0a6a1f1dSLionel Sambuc $ <span class="cmd">clang -fsyntax-only t.c</span> 139*0a6a1f1dSLionel Sambuc <span class="loc">t.c:15:11:</span> <span class="err">error:</span> <span class="msg">can't convert between vector values of different size ('__m128' and 'int const *')</span> 140f4a2713aSLionel Sambuc <span class="snip"> myvec[1]/P;</span> 141f4a2713aSLionel Sambuc <span class="point"> ~~~~~~~~^~</span> 142f4a2713aSLionel Sambuc</pre> 143f4a2713aSLionel Sambuc 144f4a2713aSLionel Sambuc<p>The following example shows where it is useful for the compiler to expose 145f4a2713aSLionel Sambucunderlying details of a typedef. If the user was somehow confused about how the 146f4a2713aSLionel Sambucsystem "pid_t" typedef is defined, Clang helpfully displays it with "aka".</p> 147f4a2713aSLionel Sambuc 148f4a2713aSLionel Sambuc<pre> 149*0a6a1f1dSLionel Sambuc $ <span class="cmd">clang -fsyntax-only t.c</span> 150*0a6a1f1dSLionel Sambuc <span class="loc">t.c:13:9:</span> <span class="err">error:</span> <span class="msg">member reference base type 'pid_t' (aka 'int') is not a structure or union</span> 151f4a2713aSLionel Sambuc <span class="snip"> myvar = myvar.x;</span> 152f4a2713aSLionel Sambuc <span class="point"> ~~~~~ ^</span> 153f4a2713aSLionel Sambuc</pre> 154f4a2713aSLionel Sambuc 155f4a2713aSLionel Sambuc<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: 156f4a2713aSLionel Sambuc 157f4a2713aSLionel Sambuc<blockquote> 158f4a2713aSLionel Sambuc<pre> 159f4a2713aSLionel Sambucnamespace services { 160f4a2713aSLionel Sambuc struct WebService { }; 161f4a2713aSLionel Sambuc} 162f4a2713aSLionel Sambucnamespace myapp { 163f4a2713aSLionel Sambuc namespace servers { 164f4a2713aSLionel Sambuc struct Server { }; 165f4a2713aSLionel Sambuc } 166f4a2713aSLionel Sambuc} 167f4a2713aSLionel Sambuc 168f4a2713aSLionel Sambucusing namespace myapp; 169f4a2713aSLionel Sambucvoid addHTTPService(servers::Server const &server, ::services::WebService const *http) { 170f4a2713aSLionel Sambuc server += http; 171f4a2713aSLionel Sambuc} 172f4a2713aSLionel Sambuc</pre> 173f4a2713aSLionel Sambuc</blockquote> 174f4a2713aSLionel Sambuc 175*0a6a1f1dSLionel Sambuc<p>and then compile it, we see that Clang is both providing accurate information and is retaining the types as written by the user (e.g., "servers::Server", "::services::WebService"): 176f4a2713aSLionel Sambuc 177f4a2713aSLionel Sambuc<pre> 178*0a6a1f1dSLionel Sambuc $ <span class="cmd">clang -fsyntax-only t.cpp</span> 179*0a6a1f1dSLionel Sambuc <span class="loc">t.cpp:9:10:</span> <span class="err">error:</span> <span class="msg">invalid operands to binary expression ('servers::Server const' and '::services::WebService const *')</span> 180f4a2713aSLionel Sambuc <span class="snip">server += http;</span> 181f4a2713aSLionel Sambuc <span class="point">~~~~~~ ^ ~~~~</span> 182f4a2713aSLionel Sambuc</pre> 183f4a2713aSLionel Sambuc 184f4a2713aSLionel Sambuc<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> 185f4a2713aSLionel Sambuc 186f4a2713aSLionel Sambuc<pre> 187*0a6a1f1dSLionel Sambuc $ <span class="cmd">clang -fsyntax-only t.cpp</span> 188*0a6a1f1dSLionel Sambuc <span class="loc">t.cpp:12:7:</span> <span class="err">error:</span> <span class="msg">incompatible type assigning 'vector<Real>', expected 'std::string' (aka 'class std::basic_string<char>')</span> 189f4a2713aSLionel Sambuc <span class="snip">str = vec</span>; 190f4a2713aSLionel Sambuc <span class="point">^ ~~~</span> 191f4a2713aSLionel Sambuc</pre> 192f4a2713aSLionel Sambuc 193f4a2713aSLionel Sambuc<h2>Fix-it Hints</h2> 194f4a2713aSLionel Sambuc 195f4a2713aSLionel Sambuc<p>"Fix-it" hints provide advice for fixing small, localized problems 196f4a2713aSLionel Sambucin source code. When Clang produces a diagnostic about a particular 197f4a2713aSLionel Sambucproblem that it can work around (e.g., non-standard or redundant 198f4a2713aSLionel Sambucsyntax, missing keywords, common mistakes, etc.), it may also provide 199f4a2713aSLionel Sambucspecific guidance in the form of a code transformation to correct the 200f4a2713aSLionel Sambucproblem. In the following example, Clang warns about the use of a GCC 201f4a2713aSLionel Sambucextension that has been considered obsolete since 1993. The underlined 202f4a2713aSLionel Sambuccode should be removed, then replaced with the code below the 203f4a2713aSLionel Sambucpoint line (".x =" or ".y =", respectively).</p> 204f4a2713aSLionel Sambuc 205f4a2713aSLionel Sambuc<pre> 206*0a6a1f1dSLionel Sambuc $ <span class="cmd">clang t.c</span> 207*0a6a1f1dSLionel Sambuc <span class="loc">t.c:5:28:</span> <span class="warn">warning:</span> <span class="msg">use of GNU old-style field designator extension</span> 208f4a2713aSLionel Sambuc <span class="snip">struct point origin = { x: 0.0, y: 0.0 };</span> 209*0a6a1f1dSLionel Sambuc <span class="err">~~</span> <span class="msg"><span class="point">^</span></span> 210f4a2713aSLionel Sambuc <span class="snip">.x = </span> 211*0a6a1f1dSLionel Sambuc <span class="loc">t.c:5:36:</span> <span class="warn">warning:</span> <span class="msg">use of GNU old-style field designator extension</span> 212f4a2713aSLionel Sambuc <span class="snip">struct point origin = { x: 0.0, y: 0.0 };</span> 213*0a6a1f1dSLionel Sambuc <span class="err">~~</span> <span class="msg"><span class="point">^</span></span> 214f4a2713aSLionel Sambuc <span class="snip">.y = </span> 215f4a2713aSLionel Sambuc</pre> 216f4a2713aSLionel Sambuc 217f4a2713aSLionel Sambuc<p>"Fix-it" hints are most useful for 218f4a2713aSLionel Sambucworking around common user errors and misconceptions. For example, C++ users 219f4a2713aSLionel Sambuccommonly forget the syntax for explicit specialization of class templates, 220f4a2713aSLionel Sambucas in the error in the following example. Again, after describing the problem, 221f4a2713aSLionel SambucClang provides the fix--add <code>template<></code>--as part of the 222f4a2713aSLionel Sambucdiagnostic.<p> 223f4a2713aSLionel Sambuc 224f4a2713aSLionel Sambuc<pre> 225*0a6a1f1dSLionel Sambuc $ <span class="cmd">clang t.cpp</span> 226*0a6a1f1dSLionel Sambuc <span class="loc">t.cpp:9:3:</span> <span class="err">error:</span> <span class="msg">template specialization requires 'template<>'</span> 227f4a2713aSLionel Sambuc struct iterator_traits<file_iterator> { 228f4a2713aSLionel Sambuc <span class="point">^</span> 229f4a2713aSLionel Sambuc <span class="snip">template<> </span> 230f4a2713aSLionel Sambuc</pre> 231f4a2713aSLionel Sambuc 232f4a2713aSLionel Sambuc<h2>Template Type Diffing</h2> 233f4a2713aSLionel Sambuc 234f4a2713aSLionel Sambuc<p>Templates types can be long and difficult to read. Moreso when part of an 235f4a2713aSLionel Sambucerror message. Instead of just printing out the type name, Clang has enough 236f4a2713aSLionel Sambucinformation to remove the common elements and highlight the differences. To 237f4a2713aSLionel Sambucshow the template structure more clearly, the templated type can also be 238f4a2713aSLionel Sambucprinted as an indented text tree.</p> 239f4a2713aSLionel Sambuc 240f4a2713aSLionel SambucDefault: template diff with type elision 241f4a2713aSLionel Sambuc<pre> 242*0a6a1f1dSLionel Sambuc<span class="loc">t.cc:4:5:</span> <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; 243f4a2713aSLionel Sambuc</pre> 244f4a2713aSLionel Sambuc-fno-elide-type: template diff without elision 245f4a2713aSLionel Sambuc<pre> 246*0a6a1f1dSLionel Sambuc<span class="loc">t.cc:4:5:</span> <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; 247f4a2713aSLionel Sambuc</pre> 248f4a2713aSLionel Sambuc-fdiagnostics-show-template-tree: template tree printing with elision 249f4a2713aSLionel Sambuc<pre> 250*0a6a1f1dSLionel Sambuc<span class="loc">t.cc:4:5:</span> <span class="note">note:</span> candidate function not viable: no known conversion for 1st argument; 251f4a2713aSLionel Sambuc vector< 252f4a2713aSLionel Sambuc map< 253f4a2713aSLionel Sambuc [...], 254f4a2713aSLionel Sambuc [<span class="template-highlight">float</span> != <span class="template-highlight">double</span>]>> 255f4a2713aSLionel Sambuc</pre> 256f4a2713aSLionel Sambuc-fdiagnostics-show-template-tree -fno-elide-type: template tree printing with no elision 257f4a2713aSLionel Sambuc<pre> 258*0a6a1f1dSLionel Sambuc<span class="loc">t.cc:4:5:</span> <span class="note">note:</span> candidate function not viable: no known conversion for 1st argument; 259f4a2713aSLionel Sambuc vector< 260f4a2713aSLionel Sambuc map< 261f4a2713aSLionel Sambuc int, 262f4a2713aSLionel Sambuc [<span class="template-highlight">float</span> != <span class="template-highlight">double</span>]>> 263f4a2713aSLionel Sambuc</pre> 264f4a2713aSLionel Sambuc 265f4a2713aSLionel Sambuc<h2>Automatic Macro Expansion</h2> 266f4a2713aSLionel Sambuc 267f4a2713aSLionel Sambuc<p>Many errors happen in macros that are sometimes deeply nested. With 268f4a2713aSLionel Sambuctraditional compilers, you need to dig deep into the definition of the macro to 269f4a2713aSLionel Sambucunderstand how you got into trouble. The following simple example shows how 270f4a2713aSLionel SambucClang helps you out by automatically printing instantiation information and 271f4a2713aSLionel Sambucnested range information for diagnostics as they are instantiated through macros 272f4a2713aSLionel Sambucand also shows how some of the other pieces work in a bigger example.</p> 273f4a2713aSLionel Sambuc 274f4a2713aSLionel Sambuc<pre> 275*0a6a1f1dSLionel Sambuc $ <span class="cmd">clang -fsyntax-only t.c</span> 276*0a6a1f1dSLionel Sambuc <span class="loc">t.c:80:3:</span> <span class="err">error:</span> <span class="msg">invalid operands to binary expression ('typeof(P)' (aka 'struct mystruct') and 'typeof(F)' (aka 'float'))</span> 277f4a2713aSLionel Sambuc <span class="snip"> X = MYMAX(P, F);</span> 278f4a2713aSLionel Sambuc <span class="point"> ^~~~~~~~~~~</span> 279*0a6a1f1dSLionel Sambuc <span class="loc">t.c:76:94:</span> <span class="note">note:</span> expanded from: 280f4a2713aSLionel Sambuc <span class="snip">#define MYMAX(A,B) __extension__ ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __b : __a; })</span> 281f4a2713aSLionel Sambuc <span class="point"> ~~~ ^ ~~~</span> 282f4a2713aSLionel Sambuc</pre> 283f4a2713aSLionel Sambuc 284f4a2713aSLionel Sambuc<p>Here's another real world warning that occurs in the "window" Unix package (which 285f4a2713aSLionel Sambucimplements the "wwopen" class of APIs):</p> 286f4a2713aSLionel Sambuc 287f4a2713aSLionel Sambuc<pre> 288*0a6a1f1dSLionel Sambuc $ <span class="cmd">clang -fsyntax-only t.c</span> 289*0a6a1f1dSLionel Sambuc <span class="loc">t.c:22:2:</span> <span class="warn">warning:</span> <span class="msg">type specifier missing, defaults to 'int'</span> 290f4a2713aSLionel Sambuc <span class="snip"> ILPAD();</span> 291f4a2713aSLionel Sambuc <span class="point"> ^</span> 292*0a6a1f1dSLionel Sambuc <span class="loc">t.c:17:17:</span> <span class="note">note:</span> expanded from: 293f4a2713aSLionel Sambuc <span class="snip">#define ILPAD() PAD((NROW - tt.tt_row) * 10) /* 1 ms per char */</span> 294f4a2713aSLionel Sambuc <span class="point"> ^</span> 295*0a6a1f1dSLionel Sambuc <span class="loc">t.c:14:2:</span> <span class="note">note:</span> expanded from: 296f4a2713aSLionel Sambuc <span class="snip"> register i; \</span> 297f4a2713aSLionel Sambuc <span class="point"> ^</span> 298f4a2713aSLionel Sambuc</pre> 299f4a2713aSLionel Sambuc 300f4a2713aSLionel Sambuc<p>In practice, we've found that Clang's treatment of macros is actually more useful in multiply nested 301f4a2713aSLionel Sambucmacros that in simple ones.</p> 302f4a2713aSLionel Sambuc 303f4a2713aSLionel Sambuc<h2>Quality of Implementation and Attention to Detail</h2> 304f4a2713aSLionel Sambuc 305f4a2713aSLionel Sambuc<p>Finally, we have put a lot of work polishing the little things, because 306f4a2713aSLionel Sambuclittle things add up over time and contribute to a great user experience.</p> 307f4a2713aSLionel Sambuc 308f4a2713aSLionel Sambuc<p>The following example shows that we recover from the simple case of 309f4a2713aSLionel Sambucforgetting a ; after a struct definition much better than GCC.</p> 310f4a2713aSLionel Sambuc 311f4a2713aSLionel Sambuc<pre> 312*0a6a1f1dSLionel Sambuc $ <span class="cmd">cat t.cc</span> 313f4a2713aSLionel Sambuc template<class T> 314*0a6a1f1dSLionel Sambuc class a {}; 315*0a6a1f1dSLionel Sambuc struct b {} 316*0a6a1f1dSLionel Sambuc a<int> c; 317*0a6a1f1dSLionel Sambuc $ <span class="cmd">gcc-4.9 t.cc</span> 318*0a6a1f1dSLionel Sambuc t.cc:4:8: error: invalid declarator before 'c' 319*0a6a1f1dSLionel Sambuc a<int> c; 320*0a6a1f1dSLionel Sambuc ^ 321*0a6a1f1dSLionel Sambuc $ <span class="cmd">clang t.cc</span> 322*0a6a1f1dSLionel Sambuc <span class="loc">t.cc:3:12:</span> <span class="err">error:</span> <span class="msg">expected ';' after struct</span> 323*0a6a1f1dSLionel Sambuc <span class="snip" >struct b {}</span> 324f4a2713aSLionel Sambuc <span class="point"> ^</span> 325f4a2713aSLionel Sambuc <span class="point"> ;</span> 326f4a2713aSLionel Sambuc</pre> 327f4a2713aSLionel Sambuc 328*0a6a1f1dSLionel Sambuc<p>The following example shows that we diagnose and recover from a missing 329*0a6a1f1dSLionel Sambuc<tt>typename</tt> keyword well, even in complex circumstances where GCC 330*0a6a1f1dSLionel Sambuccannot cope.</p> 331*0a6a1f1dSLionel Sambuc 332*0a6a1f1dSLionel Sambuc<pre> 333*0a6a1f1dSLionel Sambuc $ <span class="cmd">cat t.cc</span> 334*0a6a1f1dSLionel Sambuc template<class T> void f(T::type) { } 335*0a6a1f1dSLionel Sambuc struct A { }; 336*0a6a1f1dSLionel Sambuc void g() 337*0a6a1f1dSLionel Sambuc { 338*0a6a1f1dSLionel Sambuc A a; 339*0a6a1f1dSLionel Sambuc f<A>(a); 340*0a6a1f1dSLionel Sambuc } 341*0a6a1f1dSLionel Sambuc $ <span class="cmd">gcc-4.9 t.cc</span> 342*0a6a1f1dSLionel Sambuc t.cc:1:33: error: variable or field 'f' declared void 343*0a6a1f1dSLionel Sambuc template<class T> void f(T::type) { } 344*0a6a1f1dSLionel Sambuc ^ 345*0a6a1f1dSLionel Sambuc t.cc: In function 'void g()': 346*0a6a1f1dSLionel Sambuc t.cc:6:5: error: 'f' was not declared in this scope 347*0a6a1f1dSLionel Sambuc f<A>(a); 348*0a6a1f1dSLionel Sambuc ^ 349*0a6a1f1dSLionel Sambuc t.cc:6:8: error: expected primary-expression before '>' token 350*0a6a1f1dSLionel Sambuc f<A>(a); 351*0a6a1f1dSLionel Sambuc ^ 352*0a6a1f1dSLionel Sambuc $ <span class="cmd">clang t.cc</span> 353*0a6a1f1dSLionel Sambuc <span class="loc">t.cc:1:26:</span> <span class="err">error:</span> <span class="msg">missing 'typename' prior to dependent type name 'T::type'</span> 354*0a6a1f1dSLionel Sambuc <span class="snip" >template<class T> void f(T::type) { }</span> 355*0a6a1f1dSLionel Sambuc <span class="point"> ^~~~~~~</span> 356*0a6a1f1dSLionel Sambuc <span class="point"> typename </span> 357*0a6a1f1dSLionel Sambuc <span class="loc">t.cc:6:5:</span> <span class="err">error:</span> <span class="msg">no matching function for call to 'f'</span> 358*0a6a1f1dSLionel Sambuc <span class="snip" > f<A>(a);</span> 359*0a6a1f1dSLionel Sambuc <span class="point"> ^~~~</span> 360*0a6a1f1dSLionel Sambuc <span class="loc">t.cc:1:24:</span> <span class="note">note:</span> <span class="msg">candidate template ignored: substitution failure [with T = A]: no type named 'type' in 'A'</span> 361*0a6a1f1dSLionel Sambuc <span class="snip" >template<class T> void f(T::type) { }</span> 362*0a6a1f1dSLionel Sambuc <span class="point"> ^ ~~~~</span> 363*0a6a1f1dSLionel Sambuc</pre> 364*0a6a1f1dSLionel Sambuc 365*0a6a1f1dSLionel Sambuc 366*0a6a1f1dSLionel Sambuc 367f4a2713aSLionel Sambuc<p>While each of these details is minor, we feel that they all add up to provide 368f4a2713aSLionel Sambuca much more polished experience.</p> 369f4a2713aSLionel Sambuc 370f4a2713aSLionel Sambuc</div> 371f4a2713aSLionel Sambuc</body> 372f4a2713aSLionel Sambuc</html> 373