clang: lib/Lex/TokenConcatenation.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
16#include "llvm/Support/ErrorHandling.h"
17using namespace clang;
18
19
20
21
23
24 if (Str[0] == 'L' ||
25 (CPlusPlus11 && (Str[0] == 'u' || Str[0] == 'U' || Str[0] == 'R'))) {
26
27 if (Str.size() == 1)
28 return true;
29
30
31
32 if (Str[1] == 'R' && Str[0] != 'R' && Str.size() == 2 && CPlusPlus11)
33 return true;
34
35
36 if (Str[0] == 'u' && Str[1] == '8') {
37 if (Str.size() == 2) return true;
38 if (Str.size() == 3 && Str[2] == 'R') return true;
39 }
40 }
41
42 return false;
43}
44
45
46
47bool TokenConcatenation::IsIdentifierStringPrefix(const Token &Tok) const {
49
52 return false;
54 const char *Ptr = SM.getCharacterData(SM.getSpellingLoc(Tok.getLocation()));
56 LangOpts.CPlusPlus11);
57 }
58
60 char Buffer[256];
61 const char *TokPtr = Buffer;
64 }
65
67}
68
70 memset(TokenInfo, 0, sizeof(TokenInfo));
71
72
73 TokenInfo[tok::identifier ] |= aci_custom;
74 TokenInfo[tok::numeric_constant] |= aci_custom_firstchar;
75 TokenInfo[tok::period ] |= aci_custom_firstchar;
76 TokenInfo[tok::amp ] |= aci_custom_firstchar;
77 TokenInfo[tok::plus ] |= aci_custom_firstchar;
78 TokenInfo[tok::minus ] |= aci_custom_firstchar;
79 TokenInfo[tok::slash ] |= aci_custom_firstchar;
80 TokenInfo[tok::less ] |= aci_custom_firstchar;
81 TokenInfo[tok::greater ] |= aci_custom_firstchar;
82 TokenInfo[tok::pipe ] |= aci_custom_firstchar;
83 TokenInfo[tok::percent ] |= aci_custom_firstchar;
84 TokenInfo[tok::colon ] |= aci_custom_firstchar;
85 TokenInfo[tok::hash ] |= aci_custom_firstchar;
86 TokenInfo[tok::arrow ] |= aci_custom_firstchar;
87
88
90 TokenInfo[tok::string_literal ] |= aci_custom;
91 TokenInfo[tok::wide_string_literal ] |= aci_custom;
92 TokenInfo[tok::utf8_string_literal ] |= aci_custom;
93 TokenInfo[tok::utf16_string_literal] |= aci_custom;
94 TokenInfo[tok::utf32_string_literal] |= aci_custom;
95 TokenInfo[tok::char_constant ] |= aci_custom;
96 TokenInfo[tok::wide_char_constant ] |= aci_custom;
97 TokenInfo[tok::utf16_char_constant ] |= aci_custom;
98 TokenInfo[tok::utf32_char_constant ] |= aci_custom;
99 }
100
101
103 TokenInfo[tok::utf8_char_constant] |= aci_custom;
104
105
107 TokenInfo[tok::lessequal ] |= aci_custom_firstchar;
108
109
110 TokenInfo[tok::amp ] |= aci_avoid_equal;
111 TokenInfo[tok::plus ] |= aci_avoid_equal;
112 TokenInfo[tok::minus ] |= aci_avoid_equal;
113 TokenInfo[tok::slash ] |= aci_avoid_equal;
114 TokenInfo[tok::less ] |= aci_avoid_equal;
115 TokenInfo[tok::greater ] |= aci_avoid_equal;
116 TokenInfo[tok::pipe ] |= aci_avoid_equal;
117 TokenInfo[tok::percent ] |= aci_avoid_equal;
118 TokenInfo[tok::star ] |= aci_avoid_equal;
119 TokenInfo[tok::exclaim ] |= aci_avoid_equal;
120 TokenInfo[tok::lessless ] |= aci_avoid_equal;
121 TokenInfo[tok::greatergreater] |= aci_avoid_equal;
122 TokenInfo[tok::caret ] |= aci_avoid_equal;
123 TokenInfo[tok::equal ] |= aci_avoid_equal;
124}
125
126
127
130
131 return II->getNameStart()[0];
135 } else {
137 return *SM.getCharacterData(SM.getSpellingLoc(Tok.getLocation()));
138 }
139 } else if (Tok.getLength() < 256) {
140 char Buffer[256];
141 const char *TokPtr = Buffer;
143 return TokPtr[0];
144 } else {
146 }
147}
148
149
150
151
152
153
154
155
156
157
158
159
161 const Token &PrevTok,
162 const Token &Tok) const {
163
164 if (PrevTok.is(tok::annot_header_unit) && Tok.is(tok::semi))
165 return false;
166
167
168
170 return true;
171
172
173
174
179 return false;
180
183 PrevKind = tok::identifier;
184
185
186 unsigned ConcatInfo = TokenInfo[PrevKind];
187
188
189 if (ConcatInfo == 0) return false;
190
191 if (ConcatInfo & aci_avoid_equal) {
192
193 if (Tok.isOneOf(tok::equal, tok::equalequal))
194 return true;
195 ConcatInfo &= ~aci_avoid_equal;
196 }
198
199 assert(Tok.isOneOf(tok::annot_module_include, tok::annot_module_begin,
200 tok::annot_module_end, tok::annot_embed) &&
201 "unexpected annotation in AvoidConcat");
202
203 ConcatInfo = 0;
204 if (Tok.is(tok::annot_embed))
205 return true;
206 }
207
208 if (ConcatInfo == 0)
209 return false;
210
211
212
213
214 char FirstChar = 0;
215 if (ConcatInfo & aci_custom) {
216
217 } else {
219 }
220
221 switch (PrevKind) {
222 default:
223 llvm_unreachable("InitAvoidConcatTokenInfo built wrong");
224
225 case tok::raw_identifier:
226 llvm_unreachable("tok::raw_identifier in non-raw lexing mode!");
227
228 case tok::string_literal:
229 case tok::wide_string_literal:
230 case tok::utf8_string_literal:
231 case tok::utf16_string_literal:
232 case tok::utf32_string_literal:
233 case tok::char_constant:
234 case tok::wide_char_constant:
235 case tok::utf8_char_constant:
236 case tok::utf16_char_constant:
237 case tok::utf32_char_constant:
239 return false;
240
241
242
244 return true;
245
246
247
249 return false;
250 [[fallthrough]];
251 case tok::identifier:
252
253 if (Tok.is(tok::numeric_constant))
255
257 Tok.isOneOf(tok::wide_string_literal, tok::utf8_string_literal,
258 tok::utf16_string_literal, tok::utf32_string_literal,
259 tok::wide_char_constant, tok::utf8_char_constant,
260 tok::utf16_char_constant, tok::utf32_char_constant))
261 return true;
262
263
264 if (Tok.isNot(tok::char_constant) && Tok.isNot(tok::string_literal))
265 return false;
266
267
268
269 return IsIdentifierStringPrefix(PrevTok);
270
271 case tok::numeric_constant:
273 FirstChar == '+' || FirstChar == '-';
274 case tok::period:
275 return (FirstChar == '.' && PrevPrevTok.is(tok::period)) ||
277 (PP.getLangOpts().CPlusPlus && FirstChar == '*');
278 case tok::amp:
279 return FirstChar == '&';
280 case tok:➕
281 return FirstChar == '+';
282 case tok:➖
283 return FirstChar == '-' || FirstChar == '>';
284 case tok::slash:
285 return FirstChar == '*' || FirstChar == '/';
286 case tok::less:
287 return FirstChar == '<' || FirstChar == ':' || FirstChar == '%';
288 case tok::greater:
289 return FirstChar == '>';
290 case tok::pipe:
291 return FirstChar == '|';
292 case tok::percent:
293 return FirstChar == '>' || FirstChar == ':';
294 case tok::colon:
295 return FirstChar == '>' ||
296 (PP.getLangOpts().CPlusPlus && FirstChar == ':');
297 case tok::hash:
298 return FirstChar == '#' || FirstChar == '@' || FirstChar == '%';
299 case tok::arrow:
300 return PP.getLangOpts().CPlusPlus && FirstChar == '*';
301 case tok::lessequal:
302 return PP.getLangOpts().CPlusPlus20 && FirstChar == '>';
303 }
304}
Defines the clang::Preprocessor interface.
static char GetFirstChar(const Preprocessor &PP, const Token &Tok)
GetFirstChar - Get the first character of the token.
static bool IsStringPrefix(StringRef Str, bool CPlusPlus11)
IsStringPrefix - Return true if Str is a string prefix.
__DEVICE__ void * memset(void *__a, int __b, size_t __c)
One of these records is kept for each identifier that is lexed.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
SourceManager & getSourceManager() const
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
const LangOptions & getLangOpts() const
Encodes a location in the source.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
TokenConcatenation(const Preprocessor &PP)
bool AvoidConcat(const Token &PrevPrevTok, const Token &PrevTok, const Token &Tok) const
AvoidConcat - If printing PrevTok immediately followed by Tok would cause the two individual tokens t...
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
bool isLiteral() const
Return true if this is a "literal", like a numeric constant, string, etc.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
unsigned getLength() const
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
tok::TokenKind getKind() const
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
bool isNot(tok::TokenKind K) const
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix.
bool needsCleaning() const
Return true if this token has trigraphs or escaped newlines in it.
const char * getLiteralData() const
getLiteralData - For a literal token (numeric constant, string, etc), this returns a pointer to the s...
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
The JSON file list parser is used to communicate input to InstallAPI.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
LLVM_READONLY bool isPreprocessingNumberBody(unsigned char c)
Return true if this is the body character of a C preprocessing number, which is [a-zA-Z0-9_.
float __ovld __cnfn length(float)
Return the length of vector p, i.e., sqrt(p.x2 + p.y 2 + ...)