1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | #ifndef LLVM_CLANG_LEX_TOKEN_H |
14 | #define LLVM_CLANG_LEX_TOKEN_H |
15 | |
16 | #include "clang/Basic/SourceLocation.h" |
17 | #include "clang/Basic/TokenKinds.h" |
18 | #include "llvm/ADT/StringRef.h" |
19 | #include <cassert> |
20 | |
21 | namespace clang { |
22 | |
23 | class IdentifierInfo; |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | class Token { |
35 | |
36 | unsigned Loc; |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | unsigned UintData; |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | void *PtrData; |
63 | |
64 | |
65 | tok::TokenKind Kind; |
66 | |
67 | |
68 | unsigned short Flags; |
69 | |
70 | public: |
71 | |
72 | enum TokenFlags { |
73 | StartOfLine = 0x01, |
74 | |
75 | LeadingSpace = 0x02, |
76 | |
77 | DisableExpand = 0x04, |
78 | NeedsCleaning = 0x08, |
79 | LeadingEmptyMacro = 0x10, |
80 | HasUDSuffix = 0x20, |
81 | HasUCN = 0x40, |
82 | IgnoredComma = 0x80, |
83 | StringifiedInMacro = 0x100, |
84 | |
85 | CommaAfterElided = 0x200, |
86 | IsEditorPlaceholder = 0x400, |
87 | }; |
88 | |
89 | tok::TokenKind getKind() const { return Kind; } |
90 | void setKind(tok::TokenKind K) { Kind = K; } |
91 | |
92 | |
93 | |
94 | bool is(tok::TokenKind K) const { return Kind == K; } |
95 | bool isNot(tok::TokenKind K) const { return Kind != K; } |
96 | bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const { |
97 | return is(K1) || is(K2); |
98 | } |
99 | template <typename... Ts> |
100 | bool isOneOf(tok::TokenKind K1, tok::TokenKind K2, Ts... Ks) const { |
101 | return is(K1) || isOneOf(K2, Ks...); |
102 | } |
103 | |
104 | |
105 | |
106 | bool isAnyIdentifier() const { |
107 | return tok::isAnyIdentifier(getKind()); |
108 | } |
109 | |
110 | |
111 | |
112 | bool isLiteral() const { |
113 | return tok::isLiteral(getKind()); |
114 | } |
115 | |
116 | |
117 | bool isAnnotation() const { |
118 | return tok::isAnnotation(getKind()); |
119 | } |
120 | |
121 | |
122 | |
123 | SourceLocation getLocation() const { |
124 | return SourceLocation::getFromRawEncoding(Loc); |
125 | } |
126 | unsigned getLength() const { |
127 | (0) . __assert_fail ("!isAnnotation() && \"Annotation tokens have no length field\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Lex/Token.h", 127, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(!isAnnotation() && "Annotation tokens have no length field"); |
128 | return UintData; |
129 | } |
130 | |
131 | void setLocation(SourceLocation L) { Loc = L.getRawEncoding(); } |
132 | void setLength(unsigned Len) { |
133 | (0) . __assert_fail ("!isAnnotation() && \"Annotation tokens have no length field\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Lex/Token.h", 133, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(!isAnnotation() && "Annotation tokens have no length field"); |
134 | UintData = Len; |
135 | } |
136 | |
137 | SourceLocation getAnnotationEndLoc() const { |
138 | (0) . __assert_fail ("isAnnotation() && \"Used AnnotEndLocID on non-annotation token\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Lex/Token.h", 138, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token"); |
139 | return SourceLocation::getFromRawEncoding(UintData ? UintData : Loc); |
140 | } |
141 | void setAnnotationEndLoc(SourceLocation L) { |
142 | (0) . __assert_fail ("isAnnotation() && \"Used AnnotEndLocID on non-annotation token\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Lex/Token.h", 142, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token"); |
143 | UintData = L.getRawEncoding(); |
144 | } |
145 | |
146 | SourceLocation getLastLoc() const { |
147 | return isAnnotation() ? getAnnotationEndLoc() : getLocation(); |
148 | } |
149 | |
150 | SourceLocation getEndLoc() const { |
151 | return isAnnotation() ? getAnnotationEndLoc() |
152 | : getLocation().getLocWithOffset(getLength()); |
153 | } |
154 | |
155 | |
156 | |
157 | SourceRange getAnnotationRange() const { |
158 | return SourceRange(getLocation(), getAnnotationEndLoc()); |
159 | } |
160 | void setAnnotationRange(SourceRange R) { |
161 | setLocation(R.getBegin()); |
162 | setAnnotationEndLoc(R.getEnd()); |
163 | } |
164 | |
165 | const char *getName() const { return tok::getTokenName(Kind); } |
166 | |
167 | |
168 | void startToken() { |
169 | Kind = tok::unknown; |
170 | Flags = 0; |
171 | PtrData = nullptr; |
172 | UintData = 0; |
173 | Loc = SourceLocation().getRawEncoding(); |
174 | } |
175 | |
176 | IdentifierInfo *getIdentifierInfo() const { |
177 | (0) . __assert_fail ("isNot(tok..raw_identifier) && \"getIdentifierInfo() on a tok..raw_identifier token!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Lex/Token.h", 178, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(isNot(tok::raw_identifier) && |
178 | (0) . __assert_fail ("isNot(tok..raw_identifier) && \"getIdentifierInfo() on a tok..raw_identifier token!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Lex/Token.h", 178, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true"> "getIdentifierInfo() on a tok::raw_identifier token!"); |
179 | (0) . __assert_fail ("!isAnnotation() && \"getIdentifierInfo() on an annotation token!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Lex/Token.h", 180, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(!isAnnotation() && |
180 | (0) . __assert_fail ("!isAnnotation() && \"getIdentifierInfo() on an annotation token!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Lex/Token.h", 180, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true"> "getIdentifierInfo() on an annotation token!"); |
181 | if (isLiteral()) return nullptr; |
182 | if (is(tok::eof)) return nullptr; |
183 | return (IdentifierInfo*) PtrData; |
184 | } |
185 | void setIdentifierInfo(IdentifierInfo *II) { |
186 | PtrData = (void*) II; |
187 | } |
188 | |
189 | const void *getEofData() const { |
190 | assert(is(tok::eof)); |
191 | return reinterpret_cast<const void *>(PtrData); |
192 | } |
193 | void setEofData(const void *D) { |
194 | assert(is(tok::eof)); |
195 | assert(!PtrData); |
196 | PtrData = const_cast<void *>(D); |
197 | } |
198 | |
199 | |
200 | |
201 | |
202 | StringRef getRawIdentifier() const { |
203 | assert(is(tok::raw_identifier)); |
204 | return StringRef(reinterpret_cast<const char *>(PtrData), getLength()); |
205 | } |
206 | void setRawIdentifierData(const char *Ptr) { |
207 | assert(is(tok::raw_identifier)); |
208 | PtrData = const_cast<char*>(Ptr); |
209 | } |
210 | |
211 | |
212 | |
213 | |
214 | const char *getLiteralData() const { |
215 | (0) . __assert_fail ("isLiteral() && \"Cannot get literal data of non-literal\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Lex/Token.h", 215, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(isLiteral() && "Cannot get literal data of non-literal"); |
216 | return reinterpret_cast<const char*>(PtrData); |
217 | } |
218 | void setLiteralData(const char *Ptr) { |
219 | (0) . __assert_fail ("isLiteral() && \"Cannot set literal data of non-literal\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Lex/Token.h", 219, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(isLiteral() && "Cannot set literal data of non-literal"); |
220 | PtrData = const_cast<char*>(Ptr); |
221 | } |
222 | |
223 | void *getAnnotationValue() const { |
224 | (0) . __assert_fail ("isAnnotation() && \"Used AnnotVal on non-annotation token\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Lex/Token.h", 224, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(isAnnotation() && "Used AnnotVal on non-annotation token"); |
225 | return PtrData; |
226 | } |
227 | void setAnnotationValue(void *val) { |
228 | (0) . __assert_fail ("isAnnotation() && \"Used AnnotVal on non-annotation token\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Lex/Token.h", 228, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(isAnnotation() && "Used AnnotVal on non-annotation token"); |
229 | PtrData = val; |
230 | } |
231 | |
232 | |
233 | void setFlag(TokenFlags Flag) { |
234 | Flags |= Flag; |
235 | } |
236 | |
237 | |
238 | bool getFlag(TokenFlags Flag) const { |
239 | return (Flags & Flag) != 0; |
240 | } |
241 | |
242 | |
243 | void clearFlag(TokenFlags Flag) { |
244 | Flags &= ~Flag; |
245 | } |
246 | |
247 | |
248 | |
249 | |
250 | |
251 | unsigned getFlags() const { |
252 | return Flags; |
253 | } |
254 | |
255 | |
256 | void setFlagValue(TokenFlags Flag, bool Val) { |
257 | if (Val) |
258 | setFlag(Flag); |
259 | else |
260 | clearFlag(Flag); |
261 | } |
262 | |
263 | |
264 | |
265 | bool isAtStartOfLine() const { return getFlag(StartOfLine); } |
266 | |
267 | |
268 | |
269 | bool hasLeadingSpace() const { return getFlag(LeadingSpace); } |
270 | |
271 | |
272 | |
273 | bool isExpandDisabled() const { return getFlag(DisableExpand); } |
274 | |
275 | |
276 | bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const; |
277 | |
278 | |
279 | tok::ObjCKeywordKind getObjCKeywordID() const; |
280 | |
281 | |
282 | bool needsCleaning() const { return getFlag(NeedsCleaning); } |
283 | |
284 | |
285 | |
286 | bool hasLeadingEmptyMacro() const { return getFlag(LeadingEmptyMacro); } |
287 | |
288 | |
289 | |
290 | bool hasUDSuffix() const { return getFlag(HasUDSuffix); } |
291 | |
292 | |
293 | bool hasUCN() const { return getFlag(HasUCN); } |
294 | |
295 | |
296 | |
297 | bool stringifiedInMacro() const { return getFlag(StringifiedInMacro); } |
298 | |
299 | |
300 | bool commaAfterElided() const { return getFlag(CommaAfterElided); } |
301 | |
302 | |
303 | |
304 | |
305 | |
306 | |
307 | bool isEditorPlaceholder() const { return getFlag(IsEditorPlaceholder); } |
308 | }; |
309 | |
310 | |
311 | |
312 | struct PPConditionalInfo { |
313 | |
314 | SourceLocation IfLoc; |
315 | |
316 | |
317 | |
318 | bool WasSkipping; |
319 | |
320 | |
321 | |
322 | bool FoundNonSkip; |
323 | |
324 | |
325 | |
326 | bool FoundElse; |
327 | }; |
328 | |
329 | } |
330 | |
331 | #endif |
332 | |