Pragma.cpp revision ad5f8336f96911805bb625cc4fb1a4487745508a
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"
23ff759a66526d6a985fb4efae69c6b798d83364dfDaniel Dunbar#include "llvm/Support/CrashRecoveryContext.h"
245505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar#include "llvm/Support/ErrorHandling.h"
252e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor#include <algorithm>
265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang;
275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Out-of-line destructor to provide a home for the class.
295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerPragmaHandler::~PragmaHandler() {
305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
33c72cc5072cdc1a1a6e05f9d0f962f293a69248c4Daniel Dunbar// EmptyPragmaHandler Implementation.
34c72cc5072cdc1a1a6e05f9d0f962f293a69248c4Daniel Dunbar//===----------------------------------------------------------------------===//
35c72cc5072cdc1a1a6e05f9d0f962f293a69248c4Daniel Dunbar
369b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios KyrtzidisEmptyPragmaHandler::EmptyPragmaHandler() {}
37c72cc5072cdc1a1a6e05f9d0f962f293a69248c4Daniel Dunbar
3880c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregorvoid EmptyPragmaHandler::HandlePragma(Preprocessor &PP,
3980c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                                      PragmaIntroducerKind Introducer,
4080c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                                      Token &FirstToken) {}
41c72cc5072cdc1a1a6e05f9d0f962f293a69248c4Daniel Dunbar
42c72cc5072cdc1a1a6e05f9d0f962f293a69248c4Daniel Dunbar//===----------------------------------------------------------------------===//
435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// PragmaNamespace Implementation.
445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerPragmaNamespace::~PragmaNamespace() {
479b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  for (llvm::StringMap<PragmaHandler*>::iterator
489b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis         I = Handlers.begin(), E = Handlers.end(); I != E; ++I)
499b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis    delete I->second;
505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// FindHandler - Check to see if there is already a handler for the
535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// specified name.  If not, return the handler for the null identifier if it
545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// exists, otherwise return null.  If IgnoreNull is true (the default) then
555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// the null handler isn't returned on failure to match.
565f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerPragmaHandler *PragmaNamespace::FindHandler(StringRef Name,
575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                            bool IgnoreNull) const {
589b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  if (PragmaHandler *Handler = Handlers.lookup(Name))
599b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis    return Handler;
605f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  return IgnoreNull ? 0 : Handlers.lookup(StringRef());
619b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis}
621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
639b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidisvoid PragmaNamespace::AddPragma(PragmaHandler *Handler) {
649b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  assert(!Handlers.lookup(Handler->getName()) &&
659b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis         "A handler with this name is already registered in this namespace");
669b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  llvm::StringMapEntry<PragmaHandler *> &Entry =
679b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis    Handlers.GetOrCreateValue(Handler->getName());
689b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  Entry.setValue(Handler);
695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
714095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbarvoid PragmaNamespace::RemovePragmaHandler(PragmaHandler *Handler) {
729b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  assert(Handlers.lookup(Handler->getName()) &&
739b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis         "Handler not registered in this namespace");
749b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  Handlers.erase(Handler->getName());
754095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar}
764095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar
7780c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregorvoid PragmaNamespace::HandlePragma(Preprocessor &PP,
7880c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                                   PragmaIntroducerKind Introducer,
7980c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                                   Token &Tok) {
805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Read the 'namespace' that the directive is in, e.g. STDC.  Do not macro
815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // expand it, the user can have a STDC #define, that should not affect this.
825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  PP.LexUnexpandedToken(Tok);
831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Get the handler for this token.  If there is no handler, ignore the pragma.
859b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaHandler *Handler
869b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis    = FindHandler(Tok.getIdentifierInfo() ? Tok.getIdentifierInfo()->getName()
875f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                          : StringRef(),
889b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis                  /*IgnoreNull=*/false);
89af7cdf45da4925f788e87a4c318ee67404646088Chris Lattner  if (Handler == 0) {
90af7cdf45da4925f788e87a4c318ee67404646088Chris Lattner    PP.Diag(Tok, diag::warn_pragma_ignored);
91af7cdf45da4925f788e87a4c318ee67404646088Chris Lattner    return;
92af7cdf45da4925f788e87a4c318ee67404646088Chris Lattner  }
931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Otherwise, pass it down.
9580c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  Handler->HandlePragma(PP, Introducer, Tok);
965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Preprocessor Pragma Directive Handling.
1005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
1015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
102b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// HandlePragmaDirective - The "\#pragma" directive has been parsed.  Lex the
1035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// rest of the pragma, passing it to the registered pragma handlers.
10480c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregorvoid Preprocessor::HandlePragmaDirective(unsigned Introducer) {
1056fe6a49c4058211ff4489023c78615ec0266c5ffJordan Rose  if (!PragmasEnabled)
1066fe6a49c4058211ff4489023c78615ec0266c5ffJordan Rose    return;
1076fe6a49c4058211ff4489023c78615ec0266c5ffJordan Rose
1085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ++NumPragma;
1091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Invoke the first level of pragma handlers which reads the namespace id.
111d217773f106856a11879ec79dc468efefaf2ee75Chris Lattner  Token Tok;
11280c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  PragmaHandlers->HandlePragma(*this, PragmaIntroducerKind(Introducer), Tok);
1131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If the pragma handler didn't read the rest of the line, consume it now.
115b2eb53d9fd973a1a02e05e67a3307b3efd12eff2Peter Collingbourne  if ((CurTokenLexer && CurTokenLexer->isParsingPreprocessorDirective())
116b2eb53d9fd973a1a02e05e67a3307b3efd12eff2Peter Collingbourne   || (CurPPLexer && CurPPLexer->ParsingPreprocessorDirective))
1175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    DiscardUntilEndOfDirective();
1185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
12014e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidisnamespace {
12114e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis/// \brief Helper class for \see Preprocessor::Handle_Pragma.
12214e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidisclass LexingFor_PragmaRAII {
12314e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  Preprocessor &PP;
12414e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  bool InMacroArgPreExpansion;
12514e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  bool Failed;
12614e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  Token &OutTok;
12714e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  Token PragmaTok;
12814e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis
12914e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidispublic:
13014e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  LexingFor_PragmaRAII(Preprocessor &PP, bool InMacroArgPreExpansion,
13114e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis                       Token &Tok)
13214e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    : PP(PP), InMacroArgPreExpansion(InMacroArgPreExpansion),
13314e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis      Failed(false), OutTok(Tok) {
13414e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    if (InMacroArgPreExpansion) {
13514e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis      PragmaTok = OutTok;
13614e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis      PP.EnableBacktrackAtThisPos();
13714e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    }
13814e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  }
13914e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis
14014e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  ~LexingFor_PragmaRAII() {
14114e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    if (InMacroArgPreExpansion) {
14214e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis      if (Failed) {
14314e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis        PP.CommitBacktrackedTokens();
14414e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis      } else {
14514e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis        PP.Backtrack();
14614e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis        OutTok = PragmaTok;
14714e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis      }
14814e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    }
14914e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  }
15014e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis
15114e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  void failed() {
15214e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    Failed = true;
15314e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  }
15414e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis};
15514e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis}
15614e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis
1575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Handle_Pragma - Read a _Pragma directive, slice it up, process it, then
1585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// return the first token after the directive.  The _Pragma token has just
1595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// been read into 'Tok'.
160d217773f106856a11879ec79dc468efefaf2ee75Chris Lattnervoid Preprocessor::Handle_Pragma(Token &Tok) {
16114e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis
16214e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  // This works differently if we are pre-expanding a macro argument.
16314e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  // In that case we don't actually "activate" the pragma now, we only lex it
16414e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  // until we are sure it is lexically correct and then we backtrack so that
16514e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  // we activate the pragma whenever we encounter the tokens again in the token
16614e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  // stream. This ensures that we will activate it in the correct location
16714e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  // or that we will ignore it if it never enters the token stream, e.g:
16814e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  //
16914e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  //     #define EMPTY(x)
17014e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  //     #define INACTIVE(x) EMPTY(x)
17114e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  //     INACTIVE(_Pragma("clang diagnostic ignored \"-Wconversion\""))
17214e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis
17314e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  LexingFor_PragmaRAII _PragmaLexing(*this, InMacroArgPreExpansion, Tok);
17414e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis
1755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Remember the pragma token location.
1765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation PragmaLoc = Tok.getLocation();
1771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Read the '('.
1795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Lex(Tok);
1803692b09faa9fe346f39bc922db6dce48cdcc3f63Chris Lattner  if (Tok.isNot(tok::l_paren)) {
1813692b09faa9fe346f39bc922db6dce48cdcc3f63Chris Lattner    Diag(PragmaLoc, diag::err__Pragma_malformed);
18214e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    return _PragmaLexing.failed();
1833692b09faa9fe346f39bc922db6dce48cdcc3f63Chris Lattner  }
1845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Read the '"..."'.
1865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Lex(Tok);
1870b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith  if (!tok::isStringLiteral(Tok.getKind())) {
1883692b09faa9fe346f39bc922db6dce48cdcc3f63Chris Lattner    Diag(PragmaLoc, diag::err__Pragma_malformed);
18999831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    // Skip this token, and the ')', if present.
19099831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    if (Tok.isNot(tok::r_paren))
19199831e4677a7e2e051af636221694d60ba31fcdbRichard Smith      Lex(Tok);
19299831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    if (Tok.is(tok::r_paren))
19399831e4677a7e2e051af636221694d60ba31fcdbRichard Smith      Lex(Tok);
19414e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    return _PragmaLexing.failed();
19599831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  }
19699831e4677a7e2e051af636221694d60ba31fcdbRichard Smith
19799831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  if (Tok.hasUDSuffix()) {
19899831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    Diag(Tok, diag::err_invalid_string_udl);
19999831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    // Skip this token, and the ')', if present.
20099831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    Lex(Tok);
20199831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    if (Tok.is(tok::r_paren))
20299831e4677a7e2e051af636221694d60ba31fcdbRichard Smith      Lex(Tok);
20314e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    return _PragmaLexing.failed();
2043692b09faa9fe346f39bc922db6dce48cdcc3f63Chris Lattner  }
2051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Remember the string.
20714e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  Token StrTok = Tok;
2085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Read the ')'.
2105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Lex(Tok);
2113692b09faa9fe346f39bc922db6dce48cdcc3f63Chris Lattner  if (Tok.isNot(tok::r_paren)) {
2123692b09faa9fe346f39bc922db6dce48cdcc3f63Chris Lattner    Diag(PragmaLoc, diag::err__Pragma_malformed);
21314e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    return _PragmaLexing.failed();
2143692b09faa9fe346f39bc922db6dce48cdcc3f63Chris Lattner  }
2151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
21614e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  if (InMacroArgPreExpansion)
21714e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis    return;
21814e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis
219e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner  SourceLocation RParenLoc = Tok.getLocation();
22014e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis  std::string StrVal = getSpelling(StrTok);
2211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2220b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith  // The _Pragma is lexically sound.  Destringize according to C11 6.10.9.1:
2230b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith  // "The string literal is destringized by deleting any encoding prefix,
224a9d9145741ef77db45890911674705b81605b10bChris Lattner  // deleting the leading and trailing double-quotes, replacing each escape
225a9d9145741ef77db45890911674705b81605b10bChris Lattner  // sequence \" by a double-quote, and replacing each escape sequence \\ by a
226a9d9145741ef77db45890911674705b81605b10bChris Lattner  // single backslash."
2270b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith  if (StrVal[0] == 'L' || StrVal[0] == 'U' ||
2280b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith      (StrVal[0] == 'u' && StrVal[1] != '8'))
2295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    StrVal.erase(StrVal.begin());
2300b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith  else if (StrVal[0] == 'u')
2310b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    StrVal.erase(StrVal.begin(), StrVal.begin() + 2);
2320b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith
2330b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith  if (StrVal[0] == 'R') {
2340b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    // FIXME: C++11 does not specify how to handle raw-string-literals here.
2350b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    // We strip off the 'R', the quotes, the d-char-sequences, and the parens.
2360b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    assert(StrVal[1] == '"' && StrVal[StrVal.size() - 1] == '"' &&
2370b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith           "Invalid raw string token!");
2380b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith
2390b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    // Measure the length of the d-char-sequence.
2400b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    unsigned NumDChars = 0;
2410b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    while (StrVal[2 + NumDChars] != '(') {
2420b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith      assert(NumDChars < (StrVal.size() - 5) / 2 &&
2430b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith             "Invalid raw string token!");
2440b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith      ++NumDChars;
2450b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    }
2460b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    assert(StrVal[StrVal.size() - 2 - NumDChars] == ')');
2470b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith
2480b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    // Remove 'R " d-char-sequence' and 'd-char-sequence "'. We'll replace the
2490b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    // parens below.
2500b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    StrVal.erase(0, 2 + NumDChars);
2510b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    StrVal.erase(StrVal.size() - 1 - NumDChars);
2520b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith  } else {
2530b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' &&
2540b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith           "Invalid string token!");
2550b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith
2560b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    // Remove escaped quotes and escapes.
257269cc2daf3a36ad878ea1d4cb356aa38311f6e2dBenjamin Kramer    unsigned ResultPos = 1;
258269cc2daf3a36ad878ea1d4cb356aa38311f6e2dBenjamin Kramer    for (unsigned i = 1, e = StrVal.size() - 2; i != e; ++i) {
259269cc2daf3a36ad878ea1d4cb356aa38311f6e2dBenjamin Kramer      if (StrVal[i] != '\\' ||
260269cc2daf3a36ad878ea1d4cb356aa38311f6e2dBenjamin Kramer          (StrVal[i + 1] != '\\' && StrVal[i + 1] != '"')) {
2610b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith        // \\ -> '\' and \" -> '"'.
262269cc2daf3a36ad878ea1d4cb356aa38311f6e2dBenjamin Kramer        StrVal[ResultPos++] = StrVal[i];
2630b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith      }
2640b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    }
265269cc2daf3a36ad878ea1d4cb356aa38311f6e2dBenjamin Kramer    StrVal.erase(StrVal.begin() + ResultPos, StrVal.end() - 2);
2660b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith  }
2671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Remove the front quote, replacing it with a space, so that the pragma
2695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // contents appear to have a space before them.
2705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StrVal[0] = ' ';
2711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2721fa495304c81e03f07f278a47b5efe9317104aabChris Lattner  // Replace the terminating quote with a \n.
2735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StrVal[StrVal.size()-1] = '\n';
2741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
275a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // Plop the string (including the newline and trailing null) into a buffer
276a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // where we can lex it.
277a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  Token TmpTok;
278a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  TmpTok.startToken();
279374b3837d676133fcc1eb70a25c8baf8ec4a5c4aDmitri Gribenko  CreateString(StrVal, TmpTok);
280a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  SourceLocation TokLoc = TmpTok.getLocation();
281a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne
282a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // Make and enter a lexer object so that we lex and expand the tokens just
283a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // like any others.
284a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  Lexer *TL = Lexer::Create_PragmaLexer(TokLoc, PragmaLoc, RParenLoc,
285a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne                                        StrVal.size(), *this);
286a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne
287a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  EnterSourceFileWithLexer(TL, 0);
288a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne
289a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // With everything set up, lex this as a #pragma directive.
290a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  HandlePragmaDirective(PIK__Pragma);
2911ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
2921ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  // Finally, return whatever came after the pragma directive.
2931ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  return Lex(Tok);
2941ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall}
2951ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
2961ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall/// HandleMicrosoft__pragma - Like Handle_Pragma except the pragma text
2971ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall/// is not enclosed within a string literal.
2981ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCallvoid Preprocessor::HandleMicrosoft__pragma(Token &Tok) {
2991ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  // Remember the pragma token location.
3001ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  SourceLocation PragmaLoc = Tok.getLocation();
3011ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
3021ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  // Read the '('.
3031ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  Lex(Tok);
3041ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  if (Tok.isNot(tok::l_paren)) {
3051ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall    Diag(PragmaLoc, diag::err__Pragma_malformed);
3061ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall    return;
3071ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  }
3081ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
309a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // Get the tokens enclosed within the __pragma(), as well as the final ')'.
3105f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<Token, 32> PragmaToks;
3111ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  int NumParens = 0;
3121ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  Lex(Tok);
3131ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  while (Tok.isNot(tok::eof)) {
314a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne    PragmaToks.push_back(Tok);
3151ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall    if (Tok.is(tok::l_paren))
3161ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall      NumParens++;
3171ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall    else if (Tok.is(tok::r_paren) && NumParens-- == 0)
3181ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall      break;
3191ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall    Lex(Tok);
3201ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  }
3211ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
3223da92a9d21f707c164797dd967ba894b2282b343John McCall  if (Tok.is(tok::eof)) {
3233da92a9d21f707c164797dd967ba894b2282b343John McCall    Diag(PragmaLoc, diag::err_unterminated___pragma);
3243da92a9d21f707c164797dd967ba894b2282b343John McCall    return;
3253da92a9d21f707c164797dd967ba894b2282b343John McCall  }
3263da92a9d21f707c164797dd967ba894b2282b343John McCall
327a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  PragmaToks.front().setFlag(Token::LeadingSpace);
3281ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
32984021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  // Replace the ')' with an EOD to mark the end of the pragma.
33084021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  PragmaToks.back().setKind(tok::eod);
3311ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
332a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  Token *TokArray = new Token[PragmaToks.size()];
333a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  std::copy(PragmaToks.begin(), PragmaToks.end(), TokArray);
3341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
335a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // Push the tokens onto the stack.
336a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  EnterTokenStream(TokArray, PragmaToks.size(), true, true);
3375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // With everything set up, lex this as a #pragma directive.
339a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  HandlePragmaDirective(PIK___pragma);
3405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
341a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // Finally, return whatever came after the pragma directive.
342a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  return Lex(Tok);
343a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne}
3445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
345b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// HandlePragmaOnce - Handle \#pragma once.  OnceTok is the 'once'.
3465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
347d217773f106856a11879ec79dc468efefaf2ee75Chris Lattnervoid Preprocessor::HandlePragmaOnce(Token &OnceTok) {
3485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (isInPrimaryFile()) {
3495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Diag(OnceTok, diag::pp_pragma_once_in_main_file);
3505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return;
3515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Get the current file lexer we're looking at.  Ignore _Pragma 'files' etc.
3545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Mark the file as a once-only file now.
3552b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  HeaderInfo.MarkFileIncludeOnce(getCurrentFileLexer()->getFileEntry());
3565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
3575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3582243449253475574fc6f14986ff8f7fce5d46799Chris Lattnervoid Preprocessor::HandlePragmaMark() {
35917ff58a63197b398ae52697b088dc0fb8b255519Ted Kremenek  assert(CurPPLexer && "No current lexer?");
3606896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner  if (CurLexer)
3616896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner    CurLexer->ReadToEndOfLine();
3626896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner  else
3636896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner    CurPTHLexer->DiscardToEndOfLine();
3642243449253475574fc6f14986ff8f7fce5d46799Chris Lattner}
3652243449253475574fc6f14986ff8f7fce5d46799Chris Lattner
3662243449253475574fc6f14986ff8f7fce5d46799Chris Lattner
367b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// HandlePragmaPoison - Handle \#pragma GCC poison.  PoisonTok is the 'poison'.
3685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
369d217773f106856a11879ec79dc468efefaf2ee75Chris Lattnervoid Preprocessor::HandlePragmaPoison(Token &PoisonTok) {
370d217773f106856a11879ec79dc468efefaf2ee75Chris Lattner  Token Tok;
3715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  while (1) {
3735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Read the next token to poison.  While doing this, pretend that we are
3745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // skipping while reading the identifier to poison.
3755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // This avoids errors on code like:
3765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    //   #pragma GCC poison X
3775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    //   #pragma GCC poison X
37868a91d5736c2c03d60a9d1c59d08191b8e0d6c52Ted Kremenek    if (CurPPLexer) CurPPLexer->LexingRawMode = true;
3795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    LexUnexpandedToken(Tok);
38068a91d5736c2c03d60a9d1c59d08191b8e0d6c52Ted Kremenek    if (CurPPLexer) CurPPLexer->LexingRawMode = false;
3811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // If we reached the end of line, we're done.
38384021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne    if (Tok.is(tok::eod)) return;
3841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Can only poison identifiers.
386c4bf2b9afb7d47445a9dc6bc848657098a4e3851Abramo Bagnara    if (Tok.isNot(tok::raw_identifier)) {
3875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Diag(Tok, diag::err_pp_invalid_poison);
3885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      return;
3895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
3901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Look up the identifier info for the token.  We disabled identifier lookup
3925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // by saying we're skipping contents, so we need to do this manually.
3935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    IdentifierInfo *II = LookUpIdentifierInfo(Tok);
3941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Already poisoned.
3965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (II->isPoisoned()) continue;
3971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // If this is a macro identifier, emit a warning.
3990edde55077cc3cb9fffeba19f5936f05a68c8e2bChris Lattner    if (II->hasMacroDefinition())
4005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Diag(Tok, diag::pp_poisoning_existing_macro);
4011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Finally, poison it!
4035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    II->setIsPoisoned();
404eee242ff426bf79149f221798966e58688383c1eDouglas Gregor    if (II->isFromAST())
405eee242ff426bf79149f221798966e58688383c1eDouglas Gregor      II->setChangedSinceDeserialization();
4065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
4085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
409b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// HandlePragmaSystemHeader - Implement \#pragma GCC system_header.  We know
4105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// that the whole directive has been parsed.
411d217773f106856a11879ec79dc468efefaf2ee75Chris Lattnervoid Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) {
4125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (isInPrimaryFile()) {
4135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);
4145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return;
4155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Get the current file lexer we're looking at.  Ignore _Pragma 'files' etc.
41835c10c25ddec4effbd26dead23ea5b04ee32f45aTed Kremenek  PreprocessorLexer *TheLexer = getCurrentFileLexer();
4191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Mark the file as a system header.
4212b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  HeaderInfo.MarkFileSystemHeader(TheLexer->getFileEntry());
4221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4246896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner  PresumedLoc PLoc = SourceMgr.getPresumedLoc(SysHeaderTok.getLocation());
425cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor  if (PLoc.isInvalid())
426cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor    return;
427cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor
42865aa6885818d4b4eea2e5a9d12085b2398148662Jay Foad  unsigned FilenameID = SourceMgr.getLineTableFilenameID(PLoc.getFilename());
4291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
430784c257c8f5c3a737b0ae1dceb5d54d29b6637cfChris Lattner  // Notify the client, if desired, that we are in a new source file.
431784c257c8f5c3a737b0ae1dceb5d54d29b6637cfChris Lattner  if (Callbacks)
432784c257c8f5c3a737b0ae1dceb5d54d29b6637cfChris Lattner    Callbacks->FileChanged(SysHeaderTok.getLocation(),
433784c257c8f5c3a737b0ae1dceb5d54d29b6637cfChris Lattner                           PPCallbacks::SystemHeaderPragma, SrcMgr::C_System);
434784c257c8f5c3a737b0ae1dceb5d54d29b6637cfChris Lattner
4356896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner  // Emit a line marker.  This will change any source locations from this point
4366896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner  // forward to realize they are in a system header.
4376896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner  // Create a line note with this information.
438142b35e25b579e2a883d6ca37c3c1121f562f242Jordan Rose  SourceMgr.AddLineNote(SysHeaderTok.getLocation(), PLoc.getLine()+1,
439142b35e25b579e2a883d6ca37c3c1121f562f242Jordan Rose                        FilenameID, /*IsEntry=*/false, /*IsExit=*/false,
440142b35e25b579e2a883d6ca37c3c1121f562f242Jordan Rose                        /*IsSystem=*/true, /*IsExternC=*/false);
4415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
4425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
443b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// HandlePragmaDependency - Handle \#pragma GCC dependency "foo" blah.
4445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
445d217773f106856a11879ec79dc468efefaf2ee75Chris Lattnervoid Preprocessor::HandlePragmaDependency(Token &DependencyTok) {
446d217773f106856a11879ec79dc468efefaf2ee75Chris Lattner  Token FilenameTok;
44768a91d5736c2c03d60a9d1c59d08191b8e0d6c52Ted Kremenek  CurPPLexer->LexIncludeFilename(FilenameTok);
4485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
44984021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  // If the token kind is EOD, the error has already been diagnosed.
45084021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  if (FilenameTok.is(tok::eod))
4515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return;
4521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Reserve a buffer to get the spelling.
454f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<128> FilenameBuffer;
455453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor  bool Invalid = false;
4565f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Filename = getSpelling(FilenameTok, FilenameBuffer, &Invalid);
457453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor  if (Invalid)
458453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor    return;
4591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
460a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner  bool isAngled =
461a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner    GetIncludeFilenameSpelling(FilenameTok.getLocation(), Filename);
4625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If GetIncludeFilenameSpelling set the start ptr to null, there was an
4635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // error.
464a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner  if (Filename.empty())
4655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return;
4661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Search include directories for this file.
4685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const DirectoryLookup *CurDir;
469bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl  const FileEntry *File = LookupFile(FilenameTok.getLocation(), Filename,
470bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl                                     isAngled, 0, CurDir, NULL, NULL, NULL);
47156b05c8829efd13b7e5b333f8f587c71d025c67dChris Lattner  if (File == 0) {
472f84139a1331c63c998e8b7d54148c75ac0b48ccdEli Friedman    if (!SuppressIncludeNotFoundError)
473f84139a1331c63c998e8b7d54148c75ac0b48ccdEli Friedman      Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
47456b05c8829efd13b7e5b333f8f587c71d025c67dChris Lattner    return;
47556b05c8829efd13b7e5b333f8f587c71d025c67dChris Lattner  }
4761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4772b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  const FileEntry *CurFile = getCurrentFileLexer()->getFileEntry();
4785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If this file is older than the file it depends on, emit a diagnostic.
4805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (CurFile && CurFile->getModificationTime() < File->getModificationTime()) {
4815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Lex tokens at the end of the message and include them in the message.
4825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    std::string Message;
4835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Lex(DependencyTok);
48484021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne    while (DependencyTok.isNot(tok::eod)) {
4855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Message += getSpelling(DependencyTok) + " ";
4865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Lex(DependencyTok);
4875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
4881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
48996de25986d28171945db96a6c6a54f91fd12ae4bChris Lattner    // Remove the trailing ' ' if present.
49096de25986d28171945db96a6c6a54f91fd12ae4bChris Lattner    if (!Message.empty())
49196de25986d28171945db96a6c6a54f91fd12ae4bChris Lattner      Message.erase(Message.end()-1);
49256b05c8829efd13b7e5b333f8f587c71d025c67dChris Lattner    Diag(FilenameTok, diag::pp_out_of_date_dependency) << Message;
4935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
4955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4967adf79a620cb7fbde0608e21727425930676b7dbReid Kleckner/// ParsePragmaPushOrPopMacro - Handle parsing of pragma push_macro/pop_macro.
497f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner/// Return the IdentifierInfo* associated with the macro to push or pop.
498f47724bf78299c7a50f008e0443c5f9f9f279ddcChris LattnerIdentifierInfo *Preprocessor::ParsePragmaPushOrPopMacro(Token &Tok) {
499f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Remember the pragma token location.
500f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  Token PragmaTok = Tok;
501f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
502f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Read the '('.
503f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  Lex(Tok);
504f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (Tok.isNot(tok::l_paren)) {
505f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
506f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner      << getSpelling(PragmaTok);
507f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    return 0;
508f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
509f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
510f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Read the macro name string.
511f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  Lex(Tok);
512f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (Tok.isNot(tok::string_literal)) {
513f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
514f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner      << getSpelling(PragmaTok);
515f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    return 0;
516f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
517f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
51899831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  if (Tok.hasUDSuffix()) {
51999831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    Diag(Tok, diag::err_invalid_string_udl);
52099831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    return 0;
52199831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  }
52299831e4677a7e2e051af636221694d60ba31fcdbRichard Smith
523f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Remember the macro string.
524f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  std::string StrVal = getSpelling(Tok);
525f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
526f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Read the ')'.
527f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  Lex(Tok);
528f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (Tok.isNot(tok::r_paren)) {
529f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
530f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner      << getSpelling(PragmaTok);
531f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    return 0;
532f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
533f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
534f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' &&
535f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner         "Invalid string token!");
536f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
537f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Create a Token from the string.
538f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  Token MacroTok;
539f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  MacroTok.startToken();
540c4bf2b9afb7d47445a9dc6bc848657098a4e3851Abramo Bagnara  MacroTok.setKind(tok::raw_identifier);
541374b3837d676133fcc1eb70a25c8baf8ec4a5c4aDmitri Gribenko  CreateString(StringRef(&StrVal[1], StrVal.size() - 2), MacroTok);
542f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
543f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Get the IdentifierInfo of MacroToPushTok.
544f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  return LookUpIdentifierInfo(MacroTok);
545f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner}
546f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
547b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \brief Handle \#pragma push_macro.
548b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett///
549f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner/// The syntax is:
550b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \code
551e74dc199e95cc523c8806e0de41d8814e8bc5c42Dmitri Gribenko///   #pragma push_macro("macro")
552b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \endcode
553f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattnervoid Preprocessor::HandlePragmaPushMacro(Token &PushMacroTok) {
554f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Parse the pragma directive and get the macro IdentifierInfo*.
555f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PushMacroTok);
556f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (!IdentInfo) return;
557f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
558f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Get the MacroInfo associated with IdentInfo.
559f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  MacroInfo *MI = getMacroInfo(IdentInfo);
560f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
561f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (MI) {
562f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    // Allow the original MacroInfo to be redefined later.
563f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    MI->setIsAllowRedefinitionsWithoutWarning(true);
564f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
565f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
566f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Push the cloned MacroInfo so we can retrieve it later.
5679818a1d443e97677dd3422305de9cc2b1fb2a8c1Argyrios Kyrtzidis  PragmaPushMacroInfo[IdentInfo].push_back(MI);
568f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner}
569f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
570b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \brief Handle \#pragma pop_macro.
571b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett///
572f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner/// The syntax is:
573b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \code
574f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner///   #pragma pop_macro("macro")
575b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \endcode
576f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattnervoid Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) {
577f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  SourceLocation MessageLoc = PopMacroTok.getLocation();
578f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
579f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Parse the pragma directive and get the macro IdentifierInfo*.
580f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PopMacroTok);
581f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (!IdentInfo) return;
582f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
583f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Find the vector<MacroInfo*> associated with the macro.
584f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> >::iterator iter =
585f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    PragmaPushMacroInfo.find(IdentInfo);
586f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (iter != PragmaPushMacroInfo.end()) {
5878a64bb58c3b24d7d97895e435bbc0965c99bd3beAlexander Kornienko    // Forget the MacroInfo currently associated with IdentInfo.
5889818a1d443e97677dd3422305de9cc2b1fb2a8c1Argyrios Kyrtzidis    if (MacroDirective *CurrentMD = getMacroDirective(IdentInfo)) {
589c56fff7fd231aebf4b152f60f8f11ef91835c48aArgyrios Kyrtzidis      MacroInfo *MI = CurrentMD->getMacroInfo();
590c56fff7fd231aebf4b152f60f8f11ef91835c48aArgyrios Kyrtzidis      if (MI->isWarnIfUnused())
591c56fff7fd231aebf4b152f60f8f11ef91835c48aArgyrios Kyrtzidis        WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
592c56fff7fd231aebf4b152f60f8f11ef91835c48aArgyrios Kyrtzidis      appendMacroDirective(IdentInfo, AllocateUndefMacroDirective(MessageLoc));
5930827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis    }
594f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
595f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    // Get the MacroInfo we want to reinstall.
596f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    MacroInfo *MacroToReInstall = iter->second.back();
597f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
598e40c4238a572bf8241a04e0005f70550cbfc1cfbAlexander Kornienko    if (MacroToReInstall) {
599e40c4238a572bf8241a04e0005f70550cbfc1cfbAlexander Kornienko      // Reinstall the previously pushed macro.
600c56fff7fd231aebf4b152f60f8f11ef91835c48aArgyrios Kyrtzidis      appendDefMacroDirective(IdentInfo, MacroToReInstall, MessageLoc,
601c56fff7fd231aebf4b152f60f8f11ef91835c48aArgyrios Kyrtzidis                              /*isImported=*/false);
602e40c4238a572bf8241a04e0005f70550cbfc1cfbAlexander Kornienko    }
603f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
604f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    // Pop PragmaPushMacroInfo stack.
605f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    iter->second.pop_back();
606f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    if (iter->second.size() == 0)
607f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner      PragmaPushMacroInfo.erase(iter);
608f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  } else {
609f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    Diag(MessageLoc, diag::warn_pragma_pop_macro_no_push)
610f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner      << IdentInfo->getName();
611f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
612f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner}
6135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6144c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballmanvoid Preprocessor::HandlePragmaIncludeAlias(Token &Tok) {
6154c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // We will either get a quoted filename or a bracketed filename, and we
6164c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // have to track which we got.  The first filename is the source name,
6174c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // and the second name is the mapped filename.  If the first is quoted,
6184c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // the second must be as well (cannot mix and match quotes and brackets).
6194c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6204c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // Get the open paren
6214c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  Lex(Tok);
6224c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (Tok.isNot(tok::l_paren)) {
6234c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    Diag(Tok, diag::warn_pragma_include_alias_expected) << "(";
6244c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
6254c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
6264c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6274c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // We expect either a quoted string literal, or a bracketed name
6284c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  Token SourceFilenameTok;
6294c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  CurPPLexer->LexIncludeFilename(SourceFilenameTok);
6304c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (SourceFilenameTok.is(tok::eod)) {
6314c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    // The diagnostic has already been handled
6324c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
6334c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
6344c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6354c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  StringRef SourceFileName;
6364c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  SmallString<128> FileNameBuffer;
6374c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (SourceFilenameTok.is(tok::string_literal) ||
6384c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      SourceFilenameTok.is(tok::angle_string_literal)) {
6394c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    SourceFileName = getSpelling(SourceFilenameTok, FileNameBuffer);
6404c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  } else if (SourceFilenameTok.is(tok::less)) {
6414c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    // This could be a path instead of just a name
6424c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    FileNameBuffer.push_back('<');
6434c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    SourceLocation End;
6444c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    if (ConcatenateIncludeName(FileNameBuffer, End))
6454c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      return; // Diagnostic already emitted
6464c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    SourceFileName = FileNameBuffer.str();
6474c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  } else {
6484c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
6494c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
6504c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
6514c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  FileNameBuffer.clear();
6524c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6534c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // Now we expect a comma, followed by another include name
6544c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  Lex(Tok);
6554c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (Tok.isNot(tok::comma)) {
6564c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    Diag(Tok, diag::warn_pragma_include_alias_expected) << ",";
6574c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
6584c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
6594c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6604c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  Token ReplaceFilenameTok;
6614c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  CurPPLexer->LexIncludeFilename(ReplaceFilenameTok);
6624c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (ReplaceFilenameTok.is(tok::eod)) {
6634c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    // The diagnostic has already been handled
6644c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
6654c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
6664c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6674c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  StringRef ReplaceFileName;
6684c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (ReplaceFilenameTok.is(tok::string_literal) ||
6694c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      ReplaceFilenameTok.is(tok::angle_string_literal)) {
6704c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    ReplaceFileName = getSpelling(ReplaceFilenameTok, FileNameBuffer);
6714c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  } else if (ReplaceFilenameTok.is(tok::less)) {
6724c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    // This could be a path instead of just a name
6734c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    FileNameBuffer.push_back('<');
6744c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    SourceLocation End;
6754c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    if (ConcatenateIncludeName(FileNameBuffer, End))
6764c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      return; // Diagnostic already emitted
6774c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    ReplaceFileName = FileNameBuffer.str();
6784c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  } else {
6794c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
6804c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
6814c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
6824c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6834c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // Finally, we expect the closing paren
6844c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  Lex(Tok);
6854c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (Tok.isNot(tok::r_paren)) {
6864c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    Diag(Tok, diag::warn_pragma_include_alias_expected) << ")";
6874c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
6884c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
6894c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6904c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // Now that we have the source and target filenames, we need to make sure
6914c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // they're both of the same type (angled vs non-angled)
6924c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  StringRef OriginalSource = SourceFileName;
6934c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6944c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  bool SourceIsAngled =
6954c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    GetIncludeFilenameSpelling(SourceFilenameTok.getLocation(),
6964c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman                                SourceFileName);
6974c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  bool ReplaceIsAngled =
6984c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    GetIncludeFilenameSpelling(ReplaceFilenameTok.getLocation(),
6994c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman                                ReplaceFileName);
7004c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (!SourceFileName.empty() && !ReplaceFileName.empty() &&
7014c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      (SourceIsAngled != ReplaceIsAngled)) {
7024c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    unsigned int DiagID;
7034c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    if (SourceIsAngled)
7044c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      DiagID = diag::warn_pragma_include_alias_mismatch_angle;
7054c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    else
7064c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      DiagID = diag::warn_pragma_include_alias_mismatch_quote;
7074c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
7084c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    Diag(SourceFilenameTok.getLocation(), DiagID)
7094c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      << SourceFileName
7104c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      << ReplaceFileName;
7114c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
7124c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
7134c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
7144c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
7154c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // Now we can let the include handler know about this mapping
7164c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  getHeaderSearchInfo().AddIncludeAlias(OriginalSource, ReplaceFileName);
7174c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman}
7184c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
7195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// AddPragmaHandler - Add the specified pragma handler to the preprocessor.
7205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// If 'Namespace' is non-null, then it is a token required to exist on the
7215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
7225f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Preprocessor::AddPragmaHandler(StringRef Namespace,
7235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                    PragmaHandler *Handler) {
7245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  PragmaNamespace *InsertNS = PragmaHandlers;
7251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If this is specified to be in a namespace, step down into it.
7279b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  if (!Namespace.empty()) {
7285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // If there is already a pragma handler with the name of this namespace,
7295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // we either have an error (directive with the same name as a namespace) or
7305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // we already have the namespace to insert into.
7319b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis    if (PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace)) {
7325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      InsertNS = Existing->getIfNamespace();
7335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      assert(InsertNS != 0 && "Cannot have a pragma namespace and pragma"
7345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer             " handler with the same name!");
7355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    } else {
7365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      // Otherwise, this namespace doesn't exist yet, create and insert the
7375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      // handler for it.
7389b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis      InsertNS = new PragmaNamespace(Namespace);
7395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      PragmaHandlers->AddPragma(InsertNS);
7405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
7415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
7421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Check to make sure we don't already have a pragma for this identifier.
7445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  assert(!InsertNS->FindHandler(Handler->getName()) &&
7455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         "Pragma handler already exists for this identifier!");
7465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  InsertNS->AddPragma(Handler);
7475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
7485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7494095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar/// RemovePragmaHandler - Remove the specific pragma handler from the
7504095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar/// preprocessor. If \arg Namespace is non-null, then it should be the
7514095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar/// namespace that \arg Handler was added to. It is an error to remove
7524095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar/// a handler that has not been registered.
7535f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Preprocessor::RemovePragmaHandler(StringRef Namespace,
7544095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar                                       PragmaHandler *Handler) {
7554095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar  PragmaNamespace *NS = PragmaHandlers;
7561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7574095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar  // If this is specified to be in a namespace, step down into it.
7589b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  if (!Namespace.empty()) {
7599b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis    PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace);
7604095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar    assert(Existing && "Namespace containing handler does not exist!");
7614095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar
7624095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar    NS = Existing->getIfNamespace();
7634095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar    assert(NS && "Invalid namespace, registered as a regular pragma handler!");
7644095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar  }
7654095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar
7664095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar  NS->RemovePragmaHandler(Handler);
7671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7684095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar  // If this is a non-default namespace and it is now empty, remove
7694095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar  // it.
770ce52bb3dec520ef94574280ac3ef8ad63f4f1ce2Argyrios Kyrtzidis  if (NS != PragmaHandlers && NS->IsEmpty()) {
7714095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar    PragmaHandlers->RemovePragmaHandler(NS);
772ce52bb3dec520ef94574280ac3ef8ad63f4f1ce2Argyrios Kyrtzidis    delete NS;
773ce52bb3dec520ef94574280ac3ef8ad63f4f1ce2Argyrios Kyrtzidis  }
7744095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar}
7754095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar
7769d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbournebool Preprocessor::LexOnOffSwitch(tok::OnOffSwitch &Result) {
7779d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  Token Tok;
7789d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  LexUnexpandedToken(Tok);
7799d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne
7809d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  if (Tok.isNot(tok::identifier)) {
7819d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    Diag(Tok, diag::ext_on_off_switch_syntax);
7829d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    return true;
7839d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  }
7849d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  IdentifierInfo *II = Tok.getIdentifierInfo();
7859d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  if (II->isStr("ON"))
7869d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    Result = tok::OOS_ON;
7879d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  else if (II->isStr("OFF"))
7889d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    Result = tok::OOS_OFF;
7899d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  else if (II->isStr("DEFAULT"))
7909d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    Result = tok::OOS_DEFAULT;
7919d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  else {
7929d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    Diag(Tok, diag::ext_on_off_switch_syntax);
7939d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    return true;
7949d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  }
7959d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne
79684021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  // Verify that this is followed by EOD.
7979d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  LexUnexpandedToken(Tok);
79884021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  if (Tok.isNot(tok::eod))
79984021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne    Diag(Tok, diag::ext_pragma_syntax_eod);
8009d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  return false;
8019d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne}
8029d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne
8035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace {
804b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaOnceHandler - "\#pragma once" marks the file as atomically included.
8055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstruct PragmaOnceHandler : public PragmaHandler {
8069b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaOnceHandler() : PragmaHandler("once") {}
80780c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
80880c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                            Token &OnceTok) {
80935410d5cbbb18735d76e00496540d416dc49b577Chris Lattner    PP.CheckEndOfDirective("pragma once");
8105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    PP.HandlePragmaOnce(OnceTok);
8115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
8125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
8135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
814b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaMarkHandler - "\#pragma mark ..." is ignored by the compiler, and the
8152243449253475574fc6f14986ff8f7fce5d46799Chris Lattner/// rest of the line is not lexed.
8162243449253475574fc6f14986ff8f7fce5d46799Chris Lattnerstruct PragmaMarkHandler : public PragmaHandler {
8179b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaMarkHandler() : PragmaHandler("mark") {}
81880c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
81980c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                            Token &MarkTok) {
8202243449253475574fc6f14986ff8f7fce5d46799Chris Lattner    PP.HandlePragmaMark();
8212243449253475574fc6f14986ff8f7fce5d46799Chris Lattner  }
8222243449253475574fc6f14986ff8f7fce5d46799Chris Lattner};
8232243449253475574fc6f14986ff8f7fce5d46799Chris Lattner
824b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaPoisonHandler - "\#pragma poison x" marks x as not usable.
8255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstruct PragmaPoisonHandler : public PragmaHandler {
8269b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaPoisonHandler() : PragmaHandler("poison") {}
82780c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
82880c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                            Token &PoisonTok) {
8295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    PP.HandlePragmaPoison(PoisonTok);
8305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
8315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
8325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
833b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaSystemHeaderHandler - "\#pragma system_header" marks the current file
8342243449253475574fc6f14986ff8f7fce5d46799Chris Lattner/// as a system header, which silences warnings in it.
8355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstruct PragmaSystemHeaderHandler : public PragmaHandler {
8369b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaSystemHeaderHandler() : PragmaHandler("system_header") {}
83780c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
83880c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                            Token &SHToken) {
8395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    PP.HandlePragmaSystemHeader(SHToken);
84035410d5cbbb18735d76e00496540d416dc49b577Chris Lattner    PP.CheckEndOfDirective("pragma");
8415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
8425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
8435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstruct PragmaDependencyHandler : public PragmaHandler {
8449b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaDependencyHandler() : PragmaHandler("dependency") {}
84580c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
84680c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                            Token &DepToken) {
8475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    PP.HandlePragmaDependency(DepToken);
8485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
8495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
8501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
851abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbarstruct PragmaDebugHandler : public PragmaHandler {
852abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar  PragmaDebugHandler() : PragmaHandler("__debug") {}
85380c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
85480c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                            Token &DepToken) {
855abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    Token Tok;
856abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    PP.LexUnexpandedToken(Tok);
857abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    if (Tok.isNot(tok::identifier)) {
8586493a4d7129673f7878da2382dedf4f9abc57e4cDouglas Gregor      PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
859abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar      return;
860abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    }
861abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    IdentifierInfo *II = Tok.getIdentifierInfo();
862abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar
8635505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar    if (II->isStr("assert")) {
864b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie      llvm_unreachable("This is an assertion!");
865abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    } else if (II->isStr("crash")) {
866377da4c6b78c0130fb6141313636c8fda7b60b72David Blaikie      LLVM_BUILTIN_TRAP;
867e75d9cfbf41a0ee9e456a665776f91fdd9773b36David Blaikie    } else if (II->isStr("parser_crash")) {
868e75d9cfbf41a0ee9e456a665776f91fdd9773b36David Blaikie      Token Crasher;
869e75d9cfbf41a0ee9e456a665776f91fdd9773b36David Blaikie      Crasher.setKind(tok::annot_pragma_parser_crash);
870e75d9cfbf41a0ee9e456a665776f91fdd9773b36David Blaikie      PP.EnterToken(Crasher);
8715505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar    } else if (II->isStr("llvm_fatal_error")) {
8725505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar      llvm::report_fatal_error("#pragma clang __debug llvm_fatal_error");
8735505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar    } else if (II->isStr("llvm_unreachable")) {
8745505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar      llvm_unreachable("#pragma clang __debug llvm_unreachable");
8755505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar    } else if (II->isStr("overflow_stack")) {
8765505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar      DebugOverflowStack();
877ff759a66526d6a985fb4efae69c6b798d83364dfDaniel Dunbar    } else if (II->isStr("handle_crash")) {
878ff759a66526d6a985fb4efae69c6b798d83364dfDaniel Dunbar      llvm::CrashRecoveryContext *CRC =llvm::CrashRecoveryContext::GetCurrent();
879ff759a66526d6a985fb4efae69c6b798d83364dfDaniel Dunbar      if (CRC)
880ff759a66526d6a985fb4efae69c6b798d83364dfDaniel Dunbar        CRC->HandleCrash();
88185192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    } else if (II->isStr("captured")) {
88285192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj      HandleCaptured(PP);
8835505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar    } else {
8845505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar      PP.Diag(Tok, diag::warn_pragma_debug_unexpected_command)
8855505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar        << II->getName();
886abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    }
88785192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj
88885192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    PPCallbacks *Callbacks = PP.getPPCallbacks();
88985192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    if (Callbacks)
89085192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj      Callbacks->PragmaDebug(Tok.getLocation(), II->getName());
89185192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj  }
89285192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj
89385192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj  void HandleCaptured(Preprocessor &PP) {
89485192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    // Skip if emitting preprocessed output.
89585192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    if (PP.isPreprocessedOutput())
89685192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj      return;
89785192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj
89885192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    Token Tok;
89985192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    PP.LexUnexpandedToken(Tok);
90085192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj
90185192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    if (Tok.isNot(tok::eod)) {
90285192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj      PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol)
90385192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj        << "pragma clang __debug captured";
90485192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj      return;
90585192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    }
90685192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj
90785192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    SourceLocation NameLoc = Tok.getLocation();
90885192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    Token *Toks = PP.getPreprocessorAllocator().Allocate<Token>(1);
90985192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    Toks->startToken();
91085192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    Toks->setKind(tok::annot_pragma_captured);
91185192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    Toks->setLocation(NameLoc);
91285192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj
91385192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
91485192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj                        /*OwnsTokens=*/false);
915abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar  }
916abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar
9171066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet// Disable MSVC warning about runtime stack overflow.
9181066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet#ifdef _MSC_VER
9191066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet    #pragma warning(disable : 4717)
9201066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet#endif
921abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar  void DebugOverflowStack() {
922abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    DebugOverflowStack();
923abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar  }
9241066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet#ifdef _MSC_VER
9251066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet    #pragma warning(default : 4717)
9261066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet#endif
9271066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet
928abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar};
929abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar
930b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaDiagnosticHandler - e.g. '\#pragma GCC diagnostic ignored "-Wformat"'
931edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattnerstruct PragmaDiagnosticHandler : public PragmaHandler {
932c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregorprivate:
933c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor  const char *Namespace;
93404ae2df026b275aae5dddfc0db5ca55ff4e62179Chris Lattnerpublic:
935c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor  explicit PragmaDiagnosticHandler(const char *NS) :
936c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor    PragmaHandler("diagnostic"), Namespace(NS) {}
93780c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
93880c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                            Token &DiagToken) {
9390827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis    SourceLocation DiagLoc = DiagToken.getLocation();
940edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    Token Tok;
941edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    PP.LexUnexpandedToken(Tok);
942edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    if (Tok.isNot(tok::identifier)) {
9436493a4d7129673f7878da2382dedf4f9abc57e4cDouglas Gregor      PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
944edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      return;
945edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    }
946edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    IdentifierInfo *II = Tok.getIdentifierInfo();
947c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor    PPCallbacks *Callbacks = PP.getPPCallbacks();
9481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
949edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    diag::Mapping Map;
950edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    if (II->isStr("warning"))
951edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      Map = diag::MAP_WARNING;
952edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    else if (II->isStr("error"))
953edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      Map = diag::MAP_ERROR;
954edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    else if (II->isStr("ignored"))
955edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      Map = diag::MAP_IGNORE;
956edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    else if (II->isStr("fatal"))
957edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      Map = diag::MAP_FATAL;
9586493a4d7129673f7878da2382dedf4f9abc57e4cDouglas Gregor    else if (II->isStr("pop")) {
9590827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis      if (!PP.getDiagnostics().popMappings(DiagLoc))
9606493a4d7129673f7878da2382dedf4f9abc57e4cDouglas Gregor        PP.Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
961c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor      else if (Callbacks)
962c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor        Callbacks->PragmaDiagnosticPop(DiagLoc, Namespace);
9636493a4d7129673f7878da2382dedf4f9abc57e4cDouglas Gregor      return;
9646493a4d7129673f7878da2382dedf4f9abc57e4cDouglas Gregor    } else if (II->isStr("push")) {
9650827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis      PP.getDiagnostics().pushMappings(DiagLoc);
966c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor      if (Callbacks)
967c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor        Callbacks->PragmaDiagnosticPush(DiagLoc, Namespace);
96804ae2df026b275aae5dddfc0db5ca55ff4e62179Chris Lattner      return;
96904ae2df026b275aae5dddfc0db5ca55ff4e62179Chris Lattner    } else {
9706493a4d7129673f7878da2382dedf4f9abc57e4cDouglas Gregor      PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
971edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      return;
972edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    }
9731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
974edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    PP.LexUnexpandedToken(Tok);
97502a176871d91bba3004e4f94b2d4d588ae4b2122Andy Gibbs    SourceLocation StringLoc = Tok.getLocation();
976edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner
97702a176871d91bba3004e4f94b2d4d588ae4b2122Andy Gibbs    std::string WarningName;
97897f8461a2c553f68a258612d2322e4281c3f0915Andy Gibbs    if (!PP.FinishLexStringLiteral(Tok, WarningName, "pragma diagnostic",
97997f8461a2c553f68a258612d2322e4281c3f0915Andy Gibbs                                   /*MacroExpansion=*/false))
980edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      return;
9811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
98284021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne    if (Tok.isNot(tok::eod)) {
983edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      PP.Diag(Tok.getLocation(), diag::warn_pragma_diagnostic_invalid_token);
984edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      return;
985edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    }
9861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
987edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    if (WarningName.size() < 3 || WarningName[0] != '-' ||
988edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner        WarningName[1] != 'W') {
98902a176871d91bba3004e4f94b2d4d588ae4b2122Andy Gibbs      PP.Diag(StringLoc, diag::warn_pragma_diagnostic_invalid_option);
990edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      return;
991edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    }
9921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
993477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidis    if (PP.getDiagnostics().setDiagnosticGroupMapping(WarningName.substr(2),
9940827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis                                                      Map, DiagLoc))
99502a176871d91bba3004e4f94b2d4d588ae4b2122Andy Gibbs      PP.Diag(StringLoc, diag::warn_pragma_diagnostic_unknown_warning)
99602a176871d91bba3004e4f94b2d4d588ae4b2122Andy Gibbs        << WarningName;
997c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor    else if (Callbacks)
998c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor      Callbacks->PragmaDiagnostic(DiagLoc, Namespace, Map, WarningName);
999edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner  }
1000edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner};
10011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1002b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaIncludeAliasHandler - "\#pragma include_alias("...")".
10034c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballmanstruct PragmaIncludeAliasHandler : public PragmaHandler {
10044c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  PragmaIncludeAliasHandler() : PragmaHandler("include_alias") {}
10054c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
10064c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman                            Token &IncludeAliasTok) {
10074c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      PP.HandlePragmaIncludeAlias(IncludeAliasTok);
10084c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
10094c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman};
10104c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
1011076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// PragmaMessageHandler - Handle the microsoft and gcc \#pragma message
1012076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// extension.  The syntax is:
1013076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// \code
1014076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs///   #pragma message(string)
1015076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// \endcode
1016076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// OR, in GCC mode:
1017076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// \code
1018076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs///   #pragma message string
1019076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// \endcode
1020076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// string is a string, which is fully macro expanded, and permits string
1021076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// concatenation, embedded escape characters, etc... See MSDN for more details.
1022076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// Also handles \#pragma GCC warning and \#pragma GCC error which take the same
1023076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// form as \#pragma message.
1024abfe094ce71c42656dcb84a3bdc3e79cb3c16fc3Chris Lattnerstruct PragmaMessageHandler : public PragmaHandler {
1025076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbsprivate:
1026076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  const PPCallbacks::PragmaMessageKind Kind;
1027076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  const StringRef Namespace;
1028076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1029076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  static const char* PragmaKind(PPCallbacks::PragmaMessageKind Kind,
1030076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                                bool PragmaNameOnly = false) {
1031076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    switch (Kind) {
1032076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      case PPCallbacks::PMK_Message:
1033076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs        return PragmaNameOnly ? "message" : "pragma message";
1034076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      case PPCallbacks::PMK_Warning:
1035076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs        return PragmaNameOnly ? "warning" : "pragma warning";
1036076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      case PPCallbacks::PMK_Error:
1037076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs        return PragmaNameOnly ? "error" : "pragma error";
1038076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    }
1039076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    llvm_unreachable("Unknown PragmaMessageKind!");
1040076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  }
1041076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1042076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbspublic:
1043076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  PragmaMessageHandler(PPCallbacks::PragmaMessageKind Kind,
1044076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                       StringRef Namespace = StringRef())
1045076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    : PragmaHandler(PragmaKind(Kind, true)), Kind(Kind), Namespace(Namespace) {}
1046076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
104780c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1048076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                            Token &Tok) {
1049076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    SourceLocation MessageLoc = Tok.getLocation();
1050076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    PP.Lex(Tok);
1051076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    bool ExpectClosingParen = false;
1052076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    switch (Tok.getKind()) {
1053076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    case tok::l_paren:
1054076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      // We have a MSVC style pragma message.
1055076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      ExpectClosingParen = true;
1056076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      // Read the string.
1057076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      PP.Lex(Tok);
1058076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      break;
1059076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    case tok::string_literal:
1060076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      // We have a GCC style pragma message, and we just read the string.
1061076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      break;
1062076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    default:
1063076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      PP.Diag(MessageLoc, diag::err_pragma_message_malformed) << Kind;
1064076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      return;
1065076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    }
1066076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1067076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    std::string MessageString;
1068076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    if (!PP.FinishLexStringLiteral(Tok, MessageString, PragmaKind(Kind),
1069076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                                   /*MacroExpansion=*/true))
1070076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      return;
1071076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1072076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    if (ExpectClosingParen) {
1073076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      if (Tok.isNot(tok::r_paren)) {
1074076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs        PP.Diag(Tok.getLocation(), diag::err_pragma_message_malformed) << Kind;
1075076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs        return;
1076076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      }
1077076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      PP.Lex(Tok);  // eat the r_paren.
1078076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    }
1079076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1080076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    if (Tok.isNot(tok::eod)) {
1081076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      PP.Diag(Tok.getLocation(), diag::err_pragma_message_malformed) << Kind;
1082076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      return;
1083076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    }
1084076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1085076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    // Output the message.
1086076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    PP.Diag(MessageLoc, (Kind == PPCallbacks::PMK_Error)
1087076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                          ? diag::err_pragma_message
1088076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                          : diag::warn_pragma_message) << MessageString;
1089076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1090076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    // If the pragma is lexically sound, notify any interested PPCallbacks.
1091076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    if (PPCallbacks *Callbacks = PP.getPPCallbacks())
1092076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      Callbacks->PragmaMessage(MessageLoc, Namespace, Kind, MessageString);
1093abfe094ce71c42656dcb84a3bdc3e79cb3c16fc3Chris Lattner  }
1094abfe094ce71c42656dcb84a3bdc3e79cb3c16fc3Chris Lattner};
1095abfe094ce71c42656dcb84a3bdc3e79cb3c16fc3Chris Lattner
1096b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaPushMacroHandler - "\#pragma push_macro" saves the value of the
1097f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner/// macro on the top of the stack.
1098f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattnerstruct PragmaPushMacroHandler : public PragmaHandler {
1099f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  PragmaPushMacroHandler() : PragmaHandler("push_macro") {}
110080c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
110180c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                            Token &PushMacroTok) {
1102f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    PP.HandlePragmaPushMacro(PushMacroTok);
1103f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
1104f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner};
1105f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
1106f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
1107b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaPopMacroHandler - "\#pragma pop_macro" sets the value of the
1108f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner/// macro to the value on the top of the stack.
1109f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattnerstruct PragmaPopMacroHandler : public PragmaHandler {
1110f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  PragmaPopMacroHandler() : PragmaHandler("pop_macro") {}
111180c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
111280c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                            Token &PopMacroTok) {
1113f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    PP.HandlePragmaPopMacro(PopMacroTok);
1114f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
1115f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner};
1116f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
1117062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner// Pragma STDC implementations.
11186c5cf4a2e234923ab66127de0874a71cb6bfdd83Chris Lattner
1119b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaSTDC_FENV_ACCESSHandler - "\#pragma STDC FENV_ACCESS ...".
1120062f23246510393c19b537b68ec88b6a08ee8996Chris Lattnerstruct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler {
11219b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaSTDC_FENV_ACCESSHandler() : PragmaHandler("FENV_ACCESS") {}
112280c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
112380c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                            Token &Tok) {
11249d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    tok::OnOffSwitch OOS;
11259d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    if (PP.LexOnOffSwitch(OOS))
11269d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne     return;
11279d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    if (OOS == tok::OOS_ON)
11284d8aac3778b40c161bed9964125948ee01c08821Chris Lattner      PP.Diag(Tok, diag::warn_stdc_fenv_access_not_supported);
1129062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner  }
1130062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner};
11311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1132b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaSTDC_CX_LIMITED_RANGEHandler - "\#pragma STDC CX_LIMITED_RANGE ...".
1133062f23246510393c19b537b68ec88b6a08ee8996Chris Lattnerstruct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler {
11349b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaSTDC_CX_LIMITED_RANGEHandler()
11359b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis    : PragmaHandler("CX_LIMITED_RANGE") {}
113680c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
113780c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                            Token &Tok) {
11389d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    tok::OnOffSwitch OOS;
11399d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    PP.LexOnOffSwitch(OOS);
1140062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner  }
1141062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner};
11421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1143b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaSTDC_UnknownHandler - "\#pragma STDC ...".
1144062f23246510393c19b537b68ec88b6a08ee8996Chris Lattnerstruct PragmaSTDC_UnknownHandler : public PragmaHandler {
11459b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaSTDC_UnknownHandler() {}
114680c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
114780c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                            Token &UnknownTok) {
11486c5cf4a2e234923ab66127de0874a71cb6bfdd83Chris Lattner    // C99 6.10.6p2, unknown forms are not allowed.
1149f545be5552b6fd40a4c766fbf82dab0ab5305790Chris Lattner    PP.Diag(UnknownTok, diag::ext_stdc_pragma_ignored);
1150062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner  }
1151062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner};
11521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11538dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall/// PragmaARCCFCodeAuditedHandler -
1154b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett///   \#pragma clang arc_cf_code_audited begin/end
11558dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCallstruct PragmaARCCFCodeAuditedHandler : public PragmaHandler {
11568dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  PragmaARCCFCodeAuditedHandler() : PragmaHandler("arc_cf_code_audited") {}
11578dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
11588dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall                            Token &NameTok) {
11598dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    SourceLocation Loc = NameTok.getLocation();
11608dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    bool IsBegin;
11618dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
11628dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    Token Tok;
11638dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
11648dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    // Lex the 'begin' or 'end'.
11658dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    PP.LexUnexpandedToken(Tok);
11668dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    const IdentifierInfo *BeginEnd = Tok.getIdentifierInfo();
11678dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    if (BeginEnd && BeginEnd->isStr("begin")) {
11688dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      IsBegin = true;
11698dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    } else if (BeginEnd && BeginEnd->isStr("end")) {
11708dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      IsBegin = false;
11718dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    } else {
11728dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      PP.Diag(Tok.getLocation(), diag::err_pp_arc_cf_code_audited_syntax);
11738dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      return;
11748dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    }
11758dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
11768dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    // Verify that this is followed by EOD.
11778dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    PP.LexUnexpandedToken(Tok);
11788dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    if (Tok.isNot(tok::eod))
11798dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";
11808dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
11818dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    // The start location of the active audit.
11828dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    SourceLocation BeginLoc = PP.getPragmaARCCFCodeAuditedLoc();
11838dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
11848dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    // The start location we want after processing this.
11858dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    SourceLocation NewLoc;
11868dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
11878dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    if (IsBegin) {
11888dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      // Complain about attempts to re-enter an audit.
11898dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      if (BeginLoc.isValid()) {
11908dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall        PP.Diag(Loc, diag::err_pp_double_begin_of_arc_cf_code_audited);
11918dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall        PP.Diag(BeginLoc, diag::note_pragma_entered_here);
11928dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      }
11938dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      NewLoc = Loc;
11948dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    } else {
11958dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      // Complain about attempts to leave an audit that doesn't exist.
11968dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      if (!BeginLoc.isValid()) {
11978dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall        PP.Diag(Loc, diag::err_pp_unmatched_end_of_arc_cf_code_audited);
11988dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall        return;
11998dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      }
12008dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      NewLoc = SourceLocation();
12018dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    }
12028dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
12038dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    PP.setPragmaARCCFCodeAuditedLoc(NewLoc);
12048dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
12058dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall};
12068dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
1207ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer/// \brief Handle "\#pragma region [...]"
1208ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer///
1209ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer/// The syntax is
1210ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer/// \code
1211ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer///   #pragma region [optional name]
1212ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer///   #pragma endregion [optional comment]
1213ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer/// \endcode
1214ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer///
1215ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer/// \note This is
1216ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer/// <a href="http://msdn.microsoft.com/en-us/library/b6xkz944(v=vs.80).aspx">editor-only</a>
1217ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer/// pragma, just skipped by compiler.
1218ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemerstruct PragmaRegionHandler : public PragmaHandler {
1219ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer  PragmaRegionHandler(const char *pragma) : PragmaHandler(pragma) { }
1220ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer
1221ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1222ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer                            Token &NameTok) {
1223ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer    // #pragma region: endregion matches can be verified
1224ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer    // __pragma(region): no sense, but ignored by msvc
1225ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer    // _Pragma is not valid for MSVC, but there isn't any point
1226ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer    // to handle a _Pragma differently.
1227ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer  }
1228ad5f8336f96911805bb625cc4fb1a4487745508aDavid Majnemer};
1229fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman
12305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}  // end anonymous namespace
12315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
12325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
12335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// RegisterBuiltinPragmas - Install the standard preprocessor pragmas:
1234b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \#pragma GCC poison/system_header/dependency and \#pragma once.
12355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid Preprocessor::RegisterBuiltinPragmas() {
12369b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler(new PragmaOnceHandler());
12379b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler(new PragmaMarkHandler());
1238f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  AddPragmaHandler(new PragmaPushMacroHandler());
1239f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  AddPragmaHandler(new PragmaPopMacroHandler());
1240076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  AddPragmaHandler(new PragmaMessageHandler(PPCallbacks::PMK_Message));
12411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1242e8fa06e07363b6d5e6c371bbd454d51bab78d01dChris Lattner  // #pragma GCC ...
12439b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("GCC", new PragmaPoisonHandler());
12449b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("GCC", new PragmaSystemHeaderHandler());
12459b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("GCC", new PragmaDependencyHandler());
1246c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor  AddPragmaHandler("GCC", new PragmaDiagnosticHandler("GCC"));
1247076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  AddPragmaHandler("GCC", new PragmaMessageHandler(PPCallbacks::PMK_Warning,
1248076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                                                   "GCC"));
1249076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  AddPragmaHandler("GCC", new PragmaMessageHandler(PPCallbacks::PMK_Error,
1250076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                                                   "GCC"));
1251e8fa06e07363b6d5e6c371bbd454d51bab78d01dChris Lattner  // #pragma clang ...
12529b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("clang", new PragmaPoisonHandler());
12539b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("clang", new PragmaSystemHeaderHandler());
1254abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar  AddPragmaHandler("clang", new PragmaDebugHandler());
12559b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("clang", new PragmaDependencyHandler());
1256c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor  AddPragmaHandler("clang", new PragmaDiagnosticHandler("clang"));
12578dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  AddPragmaHandler("clang", new PragmaARCCFCodeAuditedHandler());
12589b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis
12599b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("STDC", new PragmaSTDC_FENV_ACCESSHandler());
12609b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("STDC", new PragmaSTDC_CX_LIMITED_RANGEHandler());
1261062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner  AddPragmaHandler("STDC", new PragmaSTDC_UnknownHandler());
12621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1263636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner  // MS extensions.
12644e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (LangOpts.MicrosoftExt) {
12654c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    AddPragmaHandler(new PragmaIncludeAliasHandler());
1266fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman    AddPragmaHandler(new PragmaRegionHandler("region"));
1267fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman    AddPragmaHandler(new PragmaRegionHandler("endregion"));
1268abfe094ce71c42656dcb84a3bdc3e79cb3c16fc3Chris Lattner  }
12695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1270