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