<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Dec 18, 2014 at 1:57 AM, David Majnemer <span dir="ltr"><<a href="mailto:david.majnemer@gmail.com" target="_blank">david.majnemer@gmail.com</a>></span> wrote:<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: majnemer<br>
Date: Thu Dec 18 03:57:31 2014<br>
New Revision: 224505<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=224505&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=224505&view=rev</a><br>
Log:<br>
Parse: Don't parse after the eof has been consumed<br>
<br>
ParseCXXNonStaticMemberInitializer stashes away all the tokens for the<br>
initializer and an additional EOF token to denote where the initializer<br>
ends.  However, it is possible for ParseLexedMemberInitializer to get<br>
its hands on the "real" EOF token; since the two tokens are<br>
indistinguishable, we end up consuming the EOF and descend into madness.<br>
<br>
Instead, make it possible to tell which EOF token we are looking at.<br>
<br>
This fixes PR21872.<br>
<br>
Added:<br>
    cfe/trunk/test/Parser/PR21872.cpp<br>
Modified:<br>
    cfe/trunk/include/clang/Lex/Token.h<br>
    cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Lex/Token.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Token.h?rev=224505&r1=224504&r2=224505&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Token.h?rev=224505&r1=224504&r2=224505&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Lex/Token.h (original)<br>
+++ cfe/trunk/include/clang/Lex/Token.h Thu Dec 18 03:57:31 2014<br>
@@ -23,6 +23,7 @@<br>
<br>
 namespace clang {<br>
<br>
+class Decl;<br></blockquote><div><br></div><div>This is a layering violation; Lex should have no knowledge of AST-level entities like Decls. Instead, just use an opaque void* pointer here and do the casting in the Parser.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
 class IdentifierInfo;<br>
<br>
 /// Token - This structure provides full information about a lexed token.<br>
@@ -58,6 +59,8 @@ class Token {<br>
   ///    may be dirty (have trigraphs / escaped newlines).<br>
   ///  Annotations (resolved type names, C++ scopes, etc): isAnnotation().<br>
   ///    This is a pointer to sema-specific data for the annotation token.<br>
+  ///  Eof:<br>
+  //     This is a pointer to a Decl.<br>
   ///  Other:<br>
   ///    This is null.<br>
   void *PtrData;<br>
@@ -164,12 +167,23 @@ public:<br>
     assert(!isAnnotation() &&<br>
            "getIdentifierInfo() on an annotation token!");<br>
     if (isLiteral()) return nullptr;<br>
+    if (is(tok::eof)) return nullptr;<br></blockquote><div><br></div><div>Maybe assert on this case rather than adding another branch to this function? (I'd expect it to be relatively hot.)</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
     return (IdentifierInfo*) PtrData;<br>
   }<br>
   void setIdentifierInfo(IdentifierInfo *II) {<br>
     PtrData = (void*) II;<br>
   }<br>
<br>
+  const Decl *getDecl() const {<br>
+    assert(is(tok::eof));<br>
+    return reinterpret_cast<const Decl *>(PtrData);<br>
+  }<br>
+  void setDecl(const Decl *D) {<br>
+    assert(is(tok::eof));<br>
+    assert(!PtrData);<br>
+    PtrData = const_cast<Decl *>(D);<br>
+  }<br></blockquote><div><br></div><div>Maybe setEofData?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
   /// getRawIdentifier - For a raw identifier token (i.e., an identifier<br>
   /// lexed in raw mode), returns a reference to the text substring in the<br>
   /// buffer if known.<br>
<br>
Modified: cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=224505&r1=224504&r2=224505&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=224505&r1=224504&r2=224505&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp Thu Dec 18 03:57:31 2014<br>
@@ -218,6 +218,7 @@ void Parser::ParseCXXNonStaticMemberInit<br>
   Eof.startToken();<br>
   Eof.setKind(tok::eof);<br>
   Eof.setLocation(Tok.getLocation());<br>
+  Eof.setDecl(VarD);<br>
   Toks.push_back(Eof);<br>
 }<br>
<br>
@@ -622,7 +623,9 @@ void Parser::ParseLexedMemberInitializer<br>
     while (Tok.isNot(tok::eof))<br>
       ConsumeAnyToken();<br>
   }<br>
-  ConsumeAnyToken();<br>
+  // Make sure this is *our* artificial EOF token.<br>
+  if (Tok.getDecl() == MI.Field)<br>
+    ConsumeAnyToken();<br>
 }<br>
<br>
 /// ConsumeAndStoreUntil - Consume and store the token at the passed token<br>
<br>
Added: cfe/trunk/test/Parser/PR21872.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/PR21872.cpp?rev=224505&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/PR21872.cpp?rev=224505&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/Parser/PR21872.cpp (added)<br>
+++ cfe/trunk/test/Parser/PR21872.cpp Thu Dec 18 03:57:31 2014<br>
@@ -0,0 +1,4 @@<br>
+// RUN: not %clang_cc1 -fsyntax-only %s<br>
+template <typename T> struct S {<br>
+    int k = ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((<br>
+int f;<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div></div></div>