summaryrefslogtreecommitdiffstats
path: root/include/clang/Lex/Preprocessor.h
diff options
context:
space:
mode:
authorAlex Lorenz <arphaman@gmail.com>2017-02-24 17:45:16 +0000
committerAlex Lorenz <arphaman@gmail.com>2017-02-24 17:45:16 +0000
commitb35cf4128a9e78994ff33b963728456db9471d3a (patch)
tree9549dae07cdf20dc22df7bf0c2090328bd081188 /include/clang/Lex/Preprocessor.h
parent2f3361cb8512d876a3599b8109ba0c262a47c94f (diff)
[Preprocessor] Fix incorrect token caching that occurs when lexing _Pragma
in macro argument pre-expansion mode when skipping a function body This commit fixes a token caching problem that currently occurs when clang is skipping a function body (e.g. when looking for a code completion token) and at the same time caching the tokens for _Pragma when lexing it in macro argument pre-expansion mode. When _Pragma is being lexed in macro argument pre-expansion mode, it caches the tokens so that it can avoid interpreting the pragma immediately (as the macro argument may not be used in the macro body), and then either backtracks over or commits these tokens. The problem is that, when we're backtracking/committing in such a scenario, there's already a previous backtracking position stored in BacktrackPositions (as we're skipping the function body), and this leads to a situation where the cached tokens from the pragma (like '(' 'string_literal' and ')') will remain in the cached tokens array incorrectly even after they're consumed (in the case of backtracking) or just ignored (in the case when they're committed). Furthermore, what makes it even worse, is that because of a previous backtracking position, the logic that deals with when should we call ExitCachingLexMode in CachingLex no longer works for us in this situation, and more tokens in the macro argument get cached, to the point where the EOF token that corresponds to the macro argument EOF is cached. This problem leads to all sorts of issues in code completion mode, where incorrect errors get presented and code completion completely fails to produce completion results. rdar://28523863 Differential Revision: https://reviews.llvm.org/D28772 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@296140 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/Lex/Preprocessor.h')
-rw-r--r--include/clang/Lex/Preprocessor.h18
1 files changed, 18 insertions, 0 deletions
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 7ce1aad36d..26efa8b8a1 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -1077,6 +1077,24 @@ public:
/// \brief Disable the last EnableBacktrackAtThisPos call.
void CommitBacktrackedTokens();
+ struct CachedTokensRange {
+ CachedTokensTy::size_type Begin, End;
+ };
+
+private:
+ /// \brief A range of cached tokens that should be erased after lexing
+ /// when backtracking requires the erasure of such cached tokens.
+ Optional<CachedTokensRange> CachedTokenRangeToErase;
+
+public:
+ /// \brief Returns the range of cached tokens that were lexed since
+ /// EnableBacktrackAtThisPos() was previously called.
+ CachedTokensRange LastCachedTokenRange();
+
+ /// \brief Erase the range of cached tokens that were lexed since
+ /// EnableBacktrackAtThisPos() was previously called.
+ void EraseCachedTokens(CachedTokensRange TokenRange);
+
/// \brief Make Preprocessor re-lex the tokens that were lexed since
/// EnableBacktrackAtThisPos() was previously called.
void Backtrack();