1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | #include "clang/Lex/Preprocessor.h" |
15 | using namespace clang; |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | void Preprocessor::EnableBacktrackAtThisPos() { |
26 | BacktrackPositions.push_back(CachedLexPos); |
27 | EnterCachingLexMode(); |
28 | } |
29 | |
30 | |
31 | void Preprocessor::CommitBacktrackedTokens() { |
32 | (0) . __assert_fail ("!BacktrackPositions.empty() && \"EnableBacktrackAtThisPos was not called!\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/PPCaching.cpp", 33, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!BacktrackPositions.empty() |
33 | (0) . __assert_fail ("!BacktrackPositions.empty() && \"EnableBacktrackAtThisPos was not called!\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/PPCaching.cpp", 33, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> && "EnableBacktrackAtThisPos was not called!"); |
34 | BacktrackPositions.pop_back(); |
35 | } |
36 | |
37 | Preprocessor::CachedTokensRange Preprocessor::LastCachedTokenRange() { |
38 | assert(isBacktrackEnabled()); |
39 | auto PrevCachedLexPos = BacktrackPositions.back(); |
40 | return CachedTokensRange{PrevCachedLexPos, CachedLexPos}; |
41 | } |
42 | |
43 | void Preprocessor::EraseCachedTokens(CachedTokensRange TokenRange) { |
44 | assert(TokenRange.Begin <= TokenRange.End); |
45 | if (CachedLexPos == TokenRange.Begin && TokenRange.Begin != TokenRange.End) { |
46 | |
47 | |
48 | assert(!CachedTokenRangeToErase); |
49 | CachedTokenRangeToErase = TokenRange; |
50 | return; |
51 | } |
52 | |
53 | assert(TokenRange.End == CachedLexPos); |
54 | CachedTokens.erase(CachedTokens.begin() + TokenRange.Begin, |
55 | CachedTokens.begin() + TokenRange.End); |
56 | CachedLexPos = TokenRange.Begin; |
57 | ExitCachingLexMode(); |
58 | } |
59 | |
60 | |
61 | |
62 | void Preprocessor::Backtrack() { |
63 | (0) . __assert_fail ("!BacktrackPositions.empty() && \"EnableBacktrackAtThisPos was not called!\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/PPCaching.cpp", 64, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!BacktrackPositions.empty() |
64 | (0) . __assert_fail ("!BacktrackPositions.empty() && \"EnableBacktrackAtThisPos was not called!\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/PPCaching.cpp", 64, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> && "EnableBacktrackAtThisPos was not called!"); |
65 | CachedLexPos = BacktrackPositions.back(); |
66 | BacktrackPositions.pop_back(); |
67 | recomputeCurLexerKind(); |
68 | } |
69 | |
70 | void Preprocessor::CachingLex(Token &Result) { |
71 | if (!InCachingLexMode()) |
72 | return; |
73 | |
74 | if (CachedLexPos < CachedTokens.size()) { |
75 | Result = CachedTokens[CachedLexPos++]; |
76 | |
77 | |
78 | if (CachedTokenRangeToErase && |
79 | CachedTokenRangeToErase->End == CachedLexPos) { |
80 | EraseCachedTokens(*CachedTokenRangeToErase); |
81 | CachedTokenRangeToErase = None; |
82 | } |
83 | return; |
84 | } |
85 | |
86 | ExitCachingLexMode(); |
87 | Lex(Result); |
88 | |
89 | if (isBacktrackEnabled()) { |
90 | |
91 | EnterCachingLexMode(); |
92 | CachedTokens.push_back(Result); |
93 | ++CachedLexPos; |
94 | return; |
95 | } |
96 | |
97 | if (CachedLexPos < CachedTokens.size()) { |
98 | EnterCachingLexMode(); |
99 | } else { |
100 | |
101 | CachedTokens.clear(); |
102 | CachedLexPos = 0; |
103 | } |
104 | } |
105 | |
106 | void Preprocessor::EnterCachingLexMode() { |
107 | if (InCachingLexMode()) { |
108 | (0) . __assert_fail ("CurLexerKind == CLK_CachingLexer && \"Unexpected lexer kind\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/PPCaching.cpp", 108, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(CurLexerKind == CLK_CachingLexer && "Unexpected lexer kind"); |
109 | return; |
110 | } |
111 | |
112 | PushIncludeMacroStack(); |
113 | CurLexerKind = CLK_CachingLexer; |
114 | } |
115 | |
116 | |
117 | const Token &Preprocessor::PeekAhead(unsigned N) { |
118 | (0) . __assert_fail ("CachedLexPos + N > CachedTokens.size() && \"Confused caching.\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/PPCaching.cpp", 118, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(CachedLexPos + N > CachedTokens.size() && "Confused caching."); |
119 | ExitCachingLexMode(); |
120 | for (size_t C = CachedLexPos + N - CachedTokens.size(); C > 0; --C) { |
121 | CachedTokens.push_back(Token()); |
122 | Lex(CachedTokens.back()); |
123 | } |
124 | EnterCachingLexMode(); |
125 | return CachedTokens.back(); |
126 | } |
127 | |
128 | void Preprocessor::AnnotatePreviousCachedTokens(const Token &Tok) { |
129 | (0) . __assert_fail ("Tok.isAnnotation() && \"Expected annotation token\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/PPCaching.cpp", 129, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Tok.isAnnotation() && "Expected annotation token"); |
130 | (0) . __assert_fail ("CachedLexPos != 0 && \"Expected to have some cached tokens\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/PPCaching.cpp", 130, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(CachedLexPos != 0 && "Expected to have some cached tokens"); |
131 | (0) . __assert_fail ("CachedTokens[CachedLexPos-1].getLastLoc() == Tok.getAnnotationEndLoc() && \"The annotation should be until the most recent cached token\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/PPCaching.cpp", 132, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(CachedTokens[CachedLexPos-1].getLastLoc() == Tok.getAnnotationEndLoc() |
132 | (0) . __assert_fail ("CachedTokens[CachedLexPos-1].getLastLoc() == Tok.getAnnotationEndLoc() && \"The annotation should be until the most recent cached token\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/PPCaching.cpp", 132, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> && "The annotation should be until the most recent cached token"); |
133 | |
134 | |
135 | |
136 | for (CachedTokensTy::size_type i = CachedLexPos; i != 0; --i) { |
137 | CachedTokensTy::iterator AnnotBegin = CachedTokens.begin() + i-1; |
138 | if (AnnotBegin->getLocation() == Tok.getLocation()) { |
139 | (0) . __assert_fail ("(BacktrackPositions.empty() || BacktrackPositions.back() <= i) && \"The backtrack pos points inside the annotated tokens!\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/PPCaching.cpp", 140, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((BacktrackPositions.empty() || BacktrackPositions.back() <= i) && |
140 | (0) . __assert_fail ("(BacktrackPositions.empty() || BacktrackPositions.back() <= i) && \"The backtrack pos points inside the annotated tokens!\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/PPCaching.cpp", 140, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "The backtrack pos points inside the annotated tokens!"); |
141 | |
142 | if (i < CachedLexPos) |
143 | CachedTokens.erase(AnnotBegin + 1, CachedTokens.begin() + CachedLexPos); |
144 | *AnnotBegin = Tok; |
145 | CachedLexPos = i; |
146 | return; |
147 | } |
148 | } |
149 | } |
150 | |
151 | bool Preprocessor::IsPreviousCachedToken(const Token &Tok) const { |
152 | |
153 | if (!CachedLexPos) |
154 | return false; |
155 | |
156 | const Token LastCachedTok = CachedTokens[CachedLexPos - 1]; |
157 | if (LastCachedTok.getKind() != Tok.getKind()) |
158 | return false; |
159 | |
160 | int RelOffset = 0; |
161 | if ((!getSourceManager().isInSameSLocAddrSpace( |
162 | Tok.getLocation(), getLastCachedTokenLocation(), &RelOffset)) || |
163 | RelOffset) |
164 | return false; |
165 | |
166 | return true; |
167 | } |
168 | |
169 | void Preprocessor::ReplacePreviousCachedToken(ArrayRef<Token> NewToks) { |
170 | (0) . __assert_fail ("CachedLexPos != 0 && \"Expected to have some cached tokens\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/PPCaching.cpp", 170, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(CachedLexPos != 0 && "Expected to have some cached tokens"); |
171 | CachedTokens.insert(CachedTokens.begin() + CachedLexPos - 1, NewToks.begin(), |
172 | NewToks.end()); |
173 | CachedTokens.erase(CachedTokens.begin() + CachedLexPos - 1 + NewToks.size()); |
174 | CachedLexPos += NewToks.size() - 1; |
175 | } |
176 | |