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"
25ff759a66526d6a985fb4efae69c6b798d83364dfDaniel Dunbar#include "llvm/Support/CrashRecoveryContext.h"
265505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar#include "llvm/Support/ErrorHandling.h"
272e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor#include <algorithm>
285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang;
295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
302ee042dee9f7693665e28463955401905474a284Reid Kleckner#include "llvm/Support/raw_ostream.h"
312ee042dee9f7693665e28463955401905474a284Reid Kleckner
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Out-of-line destructor to provide a home for the class.
335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerPragmaHandler::~PragmaHandler() {
345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
37c72cc5072cdc1a1a6e05f9d0f962f293a69248c4Daniel Dunbar// EmptyPragmaHandler Implementation.
38c72cc5072cdc1a1a6e05f9d0f962f293a69248c4Daniel Dunbar//===----------------------------------------------------------------------===//
39c72cc5072cdc1a1a6e05f9d0f962f293a69248c4Daniel Dunbar
409b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios KyrtzidisEmptyPragmaHandler::EmptyPragmaHandler() {}
41c72cc5072cdc1a1a6e05f9d0f962f293a69248c4Daniel Dunbar
4280c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregorvoid EmptyPragmaHandler::HandlePragma(Preprocessor &PP,
4380c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                                      PragmaIntroducerKind Introducer,
4480c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                                      Token &FirstToken) {}
45c72cc5072cdc1a1a6e05f9d0f962f293a69248c4Daniel Dunbar
46c72cc5072cdc1a1a6e05f9d0f962f293a69248c4Daniel Dunbar//===----------------------------------------------------------------------===//
475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// PragmaNamespace Implementation.
485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerPragmaNamespace::~PragmaNamespace() {
51651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  llvm::DeleteContainerSeconds(Handlers);
525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// FindHandler - Check to see if there is already a handler for the
555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// specified name.  If not, return the handler for the null identifier if it
565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// exists, otherwise return null.  If IgnoreNull is true (the default) then
575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// the null handler isn't returned on failure to match.
585f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerPragmaHandler *PragmaNamespace::FindHandler(StringRef Name,
595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                            bool IgnoreNull) const {
609b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  if (PragmaHandler *Handler = Handlers.lookup(Name))
619b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis    return Handler;
626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return IgnoreNull ? nullptr : Handlers.lookup(StringRef());
639b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis}
641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
659b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidisvoid PragmaNamespace::AddPragma(PragmaHandler *Handler) {
669b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  assert(!Handlers.lookup(Handler->getName()) &&
679b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis         "A handler with this name is already registered in this namespace");
689b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  llvm::StringMapEntry<PragmaHandler *> &Entry =
699b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis    Handlers.GetOrCreateValue(Handler->getName());
709b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  Entry.setValue(Handler);
715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
734095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbarvoid PragmaNamespace::RemovePragmaHandler(PragmaHandler *Handler) {
749b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  assert(Handlers.lookup(Handler->getName()) &&
759b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis         "Handler not registered in this namespace");
769b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  Handlers.erase(Handler->getName());
774095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar}
784095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar
7980c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregorvoid PragmaNamespace::HandlePragma(Preprocessor &PP,
8080c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                                   PragmaIntroducerKind Introducer,
8180c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                                   Token &Tok) {
825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Read the 'namespace' that the directive is in, e.g. STDC.  Do not macro
835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // expand it, the user can have a STDC #define, that should not affect this.
845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  PP.LexUnexpandedToken(Tok);
851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Get the handler for this token.  If there is no handler, ignore the pragma.
879b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaHandler *Handler
889b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis    = FindHandler(Tok.getIdentifierInfo() ? Tok.getIdentifierInfo()->getName()
895f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                          : StringRef(),
909b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis                  /*IgnoreNull=*/false);
916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (!Handler) {
92af7cdf45da4925f788e87a4c318ee67404646088Chris Lattner    PP.Diag(Tok, diag::warn_pragma_ignored);
93af7cdf45da4925f788e87a4c318ee67404646088Chris Lattner    return;
94af7cdf45da4925f788e87a4c318ee67404646088Chris Lattner  }
951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Otherwise, pass it down.
9780c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  Handler->HandlePragma(PP, Introducer, Tok);
985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
1015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Preprocessor Pragma Directive Handling.
1025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
1035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
104b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// HandlePragmaDirective - The "\#pragma" directive has been parsed.  Lex the
1055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// rest of the pragma, passing it to the registered pragma handlers.
1060189fd61ec72d86e008aa5615be80581f84cf703Enea Zaffanellavoid Preprocessor::HandlePragmaDirective(SourceLocation IntroducerLoc,
1070189fd61ec72d86e008aa5615be80581f84cf703Enea Zaffanella                                         PragmaIntroducerKind Introducer) {
1080189fd61ec72d86e008aa5615be80581f84cf703Enea Zaffanella  if (Callbacks)
1090189fd61ec72d86e008aa5615be80581f84cf703Enea Zaffanella    Callbacks->PragmaDirective(IntroducerLoc, Introducer);
1100189fd61ec72d86e008aa5615be80581f84cf703Enea Zaffanella
1116fe6a49c4058211ff4489023c78615ec0266c5ffJordan Rose  if (!PragmasEnabled)
1126fe6a49c4058211ff4489023c78615ec0266c5ffJordan Rose    return;
1136fe6a49c4058211ff4489023c78615ec0266c5ffJordan Rose
1145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ++NumPragma;
1151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Invoke the first level of pragma handlers which reads the namespace id.
117d217773f106856a11879ec79dc468efefaf2ee75Chris Lattner  Token Tok;
1180189fd61ec72d86e008aa5615be80581f84cf703Enea Zaffanella  PragmaHandlers->HandlePragma(*this, Introducer, Tok);
1191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If the pragma handler didn't read the rest of the line, consume it now.
121b2eb53d9fd973a1a02e05e67a3307b3efd12eff2Peter Collingbourne  if ((CurTokenLexer && CurTokenLexer->isParsingPreprocessorDirective())
122b2eb53d9fd973a1a02e05e67a3307b3efd12eff2Peter Collingbourne   || (CurPPLexer && CurPPLexer->ParsingPreprocessorDirective))
1235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    DiscardUntilEndOfDirective();
1245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
12614e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidisnamespace {
12714e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis/// \brief Helper class for \see Preprocessor::Handle_Pragma.
12814e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidisclass LexingFor_PragmaRAII {
12914e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  Preprocessor &PP;
13014e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  bool InMacroArgPreExpansion;
13114e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  bool Failed;
13214e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  Token &OutTok;
13314e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  Token PragmaTok;
13414e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis
13514e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidispublic:
13614e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  LexingFor_PragmaRAII(Preprocessor &PP, bool InMacroArgPreExpansion,
13714e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis                       Token &Tok)
13814e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    : PP(PP), InMacroArgPreExpansion(InMacroArgPreExpansion),
13914e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis      Failed(false), OutTok(Tok) {
14014e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    if (InMacroArgPreExpansion) {
14114e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis      PragmaTok = OutTok;
14214e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis      PP.EnableBacktrackAtThisPos();
14314e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    }
14414e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  }
14514e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis
14614e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  ~LexingFor_PragmaRAII() {
14714e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    if (InMacroArgPreExpansion) {
14814e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis      if (Failed) {
14914e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis        PP.CommitBacktrackedTokens();
15014e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis      } else {
15114e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis        PP.Backtrack();
15214e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis        OutTok = PragmaTok;
15314e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis      }
15414e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    }
15514e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  }
15614e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis
15714e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  void failed() {
15814e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    Failed = true;
15914e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  }
16014e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis};
16114e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis}
16214e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis
1635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Handle_Pragma - Read a _Pragma directive, slice it up, process it, then
1645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// return the first token after the directive.  The _Pragma token has just
1655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// been read into 'Tok'.
166d217773f106856a11879ec79dc468efefaf2ee75Chris Lattnervoid Preprocessor::Handle_Pragma(Token &Tok) {
16714e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis
16814e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  // This works differently if we are pre-expanding a macro argument.
16914e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  // In that case we don't actually "activate" the pragma now, we only lex it
17014e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  // until we are sure it is lexically correct and then we backtrack so that
17114e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  // we activate the pragma whenever we encounter the tokens again in the token
17214e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  // stream. This ensures that we will activate it in the correct location
17314e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  // or that we will ignore it if it never enters the token stream, e.g:
17414e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  //
17514e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  //     #define EMPTY(x)
17614e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  //     #define INACTIVE(x) EMPTY(x)
17714e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  //     INACTIVE(_Pragma("clang diagnostic ignored \"-Wconversion\""))
17814e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis
17914e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  LexingFor_PragmaRAII _PragmaLexing(*this, InMacroArgPreExpansion, Tok);
18014e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis
1815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Remember the pragma token location.
1825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation PragmaLoc = Tok.getLocation();
1831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Read the '('.
1855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Lex(Tok);
1863692b09faa9fe346f39bc922db6dce48cdcc3f63Chris Lattner  if (Tok.isNot(tok::l_paren)) {
1873692b09faa9fe346f39bc922db6dce48cdcc3f63Chris Lattner    Diag(PragmaLoc, diag::err__Pragma_malformed);
18814e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    return _PragmaLexing.failed();
1893692b09faa9fe346f39bc922db6dce48cdcc3f63Chris Lattner  }
1905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Read the '"..."'.
1925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Lex(Tok);
1930b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith  if (!tok::isStringLiteral(Tok.getKind())) {
1943692b09faa9fe346f39bc922db6dce48cdcc3f63Chris Lattner    Diag(PragmaLoc, diag::err__Pragma_malformed);
19599831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    // Skip this token, and the ')', if present.
19699831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    if (Tok.isNot(tok::r_paren))
19799831e4677a7e2e051af636221694d60ba31fcdbRichard Smith      Lex(Tok);
19899831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    if (Tok.is(tok::r_paren))
19999831e4677a7e2e051af636221694d60ba31fcdbRichard Smith      Lex(Tok);
20014e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    return _PragmaLexing.failed();
20199831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  }
20299831e4677a7e2e051af636221694d60ba31fcdbRichard Smith
20399831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  if (Tok.hasUDSuffix()) {
20499831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    Diag(Tok, diag::err_invalid_string_udl);
20599831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    // Skip this token, and the ')', if present.
20699831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    Lex(Tok);
20799831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    if (Tok.is(tok::r_paren))
20899831e4677a7e2e051af636221694d60ba31fcdbRichard Smith      Lex(Tok);
20914e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    return _PragmaLexing.failed();
2103692b09faa9fe346f39bc922db6dce48cdcc3f63Chris Lattner  }
2111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Remember the string.
21314e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  Token StrTok = Tok;
2145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Read the ')'.
2165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Lex(Tok);
2173692b09faa9fe346f39bc922db6dce48cdcc3f63Chris Lattner  if (Tok.isNot(tok::r_paren)) {
2183692b09faa9fe346f39bc922db6dce48cdcc3f63Chris Lattner    Diag(PragmaLoc, diag::err__Pragma_malformed);
21914e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    return _PragmaLexing.failed();
2203692b09faa9fe346f39bc922db6dce48cdcc3f63Chris Lattner  }
2211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
22214e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  if (InMacroArgPreExpansion)
22314e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    return;
22414e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis
225e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner  SourceLocation RParenLoc = Tok.getLocation();
22614e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  std::string StrVal = getSpelling(StrTok);
2271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2280b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith  // The _Pragma is lexically sound.  Destringize according to C11 6.10.9.1:
2290b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith  // "The string literal is destringized by deleting any encoding prefix,
230a9d9145741ef77db45890911674705b81605b10bChris Lattner  // deleting the leading and trailing double-quotes, replacing each escape
231a9d9145741ef77db45890911674705b81605b10bChris Lattner  // sequence \" by a double-quote, and replacing each escape sequence \\ by a
232a9d9145741ef77db45890911674705b81605b10bChris Lattner  // single backslash."
2330b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith  if (StrVal[0] == 'L' || StrVal[0] == 'U' ||
2340b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith      (StrVal[0] == 'u' && StrVal[1] != '8'))
2355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    StrVal.erase(StrVal.begin());
2360b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith  else if (StrVal[0] == 'u')
2370b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    StrVal.erase(StrVal.begin(), StrVal.begin() + 2);
2380b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith
2390b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith  if (StrVal[0] == 'R') {
2400b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    // FIXME: C++11 does not specify how to handle raw-string-literals here.
2410b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    // We strip off the 'R', the quotes, the d-char-sequences, and the parens.
2420b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    assert(StrVal[1] == '"' && StrVal[StrVal.size() - 1] == '"' &&
2430b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith           "Invalid raw string token!");
2440b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith
2450b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    // Measure the length of the d-char-sequence.
2460b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    unsigned NumDChars = 0;
2470b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    while (StrVal[2 + NumDChars] != '(') {
2480b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith      assert(NumDChars < (StrVal.size() - 5) / 2 &&
2490b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith             "Invalid raw string token!");
2500b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith      ++NumDChars;
2510b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    }
2520b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    assert(StrVal[StrVal.size() - 2 - NumDChars] == ')');
2530b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith
2540b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    // Remove 'R " d-char-sequence' and 'd-char-sequence "'. We'll replace the
2550b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    // parens below.
2560b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    StrVal.erase(0, 2 + NumDChars);
2570b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    StrVal.erase(StrVal.size() - 1 - NumDChars);
2580b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith  } else {
2590b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' &&
2600b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith           "Invalid string token!");
2610b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith
2620b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    // Remove escaped quotes and escapes.
263269cc2daf3a36ad878ea1d4cb356aa38311f6e2dBenjamin Kramer    unsigned ResultPos = 1;
26448b80c78b02efd7c4a7e3a7530d05b8aa9d3b649Reid Kleckner    for (unsigned i = 1, e = StrVal.size() - 1; i != e; ++i) {
26548b80c78b02efd7c4a7e3a7530d05b8aa9d3b649Reid Kleckner      // Skip escapes.  \\ -> '\' and \" -> '"'.
26648b80c78b02efd7c4a7e3a7530d05b8aa9d3b649Reid Kleckner      if (StrVal[i] == '\\' && i + 1 < e &&
26748b80c78b02efd7c4a7e3a7530d05b8aa9d3b649Reid Kleckner          (StrVal[i + 1] == '\\' || StrVal[i + 1] == '"'))
26848b80c78b02efd7c4a7e3a7530d05b8aa9d3b649Reid Kleckner        ++i;
26948b80c78b02efd7c4a7e3a7530d05b8aa9d3b649Reid Kleckner      StrVal[ResultPos++] = StrVal[i];
2700b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    }
27148b80c78b02efd7c4a7e3a7530d05b8aa9d3b649Reid Kleckner    StrVal.erase(StrVal.begin() + ResultPos, StrVal.end() - 1);
2720b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith  }
2731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Remove the front quote, replacing it with a space, so that the pragma
2755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // contents appear to have a space before them.
2765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StrVal[0] = ' ';
2771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2781fa495304c81e03f07f278a47b5efe9317104aabChris Lattner  // Replace the terminating quote with a \n.
2795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StrVal[StrVal.size()-1] = '\n';
2801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
281a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // Plop the string (including the newline and trailing null) into a buffer
282a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // where we can lex it.
283a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  Token TmpTok;
284a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  TmpTok.startToken();
285374b3837d676133fcc1eb70a25c8baf8ec4a5c4aDmitri Gribenko  CreateString(StrVal, TmpTok);
286a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  SourceLocation TokLoc = TmpTok.getLocation();
287a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne
288a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // Make and enter a lexer object so that we lex and expand the tokens just
289a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // like any others.
290a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  Lexer *TL = Lexer::Create_PragmaLexer(TokLoc, PragmaLoc, RParenLoc,
291a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne                                        StrVal.size(), *this);
292a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne
2936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  EnterSourceFileWithLexer(TL, nullptr);
294a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne
295a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // With everything set up, lex this as a #pragma directive.
2960189fd61ec72d86e008aa5615be80581f84cf703Enea Zaffanella  HandlePragmaDirective(PragmaLoc, PIK__Pragma);
2971ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
2981ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  // Finally, return whatever came after the pragma directive.
2991ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  return Lex(Tok);
3001ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall}
3011ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
3021ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall/// HandleMicrosoft__pragma - Like Handle_Pragma except the pragma text
3031ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall/// is not enclosed within a string literal.
3041ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCallvoid Preprocessor::HandleMicrosoft__pragma(Token &Tok) {
3051ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  // Remember the pragma token location.
3061ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  SourceLocation PragmaLoc = Tok.getLocation();
3071ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
3081ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  // Read the '('.
3091ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  Lex(Tok);
3101ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  if (Tok.isNot(tok::l_paren)) {
3111ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall    Diag(PragmaLoc, diag::err__Pragma_malformed);
3121ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall    return;
3131ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  }
3141ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
315a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // Get the tokens enclosed within the __pragma(), as well as the final ')'.
3165f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<Token, 32> PragmaToks;
3171ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  int NumParens = 0;
3181ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  Lex(Tok);
3191ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  while (Tok.isNot(tok::eof)) {
320a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne    PragmaToks.push_back(Tok);
3211ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall    if (Tok.is(tok::l_paren))
3221ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall      NumParens++;
3231ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall    else if (Tok.is(tok::r_paren) && NumParens-- == 0)
3241ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall      break;
3251ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall    Lex(Tok);
3261ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  }
3271ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
3283da92a9d21f707c164797dd967ba894b2282b343John McCall  if (Tok.is(tok::eof)) {
3293da92a9d21f707c164797dd967ba894b2282b343John McCall    Diag(PragmaLoc, diag::err_unterminated___pragma);
3303da92a9d21f707c164797dd967ba894b2282b343John McCall    return;
3313da92a9d21f707c164797dd967ba894b2282b343John McCall  }
3323da92a9d21f707c164797dd967ba894b2282b343John McCall
333a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  PragmaToks.front().setFlag(Token::LeadingSpace);
3341ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
33584021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  // Replace the ')' with an EOD to mark the end of the pragma.
33684021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  PragmaToks.back().setKind(tok::eod);
3371ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
338a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  Token *TokArray = new Token[PragmaToks.size()];
339a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  std::copy(PragmaToks.begin(), PragmaToks.end(), TokArray);
3401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
341a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // Push the tokens onto the stack.
342a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  EnterTokenStream(TokArray, PragmaToks.size(), true, true);
3435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // With everything set up, lex this as a #pragma directive.
3450189fd61ec72d86e008aa5615be80581f84cf703Enea Zaffanella  HandlePragmaDirective(PragmaLoc, PIK___pragma);
3465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
347a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // Finally, return whatever came after the pragma directive.
348a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  return Lex(Tok);
349a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne}
3505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
351b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// HandlePragmaOnce - Handle \#pragma once.  OnceTok is the 'once'.
3525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
353d217773f106856a11879ec79dc468efefaf2ee75Chris Lattnervoid Preprocessor::HandlePragmaOnce(Token &OnceTok) {
3545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (isInPrimaryFile()) {
3555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Diag(OnceTok, diag::pp_pragma_once_in_main_file);
3565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return;
3575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Get the current file lexer we're looking at.  Ignore _Pragma 'files' etc.
3605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Mark the file as a once-only file now.
3612b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  HeaderInfo.MarkFileIncludeOnce(getCurrentFileLexer()->getFileEntry());
3625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
3635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3642243449253475574fc6f14986ff8f7fce5d46799Chris Lattnervoid Preprocessor::HandlePragmaMark() {
36517ff58a63197b398ae52697b088dc0fb8b255519Ted Kremenek  assert(CurPPLexer && "No current lexer?");
3666896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner  if (CurLexer)
3676896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner    CurLexer->ReadToEndOfLine();
3686896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner  else
3696896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner    CurPTHLexer->DiscardToEndOfLine();
3702243449253475574fc6f14986ff8f7fce5d46799Chris Lattner}
3712243449253475574fc6f14986ff8f7fce5d46799Chris Lattner
3722243449253475574fc6f14986ff8f7fce5d46799Chris Lattner
373b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// HandlePragmaPoison - Handle \#pragma GCC poison.  PoisonTok is the 'poison'.
3745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
375d217773f106856a11879ec79dc468efefaf2ee75Chris Lattnervoid Preprocessor::HandlePragmaPoison(Token &PoisonTok) {
376d217773f106856a11879ec79dc468efefaf2ee75Chris Lattner  Token Tok;
3775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  while (1) {
3795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Read the next token to poison.  While doing this, pretend that we are
3805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // skipping while reading the identifier to poison.
3815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // This avoids errors on code like:
3825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    //   #pragma GCC poison X
3835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    //   #pragma GCC poison X
38468a91d5736c2c03d60a9d1c59d08191b8e0d6c52Ted Kremenek    if (CurPPLexer) CurPPLexer->LexingRawMode = true;
3855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    LexUnexpandedToken(Tok);
38668a91d5736c2c03d60a9d1c59d08191b8e0d6c52Ted Kremenek    if (CurPPLexer) CurPPLexer->LexingRawMode = false;
3871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // If we reached the end of line, we're done.
38984021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne    if (Tok.is(tok::eod)) return;
3901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Can only poison identifiers.
392c4bf2b9afb7d47445a9dc6bc848657098a4e3851Abramo Bagnara    if (Tok.isNot(tok::raw_identifier)) {
3935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Diag(Tok, diag::err_pp_invalid_poison);
3945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      return;
3955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
3961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Look up the identifier info for the token.  We disabled identifier lookup
3985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // by saying we're skipping contents, so we need to do this manually.
3995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    IdentifierInfo *II = LookUpIdentifierInfo(Tok);
4001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Already poisoned.
4025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (II->isPoisoned()) continue;
4031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // If this is a macro identifier, emit a warning.
4050edde55077cc3cb9fffeba19f5936f05a68c8e2bChris Lattner    if (II->hasMacroDefinition())
4065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Diag(Tok, diag::pp_poisoning_existing_macro);
4071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Finally, poison it!
4095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    II->setIsPoisoned();
410eee242ff426bf79149f221798966e58688383c1eDouglas Gregor    if (II->isFromAST())
411eee242ff426bf79149f221798966e58688383c1eDouglas Gregor      II->setChangedSinceDeserialization();
4125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
4145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
415b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// HandlePragmaSystemHeader - Implement \#pragma GCC system_header.  We know
4165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// that the whole directive has been parsed.
417d217773f106856a11879ec79dc468efefaf2ee75Chris Lattnervoid Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) {
4185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (isInPrimaryFile()) {
4195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);
4205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return;
4215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Get the current file lexer we're looking at.  Ignore _Pragma 'files' etc.
42435c10c25ddec4effbd26dead23ea5b04ee32f45aTed Kremenek  PreprocessorLexer *TheLexer = getCurrentFileLexer();
4251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Mark the file as a system header.
4272b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  HeaderInfo.MarkFileSystemHeader(TheLexer->getFileEntry());
4281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4306896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner  PresumedLoc PLoc = SourceMgr.getPresumedLoc(SysHeaderTok.getLocation());
431cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor  if (PLoc.isInvalid())
432cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor    return;
433cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor
43465aa6885818d4b4eea2e5a9d12085b2398148662Jay Foad  unsigned FilenameID = SourceMgr.getLineTableFilenameID(PLoc.getFilename());
4351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
436784c257c8f5c3a737b0ae1dceb5d54d29b6637cfChris Lattner  // Notify the client, if desired, that we are in a new source file.
437784c257c8f5c3a737b0ae1dceb5d54d29b6637cfChris Lattner  if (Callbacks)
438784c257c8f5c3a737b0ae1dceb5d54d29b6637cfChris Lattner    Callbacks->FileChanged(SysHeaderTok.getLocation(),
439784c257c8f5c3a737b0ae1dceb5d54d29b6637cfChris Lattner                           PPCallbacks::SystemHeaderPragma, SrcMgr::C_System);
440784c257c8f5c3a737b0ae1dceb5d54d29b6637cfChris Lattner
4416896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner  // Emit a line marker.  This will change any source locations from this point
4426896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner  // forward to realize they are in a system header.
4436896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner  // Create a line note with this information.
444142b35e25b579e2a883d6ca37c3c1121f562f242Jordan Rose  SourceMgr.AddLineNote(SysHeaderTok.getLocation(), PLoc.getLine()+1,
445142b35e25b579e2a883d6ca37c3c1121f562f242Jordan Rose                        FilenameID, /*IsEntry=*/false, /*IsExit=*/false,
446142b35e25b579e2a883d6ca37c3c1121f562f242Jordan Rose                        /*IsSystem=*/true, /*IsExternC=*/false);
4475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
4485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
449b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// HandlePragmaDependency - Handle \#pragma GCC dependency "foo" blah.
4505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
451d217773f106856a11879ec79dc468efefaf2ee75Chris Lattnervoid Preprocessor::HandlePragmaDependency(Token &DependencyTok) {
452d217773f106856a11879ec79dc468efefaf2ee75Chris Lattner  Token FilenameTok;
45368a91d5736c2c03d60a9d1c59d08191b8e0d6c52Ted Kremenek  CurPPLexer->LexIncludeFilename(FilenameTok);
4545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
45584021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  // If the token kind is EOD, the error has already been diagnosed.
45684021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  if (FilenameTok.is(tok::eod))
4575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return;
4581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Reserve a buffer to get the spelling.
460f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<128> FilenameBuffer;
461453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor  bool Invalid = false;
4625f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Filename = getSpelling(FilenameTok, FilenameBuffer, &Invalid);
463453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor  if (Invalid)
464453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor    return;
4651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
466a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner  bool isAngled =
467a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner    GetIncludeFilenameSpelling(FilenameTok.getLocation(), Filename);
4685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If GetIncludeFilenameSpelling set the start ptr to null, there was an
4695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // error.
470a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner  if (Filename.empty())
4715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return;
4721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Search include directories for this file.
4745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const DirectoryLookup *CurDir;
475bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl  const FileEntry *File = LookupFile(FilenameTok.getLocation(), Filename,
4766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                     isAngled, nullptr, CurDir, nullptr,
4776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                     nullptr, nullptr);
4786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (!File) {
479f84139a1331c63c998e8b7d54148c75ac0b48ccdEli Friedman    if (!SuppressIncludeNotFoundError)
480f84139a1331c63c998e8b7d54148c75ac0b48ccdEli Friedman      Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
48156b05c8829efd13b7e5b333f8f587c71d025c67dChris Lattner    return;
48256b05c8829efd13b7e5b333f8f587c71d025c67dChris Lattner  }
4831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4842b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  const FileEntry *CurFile = getCurrentFileLexer()->getFileEntry();
4855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If this file is older than the file it depends on, emit a diagnostic.
4875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (CurFile && CurFile->getModificationTime() < File->getModificationTime()) {
4885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Lex tokens at the end of the message and include them in the message.
4895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    std::string Message;
4905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Lex(DependencyTok);
49184021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne    while (DependencyTok.isNot(tok::eod)) {
4925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Message += getSpelling(DependencyTok) + " ";
4935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Lex(DependencyTok);
4945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
4951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
49696de25986d28171945db96a6c6a54f91fd12ae4bChris Lattner    // Remove the trailing ' ' if present.
49796de25986d28171945db96a6c6a54f91fd12ae4bChris Lattner    if (!Message.empty())
49896de25986d28171945db96a6c6a54f91fd12ae4bChris Lattner      Message.erase(Message.end()-1);
49956b05c8829efd13b7e5b333f8f587c71d025c67dChris Lattner    Diag(FilenameTok, diag::pp_out_of_date_dependency) << Message;
5005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
5015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
5025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5037adf79a620cb7fbde0608e21727425930676b7dbReid Kleckner/// ParsePragmaPushOrPopMacro - Handle parsing of pragma push_macro/pop_macro.
504f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner/// Return the IdentifierInfo* associated with the macro to push or pop.
505f47724bf78299c7a50f008e0443c5f9f9f279ddcChris LattnerIdentifierInfo *Preprocessor::ParsePragmaPushOrPopMacro(Token &Tok) {
506f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Remember the pragma token location.
507f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  Token PragmaTok = Tok;
508f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
509f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Read the '('.
510f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  Lex(Tok);
511f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (Tok.isNot(tok::l_paren)) {
512f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
513f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner      << getSpelling(PragmaTok);
5146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
515f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
516f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
517f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Read the macro name string.
518f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  Lex(Tok);
519f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (Tok.isNot(tok::string_literal)) {
520f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
521f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner      << getSpelling(PragmaTok);
5226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
523f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
524f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
52599831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  if (Tok.hasUDSuffix()) {
52699831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    Diag(Tok, diag::err_invalid_string_udl);
5276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
52899831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  }
52999831e4677a7e2e051af636221694d60ba31fcdbRichard Smith
530f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Remember the macro string.
531f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  std::string StrVal = getSpelling(Tok);
532f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
533f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Read the ')'.
534f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  Lex(Tok);
535f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (Tok.isNot(tok::r_paren)) {
536f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
537f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner      << getSpelling(PragmaTok);
5386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
539f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
540f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
541f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' &&
542f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner         "Invalid string token!");
543f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
544f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Create a Token from the string.
545f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  Token MacroTok;
546f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  MacroTok.startToken();
547c4bf2b9afb7d47445a9dc6bc848657098a4e3851Abramo Bagnara  MacroTok.setKind(tok::raw_identifier);
548374b3837d676133fcc1eb70a25c8baf8ec4a5c4aDmitri Gribenko  CreateString(StringRef(&StrVal[1], StrVal.size() - 2), MacroTok);
549f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
550f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Get the IdentifierInfo of MacroToPushTok.
551f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  return LookUpIdentifierInfo(MacroTok);
552f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner}
553f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
554b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \brief Handle \#pragma push_macro.
555b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett///
556f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner/// The syntax is:
557b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \code
558e74dc199e95cc523c8806e0de41d8814e8bc5c42Dmitri Gribenko///   #pragma push_macro("macro")
559b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \endcode
560f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattnervoid Preprocessor::HandlePragmaPushMacro(Token &PushMacroTok) {
561f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Parse the pragma directive and get the macro IdentifierInfo*.
562f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PushMacroTok);
563f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (!IdentInfo) return;
564f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
565f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Get the MacroInfo associated with IdentInfo.
566f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  MacroInfo *MI = getMacroInfo(IdentInfo);
567f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
568f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (MI) {
569f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    // Allow the original MacroInfo to be redefined later.
570f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    MI->setIsAllowRedefinitionsWithoutWarning(true);
571f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
572f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
573f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Push the cloned MacroInfo so we can retrieve it later.
5749818a1d443e97677dd3422305de9cc2b1fb2a8c1Argyrios Kyrtzidis  PragmaPushMacroInfo[IdentInfo].push_back(MI);
575f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner}
576f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
577b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \brief Handle \#pragma pop_macro.
578b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett///
579f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner/// The syntax is:
580b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \code
581f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner///   #pragma pop_macro("macro")
582b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \endcode
583f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattnervoid Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) {
584f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  SourceLocation MessageLoc = PopMacroTok.getLocation();
585f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
586f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Parse the pragma directive and get the macro IdentifierInfo*.
587f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PopMacroTok);
588f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (!IdentInfo) return;
589f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
590f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Find the vector<MacroInfo*> associated with the macro.
591f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> >::iterator iter =
592f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    PragmaPushMacroInfo.find(IdentInfo);
593f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (iter != PragmaPushMacroInfo.end()) {
5948a64bb58c3b24d7d97895e435bbc0965c99bd3beAlexander Kornienko    // Forget the MacroInfo currently associated with IdentInfo.
5959818a1d443e97677dd3422305de9cc2b1fb2a8c1Argyrios Kyrtzidis    if (MacroDirective *CurrentMD = getMacroDirective(IdentInfo)) {
596c56fff7fd231aebf4b152f60f8f11ef91835c48aArgyrios Kyrtzidis      MacroInfo *MI = CurrentMD->getMacroInfo();
597c56fff7fd231aebf4b152f60f8f11ef91835c48aArgyrios Kyrtzidis      if (MI->isWarnIfUnused())
598c56fff7fd231aebf4b152f60f8f11ef91835c48aArgyrios Kyrtzidis        WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
599c56fff7fd231aebf4b152f60f8f11ef91835c48aArgyrios Kyrtzidis      appendMacroDirective(IdentInfo, AllocateUndefMacroDirective(MessageLoc));
6000827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis    }
601f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
602f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    // Get the MacroInfo we want to reinstall.
603f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    MacroInfo *MacroToReInstall = iter->second.back();
604f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
605e40c4238a572bf8241a04e0005f70550cbfc1cfbAlexander Kornienko    if (MacroToReInstall) {
606e40c4238a572bf8241a04e0005f70550cbfc1cfbAlexander Kornienko      // Reinstall the previously pushed macro.
607c56fff7fd231aebf4b152f60f8f11ef91835c48aArgyrios Kyrtzidis      appendDefMacroDirective(IdentInfo, MacroToReInstall, MessageLoc,
608c56fff7fd231aebf4b152f60f8f11ef91835c48aArgyrios Kyrtzidis                              /*isImported=*/false);
609e40c4238a572bf8241a04e0005f70550cbfc1cfbAlexander Kornienko    }
610f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
611f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    // Pop PragmaPushMacroInfo stack.
612f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    iter->second.pop_back();
613f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    if (iter->second.size() == 0)
614f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner      PragmaPushMacroInfo.erase(iter);
615f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  } else {
616f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    Diag(MessageLoc, diag::warn_pragma_pop_macro_no_push)
617f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner      << IdentInfo->getName();
618f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
619f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner}
6205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6214c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballmanvoid Preprocessor::HandlePragmaIncludeAlias(Token &Tok) {
6224c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // We will either get a quoted filename or a bracketed filename, and we
6234c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // have to track which we got.  The first filename is the source name,
6244c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // and the second name is the mapped filename.  If the first is quoted,
6254c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // the second must be as well (cannot mix and match quotes and brackets).
6264c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6274c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // Get the open paren
6284c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  Lex(Tok);
6294c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (Tok.isNot(tok::l_paren)) {
6304c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    Diag(Tok, diag::warn_pragma_include_alias_expected) << "(";
6314c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
6324c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
6334c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6344c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // We expect either a quoted string literal, or a bracketed name
6354c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  Token SourceFilenameTok;
6364c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  CurPPLexer->LexIncludeFilename(SourceFilenameTok);
6374c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (SourceFilenameTok.is(tok::eod)) {
6384c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    // The diagnostic has already been handled
6394c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
6404c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
6414c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6424c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  StringRef SourceFileName;
6434c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  SmallString<128> FileNameBuffer;
6444c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (SourceFilenameTok.is(tok::string_literal) ||
6454c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      SourceFilenameTok.is(tok::angle_string_literal)) {
6464c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    SourceFileName = getSpelling(SourceFilenameTok, FileNameBuffer);
6474c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  } else if (SourceFilenameTok.is(tok::less)) {
6484c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    // This could be a path instead of just a name
6494c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    FileNameBuffer.push_back('<');
6504c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    SourceLocation End;
6514c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    if (ConcatenateIncludeName(FileNameBuffer, End))
6524c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      return; // Diagnostic already emitted
6534c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    SourceFileName = FileNameBuffer.str();
6544c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  } else {
6554c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
6564c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
6574c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
6584c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  FileNameBuffer.clear();
6594c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6604c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // Now we expect a comma, followed by another include name
6614c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  Lex(Tok);
6624c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (Tok.isNot(tok::comma)) {
6634c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    Diag(Tok, diag::warn_pragma_include_alias_expected) << ",";
6644c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
6654c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
6664c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6674c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  Token ReplaceFilenameTok;
6684c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  CurPPLexer->LexIncludeFilename(ReplaceFilenameTok);
6694c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (ReplaceFilenameTok.is(tok::eod)) {
6704c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    // The diagnostic has already been handled
6714c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
6724c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
6734c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6744c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  StringRef ReplaceFileName;
6754c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (ReplaceFilenameTok.is(tok::string_literal) ||
6764c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      ReplaceFilenameTok.is(tok::angle_string_literal)) {
6774c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    ReplaceFileName = getSpelling(ReplaceFilenameTok, FileNameBuffer);
6784c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  } else if (ReplaceFilenameTok.is(tok::less)) {
6794c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    // This could be a path instead of just a name
6804c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    FileNameBuffer.push_back('<');
6814c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    SourceLocation End;
6824c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    if (ConcatenateIncludeName(FileNameBuffer, End))
6834c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      return; // Diagnostic already emitted
6844c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    ReplaceFileName = FileNameBuffer.str();
6854c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  } else {
6864c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
6874c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
6884c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
6894c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6904c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // Finally, we expect the closing paren
6914c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  Lex(Tok);
6924c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (Tok.isNot(tok::r_paren)) {
6934c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    Diag(Tok, diag::warn_pragma_include_alias_expected) << ")";
6944c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
6954c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
6964c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6974c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // Now that we have the source and target filenames, we need to make sure
6984c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // they're both of the same type (angled vs non-angled)
6994c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  StringRef OriginalSource = SourceFileName;
7004c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
7014c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  bool SourceIsAngled =
7024c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    GetIncludeFilenameSpelling(SourceFilenameTok.getLocation(),
7034c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman                                SourceFileName);
7044c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  bool ReplaceIsAngled =
7054c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    GetIncludeFilenameSpelling(ReplaceFilenameTok.getLocation(),
7064c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman                                ReplaceFileName);
7074c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (!SourceFileName.empty() && !ReplaceFileName.empty() &&
7084c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      (SourceIsAngled != ReplaceIsAngled)) {
7094c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    unsigned int DiagID;
7104c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    if (SourceIsAngled)
7114c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      DiagID = diag::warn_pragma_include_alias_mismatch_angle;
7124c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    else
7134c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      DiagID = diag::warn_pragma_include_alias_mismatch_quote;
7144c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
7154c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    Diag(SourceFilenameTok.getLocation(), DiagID)
7164c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      << SourceFileName
7174c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      << ReplaceFileName;
7184c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
7194c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
7204c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
7214c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
7224c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // Now we can let the include handler know about this mapping
7234c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  getHeaderSearchInfo().AddIncludeAlias(OriginalSource, ReplaceFileName);
7244c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman}
7254c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
7265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// AddPragmaHandler - Add the specified pragma handler to the preprocessor.
7275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// If 'Namespace' is non-null, then it is a token required to exist on the
7285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
7295f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Preprocessor::AddPragmaHandler(StringRef Namespace,
7305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                    PragmaHandler *Handler) {
7315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  PragmaNamespace *InsertNS = PragmaHandlers;
7321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If this is specified to be in a namespace, step down into it.
7349b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  if (!Namespace.empty()) {
7355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // If there is already a pragma handler with the name of this namespace,
7365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // we either have an error (directive with the same name as a namespace) or
7375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // we already have the namespace to insert into.
7389b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis    if (PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace)) {
7395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      InsertNS = Existing->getIfNamespace();
7406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      assert(InsertNS != nullptr && "Cannot have a pragma namespace and pragma"
7415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer             " handler with the same name!");
7425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    } else {
7435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      // Otherwise, this namespace doesn't exist yet, create and insert the
7445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      // handler for it.
7459b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis      InsertNS = new PragmaNamespace(Namespace);
7465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      PragmaHandlers->AddPragma(InsertNS);
7475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
7485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
7491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Check to make sure we don't already have a pragma for this identifier.
7515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  assert(!InsertNS->FindHandler(Handler->getName()) &&
7525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         "Pragma handler already exists for this identifier!");
7535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  InsertNS->AddPragma(Handler);
7545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
7555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7564095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar/// RemovePragmaHandler - Remove the specific pragma handler from the
7574095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar/// preprocessor. If \arg Namespace is non-null, then it should be the
7584095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar/// namespace that \arg Handler was added to. It is an error to remove
7594095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar/// a handler that has not been registered.
7605f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Preprocessor::RemovePragmaHandler(StringRef Namespace,
7614095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar                                       PragmaHandler *Handler) {
7624095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar  PragmaNamespace *NS = PragmaHandlers;
7631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7644095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar  // If this is specified to be in a namespace, step down into it.
7659b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  if (!Namespace.empty()) {
7669b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis    PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace);
7674095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar    assert(Existing && "Namespace containing handler does not exist!");
7684095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar
7694095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar    NS = Existing->getIfNamespace();
7704095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar    assert(NS && "Invalid namespace, registered as a regular pragma handler!");
7714095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar  }
7724095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar
7734095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar  NS->RemovePragmaHandler(Handler);
7741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7754095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar  // If this is a non-default namespace and it is now empty, remove
7764095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar  // it.
777ce52bb3dec520ef94574280ac3ef8ad63f4f1ce2Argyrios Kyrtzidis  if (NS != PragmaHandlers && NS->IsEmpty()) {
7784095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar    PragmaHandlers->RemovePragmaHandler(NS);
779ce52bb3dec520ef94574280ac3ef8ad63f4f1ce2Argyrios Kyrtzidis    delete NS;
780ce52bb3dec520ef94574280ac3ef8ad63f4f1ce2Argyrios Kyrtzidis  }
7814095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar}
7824095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar
7839d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbournebool Preprocessor::LexOnOffSwitch(tok::OnOffSwitch &Result) {
7849d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  Token Tok;
7859d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  LexUnexpandedToken(Tok);
7869d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne
7879d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  if (Tok.isNot(tok::identifier)) {
7889d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    Diag(Tok, diag::ext_on_off_switch_syntax);
7899d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    return true;
7909d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  }
7919d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  IdentifierInfo *II = Tok.getIdentifierInfo();
7929d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  if (II->isStr("ON"))
7939d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    Result = tok::OOS_ON;
7949d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  else if (II->isStr("OFF"))
7959d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    Result = tok::OOS_OFF;
7969d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  else if (II->isStr("DEFAULT"))
7979d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    Result = tok::OOS_DEFAULT;
7989d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  else {
7999d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    Diag(Tok, diag::ext_on_off_switch_syntax);
8009d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    return true;
8019d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  }
8029d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne
80384021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  // Verify that this is followed by EOD.
8049d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  LexUnexpandedToken(Tok);
80584021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  if (Tok.isNot(tok::eod))
80684021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne    Diag(Tok, diag::ext_pragma_syntax_eod);
8079d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  return false;
8089d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne}
8099d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne
8105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace {
811b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaOnceHandler - "\#pragma once" marks the file as atomically included.
8125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstruct PragmaOnceHandler : public PragmaHandler {
8139b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaOnceHandler() : PragmaHandler("once") {}
814651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
815651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &OnceTok) override {
81635410d5cbbb18735d76e00496540d416dc49b577Chris Lattner    PP.CheckEndOfDirective("pragma once");
8175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    PP.HandlePragmaOnce(OnceTok);
8185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
8195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
8205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
821b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaMarkHandler - "\#pragma mark ..." is ignored by the compiler, and the
8222243449253475574fc6f14986ff8f7fce5d46799Chris Lattner/// rest of the line is not lexed.
8232243449253475574fc6f14986ff8f7fce5d46799Chris Lattnerstruct PragmaMarkHandler : public PragmaHandler {
8249b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaMarkHandler() : PragmaHandler("mark") {}
825651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
826651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &MarkTok) override {
8272243449253475574fc6f14986ff8f7fce5d46799Chris Lattner    PP.HandlePragmaMark();
8282243449253475574fc6f14986ff8f7fce5d46799Chris Lattner  }
8292243449253475574fc6f14986ff8f7fce5d46799Chris Lattner};
8302243449253475574fc6f14986ff8f7fce5d46799Chris Lattner
831b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaPoisonHandler - "\#pragma poison x" marks x as not usable.
8325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstruct PragmaPoisonHandler : public PragmaHandler {
8339b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaPoisonHandler() : PragmaHandler("poison") {}
834651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
835651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &PoisonTok) override {
8365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    PP.HandlePragmaPoison(PoisonTok);
8375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
8385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
8395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
840b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaSystemHeaderHandler - "\#pragma system_header" marks the current file
8412243449253475574fc6f14986ff8f7fce5d46799Chris Lattner/// as a system header, which silences warnings in it.
8425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstruct PragmaSystemHeaderHandler : public PragmaHandler {
8439b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaSystemHeaderHandler() : PragmaHandler("system_header") {}
844651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
845651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &SHToken) override {
8465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    PP.HandlePragmaSystemHeader(SHToken);
84735410d5cbbb18735d76e00496540d416dc49b577Chris Lattner    PP.CheckEndOfDirective("pragma");
8485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
8495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
8505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstruct PragmaDependencyHandler : public PragmaHandler {
8519b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaDependencyHandler() : PragmaHandler("dependency") {}
852651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
853651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &DepToken) override {
8545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    PP.HandlePragmaDependency(DepToken);
8555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
8565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
8571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
858abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbarstruct PragmaDebugHandler : public PragmaHandler {
859abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar  PragmaDebugHandler() : PragmaHandler("__debug") {}
860651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
861651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &DepToken) override {
862abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    Token Tok;
863abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    PP.LexUnexpandedToken(Tok);
864abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    if (Tok.isNot(tok::identifier)) {
8656493a4d7129673f7878da2382dedf4f9abc57e4cDouglas Gregor      PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
866abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar      return;
867abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    }
868abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    IdentifierInfo *II = Tok.getIdentifierInfo();
869abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar
8705505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar    if (II->isStr("assert")) {
871b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie      llvm_unreachable("This is an assertion!");
872abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    } else if (II->isStr("crash")) {
873377da4c6b78c0130fb6141313636c8fda7b60b72David Blaikie      LLVM_BUILTIN_TRAP;
874e75d9cfbf41a0ee9e456a665776f91fdd9773b36David Blaikie    } else if (II->isStr("parser_crash")) {
875e75d9cfbf41a0ee9e456a665776f91fdd9773b36David Blaikie      Token Crasher;
876e75d9cfbf41a0ee9e456a665776f91fdd9773b36David Blaikie      Crasher.setKind(tok::annot_pragma_parser_crash);
877e75d9cfbf41a0ee9e456a665776f91fdd9773b36David Blaikie      PP.EnterToken(Crasher);
8785505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar    } else if (II->isStr("llvm_fatal_error")) {
8795505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar      llvm::report_fatal_error("#pragma clang __debug llvm_fatal_error");
8805505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar    } else if (II->isStr("llvm_unreachable")) {
8815505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar      llvm_unreachable("#pragma clang __debug llvm_unreachable");
8825505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar    } else if (II->isStr("overflow_stack")) {
8835505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar      DebugOverflowStack();
884ff759a66526d6a985fb4efae69c6b798d83364dfDaniel Dunbar    } else if (II->isStr("handle_crash")) {
885ff759a66526d6a985fb4efae69c6b798d83364dfDaniel Dunbar      llvm::CrashRecoveryContext *CRC =llvm::CrashRecoveryContext::GetCurrent();
886ff759a66526d6a985fb4efae69c6b798d83364dfDaniel Dunbar      if (CRC)
887ff759a66526d6a985fb4efae69c6b798d83364dfDaniel Dunbar        CRC->HandleCrash();
88885192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    } else if (II->isStr("captured")) {
88985192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj      HandleCaptured(PP);
8905505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar    } else {
8915505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar      PP.Diag(Tok, diag::warn_pragma_debug_unexpected_command)
8925505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar        << II->getName();
893abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    }
89485192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj
89585192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    PPCallbacks *Callbacks = PP.getPPCallbacks();
89685192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    if (Callbacks)
89785192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj      Callbacks->PragmaDebug(Tok.getLocation(), II->getName());
89885192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj  }
89985192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj
90085192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj  void HandleCaptured(Preprocessor &PP) {
90185192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    // Skip if emitting preprocessed output.
90285192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    if (PP.isPreprocessedOutput())
90385192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj      return;
90485192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj
90585192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    Token Tok;
90685192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    PP.LexUnexpandedToken(Tok);
90785192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj
90885192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    if (Tok.isNot(tok::eod)) {
90985192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj      PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol)
91085192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj        << "pragma clang __debug captured";
91185192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj      return;
91285192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    }
91385192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj
91485192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    SourceLocation NameLoc = Tok.getLocation();
91585192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    Token *Toks = PP.getPreprocessorAllocator().Allocate<Token>(1);
91685192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    Toks->startToken();
91785192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    Toks->setKind(tok::annot_pragma_captured);
91885192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    Toks->setLocation(NameLoc);
91985192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj
92085192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
92185192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj                        /*OwnsTokens=*/false);
922abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar  }
923abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar
9241066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet// Disable MSVC warning about runtime stack overflow.
9251066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet#ifdef _MSC_VER
9261066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet    #pragma warning(disable : 4717)
9271066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet#endif
928651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  static void DebugOverflowStack() {
929651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    void (*volatile Self)() = DebugOverflowStack;
930651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Self();
931abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar  }
9321066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet#ifdef _MSC_VER
9331066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet    #pragma warning(default : 4717)
9341066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet#endif
9351066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet
936abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar};
937abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar
938b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaDiagnosticHandler - e.g. '\#pragma GCC diagnostic ignored "-Wformat"'
939edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattnerstruct PragmaDiagnosticHandler : public PragmaHandler {
940c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregorprivate:
941c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor  const char *Namespace;
94204ae2df026b275aae5dddfc0db5ca55ff4e62179Chris Lattnerpublic:
943c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor  explicit PragmaDiagnosticHandler(const char *NS) :
944c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor    PragmaHandler("diagnostic"), Namespace(NS) {}
945651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
946651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &DiagToken) override {
9470827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis    SourceLocation DiagLoc = DiagToken.getLocation();
948edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    Token Tok;
949edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    PP.LexUnexpandedToken(Tok);
950edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    if (Tok.isNot(tok::identifier)) {
9516493a4d7129673f7878da2382dedf4f9abc57e4cDouglas Gregor      PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
952edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      return;
953edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    }
954edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    IdentifierInfo *II = Tok.getIdentifierInfo();
955c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor    PPCallbacks *Callbacks = PP.getPPCallbacks();
9561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
957ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    if (II->isStr("pop")) {
9580827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis      if (!PP.getDiagnostics().popMappings(DiagLoc))
9596493a4d7129673f7878da2382dedf4f9abc57e4cDouglas Gregor        PP.Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
960c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor      else if (Callbacks)
961c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor        Callbacks->PragmaDiagnosticPop(DiagLoc, Namespace);
9626493a4d7129673f7878da2382dedf4f9abc57e4cDouglas Gregor      return;
9636493a4d7129673f7878da2382dedf4f9abc57e4cDouglas Gregor    } else if (II->isStr("push")) {
9640827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis      PP.getDiagnostics().pushMappings(DiagLoc);
965c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor      if (Callbacks)
966c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor        Callbacks->PragmaDiagnosticPush(DiagLoc, Namespace);
96704ae2df026b275aae5dddfc0db5ca55ff4e62179Chris Lattner      return;
968ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    }
969ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
970ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    diag::Severity SV = llvm::StringSwitch<diag::Severity>(II->getName())
971ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                            .Case("ignored", diag::Severity::Ignored)
972ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                            .Case("warning", diag::Severity::Warning)
973ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                            .Case("error", diag::Severity::Error)
974ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                            .Case("fatal", diag::Severity::Fatal)
975ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                            .Default(diag::Severity());
976ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
977ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    if (SV == diag::Severity()) {
9786493a4d7129673f7878da2382dedf4f9abc57e4cDouglas Gregor      PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
979edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      return;
980edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    }
9811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
982edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    PP.LexUnexpandedToken(Tok);
98302a176871d91bba3004e4f94b2d4d588ae4b2122Andy Gibbs    SourceLocation StringLoc = Tok.getLocation();
984edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner
98502a176871d91bba3004e4f94b2d4d588ae4b2122Andy Gibbs    std::string WarningName;
98697f8461a2c553f68a258612d2322e4281c3f0915Andy Gibbs    if (!PP.FinishLexStringLiteral(Tok, WarningName, "pragma diagnostic",
98797f8461a2c553f68a258612d2322e4281c3f0915Andy Gibbs                                   /*MacroExpansion=*/false))
988edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      return;
9891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
99084021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne    if (Tok.isNot(tok::eod)) {
991edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      PP.Diag(Tok.getLocation(), diag::warn_pragma_diagnostic_invalid_token);
992edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      return;
993edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    }
9941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
995edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    if (WarningName.size() < 3 || WarningName[0] != '-' ||
996edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner        WarningName[1] != 'W') {
99702a176871d91bba3004e4f94b2d4d588ae4b2122Andy Gibbs      PP.Diag(StringLoc, diag::warn_pragma_diagnostic_invalid_option);
998edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      return;
999edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    }
10001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1001ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    if (PP.getDiagnostics().setSeverityForGroup(WarningName.substr(2), SV,
1002ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                                                DiagLoc))
100302a176871d91bba3004e4f94b2d4d588ae4b2122Andy Gibbs      PP.Diag(StringLoc, diag::warn_pragma_diagnostic_unknown_warning)
100402a176871d91bba3004e4f94b2d4d588ae4b2122Andy Gibbs        << WarningName;
1005c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor    else if (Callbacks)
1006ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      Callbacks->PragmaDiagnostic(DiagLoc, Namespace, SV, WarningName);
1007edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner  }
1008edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner};
10091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10102ee042dee9f7693665e28463955401905474a284Reid Kleckner/// "\#pragma warning(...)".  MSVC's diagnostics do not map cleanly to clang's
10112ee042dee9f7693665e28463955401905474a284Reid Kleckner/// diagnostics, so we don't really implement this pragma.  We parse it and
10122ee042dee9f7693665e28463955401905474a284Reid Kleckner/// ignore it to avoid -Wunknown-pragma warnings.
10132ee042dee9f7693665e28463955401905474a284Reid Klecknerstruct PragmaWarningHandler : public PragmaHandler {
10142ee042dee9f7693665e28463955401905474a284Reid Kleckner  PragmaWarningHandler() : PragmaHandler("warning") {}
10152ee042dee9f7693665e28463955401905474a284Reid Kleckner
1016651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1017651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &Tok) override {
10182ee042dee9f7693665e28463955401905474a284Reid Kleckner    // Parse things like:
10192ee042dee9f7693665e28463955401905474a284Reid Kleckner    // warning(push, 1)
10202ee042dee9f7693665e28463955401905474a284Reid Kleckner    // warning(pop)
1021faea5bfd7583fe259b352b350bb5689f8c96de17John Thompson    // warning(disable : 1 2 3 ; error : 4 5 6 ; suppress : 7 8 9)
10222ee042dee9f7693665e28463955401905474a284Reid Kleckner    SourceLocation DiagLoc = Tok.getLocation();
10232ee042dee9f7693665e28463955401905474a284Reid Kleckner    PPCallbacks *Callbacks = PP.getPPCallbacks();
10242ee042dee9f7693665e28463955401905474a284Reid Kleckner
10252ee042dee9f7693665e28463955401905474a284Reid Kleckner    PP.Lex(Tok);
10262ee042dee9f7693665e28463955401905474a284Reid Kleckner    if (Tok.isNot(tok::l_paren)) {
10272ee042dee9f7693665e28463955401905474a284Reid Kleckner      PP.Diag(Tok, diag::warn_pragma_warning_expected) << "(";
10282ee042dee9f7693665e28463955401905474a284Reid Kleckner      return;
10292ee042dee9f7693665e28463955401905474a284Reid Kleckner    }
10302ee042dee9f7693665e28463955401905474a284Reid Kleckner
10312ee042dee9f7693665e28463955401905474a284Reid Kleckner    PP.Lex(Tok);
10322ee042dee9f7693665e28463955401905474a284Reid Kleckner    IdentifierInfo *II = Tok.getIdentifierInfo();
10332ee042dee9f7693665e28463955401905474a284Reid Kleckner    if (!II) {
10342ee042dee9f7693665e28463955401905474a284Reid Kleckner      PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid);
10352ee042dee9f7693665e28463955401905474a284Reid Kleckner      return;
10362ee042dee9f7693665e28463955401905474a284Reid Kleckner    }
10372ee042dee9f7693665e28463955401905474a284Reid Kleckner
10382ee042dee9f7693665e28463955401905474a284Reid Kleckner    if (II->isStr("push")) {
10392ee042dee9f7693665e28463955401905474a284Reid Kleckner      // #pragma warning( push[ ,n ] )
104072c26c0d47eb850db18b784403260bce0632c478Reid Kleckner      int Level = -1;
10412ee042dee9f7693665e28463955401905474a284Reid Kleckner      PP.Lex(Tok);
10422ee042dee9f7693665e28463955401905474a284Reid Kleckner      if (Tok.is(tok::comma)) {
10432ee042dee9f7693665e28463955401905474a284Reid Kleckner        PP.Lex(Tok);
1044651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        uint64_t Value;
1045651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        if (Tok.is(tok::numeric_constant) &&
1046651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            PP.parseSimpleIntegerLiteral(Tok, Value))
1047651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          Level = int(Value);
104872c26c0d47eb850db18b784403260bce0632c478Reid Kleckner        if (Level < 0 || Level > 4) {
10492ee042dee9f7693665e28463955401905474a284Reid Kleckner          PP.Diag(Tok, diag::warn_pragma_warning_push_level);
10502ee042dee9f7693665e28463955401905474a284Reid Kleckner          return;
10512ee042dee9f7693665e28463955401905474a284Reid Kleckner        }
10522ee042dee9f7693665e28463955401905474a284Reid Kleckner      }
10532ee042dee9f7693665e28463955401905474a284Reid Kleckner      if (Callbacks)
10542ee042dee9f7693665e28463955401905474a284Reid Kleckner        Callbacks->PragmaWarningPush(DiagLoc, Level);
10552ee042dee9f7693665e28463955401905474a284Reid Kleckner    } else if (II->isStr("pop")) {
10562ee042dee9f7693665e28463955401905474a284Reid Kleckner      // #pragma warning( pop )
10572ee042dee9f7693665e28463955401905474a284Reid Kleckner      PP.Lex(Tok);
10582ee042dee9f7693665e28463955401905474a284Reid Kleckner      if (Callbacks)
10592ee042dee9f7693665e28463955401905474a284Reid Kleckner        Callbacks->PragmaWarningPop(DiagLoc);
10602ee042dee9f7693665e28463955401905474a284Reid Kleckner    } else {
10612ee042dee9f7693665e28463955401905474a284Reid Kleckner      // #pragma warning( warning-specifier : warning-number-list
10622ee042dee9f7693665e28463955401905474a284Reid Kleckner      //                  [; warning-specifier : warning-number-list...] )
10632ee042dee9f7693665e28463955401905474a284Reid Kleckner      while (true) {
10642ee042dee9f7693665e28463955401905474a284Reid Kleckner        II = Tok.getIdentifierInfo();
10652ee042dee9f7693665e28463955401905474a284Reid Kleckner        if (!II) {
10662ee042dee9f7693665e28463955401905474a284Reid Kleckner          PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid);
10672ee042dee9f7693665e28463955401905474a284Reid Kleckner          return;
10682ee042dee9f7693665e28463955401905474a284Reid Kleckner        }
10692ee042dee9f7693665e28463955401905474a284Reid Kleckner
10702ee042dee9f7693665e28463955401905474a284Reid Kleckner        // Figure out which warning specifier this is.
10712ee042dee9f7693665e28463955401905474a284Reid Kleckner        StringRef Specifier = II->getName();
10722ee042dee9f7693665e28463955401905474a284Reid Kleckner        bool SpecifierValid =
10732ee042dee9f7693665e28463955401905474a284Reid Kleckner            llvm::StringSwitch<bool>(Specifier)
10742ee042dee9f7693665e28463955401905474a284Reid Kleckner                .Cases("1", "2", "3", "4", true)
10752ee042dee9f7693665e28463955401905474a284Reid Kleckner                .Cases("default", "disable", "error", "once", "suppress", true)
10762ee042dee9f7693665e28463955401905474a284Reid Kleckner                .Default(false);
10772ee042dee9f7693665e28463955401905474a284Reid Kleckner        if (!SpecifierValid) {
10782ee042dee9f7693665e28463955401905474a284Reid Kleckner          PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid);
10792ee042dee9f7693665e28463955401905474a284Reid Kleckner          return;
10802ee042dee9f7693665e28463955401905474a284Reid Kleckner        }
10812ee042dee9f7693665e28463955401905474a284Reid Kleckner        PP.Lex(Tok);
10822ee042dee9f7693665e28463955401905474a284Reid Kleckner        if (Tok.isNot(tok::colon)) {
10832ee042dee9f7693665e28463955401905474a284Reid Kleckner          PP.Diag(Tok, diag::warn_pragma_warning_expected) << ":";
10842ee042dee9f7693665e28463955401905474a284Reid Kleckner          return;
10852ee042dee9f7693665e28463955401905474a284Reid Kleckner        }
10862ee042dee9f7693665e28463955401905474a284Reid Kleckner
10872ee042dee9f7693665e28463955401905474a284Reid Kleckner        // Collect the warning ids.
10882ee042dee9f7693665e28463955401905474a284Reid Kleckner        SmallVector<int, 4> Ids;
10892ee042dee9f7693665e28463955401905474a284Reid Kleckner        PP.Lex(Tok);
10902ee042dee9f7693665e28463955401905474a284Reid Kleckner        while (Tok.is(tok::numeric_constant)) {
1091651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          uint64_t Value;
1092651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          if (!PP.parseSimpleIntegerLiteral(Tok, Value) || Value == 0 ||
1093651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines              Value > INT_MAX) {
10942ee042dee9f7693665e28463955401905474a284Reid Kleckner            PP.Diag(Tok, diag::warn_pragma_warning_expected_number);
10952ee042dee9f7693665e28463955401905474a284Reid Kleckner            return;
10962ee042dee9f7693665e28463955401905474a284Reid Kleckner          }
1097651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          Ids.push_back(int(Value));
10982ee042dee9f7693665e28463955401905474a284Reid Kleckner        }
10992ee042dee9f7693665e28463955401905474a284Reid Kleckner        if (Callbacks)
11002ee042dee9f7693665e28463955401905474a284Reid Kleckner          Callbacks->PragmaWarning(DiagLoc, Specifier, Ids);
11012ee042dee9f7693665e28463955401905474a284Reid Kleckner
11022ee042dee9f7693665e28463955401905474a284Reid Kleckner        // Parse the next specifier if there is a semicolon.
11032ee042dee9f7693665e28463955401905474a284Reid Kleckner        if (Tok.isNot(tok::semi))
11042ee042dee9f7693665e28463955401905474a284Reid Kleckner          break;
11052ee042dee9f7693665e28463955401905474a284Reid Kleckner        PP.Lex(Tok);
11062ee042dee9f7693665e28463955401905474a284Reid Kleckner      }
11072ee042dee9f7693665e28463955401905474a284Reid Kleckner    }
11082ee042dee9f7693665e28463955401905474a284Reid Kleckner
11092ee042dee9f7693665e28463955401905474a284Reid Kleckner    if (Tok.isNot(tok::r_paren)) {
11102ee042dee9f7693665e28463955401905474a284Reid Kleckner      PP.Diag(Tok, diag::warn_pragma_warning_expected) << ")";
11112ee042dee9f7693665e28463955401905474a284Reid Kleckner      return;
11122ee042dee9f7693665e28463955401905474a284Reid Kleckner    }
11132ee042dee9f7693665e28463955401905474a284Reid Kleckner
11142ee042dee9f7693665e28463955401905474a284Reid Kleckner    PP.Lex(Tok);
11152ee042dee9f7693665e28463955401905474a284Reid Kleckner    if (Tok.isNot(tok::eod))
11162ee042dee9f7693665e28463955401905474a284Reid Kleckner      PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma warning";
11172ee042dee9f7693665e28463955401905474a284Reid Kleckner  }
11182ee042dee9f7693665e28463955401905474a284Reid Kleckner};
11192ee042dee9f7693665e28463955401905474a284Reid Kleckner
1120b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaIncludeAliasHandler - "\#pragma include_alias("...")".
11214c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballmanstruct PragmaIncludeAliasHandler : public PragmaHandler {
11224c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  PragmaIncludeAliasHandler() : PragmaHandler("include_alias") {}
1123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &IncludeAliasTok) override {
11252ee042dee9f7693665e28463955401905474a284Reid Kleckner    PP.HandlePragmaIncludeAlias(IncludeAliasTok);
11264c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
11274c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman};
11284c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
1129076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// PragmaMessageHandler - Handle the microsoft and gcc \#pragma message
1130076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// extension.  The syntax is:
1131076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// \code
1132076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs///   #pragma message(string)
1133076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// \endcode
1134076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// OR, in GCC mode:
1135076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// \code
1136076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs///   #pragma message string
1137076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// \endcode
1138076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// string is a string, which is fully macro expanded, and permits string
1139076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// concatenation, embedded escape characters, etc... See MSDN for more details.
1140076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// Also handles \#pragma GCC warning and \#pragma GCC error which take the same
1141076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// form as \#pragma message.
1142abfe094ce71c42656dcb84a3bdc3e79cb3c16fc3Chris Lattnerstruct PragmaMessageHandler : public PragmaHandler {
1143076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbsprivate:
1144076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  const PPCallbacks::PragmaMessageKind Kind;
1145076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  const StringRef Namespace;
1146076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1147076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  static const char* PragmaKind(PPCallbacks::PragmaMessageKind Kind,
1148076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                                bool PragmaNameOnly = false) {
1149076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    switch (Kind) {
1150076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      case PPCallbacks::PMK_Message:
1151076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs        return PragmaNameOnly ? "message" : "pragma message";
1152076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      case PPCallbacks::PMK_Warning:
1153076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs        return PragmaNameOnly ? "warning" : "pragma warning";
1154076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      case PPCallbacks::PMK_Error:
1155076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs        return PragmaNameOnly ? "error" : "pragma error";
1156076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    }
1157076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    llvm_unreachable("Unknown PragmaMessageKind!");
1158076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  }
1159076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1160076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbspublic:
1161076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  PragmaMessageHandler(PPCallbacks::PragmaMessageKind Kind,
1162076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                       StringRef Namespace = StringRef())
1163076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    : PragmaHandler(PragmaKind(Kind, true)), Kind(Kind), Namespace(Namespace) {}
1164076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &Tok) override {
1167076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    SourceLocation MessageLoc = Tok.getLocation();
1168076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    PP.Lex(Tok);
1169076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    bool ExpectClosingParen = false;
1170076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    switch (Tok.getKind()) {
1171076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    case tok::l_paren:
1172076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      // We have a MSVC style pragma message.
1173076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      ExpectClosingParen = true;
1174076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      // Read the string.
1175076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      PP.Lex(Tok);
1176076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      break;
1177076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    case tok::string_literal:
1178076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      // We have a GCC style pragma message, and we just read the string.
1179076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      break;
1180076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    default:
1181076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      PP.Diag(MessageLoc, diag::err_pragma_message_malformed) << Kind;
1182076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      return;
1183076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    }
1184076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1185076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    std::string MessageString;
1186076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    if (!PP.FinishLexStringLiteral(Tok, MessageString, PragmaKind(Kind),
1187076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                                   /*MacroExpansion=*/true))
1188076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      return;
1189076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1190076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    if (ExpectClosingParen) {
1191076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      if (Tok.isNot(tok::r_paren)) {
1192076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs        PP.Diag(Tok.getLocation(), diag::err_pragma_message_malformed) << Kind;
1193076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs        return;
1194076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      }
1195076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      PP.Lex(Tok);  // eat the r_paren.
1196076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    }
1197076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1198076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    if (Tok.isNot(tok::eod)) {
1199076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      PP.Diag(Tok.getLocation(), diag::err_pragma_message_malformed) << Kind;
1200076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      return;
1201076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    }
1202076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1203076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    // Output the message.
1204076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    PP.Diag(MessageLoc, (Kind == PPCallbacks::PMK_Error)
1205076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                          ? diag::err_pragma_message
1206076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                          : diag::warn_pragma_message) << MessageString;
1207076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1208076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    // If the pragma is lexically sound, notify any interested PPCallbacks.
1209076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    if (PPCallbacks *Callbacks = PP.getPPCallbacks())
1210076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      Callbacks->PragmaMessage(MessageLoc, Namespace, Kind, MessageString);
1211abfe094ce71c42656dcb84a3bdc3e79cb3c16fc3Chris Lattner  }
1212abfe094ce71c42656dcb84a3bdc3e79cb3c16fc3Chris Lattner};
1213abfe094ce71c42656dcb84a3bdc3e79cb3c16fc3Chris Lattner
1214b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaPushMacroHandler - "\#pragma push_macro" saves the value of the
1215f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner/// macro on the top of the stack.
1216f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattnerstruct PragmaPushMacroHandler : public PragmaHandler {
1217f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  PragmaPushMacroHandler() : PragmaHandler("push_macro") {}
1218651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1219651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &PushMacroTok) override {
1220f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    PP.HandlePragmaPushMacro(PushMacroTok);
1221f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
1222f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner};
1223f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
1224f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
1225b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaPopMacroHandler - "\#pragma pop_macro" sets the value of the
1226f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner/// macro to the value on the top of the stack.
1227f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattnerstruct PragmaPopMacroHandler : public PragmaHandler {
1228f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  PragmaPopMacroHandler() : PragmaHandler("pop_macro") {}
1229651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1230651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &PopMacroTok) override {
1231f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    PP.HandlePragmaPopMacro(PopMacroTok);
1232f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
1233f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner};
1234f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
1235062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner// Pragma STDC implementations.
12366c5cf4a2e234923ab66127de0874a71cb6bfdd83Chris Lattner
1237b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaSTDC_FENV_ACCESSHandler - "\#pragma STDC FENV_ACCESS ...".
1238062f23246510393c19b537b68ec88b6a08ee8996Chris Lattnerstruct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler {
12399b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaSTDC_FENV_ACCESSHandler() : PragmaHandler("FENV_ACCESS") {}
1240651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1241651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &Tok) override {
12429d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    tok::OnOffSwitch OOS;
12439d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    if (PP.LexOnOffSwitch(OOS))
12449d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne     return;
12459d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    if (OOS == tok::OOS_ON)
12464d8aac3778b40c161bed9964125948ee01c08821Chris Lattner      PP.Diag(Tok, diag::warn_stdc_fenv_access_not_supported);
1247062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner  }
1248062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner};
12491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1250b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaSTDC_CX_LIMITED_RANGEHandler - "\#pragma STDC CX_LIMITED_RANGE ...".
1251062f23246510393c19b537b68ec88b6a08ee8996Chris Lattnerstruct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler {
12529b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaSTDC_CX_LIMITED_RANGEHandler()
12539b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis    : PragmaHandler("CX_LIMITED_RANGE") {}
1254651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1255651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &Tok) override {
12569d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    tok::OnOffSwitch OOS;
12579d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    PP.LexOnOffSwitch(OOS);
1258062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner  }
1259062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner};
12601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1261b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaSTDC_UnknownHandler - "\#pragma STDC ...".
1262062f23246510393c19b537b68ec88b6a08ee8996Chris Lattnerstruct PragmaSTDC_UnknownHandler : public PragmaHandler {
12639b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaSTDC_UnknownHandler() {}
1264651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1265651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &UnknownTok) override {
12666c5cf4a2e234923ab66127de0874a71cb6bfdd83Chris Lattner    // C99 6.10.6p2, unknown forms are not allowed.
1267f545be5552b6fd40a4c766fbf82dab0ab5305790Chris Lattner    PP.Diag(UnknownTok, diag::ext_stdc_pragma_ignored);
1268062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner  }
1269062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner};
12701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12718dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall/// PragmaARCCFCodeAuditedHandler -
1272b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett///   \#pragma clang arc_cf_code_audited begin/end
12738dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCallstruct PragmaARCCFCodeAuditedHandler : public PragmaHandler {
12748dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  PragmaARCCFCodeAuditedHandler() : PragmaHandler("arc_cf_code_audited") {}
1275651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1276651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &NameTok) override {
12778dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    SourceLocation Loc = NameTok.getLocation();
12788dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    bool IsBegin;
12798dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
12808dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    Token Tok;
12818dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
12828dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    // Lex the 'begin' or 'end'.
12838dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    PP.LexUnexpandedToken(Tok);
12848dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    const IdentifierInfo *BeginEnd = Tok.getIdentifierInfo();
12858dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    if (BeginEnd && BeginEnd->isStr("begin")) {
12868dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      IsBegin = true;
12878dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    } else if (BeginEnd && BeginEnd->isStr("end")) {
12888dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      IsBegin = false;
12898dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    } else {
12908dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      PP.Diag(Tok.getLocation(), diag::err_pp_arc_cf_code_audited_syntax);
12918dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      return;
12928dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    }
12938dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
12948dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    // Verify that this is followed by EOD.
12958dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    PP.LexUnexpandedToken(Tok);
12968dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    if (Tok.isNot(tok::eod))
12978dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";
12988dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
12998dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    // The start location of the active audit.
13008dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    SourceLocation BeginLoc = PP.getPragmaARCCFCodeAuditedLoc();
13018dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
13028dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    // The start location we want after processing this.
13038dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    SourceLocation NewLoc;
13048dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
13058dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    if (IsBegin) {
13068dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      // Complain about attempts to re-enter an audit.
13078dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      if (BeginLoc.isValid()) {
13088dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall        PP.Diag(Loc, diag::err_pp_double_begin_of_arc_cf_code_audited);
13098dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall        PP.Diag(BeginLoc, diag::note_pragma_entered_here);
13108dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      }
13118dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      NewLoc = Loc;
13128dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    } else {
13138dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      // Complain about attempts to leave an audit that doesn't exist.
13148dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      if (!BeginLoc.isValid()) {
13158dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall        PP.Diag(Loc, diag::err_pp_unmatched_end_of_arc_cf_code_audited);
13168dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall        return;
13178dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      }
13188dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      NewLoc = SourceLocation();
13198dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    }
13208dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
13218dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    PP.setPragmaARCCFCodeAuditedLoc(NewLoc);
13228dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
13238dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall};
13248dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
1325ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer/// \brief Handle "\#pragma region [...]"
1326ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer///
1327ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer/// The syntax is
1328ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer/// \code
1329ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer///   #pragma region [optional name]
1330ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer///   #pragma endregion [optional comment]
1331ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer/// \endcode
1332ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer///
1333ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer/// \note This is
1334ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer/// <a href="http://msdn.microsoft.com/en-us/library/b6xkz944(v=vs.80).aspx">editor-only</a>
1335ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer/// pragma, just skipped by compiler.
1336ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemerstruct PragmaRegionHandler : public PragmaHandler {
1337ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer  PragmaRegionHandler(const char *pragma) : PragmaHandler(pragma) { }
1338ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer
1339651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1340651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    Token &NameTok) override {
1341ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer    // #pragma region: endregion matches can be verified
1342ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer    // __pragma(region): no sense, but ignored by msvc
1343ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer    // _Pragma is not valid for MSVC, but there isn't any point
1344ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer    // to handle a _Pragma differently.
1345ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer  }
1346ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer};
1347fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman
13485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}  // end anonymous namespace
13495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
13505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
13515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// RegisterBuiltinPragmas - Install the standard preprocessor pragmas:
1352b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \#pragma GCC poison/system_header/dependency and \#pragma once.
13535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid Preprocessor::RegisterBuiltinPragmas() {
13549b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler(new PragmaOnceHandler());
13559b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler(new PragmaMarkHandler());
1356f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  AddPragmaHandler(new PragmaPushMacroHandler());
1357f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  AddPragmaHandler(new PragmaPopMacroHandler());
1358076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  AddPragmaHandler(new PragmaMessageHandler(PPCallbacks::PMK_Message));
13591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1360e8fa06e07363b6d5e6c371bbd454d51bab78d01dChris Lattner  // #pragma GCC ...
13619b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("GCC", new PragmaPoisonHandler());
13629b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("GCC", new PragmaSystemHeaderHandler());
13639b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("GCC", new PragmaDependencyHandler());
1364c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor  AddPragmaHandler("GCC", new PragmaDiagnosticHandler("GCC"));
1365076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  AddPragmaHandler("GCC", new PragmaMessageHandler(PPCallbacks::PMK_Warning,
1366076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                                                   "GCC"));
1367076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  AddPragmaHandler("GCC", new PragmaMessageHandler(PPCallbacks::PMK_Error,
1368076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                                                   "GCC"));
1369e8fa06e07363b6d5e6c371bbd454d51bab78d01dChris Lattner  // #pragma clang ...
13709b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("clang", new PragmaPoisonHandler());
13719b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("clang", new PragmaSystemHeaderHandler());
1372abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar  AddPragmaHandler("clang", new PragmaDebugHandler());
13739b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("clang", new PragmaDependencyHandler());
1374c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor  AddPragmaHandler("clang", new PragmaDiagnosticHandler("clang"));
13758dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  AddPragmaHandler("clang", new PragmaARCCFCodeAuditedHandler());
13769b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis
13779b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("STDC", new PragmaSTDC_FENV_ACCESSHandler());
13789b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("STDC", new PragmaSTDC_CX_LIMITED_RANGEHandler());
1379062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner  AddPragmaHandler("STDC", new PragmaSTDC_UnknownHandler());
13801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1381636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner  // MS extensions.
13824e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (LangOpts.MicrosoftExt) {
13832ee042dee9f7693665e28463955401905474a284Reid Kleckner    AddPragmaHandler(new PragmaWarningHandler());
13844c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    AddPragmaHandler(new PragmaIncludeAliasHandler());
1385fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman    AddPragmaHandler(new PragmaRegionHandler("region"));
1386fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman    AddPragmaHandler(new PragmaRegionHandler("endregion"));
1387abfe094ce71c42656dcb84a3bdc3e79cb3c16fc3Chris Lattner  }
13885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
13896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
13906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// Ignore all pragmas, useful for modes such as -Eonly which would otherwise
13916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// warn about those pragmas being unknown.
13926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid Preprocessor::IgnorePragmas() {
13936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  AddPragmaHandler(new EmptyPragmaHandler());
13946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // Also ignore all pragmas in all namespaces created
13956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // in Preprocessor::RegisterBuiltinPragmas().
13966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  AddPragmaHandler("GCC", new EmptyPragmaHandler());
13976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  AddPragmaHandler("clang", new EmptyPragmaHandler());
13986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (PragmaHandler *NS = PragmaHandlers->FindHandler("STDC")) {
13996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // Preprocessor::RegisterBuiltinPragmas() already registers
14006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // PragmaSTDC_UnknownHandler as the empty handler, so remove it first,
14016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // otherwise there will be an assert about a duplicate handler.
14026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    PragmaNamespace *STDCNamespace = NS->getIfNamespace();
14036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    assert(STDCNamespace &&
14046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines           "Invalid namespace, registered as a regular pragma handler!");
14056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    if (PragmaHandler *Existing = STDCNamespace->FindHandler("", false)) {
14066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      RemovePragmaHandler("STDC", Existing);
14076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      delete Existing;
14086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    }
14096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
14106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  AddPragmaHandler("STDC", new EmptyPragmaHandler());
14116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
1412