<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><div>On Nov 20, 2008, at 5:30 AM, Douglas Gregor wrote:</div><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>This is the source line:</div><div><div><div>Lexer *L; char Res;</div></div><div>...</div><div>  L->Diag(CP-2, diag::trigraph_converted) << std::string()+Res;</div></div></div></blockquote><div><br></div><div>The basic problem is that Diag() is returning a temporary, but a non-const (lvalue) reference can't bind to a temporary. I suggest making the first parameter to these operator<<'s either a const DiagnosticInfo& or a DiagnosticInfo. (The former will require a bunch of other member functions to be const, but so what?)</div></div></div></blockquote><div><br></div><div>Right.  It isn't logically const, but that will definitely fix it.  I'll do it.</div><br><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><br><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>This is a good point where we can step back and look at the amazing awfulness of this diagnostic.  It's 'pretty' printing out the expression in question, in a horribly mangled form.  Then it dumps out a candidate list, but manages to not tell me the types that it actually *has* on the LHS/RHS of the <<.  </div></div></blockquote><div><br></div>We should use this kind of thing as a test case for our diagnostics, to see how clear we can make them.<br></div></div></blockquote></div><br><div>I filed this PR with a testcase:</div><div><a href="http://llvm.org/bugs/show_bug.cgi?id=3104">http://llvm.org/bugs/show_bug.cgi?id=3104</a></div><div><br></div><div>Interestingly enough, if you run clang on the .ii file, we get these diagnostics to start with:</div><div><br></div><div><div><font class="Apple-style-span" face="Courier">Debug/Lexer.ii:2073:1: error: expected unqualified-id</font></div><div><font class="Apple-style-span" face="Courier">template <typename T> struct SerializeTrait;</font></div><div><font class="Apple-style-span" face="Courier">^</font></div><div><font class="Apple-style-span" face="Courier">Debug/Lexer.ii:2228:12: error: incompatible type returning 'class SourceLocation', expected 'class SourceLocation'</font></div><div><font class="Apple-style-span" face="Courier">    return X;</font></div><div><font class="Apple-style-span" face="Courier">           ^</font></div><div><font class="Apple-style-span" face="Courier">Debug/Lexer.ii:2209:12: error: incompatible type returning 'class SourceLocation', expected 'class SourceLocation'</font></div><div><font class="Apple-style-span" face="Courier">    return getFileLoc(FileID, Offset);</font></div><div><font class="Apple-style-span" face="Courier">           ^~~~~~~~~~~~~~~~~~~~~~~~~~</font></div><div><font class="Apple-style-span" face="Courier">Debug/Lexer.ii:2164:12: error: incompatible type returning 'class SourceLocation', expected 'class SourceLocation'</font></div><div><font class="Apple-style-span" face="Courier">    return L;</font></div><div><font class="Apple-style-span" face="Courier">           ^</font></div><div><font class="Apple-style-span" face="Courier">Debug/Lexer.ii:2144:12: error: incompatible type returning 'class SourceLocation', expected 'class SourceLocation'</font></div><div><font class="Apple-style-span" face="Courier">    return L;</font></div><div><font class="Apple-style-span" face="Courier">           ^</font></div><div><font class="Apple-style-span" face="Courier">Debug/Lexer.ii:2239:14: error: no member named 'getRawEncoding'</font></div><div><font class="Apple-style-span" face="Courier">  return LHS.getRawEncoding() == RHS.getRawEncoding();</font></div><div><font class="Apple-style-span" face="Courier">         ~~~ ^</font></div><div><font class="Apple-style-span" face="Courier">Debug/Lexer.ii:2261:35: error: no member named 'isValid'</font></div><div><font class="Apple-style-span" face="Courier">  bool isValid() const { return B.isValid() && E.isValid(); }</font></div><div><font class="Apple-style-span" face="Courier">                                ~ ^</font></div><div><font class="Apple-style-span" face="Courier">Debug/Lexer.ii:2251:20: error: class constructors are not supported yet</font></div><div><font class="Apple-style-span" face="Courier">  SourceRange(): B(SourceLocation()), E(SourceLocation()) {}</font></div><div><font class="Apple-style-span" face="Courier">                   ^</font></div><div><font class="Apple-style-span" face="Courier"><div>Debug/Lexer.ii:2251:41: error: class constructors are not supported yet</div><div>  SourceRange(): B(SourceLocation()), E(SourceLocation()) {}</div><div>                                        ^</div><div>Debug/Lexer.ii:2294:24: error: functions that differ only in their return type cannot be overloaded</div><div>  const SourceManager& getManager() const {</div><div>                       ^</div><div>Debug/Lexer.ii:2289:18: error: previous declaration is here</div><div>  SourceManager& getManager() {</div><div>                 ^</div><div>...</div></font></div><div><br></div><div>The first issue is obvious (no templates).  The new few look strange though and are probably easy to fix.  The next couple are about methods not implemented.  The 'not implemented' ones are very cute :).  It looks like overloading + const methods isn't wired up yet.</div><div><br></div><div>It's pretty impressive how much C++ is starting to parse now!</div><div><br></div><div>-Chris</div><div><br></div></div></body></html>