]> granicus.if.org Git - clang/commitdiff
After late parsing an objc method, make sure there are no leftover cached tokens,
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Sat, 17 Dec 2011 04:13:18 +0000 (04:13 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Sat, 17 Dec 2011 04:13:18 +0000 (04:13 +0000)
because the memory associated with them is going to get released.
We also don't want them to affect later parsing.
(We do the same for C++ inline methods.)

The underlying cause for the leftover tokens is going to be addressed in the
next commit.

Couldn't get a test case for the crash though. rdar://10583033.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146814 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Parse/ParseObjc.cpp

index 5ac1d6c331c7131ce844753c19f817f0077c8d2e..56d5c57c056d41baf85e4d3dadf581125a629fa2 100644 (file)
@@ -2564,7 +2564,10 @@ ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) {
  }
 
 Decl *Parser::ParseLexedObjCMethodDefs(LexedMethod &LM) {
-    
+
+  // Save the current token position.
+  SourceLocation OrigLoc = Tok.getLocation();
+
   assert(!LM.Toks.empty() && "ParseLexedObjCMethodDef - Empty body!");
   // Append the current token at the end of the new token stream so that it
   // doesn't get lost.
@@ -2603,5 +2606,19 @@ Decl *Parser::ParseLexedObjCMethodDefs(LexedMethod &LM) {
   // Leave the function body scope.
   BodyScope.Exit();
     
-  return Actions.ActOnFinishFunctionBody(MDecl, FnBody.take());
+  MDecl = Actions.ActOnFinishFunctionBody(MDecl, FnBody.take());
+
+  if (Tok.getLocation() != OrigLoc) {
+    // Due to parsing error, we either went over the cached tokens or
+    // there are still cached tokens left. If it's the latter case skip the
+    // leftover tokens.
+    // Since this is an uncommon situation that should be avoided, use the
+    // expensive isBeforeInTranslationUnit call.
+    if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(),
+                                                     OrigLoc))
+      while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof))
+        ConsumeAnyToken();
+  }
+  
+  return MDecl;
 }