Bug Summary

File:clang/lib/Lex/Pragma.cpp
Warning:line 1183, column 7
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Pragma.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/build-llvm -resource-dir /usr/lib/llvm-14/lib/clang/14.0.0 -D CLANG_ROUND_TRIP_CC1_ARGS=ON -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I tools/clang/lib/Lex -I /build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex -I /build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include -I tools/clang/include -I include -I /build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/llvm/include -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-command-line-argument -Wno-unknown-warning-option -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/build-llvm -ferror-limit 19 -fvisibility-inlines-hidden -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2021-11-10-160236-22541-1 -x c++ /build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp

/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp

1//===- Pragma.cpp - Pragma registration and handling ----------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the PragmaHandler/PragmaTable interfaces and implements
10// pragma related methods of the Preprocessor class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Lex/Pragma.h"
15#include "clang/Basic/CLWarnings.h"
16#include "clang/Basic/Diagnostic.h"
17#include "clang/Basic/DiagnosticLex.h"
18#include "clang/Basic/FileManager.h"
19#include "clang/Basic/IdentifierTable.h"
20#include "clang/Basic/LLVM.h"
21#include "clang/Basic/LangOptions.h"
22#include "clang/Basic/Module.h"
23#include "clang/Basic/SourceLocation.h"
24#include "clang/Basic/SourceManager.h"
25#include "clang/Basic/TokenKinds.h"
26#include "clang/Lex/HeaderSearch.h"
27#include "clang/Lex/LexDiagnostic.h"
28#include "clang/Lex/Lexer.h"
29#include "clang/Lex/LiteralSupport.h"
30#include "clang/Lex/MacroInfo.h"
31#include "clang/Lex/ModuleLoader.h"
32#include "clang/Lex/PPCallbacks.h"
33#include "clang/Lex/Preprocessor.h"
34#include "clang/Lex/PreprocessorLexer.h"
35#include "clang/Lex/PreprocessorOptions.h"
36#include "clang/Lex/Token.h"
37#include "clang/Lex/TokenLexer.h"
38#include "llvm/ADT/ArrayRef.h"
39#include "llvm/ADT/DenseMap.h"
40#include "llvm/ADT/Optional.h"
41#include "llvm/ADT/STLExtras.h"
42#include "llvm/ADT/SmallString.h"
43#include "llvm/ADT/SmallVector.h"
44#include "llvm/ADT/StringRef.h"
45#include "llvm/ADT/StringSwitch.h"
46#include "llvm/Support/Compiler.h"
47#include "llvm/Support/ErrorHandling.h"
48#include "llvm/Support/Timer.h"
49#include <algorithm>
50#include <cassert>
51#include <cstddef>
52#include <cstdint>
53#include <limits>
54#include <string>
55#include <utility>
56#include <vector>
57
58using namespace clang;
59
60// Out-of-line destructor to provide a home for the class.
61PragmaHandler::~PragmaHandler() = default;
62
63//===----------------------------------------------------------------------===//
64// EmptyPragmaHandler Implementation.
65//===----------------------------------------------------------------------===//
66
67EmptyPragmaHandler::EmptyPragmaHandler(StringRef Name) : PragmaHandler(Name) {}
68
69void EmptyPragmaHandler::HandlePragma(Preprocessor &PP,
70 PragmaIntroducer Introducer,
71 Token &FirstToken) {}
72
73//===----------------------------------------------------------------------===//
74// PragmaNamespace Implementation.
75//===----------------------------------------------------------------------===//
76
77/// FindHandler - Check to see if there is already a handler for the
78/// specified name. If not, return the handler for the null identifier if it
79/// exists, otherwise return null. If IgnoreNull is true (the default) then
80/// the null handler isn't returned on failure to match.
81PragmaHandler *PragmaNamespace::FindHandler(StringRef Name,
82 bool IgnoreNull) const {
83 auto I = Handlers.find(Name);
84 if (I != Handlers.end())
85 return I->getValue().get();
86 if (IgnoreNull)
87 return nullptr;
88 I = Handlers.find(StringRef());
89 if (I != Handlers.end())
90 return I->getValue().get();
91 return nullptr;
92}
93
94void PragmaNamespace::AddPragma(PragmaHandler *Handler) {
95 assert(!Handlers.count(Handler->getName()) &&(static_cast <bool> (!Handlers.count(Handler->getName
()) && "A handler with this name is already registered in this namespace"
) ? void (0) : __assert_fail ("!Handlers.count(Handler->getName()) && \"A handler with this name is already registered in this namespace\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 96, __extension__ __PRETTY_FUNCTION__))
96 "A handler with this name is already registered in this namespace")(static_cast <bool> (!Handlers.count(Handler->getName
()) && "A handler with this name is already registered in this namespace"
) ? void (0) : __assert_fail ("!Handlers.count(Handler->getName()) && \"A handler with this name is already registered in this namespace\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 96, __extension__ __PRETTY_FUNCTION__))
;
97 Handlers[Handler->getName()].reset(Handler);
98}
99
100void PragmaNamespace::RemovePragmaHandler(PragmaHandler *Handler) {
101 auto I = Handlers.find(Handler->getName());
102 assert(I != Handlers.end() &&(static_cast <bool> (I != Handlers.end() && "Handler not registered in this namespace"
) ? void (0) : __assert_fail ("I != Handlers.end() && \"Handler not registered in this namespace\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 103, __extension__ __PRETTY_FUNCTION__))
103 "Handler not registered in this namespace")(static_cast <bool> (I != Handlers.end() && "Handler not registered in this namespace"
) ? void (0) : __assert_fail ("I != Handlers.end() && \"Handler not registered in this namespace\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 103, __extension__ __PRETTY_FUNCTION__))
;
104 // Release ownership back to the caller.
105 I->getValue().release();
106 Handlers.erase(I);
107}
108
109void PragmaNamespace::HandlePragma(Preprocessor &PP,
110 PragmaIntroducer Introducer, Token &Tok) {
111 // Read the 'namespace' that the directive is in, e.g. STDC. Do not macro
112 // expand it, the user can have a STDC #define, that should not affect this.
113 PP.LexUnexpandedToken(Tok);
114
115 // Get the handler for this token. If there is no handler, ignore the pragma.
116 PragmaHandler *Handler
117 = FindHandler(Tok.getIdentifierInfo() ? Tok.getIdentifierInfo()->getName()
118 : StringRef(),
119 /*IgnoreNull=*/false);
120 if (!Handler) {
121 PP.Diag(Tok, diag::warn_pragma_ignored);
122 return;
123 }
124
125 // Otherwise, pass it down.
126 Handler->HandlePragma(PP, Introducer, Tok);
127}
128
129//===----------------------------------------------------------------------===//
130// Preprocessor Pragma Directive Handling.
131//===----------------------------------------------------------------------===//
132
133namespace {
134// TokenCollector provides the option to collect tokens that were "read"
135// and return them to the stream to be read later.
136// Currently used when reading _Pragma/__pragma directives.
137struct TokenCollector {
138 Preprocessor &Self;
139 bool Collect;
140 SmallVector<Token, 3> Tokens;
141 Token &Tok;
142
143 void lex() {
144 if (Collect)
145 Tokens.push_back(Tok);
146 Self.Lex(Tok);
147 }
148
149 void revert() {
150 assert(Collect && "did not collect tokens")(static_cast <bool> (Collect && "did not collect tokens"
) ? void (0) : __assert_fail ("Collect && \"did not collect tokens\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 150, __extension__ __PRETTY_FUNCTION__))
;
151 assert(!Tokens.empty() && "collected unexpected number of tokens")(static_cast <bool> (!Tokens.empty() && "collected unexpected number of tokens"
) ? void (0) : __assert_fail ("!Tokens.empty() && \"collected unexpected number of tokens\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 151, __extension__ __PRETTY_FUNCTION__))
;
152
153 // Push the ( "string" ) tokens into the token stream.
154 auto Toks = std::make_unique<Token[]>(Tokens.size());
155 std::copy(Tokens.begin() + 1, Tokens.end(), Toks.get());
156 Toks[Tokens.size() - 1] = Tok;
157 Self.EnterTokenStream(std::move(Toks), Tokens.size(),
158 /*DisableMacroExpansion*/ true,
159 /*IsReinject*/ true);
160
161 // ... and return the pragma token unchanged.
162 Tok = *Tokens.begin();
163 }
164};
165} // namespace
166
167/// HandlePragmaDirective - The "\#pragma" directive has been parsed. Lex the
168/// rest of the pragma, passing it to the registered pragma handlers.
169void Preprocessor::HandlePragmaDirective(PragmaIntroducer Introducer) {
170 if (Callbacks)
171 Callbacks->PragmaDirective(Introducer.Loc, Introducer.Kind);
172
173 if (!PragmasEnabled)
174 return;
175
176 ++NumPragma;
177
178 // Invoke the first level of pragma handlers which reads the namespace id.
179 Token Tok;
180 PragmaHandlers->HandlePragma(*this, Introducer, Tok);
181
182 // If the pragma handler didn't read the rest of the line, consume it now.
183 if ((CurTokenLexer && CurTokenLexer->isParsingPreprocessorDirective())
184 || (CurPPLexer && CurPPLexer->ParsingPreprocessorDirective))
185 DiscardUntilEndOfDirective();
186}
187
188/// Handle_Pragma - Read a _Pragma directive, slice it up, process it, then
189/// return the first token after the directive. The _Pragma token has just
190/// been read into 'Tok'.
191void Preprocessor::Handle_Pragma(Token &Tok) {
192 // C11 6.10.3.4/3:
193 // all pragma unary operator expressions within [a completely
194 // macro-replaced preprocessing token sequence] are [...] processed [after
195 // rescanning is complete]
196 //
197 // This means that we execute _Pragma operators in two cases:
198 //
199 // 1) on token sequences that would otherwise be produced as the output of
200 // phase 4 of preprocessing, and
201 // 2) on token sequences formed as the macro-replaced token sequence of a
202 // macro argument
203 //
204 // Case #2 appears to be a wording bug: only _Pragmas that would survive to
205 // the end of phase 4 should actually be executed. Discussion on the WG14
206 // mailing list suggests that a _Pragma operator is notionally checked early,
207 // but only pragmas that survive to the end of phase 4 should be executed.
208 //
209 // In Case #2, we check the syntax now, but then put the tokens back into the
210 // token stream for later consumption.
211
212 TokenCollector Toks = {*this, InMacroArgPreExpansion, {}, Tok};
213
214 // Remember the pragma token location.
215 SourceLocation PragmaLoc = Tok.getLocation();
216
217 // Read the '('.
218 Toks.lex();
219 if (Tok.isNot(tok::l_paren)) {
220 Diag(PragmaLoc, diag::err__Pragma_malformed);
221 return;
222 }
223
224 // Read the '"..."'.
225 Toks.lex();
226 if (!tok::isStringLiteral(Tok.getKind())) {
227 Diag(PragmaLoc, diag::err__Pragma_malformed);
228 // Skip bad tokens, and the ')', if present.
229 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::eof))
230 Lex(Tok);
231 while (Tok.isNot(tok::r_paren) &&
232 !Tok.isAtStartOfLine() &&
233 Tok.isNot(tok::eof))
234 Lex(Tok);
235 if (Tok.is(tok::r_paren))
236 Lex(Tok);
237 return;
238 }
239
240 if (Tok.hasUDSuffix()) {
241 Diag(Tok, diag::err_invalid_string_udl);
242 // Skip this token, and the ')', if present.
243 Lex(Tok);
244 if (Tok.is(tok::r_paren))
245 Lex(Tok);
246 return;
247 }
248
249 // Remember the string.
250 Token StrTok = Tok;
251
252 // Read the ')'.
253 Toks.lex();
254 if (Tok.isNot(tok::r_paren)) {
255 Diag(PragmaLoc, diag::err__Pragma_malformed);
256 return;
257 }
258
259 // If we're expanding a macro argument, put the tokens back.
260 if (InMacroArgPreExpansion) {
261 Toks.revert();
262 return;
263 }
264
265 SourceLocation RParenLoc = Tok.getLocation();
266 std::string StrVal = getSpelling(StrTok);
267
268 // The _Pragma is lexically sound. Destringize according to C11 6.10.9.1:
269 // "The string literal is destringized by deleting any encoding prefix,
270 // deleting the leading and trailing double-quotes, replacing each escape
271 // sequence \" by a double-quote, and replacing each escape sequence \\ by a
272 // single backslash."
273 if (StrVal[0] == 'L' || StrVal[0] == 'U' ||
274 (StrVal[0] == 'u' && StrVal[1] != '8'))
275 StrVal.erase(StrVal.begin());
276 else if (StrVal[0] == 'u')
277 StrVal.erase(StrVal.begin(), StrVal.begin() + 2);
278
279 if (StrVal[0] == 'R') {
280 // FIXME: C++11 does not specify how to handle raw-string-literals here.
281 // We strip off the 'R', the quotes, the d-char-sequences, and the parens.
282 assert(StrVal[1] == '"' && StrVal[StrVal.size() - 1] == '"' &&(static_cast <bool> (StrVal[1] == '"' && StrVal
[StrVal.size() - 1] == '"' && "Invalid raw string token!"
) ? void (0) : __assert_fail ("StrVal[1] == '\"' && StrVal[StrVal.size() - 1] == '\"' && \"Invalid raw string token!\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 283, __extension__ __PRETTY_FUNCTION__))
283 "Invalid raw string token!")(static_cast <bool> (StrVal[1] == '"' && StrVal
[StrVal.size() - 1] == '"' && "Invalid raw string token!"
) ? void (0) : __assert_fail ("StrVal[1] == '\"' && StrVal[StrVal.size() - 1] == '\"' && \"Invalid raw string token!\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 283, __extension__ __PRETTY_FUNCTION__))
;
284
285 // Measure the length of the d-char-sequence.
286 unsigned NumDChars = 0;
287 while (StrVal[2 + NumDChars] != '(') {
288 assert(NumDChars < (StrVal.size() - 5) / 2 &&(static_cast <bool> (NumDChars < (StrVal.size() - 5)
/ 2 && "Invalid raw string token!") ? void (0) : __assert_fail
("NumDChars < (StrVal.size() - 5) / 2 && \"Invalid raw string token!\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 289, __extension__ __PRETTY_FUNCTION__))
289 "Invalid raw string token!")(static_cast <bool> (NumDChars < (StrVal.size() - 5)
/ 2 && "Invalid raw string token!") ? void (0) : __assert_fail
("NumDChars < (StrVal.size() - 5) / 2 && \"Invalid raw string token!\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 289, __extension__ __PRETTY_FUNCTION__))
;
290 ++NumDChars;
291 }
292 assert(StrVal[StrVal.size() - 2 - NumDChars] == ')')(static_cast <bool> (StrVal[StrVal.size() - 2 - NumDChars
] == ')') ? void (0) : __assert_fail ("StrVal[StrVal.size() - 2 - NumDChars] == ')'"
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 292, __extension__ __PRETTY_FUNCTION__))
;
293
294 // Remove 'R " d-char-sequence' and 'd-char-sequence "'. We'll replace the
295 // parens below.
296 StrVal.erase(0, 2 + NumDChars);
297 StrVal.erase(StrVal.size() - 1 - NumDChars);
298 } else {
299 assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' &&(static_cast <bool> (StrVal[0] == '"' && StrVal
[StrVal.size()-1] == '"' && "Invalid string token!") ?
void (0) : __assert_fail ("StrVal[0] == '\"' && StrVal[StrVal.size()-1] == '\"' && \"Invalid string token!\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 300, __extension__ __PRETTY_FUNCTION__))
300 "Invalid string token!")(static_cast <bool> (StrVal[0] == '"' && StrVal
[StrVal.size()-1] == '"' && "Invalid string token!") ?
void (0) : __assert_fail ("StrVal[0] == '\"' && StrVal[StrVal.size()-1] == '\"' && \"Invalid string token!\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 300, __extension__ __PRETTY_FUNCTION__))
;
301
302 // Remove escaped quotes and escapes.
303 unsigned ResultPos = 1;
304 for (size_t i = 1, e = StrVal.size() - 1; i != e; ++i) {
305 // Skip escapes. \\ -> '\' and \" -> '"'.
306 if (StrVal[i] == '\\' && i + 1 < e &&
307 (StrVal[i + 1] == '\\' || StrVal[i + 1] == '"'))
308 ++i;
309 StrVal[ResultPos++] = StrVal[i];
310 }
311 StrVal.erase(StrVal.begin() + ResultPos, StrVal.end() - 1);
312 }
313
314 // Remove the front quote, replacing it with a space, so that the pragma
315 // contents appear to have a space before them.
316 StrVal[0] = ' ';
317
318 // Replace the terminating quote with a \n.
319 StrVal[StrVal.size()-1] = '\n';
320
321 // Plop the string (including the newline and trailing null) into a buffer
322 // where we can lex it.
323 Token TmpTok;
324 TmpTok.startToken();
325 CreateString(StrVal, TmpTok);
326 SourceLocation TokLoc = TmpTok.getLocation();
327
328 // Make and enter a lexer object so that we lex and expand the tokens just
329 // like any others.
330 Lexer *TL = Lexer::Create_PragmaLexer(TokLoc, PragmaLoc, RParenLoc,
331 StrVal.size(), *this);
332
333 EnterSourceFileWithLexer(TL, nullptr);
334
335 // With everything set up, lex this as a #pragma directive.
336 HandlePragmaDirective({PIK__Pragma, PragmaLoc});
337
338 // Finally, return whatever came after the pragma directive.
339 return Lex(Tok);
340}
341
342/// HandleMicrosoft__pragma - Like Handle_Pragma except the pragma text
343/// is not enclosed within a string literal.
344void Preprocessor::HandleMicrosoft__pragma(Token &Tok) {
345 // During macro pre-expansion, check the syntax now but put the tokens back
346 // into the token stream for later consumption. Same as Handle_Pragma.
347 TokenCollector Toks = {*this, InMacroArgPreExpansion, {}, Tok};
348
349 // Remember the pragma token location.
350 SourceLocation PragmaLoc = Tok.getLocation();
351
352 // Read the '('.
353 Toks.lex();
354 if (Tok.isNot(tok::l_paren)) {
355 Diag(PragmaLoc, diag::err__Pragma_malformed);
356 return;
357 }
358
359 // Get the tokens enclosed within the __pragma(), as well as the final ')'.
360 SmallVector<Token, 32> PragmaToks;
361 int NumParens = 0;
362 Toks.lex();
363 while (Tok.isNot(tok::eof)) {
364 PragmaToks.push_back(Tok);
365 if (Tok.is(tok::l_paren))
366 NumParens++;
367 else if (Tok.is(tok::r_paren) && NumParens-- == 0)
368 break;
369 Toks.lex();
370 }
371
372 if (Tok.is(tok::eof)) {
373 Diag(PragmaLoc, diag::err_unterminated___pragma);
374 return;
375 }
376
377 // If we're expanding a macro argument, put the tokens back.
378 if (InMacroArgPreExpansion) {
379 Toks.revert();
380 return;
381 }
382
383 PragmaToks.front().setFlag(Token::LeadingSpace);
384
385 // Replace the ')' with an EOD to mark the end of the pragma.
386 PragmaToks.back().setKind(tok::eod);
387
388 Token *TokArray = new Token[PragmaToks.size()];
389 std::copy(PragmaToks.begin(), PragmaToks.end(), TokArray);
390
391 // Push the tokens onto the stack.
392 EnterTokenStream(TokArray, PragmaToks.size(), true, true,
393 /*IsReinject*/ false);
394
395 // With everything set up, lex this as a #pragma directive.
396 HandlePragmaDirective({PIK___pragma, PragmaLoc});
397
398 // Finally, return whatever came after the pragma directive.
399 return Lex(Tok);
400}
401
402/// HandlePragmaOnce - Handle \#pragma once. OnceTok is the 'once'.
403void Preprocessor::HandlePragmaOnce(Token &OnceTok) {
404 // Don't honor the 'once' when handling the primary source file, unless
405 // this is a prefix to a TU, which indicates we're generating a PCH file, or
406 // when the main file is a header (e.g. when -xc-header is provided on the
407 // commandline).
408 if (isInPrimaryFile() && TUKind != TU_Prefix && !getLangOpts().IsHeaderFile) {
409 Diag(OnceTok, diag::pp_pragma_once_in_main_file);
410 return;
411 }
412
413 // Get the current file lexer we're looking at. Ignore _Pragma 'files' etc.
414 // Mark the file as a once-only file now.
415 HeaderInfo.MarkFileIncludeOnce(getCurrentFileLexer()->getFileEntry());
416}
417
418void Preprocessor::HandlePragmaMark(Token &MarkTok) {
419 assert(CurPPLexer && "No current lexer?")(static_cast <bool> (CurPPLexer && "No current lexer?"
) ? void (0) : __assert_fail ("CurPPLexer && \"No current lexer?\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 419, __extension__ __PRETTY_FUNCTION__))
;
420
421 SmallString<64> Buffer;
422 CurLexer->ReadToEndOfLine(&Buffer);
423 if (Callbacks)
424 Callbacks->PragmaMark(MarkTok.getLocation(), Buffer);
425}
426
427/// HandlePragmaPoison - Handle \#pragma GCC poison. PoisonTok is the 'poison'.
428void Preprocessor::HandlePragmaPoison() {
429 Token Tok;
430
431 while (true) {
432 // Read the next token to poison. While doing this, pretend that we are
433 // skipping while reading the identifier to poison.
434 // This avoids errors on code like:
435 // #pragma GCC poison X
436 // #pragma GCC poison X
437 if (CurPPLexer) CurPPLexer->LexingRawMode = true;
438 LexUnexpandedToken(Tok);
439 if (CurPPLexer) CurPPLexer->LexingRawMode = false;
440
441 // If we reached the end of line, we're done.
442 if (Tok.is(tok::eod)) return;
443
444 // Can only poison identifiers.
445 if (Tok.isNot(tok::raw_identifier)) {
446 Diag(Tok, diag::err_pp_invalid_poison);
447 return;
448 }
449
450 // Look up the identifier info for the token. We disabled identifier lookup
451 // by saying we're skipping contents, so we need to do this manually.
452 IdentifierInfo *II = LookUpIdentifierInfo(Tok);
453
454 // Already poisoned.
455 if (II->isPoisoned()) continue;
456
457 // If this is a macro identifier, emit a warning.
458 if (isMacroDefined(II))
459 Diag(Tok, diag::pp_poisoning_existing_macro);
460
461 // Finally, poison it!
462 II->setIsPoisoned();
463 if (II->isFromAST())
464 II->setChangedSinceDeserialization();
465 }
466}
467
468/// HandlePragmaSystemHeader - Implement \#pragma GCC system_header. We know
469/// that the whole directive has been parsed.
470void Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) {
471 if (isInPrimaryFile()) {
472 Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);
473 return;
474 }
475
476 // Get the current file lexer we're looking at. Ignore _Pragma 'files' etc.
477 PreprocessorLexer *TheLexer = getCurrentFileLexer();
478
479 // Mark the file as a system header.
480 HeaderInfo.MarkFileSystemHeader(TheLexer->getFileEntry());
481
482 PresumedLoc PLoc = SourceMgr.getPresumedLoc(SysHeaderTok.getLocation());
483 if (PLoc.isInvalid())
484 return;
485
486 unsigned FilenameID = SourceMgr.getLineTableFilenameID(PLoc.getFilename());
487
488 // Notify the client, if desired, that we are in a new source file.
489 if (Callbacks)
490 Callbacks->FileChanged(SysHeaderTok.getLocation(),
491 PPCallbacks::SystemHeaderPragma, SrcMgr::C_System);
492
493 // Emit a line marker. This will change any source locations from this point
494 // forward to realize they are in a system header.
495 // Create a line note with this information.
496 SourceMgr.AddLineNote(SysHeaderTok.getLocation(), PLoc.getLine() + 1,
497 FilenameID, /*IsEntry=*/false, /*IsExit=*/false,
498 SrcMgr::C_System);
499}
500
501static llvm::Optional<Token> LexHeader(Preprocessor &PP,
502 Optional<FileEntryRef> &File,
503 bool SuppressIncludeNotFoundError) {
504 Token FilenameTok;
505 if (PP.LexHeaderName(FilenameTok, /*AllowConcatenation*/ false))
506 return llvm::None;
507
508 // If the next token wasn't a header-name, diagnose the error.
509 if (FilenameTok.isNot(tok::header_name)) {
510 PP.Diag(FilenameTok.getLocation(), diag::err_pp_expects_filename);
511 return llvm::None;
512 }
513
514 // Reserve a buffer to get the spelling.
515 SmallString<128> FilenameBuffer;
516 bool Invalid = false;
517 StringRef Filename = PP.getSpelling(FilenameTok, FilenameBuffer, &Invalid);
518 if (Invalid)
519 return llvm::None;
520
521 bool isAngled =
522 PP.GetIncludeFilenameSpelling(FilenameTok.getLocation(), Filename);
523 // If GetIncludeFilenameSpelling set the start ptr to null, there was an
524 // error.
525 if (Filename.empty())
526 return llvm::None;
527
528 // Search include directories for this file.
529 const DirectoryLookup *CurDir;
530 File = PP.LookupFile(FilenameTok.getLocation(), Filename, isAngled, nullptr,
531 nullptr, CurDir, nullptr, nullptr, nullptr, nullptr,
532 nullptr);
533 if (!File) {
534 if (!SuppressIncludeNotFoundError)
535 PP.Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
536 return llvm::None;
537 }
538
539 return FilenameTok;
540}
541
542/// HandlePragmaIncludeInstead - Handle \#pragma clang include_instead(header).
543void Preprocessor::HandlePragmaIncludeInstead(Token &Tok) {
544 // Get the current file lexer we're looking at. Ignore _Pragma 'files' etc.
545 PreprocessorLexer *TheLexer = getCurrentFileLexer();
546
547 if (!SourceMgr.isInSystemHeader(Tok.getLocation())) {
548 Diag(Tok, diag::err_pragma_include_instead_not_sysheader);
549 return;
550 }
551
552 Lex(Tok);
553 if (Tok.isNot(tok::l_paren)) {
554 Diag(Tok, diag::err_expected) << "(";
555 return;
556 }
557
558 Optional<FileEntryRef> File;
559 llvm::Optional<Token> FilenameTok =
560 LexHeader(*this, File, SuppressIncludeNotFoundError);
561 if (!FilenameTok)
562 return;
563
564 Lex(Tok);
565 if (Tok.isNot(tok::r_paren)) {
566 Diag(Tok, diag::err_expected) << ")";
567 return;
568 }
569
570 SmallString<128> FilenameBuffer;
571 StringRef Filename = getSpelling(*FilenameTok, FilenameBuffer);
572 HeaderInfo.AddFileAlias(TheLexer->getFileEntry(), Filename);
573}
574
575/// HandlePragmaDependency - Handle \#pragma GCC dependency "foo" blah.
576void Preprocessor::HandlePragmaDependency(Token &DependencyTok) {
577 Optional<FileEntryRef> File;
578 llvm::Optional<Token> FilenameTok =
579 LexHeader(*this, File, SuppressIncludeNotFoundError);
580 if (!FilenameTok)
581 return;
582
583 const FileEntry *CurFile = getCurrentFileLexer()->getFileEntry();
584
585 // If this file is older than the file it depends on, emit a diagnostic.
586 if (CurFile && CurFile->getModificationTime() < File->getModificationTime()) {
587 // Lex tokens at the end of the message and include them in the message.
588 std::string Message;
589 Lex(DependencyTok);
590 while (DependencyTok.isNot(tok::eod)) {
591 Message += getSpelling(DependencyTok) + " ";
592 Lex(DependencyTok);
593 }
594
595 // Remove the trailing ' ' if present.
596 if (!Message.empty())
597 Message.erase(Message.end()-1);
598 Diag(*FilenameTok, diag::pp_out_of_date_dependency) << Message;
599 }
600}
601
602/// ParsePragmaPushOrPopMacro - Handle parsing of pragma push_macro/pop_macro.
603/// Return the IdentifierInfo* associated with the macro to push or pop.
604IdentifierInfo *Preprocessor::ParsePragmaPushOrPopMacro(Token &Tok) {
605 // Remember the pragma token location.
606 Token PragmaTok = Tok;
607
608 // Read the '('.
609 Lex(Tok);
610 if (Tok.isNot(tok::l_paren)) {
611 Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
612 << getSpelling(PragmaTok);
613 return nullptr;
614 }
615
616 // Read the macro name string.
617 Lex(Tok);
618 if (Tok.isNot(tok::string_literal)) {
619 Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
620 << getSpelling(PragmaTok);
621 return nullptr;
622 }
623
624 if (Tok.hasUDSuffix()) {
625 Diag(Tok, diag::err_invalid_string_udl);
626 return nullptr;
627 }
628
629 // Remember the macro string.
630 std::string StrVal = getSpelling(Tok);
631
632 // Read the ')'.
633 Lex(Tok);
634 if (Tok.isNot(tok::r_paren)) {
635 Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
636 << getSpelling(PragmaTok);
637 return nullptr;
638 }
639
640 assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' &&(static_cast <bool> (StrVal[0] == '"' && StrVal
[StrVal.size()-1] == '"' && "Invalid string token!") ?
void (0) : __assert_fail ("StrVal[0] == '\"' && StrVal[StrVal.size()-1] == '\"' && \"Invalid string token!\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 641, __extension__ __PRETTY_FUNCTION__))
641 "Invalid string token!")(static_cast <bool> (StrVal[0] == '"' && StrVal
[StrVal.size()-1] == '"' && "Invalid string token!") ?
void (0) : __assert_fail ("StrVal[0] == '\"' && StrVal[StrVal.size()-1] == '\"' && \"Invalid string token!\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 641, __extension__ __PRETTY_FUNCTION__))
;
642
643 // Create a Token from the string.
644 Token MacroTok;
645 MacroTok.startToken();
646 MacroTok.setKind(tok::raw_identifier);
647 CreateString(StringRef(&StrVal[1], StrVal.size() - 2), MacroTok);
648
649 // Get the IdentifierInfo of MacroToPushTok.
650 return LookUpIdentifierInfo(MacroTok);
651}
652
653/// Handle \#pragma push_macro.
654///
655/// The syntax is:
656/// \code
657/// #pragma push_macro("macro")
658/// \endcode
659void Preprocessor::HandlePragmaPushMacro(Token &PushMacroTok) {
660 // Parse the pragma directive and get the macro IdentifierInfo*.
661 IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PushMacroTok);
662 if (!IdentInfo) return;
663
664 // Get the MacroInfo associated with IdentInfo.
665 MacroInfo *MI = getMacroInfo(IdentInfo);
666
667 if (MI) {
668 // Allow the original MacroInfo to be redefined later.
669 MI->setIsAllowRedefinitionsWithoutWarning(true);
670 }
671
672 // Push the cloned MacroInfo so we can retrieve it later.
673 PragmaPushMacroInfo[IdentInfo].push_back(MI);
674}
675
676/// Handle \#pragma pop_macro.
677///
678/// The syntax is:
679/// \code
680/// #pragma pop_macro("macro")
681/// \endcode
682void Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) {
683 SourceLocation MessageLoc = PopMacroTok.getLocation();
684
685 // Parse the pragma directive and get the macro IdentifierInfo*.
686 IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PopMacroTok);
687 if (!IdentInfo) return;
688
689 // Find the vector<MacroInfo*> associated with the macro.
690 llvm::DenseMap<IdentifierInfo *, std::vector<MacroInfo *>>::iterator iter =
691 PragmaPushMacroInfo.find(IdentInfo);
692 if (iter != PragmaPushMacroInfo.end()) {
693 // Forget the MacroInfo currently associated with IdentInfo.
694 if (MacroInfo *MI = getMacroInfo(IdentInfo)) {
695 if (MI->isWarnIfUnused())
696 WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
697 appendMacroDirective(IdentInfo, AllocateUndefMacroDirective(MessageLoc));
698 }
699
700 // Get the MacroInfo we want to reinstall.
701 MacroInfo *MacroToReInstall = iter->second.back();
702
703 if (MacroToReInstall)
704 // Reinstall the previously pushed macro.
705 appendDefMacroDirective(IdentInfo, MacroToReInstall, MessageLoc);
706
707 // Pop PragmaPushMacroInfo stack.
708 iter->second.pop_back();
709 if (iter->second.empty())
710 PragmaPushMacroInfo.erase(iter);
711 } else {
712 Diag(MessageLoc, diag::warn_pragma_pop_macro_no_push)
713 << IdentInfo->getName();
714 }
715}
716
717void Preprocessor::HandlePragmaIncludeAlias(Token &Tok) {
718 // We will either get a quoted filename or a bracketed filename, and we
719 // have to track which we got. The first filename is the source name,
720 // and the second name is the mapped filename. If the first is quoted,
721 // the second must be as well (cannot mix and match quotes and brackets).
722
723 // Get the open paren
724 Lex(Tok);
725 if (Tok.isNot(tok::l_paren)) {
726 Diag(Tok, diag::warn_pragma_include_alias_expected) << "(";
727 return;
728 }
729
730 // We expect either a quoted string literal, or a bracketed name
731 Token SourceFilenameTok;
732 if (LexHeaderName(SourceFilenameTok))
733 return;
734
735 StringRef SourceFileName;
736 SmallString<128> FileNameBuffer;
737 if (SourceFilenameTok.is(tok::header_name)) {
738 SourceFileName = getSpelling(SourceFilenameTok, FileNameBuffer);
739 } else {
740 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
741 return;
742 }
743 FileNameBuffer.clear();
744
745 // Now we expect a comma, followed by another include name
746 Lex(Tok);
747 if (Tok.isNot(tok::comma)) {
748 Diag(Tok, diag::warn_pragma_include_alias_expected) << ",";
749 return;
750 }
751
752 Token ReplaceFilenameTok;
753 if (LexHeaderName(ReplaceFilenameTok))
754 return;
755
756 StringRef ReplaceFileName;
757 if (ReplaceFilenameTok.is(tok::header_name)) {
758 ReplaceFileName = getSpelling(ReplaceFilenameTok, FileNameBuffer);
759 } else {
760 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
761 return;
762 }
763
764 // Finally, we expect the closing paren
765 Lex(Tok);
766 if (Tok.isNot(tok::r_paren)) {
767 Diag(Tok, diag::warn_pragma_include_alias_expected) << ")";
768 return;
769 }
770
771 // Now that we have the source and target filenames, we need to make sure
772 // they're both of the same type (angled vs non-angled)
773 StringRef OriginalSource = SourceFileName;
774
775 bool SourceIsAngled =
776 GetIncludeFilenameSpelling(SourceFilenameTok.getLocation(),
777 SourceFileName);
778 bool ReplaceIsAngled =
779 GetIncludeFilenameSpelling(ReplaceFilenameTok.getLocation(),
780 ReplaceFileName);
781 if (!SourceFileName.empty() && !ReplaceFileName.empty() &&
782 (SourceIsAngled != ReplaceIsAngled)) {
783 unsigned int DiagID;
784 if (SourceIsAngled)
785 DiagID = diag::warn_pragma_include_alias_mismatch_angle;
786 else
787 DiagID = diag::warn_pragma_include_alias_mismatch_quote;
788
789 Diag(SourceFilenameTok.getLocation(), DiagID)
790 << SourceFileName
791 << ReplaceFileName;
792
793 return;
794 }
795
796 // Now we can let the include handler know about this mapping
797 getHeaderSearchInfo().AddIncludeAlias(OriginalSource, ReplaceFileName);
798}
799
800// Lex a component of a module name: either an identifier or a string literal;
801// for components that can be expressed both ways, the two forms are equivalent.
802static bool LexModuleNameComponent(
803 Preprocessor &PP, Token &Tok,
804 std::pair<IdentifierInfo *, SourceLocation> &ModuleNameComponent,
805 bool First) {
806 PP.LexUnexpandedToken(Tok);
807 if (Tok.is(tok::string_literal) && !Tok.hasUDSuffix()) {
808 StringLiteralParser Literal(Tok, PP);
809 if (Literal.hadError)
810 return true;
811 ModuleNameComponent = std::make_pair(
812 PP.getIdentifierInfo(Literal.GetString()), Tok.getLocation());
813 } else if (!Tok.isAnnotation() && Tok.getIdentifierInfo()) {
814 ModuleNameComponent =
815 std::make_pair(Tok.getIdentifierInfo(), Tok.getLocation());
816 } else {
817 PP.Diag(Tok.getLocation(), diag::err_pp_expected_module_name) << First;
818 return true;
819 }
820 return false;
821}
822
823static bool LexModuleName(
824 Preprocessor &PP, Token &Tok,
825 llvm::SmallVectorImpl<std::pair<IdentifierInfo *, SourceLocation>>
826 &ModuleName) {
827 while (true) {
828 std::pair<IdentifierInfo*, SourceLocation> NameComponent;
829 if (LexModuleNameComponent(PP, Tok, NameComponent, ModuleName.empty()))
830 return true;
831 ModuleName.push_back(NameComponent);
832
833 PP.LexUnexpandedToken(Tok);
834 if (Tok.isNot(tok::period))
835 return false;
836 }
837}
838
839void Preprocessor::HandlePragmaModuleBuild(Token &Tok) {
840 SourceLocation Loc = Tok.getLocation();
841
842 std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc;
843 if (LexModuleNameComponent(*this, Tok, ModuleNameLoc, true))
844 return;
845 IdentifierInfo *ModuleName = ModuleNameLoc.first;
846
847 LexUnexpandedToken(Tok);
848 if (Tok.isNot(tok::eod)) {
849 Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";
850 DiscardUntilEndOfDirective();
851 }
852
853 CurLexer->LexingRawMode = true;
854
855 auto TryConsumeIdentifier = [&](StringRef Ident) -> bool {
856 if (Tok.getKind() != tok::raw_identifier ||
857 Tok.getRawIdentifier() != Ident)
858 return false;
859 CurLexer->Lex(Tok);
860 return true;
861 };
862
863 // Scan forward looking for the end of the module.
864 const char *Start = CurLexer->getBufferLocation();
865 const char *End = nullptr;
866 unsigned NestingLevel = 1;
867 while (true) {
868 End = CurLexer->getBufferLocation();
869 CurLexer->Lex(Tok);
870
871 if (Tok.is(tok::eof)) {
872 Diag(Loc, diag::err_pp_module_build_missing_end);
873 break;
874 }
875
876 if (Tok.isNot(tok::hash) || !Tok.isAtStartOfLine()) {
877 // Token was part of module; keep going.
878 continue;
879 }
880
881 // We hit something directive-shaped; check to see if this is the end
882 // of the module build.
883 CurLexer->ParsingPreprocessorDirective = true;
884 CurLexer->Lex(Tok);
885 if (TryConsumeIdentifier("pragma") && TryConsumeIdentifier("clang") &&
886 TryConsumeIdentifier("module")) {
887 if (TryConsumeIdentifier("build"))
888 // #pragma clang module build -> entering a nested module build.
889 ++NestingLevel;
890 else if (TryConsumeIdentifier("endbuild")) {
891 // #pragma clang module endbuild -> leaving a module build.
892 if (--NestingLevel == 0)
893 break;
894 }
895 // We should either be looking at the EOD or more of the current directive
896 // preceding the EOD. Either way we can ignore this token and keep going.
897 assert(Tok.getKind() != tok::eof && "missing EOD before EOF")(static_cast <bool> (Tok.getKind() != tok::eof &&
"missing EOD before EOF") ? void (0) : __assert_fail ("Tok.getKind() != tok::eof && \"missing EOD before EOF\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 897, __extension__ __PRETTY_FUNCTION__))
;
898 }
899 }
900
901 CurLexer->LexingRawMode = false;
902
903 // Load the extracted text as a preprocessed module.
904 assert(CurLexer->getBuffer().begin() <= Start &&(static_cast <bool> (CurLexer->getBuffer().begin() <=
Start && Start <= CurLexer->getBuffer().end() &&
CurLexer->getBuffer().begin() <= End && End <=
CurLexer->getBuffer().end() && "module source range not contained within same file buffer"
) ? void (0) : __assert_fail ("CurLexer->getBuffer().begin() <= Start && Start <= CurLexer->getBuffer().end() && CurLexer->getBuffer().begin() <= End && End <= CurLexer->getBuffer().end() && \"module source range not contained within same file buffer\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 908, __extension__ __PRETTY_FUNCTION__))
905 Start <= CurLexer->getBuffer().end() &&(static_cast <bool> (CurLexer->getBuffer().begin() <=
Start && Start <= CurLexer->getBuffer().end() &&
CurLexer->getBuffer().begin() <= End && End <=
CurLexer->getBuffer().end() && "module source range not contained within same file buffer"
) ? void (0) : __assert_fail ("CurLexer->getBuffer().begin() <= Start && Start <= CurLexer->getBuffer().end() && CurLexer->getBuffer().begin() <= End && End <= CurLexer->getBuffer().end() && \"module source range not contained within same file buffer\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 908, __extension__ __PRETTY_FUNCTION__))
906 CurLexer->getBuffer().begin() <= End &&(static_cast <bool> (CurLexer->getBuffer().begin() <=
Start && Start <= CurLexer->getBuffer().end() &&
CurLexer->getBuffer().begin() <= End && End <=
CurLexer->getBuffer().end() && "module source range not contained within same file buffer"
) ? void (0) : __assert_fail ("CurLexer->getBuffer().begin() <= Start && Start <= CurLexer->getBuffer().end() && CurLexer->getBuffer().begin() <= End && End <= CurLexer->getBuffer().end() && \"module source range not contained within same file buffer\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 908, __extension__ __PRETTY_FUNCTION__))
907 End <= CurLexer->getBuffer().end() &&(static_cast <bool> (CurLexer->getBuffer().begin() <=
Start && Start <= CurLexer->getBuffer().end() &&
CurLexer->getBuffer().begin() <= End && End <=
CurLexer->getBuffer().end() && "module source range not contained within same file buffer"
) ? void (0) : __assert_fail ("CurLexer->getBuffer().begin() <= Start && Start <= CurLexer->getBuffer().end() && CurLexer->getBuffer().begin() <= End && End <= CurLexer->getBuffer().end() && \"module source range not contained within same file buffer\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 908, __extension__ __PRETTY_FUNCTION__))
908 "module source range not contained within same file buffer")(static_cast <bool> (CurLexer->getBuffer().begin() <=
Start && Start <= CurLexer->getBuffer().end() &&
CurLexer->getBuffer().begin() <= End && End <=
CurLexer->getBuffer().end() && "module source range not contained within same file buffer"
) ? void (0) : __assert_fail ("CurLexer->getBuffer().begin() <= Start && Start <= CurLexer->getBuffer().end() && CurLexer->getBuffer().begin() <= End && End <= CurLexer->getBuffer().end() && \"module source range not contained within same file buffer\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 908, __extension__ __PRETTY_FUNCTION__))
;
909 TheModuleLoader.createModuleFromSource(Loc, ModuleName->getName(),
910 StringRef(Start, End - Start));
911}
912
913void Preprocessor::HandlePragmaHdrstop(Token &Tok) {
914 Lex(Tok);
915 if (Tok.is(tok::l_paren)) {
916 Diag(Tok.getLocation(), diag::warn_pp_hdrstop_filename_ignored);
917
918 std::string FileName;
919 if (!LexStringLiteral(Tok, FileName, "pragma hdrstop", false))
920 return;
921
922 if (Tok.isNot(tok::r_paren)) {
923 Diag(Tok, diag::err_expected) << tok::r_paren;
924 return;
925 }
926 Lex(Tok);
927 }
928 if (Tok.isNot(tok::eod))
929 Diag(Tok.getLocation(), diag::ext_pp_extra_tokens_at_eol)
930 << "pragma hdrstop";
931
932 if (creatingPCHWithPragmaHdrStop() &&
933 SourceMgr.isInMainFile(Tok.getLocation())) {
934 assert(CurLexer && "no lexer for #pragma hdrstop processing")(static_cast <bool> (CurLexer && "no lexer for #pragma hdrstop processing"
) ? void (0) : __assert_fail ("CurLexer && \"no lexer for #pragma hdrstop processing\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 934, __extension__ __PRETTY_FUNCTION__))
;
935 Token &Result = Tok;
936 Result.startToken();
937 CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd, tok::eof);
938 CurLexer->cutOffLexing();
939 }
940 if (usingPCHWithPragmaHdrStop())
941 SkippingUntilPragmaHdrStop = false;
942}
943
944/// AddPragmaHandler - Add the specified pragma handler to the preprocessor.
945/// If 'Namespace' is non-null, then it is a token required to exist on the
946/// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
947void Preprocessor::AddPragmaHandler(StringRef Namespace,
948 PragmaHandler *Handler) {
949 PragmaNamespace *InsertNS = PragmaHandlers.get();
950
951 // If this is specified to be in a namespace, step down into it.
952 if (!Namespace.empty()) {
953 // If there is already a pragma handler with the name of this namespace,
954 // we either have an error (directive with the same name as a namespace) or
955 // we already have the namespace to insert into.
956 if (PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace)) {
957 InsertNS = Existing->getIfNamespace();
958 assert(InsertNS != nullptr && "Cannot have a pragma namespace and pragma"(static_cast <bool> (InsertNS != nullptr && "Cannot have a pragma namespace and pragma"
" handler with the same name!") ? void (0) : __assert_fail (
"InsertNS != nullptr && \"Cannot have a pragma namespace and pragma\" \" handler with the same name!\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 959, __extension__ __PRETTY_FUNCTION__))
959 " handler with the same name!")(static_cast <bool> (InsertNS != nullptr && "Cannot have a pragma namespace and pragma"
" handler with the same name!") ? void (0) : __assert_fail (
"InsertNS != nullptr && \"Cannot have a pragma namespace and pragma\" \" handler with the same name!\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 959, __extension__ __PRETTY_FUNCTION__))
;
960 } else {
961 // Otherwise, this namespace doesn't exist yet, create and insert the
962 // handler for it.
963 InsertNS = new PragmaNamespace(Namespace);
964 PragmaHandlers->AddPragma(InsertNS);
965 }
966 }
967
968 // Check to make sure we don't already have a pragma for this identifier.
969 assert(!InsertNS->FindHandler(Handler->getName()) &&(static_cast <bool> (!InsertNS->FindHandler(Handler->
getName()) && "Pragma handler already exists for this identifier!"
) ? void (0) : __assert_fail ("!InsertNS->FindHandler(Handler->getName()) && \"Pragma handler already exists for this identifier!\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 970, __extension__ __PRETTY_FUNCTION__))
970 "Pragma handler already exists for this identifier!")(static_cast <bool> (!InsertNS->FindHandler(Handler->
getName()) && "Pragma handler already exists for this identifier!"
) ? void (0) : __assert_fail ("!InsertNS->FindHandler(Handler->getName()) && \"Pragma handler already exists for this identifier!\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 970, __extension__ __PRETTY_FUNCTION__))
;
971 InsertNS->AddPragma(Handler);
972}
973
974/// RemovePragmaHandler - Remove the specific pragma handler from the
975/// preprocessor. If \arg Namespace is non-null, then it should be the
976/// namespace that \arg Handler was added to. It is an error to remove
977/// a handler that has not been registered.
978void Preprocessor::RemovePragmaHandler(StringRef Namespace,
979 PragmaHandler *Handler) {
980 PragmaNamespace *NS = PragmaHandlers.get();
981
982 // If this is specified to be in a namespace, step down into it.
983 if (!Namespace.empty()) {
984 PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace);
985 assert(Existing && "Namespace containing handler does not exist!")(static_cast <bool> (Existing && "Namespace containing handler does not exist!"
) ? void (0) : __assert_fail ("Existing && \"Namespace containing handler does not exist!\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 985, __extension__ __PRETTY_FUNCTION__))
;
986
987 NS = Existing->getIfNamespace();
988 assert(NS && "Invalid namespace, registered as a regular pragma handler!")(static_cast <bool> (NS && "Invalid namespace, registered as a regular pragma handler!"
) ? void (0) : __assert_fail ("NS && \"Invalid namespace, registered as a regular pragma handler!\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 988, __extension__ __PRETTY_FUNCTION__))
;
989 }
990
991 NS->RemovePragmaHandler(Handler);
992
993 // If this is a non-default namespace and it is now empty, remove it.
994 if (NS != PragmaHandlers.get() && NS->IsEmpty()) {
995 PragmaHandlers->RemovePragmaHandler(NS);
996 delete NS;
997 }
998}
999
1000bool Preprocessor::LexOnOffSwitch(tok::OnOffSwitch &Result) {
1001 Token Tok;
1002 LexUnexpandedToken(Tok);
1003
1004 if (Tok.isNot(tok::identifier)) {
1005 Diag(Tok, diag::ext_on_off_switch_syntax);
1006 return true;
1007 }
1008 IdentifierInfo *II = Tok.getIdentifierInfo();
1009 if (II->isStr("ON"))
1010 Result = tok::OOS_ON;
1011 else if (II->isStr("OFF"))
1012 Result = tok::OOS_OFF;
1013 else if (II->isStr("DEFAULT"))
1014 Result = tok::OOS_DEFAULT;
1015 else {
1016 Diag(Tok, diag::ext_on_off_switch_syntax);
1017 return true;
1018 }
1019
1020 // Verify that this is followed by EOD.
1021 LexUnexpandedToken(Tok);
1022 if (Tok.isNot(tok::eod))
1023 Diag(Tok, diag::ext_pragma_syntax_eod);
1024 return false;
1025}
1026
1027namespace {
1028
1029/// PragmaOnceHandler - "\#pragma once" marks the file as atomically included.
1030struct PragmaOnceHandler : public PragmaHandler {
1031 PragmaOnceHandler() : PragmaHandler("once") {}
1032
1033 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1034 Token &OnceTok) override {
1035 PP.CheckEndOfDirective("pragma once");
1036 PP.HandlePragmaOnce(OnceTok);
1037 }
1038};
1039
1040/// PragmaMarkHandler - "\#pragma mark ..." is ignored by the compiler, and the
1041/// rest of the line is not lexed.
1042struct PragmaMarkHandler : public PragmaHandler {
1043 PragmaMarkHandler() : PragmaHandler("mark") {}
1044
1045 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1046 Token &MarkTok) override {
1047 PP.HandlePragmaMark(MarkTok);
1048 }
1049};
1050
1051/// PragmaPoisonHandler - "\#pragma poison x" marks x as not usable.
1052struct PragmaPoisonHandler : public PragmaHandler {
1053 PragmaPoisonHandler() : PragmaHandler("poison") {}
1054
1055 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1056 Token &PoisonTok) override {
1057 PP.HandlePragmaPoison();
1058 }
1059};
1060
1061/// PragmaSystemHeaderHandler - "\#pragma system_header" marks the current file
1062/// as a system header, which silences warnings in it.
1063struct PragmaSystemHeaderHandler : public PragmaHandler {
1064 PragmaSystemHeaderHandler() : PragmaHandler("system_header") {}
1065
1066 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1067 Token &SHToken) override {
1068 PP.HandlePragmaSystemHeader(SHToken);
1069 PP.CheckEndOfDirective("pragma");
1070 }
1071};
1072
1073/// PragmaIncludeInsteadHandler - "\#pragma clang include_instead(header)" marks
1074/// the current file as non-includable if the including header is not a system
1075/// header.
1076struct PragmaIncludeInsteadHandler : public PragmaHandler {
1077 PragmaIncludeInsteadHandler() : PragmaHandler("include_instead") {}
1078
1079 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1080 Token &IIToken) override {
1081 PP.HandlePragmaIncludeInstead(IIToken);
1082 }
1083};
1084
1085struct PragmaDependencyHandler : public PragmaHandler {
1086 PragmaDependencyHandler() : PragmaHandler("dependency") {}
1087
1088 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1089 Token &DepToken) override {
1090 PP.HandlePragmaDependency(DepToken);
1091 }
1092};
1093
1094struct PragmaDebugHandler : public PragmaHandler {
1095 PragmaDebugHandler() : PragmaHandler("__debug") {}
1096
1097 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1098 Token &DebugToken) override {
1099 Token Tok;
1100 PP.LexUnexpandedToken(Tok);
1101 if (Tok.isNot(tok::identifier)) {
1
Calling 'Token::isNot'
4
Returning from 'Token::isNot'
5
Taking false branch
1102 PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1103 return;
1104 }
1105 IdentifierInfo *II = Tok.getIdentifierInfo();
1106
1107 if (II->isStr("assert")) {
6
Calling 'IdentifierInfo::isStr'
9
Returning from 'IdentifierInfo::isStr'
10
Taking false branch
1108 if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash)
1109 llvm_unreachable("This is an assertion!")::llvm::llvm_unreachable_internal("This is an assertion!", "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 1109)
;
1110 } else if (II->isStr("crash")) {
11
Calling 'IdentifierInfo::isStr'
14
Returning from 'IdentifierInfo::isStr'
15
Taking false branch
1111 llvm::Timer T("crash", "pragma crash");
1112 llvm::TimeRegion R(&T);
1113 if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash)
1114 LLVM_BUILTIN_TRAP__builtin_trap();
1115 } else if (II->isStr("parser_crash")) {
16
Calling 'IdentifierInfo::isStr'
19
Returning from 'IdentifierInfo::isStr'
20
Taking false branch
1116 if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash) {
1117 Token Crasher;
1118 Crasher.startToken();
1119 Crasher.setKind(tok::annot_pragma_parser_crash);
1120 Crasher.setAnnotationRange(SourceRange(Tok.getLocation()));
1121 PP.EnterToken(Crasher, /*IsReinject*/ false);
1122 }
1123 } else if (II->isStr("dump")) {
21
Calling 'IdentifierInfo::isStr'
24
Returning from 'IdentifierInfo::isStr'
25
Taking false branch
1124 Token Identifier;
1125 PP.LexUnexpandedToken(Identifier);
1126 if (auto *DumpII = Identifier.getIdentifierInfo()) {
1127 Token DumpAnnot;
1128 DumpAnnot.startToken();
1129 DumpAnnot.setKind(tok::annot_pragma_dump);
1130 DumpAnnot.setAnnotationRange(
1131 SourceRange(Tok.getLocation(), Identifier.getLocation()));
1132 DumpAnnot.setAnnotationValue(DumpII);
1133 PP.DiscardUntilEndOfDirective();
1134 PP.EnterToken(DumpAnnot, /*IsReinject*/false);
1135 } else {
1136 PP.Diag(Identifier, diag::warn_pragma_debug_missing_argument)
1137 << II->getName();
1138 }
1139 } else if (II->isStr("diag_mapping")) {
26
Calling 'IdentifierInfo::isStr'
28
Returning from 'IdentifierInfo::isStr'
29
Taking false branch
1140 Token DiagName;
1141 PP.LexUnexpandedToken(DiagName);
1142 if (DiagName.is(tok::eod))
1143 PP.getDiagnostics().dump();
1144 else if (DiagName.is(tok::string_literal) && !DiagName.hasUDSuffix()) {
1145 StringLiteralParser Literal(DiagName, PP);
1146 if (Literal.hadError)
1147 return;
1148 PP.getDiagnostics().dump(Literal.GetString());
1149 } else {
1150 PP.Diag(DiagName, diag::warn_pragma_debug_missing_argument)
1151 << II->getName();
1152 }
1153 } else if (II->isStr("llvm_fatal_error")) {
30
Calling 'IdentifierInfo::isStr'
33
Returning from 'IdentifierInfo::isStr'
34
Taking false branch
1154 if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash)
1155 llvm::report_fatal_error("#pragma clang __debug llvm_fatal_error");
1156 } else if (II->isStr("llvm_unreachable")) {
35
Calling 'IdentifierInfo::isStr'
37
Returning from 'IdentifierInfo::isStr'
38
Taking false branch
1157 if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash)
1158 llvm_unreachable("#pragma clang __debug llvm_unreachable")::llvm::llvm_unreachable_internal("#pragma clang __debug llvm_unreachable"
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 1158)
;
1159 } else if (II->isStr("macro")) {
39
Calling 'IdentifierInfo::isStr'
41
Returning from 'IdentifierInfo::isStr'
42
Taking false branch
1160 Token MacroName;
1161 PP.LexUnexpandedToken(MacroName);
1162 auto *MacroII = MacroName.getIdentifierInfo();
1163 if (MacroII)
1164 PP.dumpMacroInfo(MacroII);
1165 else
1166 PP.Diag(MacroName, diag::warn_pragma_debug_missing_argument)
1167 << II->getName();
1168 } else if (II->isStr("module_map")) {
43
Calling 'IdentifierInfo::isStr'
47
Returning from 'IdentifierInfo::isStr'
48
Taking true branch
1169 llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 8>
1170 ModuleName;
1171 if (LexModuleName(PP, Tok, ModuleName))
49
Assuming the condition is false
50
Taking false branch
1172 return;
1173 ModuleMap &MM = PP.getHeaderSearchInfo().getModuleMap();
1174 Module *M = nullptr;
51
'M' initialized to a null pointer value
1175 for (auto IIAndLoc : ModuleName) {
52
Assuming '__begin11' is equal to '__end11'
1176 M = MM.lookupModuleQualified(IIAndLoc.first->getName(), M);
1177 if (!M) {
1178 PP.Diag(IIAndLoc.second, diag::warn_pragma_debug_unknown_module)
1179 << IIAndLoc.first;
1180 return;
1181 }
1182 }
1183 M->dump();
53
Called C++ object pointer is null
1184 } else if (II->isStr("overflow_stack")) {
1185 if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash)
1186 DebugOverflowStack();
1187 } else if (II->isStr("captured")) {
1188 HandleCaptured(PP);
1189 } else if (II->isStr("modules")) {
1190 struct ModuleVisitor {
1191 Preprocessor &PP;
1192 void visit(Module *M, bool VisibleOnly) {
1193 SourceLocation ImportLoc = PP.getModuleImportLoc(M);
1194 if (!VisibleOnly || ImportLoc.isValid()) {
1195 llvm::errs() << M->getFullModuleName() << " ";
1196 if (ImportLoc.isValid()) {
1197 llvm::errs() << M << " visible ";
1198 ImportLoc.print(llvm::errs(), PP.getSourceManager());
1199 }
1200 llvm::errs() << "\n";
1201 }
1202 for (Module *Sub : M->submodules()) {
1203 if (!VisibleOnly || ImportLoc.isInvalid() || Sub->IsExplicit)
1204 visit(Sub, VisibleOnly);
1205 }
1206 }
1207 void visitAll(bool VisibleOnly) {
1208 for (auto &NameAndMod :
1209 PP.getHeaderSearchInfo().getModuleMap().modules())
1210 visit(NameAndMod.second, VisibleOnly);
1211 }
1212 } Visitor{PP};
1213
1214 Token Kind;
1215 PP.LexUnexpandedToken(Kind);
1216 auto *DumpII = Kind.getIdentifierInfo();
1217 if (!DumpII) {
1218 PP.Diag(Kind, diag::warn_pragma_debug_missing_argument)
1219 << II->getName();
1220 } else if (DumpII->isStr("all")) {
1221 Visitor.visitAll(false);
1222 } else if (DumpII->isStr("visible")) {
1223 Visitor.visitAll(true);
1224 } else if (DumpII->isStr("building")) {
1225 for (auto &Building : PP.getBuildingSubmodules()) {
1226 llvm::errs() << "in " << Building.M->getFullModuleName();
1227 if (Building.ImportLoc.isValid()) {
1228 llvm::errs() << " imported ";
1229 if (Building.IsPragma)
1230 llvm::errs() << "via pragma ";
1231 llvm::errs() << "at ";
1232 Building.ImportLoc.print(llvm::errs(), PP.getSourceManager());
1233 llvm::errs() << "\n";
1234 }
1235 }
1236 } else {
1237 PP.Diag(Tok, diag::warn_pragma_debug_unexpected_command)
1238 << DumpII->getName();
1239 }
1240 } else {
1241 PP.Diag(Tok, diag::warn_pragma_debug_unexpected_command)
1242 << II->getName();
1243 }
1244
1245 PPCallbacks *Callbacks = PP.getPPCallbacks();
1246 if (Callbacks)
1247 Callbacks->PragmaDebug(Tok.getLocation(), II->getName());
1248 }
1249
1250 void HandleCaptured(Preprocessor &PP) {
1251 Token Tok;
1252 PP.LexUnexpandedToken(Tok);
1253
1254 if (Tok.isNot(tok::eod)) {
1255 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol)
1256 << "pragma clang __debug captured";
1257 return;
1258 }
1259
1260 SourceLocation NameLoc = Tok.getLocation();
1261 MutableArrayRef<Token> Toks(
1262 PP.getPreprocessorAllocator().Allocate<Token>(1), 1);
1263 Toks[0].startToken();
1264 Toks[0].setKind(tok::annot_pragma_captured);
1265 Toks[0].setLocation(NameLoc);
1266
1267 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
1268 /*IsReinject=*/false);
1269 }
1270
1271// Disable MSVC warning about runtime stack overflow.
1272#ifdef _MSC_VER
1273 #pragma warning(disable : 4717)
1274#endif
1275 static void DebugOverflowStack(void (*P)() = nullptr) {
1276 void (*volatile Self)(void(*P)()) = DebugOverflowStack;
1277 Self(reinterpret_cast<void(*)()>(Self));
1278 }
1279#ifdef _MSC_VER
1280 #pragma warning(default : 4717)
1281#endif
1282};
1283
1284/// PragmaDiagnosticHandler - e.g. '\#pragma GCC diagnostic ignored "-Wformat"'
1285struct PragmaDiagnosticHandler : public PragmaHandler {
1286private:
1287 const char *Namespace;
1288
1289public:
1290 explicit PragmaDiagnosticHandler(const char *NS)
1291 : PragmaHandler("diagnostic"), Namespace(NS) {}
1292
1293 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1294 Token &DiagToken) override {
1295 SourceLocation DiagLoc = DiagToken.getLocation();
1296 Token Tok;
1297 PP.LexUnexpandedToken(Tok);
1298 if (Tok.isNot(tok::identifier)) {
1299 PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1300 return;
1301 }
1302 IdentifierInfo *II = Tok.getIdentifierInfo();
1303 PPCallbacks *Callbacks = PP.getPPCallbacks();
1304
1305 if (II->isStr("pop")) {
1306 if (!PP.getDiagnostics().popMappings(DiagLoc))
1307 PP.Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
1308 else if (Callbacks)
1309 Callbacks->PragmaDiagnosticPop(DiagLoc, Namespace);
1310 return;
1311 } else if (II->isStr("push")) {
1312 PP.getDiagnostics().pushMappings(DiagLoc);
1313 if (Callbacks)
1314 Callbacks->PragmaDiagnosticPush(DiagLoc, Namespace);
1315 return;
1316 }
1317
1318 diag::Severity SV = llvm::StringSwitch<diag::Severity>(II->getName())
1319 .Case("ignored", diag::Severity::Ignored)
1320 .Case("warning", diag::Severity::Warning)
1321 .Case("error", diag::Severity::Error)
1322 .Case("fatal", diag::Severity::Fatal)
1323 .Default(diag::Severity());
1324
1325 if (SV == diag::Severity()) {
1326 PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1327 return;
1328 }
1329
1330 PP.LexUnexpandedToken(Tok);
1331 SourceLocation StringLoc = Tok.getLocation();
1332
1333 std::string WarningName;
1334 if (!PP.FinishLexStringLiteral(Tok, WarningName, "pragma diagnostic",
1335 /*AllowMacroExpansion=*/false))
1336 return;
1337
1338 if (Tok.isNot(tok::eod)) {
1339 PP.Diag(Tok.getLocation(), diag::warn_pragma_diagnostic_invalid_token);
1340 return;
1341 }
1342
1343 if (WarningName.size() < 3 || WarningName[0] != '-' ||
1344 (WarningName[1] != 'W' && WarningName[1] != 'R')) {
1345 PP.Diag(StringLoc, diag::warn_pragma_diagnostic_invalid_option);
1346 return;
1347 }
1348
1349 diag::Flavor Flavor = WarningName[1] == 'W' ? diag::Flavor::WarningOrError
1350 : diag::Flavor::Remark;
1351 StringRef Group = StringRef(WarningName).substr(2);
1352 bool unknownDiag = false;
1353 if (Group == "everything") {
1354 // Special handling for pragma clang diagnostic ... "-Weverything".
1355 // There is no formal group named "everything", so there has to be a
1356 // special case for it.
1357 PP.getDiagnostics().setSeverityForAll(Flavor, SV, DiagLoc);
1358 } else
1359 unknownDiag = PP.getDiagnostics().setSeverityForGroup(Flavor, Group, SV,
1360 DiagLoc);
1361 if (unknownDiag)
1362 PP.Diag(StringLoc, diag::warn_pragma_diagnostic_unknown_warning)
1363 << WarningName;
1364 else if (Callbacks)
1365 Callbacks->PragmaDiagnostic(DiagLoc, Namespace, SV, WarningName);
1366 }
1367};
1368
1369/// "\#pragma hdrstop [<header-name-string>]"
1370struct PragmaHdrstopHandler : public PragmaHandler {
1371 PragmaHdrstopHandler() : PragmaHandler("hdrstop") {}
1372 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1373 Token &DepToken) override {
1374 PP.HandlePragmaHdrstop(DepToken);
1375 }
1376};
1377
1378/// "\#pragma warning(...)". MSVC's diagnostics do not map cleanly to clang's
1379/// diagnostics, so we don't really implement this pragma. We parse it and
1380/// ignore it to avoid -Wunknown-pragma warnings.
1381struct PragmaWarningHandler : public PragmaHandler {
1382 PragmaWarningHandler() : PragmaHandler("warning") {}
1383
1384 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1385 Token &Tok) override {
1386 // Parse things like:
1387 // warning(push, 1)
1388 // warning(pop)
1389 // warning(disable : 1 2 3 ; error : 4 5 6 ; suppress : 7 8 9)
1390 SourceLocation DiagLoc = Tok.getLocation();
1391 PPCallbacks *Callbacks = PP.getPPCallbacks();
1392
1393 PP.Lex(Tok);
1394 if (Tok.isNot(tok::l_paren)) {
1395 PP.Diag(Tok, diag::warn_pragma_warning_expected) << "(";
1396 return;
1397 }
1398
1399 PP.Lex(Tok);
1400 IdentifierInfo *II = Tok.getIdentifierInfo();
1401
1402 if (II && II->isStr("push")) {
1403 // #pragma warning( push[ ,n ] )
1404 int Level = -1;
1405 PP.Lex(Tok);
1406 if (Tok.is(tok::comma)) {
1407 PP.Lex(Tok);
1408 uint64_t Value;
1409 if (Tok.is(tok::numeric_constant) &&
1410 PP.parseSimpleIntegerLiteral(Tok, Value))
1411 Level = int(Value);
1412 if (Level < 0 || Level > 4) {
1413 PP.Diag(Tok, diag::warn_pragma_warning_push_level);
1414 return;
1415 }
1416 }
1417 PP.getDiagnostics().pushMappings(DiagLoc);
1418 if (Callbacks)
1419 Callbacks->PragmaWarningPush(DiagLoc, Level);
1420 } else if (II && II->isStr("pop")) {
1421 // #pragma warning( pop )
1422 PP.Lex(Tok);
1423 if (!PP.getDiagnostics().popMappings(DiagLoc))
1424 PP.Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
1425 else if (Callbacks)
1426 Callbacks->PragmaWarningPop(DiagLoc);
1427 } else {
1428 // #pragma warning( warning-specifier : warning-number-list
1429 // [; warning-specifier : warning-number-list...] )
1430 while (true) {
1431 II = Tok.getIdentifierInfo();
1432 if (!II && !Tok.is(tok::numeric_constant)) {
1433 PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1434 return;
1435 }
1436
1437 // Figure out which warning specifier this is.
1438 bool SpecifierValid;
1439 PPCallbacks::PragmaWarningSpecifier Specifier;
1440 if (II) {
1441 int SpecifierInt = llvm::StringSwitch<int>(II->getName())
1442 .Case("default", PPCallbacks::PWS_Default)
1443 .Case("disable", PPCallbacks::PWS_Disable)
1444 .Case("error", PPCallbacks::PWS_Error)
1445 .Case("once", PPCallbacks::PWS_Once)
1446 .Case("suppress", PPCallbacks::PWS_Suppress)
1447 .Default(-1);
1448 if ((SpecifierValid = SpecifierInt != -1))
1449 Specifier =
1450 static_cast<PPCallbacks::PragmaWarningSpecifier>(SpecifierInt);
1451
1452 // If we read a correct specifier, snatch next token (that should be
1453 // ":", checked later).
1454 if (SpecifierValid)
1455 PP.Lex(Tok);
1456 } else {
1457 // Token is a numeric constant. It should be either 1, 2, 3 or 4.
1458 uint64_t Value;
1459 if (PP.parseSimpleIntegerLiteral(Tok, Value)) {
1460 if ((SpecifierValid = (Value >= 1) && (Value <= 4)))
1461 Specifier = static_cast<PPCallbacks::PragmaWarningSpecifier>(
1462 PPCallbacks::PWS_Level1 + Value - 1);
1463 } else
1464 SpecifierValid = false;
1465 // Next token already snatched by parseSimpleIntegerLiteral.
1466 }
1467
1468 if (!SpecifierValid) {
1469 PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1470 return;
1471 }
1472 if (Tok.isNot(tok::colon)) {
1473 PP.Diag(Tok, diag::warn_pragma_warning_expected) << ":";
1474 return;
1475 }
1476
1477 // Collect the warning ids.
1478 SmallVector<int, 4> Ids;
1479 PP.Lex(Tok);
1480 while (Tok.is(tok::numeric_constant)) {
1481 uint64_t Value;
1482 if (!PP.parseSimpleIntegerLiteral(Tok, Value) || Value == 0 ||
1483 Value > INT_MAX2147483647) {
1484 PP.Diag(Tok, diag::warn_pragma_warning_expected_number);
1485 return;
1486 }
1487 Ids.push_back(int(Value));
1488 }
1489
1490 // Only act on disable for now.
1491 diag::Severity SV = diag::Severity();
1492 if (Specifier == PPCallbacks::PWS_Disable)
1493 SV = diag::Severity::Ignored;
1494 if (SV != diag::Severity())
1495 for (int Id : Ids) {
1496 if (auto Group = diagGroupFromCLWarningID(Id)) {
1497 bool unknownDiag = PP.getDiagnostics().setSeverityForGroup(
1498 diag::Flavor::WarningOrError, *Group, SV, DiagLoc);
1499 assert(!unknownDiag &&(static_cast <bool> (!unknownDiag && "wd table should only contain known diags"
) ? void (0) : __assert_fail ("!unknownDiag && \"wd table should only contain known diags\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 1500, __extension__ __PRETTY_FUNCTION__))
1500 "wd table should only contain known diags")(static_cast <bool> (!unknownDiag && "wd table should only contain known diags"
) ? void (0) : __assert_fail ("!unknownDiag && \"wd table should only contain known diags\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 1500, __extension__ __PRETTY_FUNCTION__))
;
1501 (void)unknownDiag;
1502 }
1503 }
1504
1505 if (Callbacks)
1506 Callbacks->PragmaWarning(DiagLoc, Specifier, Ids);
1507
1508 // Parse the next specifier if there is a semicolon.
1509 if (Tok.isNot(tok::semi))
1510 break;
1511 PP.Lex(Tok);
1512 }
1513 }
1514
1515 if (Tok.isNot(tok::r_paren)) {
1516 PP.Diag(Tok, diag::warn_pragma_warning_expected) << ")";
1517 return;
1518 }
1519
1520 PP.Lex(Tok);
1521 if (Tok.isNot(tok::eod))
1522 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma warning";
1523 }
1524};
1525
1526/// "\#pragma execution_character_set(...)". MSVC supports this pragma only
1527/// for "UTF-8". We parse it and ignore it if UTF-8 is provided and warn
1528/// otherwise to avoid -Wunknown-pragma warnings.
1529struct PragmaExecCharsetHandler : public PragmaHandler {
1530 PragmaExecCharsetHandler() : PragmaHandler("execution_character_set") {}
1531
1532 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1533 Token &Tok) override {
1534 // Parse things like:
1535 // execution_character_set(push, "UTF-8")
1536 // execution_character_set(pop)
1537 SourceLocation DiagLoc = Tok.getLocation();
1538 PPCallbacks *Callbacks = PP.getPPCallbacks();
1539
1540 PP.Lex(Tok);
1541 if (Tok.isNot(tok::l_paren)) {
1542 PP.Diag(Tok, diag::warn_pragma_exec_charset_expected) << "(";
1543 return;
1544 }
1545
1546 PP.Lex(Tok);
1547 IdentifierInfo *II = Tok.getIdentifierInfo();
1548
1549 if (II && II->isStr("push")) {
1550 // #pragma execution_character_set( push[ , string ] )
1551 PP.Lex(Tok);
1552 if (Tok.is(tok::comma)) {
1553 PP.Lex(Tok);
1554
1555 std::string ExecCharset;
1556 if (!PP.FinishLexStringLiteral(Tok, ExecCharset,
1557 "pragma execution_character_set",
1558 /*AllowMacroExpansion=*/false))
1559 return;
1560
1561 // MSVC supports either of these, but nothing else.
1562 if (ExecCharset != "UTF-8" && ExecCharset != "utf-8") {
1563 PP.Diag(Tok, diag::warn_pragma_exec_charset_push_invalid) << ExecCharset;
1564 return;
1565 }
1566 }
1567 if (Callbacks)
1568 Callbacks->PragmaExecCharsetPush(DiagLoc, "UTF-8");
1569 } else if (II && II->isStr("pop")) {
1570 // #pragma execution_character_set( pop )
1571 PP.Lex(Tok);
1572 if (Callbacks)
1573 Callbacks->PragmaExecCharsetPop(DiagLoc);
1574 } else {
1575 PP.Diag(Tok, diag::warn_pragma_exec_charset_spec_invalid);
1576 return;
1577 }
1578
1579 if (Tok.isNot(tok::r_paren)) {
1580 PP.Diag(Tok, diag::warn_pragma_exec_charset_expected) << ")";
1581 return;
1582 }
1583
1584 PP.Lex(Tok);
1585 if (Tok.isNot(tok::eod))
1586 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma execution_character_set";
1587 }
1588};
1589
1590/// PragmaIncludeAliasHandler - "\#pragma include_alias("...")".
1591struct PragmaIncludeAliasHandler : public PragmaHandler {
1592 PragmaIncludeAliasHandler() : PragmaHandler("include_alias") {}
1593
1594 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1595 Token &IncludeAliasTok) override {
1596 PP.HandlePragmaIncludeAlias(IncludeAliasTok);
1597 }
1598};
1599
1600/// PragmaMessageHandler - Handle the microsoft and gcc \#pragma message
1601/// extension. The syntax is:
1602/// \code
1603/// #pragma message(string)
1604/// \endcode
1605/// OR, in GCC mode:
1606/// \code
1607/// #pragma message string
1608/// \endcode
1609/// string is a string, which is fully macro expanded, and permits string
1610/// concatenation, embedded escape characters, etc... See MSDN for more details.
1611/// Also handles \#pragma GCC warning and \#pragma GCC error which take the same
1612/// form as \#pragma message.
1613struct PragmaMessageHandler : public PragmaHandler {
1614private:
1615 const PPCallbacks::PragmaMessageKind Kind;
1616 const StringRef Namespace;
1617
1618 static const char* PragmaKind(PPCallbacks::PragmaMessageKind Kind,
1619 bool PragmaNameOnly = false) {
1620 switch (Kind) {
1621 case PPCallbacks::PMK_Message:
1622 return PragmaNameOnly ? "message" : "pragma message";
1623 case PPCallbacks::PMK_Warning:
1624 return PragmaNameOnly ? "warning" : "pragma warning";
1625 case PPCallbacks::PMK_Error:
1626 return PragmaNameOnly ? "error" : "pragma error";
1627 }
1628 llvm_unreachable("Unknown PragmaMessageKind!")::llvm::llvm_unreachable_internal("Unknown PragmaMessageKind!"
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/lib/Lex/Pragma.cpp"
, 1628)
;
1629 }
1630
1631public:
1632 PragmaMessageHandler(PPCallbacks::PragmaMessageKind Kind,
1633 StringRef Namespace = StringRef())
1634 : PragmaHandler(PragmaKind(Kind, true)), Kind(Kind),
1635 Namespace(Namespace) {}
1636
1637 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1638 Token &Tok) override {
1639 SourceLocation MessageLoc = Tok.getLocation();
1640 PP.Lex(Tok);
1641 bool ExpectClosingParen = false;
1642 switch (Tok.getKind()) {
1643 case tok::l_paren:
1644 // We have a MSVC style pragma message.
1645 ExpectClosingParen = true;
1646 // Read the string.
1647 PP.Lex(Tok);
1648 break;
1649 case tok::string_literal:
1650 // We have a GCC style pragma message, and we just read the string.
1651 break;
1652 default:
1653 PP.Diag(MessageLoc, diag::err_pragma_message_malformed) << Kind;
1654 return;
1655 }
1656
1657 std::string MessageString;
1658 if (!PP.FinishLexStringLiteral(Tok, MessageString, PragmaKind(Kind),
1659 /*AllowMacroExpansion=*/true))
1660 return;
1661
1662 if (ExpectClosingParen) {
1663 if (Tok.isNot(tok::r_paren)) {
1664 PP.Diag(Tok.getLocation(), diag::err_pragma_message_malformed) << Kind;
1665 return;
1666 }
1667 PP.Lex(Tok); // eat the r_paren.
1668 }
1669
1670 if (Tok.isNot(tok::eod)) {
1671 PP.Diag(Tok.getLocation(), diag::err_pragma_message_malformed) << Kind;
1672 return;
1673 }
1674
1675 // Output the message.
1676 PP.Diag(MessageLoc, (Kind == PPCallbacks::PMK_Error)
1677 ? diag::err_pragma_message
1678 : diag::warn_pragma_message) << MessageString;
1679
1680 // If the pragma is lexically sound, notify any interested PPCallbacks.
1681 if (PPCallbacks *Callbacks = PP.getPPCallbacks())
1682 Callbacks->PragmaMessage(MessageLoc, Namespace, Kind, MessageString);
1683 }
1684};
1685
1686/// Handle the clang \#pragma module import extension. The syntax is:
1687/// \code
1688/// #pragma clang module import some.module.name
1689/// \endcode
1690struct PragmaModuleImportHandler : public PragmaHandler {
1691 PragmaModuleImportHandler() : PragmaHandler("import") {}
1692
1693 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1694 Token &Tok) override {
1695 SourceLocation ImportLoc = Tok.getLocation();
1696
1697 // Read the module name.
1698 llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 8>
1699 ModuleName;
1700 if (LexModuleName(PP, Tok, ModuleName))
1701 return;
1702
1703 if (Tok.isNot(tok::eod))
1704 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";
1705
1706 // If we have a non-empty module path, load the named module.
1707 Module *Imported =
1708 PP.getModuleLoader().loadModule(ImportLoc, ModuleName, Module::Hidden,
1709 /*IsInclusionDirective=*/false);
1710 if (!Imported)
1711 return;
1712
1713 PP.makeModuleVisible(Imported, ImportLoc);
1714 PP.EnterAnnotationToken(SourceRange(ImportLoc, ModuleName.back().second),
1715 tok::annot_module_include, Imported);
1716 if (auto *CB = PP.getPPCallbacks())
1717 CB->moduleImport(ImportLoc, ModuleName, Imported);
1718 }
1719};
1720
1721/// Handle the clang \#pragma module begin extension. The syntax is:
1722/// \code
1723/// #pragma clang module begin some.module.name
1724/// ...
1725/// #pragma clang module end
1726/// \endcode
1727struct PragmaModuleBeginHandler : public PragmaHandler {
1728 PragmaModuleBeginHandler() : PragmaHandler("begin") {}
1729
1730 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1731 Token &Tok) override {
1732 SourceLocation BeginLoc = Tok.getLocation();
1733
1734 // Read the module name.
1735 llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 8>
1736 ModuleName;
1737 if (LexModuleName(PP, Tok, ModuleName))
1738 return;
1739
1740 if (Tok.isNot(tok::eod))
1741 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";
1742
1743 // We can only enter submodules of the current module.
1744 StringRef Current = PP.getLangOpts().CurrentModule;
1745 if (ModuleName.front().first->getName() != Current) {
1746 PP.Diag(ModuleName.front().second, diag::err_pp_module_begin_wrong_module)
1747 << ModuleName.front().first << (ModuleName.size() > 1)
1748 << Current.empty() << Current;
1749 return;
1750 }
1751
1752 // Find the module we're entering. We require that a module map for it
1753 // be loaded or implicitly loadable.
1754 auto &HSI = PP.getHeaderSearchInfo();
1755 Module *M = HSI.lookupModule(Current, ModuleName.front().second);
1756 if (!M) {
1757 PP.Diag(ModuleName.front().second,
1758 diag::err_pp_module_begin_no_module_map) << Current;
1759 return;
1760 }
1761 for (unsigned I = 1; I != ModuleName.size(); ++I) {
1762 auto *NewM = M->findOrInferSubmodule(ModuleName[I].first->getName());
1763 if (!NewM) {
1764 PP.Diag(ModuleName[I].second, diag::err_pp_module_begin_no_submodule)
1765 << M->getFullModuleName() << ModuleName[I].first;
1766 return;
1767 }
1768 M = NewM;
1769 }
1770
1771 // If the module isn't available, it doesn't make sense to enter it.
1772 if (Preprocessor::checkModuleIsAvailable(
1773 PP.getLangOpts(), PP.getTargetInfo(), PP.getDiagnostics(), M)) {
1774 PP.Diag(BeginLoc, diag::note_pp_module_begin_here)
1775 << M->getTopLevelModuleName();
1776 return;
1777 }
1778
1779 // Enter the scope of the submodule.
1780 PP.EnterSubmodule(M, BeginLoc, /*ForPragma*/true);
1781 PP.EnterAnnotationToken(SourceRange(BeginLoc, ModuleName.back().second),
1782 tok::annot_module_begin, M);
1783 }
1784};
1785
1786/// Handle the clang \#pragma module end extension.
1787struct PragmaModuleEndHandler : public PragmaHandler {
1788 PragmaModuleEndHandler() : PragmaHandler("end") {}
1789
1790 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1791 Token &Tok) override {
1792 SourceLocation Loc = Tok.getLocation();
1793
1794 PP.LexUnexpandedToken(Tok);
1795 if (Tok.isNot(tok::eod))
1796 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";
1797
1798 Module *M = PP.LeaveSubmodule(/*ForPragma*/true);
1799 if (M)
1800 PP.EnterAnnotationToken(SourceRange(Loc), tok::annot_module_end, M);
1801 else
1802 PP.Diag(Loc, diag::err_pp_module_end_without_module_begin);
1803 }
1804};
1805
1806/// Handle the clang \#pragma module build extension.
1807struct PragmaModuleBuildHandler : public PragmaHandler {
1808 PragmaModuleBuildHandler() : PragmaHandler("build") {}
1809
1810 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1811 Token &Tok) override {
1812 PP.HandlePragmaModuleBuild(Tok);
1813 }
1814};
1815
1816/// Handle the clang \#pragma module load extension.
1817struct PragmaModuleLoadHandler : public PragmaHandler {
1818 PragmaModuleLoadHandler() : PragmaHandler("load") {}
1819
1820 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1821 Token &Tok) override {
1822 SourceLocation Loc = Tok.getLocation();
1823
1824 // Read the module name.
1825 llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 8>
1826 ModuleName;
1827 if (LexModuleName(PP, Tok, ModuleName))
1828 return;
1829
1830 if (Tok.isNot(tok::eod))
1831 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";
1832
1833 // Load the module, don't make it visible.
1834 PP.getModuleLoader().loadModule(Loc, ModuleName, Module::Hidden,
1835 /*IsInclusionDirective=*/false);
1836 }
1837};
1838
1839/// PragmaPushMacroHandler - "\#pragma push_macro" saves the value of the
1840/// macro on the top of the stack.
1841struct PragmaPushMacroHandler : public PragmaHandler {
1842 PragmaPushMacroHandler() : PragmaHandler("push_macro") {}
1843
1844 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1845 Token &PushMacroTok) override {
1846 PP.HandlePragmaPushMacro(PushMacroTok);
1847 }
1848};
1849
1850/// PragmaPopMacroHandler - "\#pragma pop_macro" sets the value of the
1851/// macro to the value on the top of the stack.
1852struct PragmaPopMacroHandler : public PragmaHandler {
1853 PragmaPopMacroHandler() : PragmaHandler("pop_macro") {}
1854
1855 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1856 Token &PopMacroTok) override {
1857 PP.HandlePragmaPopMacro(PopMacroTok);
1858 }
1859};
1860
1861/// PragmaARCCFCodeAuditedHandler -
1862/// \#pragma clang arc_cf_code_audited begin/end
1863struct PragmaARCCFCodeAuditedHandler : public PragmaHandler {
1864 PragmaARCCFCodeAuditedHandler() : PragmaHandler("arc_cf_code_audited") {}
1865
1866 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1867 Token &NameTok) override {
1868 SourceLocation Loc = NameTok.getLocation();
1869 bool IsBegin;
1870
1871 Token Tok;
1872
1873 // Lex the 'begin' or 'end'.
1874 PP.LexUnexpandedToken(Tok);
1875 const IdentifierInfo *BeginEnd = Tok.getIdentifierInfo();
1876 if (BeginEnd && BeginEnd->isStr("begin")) {
1877 IsBegin = true;
1878 } else if (BeginEnd && BeginEnd->isStr("end")) {
1879 IsBegin = false;
1880 } else {
1881 PP.Diag(Tok.getLocation(), diag::err_pp_arc_cf_code_audited_syntax);
1882 return;
1883 }
1884
1885 // Verify that this is followed by EOD.
1886 PP.LexUnexpandedToken(Tok);
1887 if (Tok.isNot(tok::eod))
1888 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";
1889
1890 // The start location of the active audit.
1891 SourceLocation BeginLoc = PP.getPragmaARCCFCodeAuditedInfo().second;
1892
1893 // The start location we want after processing this.
1894 SourceLocation NewLoc;
1895
1896 if (IsBegin) {
1897 // Complain about attempts to re-enter an audit.
1898 if (BeginLoc.isValid()) {
1899 PP.Diag(Loc, diag::err_pp_double_begin_of_arc_cf_code_audited);
1900 PP.Diag(BeginLoc, diag::note_pragma_entered_here);
1901 }
1902 NewLoc = Loc;
1903 } else {
1904 // Complain about attempts to leave an audit that doesn't exist.
1905 if (!BeginLoc.isValid()) {
1906 PP.Diag(Loc, diag::err_pp_unmatched_end_of_arc_cf_code_audited);
1907 return;
1908 }
1909 NewLoc = SourceLocation();
1910 }
1911
1912 PP.setPragmaARCCFCodeAuditedInfo(NameTok.getIdentifierInfo(), NewLoc);
1913 }
1914};
1915
1916/// PragmaAssumeNonNullHandler -
1917/// \#pragma clang assume_nonnull begin/end
1918struct PragmaAssumeNonNullHandler : public PragmaHandler {
1919 PragmaAssumeNonNullHandler() : PragmaHandler("assume_nonnull") {}
1920
1921 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1922 Token &NameTok) override {
1923 SourceLocation Loc = NameTok.getLocation();
1924 bool IsBegin;
1925
1926 Token Tok;
1927
1928 // Lex the 'begin' or 'end'.
1929 PP.LexUnexpandedToken(Tok);
1930 const IdentifierInfo *BeginEnd = Tok.getIdentifierInfo();
1931 if (BeginEnd && BeginEnd->isStr("begin")) {
1932 IsBegin = true;
1933 } else if (BeginEnd && BeginEnd->isStr("end")) {
1934 IsBegin = false;
1935 } else {
1936 PP.Diag(Tok.getLocation(), diag::err_pp_assume_nonnull_syntax);
1937 return;
1938 }
1939
1940 // Verify that this is followed by EOD.
1941 PP.LexUnexpandedToken(Tok);
1942 if (Tok.isNot(tok::eod))
1943 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";
1944
1945 // The start location of the active audit.
1946 SourceLocation BeginLoc = PP.getPragmaAssumeNonNullLoc();
1947
1948 // The start location we want after processing this.
1949 SourceLocation NewLoc;
1950 PPCallbacks *Callbacks = PP.getPPCallbacks();
1951
1952 if (IsBegin) {
1953 // Complain about attempts to re-enter an audit.
1954 if (BeginLoc.isValid()) {
1955 PP.Diag(Loc, diag::err_pp_double_begin_of_assume_nonnull);
1956 PP.Diag(BeginLoc, diag::note_pragma_entered_here);
1957 }
1958 NewLoc = Loc;
1959 if (Callbacks)
1960 Callbacks->PragmaAssumeNonNullBegin(NewLoc);
1961 } else {
1962 // Complain about attempts to leave an audit that doesn't exist.
1963 if (!BeginLoc.isValid()) {
1964 PP.Diag(Loc, diag::err_pp_unmatched_end_of_assume_nonnull);
1965 return;
1966 }
1967 NewLoc = SourceLocation();
1968 if (Callbacks)
1969 Callbacks->PragmaAssumeNonNullEnd(NewLoc);
1970 }
1971
1972 PP.setPragmaAssumeNonNullLoc(NewLoc);
1973 }
1974};
1975
1976/// Handle "\#pragma region [...]"
1977///
1978/// The syntax is
1979/// \code
1980/// #pragma region [optional name]
1981/// #pragma endregion [optional comment]
1982/// \endcode
1983///
1984/// \note This is
1985/// <a href="http://msdn.microsoft.com/en-us/library/b6xkz944(v=vs.80).aspx">editor-only</a>
1986/// pragma, just skipped by compiler.
1987struct PragmaRegionHandler : public PragmaHandler {
1988 PragmaRegionHandler(const char *pragma) : PragmaHandler(pragma) {}
1989
1990 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
1991 Token &NameTok) override {
1992 // #pragma region: endregion matches can be verified
1993 // __pragma(region): no sense, but ignored by msvc
1994 // _Pragma is not valid for MSVC, but there isn't any point
1995 // to handle a _Pragma differently.
1996 }
1997};
1998
1999/// This handles parsing pragmas that take a macro name and optional message
2000static IdentifierInfo *HandleMacroAnnotationPragma(Preprocessor &PP, Token &Tok,
2001 const char *Pragma,
2002 std::string &MessageString) {
2003 std::string Macro;
2004
2005 PP.Lex(Tok);
2006 if (Tok.isNot(tok::l_paren)) {
2007 PP.Diag(Tok, diag::err_expected) << "(";
2008 return nullptr;
2009 }
2010
2011 PP.LexUnexpandedToken(Tok);
2012 if (!Tok.is(tok::identifier)) {
2013 PP.Diag(Tok, diag::err_expected) << tok::identifier;
2014 return nullptr;
2015 }
2016 IdentifierInfo *II = Tok.getIdentifierInfo();
2017
2018 if (!II->hasMacroDefinition()) {
2019 PP.Diag(Tok, diag::err_pp_visibility_non_macro) << II;
2020 return nullptr;
2021 }
2022
2023 PP.Lex(Tok);
2024 if (Tok.is(tok::comma)) {
2025 PP.Lex(Tok);
2026 if (!PP.FinishLexStringLiteral(Tok, MessageString, Pragma,
2027 /*AllowMacroExpansion=*/true))
2028 return nullptr;
2029 }
2030
2031 if (Tok.isNot(tok::r_paren)) {
2032 PP.Diag(Tok, diag::err_expected) << ")";
2033 return nullptr;
2034 }
2035 return II;
2036}
2037
2038/// "\#pragma clang deprecated(...)"
2039///
2040/// The syntax is
2041/// \code
2042/// #pragma clang deprecate(MACRO_NAME [, Message])
2043/// \endcode
2044struct PragmaDeprecatedHandler : public PragmaHandler {
2045 PragmaDeprecatedHandler() : PragmaHandler("deprecated") {}
2046
2047 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
2048 Token &Tok) override {
2049 std::string MessageString;
2050
2051 if (IdentifierInfo *II = HandleMacroAnnotationPragma(
2052 PP, Tok, "#pragma clang deprecated", MessageString)) {
2053 II->setIsDeprecatedMacro(true);
2054 PP.addMacroDeprecationMsg(II, std::move(MessageString),
2055 Tok.getLocation());
2056 }
2057 }
2058};
2059
2060/// "\#pragma clang restrict_expansion(...)"
2061///
2062/// The syntax is
2063/// \code
2064/// #pragma clang restrict_expansion(MACRO_NAME [, Message])
2065/// \endcode
2066struct PragmaRestrictExpansionHandler : public PragmaHandler {
2067 PragmaRestrictExpansionHandler() : PragmaHandler("restrict_expansion") {}
2068
2069 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
2070 Token &Tok) override {
2071 std::string MessageString;
2072
2073 if (IdentifierInfo *II = HandleMacroAnnotationPragma(
2074 PP, Tok, "#pragma clang restrict_expansion", MessageString)) {
2075 II->setIsRestrictExpansion(true);
2076 PP.addRestrictExpansionMsg(II, std::move(MessageString),
2077 Tok.getLocation());
2078 }
2079 }
2080};
2081
2082/// "\#pragma clang final(...)"
2083///
2084/// The syntax is
2085/// \code
2086/// #pragma clang final(MACRO_NAME)
2087/// \endcode
2088struct PragmaFinalHandler : public PragmaHandler {
2089 PragmaFinalHandler() : PragmaHandler("final") {}
2090
2091 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
2092 Token &Tok) override {
2093 std::string Macro;
2094
2095 PP.Lex(Tok);
2096 if (Tok.isNot(tok::l_paren)) {
2097 PP.Diag(Tok, diag::err_expected) << "(";
2098 return;
2099 }
2100
2101 PP.LexUnexpandedToken(Tok);
2102 if (!Tok.is(tok::identifier)) {
2103 PP.Diag(Tok, diag::err_expected) << tok::identifier;
2104 return;
2105 }
2106 IdentifierInfo *II = Tok.getIdentifierInfo();
2107
2108 if (!II->hasMacroDefinition()) {
2109 PP.Diag(Tok, diag::err_pp_visibility_non_macro) << II;
2110 return;
2111 }
2112
2113 PP.Lex(Tok);
2114 if (Tok.isNot(tok::r_paren)) {
2115 PP.Diag(Tok, diag::err_expected) << ")";
2116 return;
2117 }
2118 II->setIsFinal(true);
2119 PP.addFinalLoc(II, Tok.getLocation());
2120 }
2121};
2122
2123} // namespace
2124
2125/// RegisterBuiltinPragmas - Install the standard preprocessor pragmas:
2126/// \#pragma GCC poison/system_header/dependency and \#pragma once.
2127void Preprocessor::RegisterBuiltinPragmas() {
2128 AddPragmaHandler(new PragmaOnceHandler());
2129 AddPragmaHandler(new PragmaMarkHandler());
2130 AddPragmaHandler(new PragmaPushMacroHandler());
2131 AddPragmaHandler(new PragmaPopMacroHandler());
2132 AddPragmaHandler(new PragmaMessageHandler(PPCallbacks::PMK_Message));
2133
2134 // #pragma GCC ...
2135 AddPragmaHandler("GCC", new PragmaPoisonHandler());
2136 AddPragmaHandler("GCC", new PragmaSystemHeaderHandler());
2137 AddPragmaHandler("GCC", new PragmaDependencyHandler());
2138 AddPragmaHandler("GCC", new PragmaDiagnosticHandler("GCC"));
2139 AddPragmaHandler("GCC", new PragmaMessageHandler(PPCallbacks::PMK_Warning,
2140 "GCC"));
2141 AddPragmaHandler("GCC", new PragmaMessageHandler(PPCallbacks::PMK_Error,
2142 "GCC"));
2143 // #pragma clang ...
2144 AddPragmaHandler("clang", new PragmaPoisonHandler());
2145 AddPragmaHandler("clang", new PragmaSystemHeaderHandler());
2146 AddPragmaHandler("clang", new PragmaIncludeInsteadHandler());
2147 AddPragmaHandler("clang", new PragmaDebugHandler());
2148 AddPragmaHandler("clang", new PragmaDependencyHandler());
2149 AddPragmaHandler("clang", new PragmaDiagnosticHandler("clang"));
2150 AddPragmaHandler("clang", new PragmaARCCFCodeAuditedHandler());
2151 AddPragmaHandler("clang", new PragmaAssumeNonNullHandler());
2152 AddPragmaHandler("clang", new PragmaDeprecatedHandler());
2153 AddPragmaHandler("clang", new PragmaRestrictExpansionHandler());
2154 AddPragmaHandler("clang", new PragmaFinalHandler());
2155
2156 // #pragma clang module ...
2157 auto *ModuleHandler = new PragmaNamespace("module");
2158 AddPragmaHandler("clang", ModuleHandler);
2159 ModuleHandler->AddPragma(new PragmaModuleImportHandler());
2160 ModuleHandler->AddPragma(new PragmaModuleBeginHandler());
2161 ModuleHandler->AddPragma(new PragmaModuleEndHandler());
2162 ModuleHandler->AddPragma(new PragmaModuleBuildHandler());
2163 ModuleHandler->AddPragma(new PragmaModuleLoadHandler());
2164
2165 // Add region pragmas.
2166 AddPragmaHandler(new PragmaRegionHandler("region"));
2167 AddPragmaHandler(new PragmaRegionHandler("endregion"));
2168
2169 // MS extensions.
2170 if (LangOpts.MicrosoftExt) {
2171 AddPragmaHandler(new PragmaWarningHandler());
2172 AddPragmaHandler(new PragmaExecCharsetHandler());
2173 AddPragmaHandler(new PragmaIncludeAliasHandler());
2174 AddPragmaHandler(new PragmaHdrstopHandler());
2175 AddPragmaHandler(new PragmaSystemHeaderHandler());
2176 }
2177
2178 // Pragmas added by plugins
2179 for (const PragmaHandlerRegistry::entry &handler :
2180 PragmaHandlerRegistry::entries()) {
2181 AddPragmaHandler(handler.instantiate().release());
2182 }
2183}
2184
2185/// Ignore all pragmas, useful for modes such as -Eonly which would otherwise
2186/// warn about those pragmas being unknown.
2187void Preprocessor::IgnorePragmas() {
2188 AddPragmaHandler(new EmptyPragmaHandler());
2189 // Also ignore all pragmas in all namespaces created
2190 // in Preprocessor::RegisterBuiltinPragmas().
2191 AddPragmaHandler("GCC", new EmptyPragmaHandler());
2192 AddPragmaHandler("clang", new EmptyPragmaHandler());
2193}

/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Lex/Token.h

1//===--- Token.h - Token interface ------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the Token interface.
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
21namespace clang {
22
23class IdentifierInfo;
24
25/// Token - This structure provides full information about a lexed token.
26/// It is not intended to be space efficient, it is intended to return as much
27/// information as possible about each returned token. This is expected to be
28/// compressed into a smaller form if memory footprint is important.
29///
30/// The parser can create a special "annotation token" representing a stream of
31/// tokens that were parsed and semantically resolved, e.g.: "foo::MyClass<int>"
32/// can be represented by a single typename annotation token that carries
33/// information about the SourceRange of the tokens and the type object.
34class Token {
35 /// The location of the token. This is actually a SourceLocation.
36 SourceLocation::UIntTy Loc;
37
38 // Conceptually these next two fields could be in a union. However, this
39 // causes gcc 4.2 to pessimize LexTokenInternal, a very performance critical
40 // routine. Keeping as separate members with casts until a more beautiful fix
41 // presents itself.
42
43 /// UintData - This holds either the length of the token text, when
44 /// a normal token, or the end of the SourceRange when an annotation
45 /// token.
46 SourceLocation::UIntTy UintData;
47
48 /// PtrData - This is a union of four different pointer types, which depends
49 /// on what type of token this is:
50 /// Identifiers, keywords, etc:
51 /// This is an IdentifierInfo*, which contains the uniqued identifier
52 /// spelling.
53 /// Literals: isLiteral() returns true.
54 /// This is a pointer to the start of the token in a text buffer, which
55 /// may be dirty (have trigraphs / escaped newlines).
56 /// Annotations (resolved type names, C++ scopes, etc): isAnnotation().
57 /// This is a pointer to sema-specific data for the annotation token.
58 /// Eof:
59 // This is a pointer to a Decl.
60 /// Other:
61 /// This is null.
62 void *PtrData;
63
64 /// Kind - The actual flavor of token this is.
65 tok::TokenKind Kind;
66
67 /// Flags - Bits we track about this token, members of the TokenFlags enum.
68 unsigned short Flags;
69
70public:
71 // Various flags set per token:
72 enum TokenFlags {
73 StartOfLine = 0x01, // At start of line or only after whitespace
74 // (considering the line after macro expansion).
75 LeadingSpace = 0x02, // Whitespace exists before this token (considering
76 // whitespace after macro expansion).
77 DisableExpand = 0x04, // This identifier may never be macro expanded.
78 NeedsCleaning = 0x08, // Contained an escaped newline or trigraph.
79 LeadingEmptyMacro = 0x10, // Empty macro exists before this token.
80 HasUDSuffix = 0x20, // This string or character literal has a ud-suffix.
81 HasUCN = 0x40, // This identifier contains a UCN.
82 IgnoredComma = 0x80, // This comma is not a macro argument separator (MS).
83 StringifiedInMacro = 0x100, // This string or character literal is formed by
84 // macro stringizing or charizing operator.
85 CommaAfterElided = 0x200, // The comma following this token was elided (MS).
86 IsEditorPlaceholder = 0x400, // This identifier is a placeholder.
87 IsReinjected = 0x800, // A phase 4 token that was produced before and
88 // re-added, e.g. via EnterTokenStream. Annotation
89 // tokens are *not* reinjected.
90 };
91
92 tok::TokenKind getKind() const { return Kind; }
93 void setKind(tok::TokenKind K) { Kind = K; }
94
95 /// is/isNot - Predicates to check if this token is a specific kind, as in
96 /// "if (Tok.is(tok::l_brace)) {...}".
97 bool is(tok::TokenKind K) const { return Kind == K; }
98 bool isNot(tok::TokenKind K) const { return Kind != K; }
2
Assuming 'K' is equal to field 'Kind'
3
Returning zero, which participates in a condition later
99 bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const {
100 return is(K1) || is(K2);
101 }
102 template <typename... Ts>
103 bool isOneOf(tok::TokenKind K1, tok::TokenKind K2, Ts... Ks) const {
104 return is(K1) || isOneOf(K2, Ks...);
105 }
106
107 /// Return true if this is a raw identifier (when lexing
108 /// in raw mode) or a non-keyword identifier (when lexing in non-raw mode).
109 bool isAnyIdentifier() const {
110 return tok::isAnyIdentifier(getKind());
111 }
112
113 /// Return true if this is a "literal", like a numeric
114 /// constant, string, etc.
115 bool isLiteral() const {
116 return tok::isLiteral(getKind());
117 }
118
119 /// Return true if this is any of tok::annot_* kind tokens.
120 bool isAnnotation() const {
121 return tok::isAnnotation(getKind());
122 }
123
124 /// Return a source location identifier for the specified
125 /// offset in the current file.
126 SourceLocation getLocation() const {
127 return SourceLocation::getFromRawEncoding(Loc);
128 }
129 unsigned getLength() const {
130 assert(!isAnnotation() && "Annotation tokens have no length field")(static_cast <bool> (!isAnnotation() && "Annotation tokens have no length field"
) ? void (0) : __assert_fail ("!isAnnotation() && \"Annotation tokens have no length field\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Lex/Token.h"
, 130, __extension__ __PRETTY_FUNCTION__))
;
131 return UintData;
132 }
133
134 void setLocation(SourceLocation L) { Loc = L.getRawEncoding(); }
135 void setLength(unsigned Len) {
136 assert(!isAnnotation() && "Annotation tokens have no length field")(static_cast <bool> (!isAnnotation() && "Annotation tokens have no length field"
) ? void (0) : __assert_fail ("!isAnnotation() && \"Annotation tokens have no length field\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Lex/Token.h"
, 136, __extension__ __PRETTY_FUNCTION__))
;
137 UintData = Len;
138 }
139
140 SourceLocation getAnnotationEndLoc() const {
141 assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token")(static_cast <bool> (isAnnotation() && "Used AnnotEndLocID on non-annotation token"
) ? void (0) : __assert_fail ("isAnnotation() && \"Used AnnotEndLocID on non-annotation token\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Lex/Token.h"
, 141, __extension__ __PRETTY_FUNCTION__))
;
142 return SourceLocation::getFromRawEncoding(UintData ? UintData : Loc);
143 }
144 void setAnnotationEndLoc(SourceLocation L) {
145 assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token")(static_cast <bool> (isAnnotation() && "Used AnnotEndLocID on non-annotation token"
) ? void (0) : __assert_fail ("isAnnotation() && \"Used AnnotEndLocID on non-annotation token\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Lex/Token.h"
, 145, __extension__ __PRETTY_FUNCTION__))
;
146 UintData = L.getRawEncoding();
147 }
148
149 SourceLocation getLastLoc() const {
150 return isAnnotation() ? getAnnotationEndLoc() : getLocation();
151 }
152
153 SourceLocation getEndLoc() const {
154 return isAnnotation() ? getAnnotationEndLoc()
155 : getLocation().getLocWithOffset(getLength());
156 }
157
158 /// SourceRange of the group of tokens that this annotation token
159 /// represents.
160 SourceRange getAnnotationRange() const {
161 return SourceRange(getLocation(), getAnnotationEndLoc());
162 }
163 void setAnnotationRange(SourceRange R) {
164 setLocation(R.getBegin());
165 setAnnotationEndLoc(R.getEnd());
166 }
167
168 const char *getName() const { return tok::getTokenName(Kind); }
169
170 /// Reset all flags to cleared.
171 void startToken() {
172 Kind = tok::unknown;
173 Flags = 0;
174 PtrData = nullptr;
175 UintData = 0;
176 Loc = SourceLocation().getRawEncoding();
177 }
178
179 IdentifierInfo *getIdentifierInfo() const {
180 assert(isNot(tok::raw_identifier) &&(static_cast <bool> (isNot(tok::raw_identifier) &&
"getIdentifierInfo() on a tok::raw_identifier token!") ? void
(0) : __assert_fail ("isNot(tok::raw_identifier) && \"getIdentifierInfo() on a tok::raw_identifier token!\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Lex/Token.h"
, 181, __extension__ __PRETTY_FUNCTION__))
181 "getIdentifierInfo() on a tok::raw_identifier token!")(static_cast <bool> (isNot(tok::raw_identifier) &&
"getIdentifierInfo() on a tok::raw_identifier token!") ? void
(0) : __assert_fail ("isNot(tok::raw_identifier) && \"getIdentifierInfo() on a tok::raw_identifier token!\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Lex/Token.h"
, 181, __extension__ __PRETTY_FUNCTION__))
;
182 assert(!isAnnotation() &&(static_cast <bool> (!isAnnotation() && "getIdentifierInfo() on an annotation token!"
) ? void (0) : __assert_fail ("!isAnnotation() && \"getIdentifierInfo() on an annotation token!\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Lex/Token.h"
, 183, __extension__ __PRETTY_FUNCTION__))
183 "getIdentifierInfo() on an annotation token!")(static_cast <bool> (!isAnnotation() && "getIdentifierInfo() on an annotation token!"
) ? void (0) : __assert_fail ("!isAnnotation() && \"getIdentifierInfo() on an annotation token!\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Lex/Token.h"
, 183, __extension__ __PRETTY_FUNCTION__))
;
184 if (isLiteral()) return nullptr;
185 if (is(tok::eof)) return nullptr;
186 return (IdentifierInfo*) PtrData;
187 }
188 void setIdentifierInfo(IdentifierInfo *II) {
189 PtrData = (void*) II;
190 }
191
192 const void *getEofData() const {
193 assert(is(tok::eof))(static_cast <bool> (is(tok::eof)) ? void (0) : __assert_fail
("is(tok::eof)", "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Lex/Token.h"
, 193, __extension__ __PRETTY_FUNCTION__))
;
194 return reinterpret_cast<const void *>(PtrData);
195 }
196 void setEofData(const void *D) {
197 assert(is(tok::eof))(static_cast <bool> (is(tok::eof)) ? void (0) : __assert_fail
("is(tok::eof)", "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Lex/Token.h"
, 197, __extension__ __PRETTY_FUNCTION__))
;
198 assert(!PtrData)(static_cast <bool> (!PtrData) ? void (0) : __assert_fail
("!PtrData", "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Lex/Token.h"
, 198, __extension__ __PRETTY_FUNCTION__))
;
199 PtrData = const_cast<void *>(D);
200 }
201
202 /// getRawIdentifier - For a raw identifier token (i.e., an identifier
203 /// lexed in raw mode), returns a reference to the text substring in the
204 /// buffer if known.
205 StringRef getRawIdentifier() const {
206 assert(is(tok::raw_identifier))(static_cast <bool> (is(tok::raw_identifier)) ? void (0
) : __assert_fail ("is(tok::raw_identifier)", "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Lex/Token.h"
, 206, __extension__ __PRETTY_FUNCTION__))
;
207 return StringRef(reinterpret_cast<const char *>(PtrData), getLength());
208 }
209 void setRawIdentifierData(const char *Ptr) {
210 assert(is(tok::raw_identifier))(static_cast <bool> (is(tok::raw_identifier)) ? void (0
) : __assert_fail ("is(tok::raw_identifier)", "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Lex/Token.h"
, 210, __extension__ __PRETTY_FUNCTION__))
;
211 PtrData = const_cast<char*>(Ptr);
212 }
213
214 /// getLiteralData - For a literal token (numeric constant, string, etc), this
215 /// returns a pointer to the start of it in the text buffer if known, null
216 /// otherwise.
217 const char *getLiteralData() const {
218 assert(isLiteral() && "Cannot get literal data of non-literal")(static_cast <bool> (isLiteral() && "Cannot get literal data of non-literal"
) ? void (0) : __assert_fail ("isLiteral() && \"Cannot get literal data of non-literal\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Lex/Token.h"
, 218, __extension__ __PRETTY_FUNCTION__))
;
219 return reinterpret_cast<const char*>(PtrData);
220 }
221 void setLiteralData(const char *Ptr) {
222 assert(isLiteral() && "Cannot set literal data of non-literal")(static_cast <bool> (isLiteral() && "Cannot set literal data of non-literal"
) ? void (0) : __assert_fail ("isLiteral() && \"Cannot set literal data of non-literal\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Lex/Token.h"
, 222, __extension__ __PRETTY_FUNCTION__))
;
223 PtrData = const_cast<char*>(Ptr);
224 }
225
226 void *getAnnotationValue() const {
227 assert(isAnnotation() && "Used AnnotVal on non-annotation token")(static_cast <bool> (isAnnotation() && "Used AnnotVal on non-annotation token"
) ? void (0) : __assert_fail ("isAnnotation() && \"Used AnnotVal on non-annotation token\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Lex/Token.h"
, 227, __extension__ __PRETTY_FUNCTION__))
;
228 return PtrData;
229 }
230 void setAnnotationValue(void *val) {
231 assert(isAnnotation() && "Used AnnotVal on non-annotation token")(static_cast <bool> (isAnnotation() && "Used AnnotVal on non-annotation token"
) ? void (0) : __assert_fail ("isAnnotation() && \"Used AnnotVal on non-annotation token\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Lex/Token.h"
, 231, __extension__ __PRETTY_FUNCTION__))
;
232 PtrData = val;
233 }
234
235 /// Set the specified flag.
236 void setFlag(TokenFlags Flag) {
237 Flags |= Flag;
238 }
239
240 /// Get the specified flag.
241 bool getFlag(TokenFlags Flag) const {
242 return (Flags & Flag) != 0;
243 }
244
245 /// Unset the specified flag.
246 void clearFlag(TokenFlags Flag) {
247 Flags &= ~Flag;
248 }
249
250 /// Return the internal represtation of the flags.
251 ///
252 /// This is only intended for low-level operations such as writing tokens to
253 /// disk.
254 unsigned getFlags() const {
255 return Flags;
256 }
257
258 /// Set a flag to either true or false.
259 void setFlagValue(TokenFlags Flag, bool Val) {
260 if (Val)
261 setFlag(Flag);
262 else
263 clearFlag(Flag);
264 }
265
266 /// isAtStartOfLine - Return true if this token is at the start of a line.
267 ///
268 bool isAtStartOfLine() const { return getFlag(StartOfLine); }
269
270 /// Return true if this token has whitespace before it.
271 ///
272 bool hasLeadingSpace() const { return getFlag(LeadingSpace); }
273
274 /// Return true if this identifier token should never
275 /// be expanded in the future, due to C99 6.10.3.4p2.
276 bool isExpandDisabled() const { return getFlag(DisableExpand); }
277
278 /// Return true if we have an ObjC keyword identifier.
279 bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const;
280
281 /// Return the ObjC keyword kind.
282 tok::ObjCKeywordKind getObjCKeywordID() const;
283
284 /// Return true if this token has trigraphs or escaped newlines in it.
285 bool needsCleaning() const { return getFlag(NeedsCleaning); }
286
287 /// Return true if this token has an empty macro before it.
288 ///
289 bool hasLeadingEmptyMacro() const { return getFlag(LeadingEmptyMacro); }
290
291 /// Return true if this token is a string or character literal which
292 /// has a ud-suffix.
293 bool hasUDSuffix() const { return getFlag(HasUDSuffix); }
294
295 /// Returns true if this token contains a universal character name.
296 bool hasUCN() const { return getFlag(HasUCN); }
297
298 /// Returns true if this token is formed by macro by stringizing or charizing
299 /// operator.
300 bool stringifiedInMacro() const { return getFlag(StringifiedInMacro); }
301
302 /// Returns true if the comma after this token was elided.
303 bool commaAfterElided() const { return getFlag(CommaAfterElided); }
304
305 /// Returns true if this token is an editor placeholder.
306 ///
307 /// Editor placeholders are produced by the code-completion engine and are
308 /// represented as characters between '<#' and '#>' in the source code. The
309 /// lexer uses identifier tokens to represent placeholders.
310 bool isEditorPlaceholder() const { return getFlag(IsEditorPlaceholder); }
311};
312
313/// Information about the conditional stack (\#if directives)
314/// currently active.
315struct PPConditionalInfo {
316 /// Location where the conditional started.
317 SourceLocation IfLoc;
318
319 /// True if this was contained in a skipping directive, e.g.,
320 /// in a "\#if 0" block.
321 bool WasSkipping;
322
323 /// True if we have emitted tokens already, and now we're in
324 /// an \#else block or something. Only useful in Skipping blocks.
325 bool FoundNonSkip;
326
327 /// True if we've seen a \#else in this block. If so,
328 /// \#elif/\#else directives are not allowed.
329 bool FoundElse;
330};
331
332} // end namespace clang
333
334#endif // LLVM_CLANG_LEX_TOKEN_H

/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Basic/IdentifierTable.h

1//===- IdentifierTable.h - Hash table for identifier lookup -----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file
10/// Defines the clang::IdentifierInfo, clang::IdentifierTable, and
11/// clang::Selector interfaces.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
16#define LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
17
18#include "clang/Basic/LLVM.h"
19#include "clang/Basic/TokenKinds.h"
20#include "llvm/ADT/DenseMapInfo.h"
21#include "llvm/ADT/SmallString.h"
22#include "llvm/ADT/StringMap.h"
23#include "llvm/ADT/StringRef.h"
24#include "llvm/Support/Allocator.h"
25#include "llvm/Support/PointerLikeTypeTraits.h"
26#include "llvm/Support/type_traits.h"
27#include <cassert>
28#include <cstddef>
29#include <cstdint>
30#include <cstring>
31#include <string>
32#include <utility>
33
34namespace clang {
35
36class DeclarationName;
37class DeclarationNameTable;
38class IdentifierInfo;
39class LangOptions;
40class MultiKeywordSelector;
41class SourceLocation;
42
43enum class ReservedIdentifierStatus {
44 NotReserved = 0,
45 StartsWithUnderscoreAtGlobalScope,
46 StartsWithUnderscoreAndIsExternC,
47 StartsWithDoubleUnderscore,
48 StartsWithUnderscoreFollowedByCapitalLetter,
49 ContainsDoubleUnderscore,
50};
51
52/// Determine whether an identifier is reserved for use as a name at global
53/// scope. Such identifiers might be implementation-specific global functions
54/// or variables.
55inline bool isReservedAtGlobalScope(ReservedIdentifierStatus Status) {
56 return Status != ReservedIdentifierStatus::NotReserved;
57}
58
59/// Determine whether an identifier is reserved in all contexts. Such
60/// identifiers might be implementation-specific keywords or macros, for
61/// example.
62inline bool isReservedInAllContexts(ReservedIdentifierStatus Status) {
63 return Status != ReservedIdentifierStatus::NotReserved &&
64 Status != ReservedIdentifierStatus::StartsWithUnderscoreAtGlobalScope &&
65 Status != ReservedIdentifierStatus::StartsWithUnderscoreAndIsExternC;
66}
67
68/// A simple pair of identifier info and location.
69using IdentifierLocPair = std::pair<IdentifierInfo *, SourceLocation>;
70
71/// IdentifierInfo and other related classes are aligned to
72/// 8 bytes so that DeclarationName can use the lower 3 bits
73/// of a pointer to one of these classes.
74enum { IdentifierInfoAlignment = 8 };
75
76static constexpr int ObjCOrBuiltinIDBits = 16;
77
78/// One of these records is kept for each identifier that
79/// is lexed. This contains information about whether the token was \#define'd,
80/// is a language keyword, or if it is a front-end token of some sort (e.g. a
81/// variable or function name). The preprocessor keeps this information in a
82/// set, and all tok::identifier tokens have a pointer to one of these.
83/// It is aligned to 8 bytes because DeclarationName needs the lower 3 bits.
84class alignas(IdentifierInfoAlignment) IdentifierInfo {
85 friend class IdentifierTable;
86
87 // Front-end token ID or tok::identifier.
88 unsigned TokenID : 9;
89
90 // ObjC keyword ('protocol' in '@protocol') or builtin (__builtin_inf).
91 // First NUM_OBJC_KEYWORDS values are for Objective-C,
92 // the remaining values are for builtins.
93 unsigned ObjCOrBuiltinID : ObjCOrBuiltinIDBits;
94
95 // True if there is a #define for this.
96 unsigned HasMacro : 1;
97
98 // True if there was a #define for this.
99 unsigned HadMacro : 1;
100
101 // True if the identifier is a language extension.
102 unsigned IsExtension : 1;
103
104 // True if the identifier is a keyword in a newer or proposed Standard.
105 unsigned IsFutureCompatKeyword : 1;
106
107 // True if the identifier is poisoned.
108 unsigned IsPoisoned : 1;
109
110 // True if the identifier is a C++ operator keyword.
111 unsigned IsCPPOperatorKeyword : 1;
112
113 // Internal bit set by the member function RecomputeNeedsHandleIdentifier.
114 // See comment about RecomputeNeedsHandleIdentifier for more info.
115 unsigned NeedsHandleIdentifier : 1;
116
117 // True if the identifier was loaded (at least partially) from an AST file.
118 unsigned IsFromAST : 1;
119
120 // True if the identifier has changed from the definition
121 // loaded from an AST file.
122 unsigned ChangedAfterLoad : 1;
123
124 // True if the identifier's frontend information has changed from the
125 // definition loaded from an AST file.
126 unsigned FEChangedAfterLoad : 1;
127
128 // True if revertTokenIDToIdentifier was called.
129 unsigned RevertedTokenID : 1;
130
131 // True if there may be additional information about
132 // this identifier stored externally.
133 unsigned OutOfDate : 1;
134
135 // True if this is the 'import' contextual keyword.
136 unsigned IsModulesImport : 1;
137
138 // True if this is a mangled OpenMP variant name.
139 unsigned IsMangledOpenMPVariantName : 1;
140
141 // True if this is a deprecated macro.
142 unsigned IsDeprecatedMacro : 1;
143
144 // True if this macro is unsafe in headers.
145 unsigned IsRestrictExpansion : 1;
146
147 // True if this macro is final.
148 unsigned IsFinal : 1;
149
150 // 22 bits left in a 64-bit word.
151
152 // Managed by the language front-end.
153 void *FETokenInfo = nullptr;
154
155 llvm::StringMapEntry<IdentifierInfo *> *Entry = nullptr;
156
157 IdentifierInfo()
158 : TokenID(tok::identifier), ObjCOrBuiltinID(0), HasMacro(false),
159 HadMacro(false), IsExtension(false), IsFutureCompatKeyword(false),
160 IsPoisoned(false), IsCPPOperatorKeyword(false),
161 NeedsHandleIdentifier(false), IsFromAST(false), ChangedAfterLoad(false),
162 FEChangedAfterLoad(false), RevertedTokenID(false), OutOfDate(false),
163 IsModulesImport(false), IsMangledOpenMPVariantName(false),
164 IsDeprecatedMacro(false), IsRestrictExpansion(false), IsFinal(false) {}
165
166public:
167 IdentifierInfo(const IdentifierInfo &) = delete;
168 IdentifierInfo &operator=(const IdentifierInfo &) = delete;
169 IdentifierInfo(IdentifierInfo &&) = delete;
170 IdentifierInfo &operator=(IdentifierInfo &&) = delete;
171
172 /// Return true if this is the identifier for the specified string.
173 ///
174 /// This is intended to be used for string literals only: II->isStr("foo").
175 template <std::size_t StrLen>
176 bool isStr(const char (&Str)[StrLen]) const {
177 return getLength() == StrLen-1 &&
7
Assuming the condition is false
8
Returning zero, which participates in a condition later
12
Assuming the condition is false
13
Returning zero, which participates in a condition later
17
Assuming the condition is false
18
Returning zero, which participates in a condition later
22
Assuming the condition is false
23
Returning zero, which participates in a condition later
27
Returning zero, which participates in a condition later
31
Assuming the condition is false
32
Returning zero, which participates in a condition later
36
Returning zero, which participates in a condition later
40
Returning zero, which participates in a condition later
44
Assuming the condition is true
46
Returning the value 1, which participates in a condition later
178 memcmp(getNameStart(), Str, StrLen-1) == 0;
45
Assuming the condition is true
179 }
180
181 /// Return true if this is the identifier for the specified StringRef.
182 bool isStr(llvm::StringRef Str) const {
183 llvm::StringRef ThisStr(getNameStart(), getLength());
184 return ThisStr == Str;
185 }
186
187 /// Return the beginning of the actual null-terminated string for this
188 /// identifier.
189 const char *getNameStart() const { return Entry->getKeyData(); }
190
191 /// Efficiently return the length of this identifier info.
192 unsigned getLength() const { return Entry->getKeyLength(); }
193
194 /// Return the actual identifier string.
195 StringRef getName() const {
196 return StringRef(getNameStart(), getLength());
197 }
198
199 /// Return true if this identifier is \#defined to some other value.
200 /// \note The current definition may be in a module and not currently visible.
201 bool hasMacroDefinition() const {
202 return HasMacro;
203 }
204 void setHasMacroDefinition(bool Val) {
205 if (HasMacro == Val) return;
206
207 HasMacro = Val;
208 if (Val) {
209 NeedsHandleIdentifier = true;
210 HadMacro = true;
211 } else {
212 // If this is a final macro, make the deprecation and header unsafe bits
213 // stick around after the undefinition so they apply to any redefinitions.
214 if (!IsFinal) {
215 // Because calling the setters of these calls recomputes, just set them
216 // manually to avoid recomputing a bunch of times.
217 IsDeprecatedMacro = false;
218 IsRestrictExpansion = false;
219 }
220 RecomputeNeedsHandleIdentifier();
221 }
222 }
223 /// Returns true if this identifier was \#defined to some value at any
224 /// moment. In this case there should be an entry for the identifier in the
225 /// macro history table in Preprocessor.
226 bool hadMacroDefinition() const {
227 return HadMacro;
228 }
229
230 bool isDeprecatedMacro() const { return IsDeprecatedMacro; }
231
232 void setIsDeprecatedMacro(bool Val) {
233 if (IsDeprecatedMacro == Val)
234 return;
235 IsDeprecatedMacro = Val;
236 if (Val)
237 NeedsHandleIdentifier = true;
238 else
239 RecomputeNeedsHandleIdentifier();
240 }
241
242 bool isRestrictExpansion() const { return IsRestrictExpansion; }
243
244 void setIsRestrictExpansion(bool Val) {
245 if (IsRestrictExpansion == Val)
246 return;
247 IsRestrictExpansion = Val;
248 if (Val)
249 NeedsHandleIdentifier = true;
250 else
251 RecomputeNeedsHandleIdentifier();
252 }
253
254 bool isFinal() const { return IsFinal; }
255
256 void setIsFinal(bool Val) { IsFinal = Val; }
257
258 /// If this is a source-language token (e.g. 'for'), this API
259 /// can be used to cause the lexer to map identifiers to source-language
260 /// tokens.
261 tok::TokenKind getTokenID() const { return (tok::TokenKind)TokenID; }
262
263 /// True if revertTokenIDToIdentifier() was called.
264 bool hasRevertedTokenIDToIdentifier() const { return RevertedTokenID; }
265
266 /// Revert TokenID to tok::identifier; used for GNU libstdc++ 4.2
267 /// compatibility.
268 ///
269 /// TokenID is normally read-only but there are 2 instances where we revert it
270 /// to tok::identifier for libstdc++ 4.2. Keep track of when this happens
271 /// using this method so we can inform serialization about it.
272 void revertTokenIDToIdentifier() {
273 assert(TokenID != tok::identifier && "Already at tok::identifier")(static_cast <bool> (TokenID != tok::identifier &&
"Already at tok::identifier") ? void (0) : __assert_fail ("TokenID != tok::identifier && \"Already at tok::identifier\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Basic/IdentifierTable.h"
, 273, __extension__ __PRETTY_FUNCTION__))
;
274 TokenID = tok::identifier;
275 RevertedTokenID = true;
276 }
277 void revertIdentifierToTokenID(tok::TokenKind TK) {
278 assert(TokenID == tok::identifier && "Should be at tok::identifier")(static_cast <bool> (TokenID == tok::identifier &&
"Should be at tok::identifier") ? void (0) : __assert_fail (
"TokenID == tok::identifier && \"Should be at tok::identifier\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Basic/IdentifierTable.h"
, 278, __extension__ __PRETTY_FUNCTION__))
;
279 TokenID = TK;
280 RevertedTokenID = false;
281 }
282
283 /// Return the preprocessor keyword ID for this identifier.
284 ///
285 /// For example, "define" will return tok::pp_define.
286 tok::PPKeywordKind getPPKeywordID() const;
287
288 /// Return the Objective-C keyword ID for the this identifier.
289 ///
290 /// For example, 'class' will return tok::objc_class if ObjC is enabled.
291 tok::ObjCKeywordKind getObjCKeywordID() const {
292 if (ObjCOrBuiltinID < tok::NUM_OBJC_KEYWORDS)
293 return tok::ObjCKeywordKind(ObjCOrBuiltinID);
294 else
295 return tok::objc_not_keyword;
296 }
297 void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCOrBuiltinID = ID; }
298
299 /// Return a value indicating whether this is a builtin function.
300 ///
301 /// 0 is not-built-in. 1+ are specific builtin functions.
302 unsigned getBuiltinID() const {
303 if (ObjCOrBuiltinID >= tok::NUM_OBJC_KEYWORDS)
304 return ObjCOrBuiltinID - tok::NUM_OBJC_KEYWORDS;
305 else
306 return 0;
307 }
308 void setBuiltinID(unsigned ID) {
309 ObjCOrBuiltinID = ID + tok::NUM_OBJC_KEYWORDS;
310 assert(ObjCOrBuiltinID - unsigned(tok::NUM_OBJC_KEYWORDS) == ID(static_cast <bool> (ObjCOrBuiltinID - unsigned(tok::NUM_OBJC_KEYWORDS
) == ID && "ID too large for field!") ? void (0) : __assert_fail
("ObjCOrBuiltinID - unsigned(tok::NUM_OBJC_KEYWORDS) == ID && \"ID too large for field!\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Basic/IdentifierTable.h"
, 311, __extension__ __PRETTY_FUNCTION__))
311 && "ID too large for field!")(static_cast <bool> (ObjCOrBuiltinID - unsigned(tok::NUM_OBJC_KEYWORDS
) == ID && "ID too large for field!") ? void (0) : __assert_fail
("ObjCOrBuiltinID - unsigned(tok::NUM_OBJC_KEYWORDS) == ID && \"ID too large for field!\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Basic/IdentifierTable.h"
, 311, __extension__ __PRETTY_FUNCTION__))
;
312 }
313
314 unsigned getObjCOrBuiltinID() const { return ObjCOrBuiltinID; }
315 void setObjCOrBuiltinID(unsigned ID) { ObjCOrBuiltinID = ID; }
316
317 /// get/setExtension - Initialize information about whether or not this
318 /// language token is an extension. This controls extension warnings, and is
319 /// only valid if a custom token ID is set.
320 bool isExtensionToken() const { return IsExtension; }
321 void setIsExtensionToken(bool Val) {
322 IsExtension = Val;
323 if (Val)
324 NeedsHandleIdentifier = true;
325 else
326 RecomputeNeedsHandleIdentifier();
327 }
328
329 /// is/setIsFutureCompatKeyword - Initialize information about whether or not
330 /// this language token is a keyword in a newer or proposed Standard. This
331 /// controls compatibility warnings, and is only true when not parsing the
332 /// corresponding Standard. Once a compatibility problem has been diagnosed
333 /// with this keyword, the flag will be cleared.
334 bool isFutureCompatKeyword() const { return IsFutureCompatKeyword; }
335 void setIsFutureCompatKeyword(bool Val) {
336 IsFutureCompatKeyword = Val;
337 if (Val)
338 NeedsHandleIdentifier = true;
339 else
340 RecomputeNeedsHandleIdentifier();
341 }
342
343 /// setIsPoisoned - Mark this identifier as poisoned. After poisoning, the
344 /// Preprocessor will emit an error every time this token is used.
345 void setIsPoisoned(bool Value = true) {
346 IsPoisoned = Value;
347 if (Value)
348 NeedsHandleIdentifier = true;
349 else
350 RecomputeNeedsHandleIdentifier();
351 }
352
353 /// Return true if this token has been poisoned.
354 bool isPoisoned() const { return IsPoisoned; }
355
356 /// isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether
357 /// this identifier is a C++ alternate representation of an operator.
358 void setIsCPlusPlusOperatorKeyword(bool Val = true) {
359 IsCPPOperatorKeyword = Val;
360 }
361 bool isCPlusPlusOperatorKeyword() const { return IsCPPOperatorKeyword; }
362
363 /// Return true if this token is a keyword in the specified language.
364 bool isKeyword(const LangOptions &LangOpts) const;
365
366 /// Return true if this token is a C++ keyword in the specified
367 /// language.
368 bool isCPlusPlusKeyword(const LangOptions &LangOpts) const;
369
370 /// Get and set FETokenInfo. The language front-end is allowed to associate
371 /// arbitrary metadata with this token.
372 void *getFETokenInfo() const { return FETokenInfo; }
373 void setFETokenInfo(void *T) { FETokenInfo = T; }
374
375 /// Return true if the Preprocessor::HandleIdentifier must be called
376 /// on a token of this identifier.
377 ///
378 /// If this returns false, we know that HandleIdentifier will not affect
379 /// the token.
380 bool isHandleIdentifierCase() const { return NeedsHandleIdentifier; }
381
382 /// Return true if the identifier in its current state was loaded
383 /// from an AST file.
384 bool isFromAST() const { return IsFromAST; }
385
386 void setIsFromAST() { IsFromAST = true; }
387
388 /// Determine whether this identifier has changed since it was loaded
389 /// from an AST file.
390 bool hasChangedSinceDeserialization() const {
391 return ChangedAfterLoad;
392 }
393
394 /// Note that this identifier has changed since it was loaded from
395 /// an AST file.
396 void setChangedSinceDeserialization() {
397 ChangedAfterLoad = true;
398 }
399
400 /// Determine whether the frontend token information for this
401 /// identifier has changed since it was loaded from an AST file.
402 bool hasFETokenInfoChangedSinceDeserialization() const {
403 return FEChangedAfterLoad;
404 }
405
406 /// Note that the frontend token information for this identifier has
407 /// changed since it was loaded from an AST file.
408 void setFETokenInfoChangedSinceDeserialization() {
409 FEChangedAfterLoad = true;
410 }
411
412 /// Determine whether the information for this identifier is out of
413 /// date with respect to the external source.
414 bool isOutOfDate() const { return OutOfDate; }
415
416 /// Set whether the information for this identifier is out of
417 /// date with respect to the external source.
418 void setOutOfDate(bool OOD) {
419 OutOfDate = OOD;
420 if (OOD)
421 NeedsHandleIdentifier = true;
422 else
423 RecomputeNeedsHandleIdentifier();
424 }
425
426 /// Determine whether this is the contextual keyword \c import.
427 bool isModulesImport() const { return IsModulesImport; }
428
429 /// Set whether this identifier is the contextual keyword \c import.
430 void setModulesImport(bool I) {
431 IsModulesImport = I;
432 if (I)
433 NeedsHandleIdentifier = true;
434 else
435 RecomputeNeedsHandleIdentifier();
436 }
437
438 /// Determine whether this is the mangled name of an OpenMP variant.
439 bool isMangledOpenMPVariantName() const { return IsMangledOpenMPVariantName; }
440
441 /// Set whether this is the mangled name of an OpenMP variant.
442 void setMangledOpenMPVariantName(bool I) { IsMangledOpenMPVariantName = I; }
443
444 /// Return true if this identifier is an editor placeholder.
445 ///
446 /// Editor placeholders are produced by the code-completion engine and are
447 /// represented as characters between '<#' and '#>' in the source code. An
448 /// example of auto-completed call with a placeholder parameter is shown
449 /// below:
450 /// \code
451 /// function(<#int x#>);
452 /// \endcode
453 bool isEditorPlaceholder() const {
454 return getName().startswith("<#") && getName().endswith("#>");
455 }
456
457 /// Determine whether \p this is a name reserved for the implementation (C99
458 /// 7.1.3, C++ [lib.global.names]).
459 ReservedIdentifierStatus isReserved(const LangOptions &LangOpts) const;
460
461 /// Provide less than operator for lexicographical sorting.
462 bool operator<(const IdentifierInfo &RHS) const {
463 return getName() < RHS.getName();
464 }
465
466private:
467 /// The Preprocessor::HandleIdentifier does several special (but rare)
468 /// things to identifiers of various sorts. For example, it changes the
469 /// \c for keyword token from tok::identifier to tok::for.
470 ///
471 /// This method is very tied to the definition of HandleIdentifier. Any
472 /// change to it should be reflected here.
473 void RecomputeNeedsHandleIdentifier() {
474 NeedsHandleIdentifier = isPoisoned() || hasMacroDefinition() ||
475 isExtensionToken() || isFutureCompatKeyword() ||
476 isOutOfDate() || isModulesImport();
477 }
478};
479
480/// An RAII object for [un]poisoning an identifier within a scope.
481///
482/// \p II is allowed to be null, in which case objects of this type have
483/// no effect.
484class PoisonIdentifierRAIIObject {
485 IdentifierInfo *const II;
486 const bool OldValue;
487
488public:
489 PoisonIdentifierRAIIObject(IdentifierInfo *II, bool NewValue)
490 : II(II), OldValue(II ? II->isPoisoned() : false) {
491 if(II)
492 II->setIsPoisoned(NewValue);
493 }
494
495 ~PoisonIdentifierRAIIObject() {
496 if(II)
497 II->setIsPoisoned(OldValue);
498 }
499};
500
501/// An iterator that walks over all of the known identifiers
502/// in the lookup table.
503///
504/// Since this iterator uses an abstract interface via virtual
505/// functions, it uses an object-oriented interface rather than the
506/// more standard C++ STL iterator interface. In this OO-style
507/// iteration, the single function \c Next() provides dereference,
508/// advance, and end-of-sequence checking in a single
509/// operation. Subclasses of this iterator type will provide the
510/// actual functionality.
511class IdentifierIterator {
512protected:
513 IdentifierIterator() = default;
514
515public:
516 IdentifierIterator(const IdentifierIterator &) = delete;
517 IdentifierIterator &operator=(const IdentifierIterator &) = delete;
518
519 virtual ~IdentifierIterator();
520
521 /// Retrieve the next string in the identifier table and
522 /// advances the iterator for the following string.
523 ///
524 /// \returns The next string in the identifier table. If there is
525 /// no such string, returns an empty \c StringRef.
526 virtual StringRef Next() = 0;
527};
528
529/// Provides lookups to, and iteration over, IdentiferInfo objects.
530class IdentifierInfoLookup {
531public:
532 virtual ~IdentifierInfoLookup();
533
534 /// Return the IdentifierInfo for the specified named identifier.
535 ///
536 /// Unlike the version in IdentifierTable, this returns a pointer instead
537 /// of a reference. If the pointer is null then the IdentifierInfo cannot
538 /// be found.
539 virtual IdentifierInfo* get(StringRef Name) = 0;
540
541 /// Retrieve an iterator into the set of all identifiers
542 /// known to this identifier lookup source.
543 ///
544 /// This routine provides access to all of the identifiers known to
545 /// the identifier lookup, allowing access to the contents of the
546 /// identifiers without introducing the overhead of constructing
547 /// IdentifierInfo objects for each.
548 ///
549 /// \returns A new iterator into the set of known identifiers. The
550 /// caller is responsible for deleting this iterator.
551 virtual IdentifierIterator *getIdentifiers();
552};
553
554/// Implements an efficient mapping from strings to IdentifierInfo nodes.
555///
556/// This has no other purpose, but this is an extremely performance-critical
557/// piece of the code, as each occurrence of every identifier goes through
558/// here when lexed.
559class IdentifierTable {
560 // Shark shows that using MallocAllocator is *much* slower than using this
561 // BumpPtrAllocator!
562 using HashTableTy = llvm::StringMap<IdentifierInfo *, llvm::BumpPtrAllocator>;
563 HashTableTy HashTable;
564
565 IdentifierInfoLookup* ExternalLookup;
566
567public:
568 /// Create the identifier table.
569 explicit IdentifierTable(IdentifierInfoLookup *ExternalLookup = nullptr);
570
571 /// Create the identifier table, populating it with info about the
572 /// language keywords for the language specified by \p LangOpts.
573 explicit IdentifierTable(const LangOptions &LangOpts,
574 IdentifierInfoLookup *ExternalLookup = nullptr);
575
576 /// Set the external identifier lookup mechanism.
577 void setExternalIdentifierLookup(IdentifierInfoLookup *IILookup) {
578 ExternalLookup = IILookup;
579 }
580
581 /// Retrieve the external identifier lookup object, if any.
582 IdentifierInfoLookup *getExternalIdentifierLookup() const {
583 return ExternalLookup;
584 }
585
586 llvm::BumpPtrAllocator& getAllocator() {
587 return HashTable.getAllocator();
588 }
589
590 /// Return the identifier token info for the specified named
591 /// identifier.
592 IdentifierInfo &get(StringRef Name) {
593 auto &Entry = *HashTable.insert(std::make_pair(Name, nullptr)).first;
594
595 IdentifierInfo *&II = Entry.second;
596 if (II) return *II;
597
598 // No entry; if we have an external lookup, look there first.
599 if (ExternalLookup) {
600 II = ExternalLookup->get(Name);
601 if (II)
602 return *II;
603 }
604
605 // Lookups failed, make a new IdentifierInfo.
606 void *Mem = getAllocator().Allocate<IdentifierInfo>();
607 II = new (Mem) IdentifierInfo();
608
609 // Make sure getName() knows how to find the IdentifierInfo
610 // contents.
611 II->Entry = &Entry;
612
613 return *II;
614 }
615
616 IdentifierInfo &get(StringRef Name, tok::TokenKind TokenCode) {
617 IdentifierInfo &II = get(Name);
618 II.TokenID = TokenCode;
619 assert(II.TokenID == (unsigned) TokenCode && "TokenCode too large")(static_cast <bool> (II.TokenID == (unsigned) TokenCode
&& "TokenCode too large") ? void (0) : __assert_fail
("II.TokenID == (unsigned) TokenCode && \"TokenCode too large\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Basic/IdentifierTable.h"
, 619, __extension__ __PRETTY_FUNCTION__))
;
620 return II;
621 }
622
623 /// Gets an IdentifierInfo for the given name without consulting
624 /// external sources.
625 ///
626 /// This is a version of get() meant for external sources that want to
627 /// introduce or modify an identifier. If they called get(), they would
628 /// likely end up in a recursion.
629 IdentifierInfo &getOwn(StringRef Name) {
630 auto &Entry = *HashTable.insert(std::make_pair(Name, nullptr)).first;
631
632 IdentifierInfo *&II = Entry.second;
633 if (II)
634 return *II;
635
636 // Lookups failed, make a new IdentifierInfo.
637 void *Mem = getAllocator().Allocate<IdentifierInfo>();
638 II = new (Mem) IdentifierInfo();
639
640 // Make sure getName() knows how to find the IdentifierInfo
641 // contents.
642 II->Entry = &Entry;
643
644 // If this is the 'import' contextual keyword, mark it as such.
645 if (Name.equals("import"))
646 II->setModulesImport(true);
647
648 return *II;
649 }
650
651 using iterator = HashTableTy::const_iterator;
652 using const_iterator = HashTableTy::const_iterator;
653
654 iterator begin() const { return HashTable.begin(); }
655 iterator end() const { return HashTable.end(); }
656 unsigned size() const { return HashTable.size(); }
657
658 iterator find(StringRef Name) const { return HashTable.find(Name); }
659
660 /// Print some statistics to stderr that indicate how well the
661 /// hashing is doing.
662 void PrintStats() const;
663
664 /// Populate the identifier table with info about the language keywords
665 /// for the language specified by \p LangOpts.
666 void AddKeywords(const LangOptions &LangOpts);
667};
668
669/// A family of Objective-C methods.
670///
671/// These families have no inherent meaning in the language, but are
672/// nonetheless central enough in the existing implementations to
673/// merit direct AST support. While, in theory, arbitrary methods can
674/// be considered to form families, we focus here on the methods
675/// involving allocation and retain-count management, as these are the
676/// most "core" and the most likely to be useful to diverse clients
677/// without extra information.
678///
679/// Both selectors and actual method declarations may be classified
680/// into families. Method families may impose additional restrictions
681/// beyond their selector name; for example, a method called '_init'
682/// that returns void is not considered to be in the 'init' family
683/// (but would be if it returned 'id'). It is also possible to
684/// explicitly change or remove a method's family. Therefore the
685/// method's family should be considered the single source of truth.
686enum ObjCMethodFamily {
687 /// No particular method family.
688 OMF_None,
689
690 // Selectors in these families may have arbitrary arity, may be
691 // written with arbitrary leading underscores, and may have
692 // additional CamelCase "words" in their first selector chunk
693 // following the family name.
694 OMF_alloc,
695 OMF_copy,
696 OMF_init,
697 OMF_mutableCopy,
698 OMF_new,
699
700 // These families are singletons consisting only of the nullary
701 // selector with the given name.
702 OMF_autorelease,
703 OMF_dealloc,
704 OMF_finalize,
705 OMF_release,
706 OMF_retain,
707 OMF_retainCount,
708 OMF_self,
709 OMF_initialize,
710
711 // performSelector families
712 OMF_performSelector
713};
714
715/// Enough bits to store any enumerator in ObjCMethodFamily or
716/// InvalidObjCMethodFamily.
717enum { ObjCMethodFamilyBitWidth = 4 };
718
719/// An invalid value of ObjCMethodFamily.
720enum { InvalidObjCMethodFamily = (1 << ObjCMethodFamilyBitWidth) - 1 };
721
722/// A family of Objective-C methods.
723///
724/// These are family of methods whose result type is initially 'id', but
725/// but are candidate for the result type to be changed to 'instancetype'.
726enum ObjCInstanceTypeFamily {
727 OIT_None,
728 OIT_Array,
729 OIT_Dictionary,
730 OIT_Singleton,
731 OIT_Init,
732 OIT_ReturnsSelf
733};
734
735enum ObjCStringFormatFamily {
736 SFF_None,
737 SFF_NSString,
738 SFF_CFString
739};
740
741/// Smart pointer class that efficiently represents Objective-C method
742/// names.
743///
744/// This class will either point to an IdentifierInfo or a
745/// MultiKeywordSelector (which is private). This enables us to optimize
746/// selectors that take no arguments and selectors that take 1 argument, which
747/// accounts for 78% of all selectors in Cocoa.h.
748class Selector {
749 friend class Diagnostic;
750 friend class SelectorTable; // only the SelectorTable can create these
751 friend class DeclarationName; // and the AST's DeclarationName.
752
753 enum IdentifierInfoFlag {
754 // Empty selector = 0. Note that these enumeration values must
755 // correspond to the enumeration values of DeclarationName::StoredNameKind
756 ZeroArg = 0x01,
757 OneArg = 0x02,
758 MultiArg = 0x07,
759 ArgFlags = 0x07
760 };
761
762 /// A pointer to the MultiKeywordSelector or IdentifierInfo. We use the low
763 /// three bits of InfoPtr to store an IdentifierInfoFlag. Note that in any
764 /// case IdentifierInfo and MultiKeywordSelector are already aligned to
765 /// 8 bytes even on 32 bits archs because of DeclarationName.
766 uintptr_t InfoPtr = 0;
767
768 Selector(IdentifierInfo *II, unsigned nArgs) {
769 InfoPtr = reinterpret_cast<uintptr_t>(II);
770 assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo")(static_cast <bool> ((InfoPtr & ArgFlags) == 0 &&
"Insufficiently aligned IdentifierInfo") ? void (0) : __assert_fail
("(InfoPtr & ArgFlags) == 0 &&\"Insufficiently aligned IdentifierInfo\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Basic/IdentifierTable.h"
, 770, __extension__ __PRETTY_FUNCTION__))
;
771 assert(nArgs < 2 && "nArgs not equal to 0/1")(static_cast <bool> (nArgs < 2 && "nArgs not equal to 0/1"
) ? void (0) : __assert_fail ("nArgs < 2 && \"nArgs not equal to 0/1\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Basic/IdentifierTable.h"
, 771, __extension__ __PRETTY_FUNCTION__))
;
772 InfoPtr |= nArgs+1;
773 }
774
775 Selector(MultiKeywordSelector *SI) {
776 InfoPtr = reinterpret_cast<uintptr_t>(SI);
777 assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo")(static_cast <bool> ((InfoPtr & ArgFlags) == 0 &&
"Insufficiently aligned IdentifierInfo") ? void (0) : __assert_fail
("(InfoPtr & ArgFlags) == 0 &&\"Insufficiently aligned IdentifierInfo\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Basic/IdentifierTable.h"
, 777, __extension__ __PRETTY_FUNCTION__))
;
778 InfoPtr |= MultiArg;
779 }
780
781 IdentifierInfo *getAsIdentifierInfo() const {
782 if (getIdentifierInfoFlag() < MultiArg)
783 return reinterpret_cast<IdentifierInfo *>(InfoPtr & ~ArgFlags);
784 return nullptr;
785 }
786
787 MultiKeywordSelector *getMultiKeywordSelector() const {
788 return reinterpret_cast<MultiKeywordSelector *>(InfoPtr & ~ArgFlags);
789 }
790
791 unsigned getIdentifierInfoFlag() const {
792 return InfoPtr & ArgFlags;
793 }
794
795 static ObjCMethodFamily getMethodFamilyImpl(Selector sel);
796
797 static ObjCStringFormatFamily getStringFormatFamilyImpl(Selector sel);
798
799public:
800 /// The default ctor should only be used when creating data structures that
801 /// will contain selectors.
802 Selector() = default;
803 explicit Selector(uintptr_t V) : InfoPtr(V) {}
804
805 /// operator==/!= - Indicate whether the specified selectors are identical.
806 bool operator==(Selector RHS) const {
807 return InfoPtr == RHS.InfoPtr;
808 }
809 bool operator!=(Selector RHS) const {
810 return InfoPtr != RHS.InfoPtr;
811 }
812
813 void *getAsOpaquePtr() const {
814 return reinterpret_cast<void*>(InfoPtr);
815 }
816
817 /// Determine whether this is the empty selector.
818 bool isNull() const { return InfoPtr == 0; }
819
820 // Predicates to identify the selector type.
821 bool isKeywordSelector() const {
822 return getIdentifierInfoFlag() != ZeroArg;
823 }
824
825 bool isUnarySelector() const {
826 return getIdentifierInfoFlag() == ZeroArg;
827 }
828
829 /// If this selector is the specific keyword selector described by Names.
830 bool isKeywordSelector(ArrayRef<StringRef> Names) const;
831
832 /// If this selector is the specific unary selector described by Name.
833 bool isUnarySelector(StringRef Name) const;
834
835 unsigned getNumArgs() const;
836
837 /// Retrieve the identifier at a given position in the selector.
838 ///
839 /// Note that the identifier pointer returned may be NULL. Clients that only
840 /// care about the text of the identifier string, and not the specific,
841 /// uniqued identifier pointer, should use \c getNameForSlot(), which returns
842 /// an empty string when the identifier pointer would be NULL.
843 ///
844 /// \param argIndex The index for which we want to retrieve the identifier.
845 /// This index shall be less than \c getNumArgs() unless this is a keyword
846 /// selector, in which case 0 is the only permissible value.
847 ///
848 /// \returns the uniqued identifier for this slot, or NULL if this slot has
849 /// no corresponding identifier.
850 IdentifierInfo *getIdentifierInfoForSlot(unsigned argIndex) const;
851
852 /// Retrieve the name at a given position in the selector.
853 ///
854 /// \param argIndex The index for which we want to retrieve the name.
855 /// This index shall be less than \c getNumArgs() unless this is a keyword
856 /// selector, in which case 0 is the only permissible value.
857 ///
858 /// \returns the name for this slot, which may be the empty string if no
859 /// name was supplied.
860 StringRef getNameForSlot(unsigned argIndex) const;
861
862 /// Derive the full selector name (e.g. "foo:bar:") and return
863 /// it as an std::string.
864 std::string getAsString() const;
865
866 /// Prints the full selector name (e.g. "foo:bar:").
867 void print(llvm::raw_ostream &OS) const;
868
869 void dump() const;
870
871 /// Derive the conventional family of this method.
872 ObjCMethodFamily getMethodFamily() const {
873 return getMethodFamilyImpl(*this);
874 }
875
876 ObjCStringFormatFamily getStringFormatFamily() const {
877 return getStringFormatFamilyImpl(*this);
878 }
879
880 static Selector getEmptyMarker() {
881 return Selector(uintptr_t(-1));
882 }
883
884 static Selector getTombstoneMarker() {
885 return Selector(uintptr_t(-2));
886 }
887
888 static ObjCInstanceTypeFamily getInstTypeMethodFamily(Selector sel);
889};
890
891/// This table allows us to fully hide how we implement
892/// multi-keyword caching.
893class SelectorTable {
894 // Actually a SelectorTableImpl
895 void *Impl;
896
897public:
898 SelectorTable();
899 SelectorTable(const SelectorTable &) = delete;
900 SelectorTable &operator=(const SelectorTable &) = delete;
901 ~SelectorTable();
902
903 /// Can create any sort of selector.
904 ///
905 /// \p NumArgs indicates whether this is a no argument selector "foo", a
906 /// single argument selector "foo:" or multi-argument "foo:bar:".
907 Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV);
908
909 Selector getUnarySelector(IdentifierInfo *ID) {
910 return Selector(ID, 1);
911 }
912
913 Selector getNullarySelector(IdentifierInfo *ID) {
914 return Selector(ID, 0);
915 }
916
917 /// Return the total amount of memory allocated for managing selectors.
918 size_t getTotalMemory() const;
919
920 /// Return the default setter name for the given identifier.
921 ///
922 /// This is "set" + \p Name where the initial character of \p Name
923 /// has been capitalized.
924 static SmallString<64> constructSetterName(StringRef Name);
925
926 /// Return the default setter selector for the given identifier.
927 ///
928 /// This is "set" + \p Name where the initial character of \p Name
929 /// has been capitalized.
930 static Selector constructSetterSelector(IdentifierTable &Idents,
931 SelectorTable &SelTable,
932 const IdentifierInfo *Name);
933
934 /// Return the property name for the given setter selector.
935 static std::string getPropertyNameFromSetterSelector(Selector Sel);
936};
937
938namespace detail {
939
940/// DeclarationNameExtra is used as a base of various uncommon special names.
941/// This class is needed since DeclarationName has not enough space to store
942/// the kind of every possible names. Therefore the kind of common names is
943/// stored directly in DeclarationName, and the kind of uncommon names is
944/// stored in DeclarationNameExtra. It is aligned to 8 bytes because
945/// DeclarationName needs the lower 3 bits to store the kind of common names.
946/// DeclarationNameExtra is tightly coupled to DeclarationName and any change
947/// here is very likely to require changes in DeclarationName(Table).
948class alignas(IdentifierInfoAlignment) DeclarationNameExtra {
949 friend class clang::DeclarationName;
950 friend class clang::DeclarationNameTable;
951
952protected:
953 /// The kind of "extra" information stored in the DeclarationName. See
954 /// @c ExtraKindOrNumArgs for an explanation of how these enumerator values
955 /// are used. Note that DeclarationName depends on the numerical values
956 /// of the enumerators in this enum. See DeclarationName::StoredNameKind
957 /// for more info.
958 enum ExtraKind {
959 CXXDeductionGuideName,
960 CXXLiteralOperatorName,
961 CXXUsingDirective,
962 ObjCMultiArgSelector
963 };
964
965 /// ExtraKindOrNumArgs has one of the following meaning:
966 /// * The kind of an uncommon C++ special name. This DeclarationNameExtra
967 /// is in this case in fact either a CXXDeductionGuideNameExtra or
968 /// a CXXLiteralOperatorIdName.
969 ///
970 /// * It may be also name common to C++ using-directives (CXXUsingDirective),
971 ///
972 /// * Otherwise it is ObjCMultiArgSelector+NumArgs, where NumArgs is
973 /// the number of arguments in the Objective-C selector, in which
974 /// case the DeclarationNameExtra is also a MultiKeywordSelector.
975 unsigned ExtraKindOrNumArgs;
976
977 DeclarationNameExtra(ExtraKind Kind) : ExtraKindOrNumArgs(Kind) {}
978 DeclarationNameExtra(unsigned NumArgs)
979 : ExtraKindOrNumArgs(ObjCMultiArgSelector + NumArgs) {}
980
981 /// Return the corresponding ExtraKind.
982 ExtraKind getKind() const {
983 return static_cast<ExtraKind>(ExtraKindOrNumArgs >
984 (unsigned)ObjCMultiArgSelector
985 ? (unsigned)ObjCMultiArgSelector
986 : ExtraKindOrNumArgs);
987 }
988
989 /// Return the number of arguments in an ObjC selector. Only valid when this
990 /// is indeed an ObjCMultiArgSelector.
991 unsigned getNumArgs() const {
992 assert(ExtraKindOrNumArgs >= (unsigned)ObjCMultiArgSelector &&(static_cast <bool> (ExtraKindOrNumArgs >= (unsigned
)ObjCMultiArgSelector && "getNumArgs called but this is not an ObjC selector!"
) ? void (0) : __assert_fail ("ExtraKindOrNumArgs >= (unsigned)ObjCMultiArgSelector && \"getNumArgs called but this is not an ObjC selector!\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Basic/IdentifierTable.h"
, 993, __extension__ __PRETTY_FUNCTION__))
993 "getNumArgs called but this is not an ObjC selector!")(static_cast <bool> (ExtraKindOrNumArgs >= (unsigned
)ObjCMultiArgSelector && "getNumArgs called but this is not an ObjC selector!"
) ? void (0) : __assert_fail ("ExtraKindOrNumArgs >= (unsigned)ObjCMultiArgSelector && \"getNumArgs called but this is not an ObjC selector!\""
, "/build/llvm-toolchain-snapshot-14~++20211110111138+cffbfd01e37b/clang/include/clang/Basic/IdentifierTable.h"
, 993, __extension__ __PRETTY_FUNCTION__))
;
994 return ExtraKindOrNumArgs - (unsigned)ObjCMultiArgSelector;
995 }
996};
997
998} // namespace detail
999
1000} // namespace clang
1001
1002namespace llvm {
1003
1004/// Define DenseMapInfo so that Selectors can be used as keys in DenseMap and
1005/// DenseSets.
1006template <>
1007struct DenseMapInfo<clang::Selector> {
1008 static clang::Selector getEmptyKey() {
1009 return clang::Selector::getEmptyMarker();
1010 }
1011
1012 static clang::Selector getTombstoneKey() {
1013 return clang::Selector::getTombstoneMarker();
1014 }
1015
1016 static unsigned getHashValue(clang::Selector S);
1017
1018 static bool isEqual(clang::Selector LHS, clang::Selector RHS) {
1019 return LHS == RHS;
1020 }
1021};
1022
1023template<>
1024struct PointerLikeTypeTraits<clang::Selector> {
1025 static const void *getAsVoidPointer(clang::Selector P) {
1026 return P.getAsOpaquePtr();
1027 }
1028
1029 static clang::Selector getFromVoidPointer(const void *P) {
1030 return clang::Selector(reinterpret_cast<uintptr_t>(P));
1031 }
1032
1033 static constexpr int NumLowBitsAvailable = 0;
1034};
1035
1036// Provide PointerLikeTypeTraits for IdentifierInfo pointers, which
1037// are not guaranteed to be 8-byte aligned.
1038template<>
1039struct PointerLikeTypeTraits<clang::IdentifierInfo*> {
1040 static void *getAsVoidPointer(clang::IdentifierInfo* P) {
1041 return P;
1042 }
1043
1044 static clang::IdentifierInfo *getFromVoidPointer(void *P) {
1045 return static_cast<clang::IdentifierInfo*>(P);
1046 }
1047
1048 static constexpr int NumLowBitsAvailable = 1;
1049};
1050
1051template<>
1052struct PointerLikeTypeTraits<const clang::IdentifierInfo*> {
1053 static const void *getAsVoidPointer(const clang::IdentifierInfo* P) {
1054 return P;
1055 }
1056
1057 static const clang::IdentifierInfo *getFromVoidPointer(const void *P) {
1058 return static_cast<const clang::IdentifierInfo*>(P);
1059 }
1060
1061 static constexpr int NumLowBitsAvailable = 1;
1062};
1063
1064} // namespace llvm
1065
1066#endif // LLVM_CLANG_BASIC_IDENTIFIERTABLE_H