diff options
author | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2016-01-31 00:47:51 +0000 |
---|---|---|
committer | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2016-01-31 00:47:51 +0000 |
commit | 428a5aa9a5ff6ab0242c6813eaa0a39b87ea15ab (patch) | |
tree | bdafcb4b709e0bb05cb89a8eae7a17083a1e9a8e /clang/lib/Parse/ParseTemplate.cpp | |
parent | 054b391cf479b7bfda27c82b856a823d5b81aac6 (diff) | |
download | bcm5719-llvm-428a5aa9a5ff6ab0242c6813eaa0a39b87ea15ab.tar.gz bcm5719-llvm-428a5aa9a5ff6ab0242c6813eaa0a39b87ea15ab.zip |
[Parser] Update CachedTokens while parsing ObjectiveC template argument list
Consider the following ObjC++ snippet:
--
@protocol PA;
@protocol PB;
@class NSArray<ObjectType>;
typedef int some_t;
id<PA> FA(NSArray<id<PB>> *h, some_t group);
--
This would hit an assertion in the parser after generating an annotation token
while trying to update the token cache:
Assertion failed: (CachedTokens[CachedLexPos-1].getLastLoc() == Tok.getAnnotationEndLoc() && "The annotation should be until the most recent cached token")
...
7 clang::Preprocessor::AnnotatePreviousCachedTokens(clang::Token const&) + 494
8 clang::Parser::TryAnnotateTypeOrScopeTokenAfterScopeSpec(bool, bool, clang::CXXScopeSpec&, bool) + 1163
9 clang::Parser::TryAnnotateTypeOrScopeToken(bool, bool) + 361
10 clang::Parser::isCXXDeclarationSpecifier(clang::Parser::TPResult, bool*) + 598
...
The cached preprocessor token in this case is:
greatergreater '>>' Loc=<testcase.mm:7:24>
while the annotation ("NSArray<id<PB>>") ends at "testcase.mm:7:25", hence the
assertion.
Properly update the CachedTokens during template parsing to contain
two greater tokens instead of a greatergreater.
Differential Revision: http://reviews.llvm.org/D15173
rdar://problem/23494277
llvm-svn: 259311
Diffstat (limited to 'clang/lib/Parse/ParseTemplate.cpp')
-rw-r--r-- | clang/lib/Parse/ParseTemplate.cpp | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index fffc40ee4e1..9e68c4a15d3 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -831,6 +831,7 @@ bool Parser::ParseGreaterThanInTemplateList(SourceLocation &RAngleLoc, } // 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: @@ -847,6 +848,17 @@ bool Parser::ParseGreaterThanInTemplateList(SourceLocation &RAngleLoc, 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 && PP.IsPreviousCachedToken(PrevTok)) { + PrevTok.setKind(RemainingToken); + PrevTok.setLength(1); + Token NewToks[] = {PrevTok, Tok}; + PP.ReplacePreviousCachedToken(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 '>'. |