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