summaryrefslogtreecommitdiffstats
path: root/clang/lib/Lex
diff options
context:
space:
mode:
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>2016-01-31 00:47:51 +0000
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>2016-01-31 00:47:51 +0000
commit428a5aa9a5ff6ab0242c6813eaa0a39b87ea15ab (patch)
treebdafcb4b709e0bb05cb89a8eae7a17083a1e9a8e /clang/lib/Lex
parent054b391cf479b7bfda27c82b856a823d5b81aac6 (diff)
downloadbcm5719-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/Lex')
-rw-r--r--clang/lib/Lex/PPCaching.cpp26
1 files changed, 26 insertions, 0 deletions
diff --git a/clang/lib/Lex/PPCaching.cpp b/clang/lib/Lex/PPCaching.cpp
index bd48ae64ab4..4742aae5c12 100644
--- a/clang/lib/Lex/PPCaching.cpp
+++ b/clang/lib/Lex/PPCaching.cpp
@@ -116,3 +116,29 @@ void Preprocessor::AnnotatePreviousCachedTokens(const Token &Tok) {
}
}
}
+
+bool Preprocessor::IsPreviousCachedToken(const Token &Tok) const {
+ // There's currently no cached token...
+ if (!CachedLexPos)
+ return false;
+
+ const Token LastCachedTok = CachedTokens[CachedLexPos - 1];
+ if (LastCachedTok.getKind() != Tok.getKind())
+ return false;
+
+ int RelOffset = 0;
+ if ((!getSourceManager().isInSameSLocAddrSpace(
+ Tok.getLocation(), getLastCachedTokenLocation(), &RelOffset)) ||
+ RelOffset)
+ return false;
+
+ return true;
+}
+
+void Preprocessor::ReplacePreviousCachedToken(ArrayRef<Token> NewToks) {
+ assert(CachedLexPos != 0 && "Expected to have some cached tokens");
+ CachedTokens.insert(CachedTokens.begin() + CachedLexPos - 1, NewToks.begin(),
+ NewToks.end());
+ CachedTokens.erase(CachedTokens.begin() + CachedLexPos - 1 + NewToks.size());
+ CachedLexPos += NewToks.size() - 1;
+}
OpenPOWER on IntegriCloud