xref: /minix3/external/bsd/llvm/dist/clang/lib/Lex/Pragma.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===--- Pragma.cpp - Pragma registration and handling --------------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file implements the PragmaHandler/PragmaTable interfaces and implements
11f4a2713aSLionel Sambuc // pragma related methods of the Preprocessor class.
12f4a2713aSLionel Sambuc //
13f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14f4a2713aSLionel Sambuc 
15f4a2713aSLionel Sambuc #include "clang/Lex/Pragma.h"
16f4a2713aSLionel Sambuc #include "clang/Basic/FileManager.h"
17f4a2713aSLionel Sambuc #include "clang/Basic/SourceManager.h"
18f4a2713aSLionel Sambuc #include "clang/Lex/HeaderSearch.h"
19f4a2713aSLionel Sambuc #include "clang/Lex/LexDiagnostic.h"
20f4a2713aSLionel Sambuc #include "clang/Lex/LiteralSupport.h"
21f4a2713aSLionel Sambuc #include "clang/Lex/MacroInfo.h"
22f4a2713aSLionel Sambuc #include "clang/Lex/Preprocessor.h"
23f4a2713aSLionel Sambuc #include "llvm/ADT/STLExtras.h"
24f4a2713aSLionel Sambuc #include "llvm/ADT/StringSwitch.h"
25f4a2713aSLionel Sambuc #include "llvm/Support/CrashRecoveryContext.h"
26f4a2713aSLionel Sambuc #include "llvm/Support/ErrorHandling.h"
27f4a2713aSLionel Sambuc #include <algorithm>
28f4a2713aSLionel Sambuc using namespace clang;
29f4a2713aSLionel Sambuc 
30f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h"
31f4a2713aSLionel Sambuc 
32f4a2713aSLionel Sambuc // Out-of-line destructor to provide a home for the class.
~PragmaHandler()33f4a2713aSLionel Sambuc PragmaHandler::~PragmaHandler() {
34f4a2713aSLionel Sambuc }
35f4a2713aSLionel Sambuc 
36f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
37f4a2713aSLionel Sambuc // EmptyPragmaHandler Implementation.
38f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
39f4a2713aSLionel Sambuc 
EmptyPragmaHandler()40f4a2713aSLionel Sambuc EmptyPragmaHandler::EmptyPragmaHandler() {}
41f4a2713aSLionel Sambuc 
HandlePragma(Preprocessor & PP,PragmaIntroducerKind Introducer,Token & FirstToken)42f4a2713aSLionel Sambuc void EmptyPragmaHandler::HandlePragma(Preprocessor &PP,
43f4a2713aSLionel Sambuc                                       PragmaIntroducerKind Introducer,
44f4a2713aSLionel Sambuc                                       Token &FirstToken) {}
45f4a2713aSLionel Sambuc 
46f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
47f4a2713aSLionel Sambuc // PragmaNamespace Implementation.
48f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
49f4a2713aSLionel Sambuc 
~PragmaNamespace()50f4a2713aSLionel Sambuc PragmaNamespace::~PragmaNamespace() {
51*0a6a1f1dSLionel Sambuc   llvm::DeleteContainerSeconds(Handlers);
52f4a2713aSLionel Sambuc }
53f4a2713aSLionel Sambuc 
54f4a2713aSLionel Sambuc /// FindHandler - Check to see if there is already a handler for the
55f4a2713aSLionel Sambuc /// specified name.  If not, return the handler for the null identifier if it
56f4a2713aSLionel Sambuc /// exists, otherwise return null.  If IgnoreNull is true (the default) then
57f4a2713aSLionel Sambuc /// the null handler isn't returned on failure to match.
FindHandler(StringRef Name,bool IgnoreNull) const58f4a2713aSLionel Sambuc PragmaHandler *PragmaNamespace::FindHandler(StringRef Name,
59f4a2713aSLionel Sambuc                                             bool IgnoreNull) const {
60f4a2713aSLionel Sambuc   if (PragmaHandler *Handler = Handlers.lookup(Name))
61f4a2713aSLionel Sambuc     return Handler;
62*0a6a1f1dSLionel Sambuc   return IgnoreNull ? nullptr : Handlers.lookup(StringRef());
63f4a2713aSLionel Sambuc }
64f4a2713aSLionel Sambuc 
AddPragma(PragmaHandler * Handler)65f4a2713aSLionel Sambuc void PragmaNamespace::AddPragma(PragmaHandler *Handler) {
66f4a2713aSLionel Sambuc   assert(!Handlers.lookup(Handler->getName()) &&
67f4a2713aSLionel Sambuc          "A handler with this name is already registered in this namespace");
68*0a6a1f1dSLionel Sambuc   Handlers[Handler->getName()] = Handler;
69f4a2713aSLionel Sambuc }
70f4a2713aSLionel Sambuc 
RemovePragmaHandler(PragmaHandler * Handler)71f4a2713aSLionel Sambuc void PragmaNamespace::RemovePragmaHandler(PragmaHandler *Handler) {
72f4a2713aSLionel Sambuc   assert(Handlers.lookup(Handler->getName()) &&
73f4a2713aSLionel Sambuc          "Handler not registered in this namespace");
74f4a2713aSLionel Sambuc   Handlers.erase(Handler->getName());
75f4a2713aSLionel Sambuc }
76f4a2713aSLionel Sambuc 
HandlePragma(Preprocessor & PP,PragmaIntroducerKind Introducer,Token & Tok)77f4a2713aSLionel Sambuc void PragmaNamespace::HandlePragma(Preprocessor &PP,
78f4a2713aSLionel Sambuc                                    PragmaIntroducerKind Introducer,
79f4a2713aSLionel Sambuc                                    Token &Tok) {
80f4a2713aSLionel Sambuc   // Read the 'namespace' that the directive is in, e.g. STDC.  Do not macro
81f4a2713aSLionel Sambuc   // expand it, the user can have a STDC #define, that should not affect this.
82f4a2713aSLionel Sambuc   PP.LexUnexpandedToken(Tok);
83f4a2713aSLionel Sambuc 
84f4a2713aSLionel Sambuc   // Get the handler for this token.  If there is no handler, ignore the pragma.
85f4a2713aSLionel Sambuc   PragmaHandler *Handler
86f4a2713aSLionel Sambuc     = FindHandler(Tok.getIdentifierInfo() ? Tok.getIdentifierInfo()->getName()
87f4a2713aSLionel Sambuc                                           : StringRef(),
88f4a2713aSLionel Sambuc                   /*IgnoreNull=*/false);
89*0a6a1f1dSLionel Sambuc   if (!Handler) {
90f4a2713aSLionel Sambuc     PP.Diag(Tok, diag::warn_pragma_ignored);
91f4a2713aSLionel Sambuc     return;
92f4a2713aSLionel Sambuc   }
93f4a2713aSLionel Sambuc 
94f4a2713aSLionel Sambuc   // Otherwise, pass it down.
95f4a2713aSLionel Sambuc   Handler->HandlePragma(PP, Introducer, Tok);
96f4a2713aSLionel Sambuc }
97f4a2713aSLionel Sambuc 
98f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
99f4a2713aSLionel Sambuc // Preprocessor Pragma Directive Handling.
100f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
101f4a2713aSLionel Sambuc 
102f4a2713aSLionel Sambuc /// HandlePragmaDirective - The "\#pragma" directive has been parsed.  Lex the
103f4a2713aSLionel Sambuc /// rest of the pragma, passing it to the registered pragma handlers.
HandlePragmaDirective(SourceLocation IntroducerLoc,PragmaIntroducerKind Introducer)104f4a2713aSLionel Sambuc void Preprocessor::HandlePragmaDirective(SourceLocation IntroducerLoc,
105f4a2713aSLionel Sambuc                                          PragmaIntroducerKind Introducer) {
106f4a2713aSLionel Sambuc   if (Callbacks)
107f4a2713aSLionel Sambuc     Callbacks->PragmaDirective(IntroducerLoc, Introducer);
108f4a2713aSLionel Sambuc 
109f4a2713aSLionel Sambuc   if (!PragmasEnabled)
110f4a2713aSLionel Sambuc     return;
111f4a2713aSLionel Sambuc 
112f4a2713aSLionel Sambuc   ++NumPragma;
113f4a2713aSLionel Sambuc 
114f4a2713aSLionel Sambuc   // Invoke the first level of pragma handlers which reads the namespace id.
115f4a2713aSLionel Sambuc   Token Tok;
116f4a2713aSLionel Sambuc   PragmaHandlers->HandlePragma(*this, Introducer, Tok);
117f4a2713aSLionel Sambuc 
118f4a2713aSLionel Sambuc   // If the pragma handler didn't read the rest of the line, consume it now.
119f4a2713aSLionel Sambuc   if ((CurTokenLexer && CurTokenLexer->isParsingPreprocessorDirective())
120f4a2713aSLionel Sambuc    || (CurPPLexer && CurPPLexer->ParsingPreprocessorDirective))
121f4a2713aSLionel Sambuc     DiscardUntilEndOfDirective();
122f4a2713aSLionel Sambuc }
123f4a2713aSLionel Sambuc 
124f4a2713aSLionel Sambuc namespace {
125f4a2713aSLionel Sambuc /// \brief Helper class for \see Preprocessor::Handle_Pragma.
126f4a2713aSLionel Sambuc class LexingFor_PragmaRAII {
127f4a2713aSLionel Sambuc   Preprocessor &PP;
128f4a2713aSLionel Sambuc   bool InMacroArgPreExpansion;
129f4a2713aSLionel Sambuc   bool Failed;
130f4a2713aSLionel Sambuc   Token &OutTok;
131f4a2713aSLionel Sambuc   Token PragmaTok;
132f4a2713aSLionel Sambuc 
133f4a2713aSLionel Sambuc public:
LexingFor_PragmaRAII(Preprocessor & PP,bool InMacroArgPreExpansion,Token & Tok)134f4a2713aSLionel Sambuc   LexingFor_PragmaRAII(Preprocessor &PP, bool InMacroArgPreExpansion,
135f4a2713aSLionel Sambuc                        Token &Tok)
136f4a2713aSLionel Sambuc     : PP(PP), InMacroArgPreExpansion(InMacroArgPreExpansion),
137f4a2713aSLionel Sambuc       Failed(false), OutTok(Tok) {
138f4a2713aSLionel Sambuc     if (InMacroArgPreExpansion) {
139f4a2713aSLionel Sambuc       PragmaTok = OutTok;
140f4a2713aSLionel Sambuc       PP.EnableBacktrackAtThisPos();
141f4a2713aSLionel Sambuc     }
142f4a2713aSLionel Sambuc   }
143f4a2713aSLionel Sambuc 
~LexingFor_PragmaRAII()144f4a2713aSLionel Sambuc   ~LexingFor_PragmaRAII() {
145f4a2713aSLionel Sambuc     if (InMacroArgPreExpansion) {
146f4a2713aSLionel Sambuc       if (Failed) {
147f4a2713aSLionel Sambuc         PP.CommitBacktrackedTokens();
148f4a2713aSLionel Sambuc       } else {
149f4a2713aSLionel Sambuc         PP.Backtrack();
150f4a2713aSLionel Sambuc         OutTok = PragmaTok;
151f4a2713aSLionel Sambuc       }
152f4a2713aSLionel Sambuc     }
153f4a2713aSLionel Sambuc   }
154f4a2713aSLionel Sambuc 
failed()155f4a2713aSLionel Sambuc   void failed() {
156f4a2713aSLionel Sambuc     Failed = true;
157f4a2713aSLionel Sambuc   }
158f4a2713aSLionel Sambuc };
159f4a2713aSLionel Sambuc }
160f4a2713aSLionel Sambuc 
161f4a2713aSLionel Sambuc /// Handle_Pragma - Read a _Pragma directive, slice it up, process it, then
162f4a2713aSLionel Sambuc /// return the first token after the directive.  The _Pragma token has just
163f4a2713aSLionel Sambuc /// been read into 'Tok'.
Handle_Pragma(Token & Tok)164f4a2713aSLionel Sambuc void Preprocessor::Handle_Pragma(Token &Tok) {
165f4a2713aSLionel Sambuc 
166f4a2713aSLionel Sambuc   // This works differently if we are pre-expanding a macro argument.
167f4a2713aSLionel Sambuc   // In that case we don't actually "activate" the pragma now, we only lex it
168f4a2713aSLionel Sambuc   // until we are sure it is lexically correct and then we backtrack so that
169f4a2713aSLionel Sambuc   // we activate the pragma whenever we encounter the tokens again in the token
170f4a2713aSLionel Sambuc   // stream. This ensures that we will activate it in the correct location
171f4a2713aSLionel Sambuc   // or that we will ignore it if it never enters the token stream, e.g:
172f4a2713aSLionel Sambuc   //
173f4a2713aSLionel Sambuc   //     #define EMPTY(x)
174f4a2713aSLionel Sambuc   //     #define INACTIVE(x) EMPTY(x)
175f4a2713aSLionel Sambuc   //     INACTIVE(_Pragma("clang diagnostic ignored \"-Wconversion\""))
176f4a2713aSLionel Sambuc 
177f4a2713aSLionel Sambuc   LexingFor_PragmaRAII _PragmaLexing(*this, InMacroArgPreExpansion, Tok);
178f4a2713aSLionel Sambuc 
179f4a2713aSLionel Sambuc   // Remember the pragma token location.
180f4a2713aSLionel Sambuc   SourceLocation PragmaLoc = Tok.getLocation();
181f4a2713aSLionel Sambuc 
182f4a2713aSLionel Sambuc   // Read the '('.
183f4a2713aSLionel Sambuc   Lex(Tok);
184f4a2713aSLionel Sambuc   if (Tok.isNot(tok::l_paren)) {
185f4a2713aSLionel Sambuc     Diag(PragmaLoc, diag::err__Pragma_malformed);
186f4a2713aSLionel Sambuc     return _PragmaLexing.failed();
187f4a2713aSLionel Sambuc   }
188f4a2713aSLionel Sambuc 
189f4a2713aSLionel Sambuc   // Read the '"..."'.
190f4a2713aSLionel Sambuc   Lex(Tok);
191f4a2713aSLionel Sambuc   if (!tok::isStringLiteral(Tok.getKind())) {
192f4a2713aSLionel Sambuc     Diag(PragmaLoc, diag::err__Pragma_malformed);
193f4a2713aSLionel Sambuc     // Skip this token, and the ')', if present.
194*0a6a1f1dSLionel Sambuc     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::eof))
195f4a2713aSLionel Sambuc       Lex(Tok);
196f4a2713aSLionel Sambuc     if (Tok.is(tok::r_paren))
197f4a2713aSLionel Sambuc       Lex(Tok);
198f4a2713aSLionel Sambuc     return _PragmaLexing.failed();
199f4a2713aSLionel Sambuc   }
200f4a2713aSLionel Sambuc 
201f4a2713aSLionel Sambuc   if (Tok.hasUDSuffix()) {
202f4a2713aSLionel Sambuc     Diag(Tok, diag::err_invalid_string_udl);
203f4a2713aSLionel Sambuc     // Skip this token, and the ')', if present.
204f4a2713aSLionel Sambuc     Lex(Tok);
205f4a2713aSLionel Sambuc     if (Tok.is(tok::r_paren))
206f4a2713aSLionel Sambuc       Lex(Tok);
207f4a2713aSLionel Sambuc     return _PragmaLexing.failed();
208f4a2713aSLionel Sambuc   }
209f4a2713aSLionel Sambuc 
210f4a2713aSLionel Sambuc   // Remember the string.
211f4a2713aSLionel Sambuc   Token StrTok = Tok;
212f4a2713aSLionel Sambuc 
213f4a2713aSLionel Sambuc   // Read the ')'.
214f4a2713aSLionel Sambuc   Lex(Tok);
215f4a2713aSLionel Sambuc   if (Tok.isNot(tok::r_paren)) {
216f4a2713aSLionel Sambuc     Diag(PragmaLoc, diag::err__Pragma_malformed);
217f4a2713aSLionel Sambuc     return _PragmaLexing.failed();
218f4a2713aSLionel Sambuc   }
219f4a2713aSLionel Sambuc 
220f4a2713aSLionel Sambuc   if (InMacroArgPreExpansion)
221f4a2713aSLionel Sambuc     return;
222f4a2713aSLionel Sambuc 
223f4a2713aSLionel Sambuc   SourceLocation RParenLoc = Tok.getLocation();
224f4a2713aSLionel Sambuc   std::string StrVal = getSpelling(StrTok);
225f4a2713aSLionel Sambuc 
226f4a2713aSLionel Sambuc   // The _Pragma is lexically sound.  Destringize according to C11 6.10.9.1:
227f4a2713aSLionel Sambuc   // "The string literal is destringized by deleting any encoding prefix,
228f4a2713aSLionel Sambuc   // deleting the leading and trailing double-quotes, replacing each escape
229f4a2713aSLionel Sambuc   // sequence \" by a double-quote, and replacing each escape sequence \\ by a
230f4a2713aSLionel Sambuc   // single backslash."
231f4a2713aSLionel Sambuc   if (StrVal[0] == 'L' || StrVal[0] == 'U' ||
232f4a2713aSLionel Sambuc       (StrVal[0] == 'u' && StrVal[1] != '8'))
233f4a2713aSLionel Sambuc     StrVal.erase(StrVal.begin());
234f4a2713aSLionel Sambuc   else if (StrVal[0] == 'u')
235f4a2713aSLionel Sambuc     StrVal.erase(StrVal.begin(), StrVal.begin() + 2);
236f4a2713aSLionel Sambuc 
237f4a2713aSLionel Sambuc   if (StrVal[0] == 'R') {
238f4a2713aSLionel Sambuc     // FIXME: C++11 does not specify how to handle raw-string-literals here.
239f4a2713aSLionel Sambuc     // We strip off the 'R', the quotes, the d-char-sequences, and the parens.
240f4a2713aSLionel Sambuc     assert(StrVal[1] == '"' && StrVal[StrVal.size() - 1] == '"' &&
241f4a2713aSLionel Sambuc            "Invalid raw string token!");
242f4a2713aSLionel Sambuc 
243f4a2713aSLionel Sambuc     // Measure the length of the d-char-sequence.
244f4a2713aSLionel Sambuc     unsigned NumDChars = 0;
245f4a2713aSLionel Sambuc     while (StrVal[2 + NumDChars] != '(') {
246f4a2713aSLionel Sambuc       assert(NumDChars < (StrVal.size() - 5) / 2 &&
247f4a2713aSLionel Sambuc              "Invalid raw string token!");
248f4a2713aSLionel Sambuc       ++NumDChars;
249f4a2713aSLionel Sambuc     }
250f4a2713aSLionel Sambuc     assert(StrVal[StrVal.size() - 2 - NumDChars] == ')');
251f4a2713aSLionel Sambuc 
252f4a2713aSLionel Sambuc     // Remove 'R " d-char-sequence' and 'd-char-sequence "'. We'll replace the
253f4a2713aSLionel Sambuc     // parens below.
254f4a2713aSLionel Sambuc     StrVal.erase(0, 2 + NumDChars);
255f4a2713aSLionel Sambuc     StrVal.erase(StrVal.size() - 1 - NumDChars);
256f4a2713aSLionel Sambuc   } else {
257f4a2713aSLionel Sambuc     assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' &&
258f4a2713aSLionel Sambuc            "Invalid string token!");
259f4a2713aSLionel Sambuc 
260f4a2713aSLionel Sambuc     // Remove escaped quotes and escapes.
261f4a2713aSLionel Sambuc     unsigned ResultPos = 1;
262f4a2713aSLionel Sambuc     for (unsigned i = 1, e = StrVal.size() - 1; i != e; ++i) {
263f4a2713aSLionel Sambuc       // Skip escapes.  \\ -> '\' and \" -> '"'.
264f4a2713aSLionel Sambuc       if (StrVal[i] == '\\' && i + 1 < e &&
265f4a2713aSLionel Sambuc           (StrVal[i + 1] == '\\' || StrVal[i + 1] == '"'))
266f4a2713aSLionel Sambuc         ++i;
267f4a2713aSLionel Sambuc       StrVal[ResultPos++] = StrVal[i];
268f4a2713aSLionel Sambuc     }
269f4a2713aSLionel Sambuc     StrVal.erase(StrVal.begin() + ResultPos, StrVal.end() - 1);
270f4a2713aSLionel Sambuc   }
271f4a2713aSLionel Sambuc 
272f4a2713aSLionel Sambuc   // Remove the front quote, replacing it with a space, so that the pragma
273f4a2713aSLionel Sambuc   // contents appear to have a space before them.
274f4a2713aSLionel Sambuc   StrVal[0] = ' ';
275f4a2713aSLionel Sambuc 
276f4a2713aSLionel Sambuc   // Replace the terminating quote with a \n.
277f4a2713aSLionel Sambuc   StrVal[StrVal.size()-1] = '\n';
278f4a2713aSLionel Sambuc 
279f4a2713aSLionel Sambuc   // Plop the string (including the newline and trailing null) into a buffer
280f4a2713aSLionel Sambuc   // where we can lex it.
281f4a2713aSLionel Sambuc   Token TmpTok;
282f4a2713aSLionel Sambuc   TmpTok.startToken();
283f4a2713aSLionel Sambuc   CreateString(StrVal, TmpTok);
284f4a2713aSLionel Sambuc   SourceLocation TokLoc = TmpTok.getLocation();
285f4a2713aSLionel Sambuc 
286f4a2713aSLionel Sambuc   // Make and enter a lexer object so that we lex and expand the tokens just
287f4a2713aSLionel Sambuc   // like any others.
288f4a2713aSLionel Sambuc   Lexer *TL = Lexer::Create_PragmaLexer(TokLoc, PragmaLoc, RParenLoc,
289f4a2713aSLionel Sambuc                                         StrVal.size(), *this);
290f4a2713aSLionel Sambuc 
291*0a6a1f1dSLionel Sambuc   EnterSourceFileWithLexer(TL, nullptr);
292f4a2713aSLionel Sambuc 
293f4a2713aSLionel Sambuc   // With everything set up, lex this as a #pragma directive.
294f4a2713aSLionel Sambuc   HandlePragmaDirective(PragmaLoc, PIK__Pragma);
295f4a2713aSLionel Sambuc 
296f4a2713aSLionel Sambuc   // Finally, return whatever came after the pragma directive.
297f4a2713aSLionel Sambuc   return Lex(Tok);
298f4a2713aSLionel Sambuc }
299f4a2713aSLionel Sambuc 
300f4a2713aSLionel Sambuc /// HandleMicrosoft__pragma - Like Handle_Pragma except the pragma text
301f4a2713aSLionel Sambuc /// is not enclosed within a string literal.
HandleMicrosoft__pragma(Token & Tok)302f4a2713aSLionel Sambuc void Preprocessor::HandleMicrosoft__pragma(Token &Tok) {
303f4a2713aSLionel Sambuc   // Remember the pragma token location.
304f4a2713aSLionel Sambuc   SourceLocation PragmaLoc = Tok.getLocation();
305f4a2713aSLionel Sambuc 
306f4a2713aSLionel Sambuc   // Read the '('.
307f4a2713aSLionel Sambuc   Lex(Tok);
308f4a2713aSLionel Sambuc   if (Tok.isNot(tok::l_paren)) {
309f4a2713aSLionel Sambuc     Diag(PragmaLoc, diag::err__Pragma_malformed);
310f4a2713aSLionel Sambuc     return;
311f4a2713aSLionel Sambuc   }
312f4a2713aSLionel Sambuc 
313f4a2713aSLionel Sambuc   // Get the tokens enclosed within the __pragma(), as well as the final ')'.
314f4a2713aSLionel Sambuc   SmallVector<Token, 32> PragmaToks;
315f4a2713aSLionel Sambuc   int NumParens = 0;
316f4a2713aSLionel Sambuc   Lex(Tok);
317f4a2713aSLionel Sambuc   while (Tok.isNot(tok::eof)) {
318f4a2713aSLionel Sambuc     PragmaToks.push_back(Tok);
319f4a2713aSLionel Sambuc     if (Tok.is(tok::l_paren))
320f4a2713aSLionel Sambuc       NumParens++;
321f4a2713aSLionel Sambuc     else if (Tok.is(tok::r_paren) && NumParens-- == 0)
322f4a2713aSLionel Sambuc       break;
323f4a2713aSLionel Sambuc     Lex(Tok);
324f4a2713aSLionel Sambuc   }
325f4a2713aSLionel Sambuc 
326f4a2713aSLionel Sambuc   if (Tok.is(tok::eof)) {
327f4a2713aSLionel Sambuc     Diag(PragmaLoc, diag::err_unterminated___pragma);
328f4a2713aSLionel Sambuc     return;
329f4a2713aSLionel Sambuc   }
330f4a2713aSLionel Sambuc 
331f4a2713aSLionel Sambuc   PragmaToks.front().setFlag(Token::LeadingSpace);
332f4a2713aSLionel Sambuc 
333f4a2713aSLionel Sambuc   // Replace the ')' with an EOD to mark the end of the pragma.
334f4a2713aSLionel Sambuc   PragmaToks.back().setKind(tok::eod);
335f4a2713aSLionel Sambuc 
336f4a2713aSLionel Sambuc   Token *TokArray = new Token[PragmaToks.size()];
337f4a2713aSLionel Sambuc   std::copy(PragmaToks.begin(), PragmaToks.end(), TokArray);
338f4a2713aSLionel Sambuc 
339f4a2713aSLionel Sambuc   // Push the tokens onto the stack.
340f4a2713aSLionel Sambuc   EnterTokenStream(TokArray, PragmaToks.size(), true, true);
341f4a2713aSLionel Sambuc 
342f4a2713aSLionel Sambuc   // With everything set up, lex this as a #pragma directive.
343f4a2713aSLionel Sambuc   HandlePragmaDirective(PragmaLoc, PIK___pragma);
344f4a2713aSLionel Sambuc 
345f4a2713aSLionel Sambuc   // Finally, return whatever came after the pragma directive.
346f4a2713aSLionel Sambuc   return Lex(Tok);
347f4a2713aSLionel Sambuc }
348f4a2713aSLionel Sambuc 
349f4a2713aSLionel Sambuc /// HandlePragmaOnce - Handle \#pragma once.  OnceTok is the 'once'.
350f4a2713aSLionel Sambuc ///
HandlePragmaOnce(Token & OnceTok)351f4a2713aSLionel Sambuc void Preprocessor::HandlePragmaOnce(Token &OnceTok) {
352f4a2713aSLionel Sambuc   if (isInPrimaryFile()) {
353f4a2713aSLionel Sambuc     Diag(OnceTok, diag::pp_pragma_once_in_main_file);
354f4a2713aSLionel Sambuc     return;
355f4a2713aSLionel Sambuc   }
356f4a2713aSLionel Sambuc 
357f4a2713aSLionel Sambuc   // Get the current file lexer we're looking at.  Ignore _Pragma 'files' etc.
358f4a2713aSLionel Sambuc   // Mark the file as a once-only file now.
359f4a2713aSLionel Sambuc   HeaderInfo.MarkFileIncludeOnce(getCurrentFileLexer()->getFileEntry());
360f4a2713aSLionel Sambuc }
361f4a2713aSLionel Sambuc 
HandlePragmaMark()362f4a2713aSLionel Sambuc void Preprocessor::HandlePragmaMark() {
363f4a2713aSLionel Sambuc   assert(CurPPLexer && "No current lexer?");
364f4a2713aSLionel Sambuc   if (CurLexer)
365f4a2713aSLionel Sambuc     CurLexer->ReadToEndOfLine();
366f4a2713aSLionel Sambuc   else
367f4a2713aSLionel Sambuc     CurPTHLexer->DiscardToEndOfLine();
368f4a2713aSLionel Sambuc }
369f4a2713aSLionel Sambuc 
370f4a2713aSLionel Sambuc 
371f4a2713aSLionel Sambuc /// HandlePragmaPoison - Handle \#pragma GCC poison.  PoisonTok is the 'poison'.
372f4a2713aSLionel Sambuc ///
HandlePragmaPoison(Token & PoisonTok)373f4a2713aSLionel Sambuc void Preprocessor::HandlePragmaPoison(Token &PoisonTok) {
374f4a2713aSLionel Sambuc   Token Tok;
375f4a2713aSLionel Sambuc 
376f4a2713aSLionel Sambuc   while (1) {
377f4a2713aSLionel Sambuc     // Read the next token to poison.  While doing this, pretend that we are
378f4a2713aSLionel Sambuc     // skipping while reading the identifier to poison.
379f4a2713aSLionel Sambuc     // This avoids errors on code like:
380f4a2713aSLionel Sambuc     //   #pragma GCC poison X
381f4a2713aSLionel Sambuc     //   #pragma GCC poison X
382f4a2713aSLionel Sambuc     if (CurPPLexer) CurPPLexer->LexingRawMode = true;
383f4a2713aSLionel Sambuc     LexUnexpandedToken(Tok);
384f4a2713aSLionel Sambuc     if (CurPPLexer) CurPPLexer->LexingRawMode = false;
385f4a2713aSLionel Sambuc 
386f4a2713aSLionel Sambuc     // If we reached the end of line, we're done.
387f4a2713aSLionel Sambuc     if (Tok.is(tok::eod)) return;
388f4a2713aSLionel Sambuc 
389f4a2713aSLionel Sambuc     // Can only poison identifiers.
390f4a2713aSLionel Sambuc     if (Tok.isNot(tok::raw_identifier)) {
391f4a2713aSLionel Sambuc       Diag(Tok, diag::err_pp_invalid_poison);
392f4a2713aSLionel Sambuc       return;
393f4a2713aSLionel Sambuc     }
394f4a2713aSLionel Sambuc 
395f4a2713aSLionel Sambuc     // Look up the identifier info for the token.  We disabled identifier lookup
396f4a2713aSLionel Sambuc     // by saying we're skipping contents, so we need to do this manually.
397f4a2713aSLionel Sambuc     IdentifierInfo *II = LookUpIdentifierInfo(Tok);
398f4a2713aSLionel Sambuc 
399f4a2713aSLionel Sambuc     // Already poisoned.
400f4a2713aSLionel Sambuc     if (II->isPoisoned()) continue;
401f4a2713aSLionel Sambuc 
402f4a2713aSLionel Sambuc     // If this is a macro identifier, emit a warning.
403f4a2713aSLionel Sambuc     if (II->hasMacroDefinition())
404f4a2713aSLionel Sambuc       Diag(Tok, diag::pp_poisoning_existing_macro);
405f4a2713aSLionel Sambuc 
406f4a2713aSLionel Sambuc     // Finally, poison it!
407f4a2713aSLionel Sambuc     II->setIsPoisoned();
408f4a2713aSLionel Sambuc     if (II->isFromAST())
409f4a2713aSLionel Sambuc       II->setChangedSinceDeserialization();
410f4a2713aSLionel Sambuc   }
411f4a2713aSLionel Sambuc }
412f4a2713aSLionel Sambuc 
413f4a2713aSLionel Sambuc /// HandlePragmaSystemHeader - Implement \#pragma GCC system_header.  We know
414f4a2713aSLionel Sambuc /// that the whole directive has been parsed.
HandlePragmaSystemHeader(Token & SysHeaderTok)415f4a2713aSLionel Sambuc void Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) {
416f4a2713aSLionel Sambuc   if (isInPrimaryFile()) {
417f4a2713aSLionel Sambuc     Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);
418f4a2713aSLionel Sambuc     return;
419f4a2713aSLionel Sambuc   }
420f4a2713aSLionel Sambuc 
421f4a2713aSLionel Sambuc   // Get the current file lexer we're looking at.  Ignore _Pragma 'files' etc.
422f4a2713aSLionel Sambuc   PreprocessorLexer *TheLexer = getCurrentFileLexer();
423f4a2713aSLionel Sambuc 
424f4a2713aSLionel Sambuc   // Mark the file as a system header.
425f4a2713aSLionel Sambuc   HeaderInfo.MarkFileSystemHeader(TheLexer->getFileEntry());
426f4a2713aSLionel Sambuc 
427f4a2713aSLionel Sambuc 
428f4a2713aSLionel Sambuc   PresumedLoc PLoc = SourceMgr.getPresumedLoc(SysHeaderTok.getLocation());
429f4a2713aSLionel Sambuc   if (PLoc.isInvalid())
430f4a2713aSLionel Sambuc     return;
431f4a2713aSLionel Sambuc 
432f4a2713aSLionel Sambuc   unsigned FilenameID = SourceMgr.getLineTableFilenameID(PLoc.getFilename());
433f4a2713aSLionel Sambuc 
434f4a2713aSLionel Sambuc   // Notify the client, if desired, that we are in a new source file.
435f4a2713aSLionel Sambuc   if (Callbacks)
436f4a2713aSLionel Sambuc     Callbacks->FileChanged(SysHeaderTok.getLocation(),
437f4a2713aSLionel Sambuc                            PPCallbacks::SystemHeaderPragma, SrcMgr::C_System);
438f4a2713aSLionel Sambuc 
439f4a2713aSLionel Sambuc   // Emit a line marker.  This will change any source locations from this point
440f4a2713aSLionel Sambuc   // forward to realize they are in a system header.
441f4a2713aSLionel Sambuc   // Create a line note with this information.
442f4a2713aSLionel Sambuc   SourceMgr.AddLineNote(SysHeaderTok.getLocation(), PLoc.getLine()+1,
443f4a2713aSLionel Sambuc                         FilenameID, /*IsEntry=*/false, /*IsExit=*/false,
444f4a2713aSLionel Sambuc                         /*IsSystem=*/true, /*IsExternC=*/false);
445f4a2713aSLionel Sambuc }
446f4a2713aSLionel Sambuc 
447f4a2713aSLionel Sambuc /// HandlePragmaDependency - Handle \#pragma GCC dependency "foo" blah.
448f4a2713aSLionel Sambuc ///
HandlePragmaDependency(Token & DependencyTok)449f4a2713aSLionel Sambuc void Preprocessor::HandlePragmaDependency(Token &DependencyTok) {
450f4a2713aSLionel Sambuc   Token FilenameTok;
451f4a2713aSLionel Sambuc   CurPPLexer->LexIncludeFilename(FilenameTok);
452f4a2713aSLionel Sambuc 
453f4a2713aSLionel Sambuc   // If the token kind is EOD, the error has already been diagnosed.
454f4a2713aSLionel Sambuc   if (FilenameTok.is(tok::eod))
455f4a2713aSLionel Sambuc     return;
456f4a2713aSLionel Sambuc 
457f4a2713aSLionel Sambuc   // Reserve a buffer to get the spelling.
458f4a2713aSLionel Sambuc   SmallString<128> FilenameBuffer;
459f4a2713aSLionel Sambuc   bool Invalid = false;
460f4a2713aSLionel Sambuc   StringRef Filename = getSpelling(FilenameTok, FilenameBuffer, &Invalid);
461f4a2713aSLionel Sambuc   if (Invalid)
462f4a2713aSLionel Sambuc     return;
463f4a2713aSLionel Sambuc 
464f4a2713aSLionel Sambuc   bool isAngled =
465f4a2713aSLionel Sambuc     GetIncludeFilenameSpelling(FilenameTok.getLocation(), Filename);
466f4a2713aSLionel Sambuc   // If GetIncludeFilenameSpelling set the start ptr to null, there was an
467f4a2713aSLionel Sambuc   // error.
468f4a2713aSLionel Sambuc   if (Filename.empty())
469f4a2713aSLionel Sambuc     return;
470f4a2713aSLionel Sambuc 
471f4a2713aSLionel Sambuc   // Search include directories for this file.
472f4a2713aSLionel Sambuc   const DirectoryLookup *CurDir;
473*0a6a1f1dSLionel Sambuc   const FileEntry *File =
474*0a6a1f1dSLionel Sambuc       LookupFile(FilenameTok.getLocation(), Filename, isAngled, nullptr,
475*0a6a1f1dSLionel Sambuc                  nullptr, CurDir, nullptr, nullptr, nullptr);
476*0a6a1f1dSLionel Sambuc   if (!File) {
477f4a2713aSLionel Sambuc     if (!SuppressIncludeNotFoundError)
478f4a2713aSLionel Sambuc       Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
479f4a2713aSLionel Sambuc     return;
480f4a2713aSLionel Sambuc   }
481f4a2713aSLionel Sambuc 
482f4a2713aSLionel Sambuc   const FileEntry *CurFile = getCurrentFileLexer()->getFileEntry();
483f4a2713aSLionel Sambuc 
484f4a2713aSLionel Sambuc   // If this file is older than the file it depends on, emit a diagnostic.
485f4a2713aSLionel Sambuc   if (CurFile && CurFile->getModificationTime() < File->getModificationTime()) {
486f4a2713aSLionel Sambuc     // Lex tokens at the end of the message and include them in the message.
487f4a2713aSLionel Sambuc     std::string Message;
488f4a2713aSLionel Sambuc     Lex(DependencyTok);
489f4a2713aSLionel Sambuc     while (DependencyTok.isNot(tok::eod)) {
490f4a2713aSLionel Sambuc       Message += getSpelling(DependencyTok) + " ";
491f4a2713aSLionel Sambuc       Lex(DependencyTok);
492f4a2713aSLionel Sambuc     }
493f4a2713aSLionel Sambuc 
494f4a2713aSLionel Sambuc     // Remove the trailing ' ' if present.
495f4a2713aSLionel Sambuc     if (!Message.empty())
496f4a2713aSLionel Sambuc       Message.erase(Message.end()-1);
497f4a2713aSLionel Sambuc     Diag(FilenameTok, diag::pp_out_of_date_dependency) << Message;
498f4a2713aSLionel Sambuc   }
499f4a2713aSLionel Sambuc }
500f4a2713aSLionel Sambuc 
501f4a2713aSLionel Sambuc /// ParsePragmaPushOrPopMacro - Handle parsing of pragma push_macro/pop_macro.
502f4a2713aSLionel Sambuc /// Return the IdentifierInfo* associated with the macro to push or pop.
ParsePragmaPushOrPopMacro(Token & Tok)503f4a2713aSLionel Sambuc IdentifierInfo *Preprocessor::ParsePragmaPushOrPopMacro(Token &Tok) {
504f4a2713aSLionel Sambuc   // Remember the pragma token location.
505f4a2713aSLionel Sambuc   Token PragmaTok = Tok;
506f4a2713aSLionel Sambuc 
507f4a2713aSLionel Sambuc   // Read the '('.
508f4a2713aSLionel Sambuc   Lex(Tok);
509f4a2713aSLionel Sambuc   if (Tok.isNot(tok::l_paren)) {
510f4a2713aSLionel Sambuc     Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
511f4a2713aSLionel Sambuc       << getSpelling(PragmaTok);
512*0a6a1f1dSLionel Sambuc     return nullptr;
513f4a2713aSLionel Sambuc   }
514f4a2713aSLionel Sambuc 
515f4a2713aSLionel Sambuc   // Read the macro name string.
516f4a2713aSLionel Sambuc   Lex(Tok);
517f4a2713aSLionel Sambuc   if (Tok.isNot(tok::string_literal)) {
518f4a2713aSLionel Sambuc     Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
519f4a2713aSLionel Sambuc       << getSpelling(PragmaTok);
520*0a6a1f1dSLionel Sambuc     return nullptr;
521f4a2713aSLionel Sambuc   }
522f4a2713aSLionel Sambuc 
523f4a2713aSLionel Sambuc   if (Tok.hasUDSuffix()) {
524f4a2713aSLionel Sambuc     Diag(Tok, diag::err_invalid_string_udl);
525*0a6a1f1dSLionel Sambuc     return nullptr;
526f4a2713aSLionel Sambuc   }
527f4a2713aSLionel Sambuc 
528f4a2713aSLionel Sambuc   // Remember the macro string.
529f4a2713aSLionel Sambuc   std::string StrVal = getSpelling(Tok);
530f4a2713aSLionel Sambuc 
531f4a2713aSLionel Sambuc   // Read the ')'.
532f4a2713aSLionel Sambuc   Lex(Tok);
533f4a2713aSLionel Sambuc   if (Tok.isNot(tok::r_paren)) {
534f4a2713aSLionel Sambuc     Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
535f4a2713aSLionel Sambuc       << getSpelling(PragmaTok);
536*0a6a1f1dSLionel Sambuc     return nullptr;
537f4a2713aSLionel Sambuc   }
538f4a2713aSLionel Sambuc 
539f4a2713aSLionel Sambuc   assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' &&
540f4a2713aSLionel Sambuc          "Invalid string token!");
541f4a2713aSLionel Sambuc 
542f4a2713aSLionel Sambuc   // Create a Token from the string.
543f4a2713aSLionel Sambuc   Token MacroTok;
544f4a2713aSLionel Sambuc   MacroTok.startToken();
545f4a2713aSLionel Sambuc   MacroTok.setKind(tok::raw_identifier);
546f4a2713aSLionel Sambuc   CreateString(StringRef(&StrVal[1], StrVal.size() - 2), MacroTok);
547f4a2713aSLionel Sambuc 
548f4a2713aSLionel Sambuc   // Get the IdentifierInfo of MacroToPushTok.
549f4a2713aSLionel Sambuc   return LookUpIdentifierInfo(MacroTok);
550f4a2713aSLionel Sambuc }
551f4a2713aSLionel Sambuc 
552f4a2713aSLionel Sambuc /// \brief Handle \#pragma push_macro.
553f4a2713aSLionel Sambuc ///
554f4a2713aSLionel Sambuc /// The syntax is:
555f4a2713aSLionel Sambuc /// \code
556f4a2713aSLionel Sambuc ///   #pragma push_macro("macro")
557f4a2713aSLionel Sambuc /// \endcode
HandlePragmaPushMacro(Token & PushMacroTok)558f4a2713aSLionel Sambuc void Preprocessor::HandlePragmaPushMacro(Token &PushMacroTok) {
559f4a2713aSLionel Sambuc   // Parse the pragma directive and get the macro IdentifierInfo*.
560f4a2713aSLionel Sambuc   IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PushMacroTok);
561f4a2713aSLionel Sambuc   if (!IdentInfo) return;
562f4a2713aSLionel Sambuc 
563f4a2713aSLionel Sambuc   // Get the MacroInfo associated with IdentInfo.
564f4a2713aSLionel Sambuc   MacroInfo *MI = getMacroInfo(IdentInfo);
565f4a2713aSLionel Sambuc 
566f4a2713aSLionel Sambuc   if (MI) {
567f4a2713aSLionel Sambuc     // Allow the original MacroInfo to be redefined later.
568f4a2713aSLionel Sambuc     MI->setIsAllowRedefinitionsWithoutWarning(true);
569f4a2713aSLionel Sambuc   }
570f4a2713aSLionel Sambuc 
571f4a2713aSLionel Sambuc   // Push the cloned MacroInfo so we can retrieve it later.
572f4a2713aSLionel Sambuc   PragmaPushMacroInfo[IdentInfo].push_back(MI);
573f4a2713aSLionel Sambuc }
574f4a2713aSLionel Sambuc 
575f4a2713aSLionel Sambuc /// \brief Handle \#pragma pop_macro.
576f4a2713aSLionel Sambuc ///
577f4a2713aSLionel Sambuc /// The syntax is:
578f4a2713aSLionel Sambuc /// \code
579f4a2713aSLionel Sambuc ///   #pragma pop_macro("macro")
580f4a2713aSLionel Sambuc /// \endcode
HandlePragmaPopMacro(Token & PopMacroTok)581f4a2713aSLionel Sambuc void Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) {
582f4a2713aSLionel Sambuc   SourceLocation MessageLoc = PopMacroTok.getLocation();
583f4a2713aSLionel Sambuc 
584f4a2713aSLionel Sambuc   // Parse the pragma directive and get the macro IdentifierInfo*.
585f4a2713aSLionel Sambuc   IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PopMacroTok);
586f4a2713aSLionel Sambuc   if (!IdentInfo) return;
587f4a2713aSLionel Sambuc 
588f4a2713aSLionel Sambuc   // Find the vector<MacroInfo*> associated with the macro.
589f4a2713aSLionel Sambuc   llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> >::iterator iter =
590f4a2713aSLionel Sambuc     PragmaPushMacroInfo.find(IdentInfo);
591f4a2713aSLionel Sambuc   if (iter != PragmaPushMacroInfo.end()) {
592f4a2713aSLionel Sambuc     // Forget the MacroInfo currently associated with IdentInfo.
593f4a2713aSLionel Sambuc     if (MacroDirective *CurrentMD = getMacroDirective(IdentInfo)) {
594f4a2713aSLionel Sambuc       MacroInfo *MI = CurrentMD->getMacroInfo();
595f4a2713aSLionel Sambuc       if (MI->isWarnIfUnused())
596f4a2713aSLionel Sambuc         WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
597f4a2713aSLionel Sambuc       appendMacroDirective(IdentInfo, AllocateUndefMacroDirective(MessageLoc));
598f4a2713aSLionel Sambuc     }
599f4a2713aSLionel Sambuc 
600f4a2713aSLionel Sambuc     // Get the MacroInfo we want to reinstall.
601f4a2713aSLionel Sambuc     MacroInfo *MacroToReInstall = iter->second.back();
602f4a2713aSLionel Sambuc 
603f4a2713aSLionel Sambuc     if (MacroToReInstall) {
604f4a2713aSLionel Sambuc       // Reinstall the previously pushed macro.
605f4a2713aSLionel Sambuc       appendDefMacroDirective(IdentInfo, MacroToReInstall, MessageLoc,
606*0a6a1f1dSLionel Sambuc                               /*isImported=*/false, /*Overrides*/None);
607f4a2713aSLionel Sambuc     }
608f4a2713aSLionel Sambuc 
609f4a2713aSLionel Sambuc     // Pop PragmaPushMacroInfo stack.
610f4a2713aSLionel Sambuc     iter->second.pop_back();
611f4a2713aSLionel Sambuc     if (iter->second.size() == 0)
612f4a2713aSLionel Sambuc       PragmaPushMacroInfo.erase(iter);
613f4a2713aSLionel Sambuc   } else {
614f4a2713aSLionel Sambuc     Diag(MessageLoc, diag::warn_pragma_pop_macro_no_push)
615f4a2713aSLionel Sambuc       << IdentInfo->getName();
616f4a2713aSLionel Sambuc   }
617f4a2713aSLionel Sambuc }
618f4a2713aSLionel Sambuc 
HandlePragmaIncludeAlias(Token & Tok)619f4a2713aSLionel Sambuc void Preprocessor::HandlePragmaIncludeAlias(Token &Tok) {
620f4a2713aSLionel Sambuc   // We will either get a quoted filename or a bracketed filename, and we
621f4a2713aSLionel Sambuc   // have to track which we got.  The first filename is the source name,
622f4a2713aSLionel Sambuc   // and the second name is the mapped filename.  If the first is quoted,
623f4a2713aSLionel Sambuc   // the second must be as well (cannot mix and match quotes and brackets).
624f4a2713aSLionel Sambuc 
625f4a2713aSLionel Sambuc   // Get the open paren
626f4a2713aSLionel Sambuc   Lex(Tok);
627f4a2713aSLionel Sambuc   if (Tok.isNot(tok::l_paren)) {
628f4a2713aSLionel Sambuc     Diag(Tok, diag::warn_pragma_include_alias_expected) << "(";
629f4a2713aSLionel Sambuc     return;
630f4a2713aSLionel Sambuc   }
631f4a2713aSLionel Sambuc 
632f4a2713aSLionel Sambuc   // We expect either a quoted string literal, or a bracketed name
633f4a2713aSLionel Sambuc   Token SourceFilenameTok;
634f4a2713aSLionel Sambuc   CurPPLexer->LexIncludeFilename(SourceFilenameTok);
635f4a2713aSLionel Sambuc   if (SourceFilenameTok.is(tok::eod)) {
636f4a2713aSLionel Sambuc     // The diagnostic has already been handled
637f4a2713aSLionel Sambuc     return;
638f4a2713aSLionel Sambuc   }
639f4a2713aSLionel Sambuc 
640f4a2713aSLionel Sambuc   StringRef SourceFileName;
641f4a2713aSLionel Sambuc   SmallString<128> FileNameBuffer;
642f4a2713aSLionel Sambuc   if (SourceFilenameTok.is(tok::string_literal) ||
643f4a2713aSLionel Sambuc       SourceFilenameTok.is(tok::angle_string_literal)) {
644f4a2713aSLionel Sambuc     SourceFileName = getSpelling(SourceFilenameTok, FileNameBuffer);
645f4a2713aSLionel Sambuc   } else if (SourceFilenameTok.is(tok::less)) {
646f4a2713aSLionel Sambuc     // This could be a path instead of just a name
647f4a2713aSLionel Sambuc     FileNameBuffer.push_back('<');
648f4a2713aSLionel Sambuc     SourceLocation End;
649f4a2713aSLionel Sambuc     if (ConcatenateIncludeName(FileNameBuffer, End))
650f4a2713aSLionel Sambuc       return; // Diagnostic already emitted
651f4a2713aSLionel Sambuc     SourceFileName = FileNameBuffer.str();
652f4a2713aSLionel Sambuc   } else {
653f4a2713aSLionel Sambuc     Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
654f4a2713aSLionel Sambuc     return;
655f4a2713aSLionel Sambuc   }
656f4a2713aSLionel Sambuc   FileNameBuffer.clear();
657f4a2713aSLionel Sambuc 
658f4a2713aSLionel Sambuc   // Now we expect a comma, followed by another include name
659f4a2713aSLionel Sambuc   Lex(Tok);
660f4a2713aSLionel Sambuc   if (Tok.isNot(tok::comma)) {
661f4a2713aSLionel Sambuc     Diag(Tok, diag::warn_pragma_include_alias_expected) << ",";
662f4a2713aSLionel Sambuc     return;
663f4a2713aSLionel Sambuc   }
664f4a2713aSLionel Sambuc 
665f4a2713aSLionel Sambuc   Token ReplaceFilenameTok;
666f4a2713aSLionel Sambuc   CurPPLexer->LexIncludeFilename(ReplaceFilenameTok);
667f4a2713aSLionel Sambuc   if (ReplaceFilenameTok.is(tok::eod)) {
668f4a2713aSLionel Sambuc     // The diagnostic has already been handled
669f4a2713aSLionel Sambuc     return;
670f4a2713aSLionel Sambuc   }
671f4a2713aSLionel Sambuc 
672f4a2713aSLionel Sambuc   StringRef ReplaceFileName;
673f4a2713aSLionel Sambuc   if (ReplaceFilenameTok.is(tok::string_literal) ||
674f4a2713aSLionel Sambuc       ReplaceFilenameTok.is(tok::angle_string_literal)) {
675f4a2713aSLionel Sambuc     ReplaceFileName = getSpelling(ReplaceFilenameTok, FileNameBuffer);
676f4a2713aSLionel Sambuc   } else if (ReplaceFilenameTok.is(tok::less)) {
677f4a2713aSLionel Sambuc     // This could be a path instead of just a name
678f4a2713aSLionel Sambuc     FileNameBuffer.push_back('<');
679f4a2713aSLionel Sambuc     SourceLocation End;
680f4a2713aSLionel Sambuc     if (ConcatenateIncludeName(FileNameBuffer, End))
681f4a2713aSLionel Sambuc       return; // Diagnostic already emitted
682f4a2713aSLionel Sambuc     ReplaceFileName = FileNameBuffer.str();
683f4a2713aSLionel Sambuc   } else {
684f4a2713aSLionel Sambuc     Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
685f4a2713aSLionel Sambuc     return;
686f4a2713aSLionel Sambuc   }
687f4a2713aSLionel Sambuc 
688f4a2713aSLionel Sambuc   // Finally, we expect the closing paren
689f4a2713aSLionel Sambuc   Lex(Tok);
690f4a2713aSLionel Sambuc   if (Tok.isNot(tok::r_paren)) {
691f4a2713aSLionel Sambuc     Diag(Tok, diag::warn_pragma_include_alias_expected) << ")";
692f4a2713aSLionel Sambuc     return;
693f4a2713aSLionel Sambuc   }
694f4a2713aSLionel Sambuc 
695f4a2713aSLionel Sambuc   // Now that we have the source and target filenames, we need to make sure
696f4a2713aSLionel Sambuc   // they're both of the same type (angled vs non-angled)
697f4a2713aSLionel Sambuc   StringRef OriginalSource = SourceFileName;
698f4a2713aSLionel Sambuc 
699f4a2713aSLionel Sambuc   bool SourceIsAngled =
700f4a2713aSLionel Sambuc     GetIncludeFilenameSpelling(SourceFilenameTok.getLocation(),
701f4a2713aSLionel Sambuc                                 SourceFileName);
702f4a2713aSLionel Sambuc   bool ReplaceIsAngled =
703f4a2713aSLionel Sambuc     GetIncludeFilenameSpelling(ReplaceFilenameTok.getLocation(),
704f4a2713aSLionel Sambuc                                 ReplaceFileName);
705f4a2713aSLionel Sambuc   if (!SourceFileName.empty() && !ReplaceFileName.empty() &&
706f4a2713aSLionel Sambuc       (SourceIsAngled != ReplaceIsAngled)) {
707f4a2713aSLionel Sambuc     unsigned int DiagID;
708f4a2713aSLionel Sambuc     if (SourceIsAngled)
709f4a2713aSLionel Sambuc       DiagID = diag::warn_pragma_include_alias_mismatch_angle;
710f4a2713aSLionel Sambuc     else
711f4a2713aSLionel Sambuc       DiagID = diag::warn_pragma_include_alias_mismatch_quote;
712f4a2713aSLionel Sambuc 
713f4a2713aSLionel Sambuc     Diag(SourceFilenameTok.getLocation(), DiagID)
714f4a2713aSLionel Sambuc       << SourceFileName
715f4a2713aSLionel Sambuc       << ReplaceFileName;
716f4a2713aSLionel Sambuc 
717f4a2713aSLionel Sambuc     return;
718f4a2713aSLionel Sambuc   }
719f4a2713aSLionel Sambuc 
720f4a2713aSLionel Sambuc   // Now we can let the include handler know about this mapping
721f4a2713aSLionel Sambuc   getHeaderSearchInfo().AddIncludeAlias(OriginalSource, ReplaceFileName);
722f4a2713aSLionel Sambuc }
723f4a2713aSLionel Sambuc 
724f4a2713aSLionel Sambuc /// AddPragmaHandler - Add the specified pragma handler to the preprocessor.
725f4a2713aSLionel Sambuc /// If 'Namespace' is non-null, then it is a token required to exist on the
726f4a2713aSLionel Sambuc /// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
AddPragmaHandler(StringRef Namespace,PragmaHandler * Handler)727f4a2713aSLionel Sambuc void Preprocessor::AddPragmaHandler(StringRef Namespace,
728f4a2713aSLionel Sambuc                                     PragmaHandler *Handler) {
729*0a6a1f1dSLionel Sambuc   PragmaNamespace *InsertNS = PragmaHandlers.get();
730f4a2713aSLionel Sambuc 
731f4a2713aSLionel Sambuc   // If this is specified to be in a namespace, step down into it.
732f4a2713aSLionel Sambuc   if (!Namespace.empty()) {
733f4a2713aSLionel Sambuc     // If there is already a pragma handler with the name of this namespace,
734f4a2713aSLionel Sambuc     // we either have an error (directive with the same name as a namespace) or
735f4a2713aSLionel Sambuc     // we already have the namespace to insert into.
736f4a2713aSLionel Sambuc     if (PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace)) {
737f4a2713aSLionel Sambuc       InsertNS = Existing->getIfNamespace();
738*0a6a1f1dSLionel Sambuc       assert(InsertNS != nullptr && "Cannot have a pragma namespace and pragma"
739f4a2713aSLionel Sambuc              " handler with the same name!");
740f4a2713aSLionel Sambuc     } else {
741f4a2713aSLionel Sambuc       // Otherwise, this namespace doesn't exist yet, create and insert the
742f4a2713aSLionel Sambuc       // handler for it.
743f4a2713aSLionel Sambuc       InsertNS = new PragmaNamespace(Namespace);
744f4a2713aSLionel Sambuc       PragmaHandlers->AddPragma(InsertNS);
745f4a2713aSLionel Sambuc     }
746f4a2713aSLionel Sambuc   }
747f4a2713aSLionel Sambuc 
748f4a2713aSLionel Sambuc   // Check to make sure we don't already have a pragma for this identifier.
749f4a2713aSLionel Sambuc   assert(!InsertNS->FindHandler(Handler->getName()) &&
750f4a2713aSLionel Sambuc          "Pragma handler already exists for this identifier!");
751f4a2713aSLionel Sambuc   InsertNS->AddPragma(Handler);
752f4a2713aSLionel Sambuc }
753f4a2713aSLionel Sambuc 
754f4a2713aSLionel Sambuc /// RemovePragmaHandler - Remove the specific pragma handler from the
755f4a2713aSLionel Sambuc /// preprocessor. If \arg Namespace is non-null, then it should be the
756f4a2713aSLionel Sambuc /// namespace that \arg Handler was added to. It is an error to remove
757f4a2713aSLionel Sambuc /// a handler that has not been registered.
RemovePragmaHandler(StringRef Namespace,PragmaHandler * Handler)758f4a2713aSLionel Sambuc void Preprocessor::RemovePragmaHandler(StringRef Namespace,
759f4a2713aSLionel Sambuc                                        PragmaHandler *Handler) {
760*0a6a1f1dSLionel Sambuc   PragmaNamespace *NS = PragmaHandlers.get();
761f4a2713aSLionel Sambuc 
762f4a2713aSLionel Sambuc   // If this is specified to be in a namespace, step down into it.
763f4a2713aSLionel Sambuc   if (!Namespace.empty()) {
764f4a2713aSLionel Sambuc     PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace);
765f4a2713aSLionel Sambuc     assert(Existing && "Namespace containing handler does not exist!");
766f4a2713aSLionel Sambuc 
767f4a2713aSLionel Sambuc     NS = Existing->getIfNamespace();
768f4a2713aSLionel Sambuc     assert(NS && "Invalid namespace, registered as a regular pragma handler!");
769f4a2713aSLionel Sambuc   }
770f4a2713aSLionel Sambuc 
771f4a2713aSLionel Sambuc   NS->RemovePragmaHandler(Handler);
772f4a2713aSLionel Sambuc 
773*0a6a1f1dSLionel Sambuc   // If this is a non-default namespace and it is now empty, remove it.
774*0a6a1f1dSLionel Sambuc   if (NS != PragmaHandlers.get() && NS->IsEmpty()) {
775f4a2713aSLionel Sambuc     PragmaHandlers->RemovePragmaHandler(NS);
776f4a2713aSLionel Sambuc     delete NS;
777f4a2713aSLionel Sambuc   }
778f4a2713aSLionel Sambuc }
779f4a2713aSLionel Sambuc 
LexOnOffSwitch(tok::OnOffSwitch & Result)780f4a2713aSLionel Sambuc bool Preprocessor::LexOnOffSwitch(tok::OnOffSwitch &Result) {
781f4a2713aSLionel Sambuc   Token Tok;
782f4a2713aSLionel Sambuc   LexUnexpandedToken(Tok);
783f4a2713aSLionel Sambuc 
784f4a2713aSLionel Sambuc   if (Tok.isNot(tok::identifier)) {
785f4a2713aSLionel Sambuc     Diag(Tok, diag::ext_on_off_switch_syntax);
786f4a2713aSLionel Sambuc     return true;
787f4a2713aSLionel Sambuc   }
788f4a2713aSLionel Sambuc   IdentifierInfo *II = Tok.getIdentifierInfo();
789f4a2713aSLionel Sambuc   if (II->isStr("ON"))
790f4a2713aSLionel Sambuc     Result = tok::OOS_ON;
791f4a2713aSLionel Sambuc   else if (II->isStr("OFF"))
792f4a2713aSLionel Sambuc     Result = tok::OOS_OFF;
793f4a2713aSLionel Sambuc   else if (II->isStr("DEFAULT"))
794f4a2713aSLionel Sambuc     Result = tok::OOS_DEFAULT;
795f4a2713aSLionel Sambuc   else {
796f4a2713aSLionel Sambuc     Diag(Tok, diag::ext_on_off_switch_syntax);
797f4a2713aSLionel Sambuc     return true;
798f4a2713aSLionel Sambuc   }
799f4a2713aSLionel Sambuc 
800f4a2713aSLionel Sambuc   // Verify that this is followed by EOD.
801f4a2713aSLionel Sambuc   LexUnexpandedToken(Tok);
802f4a2713aSLionel Sambuc   if (Tok.isNot(tok::eod))
803f4a2713aSLionel Sambuc     Diag(Tok, diag::ext_pragma_syntax_eod);
804f4a2713aSLionel Sambuc   return false;
805f4a2713aSLionel Sambuc }
806f4a2713aSLionel Sambuc 
807f4a2713aSLionel Sambuc namespace {
808f4a2713aSLionel Sambuc /// PragmaOnceHandler - "\#pragma once" marks the file as atomically included.
809f4a2713aSLionel Sambuc struct PragmaOnceHandler : public PragmaHandler {
PragmaOnceHandler__anon8441e45d0211::PragmaOnceHandler810f4a2713aSLionel Sambuc   PragmaOnceHandler() : PragmaHandler("once") {}
HandlePragma__anon8441e45d0211::PragmaOnceHandler811*0a6a1f1dSLionel Sambuc   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
812*0a6a1f1dSLionel Sambuc                     Token &OnceTok) override {
813f4a2713aSLionel Sambuc     PP.CheckEndOfDirective("pragma once");
814f4a2713aSLionel Sambuc     PP.HandlePragmaOnce(OnceTok);
815f4a2713aSLionel Sambuc   }
816f4a2713aSLionel Sambuc };
817f4a2713aSLionel Sambuc 
818f4a2713aSLionel Sambuc /// PragmaMarkHandler - "\#pragma mark ..." is ignored by the compiler, and the
819f4a2713aSLionel Sambuc /// rest of the line is not lexed.
820f4a2713aSLionel Sambuc struct PragmaMarkHandler : public PragmaHandler {
PragmaMarkHandler__anon8441e45d0211::PragmaMarkHandler821f4a2713aSLionel Sambuc   PragmaMarkHandler() : PragmaHandler("mark") {}
HandlePragma__anon8441e45d0211::PragmaMarkHandler822*0a6a1f1dSLionel Sambuc   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
823*0a6a1f1dSLionel Sambuc                     Token &MarkTok) override {
824f4a2713aSLionel Sambuc     PP.HandlePragmaMark();
825f4a2713aSLionel Sambuc   }
826f4a2713aSLionel Sambuc };
827f4a2713aSLionel Sambuc 
828f4a2713aSLionel Sambuc /// PragmaPoisonHandler - "\#pragma poison x" marks x as not usable.
829f4a2713aSLionel Sambuc struct PragmaPoisonHandler : public PragmaHandler {
PragmaPoisonHandler__anon8441e45d0211::PragmaPoisonHandler830f4a2713aSLionel Sambuc   PragmaPoisonHandler() : PragmaHandler("poison") {}
HandlePragma__anon8441e45d0211::PragmaPoisonHandler831*0a6a1f1dSLionel Sambuc   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
832*0a6a1f1dSLionel Sambuc                     Token &PoisonTok) override {
833f4a2713aSLionel Sambuc     PP.HandlePragmaPoison(PoisonTok);
834f4a2713aSLionel Sambuc   }
835f4a2713aSLionel Sambuc };
836f4a2713aSLionel Sambuc 
837f4a2713aSLionel Sambuc /// PragmaSystemHeaderHandler - "\#pragma system_header" marks the current file
838f4a2713aSLionel Sambuc /// as a system header, which silences warnings in it.
839f4a2713aSLionel Sambuc struct PragmaSystemHeaderHandler : public PragmaHandler {
PragmaSystemHeaderHandler__anon8441e45d0211::PragmaSystemHeaderHandler840f4a2713aSLionel Sambuc   PragmaSystemHeaderHandler() : PragmaHandler("system_header") {}
HandlePragma__anon8441e45d0211::PragmaSystemHeaderHandler841*0a6a1f1dSLionel Sambuc   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
842*0a6a1f1dSLionel Sambuc                     Token &SHToken) override {
843f4a2713aSLionel Sambuc     PP.HandlePragmaSystemHeader(SHToken);
844f4a2713aSLionel Sambuc     PP.CheckEndOfDirective("pragma");
845f4a2713aSLionel Sambuc   }
846f4a2713aSLionel Sambuc };
847f4a2713aSLionel Sambuc struct PragmaDependencyHandler : public PragmaHandler {
PragmaDependencyHandler__anon8441e45d0211::PragmaDependencyHandler848f4a2713aSLionel Sambuc   PragmaDependencyHandler() : PragmaHandler("dependency") {}
HandlePragma__anon8441e45d0211::PragmaDependencyHandler849*0a6a1f1dSLionel Sambuc   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
850*0a6a1f1dSLionel Sambuc                     Token &DepToken) override {
851f4a2713aSLionel Sambuc     PP.HandlePragmaDependency(DepToken);
852f4a2713aSLionel Sambuc   }
853f4a2713aSLionel Sambuc };
854f4a2713aSLionel Sambuc 
855f4a2713aSLionel Sambuc struct PragmaDebugHandler : public PragmaHandler {
PragmaDebugHandler__anon8441e45d0211::PragmaDebugHandler856f4a2713aSLionel Sambuc   PragmaDebugHandler() : PragmaHandler("__debug") {}
HandlePragma__anon8441e45d0211::PragmaDebugHandler857*0a6a1f1dSLionel Sambuc   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
858*0a6a1f1dSLionel Sambuc                     Token &DepToken) override {
859f4a2713aSLionel Sambuc     Token Tok;
860f4a2713aSLionel Sambuc     PP.LexUnexpandedToken(Tok);
861f4a2713aSLionel Sambuc     if (Tok.isNot(tok::identifier)) {
862f4a2713aSLionel Sambuc       PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
863f4a2713aSLionel Sambuc       return;
864f4a2713aSLionel Sambuc     }
865f4a2713aSLionel Sambuc     IdentifierInfo *II = Tok.getIdentifierInfo();
866f4a2713aSLionel Sambuc 
867f4a2713aSLionel Sambuc     if (II->isStr("assert")) {
868f4a2713aSLionel Sambuc       llvm_unreachable("This is an assertion!");
869f4a2713aSLionel Sambuc     } else if (II->isStr("crash")) {
870f4a2713aSLionel Sambuc       LLVM_BUILTIN_TRAP;
871f4a2713aSLionel Sambuc     } else if (II->isStr("parser_crash")) {
872f4a2713aSLionel Sambuc       Token Crasher;
873f4a2713aSLionel Sambuc       Crasher.setKind(tok::annot_pragma_parser_crash);
874f4a2713aSLionel Sambuc       PP.EnterToken(Crasher);
875f4a2713aSLionel Sambuc     } else if (II->isStr("llvm_fatal_error")) {
876f4a2713aSLionel Sambuc       llvm::report_fatal_error("#pragma clang __debug llvm_fatal_error");
877f4a2713aSLionel Sambuc     } else if (II->isStr("llvm_unreachable")) {
878f4a2713aSLionel Sambuc       llvm_unreachable("#pragma clang __debug llvm_unreachable");
879f4a2713aSLionel Sambuc     } else if (II->isStr("overflow_stack")) {
880f4a2713aSLionel Sambuc       DebugOverflowStack();
881f4a2713aSLionel Sambuc     } else if (II->isStr("handle_crash")) {
882f4a2713aSLionel Sambuc       llvm::CrashRecoveryContext *CRC =llvm::CrashRecoveryContext::GetCurrent();
883f4a2713aSLionel Sambuc       if (CRC)
884f4a2713aSLionel Sambuc         CRC->HandleCrash();
885f4a2713aSLionel Sambuc     } else if (II->isStr("captured")) {
886f4a2713aSLionel Sambuc       HandleCaptured(PP);
887f4a2713aSLionel Sambuc     } else {
888f4a2713aSLionel Sambuc       PP.Diag(Tok, diag::warn_pragma_debug_unexpected_command)
889f4a2713aSLionel Sambuc         << II->getName();
890f4a2713aSLionel Sambuc     }
891f4a2713aSLionel Sambuc 
892f4a2713aSLionel Sambuc     PPCallbacks *Callbacks = PP.getPPCallbacks();
893f4a2713aSLionel Sambuc     if (Callbacks)
894f4a2713aSLionel Sambuc       Callbacks->PragmaDebug(Tok.getLocation(), II->getName());
895f4a2713aSLionel Sambuc   }
896f4a2713aSLionel Sambuc 
HandleCaptured__anon8441e45d0211::PragmaDebugHandler897f4a2713aSLionel Sambuc   void HandleCaptured(Preprocessor &PP) {
898f4a2713aSLionel Sambuc     // Skip if emitting preprocessed output.
899f4a2713aSLionel Sambuc     if (PP.isPreprocessedOutput())
900f4a2713aSLionel Sambuc       return;
901f4a2713aSLionel Sambuc 
902f4a2713aSLionel Sambuc     Token Tok;
903f4a2713aSLionel Sambuc     PP.LexUnexpandedToken(Tok);
904f4a2713aSLionel Sambuc 
905f4a2713aSLionel Sambuc     if (Tok.isNot(tok::eod)) {
906f4a2713aSLionel Sambuc       PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol)
907f4a2713aSLionel Sambuc         << "pragma clang __debug captured";
908f4a2713aSLionel Sambuc       return;
909f4a2713aSLionel Sambuc     }
910f4a2713aSLionel Sambuc 
911f4a2713aSLionel Sambuc     SourceLocation NameLoc = Tok.getLocation();
912f4a2713aSLionel Sambuc     Token *Toks = PP.getPreprocessorAllocator().Allocate<Token>(1);
913f4a2713aSLionel Sambuc     Toks->startToken();
914f4a2713aSLionel Sambuc     Toks->setKind(tok::annot_pragma_captured);
915f4a2713aSLionel Sambuc     Toks->setLocation(NameLoc);
916f4a2713aSLionel Sambuc 
917f4a2713aSLionel Sambuc     PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
918f4a2713aSLionel Sambuc                         /*OwnsTokens=*/false);
919f4a2713aSLionel Sambuc   }
920f4a2713aSLionel Sambuc 
921f4a2713aSLionel Sambuc // Disable MSVC warning about runtime stack overflow.
922f4a2713aSLionel Sambuc #ifdef _MSC_VER
923f4a2713aSLionel Sambuc     #pragma warning(disable : 4717)
924f4a2713aSLionel Sambuc #endif
DebugOverflowStack__anon8441e45d0211::PragmaDebugHandler925*0a6a1f1dSLionel Sambuc   static void DebugOverflowStack() {
926*0a6a1f1dSLionel Sambuc     void (*volatile Self)() = DebugOverflowStack;
927*0a6a1f1dSLionel Sambuc     Self();
928f4a2713aSLionel Sambuc   }
929f4a2713aSLionel Sambuc #ifdef _MSC_VER
930f4a2713aSLionel Sambuc     #pragma warning(default : 4717)
931f4a2713aSLionel Sambuc #endif
932f4a2713aSLionel Sambuc 
933f4a2713aSLionel Sambuc };
934f4a2713aSLionel Sambuc 
935f4a2713aSLionel Sambuc /// PragmaDiagnosticHandler - e.g. '\#pragma GCC diagnostic ignored "-Wformat"'
936f4a2713aSLionel Sambuc struct PragmaDiagnosticHandler : public PragmaHandler {
937f4a2713aSLionel Sambuc private:
938f4a2713aSLionel Sambuc   const char *Namespace;
939f4a2713aSLionel Sambuc public:
PragmaDiagnosticHandler__anon8441e45d0211::PragmaDiagnosticHandler940f4a2713aSLionel Sambuc   explicit PragmaDiagnosticHandler(const char *NS) :
941f4a2713aSLionel Sambuc     PragmaHandler("diagnostic"), Namespace(NS) {}
HandlePragma__anon8441e45d0211::PragmaDiagnosticHandler942*0a6a1f1dSLionel Sambuc   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
943*0a6a1f1dSLionel Sambuc                     Token &DiagToken) override {
944f4a2713aSLionel Sambuc     SourceLocation DiagLoc = DiagToken.getLocation();
945f4a2713aSLionel Sambuc     Token Tok;
946f4a2713aSLionel Sambuc     PP.LexUnexpandedToken(Tok);
947f4a2713aSLionel Sambuc     if (Tok.isNot(tok::identifier)) {
948f4a2713aSLionel Sambuc       PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
949f4a2713aSLionel Sambuc       return;
950f4a2713aSLionel Sambuc     }
951f4a2713aSLionel Sambuc     IdentifierInfo *II = Tok.getIdentifierInfo();
952f4a2713aSLionel Sambuc     PPCallbacks *Callbacks = PP.getPPCallbacks();
953f4a2713aSLionel Sambuc 
954*0a6a1f1dSLionel Sambuc     if (II->isStr("pop")) {
955f4a2713aSLionel Sambuc       if (!PP.getDiagnostics().popMappings(DiagLoc))
956f4a2713aSLionel Sambuc         PP.Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
957f4a2713aSLionel Sambuc       else if (Callbacks)
958f4a2713aSLionel Sambuc         Callbacks->PragmaDiagnosticPop(DiagLoc, Namespace);
959f4a2713aSLionel Sambuc       return;
960f4a2713aSLionel Sambuc     } else if (II->isStr("push")) {
961f4a2713aSLionel Sambuc       PP.getDiagnostics().pushMappings(DiagLoc);
962f4a2713aSLionel Sambuc       if (Callbacks)
963f4a2713aSLionel Sambuc         Callbacks->PragmaDiagnosticPush(DiagLoc, Namespace);
964f4a2713aSLionel Sambuc       return;
965*0a6a1f1dSLionel Sambuc     }
966*0a6a1f1dSLionel Sambuc 
967*0a6a1f1dSLionel Sambuc     diag::Severity SV = llvm::StringSwitch<diag::Severity>(II->getName())
968*0a6a1f1dSLionel Sambuc                             .Case("ignored", diag::Severity::Ignored)
969*0a6a1f1dSLionel Sambuc                             .Case("warning", diag::Severity::Warning)
970*0a6a1f1dSLionel Sambuc                             .Case("error", diag::Severity::Error)
971*0a6a1f1dSLionel Sambuc                             .Case("fatal", diag::Severity::Fatal)
972*0a6a1f1dSLionel Sambuc                             .Default(diag::Severity());
973*0a6a1f1dSLionel Sambuc 
974*0a6a1f1dSLionel Sambuc     if (SV == diag::Severity()) {
975f4a2713aSLionel Sambuc       PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
976f4a2713aSLionel Sambuc       return;
977f4a2713aSLionel Sambuc     }
978f4a2713aSLionel Sambuc 
979f4a2713aSLionel Sambuc     PP.LexUnexpandedToken(Tok);
980f4a2713aSLionel Sambuc     SourceLocation StringLoc = Tok.getLocation();
981f4a2713aSLionel Sambuc 
982f4a2713aSLionel Sambuc     std::string WarningName;
983f4a2713aSLionel Sambuc     if (!PP.FinishLexStringLiteral(Tok, WarningName, "pragma diagnostic",
984f4a2713aSLionel Sambuc                                    /*MacroExpansion=*/false))
985f4a2713aSLionel Sambuc       return;
986f4a2713aSLionel Sambuc 
987f4a2713aSLionel Sambuc     if (Tok.isNot(tok::eod)) {
988f4a2713aSLionel Sambuc       PP.Diag(Tok.getLocation(), diag::warn_pragma_diagnostic_invalid_token);
989f4a2713aSLionel Sambuc       return;
990f4a2713aSLionel Sambuc     }
991f4a2713aSLionel Sambuc 
992f4a2713aSLionel Sambuc     if (WarningName.size() < 3 || WarningName[0] != '-' ||
993*0a6a1f1dSLionel Sambuc         (WarningName[1] != 'W' && WarningName[1] != 'R')) {
994f4a2713aSLionel Sambuc       PP.Diag(StringLoc, diag::warn_pragma_diagnostic_invalid_option);
995f4a2713aSLionel Sambuc       return;
996f4a2713aSLionel Sambuc     }
997f4a2713aSLionel Sambuc 
998*0a6a1f1dSLionel Sambuc     if (PP.getDiagnostics().setSeverityForGroup(
999*0a6a1f1dSLionel Sambuc             WarningName[1] == 'W' ? diag::Flavor::WarningOrError
1000*0a6a1f1dSLionel Sambuc                                   : diag::Flavor::Remark,
1001*0a6a1f1dSLionel Sambuc             WarningName.substr(2), SV, DiagLoc))
1002f4a2713aSLionel Sambuc       PP.Diag(StringLoc, diag::warn_pragma_diagnostic_unknown_warning)
1003f4a2713aSLionel Sambuc         << WarningName;
1004f4a2713aSLionel Sambuc     else if (Callbacks)
1005*0a6a1f1dSLionel Sambuc       Callbacks->PragmaDiagnostic(DiagLoc, Namespace, SV, WarningName);
1006f4a2713aSLionel Sambuc   }
1007f4a2713aSLionel Sambuc };
1008f4a2713aSLionel Sambuc 
1009f4a2713aSLionel Sambuc /// "\#pragma warning(...)".  MSVC's diagnostics do not map cleanly to clang's
1010f4a2713aSLionel Sambuc /// diagnostics, so we don't really implement this pragma.  We parse it and
1011f4a2713aSLionel Sambuc /// ignore it to avoid -Wunknown-pragma warnings.
1012f4a2713aSLionel Sambuc struct PragmaWarningHandler : public PragmaHandler {
PragmaWarningHandler__anon8441e45d0211::PragmaWarningHandler1013f4a2713aSLionel Sambuc   PragmaWarningHandler() : PragmaHandler("warning") {}
1014f4a2713aSLionel Sambuc 
HandlePragma__anon8441e45d0211::PragmaWarningHandler1015*0a6a1f1dSLionel Sambuc   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1016*0a6a1f1dSLionel Sambuc                     Token &Tok) override {
1017f4a2713aSLionel Sambuc     // Parse things like:
1018f4a2713aSLionel Sambuc     // warning(push, 1)
1019f4a2713aSLionel Sambuc     // warning(pop)
1020f4a2713aSLionel Sambuc     // warning(disable : 1 2 3 ; error : 4 5 6 ; suppress : 7 8 9)
1021f4a2713aSLionel Sambuc     SourceLocation DiagLoc = Tok.getLocation();
1022f4a2713aSLionel Sambuc     PPCallbacks *Callbacks = PP.getPPCallbacks();
1023f4a2713aSLionel Sambuc 
1024f4a2713aSLionel Sambuc     PP.Lex(Tok);
1025f4a2713aSLionel Sambuc     if (Tok.isNot(tok::l_paren)) {
1026f4a2713aSLionel Sambuc       PP.Diag(Tok, diag::warn_pragma_warning_expected) << "(";
1027f4a2713aSLionel Sambuc       return;
1028f4a2713aSLionel Sambuc     }
1029f4a2713aSLionel Sambuc 
1030f4a2713aSLionel Sambuc     PP.Lex(Tok);
1031f4a2713aSLionel Sambuc     IdentifierInfo *II = Tok.getIdentifierInfo();
1032f4a2713aSLionel Sambuc     if (!II) {
1033f4a2713aSLionel Sambuc       PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1034f4a2713aSLionel Sambuc       return;
1035f4a2713aSLionel Sambuc     }
1036f4a2713aSLionel Sambuc 
1037f4a2713aSLionel Sambuc     if (II->isStr("push")) {
1038f4a2713aSLionel Sambuc       // #pragma warning( push[ ,n ] )
1039f4a2713aSLionel Sambuc       int Level = -1;
1040f4a2713aSLionel Sambuc       PP.Lex(Tok);
1041f4a2713aSLionel Sambuc       if (Tok.is(tok::comma)) {
1042f4a2713aSLionel Sambuc         PP.Lex(Tok);
1043*0a6a1f1dSLionel Sambuc         uint64_t Value;
1044*0a6a1f1dSLionel Sambuc         if (Tok.is(tok::numeric_constant) &&
1045*0a6a1f1dSLionel Sambuc             PP.parseSimpleIntegerLiteral(Tok, Value))
1046*0a6a1f1dSLionel Sambuc           Level = int(Value);
1047f4a2713aSLionel Sambuc         if (Level < 0 || Level > 4) {
1048f4a2713aSLionel Sambuc           PP.Diag(Tok, diag::warn_pragma_warning_push_level);
1049f4a2713aSLionel Sambuc           return;
1050f4a2713aSLionel Sambuc         }
1051f4a2713aSLionel Sambuc       }
1052f4a2713aSLionel Sambuc       if (Callbacks)
1053f4a2713aSLionel Sambuc         Callbacks->PragmaWarningPush(DiagLoc, Level);
1054f4a2713aSLionel Sambuc     } else if (II->isStr("pop")) {
1055f4a2713aSLionel Sambuc       // #pragma warning( pop )
1056f4a2713aSLionel Sambuc       PP.Lex(Tok);
1057f4a2713aSLionel Sambuc       if (Callbacks)
1058f4a2713aSLionel Sambuc         Callbacks->PragmaWarningPop(DiagLoc);
1059f4a2713aSLionel Sambuc     } else {
1060f4a2713aSLionel Sambuc       // #pragma warning( warning-specifier : warning-number-list
1061f4a2713aSLionel Sambuc       //                  [; warning-specifier : warning-number-list...] )
1062f4a2713aSLionel Sambuc       while (true) {
1063f4a2713aSLionel Sambuc         II = Tok.getIdentifierInfo();
1064f4a2713aSLionel Sambuc         if (!II) {
1065f4a2713aSLionel Sambuc           PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1066f4a2713aSLionel Sambuc           return;
1067f4a2713aSLionel Sambuc         }
1068f4a2713aSLionel Sambuc 
1069f4a2713aSLionel Sambuc         // Figure out which warning specifier this is.
1070f4a2713aSLionel Sambuc         StringRef Specifier = II->getName();
1071f4a2713aSLionel Sambuc         bool SpecifierValid =
1072f4a2713aSLionel Sambuc             llvm::StringSwitch<bool>(Specifier)
1073f4a2713aSLionel Sambuc                 .Cases("1", "2", "3", "4", true)
1074f4a2713aSLionel Sambuc                 .Cases("default", "disable", "error", "once", "suppress", true)
1075f4a2713aSLionel Sambuc                 .Default(false);
1076f4a2713aSLionel Sambuc         if (!SpecifierValid) {
1077f4a2713aSLionel Sambuc           PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1078f4a2713aSLionel Sambuc           return;
1079f4a2713aSLionel Sambuc         }
1080f4a2713aSLionel Sambuc         PP.Lex(Tok);
1081f4a2713aSLionel Sambuc         if (Tok.isNot(tok::colon)) {
1082f4a2713aSLionel Sambuc           PP.Diag(Tok, diag::warn_pragma_warning_expected) << ":";
1083f4a2713aSLionel Sambuc           return;
1084f4a2713aSLionel Sambuc         }
1085f4a2713aSLionel Sambuc 
1086f4a2713aSLionel Sambuc         // Collect the warning ids.
1087f4a2713aSLionel Sambuc         SmallVector<int, 4> Ids;
1088f4a2713aSLionel Sambuc         PP.Lex(Tok);
1089f4a2713aSLionel Sambuc         while (Tok.is(tok::numeric_constant)) {
1090*0a6a1f1dSLionel Sambuc           uint64_t Value;
1091*0a6a1f1dSLionel Sambuc           if (!PP.parseSimpleIntegerLiteral(Tok, Value) || Value == 0 ||
1092*0a6a1f1dSLionel Sambuc               Value > INT_MAX) {
1093f4a2713aSLionel Sambuc             PP.Diag(Tok, diag::warn_pragma_warning_expected_number);
1094f4a2713aSLionel Sambuc             return;
1095f4a2713aSLionel Sambuc           }
1096*0a6a1f1dSLionel Sambuc           Ids.push_back(int(Value));
1097f4a2713aSLionel Sambuc         }
1098f4a2713aSLionel Sambuc         if (Callbacks)
1099f4a2713aSLionel Sambuc           Callbacks->PragmaWarning(DiagLoc, Specifier, Ids);
1100f4a2713aSLionel Sambuc 
1101f4a2713aSLionel Sambuc         // Parse the next specifier if there is a semicolon.
1102f4a2713aSLionel Sambuc         if (Tok.isNot(tok::semi))
1103f4a2713aSLionel Sambuc           break;
1104f4a2713aSLionel Sambuc         PP.Lex(Tok);
1105f4a2713aSLionel Sambuc       }
1106f4a2713aSLionel Sambuc     }
1107f4a2713aSLionel Sambuc 
1108f4a2713aSLionel Sambuc     if (Tok.isNot(tok::r_paren)) {
1109f4a2713aSLionel Sambuc       PP.Diag(Tok, diag::warn_pragma_warning_expected) << ")";
1110f4a2713aSLionel Sambuc       return;
1111f4a2713aSLionel Sambuc     }
1112f4a2713aSLionel Sambuc 
1113f4a2713aSLionel Sambuc     PP.Lex(Tok);
1114f4a2713aSLionel Sambuc     if (Tok.isNot(tok::eod))
1115f4a2713aSLionel Sambuc       PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma warning";
1116f4a2713aSLionel Sambuc   }
1117f4a2713aSLionel Sambuc };
1118f4a2713aSLionel Sambuc 
1119f4a2713aSLionel Sambuc /// PragmaIncludeAliasHandler - "\#pragma include_alias("...")".
1120f4a2713aSLionel Sambuc struct PragmaIncludeAliasHandler : public PragmaHandler {
PragmaIncludeAliasHandler__anon8441e45d0211::PragmaIncludeAliasHandler1121f4a2713aSLionel Sambuc   PragmaIncludeAliasHandler() : PragmaHandler("include_alias") {}
HandlePragma__anon8441e45d0211::PragmaIncludeAliasHandler1122*0a6a1f1dSLionel Sambuc   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1123*0a6a1f1dSLionel Sambuc                     Token &IncludeAliasTok) override {
1124f4a2713aSLionel Sambuc     PP.HandlePragmaIncludeAlias(IncludeAliasTok);
1125f4a2713aSLionel Sambuc   }
1126f4a2713aSLionel Sambuc };
1127f4a2713aSLionel Sambuc 
1128f4a2713aSLionel Sambuc /// PragmaMessageHandler - Handle the microsoft and gcc \#pragma message
1129f4a2713aSLionel Sambuc /// extension.  The syntax is:
1130f4a2713aSLionel Sambuc /// \code
1131f4a2713aSLionel Sambuc ///   #pragma message(string)
1132f4a2713aSLionel Sambuc /// \endcode
1133f4a2713aSLionel Sambuc /// OR, in GCC mode:
1134f4a2713aSLionel Sambuc /// \code
1135f4a2713aSLionel Sambuc ///   #pragma message string
1136f4a2713aSLionel Sambuc /// \endcode
1137f4a2713aSLionel Sambuc /// string is a string, which is fully macro expanded, and permits string
1138f4a2713aSLionel Sambuc /// concatenation, embedded escape characters, etc... See MSDN for more details.
1139f4a2713aSLionel Sambuc /// Also handles \#pragma GCC warning and \#pragma GCC error which take the same
1140f4a2713aSLionel Sambuc /// form as \#pragma message.
1141f4a2713aSLionel Sambuc struct PragmaMessageHandler : public PragmaHandler {
1142f4a2713aSLionel Sambuc private:
1143f4a2713aSLionel Sambuc   const PPCallbacks::PragmaMessageKind Kind;
1144f4a2713aSLionel Sambuc   const StringRef Namespace;
1145f4a2713aSLionel Sambuc 
PragmaKind__anon8441e45d0211::PragmaMessageHandler1146f4a2713aSLionel Sambuc   static const char* PragmaKind(PPCallbacks::PragmaMessageKind Kind,
1147f4a2713aSLionel Sambuc                                 bool PragmaNameOnly = false) {
1148f4a2713aSLionel Sambuc     switch (Kind) {
1149f4a2713aSLionel Sambuc       case PPCallbacks::PMK_Message:
1150f4a2713aSLionel Sambuc         return PragmaNameOnly ? "message" : "pragma message";
1151f4a2713aSLionel Sambuc       case PPCallbacks::PMK_Warning:
1152f4a2713aSLionel Sambuc         return PragmaNameOnly ? "warning" : "pragma warning";
1153f4a2713aSLionel Sambuc       case PPCallbacks::PMK_Error:
1154f4a2713aSLionel Sambuc         return PragmaNameOnly ? "error" : "pragma error";
1155f4a2713aSLionel Sambuc     }
1156f4a2713aSLionel Sambuc     llvm_unreachable("Unknown PragmaMessageKind!");
1157f4a2713aSLionel Sambuc   }
1158f4a2713aSLionel Sambuc 
1159f4a2713aSLionel Sambuc public:
PragmaMessageHandler__anon8441e45d0211::PragmaMessageHandler1160f4a2713aSLionel Sambuc   PragmaMessageHandler(PPCallbacks::PragmaMessageKind Kind,
1161f4a2713aSLionel Sambuc                        StringRef Namespace = StringRef())
1162f4a2713aSLionel Sambuc     : PragmaHandler(PragmaKind(Kind, true)), Kind(Kind), Namespace(Namespace) {}
1163f4a2713aSLionel Sambuc 
HandlePragma__anon8441e45d0211::PragmaMessageHandler1164*0a6a1f1dSLionel Sambuc   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1165*0a6a1f1dSLionel Sambuc                     Token &Tok) override {
1166f4a2713aSLionel Sambuc     SourceLocation MessageLoc = Tok.getLocation();
1167f4a2713aSLionel Sambuc     PP.Lex(Tok);
1168f4a2713aSLionel Sambuc     bool ExpectClosingParen = false;
1169f4a2713aSLionel Sambuc     switch (Tok.getKind()) {
1170f4a2713aSLionel Sambuc     case tok::l_paren:
1171f4a2713aSLionel Sambuc       // We have a MSVC style pragma message.
1172f4a2713aSLionel Sambuc       ExpectClosingParen = true;
1173f4a2713aSLionel Sambuc       // Read the string.
1174f4a2713aSLionel Sambuc       PP.Lex(Tok);
1175f4a2713aSLionel Sambuc       break;
1176f4a2713aSLionel Sambuc     case tok::string_literal:
1177f4a2713aSLionel Sambuc       // We have a GCC style pragma message, and we just read the string.
1178f4a2713aSLionel Sambuc       break;
1179f4a2713aSLionel Sambuc     default:
1180f4a2713aSLionel Sambuc       PP.Diag(MessageLoc, diag::err_pragma_message_malformed) << Kind;
1181f4a2713aSLionel Sambuc       return;
1182f4a2713aSLionel Sambuc     }
1183f4a2713aSLionel Sambuc 
1184f4a2713aSLionel Sambuc     std::string MessageString;
1185f4a2713aSLionel Sambuc     if (!PP.FinishLexStringLiteral(Tok, MessageString, PragmaKind(Kind),
1186f4a2713aSLionel Sambuc                                    /*MacroExpansion=*/true))
1187f4a2713aSLionel Sambuc       return;
1188f4a2713aSLionel Sambuc 
1189f4a2713aSLionel Sambuc     if (ExpectClosingParen) {
1190f4a2713aSLionel Sambuc       if (Tok.isNot(tok::r_paren)) {
1191f4a2713aSLionel Sambuc         PP.Diag(Tok.getLocation(), diag::err_pragma_message_malformed) << Kind;
1192f4a2713aSLionel Sambuc         return;
1193f4a2713aSLionel Sambuc       }
1194f4a2713aSLionel Sambuc       PP.Lex(Tok);  // eat the r_paren.
1195f4a2713aSLionel Sambuc     }
1196f4a2713aSLionel Sambuc 
1197f4a2713aSLionel Sambuc     if (Tok.isNot(tok::eod)) {
1198f4a2713aSLionel Sambuc       PP.Diag(Tok.getLocation(), diag::err_pragma_message_malformed) << Kind;
1199f4a2713aSLionel Sambuc       return;
1200f4a2713aSLionel Sambuc     }
1201f4a2713aSLionel Sambuc 
1202f4a2713aSLionel Sambuc     // Output the message.
1203f4a2713aSLionel Sambuc     PP.Diag(MessageLoc, (Kind == PPCallbacks::PMK_Error)
1204f4a2713aSLionel Sambuc                           ? diag::err_pragma_message
1205f4a2713aSLionel Sambuc                           : diag::warn_pragma_message) << MessageString;
1206f4a2713aSLionel Sambuc 
1207f4a2713aSLionel Sambuc     // If the pragma is lexically sound, notify any interested PPCallbacks.
1208f4a2713aSLionel Sambuc     if (PPCallbacks *Callbacks = PP.getPPCallbacks())
1209f4a2713aSLionel Sambuc       Callbacks->PragmaMessage(MessageLoc, Namespace, Kind, MessageString);
1210f4a2713aSLionel Sambuc   }
1211f4a2713aSLionel Sambuc };
1212f4a2713aSLionel Sambuc 
1213f4a2713aSLionel Sambuc /// PragmaPushMacroHandler - "\#pragma push_macro" saves the value of the
1214f4a2713aSLionel Sambuc /// macro on the top of the stack.
1215f4a2713aSLionel Sambuc struct PragmaPushMacroHandler : public PragmaHandler {
PragmaPushMacroHandler__anon8441e45d0211::PragmaPushMacroHandler1216f4a2713aSLionel Sambuc   PragmaPushMacroHandler() : PragmaHandler("push_macro") {}
HandlePragma__anon8441e45d0211::PragmaPushMacroHandler1217*0a6a1f1dSLionel Sambuc   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1218*0a6a1f1dSLionel Sambuc                     Token &PushMacroTok) override {
1219f4a2713aSLionel Sambuc     PP.HandlePragmaPushMacro(PushMacroTok);
1220f4a2713aSLionel Sambuc   }
1221f4a2713aSLionel Sambuc };
1222f4a2713aSLionel Sambuc 
1223f4a2713aSLionel Sambuc 
1224f4a2713aSLionel Sambuc /// PragmaPopMacroHandler - "\#pragma pop_macro" sets the value of the
1225f4a2713aSLionel Sambuc /// macro to the value on the top of the stack.
1226f4a2713aSLionel Sambuc struct PragmaPopMacroHandler : public PragmaHandler {
PragmaPopMacroHandler__anon8441e45d0211::PragmaPopMacroHandler1227f4a2713aSLionel Sambuc   PragmaPopMacroHandler() : PragmaHandler("pop_macro") {}
HandlePragma__anon8441e45d0211::PragmaPopMacroHandler1228*0a6a1f1dSLionel Sambuc   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1229*0a6a1f1dSLionel Sambuc                     Token &PopMacroTok) override {
1230f4a2713aSLionel Sambuc     PP.HandlePragmaPopMacro(PopMacroTok);
1231f4a2713aSLionel Sambuc   }
1232f4a2713aSLionel Sambuc };
1233f4a2713aSLionel Sambuc 
1234f4a2713aSLionel Sambuc // Pragma STDC implementations.
1235f4a2713aSLionel Sambuc 
1236f4a2713aSLionel Sambuc /// PragmaSTDC_FENV_ACCESSHandler - "\#pragma STDC FENV_ACCESS ...".
1237f4a2713aSLionel Sambuc struct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler {
PragmaSTDC_FENV_ACCESSHandler__anon8441e45d0211::PragmaSTDC_FENV_ACCESSHandler1238f4a2713aSLionel Sambuc   PragmaSTDC_FENV_ACCESSHandler() : PragmaHandler("FENV_ACCESS") {}
HandlePragma__anon8441e45d0211::PragmaSTDC_FENV_ACCESSHandler1239*0a6a1f1dSLionel Sambuc   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1240*0a6a1f1dSLionel Sambuc                     Token &Tok) override {
1241f4a2713aSLionel Sambuc     tok::OnOffSwitch OOS;
1242f4a2713aSLionel Sambuc     if (PP.LexOnOffSwitch(OOS))
1243f4a2713aSLionel Sambuc      return;
1244f4a2713aSLionel Sambuc     if (OOS == tok::OOS_ON)
1245f4a2713aSLionel Sambuc       PP.Diag(Tok, diag::warn_stdc_fenv_access_not_supported);
1246f4a2713aSLionel Sambuc   }
1247f4a2713aSLionel Sambuc };
1248f4a2713aSLionel Sambuc 
1249f4a2713aSLionel Sambuc /// PragmaSTDC_CX_LIMITED_RANGEHandler - "\#pragma STDC CX_LIMITED_RANGE ...".
1250f4a2713aSLionel Sambuc struct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler {
PragmaSTDC_CX_LIMITED_RANGEHandler__anon8441e45d0211::PragmaSTDC_CX_LIMITED_RANGEHandler1251f4a2713aSLionel Sambuc   PragmaSTDC_CX_LIMITED_RANGEHandler()
1252f4a2713aSLionel Sambuc     : PragmaHandler("CX_LIMITED_RANGE") {}
HandlePragma__anon8441e45d0211::PragmaSTDC_CX_LIMITED_RANGEHandler1253*0a6a1f1dSLionel Sambuc   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1254*0a6a1f1dSLionel Sambuc                     Token &Tok) override {
1255f4a2713aSLionel Sambuc     tok::OnOffSwitch OOS;
1256f4a2713aSLionel Sambuc     PP.LexOnOffSwitch(OOS);
1257f4a2713aSLionel Sambuc   }
1258f4a2713aSLionel Sambuc };
1259f4a2713aSLionel Sambuc 
1260f4a2713aSLionel Sambuc /// PragmaSTDC_UnknownHandler - "\#pragma STDC ...".
1261f4a2713aSLionel Sambuc struct PragmaSTDC_UnknownHandler : public PragmaHandler {
PragmaSTDC_UnknownHandler__anon8441e45d0211::PragmaSTDC_UnknownHandler1262f4a2713aSLionel Sambuc   PragmaSTDC_UnknownHandler() {}
HandlePragma__anon8441e45d0211::PragmaSTDC_UnknownHandler1263*0a6a1f1dSLionel Sambuc   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1264*0a6a1f1dSLionel Sambuc                     Token &UnknownTok) override {
1265f4a2713aSLionel Sambuc     // C99 6.10.6p2, unknown forms are not allowed.
1266f4a2713aSLionel Sambuc     PP.Diag(UnknownTok, diag::ext_stdc_pragma_ignored);
1267f4a2713aSLionel Sambuc   }
1268f4a2713aSLionel Sambuc };
1269f4a2713aSLionel Sambuc 
1270f4a2713aSLionel Sambuc /// PragmaARCCFCodeAuditedHandler -
1271f4a2713aSLionel Sambuc ///   \#pragma clang arc_cf_code_audited begin/end
1272f4a2713aSLionel Sambuc struct PragmaARCCFCodeAuditedHandler : public PragmaHandler {
PragmaARCCFCodeAuditedHandler__anon8441e45d0211::PragmaARCCFCodeAuditedHandler1273f4a2713aSLionel Sambuc   PragmaARCCFCodeAuditedHandler() : PragmaHandler("arc_cf_code_audited") {}
HandlePragma__anon8441e45d0211::PragmaARCCFCodeAuditedHandler1274*0a6a1f1dSLionel Sambuc   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1275*0a6a1f1dSLionel Sambuc                     Token &NameTok) override {
1276f4a2713aSLionel Sambuc     SourceLocation Loc = NameTok.getLocation();
1277f4a2713aSLionel Sambuc     bool IsBegin;
1278f4a2713aSLionel Sambuc 
1279f4a2713aSLionel Sambuc     Token Tok;
1280f4a2713aSLionel Sambuc 
1281f4a2713aSLionel Sambuc     // Lex the 'begin' or 'end'.
1282f4a2713aSLionel Sambuc     PP.LexUnexpandedToken(Tok);
1283f4a2713aSLionel Sambuc     const IdentifierInfo *BeginEnd = Tok.getIdentifierInfo();
1284f4a2713aSLionel Sambuc     if (BeginEnd && BeginEnd->isStr("begin")) {
1285f4a2713aSLionel Sambuc       IsBegin = true;
1286f4a2713aSLionel Sambuc     } else if (BeginEnd && BeginEnd->isStr("end")) {
1287f4a2713aSLionel Sambuc       IsBegin = false;
1288f4a2713aSLionel Sambuc     } else {
1289f4a2713aSLionel Sambuc       PP.Diag(Tok.getLocation(), diag::err_pp_arc_cf_code_audited_syntax);
1290f4a2713aSLionel Sambuc       return;
1291f4a2713aSLionel Sambuc     }
1292f4a2713aSLionel Sambuc 
1293f4a2713aSLionel Sambuc     // Verify that this is followed by EOD.
1294f4a2713aSLionel Sambuc     PP.LexUnexpandedToken(Tok);
1295f4a2713aSLionel Sambuc     if (Tok.isNot(tok::eod))
1296f4a2713aSLionel Sambuc       PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";
1297f4a2713aSLionel Sambuc 
1298f4a2713aSLionel Sambuc     // The start location of the active audit.
1299f4a2713aSLionel Sambuc     SourceLocation BeginLoc = PP.getPragmaARCCFCodeAuditedLoc();
1300f4a2713aSLionel Sambuc 
1301f4a2713aSLionel Sambuc     // The start location we want after processing this.
1302f4a2713aSLionel Sambuc     SourceLocation NewLoc;
1303f4a2713aSLionel Sambuc 
1304f4a2713aSLionel Sambuc     if (IsBegin) {
1305f4a2713aSLionel Sambuc       // Complain about attempts to re-enter an audit.
1306f4a2713aSLionel Sambuc       if (BeginLoc.isValid()) {
1307f4a2713aSLionel Sambuc         PP.Diag(Loc, diag::err_pp_double_begin_of_arc_cf_code_audited);
1308f4a2713aSLionel Sambuc         PP.Diag(BeginLoc, diag::note_pragma_entered_here);
1309f4a2713aSLionel Sambuc       }
1310f4a2713aSLionel Sambuc       NewLoc = Loc;
1311f4a2713aSLionel Sambuc     } else {
1312f4a2713aSLionel Sambuc       // Complain about attempts to leave an audit that doesn't exist.
1313f4a2713aSLionel Sambuc       if (!BeginLoc.isValid()) {
1314f4a2713aSLionel Sambuc         PP.Diag(Loc, diag::err_pp_unmatched_end_of_arc_cf_code_audited);
1315f4a2713aSLionel Sambuc         return;
1316f4a2713aSLionel Sambuc       }
1317f4a2713aSLionel Sambuc       NewLoc = SourceLocation();
1318f4a2713aSLionel Sambuc     }
1319f4a2713aSLionel Sambuc 
1320f4a2713aSLionel Sambuc     PP.setPragmaARCCFCodeAuditedLoc(NewLoc);
1321f4a2713aSLionel Sambuc   }
1322f4a2713aSLionel Sambuc };
1323f4a2713aSLionel Sambuc 
1324f4a2713aSLionel Sambuc /// \brief Handle "\#pragma region [...]"
1325f4a2713aSLionel Sambuc ///
1326f4a2713aSLionel Sambuc /// The syntax is
1327f4a2713aSLionel Sambuc /// \code
1328f4a2713aSLionel Sambuc ///   #pragma region [optional name]
1329f4a2713aSLionel Sambuc ///   #pragma endregion [optional comment]
1330f4a2713aSLionel Sambuc /// \endcode
1331f4a2713aSLionel Sambuc ///
1332f4a2713aSLionel Sambuc /// \note This is
1333f4a2713aSLionel Sambuc /// <a href="http://msdn.microsoft.com/en-us/library/b6xkz944(v=vs.80).aspx">editor-only</a>
1334f4a2713aSLionel Sambuc /// pragma, just skipped by compiler.
1335f4a2713aSLionel Sambuc struct PragmaRegionHandler : public PragmaHandler {
PragmaRegionHandler__anon8441e45d0211::PragmaRegionHandler1336f4a2713aSLionel Sambuc   PragmaRegionHandler(const char *pragma) : PragmaHandler(pragma) { }
1337f4a2713aSLionel Sambuc 
HandlePragma__anon8441e45d0211::PragmaRegionHandler1338*0a6a1f1dSLionel Sambuc   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1339*0a6a1f1dSLionel Sambuc                     Token &NameTok) override {
1340f4a2713aSLionel Sambuc     // #pragma region: endregion matches can be verified
1341f4a2713aSLionel Sambuc     // __pragma(region): no sense, but ignored by msvc
1342f4a2713aSLionel Sambuc     // _Pragma is not valid for MSVC, but there isn't any point
1343f4a2713aSLionel Sambuc     // to handle a _Pragma differently.
1344f4a2713aSLionel Sambuc   }
1345f4a2713aSLionel Sambuc };
1346f4a2713aSLionel Sambuc 
1347f4a2713aSLionel Sambuc }  // end anonymous namespace
1348f4a2713aSLionel Sambuc 
1349f4a2713aSLionel Sambuc 
1350f4a2713aSLionel Sambuc /// RegisterBuiltinPragmas - Install the standard preprocessor pragmas:
1351f4a2713aSLionel Sambuc /// \#pragma GCC poison/system_header/dependency and \#pragma once.
RegisterBuiltinPragmas()1352f4a2713aSLionel Sambuc void Preprocessor::RegisterBuiltinPragmas() {
1353f4a2713aSLionel Sambuc   AddPragmaHandler(new PragmaOnceHandler());
1354f4a2713aSLionel Sambuc   AddPragmaHandler(new PragmaMarkHandler());
1355f4a2713aSLionel Sambuc   AddPragmaHandler(new PragmaPushMacroHandler());
1356f4a2713aSLionel Sambuc   AddPragmaHandler(new PragmaPopMacroHandler());
1357f4a2713aSLionel Sambuc   AddPragmaHandler(new PragmaMessageHandler(PPCallbacks::PMK_Message));
1358f4a2713aSLionel Sambuc 
1359f4a2713aSLionel Sambuc   // #pragma GCC ...
1360f4a2713aSLionel Sambuc   AddPragmaHandler("GCC", new PragmaPoisonHandler());
1361f4a2713aSLionel Sambuc   AddPragmaHandler("GCC", new PragmaSystemHeaderHandler());
1362f4a2713aSLionel Sambuc   AddPragmaHandler("GCC", new PragmaDependencyHandler());
1363f4a2713aSLionel Sambuc   AddPragmaHandler("GCC", new PragmaDiagnosticHandler("GCC"));
1364f4a2713aSLionel Sambuc   AddPragmaHandler("GCC", new PragmaMessageHandler(PPCallbacks::PMK_Warning,
1365f4a2713aSLionel Sambuc                                                    "GCC"));
1366f4a2713aSLionel Sambuc   AddPragmaHandler("GCC", new PragmaMessageHandler(PPCallbacks::PMK_Error,
1367f4a2713aSLionel Sambuc                                                    "GCC"));
1368f4a2713aSLionel Sambuc   // #pragma clang ...
1369f4a2713aSLionel Sambuc   AddPragmaHandler("clang", new PragmaPoisonHandler());
1370f4a2713aSLionel Sambuc   AddPragmaHandler("clang", new PragmaSystemHeaderHandler());
1371f4a2713aSLionel Sambuc   AddPragmaHandler("clang", new PragmaDebugHandler());
1372f4a2713aSLionel Sambuc   AddPragmaHandler("clang", new PragmaDependencyHandler());
1373f4a2713aSLionel Sambuc   AddPragmaHandler("clang", new PragmaDiagnosticHandler("clang"));
1374f4a2713aSLionel Sambuc   AddPragmaHandler("clang", new PragmaARCCFCodeAuditedHandler());
1375f4a2713aSLionel Sambuc 
1376f4a2713aSLionel Sambuc   AddPragmaHandler("STDC", new PragmaSTDC_FENV_ACCESSHandler());
1377f4a2713aSLionel Sambuc   AddPragmaHandler("STDC", new PragmaSTDC_CX_LIMITED_RANGEHandler());
1378f4a2713aSLionel Sambuc   AddPragmaHandler("STDC", new PragmaSTDC_UnknownHandler());
1379f4a2713aSLionel Sambuc 
1380f4a2713aSLionel Sambuc   // MS extensions.
1381f4a2713aSLionel Sambuc   if (LangOpts.MicrosoftExt) {
1382f4a2713aSLionel Sambuc     AddPragmaHandler(new PragmaWarningHandler());
1383f4a2713aSLionel Sambuc     AddPragmaHandler(new PragmaIncludeAliasHandler());
1384f4a2713aSLionel Sambuc     AddPragmaHandler(new PragmaRegionHandler("region"));
1385f4a2713aSLionel Sambuc     AddPragmaHandler(new PragmaRegionHandler("endregion"));
1386f4a2713aSLionel Sambuc   }
1387f4a2713aSLionel Sambuc }
1388*0a6a1f1dSLionel Sambuc 
1389*0a6a1f1dSLionel Sambuc /// Ignore all pragmas, useful for modes such as -Eonly which would otherwise
1390*0a6a1f1dSLionel Sambuc /// warn about those pragmas being unknown.
IgnorePragmas()1391*0a6a1f1dSLionel Sambuc void Preprocessor::IgnorePragmas() {
1392*0a6a1f1dSLionel Sambuc   AddPragmaHandler(new EmptyPragmaHandler());
1393*0a6a1f1dSLionel Sambuc   // Also ignore all pragmas in all namespaces created
1394*0a6a1f1dSLionel Sambuc   // in Preprocessor::RegisterBuiltinPragmas().
1395*0a6a1f1dSLionel Sambuc   AddPragmaHandler("GCC", new EmptyPragmaHandler());
1396*0a6a1f1dSLionel Sambuc   AddPragmaHandler("clang", new EmptyPragmaHandler());
1397*0a6a1f1dSLionel Sambuc   if (PragmaHandler *NS = PragmaHandlers->FindHandler("STDC")) {
1398*0a6a1f1dSLionel Sambuc     // Preprocessor::RegisterBuiltinPragmas() already registers
1399*0a6a1f1dSLionel Sambuc     // PragmaSTDC_UnknownHandler as the empty handler, so remove it first,
1400*0a6a1f1dSLionel Sambuc     // otherwise there will be an assert about a duplicate handler.
1401*0a6a1f1dSLionel Sambuc     PragmaNamespace *STDCNamespace = NS->getIfNamespace();
1402*0a6a1f1dSLionel Sambuc     assert(STDCNamespace &&
1403*0a6a1f1dSLionel Sambuc            "Invalid namespace, registered as a regular pragma handler!");
1404*0a6a1f1dSLionel Sambuc     if (PragmaHandler *Existing = STDCNamespace->FindHandler("", false)) {
1405*0a6a1f1dSLionel Sambuc       RemovePragmaHandler("STDC", Existing);
1406*0a6a1f1dSLionel Sambuc       delete Existing;
1407*0a6a1f1dSLionel Sambuc     }
1408*0a6a1f1dSLionel Sambuc   }
1409*0a6a1f1dSLionel Sambuc   AddPragmaHandler("STDC", new EmptyPragmaHandler());
1410*0a6a1f1dSLionel Sambuc }
1411