[PATCH] D15173: [Preprocessor] Fix assertion in AnnotatePreviousCachedTokens

Bruno Cardoso Lopes via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 7 19:13:54 PST 2016


bruno updated this revision to Diff 44306.
bruno added a comment.

Hi Richard,

Thanks for the detailed explanation, it now makes sense to me. I updated the patch with another approach! Let me know if it's the right direction.


http://reviews.llvm.org/D15173

Files:
  include/clang/Lex/Preprocessor.h
  lib/Lex/PPCaching.cpp
  lib/Parse/ParseTemplate.cpp
  test/Parser/objcxx11-protocol-in-template.mm

Index: test/Parser/objcxx11-protocol-in-template.mm
===================================================================
--- test/Parser/objcxx11-protocol-in-template.mm
+++ test/Parser/objcxx11-protocol-in-template.mm
@@ -8,3 +8,11 @@
 
 vector<id<P>> v;
 vector<vector<id<P>>> v2;
+
+ at protocol PA;
+ at protocol PB;
+
+ at class NSArray<ObjectType>;
+typedef int some_t;
+
+id<PA> FA(NSArray<id<PB>> *h, some_t group);
Index: lib/Parse/ParseTemplate.cpp
===================================================================
--- lib/Parse/ParseTemplate.cpp
+++ lib/Parse/ParseTemplate.cpp
@@ -827,6 +827,7 @@
   }
 
   // Strip the initial '>' from the token.
+  Token PrevTok = Tok;
   if (RemainingToken == tok::equal && Next.is(tok::equal) &&
       areTokensAdjacent(Tok, Next)) {
     // Join two adjacent '=' tokens into one, for cases like:
@@ -843,6 +844,20 @@
                                                  PP.getSourceManager(),
                                                  getLangOpts()));
 
+  // The advance from '>>' to '>' in a ObjectiveC template argument list needs
+  // to be properly reflected in the token cache to allow correct interaction
+  // between annotation and backtracking.
+  if (ObjCGenericList && PrevTok.getKind() == tok::greatergreater &&
+      RemainingToken == tok::greater &&
+      PrevTok.getLocation().getRawEncoding() <=
+          PP.getLastCachedTokenLocation().getRawEncoding()) {
+    Token ReplTok = PrevTok;
+    PrevTok.setKind(RemainingToken);
+    PrevTok.setLength(1);
+    SmallVector<Token, 2> NewToks = {PrevTok, Tok};
+    PP.ReplaceCachedToken(ReplTok, NewToks);
+  }
+
   if (!ConsumeLastToken) {
     // Since we're not supposed to consume the '>' token, we need to push
     // this token and revert the current token back to the '>'.
Index: lib/Lex/PPCaching.cpp
===================================================================
--- lib/Lex/PPCaching.cpp
+++ lib/Lex/PPCaching.cpp
@@ -116,3 +116,19 @@
     }
   }
 }
+
+void Preprocessor::ReplaceCachedToken(const Token &Tok,
+                                      SmallVectorImpl<Token> &NewToks) {
+  assert(CachedLexPos != 0 && "Expected to have some cached tokens");
+  for (auto i = CachedLexPos - 1; i != 0; --i) {
+    const Token CurrCachedTok = CachedTokens[i];
+    if (CurrCachedTok.getKind() == Tok.getKind() &&
+        CurrCachedTok.getLocation() == Tok.getLocation()) {
+      CachedTokens.insert(CachedTokens.begin() + i, NewToks.begin(),
+                          NewToks.end());
+      CachedTokens.erase(CachedTokens.begin() + i + NewToks.size());
+      CachedLexPos += NewToks.size() - 1;
+      return;
+    }
+  }
+}
Index: include/clang/Lex/Preprocessor.h
===================================================================
--- include/clang/Lex/Preprocessor.h
+++ include/clang/Lex/Preprocessor.h
@@ -1185,6 +1185,12 @@
     return CachedTokens[CachedLexPos-1].getLastLoc();
   }
 
+  /// \brief Replace token \p Tok in CachedTokens by the tokens in \p NewToks.
+  ///
+  /// Useful when a token needs to be split in smaller ones and CachedTokens
+  /// must to be updated to reflect that.
+  void ReplaceCachedToken(const Token &Tok, SmallVectorImpl<Token> &NewToks);
+
   /// \brief Replace the last token with an annotation token.
   ///
   /// Like AnnotateCachedTokens(), this routine replaces an


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D15173.44306.patch
Type: text/x-patch
Size: 3343 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160108/3573ce80/attachment.bin>


More information about the cfe-commits mailing list