]> granicus.if.org Git - clang/commitdiff
Fix this:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Wed, 19 Nov 2008 15:22:16 +0000 (15:22 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Wed, 19 Nov 2008 15:22:16 +0000 (15:22 +0000)
With this snippet:
  void f(a::b);

An assert is hit:
Assertion failed: CachedTokens[CachedLexPos-1].getLocation() == Tok.getAnnotationEndLoc() && "The annotation should be until the most recent cached token", file ..\..\lib\Lex\PPCaching.cpp, line 98

Introduce Preprocessor::RevertCachedTokens that reverts a specific number of tokens when backtracking is enabled.

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

include/clang/Lex/Preprocessor.h
lib/Parse/Parser.cpp
test/SemaCXX/nested-name-spec.cpp

index 9af53bf4947441671e25492e194fa8775130b4f3..4d31be4ecf4edead3d4f903025231ba34aa674fb 100644 (file)
@@ -369,6 +369,20 @@ public:
       return PeekAhead(N+1);
   }
 
+  /// RevertCachedTokens - When backtracking is enabled and tokens are cached,
+  /// this allows to revert a specific number of tokens.
+  /// Note that the number of tokens being reverted should be up to the last
+  /// backtrack position, not more.
+  void RevertCachedTokens(unsigned N) {
+    assert(isBacktrackEnabled() &&
+           "Should only be called when tokens are cached for backtracking");
+    assert(signed(CachedLexPos) - signed(N) >= signed(BacktrackPositions.back())
+         && "Should revert tokens up to the last backtrack position, not more");
+    assert(signed(CachedLexPos) - signed(N) >= 0 &&
+           "Corrupted backtrack positions ?");
+    CachedLexPos -= N;
+  }
+
   /// EnterToken - Enters a token in the token stream to be lexed next. If
   /// BackTrack() is called afterwards, the token will remain at the insertion
   /// point.
index 86526cc158cb81598041956dc74ee7370a52f858..861609ce7538348f667ab9d80be76b41e4e7557d 100644 (file)
@@ -731,9 +731,12 @@ void Parser::TryAnnotateTypeOrScopeToken() {
 
   if (SS.isNotEmpty()) {
     // A C++ scope specifier that isn't followed by a typename.
-    // Push the current token back into the token stream and use an annotation
-    // scope token for current token.
-    PP.EnterToken(Tok);
+    // Push the current token back into the token stream (or revert it if it is
+    // cached) and use an annotation scope token for current token.
+    if (PP.isBacktrackEnabled())
+      PP.RevertCachedTokens(1);
+    else
+      PP.EnterToken(Tok);
     Tok.setKind(tok::annot_cxxscope);
     Tok.setAnnotationValue(SS.getScopeRep());
     Tok.setAnnotationRange(SS.getRange());
@@ -754,9 +757,12 @@ void Parser::TryAnnotateScopeToken() {
     CXXScopeSpec SS;
     ParseCXXScopeSpecifier(SS);
 
-    // Push the current token back into the token stream and use an annotation
-    // scope token for current token.
-    PP.EnterToken(Tok);
+    // Push the current token back into the token stream (or revert it if it is
+    // cached) and use an annotation scope token for current token.
+    if (PP.isBacktrackEnabled())
+      PP.RevertCachedTokens(1);
+    else
+      PP.EnterToken(Tok);
     Tok.setKind(tok::annot_cxxscope);
     Tok.setAnnotationValue(SS.getScopeRep());
     Tok.setAnnotationRange(SS.getRange());
index cf0500dffe5858fe75d7bdc69973aba29bb7efc9..b22d8dc3d4d3073186ac524c76efbb29bca287c0 100644 (file)
@@ -63,3 +63,6 @@ void f3() {
   { typedef A::C A;  A::ax = 0; } // expected-error {{no member named 'ax'}}
   { typedef A::C A;  A::cx = 0; }
 }
+
+// make sure the following doesn't hit any asserts
+void f4(undef::C); // expected-error {{use of undeclared identifier 'undef'}} // expected-error {{expected ')'}} expected-error {{to match this '('}} // expected-error {{variable has incomplete type 'void'}}