Pragma.cpp revision b6d6993e6e6d3daf4d9876794254d20a134e37c2
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- Pragma.cpp - Pragma registration and handling --------------------===//
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                     The LLVM Compiler Infrastructure
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This file implements the PragmaHandler/PragmaTable interfaces and implements
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// pragma related methods of the Preprocessor class.
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Lex/Pragma.h"
1655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/FileManager.h"
1755fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/SourceManager.h"
185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Lex/HeaderSearch.h"
1955fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Lex/LexDiagnostic.h"
20a9d9145741ef77db45890911674705b81605b10bChris Lattner#include "clang/Lex/LiteralSupport.h"
21f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner#include "clang/Lex/MacroInfo.h"
2255fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Lex/Preprocessor.h"
232ee042dee9f7693665e28463955401905474a284Reid Kleckner#include "llvm/ADT/STLExtras.h"
242ee042dee9f7693665e28463955401905474a284Reid Kleckner#include "llvm/ADT/StringSwitch.h"
25b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar#include "llvm/ADT/StringExtras.h"
26ff759a66526d6a985fb4efae69c6b798d83364dfDaniel Dunbar#include "llvm/Support/CrashRecoveryContext.h"
275505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar#include "llvm/Support/ErrorHandling.h"
282e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor#include <algorithm>
295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang;
305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
312ee042dee9f7693665e28463955401905474a284Reid Kleckner#include "llvm/Support/raw_ostream.h"
322ee042dee9f7693665e28463955401905474a284Reid Kleckner
335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Out-of-line destructor to provide a home for the class.
345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerPragmaHandler::~PragmaHandler() {
355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
38c72cc5072cdc1a1a6e05f9d0f962f293a69248c4Daniel Dunbar// EmptyPragmaHandler Implementation.
39c72cc5072cdc1a1a6e05f9d0f962f293a69248c4Daniel Dunbar//===----------------------------------------------------------------------===//
40c72cc5072cdc1a1a6e05f9d0f962f293a69248c4Daniel Dunbar
419b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios KyrtzidisEmptyPragmaHandler::EmptyPragmaHandler() {}
42c72cc5072cdc1a1a6e05f9d0f962f293a69248c4Daniel Dunbar
4380c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregorvoid EmptyPragmaHandler::HandlePragma(Preprocessor &PP,
4480c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                                      PragmaIntroducerKind Introducer,
4580c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                                      Token &FirstToken) {}
46c72cc5072cdc1a1a6e05f9d0f962f293a69248c4Daniel Dunbar
47c72cc5072cdc1a1a6e05f9d0f962f293a69248c4Daniel Dunbar//===----------------------------------------------------------------------===//
485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// PragmaNamespace Implementation.
495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerPragmaNamespace::~PragmaNamespace() {
52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  llvm::DeleteContainerSeconds(Handlers);
535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// FindHandler - Check to see if there is already a handler for the
565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// specified name.  If not, return the handler for the null identifier if it
575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// exists, otherwise return null.  If IgnoreNull is true (the default) then
585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// the null handler isn't returned on failure to match.
595f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerPragmaHandler *PragmaNamespace::FindHandler(StringRef Name,
605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                            bool IgnoreNull) const {
619b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  if (PragmaHandler *Handler = Handlers.lookup(Name))
629b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis    return Handler;
636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return IgnoreNull ? nullptr : Handlers.lookup(StringRef());
649b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis}
651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
669b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidisvoid PragmaNamespace::AddPragma(PragmaHandler *Handler) {
679b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  assert(!Handlers.lookup(Handler->getName()) &&
689b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis         "A handler with this name is already registered in this namespace");
69176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  Handlers[Handler->getName()] = Handler;
705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
724095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbarvoid PragmaNamespace::RemovePragmaHandler(PragmaHandler *Handler) {
739b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  assert(Handlers.lookup(Handler->getName()) &&
749b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis         "Handler not registered in this namespace");
759b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  Handlers.erase(Handler->getName());
764095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar}
774095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar
7880c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregorvoid PragmaNamespace::HandlePragma(Preprocessor &PP,
7980c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                                   PragmaIntroducerKind Introducer,
8080c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                                   Token &Tok) {
815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Read the 'namespace' that the directive is in, e.g. STDC.  Do not macro
825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // expand it, the user can have a STDC #define, that should not affect this.
835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  PP.LexUnexpandedToken(Tok);
841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Get the handler for this token.  If there is no handler, ignore the pragma.
869b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaHandler *Handler
879b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis    = FindHandler(Tok.getIdentifierInfo() ? Tok.getIdentifierInfo()->getName()
885f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                          : StringRef(),
899b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis                  /*IgnoreNull=*/false);
906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (!Handler) {
91af7cdf45da4925f788e87a4c318ee67404646088Chris Lattner    PP.Diag(Tok, diag::warn_pragma_ignored);
92af7cdf45da4925f788e87a4c318ee67404646088Chris Lattner    return;
93af7cdf45da4925f788e87a4c318ee67404646088Chris Lattner  }
941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Otherwise, pass it down.
9680c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  Handler->HandlePragma(PP, Introducer, Tok);
975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
1005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Preprocessor Pragma Directive Handling.
1015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
1025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
103b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// HandlePragmaDirective - The "\#pragma" directive has been parsed.  Lex the
1045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// rest of the pragma, passing it to the registered pragma handlers.
1050189fd61ec72d86e008aa5615be80581f84cf703Enea Zaffanellavoid Preprocessor::HandlePragmaDirective(SourceLocation IntroducerLoc,
1060189fd61ec72d86e008aa5615be80581f84cf703Enea Zaffanella                                         PragmaIntroducerKind Introducer) {
1070189fd61ec72d86e008aa5615be80581f84cf703Enea Zaffanella  if (Callbacks)
1080189fd61ec72d86e008aa5615be80581f84cf703Enea Zaffanella    Callbacks->PragmaDirective(IntroducerLoc, Introducer);
1090189fd61ec72d86e008aa5615be80581f84cf703Enea Zaffanella
1106fe6a49c4058211ff4489023c78615ec0266c5ffJordan Rose  if (!PragmasEnabled)
1116fe6a49c4058211ff4489023c78615ec0266c5ffJordan Rose    return;
1126fe6a49c4058211ff4489023c78615ec0266c5ffJordan Rose
1135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ++NumPragma;
1141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Invoke the first level of pragma handlers which reads the namespace id.
116d217773f106856a11879ec79dc468efefaf2ee75Chris Lattner  Token Tok;
1170189fd61ec72d86e008aa5615be80581f84cf703Enea Zaffanella  PragmaHandlers->HandlePragma(*this, Introducer, Tok);
1181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If the pragma handler didn't read the rest of the line, consume it now.
120b2eb53d9fd973a1a02e05e67a3307b3efd12eff2Peter Collingbourne  if ((CurTokenLexer && CurTokenLexer->isParsingPreprocessorDirective())
121b2eb53d9fd973a1a02e05e67a3307b3efd12eff2Peter Collingbourne   || (CurPPLexer && CurPPLexer->ParsingPreprocessorDirective))
1225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    DiscardUntilEndOfDirective();
1235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
12514e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidisnamespace {
12614e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis/// \brief Helper class for \see Preprocessor::Handle_Pragma.
12714e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidisclass LexingFor_PragmaRAII {
12814e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  Preprocessor &PP;
12914e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  bool InMacroArgPreExpansion;
13014e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  bool Failed;
13114e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  Token &OutTok;
13214e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  Token PragmaTok;
13314e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis
13414e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidispublic:
13514e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  LexingFor_PragmaRAII(Preprocessor &PP, bool InMacroArgPreExpansion,
13614e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis                       Token &Tok)
13714e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    : PP(PP), InMacroArgPreExpansion(InMacroArgPreExpansion),
13814e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis      Failed(false), OutTok(Tok) {
13914e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    if (InMacroArgPreExpansion) {
14014e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis      PragmaTok = OutTok;
14114e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis      PP.EnableBacktrackAtThisPos();
14214e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    }
14314e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  }
14414e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis
14514e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  ~LexingFor_PragmaRAII() {
14614e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    if (InMacroArgPreExpansion) {
14714e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis      if (Failed) {
14814e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis        PP.CommitBacktrackedTokens();
14914e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis      } else {
15014e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis        PP.Backtrack();
15114e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis        OutTok = PragmaTok;
15214e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis      }
15314e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    }
15414e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  }
15514e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis
15614e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  void failed() {
15714e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    Failed = true;
15814e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  }
15914e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis};
16014e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis}
16114e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis
1625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Handle_Pragma - Read a _Pragma directive, slice it up, process it, then
1635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// return the first token after the directive.  The _Pragma token has just
1645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// been read into 'Tok'.
165d217773f106856a11879ec79dc468efefaf2ee75Chris Lattnervoid Preprocessor::Handle_Pragma(Token &Tok) {
16614e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis
16714e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  // This works differently if we are pre-expanding a macro argument.
16814e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  // In that case we don't actually "activate" the pragma now, we only lex it
16914e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  // until we are sure it is lexically correct and then we backtrack so that
17014e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  // we activate the pragma whenever we encounter the tokens again in the token
17114e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  // stream. This ensures that we will activate it in the correct location
17214e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  // or that we will ignore it if it never enters the token stream, e.g:
17314e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  //
17414e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  //     #define EMPTY(x)
17514e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  //     #define INACTIVE(x) EMPTY(x)
17614e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  //     INACTIVE(_Pragma("clang diagnostic ignored \"-Wconversion\""))
17714e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis
17814e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  LexingFor_PragmaRAII _PragmaLexing(*this, InMacroArgPreExpansion, Tok);
17914e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis
1805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Remember the pragma token location.
1815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation PragmaLoc = Tok.getLocation();
1821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Read the '('.
1845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Lex(Tok);
1853692b09faa9fe346f39bc922db6dce48cdcc3f63Chris Lattner  if (Tok.isNot(tok::l_paren)) {
1863692b09faa9fe346f39bc922db6dce48cdcc3f63Chris Lattner    Diag(PragmaLoc, diag::err__Pragma_malformed);
18714e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    return _PragmaLexing.failed();
1883692b09faa9fe346f39bc922db6dce48cdcc3f63Chris Lattner  }
1895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Read the '"..."'.
1915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Lex(Tok);
1920b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith  if (!tok::isStringLiteral(Tok.getKind())) {
1933692b09faa9fe346f39bc922db6dce48cdcc3f63Chris Lattner    Diag(PragmaLoc, diag::err__Pragma_malformed);
19499831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    // Skip this token, and the ')', if present.
195176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::eof))
19699831e4677a7e2e051af636221694d60ba31fcdbRichard Smith      Lex(Tok);
19799831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    if (Tok.is(tok::r_paren))
19899831e4677a7e2e051af636221694d60ba31fcdbRichard Smith      Lex(Tok);
19914e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    return _PragmaLexing.failed();
20099831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  }
20199831e4677a7e2e051af636221694d60ba31fcdbRichard Smith
20299831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  if (Tok.hasUDSuffix()) {
20399831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    Diag(Tok, diag::err_invalid_string_udl);
20499831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    // Skip this token, and the ')', if present.
20599831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    Lex(Tok);
20699831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    if (Tok.is(tok::r_paren))
20799831e4677a7e2e051af636221694d60ba31fcdbRichard Smith      Lex(Tok);
20814e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    return _PragmaLexing.failed();
2093692b09faa9fe346f39bc922db6dce48cdcc3f63Chris Lattner  }
2101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Remember the string.
21214e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  Token StrTok = Tok;
2135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Read the ')'.
2155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Lex(Tok);
2163692b09faa9fe346f39bc922db6dce48cdcc3f63Chris Lattner  if (Tok.isNot(tok::r_paren)) {
2173692b09faa9fe346f39bc922db6dce48cdcc3f63Chris Lattner    Diag(PragmaLoc, diag::err__Pragma_malformed);
21814e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    return _PragmaLexing.failed();
2193692b09faa9fe346f39bc922db6dce48cdcc3f63Chris Lattner  }
2201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
22114e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  if (InMacroArgPreExpansion)
22214e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    return;
22314e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis
224e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner  SourceLocation RParenLoc = Tok.getLocation();
22514e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  std::string StrVal = getSpelling(StrTok);
2261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2270b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith  // The _Pragma is lexically sound.  Destringize according to C11 6.10.9.1:
2280b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith  // "The string literal is destringized by deleting any encoding prefix,
229a9d9145741ef77db45890911674705b81605b10bChris Lattner  // deleting the leading and trailing double-quotes, replacing each escape
230a9d9145741ef77db45890911674705b81605b10bChris Lattner  // sequence \" by a double-quote, and replacing each escape sequence \\ by a
231a9d9145741ef77db45890911674705b81605b10bChris Lattner  // single backslash."
2320b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith  if (StrVal[0] == 'L' || StrVal[0] == 'U' ||
2330b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith      (StrVal[0] == 'u' && StrVal[1] != '8'))
2345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    StrVal.erase(StrVal.begin());
2350b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith  else if (StrVal[0] == 'u')
2360b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    StrVal.erase(StrVal.begin(), StrVal.begin() + 2);
2370b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith
2380b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith  if (StrVal[0] == 'R') {
2390b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    // FIXME: C++11 does not specify how to handle raw-string-literals here.
2400b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    // We strip off the 'R', the quotes, the d-char-sequences, and the parens.
2410b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    assert(StrVal[1] == '"' && StrVal[StrVal.size() - 1] == '"' &&
2420b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith           "Invalid raw string token!");
2430b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith
2440b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    // Measure the length of the d-char-sequence.
2450b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    unsigned NumDChars = 0;
2460b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    while (StrVal[2 + NumDChars] != '(') {
2470b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith      assert(NumDChars < (StrVal.size() - 5) / 2 &&
2480b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith             "Invalid raw string token!");
2490b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith      ++NumDChars;
2500b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    }
2510b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    assert(StrVal[StrVal.size() - 2 - NumDChars] == ')');
2520b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith
2530b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    // Remove 'R " d-char-sequence' and 'd-char-sequence "'. We'll replace the
2540b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    // parens below.
2550b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    StrVal.erase(0, 2 + NumDChars);
2560b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    StrVal.erase(StrVal.size() - 1 - NumDChars);
2570b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith  } else {
2580b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' &&
2590b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith           "Invalid string token!");
2600b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith
2610b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    // Remove escaped quotes and escapes.
262269cc2daf3a36ad878ea1d4cb356aa38311f6e2dBenjamin Kramer    unsigned ResultPos = 1;
26348b80c78b02efd7c4a7e3a7530d05b8aa9d3b649Reid Kleckner    for (unsigned i = 1, e = StrVal.size() - 1; i != e; ++i) {
26448b80c78b02efd7c4a7e3a7530d05b8aa9d3b649Reid Kleckner      // Skip escapes.  \\ -> '\' and \" -> '"'.
26548b80c78b02efd7c4a7e3a7530d05b8aa9d3b649Reid Kleckner      if (StrVal[i] == '\\' && i + 1 < e &&
26648b80c78b02efd7c4a7e3a7530d05b8aa9d3b649Reid Kleckner          (StrVal[i + 1] == '\\' || StrVal[i + 1] == '"'))
26748b80c78b02efd7c4a7e3a7530d05b8aa9d3b649Reid Kleckner        ++i;
26848b80c78b02efd7c4a7e3a7530d05b8aa9d3b649Reid Kleckner      StrVal[ResultPos++] = StrVal[i];
2690b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    }
27048b80c78b02efd7c4a7e3a7530d05b8aa9d3b649Reid Kleckner    StrVal.erase(StrVal.begin() + ResultPos, StrVal.end() - 1);
2710b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith  }
2721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Remove the front quote, replacing it with a space, so that the pragma
2745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // contents appear to have a space before them.
2755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StrVal[0] = ' ';
2761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2771fa495304c81e03f07f278a47b5efe9317104aabChris Lattner  // Replace the terminating quote with a \n.
2785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StrVal[StrVal.size()-1] = '\n';
2791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
280a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // Plop the string (including the newline and trailing null) into a buffer
281a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // where we can lex it.
282a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  Token TmpTok;
283a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  TmpTok.startToken();
284374b3837d676133fcc1eb70a25c8baf8ec4a5c4aDmitri Gribenko  CreateString(StrVal, TmpTok);
285a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  SourceLocation TokLoc = TmpTok.getLocation();
286a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne
287a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // Make and enter a lexer object so that we lex and expand the tokens just
288a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // like any others.
289a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  Lexer *TL = Lexer::Create_PragmaLexer(TokLoc, PragmaLoc, RParenLoc,
290a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne                                        StrVal.size(), *this);
291a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne
2926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  EnterSourceFileWithLexer(TL, nullptr);
293a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne
294a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // With everything set up, lex this as a #pragma directive.
2950189fd61ec72d86e008aa5615be80581f84cf703Enea Zaffanella  HandlePragmaDirective(PragmaLoc, PIK__Pragma);
2961ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
2971ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  // Finally, return whatever came after the pragma directive.
2981ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  return Lex(Tok);
2991ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall}
3001ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
3011ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall/// HandleMicrosoft__pragma - Like Handle_Pragma except the pragma text
3021ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall/// is not enclosed within a string literal.
3031ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCallvoid Preprocessor::HandleMicrosoft__pragma(Token &Tok) {
3041ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  // Remember the pragma token location.
3051ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  SourceLocation PragmaLoc = Tok.getLocation();
3061ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
3071ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  // Read the '('.
3081ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  Lex(Tok);
3091ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  if (Tok.isNot(tok::l_paren)) {
3101ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall    Diag(PragmaLoc, diag::err__Pragma_malformed);
3111ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall    return;
3121ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  }
3131ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
314a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // Get the tokens enclosed within the __pragma(), as well as the final ')'.
3155f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<Token, 32> PragmaToks;
3161ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  int NumParens = 0;
3171ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  Lex(Tok);
3181ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  while (Tok.isNot(tok::eof)) {
319a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne    PragmaToks.push_back(Tok);
3201ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall    if (Tok.is(tok::l_paren))
3211ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall      NumParens++;
3221ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall    else if (Tok.is(tok::r_paren) && NumParens-- == 0)
3231ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall      break;
3241ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall    Lex(Tok);
3251ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  }
3261ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
3273da92a9d21f707c164797dd967ba894b2282b343John McCall  if (Tok.is(tok::eof)) {
3283da92a9d21f707c164797dd967ba894b2282b343John McCall    Diag(PragmaLoc, diag::err_unterminated___pragma);
3293da92a9d21f707c164797dd967ba894b2282b343John McCall    return;
3303da92a9d21f707c164797dd967ba894b2282b343John McCall  }
3313da92a9d21f707c164797dd967ba894b2282b343John McCall
332a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  PragmaToks.front().setFlag(Token::LeadingSpace);
3331ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
33484021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  // Replace the ')' with an EOD to mark the end of the pragma.
33584021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  PragmaToks.back().setKind(tok::eod);
3361ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
337a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  Token *TokArray = new Token[PragmaToks.size()];
338a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  std::copy(PragmaToks.begin(), PragmaToks.end(), TokArray);
3391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
340a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // Push the tokens onto the stack.
341a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  EnterTokenStream(TokArray, PragmaToks.size(), true, true);
3425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // With everything set up, lex this as a #pragma directive.
3440189fd61ec72d86e008aa5615be80581f84cf703Enea Zaffanella  HandlePragmaDirective(PragmaLoc, PIK___pragma);
3455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
346a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // Finally, return whatever came after the pragma directive.
347a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  return Lex(Tok);
348a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne}
3495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
350b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// HandlePragmaOnce - Handle \#pragma once.  OnceTok is the 'once'.
3515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
352d217773f106856a11879ec79dc468efefaf2ee75Chris Lattnervoid Preprocessor::HandlePragmaOnce(Token &OnceTok) {
3535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (isInPrimaryFile()) {
3545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Diag(OnceTok, diag::pp_pragma_once_in_main_file);
3555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return;
3565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Get the current file lexer we're looking at.  Ignore _Pragma 'files' etc.
3595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Mark the file as a once-only file now.
3602b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  HeaderInfo.MarkFileIncludeOnce(getCurrentFileLexer()->getFileEntry());
3615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
3625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3632243449253475574fc6f14986ff8f7fce5d46799Chris Lattnervoid Preprocessor::HandlePragmaMark() {
36417ff58a63197b398ae52697b088dc0fb8b255519Ted Kremenek  assert(CurPPLexer && "No current lexer?");
3656896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner  if (CurLexer)
3666896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner    CurLexer->ReadToEndOfLine();
3676896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner  else
3686896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner    CurPTHLexer->DiscardToEndOfLine();
3692243449253475574fc6f14986ff8f7fce5d46799Chris Lattner}
3702243449253475574fc6f14986ff8f7fce5d46799Chris Lattner
3712243449253475574fc6f14986ff8f7fce5d46799Chris Lattner
372b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// HandlePragmaPoison - Handle \#pragma GCC poison.  PoisonTok is the 'poison'.
3735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
374d217773f106856a11879ec79dc468efefaf2ee75Chris Lattnervoid Preprocessor::HandlePragmaPoison(Token &PoisonTok) {
375d217773f106856a11879ec79dc468efefaf2ee75Chris Lattner  Token Tok;
3765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  while (1) {
3785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Read the next token to poison.  While doing this, pretend that we are
3795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // skipping while reading the identifier to poison.
3805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // This avoids errors on code like:
3815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    //   #pragma GCC poison X
3825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    //   #pragma GCC poison X
38368a91d5736c2c03d60a9d1c59d08191b8e0d6c52Ted Kremenek    if (CurPPLexer) CurPPLexer->LexingRawMode = true;
3845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    LexUnexpandedToken(Tok);
38568a91d5736c2c03d60a9d1c59d08191b8e0d6c52Ted Kremenek    if (CurPPLexer) CurPPLexer->LexingRawMode = false;
3861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // If we reached the end of line, we're done.
38884021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne    if (Tok.is(tok::eod)) return;
3891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Can only poison identifiers.
391c4bf2b9afb7d47445a9dc6bc848657098a4e3851Abramo Bagnara    if (Tok.isNot(tok::raw_identifier)) {
3925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Diag(Tok, diag::err_pp_invalid_poison);
3935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      return;
3945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
3951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Look up the identifier info for the token.  We disabled identifier lookup
3975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // by saying we're skipping contents, so we need to do this manually.
3985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    IdentifierInfo *II = LookUpIdentifierInfo(Tok);
3991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Already poisoned.
4015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (II->isPoisoned()) continue;
4021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // If this is a macro identifier, emit a warning.
404b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    if (isMacroDefined(II))
4055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Diag(Tok, diag::pp_poisoning_existing_macro);
4061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Finally, poison it!
4085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    II->setIsPoisoned();
409eee242ff426bf79149f221798966e58688383c1eDouglas Gregor    if (II->isFromAST())
410eee242ff426bf79149f221798966e58688383c1eDouglas Gregor      II->setChangedSinceDeserialization();
4115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
4135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
414b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// HandlePragmaSystemHeader - Implement \#pragma GCC system_header.  We know
4155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// that the whole directive has been parsed.
416d217773f106856a11879ec79dc468efefaf2ee75Chris Lattnervoid Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) {
4175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (isInPrimaryFile()) {
4185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);
4195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return;
4205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Get the current file lexer we're looking at.  Ignore _Pragma 'files' etc.
42335c10c25ddec4effbd26dead23ea5b04ee32f45aTed Kremenek  PreprocessorLexer *TheLexer = getCurrentFileLexer();
4241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Mark the file as a system header.
4262b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  HeaderInfo.MarkFileSystemHeader(TheLexer->getFileEntry());
4271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4296896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner  PresumedLoc PLoc = SourceMgr.getPresumedLoc(SysHeaderTok.getLocation());
430cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor  if (PLoc.isInvalid())
431cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor    return;
432cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor
43365aa6885818d4b4eea2e5a9d12085b2398148662Jay Foad  unsigned FilenameID = SourceMgr.getLineTableFilenameID(PLoc.getFilename());
4341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
435784c257c8f5c3a737b0ae1dceb5d54d29b6637cfChris Lattner  // Notify the client, if desired, that we are in a new source file.
436784c257c8f5c3a737b0ae1dceb5d54d29b6637cfChris Lattner  if (Callbacks)
437784c257c8f5c3a737b0ae1dceb5d54d29b6637cfChris Lattner    Callbacks->FileChanged(SysHeaderTok.getLocation(),
438784c257c8f5c3a737b0ae1dceb5d54d29b6637cfChris Lattner                           PPCallbacks::SystemHeaderPragma, SrcMgr::C_System);
439784c257c8f5c3a737b0ae1dceb5d54d29b6637cfChris Lattner
4406896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner  // Emit a line marker.  This will change any source locations from this point
4416896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner  // forward to realize they are in a system header.
4426896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner  // Create a line note with this information.
443142b35e25b579e2a883d6ca37c3c1121f562f242Jordan Rose  SourceMgr.AddLineNote(SysHeaderTok.getLocation(), PLoc.getLine()+1,
444142b35e25b579e2a883d6ca37c3c1121f562f242Jordan Rose                        FilenameID, /*IsEntry=*/false, /*IsExit=*/false,
445142b35e25b579e2a883d6ca37c3c1121f562f242Jordan Rose                        /*IsSystem=*/true, /*IsExternC=*/false);
4465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
4475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
448b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// HandlePragmaDependency - Handle \#pragma GCC dependency "foo" blah.
4495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
450d217773f106856a11879ec79dc468efefaf2ee75Chris Lattnervoid Preprocessor::HandlePragmaDependency(Token &DependencyTok) {
451d217773f106856a11879ec79dc468efefaf2ee75Chris Lattner  Token FilenameTok;
45268a91d5736c2c03d60a9d1c59d08191b8e0d6c52Ted Kremenek  CurPPLexer->LexIncludeFilename(FilenameTok);
4535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
45484021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  // If the token kind is EOD, the error has already been diagnosed.
45584021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  if (FilenameTok.is(tok::eod))
4565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return;
4571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Reserve a buffer to get the spelling.
459f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<128> FilenameBuffer;
460453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor  bool Invalid = false;
4615f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Filename = getSpelling(FilenameTok, FilenameBuffer, &Invalid);
462453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor  if (Invalid)
463453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor    return;
4641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
465a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner  bool isAngled =
466a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner    GetIncludeFilenameSpelling(FilenameTok.getLocation(), Filename);
4675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If GetIncludeFilenameSpelling set the start ptr to null, there was an
4685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // error.
469a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner  if (Filename.empty())
4705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return;
4711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Search include directories for this file.
4735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const DirectoryLookup *CurDir;
474176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  const FileEntry *File =
475176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      LookupFile(FilenameTok.getLocation(), Filename, isAngled, nullptr,
476176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                 nullptr, CurDir, nullptr, nullptr, nullptr);
4776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (!File) {
478f84139a1331c63c998e8b7d54148c75ac0b48ccdEli Friedman    if (!SuppressIncludeNotFoundError)
479f84139a1331c63c998e8b7d54148c75ac0b48ccdEli Friedman      Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
48056b05c8829efd13b7e5b333f8f587c71d025c67dChris Lattner    return;
48156b05c8829efd13b7e5b333f8f587c71d025c67dChris Lattner  }
4821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4832b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  const FileEntry *CurFile = getCurrentFileLexer()->getFileEntry();
4845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If this file is older than the file it depends on, emit a diagnostic.
4865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (CurFile && CurFile->getModificationTime() < File->getModificationTime()) {
4875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Lex tokens at the end of the message and include them in the message.
4885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    std::string Message;
4895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Lex(DependencyTok);
49084021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne    while (DependencyTok.isNot(tok::eod)) {
4915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Message += getSpelling(DependencyTok) + " ";
4925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Lex(DependencyTok);
4935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
4941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
49596de25986d28171945db96a6c6a54f91fd12ae4bChris Lattner    // Remove the trailing ' ' if present.
49696de25986d28171945db96a6c6a54f91fd12ae4bChris Lattner    if (!Message.empty())
49796de25986d28171945db96a6c6a54f91fd12ae4bChris Lattner      Message.erase(Message.end()-1);
49856b05c8829efd13b7e5b333f8f587c71d025c67dChris Lattner    Diag(FilenameTok, diag::pp_out_of_date_dependency) << Message;
4995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
5005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
5015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5027adf79a620cb7fbde0608e21727425930676b7dbReid Kleckner/// ParsePragmaPushOrPopMacro - Handle parsing of pragma push_macro/pop_macro.
503f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner/// Return the IdentifierInfo* associated with the macro to push or pop.
504f47724bf78299c7a50f008e0443c5f9f9f279ddcChris LattnerIdentifierInfo *Preprocessor::ParsePragmaPushOrPopMacro(Token &Tok) {
505f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Remember the pragma token location.
506f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  Token PragmaTok = Tok;
507f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
508f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Read the '('.
509f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  Lex(Tok);
510f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (Tok.isNot(tok::l_paren)) {
511f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
512f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner      << getSpelling(PragmaTok);
5136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
514f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
515f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
516f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Read the macro name string.
517f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  Lex(Tok);
518f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (Tok.isNot(tok::string_literal)) {
519f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
520f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner      << getSpelling(PragmaTok);
5216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
522f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
523f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
52499831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  if (Tok.hasUDSuffix()) {
52599831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    Diag(Tok, diag::err_invalid_string_udl);
5266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
52799831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  }
52899831e4677a7e2e051af636221694d60ba31fcdbRichard Smith
529f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Remember the macro string.
530f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  std::string StrVal = getSpelling(Tok);
531f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
532f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Read the ')'.
533f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  Lex(Tok);
534f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (Tok.isNot(tok::r_paren)) {
535f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
536f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner      << getSpelling(PragmaTok);
5376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
538f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
539f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
540f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' &&
541f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner         "Invalid string token!");
542f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
543f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Create a Token from the string.
544f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  Token MacroTok;
545f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  MacroTok.startToken();
546c4bf2b9afb7d47445a9dc6bc848657098a4e3851Abramo Bagnara  MacroTok.setKind(tok::raw_identifier);
547374b3837d676133fcc1eb70a25c8baf8ec4a5c4aDmitri Gribenko  CreateString(StringRef(&StrVal[1], StrVal.size() - 2), MacroTok);
548f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
549f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Get the IdentifierInfo of MacroToPushTok.
550f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  return LookUpIdentifierInfo(MacroTok);
551f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner}
552f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
553b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \brief Handle \#pragma push_macro.
554b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett///
555f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner/// The syntax is:
556b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \code
557e74dc199e95cc523c8806e0de41d8814e8bc5c42Dmitri Gribenko///   #pragma push_macro("macro")
558b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \endcode
559f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattnervoid Preprocessor::HandlePragmaPushMacro(Token &PushMacroTok) {
560f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Parse the pragma directive and get the macro IdentifierInfo*.
561f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PushMacroTok);
562f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (!IdentInfo) return;
563f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
564f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Get the MacroInfo associated with IdentInfo.
565f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  MacroInfo *MI = getMacroInfo(IdentInfo);
566f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
567f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (MI) {
568f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    // Allow the original MacroInfo to be redefined later.
569f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    MI->setIsAllowRedefinitionsWithoutWarning(true);
570f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
571f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
572f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Push the cloned MacroInfo so we can retrieve it later.
5739818a1d443e97677dd3422305de9cc2b1fb2a8c1Argyrios Kyrtzidis  PragmaPushMacroInfo[IdentInfo].push_back(MI);
574f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner}
575f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
576b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \brief Handle \#pragma pop_macro.
577b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett///
578f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner/// The syntax is:
579b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \code
580f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner///   #pragma pop_macro("macro")
581b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \endcode
582f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattnervoid Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) {
583f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  SourceLocation MessageLoc = PopMacroTok.getLocation();
584f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
585f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Parse the pragma directive and get the macro IdentifierInfo*.
586f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PopMacroTok);
587f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (!IdentInfo) return;
588f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
589f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Find the vector<MacroInfo*> associated with the macro.
590f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> >::iterator iter =
591f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    PragmaPushMacroInfo.find(IdentInfo);
592f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (iter != PragmaPushMacroInfo.end()) {
5938a64bb58c3b24d7d97895e435bbc0965c99bd3beAlexander Kornienko    // Forget the MacroInfo currently associated with IdentInfo.
594b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    if (MacroInfo *MI = getMacroInfo(IdentInfo)) {
595c56fff7fd231aebf4b152f60f8f11ef91835c48aArgyrios Kyrtzidis      if (MI->isWarnIfUnused())
596c56fff7fd231aebf4b152f60f8f11ef91835c48aArgyrios Kyrtzidis        WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
597c56fff7fd231aebf4b152f60f8f11ef91835c48aArgyrios Kyrtzidis      appendMacroDirective(IdentInfo, AllocateUndefMacroDirective(MessageLoc));
5980827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis    }
599f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
600f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    // Get the MacroInfo we want to reinstall.
601f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    MacroInfo *MacroToReInstall = iter->second.back();
602f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
603b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    if (MacroToReInstall)
604e40c4238a572bf8241a04e0005f70550cbfc1cfbAlexander Kornienko      // Reinstall the previously pushed macro.
605b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      appendDefMacroDirective(IdentInfo, MacroToReInstall, MessageLoc);
606f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
607f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    // Pop PragmaPushMacroInfo stack.
608f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    iter->second.pop_back();
609f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    if (iter->second.size() == 0)
610f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner      PragmaPushMacroInfo.erase(iter);
611f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  } else {
612f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    Diag(MessageLoc, diag::warn_pragma_pop_macro_no_push)
613f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner      << IdentInfo->getName();
614f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
615f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner}
6165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6174c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballmanvoid Preprocessor::HandlePragmaIncludeAlias(Token &Tok) {
6184c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // We will either get a quoted filename or a bracketed filename, and we
6194c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // have to track which we got.  The first filename is the source name,
6204c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // and the second name is the mapped filename.  If the first is quoted,
6214c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // the second must be as well (cannot mix and match quotes and brackets).
6224c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6234c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // Get the open paren
6244c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  Lex(Tok);
6254c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (Tok.isNot(tok::l_paren)) {
6264c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    Diag(Tok, diag::warn_pragma_include_alias_expected) << "(";
6274c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
6284c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
6294c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6304c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // We expect either a quoted string literal, or a bracketed name
6314c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  Token SourceFilenameTok;
6324c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  CurPPLexer->LexIncludeFilename(SourceFilenameTok);
6334c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (SourceFilenameTok.is(tok::eod)) {
6344c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    // The diagnostic has already been handled
6354c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
6364c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
6374c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6384c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  StringRef SourceFileName;
6394c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  SmallString<128> FileNameBuffer;
6404c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (SourceFilenameTok.is(tok::string_literal) ||
6414c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      SourceFilenameTok.is(tok::angle_string_literal)) {
6424c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    SourceFileName = getSpelling(SourceFilenameTok, FileNameBuffer);
6434c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  } else if (SourceFilenameTok.is(tok::less)) {
6444c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    // This could be a path instead of just a name
6454c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    FileNameBuffer.push_back('<');
6464c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    SourceLocation End;
6474c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    if (ConcatenateIncludeName(FileNameBuffer, End))
6484c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      return; // Diagnostic already emitted
6493ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    SourceFileName = FileNameBuffer;
6504c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  } else {
6514c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
6524c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
6534c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
6544c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  FileNameBuffer.clear();
6554c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6564c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // Now we expect a comma, followed by another include name
6574c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  Lex(Tok);
6584c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (Tok.isNot(tok::comma)) {
6594c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    Diag(Tok, diag::warn_pragma_include_alias_expected) << ",";
6604c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
6614c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
6624c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6634c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  Token ReplaceFilenameTok;
6644c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  CurPPLexer->LexIncludeFilename(ReplaceFilenameTok);
6654c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (ReplaceFilenameTok.is(tok::eod)) {
6664c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    // The diagnostic has already been handled
6674c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
6684c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
6694c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6704c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  StringRef ReplaceFileName;
6714c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (ReplaceFilenameTok.is(tok::string_literal) ||
6724c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      ReplaceFilenameTok.is(tok::angle_string_literal)) {
6734c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    ReplaceFileName = getSpelling(ReplaceFilenameTok, FileNameBuffer);
6744c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  } else if (ReplaceFilenameTok.is(tok::less)) {
6754c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    // This could be a path instead of just a name
6764c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    FileNameBuffer.push_back('<');
6774c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    SourceLocation End;
6784c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    if (ConcatenateIncludeName(FileNameBuffer, End))
6794c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      return; // Diagnostic already emitted
6803ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    ReplaceFileName = FileNameBuffer;
6814c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  } else {
6824c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
6834c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
6844c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
6854c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6864c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // Finally, we expect the closing paren
6874c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  Lex(Tok);
6884c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (Tok.isNot(tok::r_paren)) {
6894c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    Diag(Tok, diag::warn_pragma_include_alias_expected) << ")";
6904c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
6914c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
6924c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6934c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // Now that we have the source and target filenames, we need to make sure
6944c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // they're both of the same type (angled vs non-angled)
6954c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  StringRef OriginalSource = SourceFileName;
6964c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6974c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  bool SourceIsAngled =
6984c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    GetIncludeFilenameSpelling(SourceFilenameTok.getLocation(),
6994c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman                                SourceFileName);
7004c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  bool ReplaceIsAngled =
7014c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    GetIncludeFilenameSpelling(ReplaceFilenameTok.getLocation(),
7024c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman                                ReplaceFileName);
7034c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (!SourceFileName.empty() && !ReplaceFileName.empty() &&
7044c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      (SourceIsAngled != ReplaceIsAngled)) {
7054c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    unsigned int DiagID;
7064c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    if (SourceIsAngled)
7074c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      DiagID = diag::warn_pragma_include_alias_mismatch_angle;
7084c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    else
7094c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      DiagID = diag::warn_pragma_include_alias_mismatch_quote;
7104c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
7114c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    Diag(SourceFilenameTok.getLocation(), DiagID)
7124c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      << SourceFileName
7134c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      << ReplaceFileName;
7144c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
7154c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
7164c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
7174c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
7184c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // Now we can let the include handler know about this mapping
7194c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  getHeaderSearchInfo().AddIncludeAlias(OriginalSource, ReplaceFileName);
7204c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman}
7214c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
7225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// AddPragmaHandler - Add the specified pragma handler to the preprocessor.
7235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// If 'Namespace' is non-null, then it is a token required to exist on the
7245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
7255f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Preprocessor::AddPragmaHandler(StringRef Namespace,
7265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                    PragmaHandler *Handler) {
727176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  PragmaNamespace *InsertNS = PragmaHandlers.get();
7281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If this is specified to be in a namespace, step down into it.
7309b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  if (!Namespace.empty()) {
7315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // If there is already a pragma handler with the name of this namespace,
7325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // we either have an error (directive with the same name as a namespace) or
7335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // we already have the namespace to insert into.
7349b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis    if (PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace)) {
7355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      InsertNS = Existing->getIfNamespace();
7366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      assert(InsertNS != nullptr && "Cannot have a pragma namespace and pragma"
7375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer             " handler with the same name!");
7385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    } else {
7395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      // Otherwise, this namespace doesn't exist yet, create and insert the
7405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      // handler for it.
7419b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis      InsertNS = new PragmaNamespace(Namespace);
7425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      PragmaHandlers->AddPragma(InsertNS);
7435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
7445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
7451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Check to make sure we don't already have a pragma for this identifier.
7475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  assert(!InsertNS->FindHandler(Handler->getName()) &&
7485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         "Pragma handler already exists for this identifier!");
7495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  InsertNS->AddPragma(Handler);
7505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
7515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7524095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar/// RemovePragmaHandler - Remove the specific pragma handler from the
7534095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar/// preprocessor. If \arg Namespace is non-null, then it should be the
7544095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar/// namespace that \arg Handler was added to. It is an error to remove
7554095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar/// a handler that has not been registered.
7565f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Preprocessor::RemovePragmaHandler(StringRef Namespace,
7574095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar                                       PragmaHandler *Handler) {
758176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  PragmaNamespace *NS = PragmaHandlers.get();
7591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7604095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar  // If this is specified to be in a namespace, step down into it.
7619b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  if (!Namespace.empty()) {
7629b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis    PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace);
7634095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar    assert(Existing && "Namespace containing handler does not exist!");
7644095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar
7654095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar    NS = Existing->getIfNamespace();
7664095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar    assert(NS && "Invalid namespace, registered as a regular pragma handler!");
7674095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar  }
7684095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar
7694095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar  NS->RemovePragmaHandler(Handler);
7701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
771176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // If this is a non-default namespace and it is now empty, remove it.
772176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  if (NS != PragmaHandlers.get() && NS->IsEmpty()) {
7734095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar    PragmaHandlers->RemovePragmaHandler(NS);
774ce52bb3dec520ef94574280ac3ef8ad63f4f1ce2Argyrios Kyrtzidis    delete NS;
775ce52bb3dec520ef94574280ac3ef8ad63f4f1ce2Argyrios Kyrtzidis  }
7764095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar}
7774095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar
7789d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbournebool Preprocessor::LexOnOffSwitch(tok::OnOffSwitch &Result) {
7799d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  Token Tok;
7809d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  LexUnexpandedToken(Tok);
7819d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne
7829d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  if (Tok.isNot(tok::identifier)) {
7839d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    Diag(Tok, diag::ext_on_off_switch_syntax);
7849d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    return true;
7859d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  }
7869d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  IdentifierInfo *II = Tok.getIdentifierInfo();
7879d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  if (II->isStr("ON"))
7889d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    Result = tok::OOS_ON;
7899d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  else if (II->isStr("OFF"))
7909d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    Result = tok::OOS_OFF;
7919d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  else if (II->isStr("DEFAULT"))
7929d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    Result = tok::OOS_DEFAULT;
7939d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  else {
7949d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    Diag(Tok, diag::ext_on_off_switch_syntax);
7959d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    return true;
7969d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  }
7979d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne
79884021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  // Verify that this is followed by EOD.
7999d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  LexUnexpandedToken(Tok);
80084021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  if (Tok.isNot(tok::eod))
80184021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne    Diag(Tok, diag::ext_pragma_syntax_eod);
8029d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  return false;
8039d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne}
8049d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne
8055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace {
806b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaOnceHandler - "\#pragma once" marks the file as atomically included.
8075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstruct PragmaOnceHandler : public PragmaHandler {
8089b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaOnceHandler() : PragmaHandler("once") {}
809651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
810651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &OnceTok) override {
81135410d5cbbb18735d76e00496540d416dc49b577Chris Lattner    PP.CheckEndOfDirective("pragma once");
8125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    PP.HandlePragmaOnce(OnceTok);
8135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
8145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
8155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
816b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaMarkHandler - "\#pragma mark ..." is ignored by the compiler, and the
8172243449253475574fc6f14986ff8f7fce5d46799Chris Lattner/// rest of the line is not lexed.
8182243449253475574fc6f14986ff8f7fce5d46799Chris Lattnerstruct PragmaMarkHandler : public PragmaHandler {
8199b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaMarkHandler() : PragmaHandler("mark") {}
820651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
821651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &MarkTok) override {
8222243449253475574fc6f14986ff8f7fce5d46799Chris Lattner    PP.HandlePragmaMark();
8232243449253475574fc6f14986ff8f7fce5d46799Chris Lattner  }
8242243449253475574fc6f14986ff8f7fce5d46799Chris Lattner};
8252243449253475574fc6f14986ff8f7fce5d46799Chris Lattner
826b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaPoisonHandler - "\#pragma poison x" marks x as not usable.
8275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstruct PragmaPoisonHandler : public PragmaHandler {
8289b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaPoisonHandler() : PragmaHandler("poison") {}
829651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
830651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &PoisonTok) override {
8315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    PP.HandlePragmaPoison(PoisonTok);
8325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
8335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
8345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
835b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaSystemHeaderHandler - "\#pragma system_header" marks the current file
8362243449253475574fc6f14986ff8f7fce5d46799Chris Lattner/// as a system header, which silences warnings in it.
8375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstruct PragmaSystemHeaderHandler : public PragmaHandler {
8389b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaSystemHeaderHandler() : PragmaHandler("system_header") {}
839651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
840651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &SHToken) override {
8415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    PP.HandlePragmaSystemHeader(SHToken);
84235410d5cbbb18735d76e00496540d416dc49b577Chris Lattner    PP.CheckEndOfDirective("pragma");
8435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
8445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
8455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstruct PragmaDependencyHandler : public PragmaHandler {
8469b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaDependencyHandler() : PragmaHandler("dependency") {}
847651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
848651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &DepToken) override {
8495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    PP.HandlePragmaDependency(DepToken);
8505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
8515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
8521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
853abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbarstruct PragmaDebugHandler : public PragmaHandler {
854abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar  PragmaDebugHandler() : PragmaHandler("__debug") {}
855651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
856651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &DepToken) override {
857abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    Token Tok;
858abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    PP.LexUnexpandedToken(Tok);
859abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    if (Tok.isNot(tok::identifier)) {
8606493a4d7129673f7878da2382dedf4f9abc57e4cDouglas Gregor      PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
861abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar      return;
862abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    }
863abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    IdentifierInfo *II = Tok.getIdentifierInfo();
864abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar
8655505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar    if (II->isStr("assert")) {
866b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie      llvm_unreachable("This is an assertion!");
867abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    } else if (II->isStr("crash")) {
868377da4c6b78c0130fb6141313636c8fda7b60b72David Blaikie      LLVM_BUILTIN_TRAP;
869e75d9cfbf41a0ee9e456a665776f91fdd9773b36David Blaikie    } else if (II->isStr("parser_crash")) {
870e75d9cfbf41a0ee9e456a665776f91fdd9773b36David Blaikie      Token Crasher;
8713ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      Crasher.startToken();
872e75d9cfbf41a0ee9e456a665776f91fdd9773b36David Blaikie      Crasher.setKind(tok::annot_pragma_parser_crash);
8733ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      Crasher.setAnnotationRange(SourceRange(Tok.getLocation()));
874e75d9cfbf41a0ee9e456a665776f91fdd9773b36David Blaikie      PP.EnterToken(Crasher);
8755505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar    } else if (II->isStr("llvm_fatal_error")) {
8765505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar      llvm::report_fatal_error("#pragma clang __debug llvm_fatal_error");
8775505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar    } else if (II->isStr("llvm_unreachable")) {
8785505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar      llvm_unreachable("#pragma clang __debug llvm_unreachable");
879b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    } else if (II->isStr("macro")) {
880b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      Token MacroName;
881b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      PP.LexUnexpandedToken(MacroName);
882b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      auto *MacroII = MacroName.getIdentifierInfo();
883b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      if (MacroII)
884b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        PP.dumpMacroInfo(MacroII);
885b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      else
886b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        PP.Diag(MacroName, diag::warn_pragma_diagnostic_invalid);
8875505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar    } else if (II->isStr("overflow_stack")) {
8885505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar      DebugOverflowStack();
889ff759a66526d6a985fb4efae69c6b798d83364dfDaniel Dunbar    } else if (II->isStr("handle_crash")) {
890ff759a66526d6a985fb4efae69c6b798d83364dfDaniel Dunbar      llvm::CrashRecoveryContext *CRC =llvm::CrashRecoveryContext::GetCurrent();
891ff759a66526d6a985fb4efae69c6b798d83364dfDaniel Dunbar      if (CRC)
892ff759a66526d6a985fb4efae69c6b798d83364dfDaniel Dunbar        CRC->HandleCrash();
89385192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    } else if (II->isStr("captured")) {
89485192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj      HandleCaptured(PP);
8955505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar    } else {
8965505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar      PP.Diag(Tok, diag::warn_pragma_debug_unexpected_command)
8975505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar        << II->getName();
898abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    }
89985192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj
90085192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    PPCallbacks *Callbacks = PP.getPPCallbacks();
90185192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    if (Callbacks)
90285192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj      Callbacks->PragmaDebug(Tok.getLocation(), II->getName());
90385192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj  }
90485192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj
90585192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj  void HandleCaptured(Preprocessor &PP) {
90685192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    // Skip if emitting preprocessed output.
90785192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    if (PP.isPreprocessedOutput())
90885192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj      return;
90985192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj
91085192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    Token Tok;
91185192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    PP.LexUnexpandedToken(Tok);
91285192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj
91385192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    if (Tok.isNot(tok::eod)) {
91485192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj      PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol)
91585192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj        << "pragma clang __debug captured";
91685192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj      return;
91785192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    }
91885192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj
91985192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    SourceLocation NameLoc = Tok.getLocation();
92085192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    Token *Toks = PP.getPreprocessorAllocator().Allocate<Token>(1);
92185192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    Toks->startToken();
92285192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    Toks->setKind(tok::annot_pragma_captured);
92385192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    Toks->setLocation(NameLoc);
92485192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj
92585192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
92685192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj                        /*OwnsTokens=*/false);
927abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar  }
928abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar
9291066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet// Disable MSVC warning about runtime stack overflow.
9301066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet#ifdef _MSC_VER
9311066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet    #pragma warning(disable : 4717)
9321066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet#endif
933651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  static void DebugOverflowStack() {
934651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    void (*volatile Self)() = DebugOverflowStack;
935651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Self();
936abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar  }
9371066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet#ifdef _MSC_VER
9381066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet    #pragma warning(default : 4717)
9391066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet#endif
9401066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet
941abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar};
942abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar
943b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaDiagnosticHandler - e.g. '\#pragma GCC diagnostic ignored "-Wformat"'
944edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattnerstruct PragmaDiagnosticHandler : public PragmaHandler {
945c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregorprivate:
946c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor  const char *Namespace;
94704ae2df026b275aae5dddfc0db5ca55ff4e62179Chris Lattnerpublic:
948c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor  explicit PragmaDiagnosticHandler(const char *NS) :
949c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor    PragmaHandler("diagnostic"), Namespace(NS) {}
950651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
951651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &DiagToken) override {
9520827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis    SourceLocation DiagLoc = DiagToken.getLocation();
953edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    Token Tok;
954edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    PP.LexUnexpandedToken(Tok);
955edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    if (Tok.isNot(tok::identifier)) {
9566493a4d7129673f7878da2382dedf4f9abc57e4cDouglas Gregor      PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
957edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      return;
958edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    }
959edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    IdentifierInfo *II = Tok.getIdentifierInfo();
960c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor    PPCallbacks *Callbacks = PP.getPPCallbacks();
9611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
962c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    if (II->isStr("pop")) {
9630827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis      if (!PP.getDiagnostics().popMappings(DiagLoc))
9646493a4d7129673f7878da2382dedf4f9abc57e4cDouglas Gregor        PP.Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
965c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor      else if (Callbacks)
966c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor        Callbacks->PragmaDiagnosticPop(DiagLoc, Namespace);
9676493a4d7129673f7878da2382dedf4f9abc57e4cDouglas Gregor      return;
9686493a4d7129673f7878da2382dedf4f9abc57e4cDouglas Gregor    } else if (II->isStr("push")) {
9690827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis      PP.getDiagnostics().pushMappings(DiagLoc);
970c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor      if (Callbacks)
971c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor        Callbacks->PragmaDiagnosticPush(DiagLoc, Namespace);
97204ae2df026b275aae5dddfc0db5ca55ff4e62179Chris Lattner      return;
973c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    }
974c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
975c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    diag::Severity SV = llvm::StringSwitch<diag::Severity>(II->getName())
976c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                            .Case("ignored", diag::Severity::Ignored)
977c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                            .Case("warning", diag::Severity::Warning)
978c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                            .Case("error", diag::Severity::Error)
979c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                            .Case("fatal", diag::Severity::Fatal)
980c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                            .Default(diag::Severity());
981c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
982c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    if (SV == diag::Severity()) {
9836493a4d7129673f7878da2382dedf4f9abc57e4cDouglas Gregor      PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
984edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      return;
985edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    }
9861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
987edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    PP.LexUnexpandedToken(Tok);
98802a176871d91bba3004e4f94b2d4d588ae4b2122Andy Gibbs    SourceLocation StringLoc = Tok.getLocation();
989edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner
99002a176871d91bba3004e4f94b2d4d588ae4b2122Andy Gibbs    std::string WarningName;
99197f8461a2c553f68a258612d2322e4281c3f0915Andy Gibbs    if (!PP.FinishLexStringLiteral(Tok, WarningName, "pragma diagnostic",
99297f8461a2c553f68a258612d2322e4281c3f0915Andy Gibbs                                   /*MacroExpansion=*/false))
993edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      return;
9941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
99584021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne    if (Tok.isNot(tok::eod)) {
996edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      PP.Diag(Tok.getLocation(), diag::warn_pragma_diagnostic_invalid_token);
997edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      return;
998edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    }
9991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1000edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    if (WarningName.size() < 3 || WarningName[0] != '-' ||
1001176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        (WarningName[1] != 'W' && WarningName[1] != 'R')) {
100202a176871d91bba3004e4f94b2d4d588ae4b2122Andy Gibbs      PP.Diag(StringLoc, diag::warn_pragma_diagnostic_invalid_option);
1003edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      return;
1004edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    }
10051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1006176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    if (PP.getDiagnostics().setSeverityForGroup(
1007176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines            WarningName[1] == 'W' ? diag::Flavor::WarningOrError
1008176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                  : diag::Flavor::Remark,
1009176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines            WarningName.substr(2), SV, DiagLoc))
101002a176871d91bba3004e4f94b2d4d588ae4b2122Andy Gibbs      PP.Diag(StringLoc, diag::warn_pragma_diagnostic_unknown_warning)
101102a176871d91bba3004e4f94b2d4d588ae4b2122Andy Gibbs        << WarningName;
1012c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor    else if (Callbacks)
1013c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines      Callbacks->PragmaDiagnostic(DiagLoc, Namespace, SV, WarningName);
1014edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner  }
1015edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner};
10161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10172ee042dee9f7693665e28463955401905474a284Reid Kleckner/// "\#pragma warning(...)".  MSVC's diagnostics do not map cleanly to clang's
10182ee042dee9f7693665e28463955401905474a284Reid Kleckner/// diagnostics, so we don't really implement this pragma.  We parse it and
10192ee042dee9f7693665e28463955401905474a284Reid Kleckner/// ignore it to avoid -Wunknown-pragma warnings.
10202ee042dee9f7693665e28463955401905474a284Reid Klecknerstruct PragmaWarningHandler : public PragmaHandler {
10212ee042dee9f7693665e28463955401905474a284Reid Kleckner  PragmaWarningHandler() : PragmaHandler("warning") {}
10222ee042dee9f7693665e28463955401905474a284Reid Kleckner
1023651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1024651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &Tok) override {
10252ee042dee9f7693665e28463955401905474a284Reid Kleckner    // Parse things like:
10262ee042dee9f7693665e28463955401905474a284Reid Kleckner    // warning(push, 1)
10272ee042dee9f7693665e28463955401905474a284Reid Kleckner    // warning(pop)
1028faea5bfd7583fe259b352b350bb5689f8c96de17John Thompson    // warning(disable : 1 2 3 ; error : 4 5 6 ; suppress : 7 8 9)
10292ee042dee9f7693665e28463955401905474a284Reid Kleckner    SourceLocation DiagLoc = Tok.getLocation();
10302ee042dee9f7693665e28463955401905474a284Reid Kleckner    PPCallbacks *Callbacks = PP.getPPCallbacks();
10312ee042dee9f7693665e28463955401905474a284Reid Kleckner
10322ee042dee9f7693665e28463955401905474a284Reid Kleckner    PP.Lex(Tok);
10332ee042dee9f7693665e28463955401905474a284Reid Kleckner    if (Tok.isNot(tok::l_paren)) {
10342ee042dee9f7693665e28463955401905474a284Reid Kleckner      PP.Diag(Tok, diag::warn_pragma_warning_expected) << "(";
10352ee042dee9f7693665e28463955401905474a284Reid Kleckner      return;
10362ee042dee9f7693665e28463955401905474a284Reid Kleckner    }
10372ee042dee9f7693665e28463955401905474a284Reid Kleckner
10382ee042dee9f7693665e28463955401905474a284Reid Kleckner    PP.Lex(Tok);
10392ee042dee9f7693665e28463955401905474a284Reid Kleckner    IdentifierInfo *II = Tok.getIdentifierInfo();
10402ee042dee9f7693665e28463955401905474a284Reid Kleckner
1041b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    if (II && II->isStr("push")) {
10422ee042dee9f7693665e28463955401905474a284Reid Kleckner      // #pragma warning( push[ ,n ] )
104372c26c0d47eb850db18b784403260bce0632c478Reid Kleckner      int Level = -1;
10442ee042dee9f7693665e28463955401905474a284Reid Kleckner      PP.Lex(Tok);
10452ee042dee9f7693665e28463955401905474a284Reid Kleckner      if (Tok.is(tok::comma)) {
10462ee042dee9f7693665e28463955401905474a284Reid Kleckner        PP.Lex(Tok);
1047651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        uint64_t Value;
1048651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        if (Tok.is(tok::numeric_constant) &&
1049651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            PP.parseSimpleIntegerLiteral(Tok, Value))
1050651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          Level = int(Value);
105172c26c0d47eb850db18b784403260bce0632c478Reid Kleckner        if (Level < 0 || Level > 4) {
10522ee042dee9f7693665e28463955401905474a284Reid Kleckner          PP.Diag(Tok, diag::warn_pragma_warning_push_level);
10532ee042dee9f7693665e28463955401905474a284Reid Kleckner          return;
10542ee042dee9f7693665e28463955401905474a284Reid Kleckner        }
10552ee042dee9f7693665e28463955401905474a284Reid Kleckner      }
10562ee042dee9f7693665e28463955401905474a284Reid Kleckner      if (Callbacks)
10572ee042dee9f7693665e28463955401905474a284Reid Kleckner        Callbacks->PragmaWarningPush(DiagLoc, Level);
1058b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    } else if (II && II->isStr("pop")) {
10592ee042dee9f7693665e28463955401905474a284Reid Kleckner      // #pragma warning( pop )
10602ee042dee9f7693665e28463955401905474a284Reid Kleckner      PP.Lex(Tok);
10612ee042dee9f7693665e28463955401905474a284Reid Kleckner      if (Callbacks)
10622ee042dee9f7693665e28463955401905474a284Reid Kleckner        Callbacks->PragmaWarningPop(DiagLoc);
10632ee042dee9f7693665e28463955401905474a284Reid Kleckner    } else {
10642ee042dee9f7693665e28463955401905474a284Reid Kleckner      // #pragma warning( warning-specifier : warning-number-list
10652ee042dee9f7693665e28463955401905474a284Reid Kleckner      //                  [; warning-specifier : warning-number-list...] )
10662ee042dee9f7693665e28463955401905474a284Reid Kleckner      while (true) {
10672ee042dee9f7693665e28463955401905474a284Reid Kleckner        II = Tok.getIdentifierInfo();
1068b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        if (!II && !Tok.is(tok::numeric_constant)) {
10692ee042dee9f7693665e28463955401905474a284Reid Kleckner          PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid);
10702ee042dee9f7693665e28463955401905474a284Reid Kleckner          return;
10712ee042dee9f7693665e28463955401905474a284Reid Kleckner        }
10722ee042dee9f7693665e28463955401905474a284Reid Kleckner
10732ee042dee9f7693665e28463955401905474a284Reid Kleckner        // Figure out which warning specifier this is.
1074b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        bool SpecifierValid;
1075b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        StringRef Specifier;
1076b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        llvm::SmallString<1> SpecifierBuf;
1077b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        if (II) {
1078b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar          Specifier = II->getName();
1079b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar          SpecifierValid = llvm::StringSwitch<bool>(Specifier)
1080b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                               .Cases("default", "disable", "error", "once",
1081b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                                      "suppress", true)
1082b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar                               .Default(false);
1083b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar          // If we read a correct specifier, snatch next token (that should be
1084b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar          // ":", checked later).
1085b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar          if (SpecifierValid)
1086b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar            PP.Lex(Tok);
1087b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        } else {
1088b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar          // Token is a numeric constant. It should be either 1, 2, 3 or 4.
1089b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar          uint64_t Value;
1090b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar          Specifier = PP.getSpelling(Tok, SpecifierBuf);
1091b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar          if (PP.parseSimpleIntegerLiteral(Tok, Value)) {
1092b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar            SpecifierValid = (Value >= 1) && (Value <= 4);
1093b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar          } else
1094b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar            SpecifierValid = false;
1095b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar          // Next token already snatched by parseSimpleIntegerLiteral.
1096b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        }
1097b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
10982ee042dee9f7693665e28463955401905474a284Reid Kleckner        if (!SpecifierValid) {
10992ee042dee9f7693665e28463955401905474a284Reid Kleckner          PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid);
11002ee042dee9f7693665e28463955401905474a284Reid Kleckner          return;
11012ee042dee9f7693665e28463955401905474a284Reid Kleckner        }
11022ee042dee9f7693665e28463955401905474a284Reid Kleckner        if (Tok.isNot(tok::colon)) {
11032ee042dee9f7693665e28463955401905474a284Reid Kleckner          PP.Diag(Tok, diag::warn_pragma_warning_expected) << ":";
11042ee042dee9f7693665e28463955401905474a284Reid Kleckner          return;
11052ee042dee9f7693665e28463955401905474a284Reid Kleckner        }
11062ee042dee9f7693665e28463955401905474a284Reid Kleckner
11072ee042dee9f7693665e28463955401905474a284Reid Kleckner        // Collect the warning ids.
11082ee042dee9f7693665e28463955401905474a284Reid Kleckner        SmallVector<int, 4> Ids;
11092ee042dee9f7693665e28463955401905474a284Reid Kleckner        PP.Lex(Tok);
11102ee042dee9f7693665e28463955401905474a284Reid Kleckner        while (Tok.is(tok::numeric_constant)) {
1111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          uint64_t Value;
1112651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          if (!PP.parseSimpleIntegerLiteral(Tok, Value) || Value == 0 ||
1113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines              Value > INT_MAX) {
11142ee042dee9f7693665e28463955401905474a284Reid Kleckner            PP.Diag(Tok, diag::warn_pragma_warning_expected_number);
11152ee042dee9f7693665e28463955401905474a284Reid Kleckner            return;
11162ee042dee9f7693665e28463955401905474a284Reid Kleckner          }
1117651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          Ids.push_back(int(Value));
11182ee042dee9f7693665e28463955401905474a284Reid Kleckner        }
11192ee042dee9f7693665e28463955401905474a284Reid Kleckner        if (Callbacks)
11202ee042dee9f7693665e28463955401905474a284Reid Kleckner          Callbacks->PragmaWarning(DiagLoc, Specifier, Ids);
11212ee042dee9f7693665e28463955401905474a284Reid Kleckner
11222ee042dee9f7693665e28463955401905474a284Reid Kleckner        // Parse the next specifier if there is a semicolon.
11232ee042dee9f7693665e28463955401905474a284Reid Kleckner        if (Tok.isNot(tok::semi))
11242ee042dee9f7693665e28463955401905474a284Reid Kleckner          break;
11252ee042dee9f7693665e28463955401905474a284Reid Kleckner        PP.Lex(Tok);
11262ee042dee9f7693665e28463955401905474a284Reid Kleckner      }
11272ee042dee9f7693665e28463955401905474a284Reid Kleckner    }
11282ee042dee9f7693665e28463955401905474a284Reid Kleckner
11292ee042dee9f7693665e28463955401905474a284Reid Kleckner    if (Tok.isNot(tok::r_paren)) {
11302ee042dee9f7693665e28463955401905474a284Reid Kleckner      PP.Diag(Tok, diag::warn_pragma_warning_expected) << ")";
11312ee042dee9f7693665e28463955401905474a284Reid Kleckner      return;
11322ee042dee9f7693665e28463955401905474a284Reid Kleckner    }
11332ee042dee9f7693665e28463955401905474a284Reid Kleckner
11342ee042dee9f7693665e28463955401905474a284Reid Kleckner    PP.Lex(Tok);
11352ee042dee9f7693665e28463955401905474a284Reid Kleckner    if (Tok.isNot(tok::eod))
11362ee042dee9f7693665e28463955401905474a284Reid Kleckner      PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma warning";
11372ee042dee9f7693665e28463955401905474a284Reid Kleckner  }
11382ee042dee9f7693665e28463955401905474a284Reid Kleckner};
11392ee042dee9f7693665e28463955401905474a284Reid Kleckner
1140b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaIncludeAliasHandler - "\#pragma include_alias("...")".
11414c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballmanstruct PragmaIncludeAliasHandler : public PragmaHandler {
11424c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  PragmaIncludeAliasHandler() : PragmaHandler("include_alias") {}
1143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &IncludeAliasTok) override {
11452ee042dee9f7693665e28463955401905474a284Reid Kleckner    PP.HandlePragmaIncludeAlias(IncludeAliasTok);
11464c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
11474c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman};
11484c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
1149076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// PragmaMessageHandler - Handle the microsoft and gcc \#pragma message
1150076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// extension.  The syntax is:
1151076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// \code
1152076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs///   #pragma message(string)
1153076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// \endcode
1154076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// OR, in GCC mode:
1155076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// \code
1156076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs///   #pragma message string
1157076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// \endcode
1158076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// string is a string, which is fully macro expanded, and permits string
1159076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// concatenation, embedded escape characters, etc... See MSDN for more details.
1160076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// Also handles \#pragma GCC warning and \#pragma GCC error which take the same
1161076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// form as \#pragma message.
1162abfe094ce71c42656dcb84a3bdc3e79cb3c16fc3Chris Lattnerstruct PragmaMessageHandler : public PragmaHandler {
1163076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbsprivate:
1164076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  const PPCallbacks::PragmaMessageKind Kind;
1165076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  const StringRef Namespace;
1166076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1167076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  static const char* PragmaKind(PPCallbacks::PragmaMessageKind Kind,
1168076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                                bool PragmaNameOnly = false) {
1169076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    switch (Kind) {
1170076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      case PPCallbacks::PMK_Message:
1171076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs        return PragmaNameOnly ? "message" : "pragma message";
1172076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      case PPCallbacks::PMK_Warning:
1173076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs        return PragmaNameOnly ? "warning" : "pragma warning";
1174076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      case PPCallbacks::PMK_Error:
1175076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs        return PragmaNameOnly ? "error" : "pragma error";
1176076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    }
1177076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    llvm_unreachable("Unknown PragmaMessageKind!");
1178076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  }
1179076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1180076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbspublic:
1181076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  PragmaMessageHandler(PPCallbacks::PragmaMessageKind Kind,
1182076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                       StringRef Namespace = StringRef())
1183076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    : PragmaHandler(PragmaKind(Kind, true)), Kind(Kind), Namespace(Namespace) {}
1184076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1185651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1186651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &Tok) override {
1187076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    SourceLocation MessageLoc = Tok.getLocation();
1188076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    PP.Lex(Tok);
1189076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    bool ExpectClosingParen = false;
1190076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    switch (Tok.getKind()) {
1191076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    case tok::l_paren:
1192076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      // We have a MSVC style pragma message.
1193076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      ExpectClosingParen = true;
1194076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      // Read the string.
1195076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      PP.Lex(Tok);
1196076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      break;
1197076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    case tok::string_literal:
1198076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      // We have a GCC style pragma message, and we just read the string.
1199076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      break;
1200076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    default:
1201076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      PP.Diag(MessageLoc, diag::err_pragma_message_malformed) << Kind;
1202076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      return;
1203076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    }
1204076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1205076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    std::string MessageString;
1206076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    if (!PP.FinishLexStringLiteral(Tok, MessageString, PragmaKind(Kind),
1207076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                                   /*MacroExpansion=*/true))
1208076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      return;
1209076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1210076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    if (ExpectClosingParen) {
1211076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      if (Tok.isNot(tok::r_paren)) {
1212076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs        PP.Diag(Tok.getLocation(), diag::err_pragma_message_malformed) << Kind;
1213076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs        return;
1214076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      }
1215076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      PP.Lex(Tok);  // eat the r_paren.
1216076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    }
1217076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1218076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    if (Tok.isNot(tok::eod)) {
1219076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      PP.Diag(Tok.getLocation(), diag::err_pragma_message_malformed) << Kind;
1220076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      return;
1221076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    }
1222076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1223076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    // Output the message.
1224076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    PP.Diag(MessageLoc, (Kind == PPCallbacks::PMK_Error)
1225076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                          ? diag::err_pragma_message
1226076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                          : diag::warn_pragma_message) << MessageString;
1227076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1228076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    // If the pragma is lexically sound, notify any interested PPCallbacks.
1229076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    if (PPCallbacks *Callbacks = PP.getPPCallbacks())
1230076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      Callbacks->PragmaMessage(MessageLoc, Namespace, Kind, MessageString);
1231abfe094ce71c42656dcb84a3bdc3e79cb3c16fc3Chris Lattner  }
1232abfe094ce71c42656dcb84a3bdc3e79cb3c16fc3Chris Lattner};
1233abfe094ce71c42656dcb84a3bdc3e79cb3c16fc3Chris Lattner
1234b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaPushMacroHandler - "\#pragma push_macro" saves the value of the
1235f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner/// macro on the top of the stack.
1236f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattnerstruct PragmaPushMacroHandler : public PragmaHandler {
1237f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  PragmaPushMacroHandler() : PragmaHandler("push_macro") {}
1238651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1239651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &PushMacroTok) override {
1240f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    PP.HandlePragmaPushMacro(PushMacroTok);
1241f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
1242f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner};
1243f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
1244f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
1245b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaPopMacroHandler - "\#pragma pop_macro" sets the value of the
1246f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner/// macro to the value on the top of the stack.
1247f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattnerstruct PragmaPopMacroHandler : public PragmaHandler {
1248f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  PragmaPopMacroHandler() : PragmaHandler("pop_macro") {}
1249651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1250651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &PopMacroTok) override {
1251f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    PP.HandlePragmaPopMacro(PopMacroTok);
1252f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
1253f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner};
1254f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
1255062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner// Pragma STDC implementations.
12566c5cf4a2e234923ab66127de0874a71cb6bfdd83Chris Lattner
1257b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaSTDC_FENV_ACCESSHandler - "\#pragma STDC FENV_ACCESS ...".
1258062f23246510393c19b537b68ec88b6a08ee8996Chris Lattnerstruct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler {
12599b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaSTDC_FENV_ACCESSHandler() : PragmaHandler("FENV_ACCESS") {}
1260651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1261651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &Tok) override {
12629d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    tok::OnOffSwitch OOS;
12639d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    if (PP.LexOnOffSwitch(OOS))
12649d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne     return;
12659d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    if (OOS == tok::OOS_ON)
12664d8aac3778b40c161bed9964125948ee01c08821Chris Lattner      PP.Diag(Tok, diag::warn_stdc_fenv_access_not_supported);
1267062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner  }
1268062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner};
12691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1270b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaSTDC_CX_LIMITED_RANGEHandler - "\#pragma STDC CX_LIMITED_RANGE ...".
1271062f23246510393c19b537b68ec88b6a08ee8996Chris Lattnerstruct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler {
12729b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaSTDC_CX_LIMITED_RANGEHandler()
12739b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis    : PragmaHandler("CX_LIMITED_RANGE") {}
1274651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1275651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &Tok) override {
12769d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    tok::OnOffSwitch OOS;
12779d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    PP.LexOnOffSwitch(OOS);
1278062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner  }
1279062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner};
12801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1281b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaSTDC_UnknownHandler - "\#pragma STDC ...".
1282062f23246510393c19b537b68ec88b6a08ee8996Chris Lattnerstruct PragmaSTDC_UnknownHandler : public PragmaHandler {
12839b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaSTDC_UnknownHandler() {}
1284651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1285651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &UnknownTok) override {
12866c5cf4a2e234923ab66127de0874a71cb6bfdd83Chris Lattner    // C99 6.10.6p2, unknown forms are not allowed.
1287f545be5552b6fd40a4c766fbf82dab0ab5305790Chris Lattner    PP.Diag(UnknownTok, diag::ext_stdc_pragma_ignored);
1288062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner  }
1289062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner};
12901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12918dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall/// PragmaARCCFCodeAuditedHandler -
1292b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett///   \#pragma clang arc_cf_code_audited begin/end
12938dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCallstruct PragmaARCCFCodeAuditedHandler : public PragmaHandler {
12948dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  PragmaARCCFCodeAuditedHandler() : PragmaHandler("arc_cf_code_audited") {}
1295651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1296651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &NameTok) override {
12978dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    SourceLocation Loc = NameTok.getLocation();
12988dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    bool IsBegin;
12998dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
13008dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    Token Tok;
13018dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
13028dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    // Lex the 'begin' or 'end'.
13038dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    PP.LexUnexpandedToken(Tok);
13048dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    const IdentifierInfo *BeginEnd = Tok.getIdentifierInfo();
13058dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    if (BeginEnd && BeginEnd->isStr("begin")) {
13068dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      IsBegin = true;
13078dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    } else if (BeginEnd && BeginEnd->isStr("end")) {
13088dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      IsBegin = false;
13098dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    } else {
13108dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      PP.Diag(Tok.getLocation(), diag::err_pp_arc_cf_code_audited_syntax);
13118dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      return;
13128dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    }
13138dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
13148dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    // Verify that this is followed by EOD.
13158dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    PP.LexUnexpandedToken(Tok);
13168dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    if (Tok.isNot(tok::eod))
13178dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";
13188dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
13198dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    // The start location of the active audit.
13208dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    SourceLocation BeginLoc = PP.getPragmaARCCFCodeAuditedLoc();
13218dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
13228dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    // The start location we want after processing this.
13238dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    SourceLocation NewLoc;
13248dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
13258dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    if (IsBegin) {
13268dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      // Complain about attempts to re-enter an audit.
13278dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      if (BeginLoc.isValid()) {
13288dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall        PP.Diag(Loc, diag::err_pp_double_begin_of_arc_cf_code_audited);
13298dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall        PP.Diag(BeginLoc, diag::note_pragma_entered_here);
13308dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      }
13318dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      NewLoc = Loc;
13328dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    } else {
13338dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      // Complain about attempts to leave an audit that doesn't exist.
13348dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      if (!BeginLoc.isValid()) {
13358dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall        PP.Diag(Loc, diag::err_pp_unmatched_end_of_arc_cf_code_audited);
13368dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall        return;
13378dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      }
13388dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      NewLoc = SourceLocation();
13398dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    }
13408dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
13418dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    PP.setPragmaARCCFCodeAuditedLoc(NewLoc);
13428dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
13438dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall};
13448dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
1345ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer/// \brief Handle "\#pragma region [...]"
1346ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer///
1347ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer/// The syntax is
1348ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer/// \code
1349ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer///   #pragma region [optional name]
1350ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer///   #pragma endregion [optional comment]
1351ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer/// \endcode
1352ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer///
1353ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer/// \note This is
1354ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer/// <a href="http://msdn.microsoft.com/en-us/library/b6xkz944(v=vs.80).aspx">editor-only</a>
1355ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer/// pragma, just skipped by compiler.
1356ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemerstruct PragmaRegionHandler : public PragmaHandler {
1357ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer  PragmaRegionHandler(const char *pragma) : PragmaHandler(pragma) { }
1358ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer
1359651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1360651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &NameTok) override {
1361ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer    // #pragma region: endregion matches can be verified
1362ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer    // __pragma(region): no sense, but ignored by msvc
1363ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer    // _Pragma is not valid for MSVC, but there isn't any point
1364ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer    // to handle a _Pragma differently.
1365ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer  }
1366ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer};
1367fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman
13685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}  // end anonymous namespace
13695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
13705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
13715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// RegisterBuiltinPragmas - Install the standard preprocessor pragmas:
1372b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \#pragma GCC poison/system_header/dependency and \#pragma once.
13735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid Preprocessor::RegisterBuiltinPragmas() {
13749b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler(new PragmaOnceHandler());
13759b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler(new PragmaMarkHandler());
1376f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  AddPragmaHandler(new PragmaPushMacroHandler());
1377f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  AddPragmaHandler(new PragmaPopMacroHandler());
1378076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  AddPragmaHandler(new PragmaMessageHandler(PPCallbacks::PMK_Message));
13791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1380e8fa06e07363b6d5e6c371bbd454d51bab78d01dChris Lattner  // #pragma GCC ...
13819b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("GCC", new PragmaPoisonHandler());
13829b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("GCC", new PragmaSystemHeaderHandler());
13839b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("GCC", new PragmaDependencyHandler());
1384c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor  AddPragmaHandler("GCC", new PragmaDiagnosticHandler("GCC"));
1385076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  AddPragmaHandler("GCC", new PragmaMessageHandler(PPCallbacks::PMK_Warning,
1386076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                                                   "GCC"));
1387076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  AddPragmaHandler("GCC", new PragmaMessageHandler(PPCallbacks::PMK_Error,
1388076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                                                   "GCC"));
1389e8fa06e07363b6d5e6c371bbd454d51bab78d01dChris Lattner  // #pragma clang ...
13909b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("clang", new PragmaPoisonHandler());
13919b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("clang", new PragmaSystemHeaderHandler());
1392abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar  AddPragmaHandler("clang", new PragmaDebugHandler());
13939b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("clang", new PragmaDependencyHandler());
1394c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor  AddPragmaHandler("clang", new PragmaDiagnosticHandler("clang"));
13958dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  AddPragmaHandler("clang", new PragmaARCCFCodeAuditedHandler());
13969b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis
13979b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("STDC", new PragmaSTDC_FENV_ACCESSHandler());
13989b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("STDC", new PragmaSTDC_CX_LIMITED_RANGEHandler());
1399062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner  AddPragmaHandler("STDC", new PragmaSTDC_UnknownHandler());
14001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1401636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner  // MS extensions.
14024e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (LangOpts.MicrosoftExt) {
14032ee042dee9f7693665e28463955401905474a284Reid Kleckner    AddPragmaHandler(new PragmaWarningHandler());
14044c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    AddPragmaHandler(new PragmaIncludeAliasHandler());
1405fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman    AddPragmaHandler(new PragmaRegionHandler("region"));
1406fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman    AddPragmaHandler(new PragmaRegionHandler("endregion"));
1407abfe094ce71c42656dcb84a3bdc3e79cb3c16fc3Chris Lattner  }
14085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
14096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
14106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// Ignore all pragmas, useful for modes such as -Eonly which would otherwise
14116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// warn about those pragmas being unknown.
14126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid Preprocessor::IgnorePragmas() {
14136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  AddPragmaHandler(new EmptyPragmaHandler());
14146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // Also ignore all pragmas in all namespaces created
14156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // in Preprocessor::RegisterBuiltinPragmas().
14166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  AddPragmaHandler("GCC", new EmptyPragmaHandler());
14176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  AddPragmaHandler("clang", new EmptyPragmaHandler());
14186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (PragmaHandler *NS = PragmaHandlers->FindHandler("STDC")) {
14196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // Preprocessor::RegisterBuiltinPragmas() already registers
14206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // PragmaSTDC_UnknownHandler as the empty handler, so remove it first,
14216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // otherwise there will be an assert about a duplicate handler.
14226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    PragmaNamespace *STDCNamespace = NS->getIfNamespace();
14236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    assert(STDCNamespace &&
14246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines           "Invalid namespace, registered as a regular pragma handler!");
14256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    if (PragmaHandler *Existing = STDCNamespace->FindHandler("", false)) {
14266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      RemovePragmaHandler("STDC", Existing);
14276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      delete Existing;
14286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    }
14296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
14306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  AddPragmaHandler("STDC", new EmptyPragmaHandler());
14316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
1432