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