xref: /openbsd-src/gnu/llvm/clang/lib/Lex/Pragma.cpp (revision 12c855180aad702bbcca06e0398d774beeafb155)
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