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