Pragma.cpp revision 142b35e25b579e2a883d6ca37c3c1121f562f242
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.
2570b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    for (unsigned i = 1, e = StrVal.size(); i < e-2; ++i) {
2580b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith      if (StrVal[i] == '\\' &&
2590b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith          (StrVal[i+1] == '\\' || StrVal[i+1] == '"')) {
2600b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith        // \\ -> '\' and \" -> '"'.
2610b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith        StrVal.erase(StrVal.begin()+i);
2620b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith        --e;
2630b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith      }
2640b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith    }
2650b91cc47a5642de2e1f567fe0f29420acdcdebbeRichard Smith  }
2661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Remove the front quote, replacing it with a space, so that the pragma
2685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // contents appear to have a space before them.
2695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StrVal[0] = ' ';
2701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2711fa495304c81e03f07f278a47b5efe9317104aabChris Lattner  // Replace the terminating quote with a \n.
2725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StrVal[StrVal.size()-1] = '\n';
2731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
274a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // Plop the string (including the newline and trailing null) into a buffer
275a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // where we can lex it.
276a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  Token TmpTok;
277a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  TmpTok.startToken();
278374b3837d676133fcc1eb70a25c8baf8ec4a5c4aDmitri Gribenko  CreateString(StrVal, TmpTok);
279a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  SourceLocation TokLoc = TmpTok.getLocation();
280a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne
281a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // Make and enter a lexer object so that we lex and expand the tokens just
282a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // like any others.
283a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  Lexer *TL = Lexer::Create_PragmaLexer(TokLoc, PragmaLoc, RParenLoc,
284a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne                                        StrVal.size(), *this);
285a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne
286a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  EnterSourceFileWithLexer(TL, 0);
287a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne
288a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // With everything set up, lex this as a #pragma directive.
289a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  HandlePragmaDirective(PIK__Pragma);
2901ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
2911ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  // Finally, return whatever came after the pragma directive.
2921ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  return Lex(Tok);
2931ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall}
2941ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
2951ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall/// HandleMicrosoft__pragma - Like Handle_Pragma except the pragma text
2961ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall/// is not enclosed within a string literal.
2971ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCallvoid Preprocessor::HandleMicrosoft__pragma(Token &Tok) {
2981ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  // Remember the pragma token location.
2991ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  SourceLocation PragmaLoc = Tok.getLocation();
3001ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
3011ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  // Read the '('.
3021ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  Lex(Tok);
3031ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  if (Tok.isNot(tok::l_paren)) {
3041ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall    Diag(PragmaLoc, diag::err__Pragma_malformed);
3051ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall    return;
3061ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  }
3071ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
308a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // Get the tokens enclosed within the __pragma(), as well as the final ')'.
3095f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<Token, 32> PragmaToks;
3101ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  int NumParens = 0;
3111ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  Lex(Tok);
3121ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  while (Tok.isNot(tok::eof)) {
313a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne    PragmaToks.push_back(Tok);
3141ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall    if (Tok.is(tok::l_paren))
3151ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall      NumParens++;
3161ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall    else if (Tok.is(tok::r_paren) && NumParens-- == 0)
3171ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall      break;
3181ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall    Lex(Tok);
3191ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall  }
3201ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
3213da92a9d21f707c164797dd967ba894b2282b343John McCall  if (Tok.is(tok::eof)) {
3223da92a9d21f707c164797dd967ba894b2282b343John McCall    Diag(PragmaLoc, diag::err_unterminated___pragma);
3233da92a9d21f707c164797dd967ba894b2282b343John McCall    return;
3243da92a9d21f707c164797dd967ba894b2282b343John McCall  }
3253da92a9d21f707c164797dd967ba894b2282b343John McCall
326a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  PragmaToks.front().setFlag(Token::LeadingSpace);
3271ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
32884021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  // Replace the ')' with an EOD to mark the end of the pragma.
32984021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  PragmaToks.back().setKind(tok::eod);
3301ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall
331a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  Token *TokArray = new Token[PragmaToks.size()];
332a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  std::copy(PragmaToks.begin(), PragmaToks.end(), TokArray);
3331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
334a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // Push the tokens onto the stack.
335a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  EnterTokenStream(TokArray, PragmaToks.size(), true, true);
3365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // With everything set up, lex this as a #pragma directive.
338a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  HandlePragmaDirective(PIK___pragma);
3395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
340a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  // Finally, return whatever came after the pragma directive.
341a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne  return Lex(Tok);
342a5ef584fd3d18da0c98342b4b6453948b7eb30d3Peter Collingbourne}
3435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
344b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// HandlePragmaOnce - Handle \#pragma once.  OnceTok is the 'once'.
3455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
346d217773f106856a11879ec79dc468efefaf2ee75Chris Lattnervoid Preprocessor::HandlePragmaOnce(Token &OnceTok) {
3475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (isInPrimaryFile()) {
3485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Diag(OnceTok, diag::pp_pragma_once_in_main_file);
3495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return;
3505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Get the current file lexer we're looking at.  Ignore _Pragma 'files' etc.
3535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Mark the file as a once-only file now.
3542b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  HeaderInfo.MarkFileIncludeOnce(getCurrentFileLexer()->getFileEntry());
3555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
3565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3572243449253475574fc6f14986ff8f7fce5d46799Chris Lattnervoid Preprocessor::HandlePragmaMark() {
35817ff58a63197b398ae52697b088dc0fb8b255519Ted Kremenek  assert(CurPPLexer && "No current lexer?");
3596896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner  if (CurLexer)
3606896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner    CurLexer->ReadToEndOfLine();
3616896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner  else
3626896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner    CurPTHLexer->DiscardToEndOfLine();
3632243449253475574fc6f14986ff8f7fce5d46799Chris Lattner}
3642243449253475574fc6f14986ff8f7fce5d46799Chris Lattner
3652243449253475574fc6f14986ff8f7fce5d46799Chris Lattner
366b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// HandlePragmaPoison - Handle \#pragma GCC poison.  PoisonTok is the 'poison'.
3675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
368d217773f106856a11879ec79dc468efefaf2ee75Chris Lattnervoid Preprocessor::HandlePragmaPoison(Token &PoisonTok) {
369d217773f106856a11879ec79dc468efefaf2ee75Chris Lattner  Token Tok;
3705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  while (1) {
3725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Read the next token to poison.  While doing this, pretend that we are
3735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // skipping while reading the identifier to poison.
3745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // This avoids errors on code like:
3755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    //   #pragma GCC poison X
3765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    //   #pragma GCC poison X
37768a91d5736c2c03d60a9d1c59d08191b8e0d6c52Ted Kremenek    if (CurPPLexer) CurPPLexer->LexingRawMode = true;
3785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    LexUnexpandedToken(Tok);
37968a91d5736c2c03d60a9d1c59d08191b8e0d6c52Ted Kremenek    if (CurPPLexer) CurPPLexer->LexingRawMode = false;
3801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // If we reached the end of line, we're done.
38284021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne    if (Tok.is(tok::eod)) return;
3831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Can only poison identifiers.
385c4bf2b9afb7d47445a9dc6bc848657098a4e3851Abramo Bagnara    if (Tok.isNot(tok::raw_identifier)) {
3865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Diag(Tok, diag::err_pp_invalid_poison);
3875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      return;
3885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
3891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Look up the identifier info for the token.  We disabled identifier lookup
3915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // by saying we're skipping contents, so we need to do this manually.
3925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    IdentifierInfo *II = LookUpIdentifierInfo(Tok);
3931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Already poisoned.
3955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (II->isPoisoned()) continue;
3961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // If this is a macro identifier, emit a warning.
3980edde55077cc3cb9fffeba19f5936f05a68c8e2bChris Lattner    if (II->hasMacroDefinition())
3995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Diag(Tok, diag::pp_poisoning_existing_macro);
4001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Finally, poison it!
4025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    II->setIsPoisoned();
403eee242ff426bf79149f221798966e58688383c1eDouglas Gregor    if (II->isFromAST())
404eee242ff426bf79149f221798966e58688383c1eDouglas Gregor      II->setChangedSinceDeserialization();
4055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
4075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
408b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// HandlePragmaSystemHeader - Implement \#pragma GCC system_header.  We know
4095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// that the whole directive has been parsed.
410d217773f106856a11879ec79dc468efefaf2ee75Chris Lattnervoid Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) {
4115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (isInPrimaryFile()) {
4125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);
4135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return;
4145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Get the current file lexer we're looking at.  Ignore _Pragma 'files' etc.
41735c10c25ddec4effbd26dead23ea5b04ee32f45aTed Kremenek  PreprocessorLexer *TheLexer = getCurrentFileLexer();
4181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Mark the file as a system header.
4202b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  HeaderInfo.MarkFileSystemHeader(TheLexer->getFileEntry());
4211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4236896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner  PresumedLoc PLoc = SourceMgr.getPresumedLoc(SysHeaderTok.getLocation());
424cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor  if (PLoc.isInvalid())
425cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor    return;
426cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor
42765aa6885818d4b4eea2e5a9d12085b2398148662Jay Foad  unsigned FilenameID = SourceMgr.getLineTableFilenameID(PLoc.getFilename());
4281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
429784c257c8f5c3a737b0ae1dceb5d54d29b6637cfChris Lattner  // Notify the client, if desired, that we are in a new source file.
430784c257c8f5c3a737b0ae1dceb5d54d29b6637cfChris Lattner  if (Callbacks)
431784c257c8f5c3a737b0ae1dceb5d54d29b6637cfChris Lattner    Callbacks->FileChanged(SysHeaderTok.getLocation(),
432784c257c8f5c3a737b0ae1dceb5d54d29b6637cfChris Lattner                           PPCallbacks::SystemHeaderPragma, SrcMgr::C_System);
433784c257c8f5c3a737b0ae1dceb5d54d29b6637cfChris Lattner
4346896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner  // Emit a line marker.  This will change any source locations from this point
4356896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner  // forward to realize they are in a system header.
4366896a371e302c63ce3d4a99ad2c32e42dde6a9e4Chris Lattner  // Create a line note with this information.
437142b35e25b579e2a883d6ca37c3c1121f562f242Jordan Rose  SourceMgr.AddLineNote(SysHeaderTok.getLocation(), PLoc.getLine()+1,
438142b35e25b579e2a883d6ca37c3c1121f562f242Jordan Rose                        FilenameID, /*IsEntry=*/false, /*IsExit=*/false,
439142b35e25b579e2a883d6ca37c3c1121f562f242Jordan Rose                        /*IsSystem=*/true, /*IsExternC=*/false);
4405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
4415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
442b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// HandlePragmaDependency - Handle \#pragma GCC dependency "foo" blah.
4435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
444d217773f106856a11879ec79dc468efefaf2ee75Chris Lattnervoid Preprocessor::HandlePragmaDependency(Token &DependencyTok) {
445d217773f106856a11879ec79dc468efefaf2ee75Chris Lattner  Token FilenameTok;
44668a91d5736c2c03d60a9d1c59d08191b8e0d6c52Ted Kremenek  CurPPLexer->LexIncludeFilename(FilenameTok);
4475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
44884021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  // If the token kind is EOD, the error has already been diagnosed.
44984021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  if (FilenameTok.is(tok::eod))
4505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return;
4511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Reserve a buffer to get the spelling.
453f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<128> FilenameBuffer;
454453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor  bool Invalid = false;
4555f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Filename = getSpelling(FilenameTok, FilenameBuffer, &Invalid);
456453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor  if (Invalid)
457453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor    return;
4581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
459a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner  bool isAngled =
460a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner    GetIncludeFilenameSpelling(FilenameTok.getLocation(), Filename);
4615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If GetIncludeFilenameSpelling set the start ptr to null, there was an
4625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // error.
463a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner  if (Filename.empty())
4645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return;
4651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Search include directories for this file.
4675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const DirectoryLookup *CurDir;
468fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor  const FileEntry *File = LookupFile(Filename, isAngled, 0, CurDir, NULL, NULL,
469fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor                                     NULL);
47056b05c8829efd13b7e5b333f8f587c71d025c67dChris Lattner  if (File == 0) {
471f84139a1331c63c998e8b7d54148c75ac0b48ccdEli Friedman    if (!SuppressIncludeNotFoundError)
472f84139a1331c63c998e8b7d54148c75ac0b48ccdEli Friedman      Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
47356b05c8829efd13b7e5b333f8f587c71d025c67dChris Lattner    return;
47456b05c8829efd13b7e5b333f8f587c71d025c67dChris Lattner  }
4751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4762b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  const FileEntry *CurFile = getCurrentFileLexer()->getFileEntry();
4775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If this file is older than the file it depends on, emit a diagnostic.
4795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (CurFile && CurFile->getModificationTime() < File->getModificationTime()) {
4805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Lex tokens at the end of the message and include them in the message.
4815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    std::string Message;
4825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Lex(DependencyTok);
48384021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne    while (DependencyTok.isNot(tok::eod)) {
4845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Message += getSpelling(DependencyTok) + " ";
4855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Lex(DependencyTok);
4865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
4871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
48896de25986d28171945db96a6c6a54f91fd12ae4bChris Lattner    // Remove the trailing ' ' if present.
48996de25986d28171945db96a6c6a54f91fd12ae4bChris Lattner    if (!Message.empty())
49096de25986d28171945db96a6c6a54f91fd12ae4bChris Lattner      Message.erase(Message.end()-1);
49156b05c8829efd13b7e5b333f8f587c71d025c67dChris Lattner    Diag(FilenameTok, diag::pp_out_of_date_dependency) << Message;
4925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
4945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
495b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \brief Handle the microsoft \#pragma comment extension.
496b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett///
497b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// The syntax is:
498b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \code
499e74dc199e95cc523c8806e0de41d8814e8bc5c42Dmitri Gribenko///   #pragma comment(linker, "foo")
500b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \endcode
501636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner/// 'linker' is one of five identifiers: compiler, exestr, lib, linker, user.
502636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner/// "foo" is a string, which is fully macro expanded, and permits string
503d7ee349f1dd84e023d09a35fb4d40c15888a55acGabor Greif/// concatenation, embedded escape characters etc.  See MSDN for more details.
504636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattnervoid Preprocessor::HandlePragmaComment(Token &Tok) {
505636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner  SourceLocation CommentLoc = Tok.getLocation();
506636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner  Lex(Tok);
507636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner  if (Tok.isNot(tok::l_paren)) {
508636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner    Diag(CommentLoc, diag::err_pragma_comment_malformed);
509636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner    return;
510636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner  }
5111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
512636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner  // Read the identifier.
513636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner  Lex(Tok);
514636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner  if (Tok.isNot(tok::identifier)) {
515636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner    Diag(CommentLoc, diag::err_pragma_comment_malformed);
516636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner    return;
517636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner  }
5181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
519636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner  // Verify that this is one of the 5 whitelisted options.
520636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner  // FIXME: warn that 'exestr' is deprecated.
521636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner  const IdentifierInfo *II = Tok.getIdentifierInfo();
5221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (!II->isStr("compiler") && !II->isStr("exestr") && !II->isStr("lib") &&
523636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner      !II->isStr("linker") && !II->isStr("user")) {
524636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner    Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind);
525636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner    return;
526636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner  }
5271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
528a9d9145741ef77db45890911674705b81605b10bChris Lattner  // Read the optional string if present.
529636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner  Lex(Tok);
530a9d9145741ef77db45890911674705b81605b10bChris Lattner  std::string ArgumentString;
53102a176871d91bba3004e4f94b2d4d588ae4b2122Andy Gibbs  if (Tok.is(tok::comma) && !LexStringLiteral(Tok, ArgumentString,
53297f8461a2c553f68a258612d2322e4281c3f0915Andy Gibbs                                              "pragma comment",
53302a176871d91bba3004e4f94b2d4d588ae4b2122Andy Gibbs                                              /*MacroExpansion=*/true))
53402a176871d91bba3004e4f94b2d4d588ae4b2122Andy Gibbs    return;
5351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
536a9d9145741ef77db45890911674705b81605b10bChris Lattner  // FIXME: If the kind is "compiler" warn if the string is present (it is
537a9d9145741ef77db45890911674705b81605b10bChris Lattner  // ignored).
538a9d9145741ef77db45890911674705b81605b10bChris Lattner  // FIXME: 'lib' requires a comment string.
539a9d9145741ef77db45890911674705b81605b10bChris Lattner  // FIXME: 'linker' requires a comment string, and has a specific list of
540a9d9145741ef77db45890911674705b81605b10bChris Lattner  // things that are allowable.
5411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
542636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner  if (Tok.isNot(tok::r_paren)) {
543636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner    Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
544636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner    return;
545636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner  }
546a9d9145741ef77db45890911674705b81605b10bChris Lattner  Lex(Tok);  // eat the r_paren.
547636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner
54884021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  if (Tok.isNot(tok::eod)) {
549636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner    Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
550636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner    return;
551636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner  }
5521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
553a9d9145741ef77db45890911674705b81605b10bChris Lattner  // If the pragma is lexically sound, notify any interested PPCallbacks.
554172e336b12fa32a1737f66d77a3f2de86f9cc8e8Chris Lattner  if (Callbacks)
555172e336b12fa32a1737f66d77a3f2de86f9cc8e8Chris Lattner    Callbacks->PragmaComment(CommentLoc, II, ArgumentString);
556636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner}
557636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner
558f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner/// ParsePragmaPushOrPopMacro - Handle parsing of pragma push_macro/pop_macro.
559f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner/// Return the IdentifierInfo* associated with the macro to push or pop.
560f47724bf78299c7a50f008e0443c5f9f9f279ddcChris LattnerIdentifierInfo *Preprocessor::ParsePragmaPushOrPopMacro(Token &Tok) {
561f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Remember the pragma token location.
562f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  Token PragmaTok = Tok;
563f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
564f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Read the '('.
565f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  Lex(Tok);
566f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (Tok.isNot(tok::l_paren)) {
567f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
568f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner      << getSpelling(PragmaTok);
569f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    return 0;
570f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
571f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
572f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Read the macro name string.
573f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  Lex(Tok);
574f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (Tok.isNot(tok::string_literal)) {
575f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
576f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner      << getSpelling(PragmaTok);
577f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    return 0;
578f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
579f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
58099831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  if (Tok.hasUDSuffix()) {
58199831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    Diag(Tok, diag::err_invalid_string_udl);
58299831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    return 0;
58399831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  }
58499831e4677a7e2e051af636221694d60ba31fcdbRichard Smith
585f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Remember the macro string.
586f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  std::string StrVal = getSpelling(Tok);
587f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
588f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Read the ')'.
589f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  Lex(Tok);
590f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (Tok.isNot(tok::r_paren)) {
591f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
592f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner      << getSpelling(PragmaTok);
593f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    return 0;
594f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
595f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
596f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' &&
597f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner         "Invalid string token!");
598f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
599f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Create a Token from the string.
600f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  Token MacroTok;
601f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  MacroTok.startToken();
602c4bf2b9afb7d47445a9dc6bc848657098a4e3851Abramo Bagnara  MacroTok.setKind(tok::raw_identifier);
603374b3837d676133fcc1eb70a25c8baf8ec4a5c4aDmitri Gribenko  CreateString(StringRef(&StrVal[1], StrVal.size() - 2), MacroTok);
604f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
605f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Get the IdentifierInfo of MacroToPushTok.
606f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  return LookUpIdentifierInfo(MacroTok);
607f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner}
608f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
609b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \brief Handle \#pragma push_macro.
610b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett///
611f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner/// The syntax is:
612b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \code
613e74dc199e95cc523c8806e0de41d8814e8bc5c42Dmitri Gribenko///   #pragma push_macro("macro")
614b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \endcode
615f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattnervoid Preprocessor::HandlePragmaPushMacro(Token &PushMacroTok) {
616f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Parse the pragma directive and get the macro IdentifierInfo*.
617f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PushMacroTok);
618f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (!IdentInfo) return;
619f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
620f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Get the MacroInfo associated with IdentInfo.
621f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  MacroInfo *MI = getMacroInfo(IdentInfo);
622f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
623f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (MI) {
624f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    // Allow the original MacroInfo to be redefined later.
625f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    MI->setIsAllowRedefinitionsWithoutWarning(true);
626f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
627f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
628f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Push the cloned MacroInfo so we can retrieve it later.
6299818a1d443e97677dd3422305de9cc2b1fb2a8c1Argyrios Kyrtzidis  PragmaPushMacroInfo[IdentInfo].push_back(MI);
630f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner}
631f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
632b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \brief Handle \#pragma pop_macro.
633b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett///
634f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner/// The syntax is:
635b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \code
636f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner///   #pragma pop_macro("macro")
637b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \endcode
638f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattnervoid Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) {
639f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  SourceLocation MessageLoc = PopMacroTok.getLocation();
640f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
641f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Parse the pragma directive and get the macro IdentifierInfo*.
642f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PopMacroTok);
643f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (!IdentInfo) return;
644f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
645f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  // Find the vector<MacroInfo*> associated with the macro.
646f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> >::iterator iter =
647f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    PragmaPushMacroInfo.find(IdentInfo);
648f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  if (iter != PragmaPushMacroInfo.end()) {
6498a64bb58c3b24d7d97895e435bbc0965c99bd3beAlexander Kornienko    // Forget the MacroInfo currently associated with IdentInfo.
6509818a1d443e97677dd3422305de9cc2b1fb2a8c1Argyrios Kyrtzidis    if (MacroDirective *CurrentMD = getMacroDirective(IdentInfo)) {
651c56fff7fd231aebf4b152f60f8f11ef91835c48aArgyrios Kyrtzidis      MacroInfo *MI = CurrentMD->getMacroInfo();
652c56fff7fd231aebf4b152f60f8f11ef91835c48aArgyrios Kyrtzidis      if (MI->isWarnIfUnused())
653c56fff7fd231aebf4b152f60f8f11ef91835c48aArgyrios Kyrtzidis        WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
654c56fff7fd231aebf4b152f60f8f11ef91835c48aArgyrios Kyrtzidis      appendMacroDirective(IdentInfo, AllocateUndefMacroDirective(MessageLoc));
6550827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis    }
656f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
657f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    // Get the MacroInfo we want to reinstall.
658f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    MacroInfo *MacroToReInstall = iter->second.back();
659f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
660e40c4238a572bf8241a04e0005f70550cbfc1cfbAlexander Kornienko    if (MacroToReInstall) {
661e40c4238a572bf8241a04e0005f70550cbfc1cfbAlexander Kornienko      // Reinstall the previously pushed macro.
662c56fff7fd231aebf4b152f60f8f11ef91835c48aArgyrios Kyrtzidis      appendDefMacroDirective(IdentInfo, MacroToReInstall, MessageLoc,
663c56fff7fd231aebf4b152f60f8f11ef91835c48aArgyrios Kyrtzidis                              /*isImported=*/false);
664e40c4238a572bf8241a04e0005f70550cbfc1cfbAlexander Kornienko    }
665f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
666f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    // Pop PragmaPushMacroInfo stack.
667f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    iter->second.pop_back();
668f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    if (iter->second.size() == 0)
669f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner      PragmaPushMacroInfo.erase(iter);
670f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  } else {
671f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    Diag(MessageLoc, diag::warn_pragma_pop_macro_no_push)
672f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner      << IdentInfo->getName();
673f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
674f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner}
6755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6764c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballmanvoid Preprocessor::HandlePragmaIncludeAlias(Token &Tok) {
6774c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // We will either get a quoted filename or a bracketed filename, and we
6784c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // have to track which we got.  The first filename is the source name,
6794c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // and the second name is the mapped filename.  If the first is quoted,
6804c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // the second must be as well (cannot mix and match quotes and brackets).
6814c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6824c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // Get the open paren
6834c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  Lex(Tok);
6844c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (Tok.isNot(tok::l_paren)) {
6854c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    Diag(Tok, diag::warn_pragma_include_alias_expected) << "(";
6864c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
6874c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
6884c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6894c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // We expect either a quoted string literal, or a bracketed name
6904c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  Token SourceFilenameTok;
6914c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  CurPPLexer->LexIncludeFilename(SourceFilenameTok);
6924c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (SourceFilenameTok.is(tok::eod)) {
6934c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    // The diagnostic has already been handled
6944c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
6954c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
6964c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
6974c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  StringRef SourceFileName;
6984c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  SmallString<128> FileNameBuffer;
6994c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (SourceFilenameTok.is(tok::string_literal) ||
7004c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      SourceFilenameTok.is(tok::angle_string_literal)) {
7014c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    SourceFileName = getSpelling(SourceFilenameTok, FileNameBuffer);
7024c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  } else if (SourceFilenameTok.is(tok::less)) {
7034c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    // This could be a path instead of just a name
7044c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    FileNameBuffer.push_back('<');
7054c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    SourceLocation End;
7064c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    if (ConcatenateIncludeName(FileNameBuffer, End))
7074c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      return; // Diagnostic already emitted
7084c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    SourceFileName = FileNameBuffer.str();
7094c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  } else {
7104c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
7114c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
7124c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
7134c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  FileNameBuffer.clear();
7144c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
7154c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // Now we expect a comma, followed by another include name
7164c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  Lex(Tok);
7174c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (Tok.isNot(tok::comma)) {
7184c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    Diag(Tok, diag::warn_pragma_include_alias_expected) << ",";
7194c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
7204c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
7214c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
7224c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  Token ReplaceFilenameTok;
7234c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  CurPPLexer->LexIncludeFilename(ReplaceFilenameTok);
7244c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (ReplaceFilenameTok.is(tok::eod)) {
7254c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    // The diagnostic has already been handled
7264c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
7274c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
7284c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
7294c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  StringRef ReplaceFileName;
7304c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (ReplaceFilenameTok.is(tok::string_literal) ||
7314c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      ReplaceFilenameTok.is(tok::angle_string_literal)) {
7324c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    ReplaceFileName = getSpelling(ReplaceFilenameTok, FileNameBuffer);
7334c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  } else if (ReplaceFilenameTok.is(tok::less)) {
7344c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    // This could be a path instead of just a name
7354c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    FileNameBuffer.push_back('<');
7364c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    SourceLocation End;
7374c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    if (ConcatenateIncludeName(FileNameBuffer, End))
7384c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      return; // Diagnostic already emitted
7394c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    ReplaceFileName = FileNameBuffer.str();
7404c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  } else {
7414c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
7424c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
7434c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
7444c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
7454c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // Finally, we expect the closing paren
7464c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  Lex(Tok);
7474c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (Tok.isNot(tok::r_paren)) {
7484c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    Diag(Tok, diag::warn_pragma_include_alias_expected) << ")";
7494c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
7504c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
7514c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
7524c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // Now that we have the source and target filenames, we need to make sure
7534c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // they're both of the same type (angled vs non-angled)
7544c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  StringRef OriginalSource = SourceFileName;
7554c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
7564c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  bool SourceIsAngled =
7574c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    GetIncludeFilenameSpelling(SourceFilenameTok.getLocation(),
7584c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman                                SourceFileName);
7594c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  bool ReplaceIsAngled =
7604c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    GetIncludeFilenameSpelling(ReplaceFilenameTok.getLocation(),
7614c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman                                ReplaceFileName);
7624c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  if (!SourceFileName.empty() && !ReplaceFileName.empty() &&
7634c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      (SourceIsAngled != ReplaceIsAngled)) {
7644c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    unsigned int DiagID;
7654c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    if (SourceIsAngled)
7664c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      DiagID = diag::warn_pragma_include_alias_mismatch_angle;
7674c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    else
7684c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      DiagID = diag::warn_pragma_include_alias_mismatch_quote;
7694c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
7704c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    Diag(SourceFilenameTok.getLocation(), DiagID)
7714c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      << SourceFileName
7724c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      << ReplaceFileName;
7734c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
7744c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return;
7754c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
7764c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
7774c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  // Now we can let the include handler know about this mapping
7784c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  getHeaderSearchInfo().AddIncludeAlias(OriginalSource, ReplaceFileName);
7794c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman}
7804c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
7815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// AddPragmaHandler - Add the specified pragma handler to the preprocessor.
7825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// If 'Namespace' is non-null, then it is a token required to exist on the
7835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
7845f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Preprocessor::AddPragmaHandler(StringRef Namespace,
7855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                    PragmaHandler *Handler) {
7865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  PragmaNamespace *InsertNS = PragmaHandlers;
7871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If this is specified to be in a namespace, step down into it.
7899b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  if (!Namespace.empty()) {
7905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // If there is already a pragma handler with the name of this namespace,
7915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // we either have an error (directive with the same name as a namespace) or
7925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // we already have the namespace to insert into.
7939b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis    if (PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace)) {
7945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      InsertNS = Existing->getIfNamespace();
7955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      assert(InsertNS != 0 && "Cannot have a pragma namespace and pragma"
7965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer             " handler with the same name!");
7975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    } else {
7985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      // Otherwise, this namespace doesn't exist yet, create and insert the
7995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      // handler for it.
8009b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis      InsertNS = new PragmaNamespace(Namespace);
8015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      PragmaHandlers->AddPragma(InsertNS);
8025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
8035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
8041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Check to make sure we don't already have a pragma for this identifier.
8065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  assert(!InsertNS->FindHandler(Handler->getName()) &&
8075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         "Pragma handler already exists for this identifier!");
8085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  InsertNS->AddPragma(Handler);
8095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
8105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
8114095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar/// RemovePragmaHandler - Remove the specific pragma handler from the
8124095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar/// preprocessor. If \arg Namespace is non-null, then it should be the
8134095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar/// namespace that \arg Handler was added to. It is an error to remove
8144095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar/// a handler that has not been registered.
8155f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Preprocessor::RemovePragmaHandler(StringRef Namespace,
8164095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar                                       PragmaHandler *Handler) {
8174095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar  PragmaNamespace *NS = PragmaHandlers;
8181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8194095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar  // If this is specified to be in a namespace, step down into it.
8209b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  if (!Namespace.empty()) {
8219b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis    PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace);
8224095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar    assert(Existing && "Namespace containing handler does not exist!");
8234095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar
8244095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar    NS = Existing->getIfNamespace();
8254095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar    assert(NS && "Invalid namespace, registered as a regular pragma handler!");
8264095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar  }
8274095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar
8284095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar  NS->RemovePragmaHandler(Handler);
8291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8304095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar  // If this is a non-default namespace and it is now empty, remove
8314095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar  // it.
832ce52bb3dec520ef94574280ac3ef8ad63f4f1ce2Argyrios Kyrtzidis  if (NS != PragmaHandlers && NS->IsEmpty()) {
8334095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar    PragmaHandlers->RemovePragmaHandler(NS);
834ce52bb3dec520ef94574280ac3ef8ad63f4f1ce2Argyrios Kyrtzidis    delete NS;
835ce52bb3dec520ef94574280ac3ef8ad63f4f1ce2Argyrios Kyrtzidis  }
8364095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar}
8374095080aff204008eefb26b100906c6ca2bc4bb6Daniel Dunbar
8389d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbournebool Preprocessor::LexOnOffSwitch(tok::OnOffSwitch &Result) {
8399d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  Token Tok;
8409d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  LexUnexpandedToken(Tok);
8419d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne
8429d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  if (Tok.isNot(tok::identifier)) {
8439d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    Diag(Tok, diag::ext_on_off_switch_syntax);
8449d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    return true;
8459d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  }
8469d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  IdentifierInfo *II = Tok.getIdentifierInfo();
8479d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  if (II->isStr("ON"))
8489d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    Result = tok::OOS_ON;
8499d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  else if (II->isStr("OFF"))
8509d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    Result = tok::OOS_OFF;
8519d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  else if (II->isStr("DEFAULT"))
8529d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    Result = tok::OOS_DEFAULT;
8539d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  else {
8549d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    Diag(Tok, diag::ext_on_off_switch_syntax);
8559d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    return true;
8569d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  }
8579d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne
85884021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  // Verify that this is followed by EOD.
8599d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  LexUnexpandedToken(Tok);
86084021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  if (Tok.isNot(tok::eod))
86184021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne    Diag(Tok, diag::ext_pragma_syntax_eod);
8629d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne  return false;
8639d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne}
8649d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne
8655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace {
866b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaOnceHandler - "\#pragma once" marks the file as atomically included.
8675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstruct PragmaOnceHandler : public PragmaHandler {
8689b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaOnceHandler() : PragmaHandler("once") {}
86980c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
87080c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                            Token &OnceTok) {
87135410d5cbbb18735d76e00496540d416dc49b577Chris Lattner    PP.CheckEndOfDirective("pragma once");
8725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    PP.HandlePragmaOnce(OnceTok);
8735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
8745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
8755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
876b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaMarkHandler - "\#pragma mark ..." is ignored by the compiler, and the
8772243449253475574fc6f14986ff8f7fce5d46799Chris Lattner/// rest of the line is not lexed.
8782243449253475574fc6f14986ff8f7fce5d46799Chris Lattnerstruct PragmaMarkHandler : public PragmaHandler {
8799b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaMarkHandler() : PragmaHandler("mark") {}
88080c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
88180c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                            Token &MarkTok) {
8822243449253475574fc6f14986ff8f7fce5d46799Chris Lattner    PP.HandlePragmaMark();
8832243449253475574fc6f14986ff8f7fce5d46799Chris Lattner  }
8842243449253475574fc6f14986ff8f7fce5d46799Chris Lattner};
8852243449253475574fc6f14986ff8f7fce5d46799Chris Lattner
886b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaPoisonHandler - "\#pragma poison x" marks x as not usable.
8875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstruct PragmaPoisonHandler : public PragmaHandler {
8889b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaPoisonHandler() : PragmaHandler("poison") {}
88980c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
89080c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                            Token &PoisonTok) {
8915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    PP.HandlePragmaPoison(PoisonTok);
8925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
8935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
8945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
895b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaSystemHeaderHandler - "\#pragma system_header" marks the current file
8962243449253475574fc6f14986ff8f7fce5d46799Chris Lattner/// as a system header, which silences warnings in it.
8975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstruct PragmaSystemHeaderHandler : public PragmaHandler {
8989b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaSystemHeaderHandler() : PragmaHandler("system_header") {}
89980c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
90080c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                            Token &SHToken) {
9015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    PP.HandlePragmaSystemHeader(SHToken);
90235410d5cbbb18735d76e00496540d416dc49b577Chris Lattner    PP.CheckEndOfDirective("pragma");
9035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
9045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
9055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstruct PragmaDependencyHandler : public PragmaHandler {
9069b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaDependencyHandler() : PragmaHandler("dependency") {}
90780c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
90880c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                            Token &DepToken) {
9095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    PP.HandlePragmaDependency(DepToken);
9105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
9115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
9121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
913abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbarstruct PragmaDebugHandler : public PragmaHandler {
914abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar  PragmaDebugHandler() : PragmaHandler("__debug") {}
91580c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
91680c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                            Token &DepToken) {
917abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    Token Tok;
918abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    PP.LexUnexpandedToken(Tok);
919abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    if (Tok.isNot(tok::identifier)) {
9206493a4d7129673f7878da2382dedf4f9abc57e4cDouglas Gregor      PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
921abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar      return;
922abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    }
923abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    IdentifierInfo *II = Tok.getIdentifierInfo();
924abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar
9255505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar    if (II->isStr("assert")) {
926b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie      llvm_unreachable("This is an assertion!");
927abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    } else if (II->isStr("crash")) {
928377da4c6b78c0130fb6141313636c8fda7b60b72David Blaikie      LLVM_BUILTIN_TRAP;
929e75d9cfbf41a0ee9e456a665776f91fdd9773b36David Blaikie    } else if (II->isStr("parser_crash")) {
930e75d9cfbf41a0ee9e456a665776f91fdd9773b36David Blaikie      Token Crasher;
931e75d9cfbf41a0ee9e456a665776f91fdd9773b36David Blaikie      Crasher.setKind(tok::annot_pragma_parser_crash);
932e75d9cfbf41a0ee9e456a665776f91fdd9773b36David Blaikie      PP.EnterToken(Crasher);
9335505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar    } else if (II->isStr("llvm_fatal_error")) {
9345505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar      llvm::report_fatal_error("#pragma clang __debug llvm_fatal_error");
9355505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar    } else if (II->isStr("llvm_unreachable")) {
9365505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar      llvm_unreachable("#pragma clang __debug llvm_unreachable");
9375505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar    } else if (II->isStr("overflow_stack")) {
9385505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar      DebugOverflowStack();
939ff759a66526d6a985fb4efae69c6b798d83364dfDaniel Dunbar    } else if (II->isStr("handle_crash")) {
940ff759a66526d6a985fb4efae69c6b798d83364dfDaniel Dunbar      llvm::CrashRecoveryContext *CRC =llvm::CrashRecoveryContext::GetCurrent();
941ff759a66526d6a985fb4efae69c6b798d83364dfDaniel Dunbar      if (CRC)
942ff759a66526d6a985fb4efae69c6b798d83364dfDaniel Dunbar        CRC->HandleCrash();
94385192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    } else if (II->isStr("captured")) {
94485192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj      HandleCaptured(PP);
9455505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar    } else {
9465505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar      PP.Diag(Tok, diag::warn_pragma_debug_unexpected_command)
9475505413ee8e4e2924f52ba81181071f3a492e7d9Daniel Dunbar        << II->getName();
948abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    }
94985192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj
95085192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    PPCallbacks *Callbacks = PP.getPPCallbacks();
95185192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    if (Callbacks)
95285192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj      Callbacks->PragmaDebug(Tok.getLocation(), II->getName());
95385192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj  }
95485192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj
95585192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj  void HandleCaptured(Preprocessor &PP) {
95685192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    // Skip if emitting preprocessed output.
95785192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    if (PP.isPreprocessedOutput())
95885192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj      return;
95985192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj
96085192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    Token Tok;
96185192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    PP.LexUnexpandedToken(Tok);
96285192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj
96385192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    if (Tok.isNot(tok::eod)) {
96485192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj      PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol)
96585192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj        << "pragma clang __debug captured";
96685192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj      return;
96785192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    }
96885192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj
96985192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    SourceLocation NameLoc = Tok.getLocation();
97085192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    Token *Toks = PP.getPreprocessorAllocator().Allocate<Token>(1);
97185192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    Toks->startToken();
97285192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    Toks->setKind(tok::annot_pragma_captured);
97385192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    Toks->setLocation(NameLoc);
97485192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj
97585192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj    PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
97685192c7fe187d5486e12dbc6960af28f16a558a0Tareq A. Siraj                        /*OwnsTokens=*/false);
977abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar  }
978abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar
9791066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet// Disable MSVC warning about runtime stack overflow.
9801066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet#ifdef _MSC_VER
9811066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet    #pragma warning(disable : 4717)
9821066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet#endif
983abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar  void DebugOverflowStack() {
984abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar    DebugOverflowStack();
985abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar  }
9861066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet#ifdef _MSC_VER
9871066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet    #pragma warning(default : 4717)
9881066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet#endif
9891066c6c7c4d5186c2434b90b054c302564f98080Francois Pichet
990abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar};
991abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar
992b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaDiagnosticHandler - e.g. '\#pragma GCC diagnostic ignored "-Wformat"'
993edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattnerstruct PragmaDiagnosticHandler : public PragmaHandler {
994c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregorprivate:
995c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor  const char *Namespace;
99604ae2df026b275aae5dddfc0db5ca55ff4e62179Chris Lattnerpublic:
997c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor  explicit PragmaDiagnosticHandler(const char *NS) :
998c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor    PragmaHandler("diagnostic"), Namespace(NS) {}
99980c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
100080c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                            Token &DiagToken) {
10010827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis    SourceLocation DiagLoc = DiagToken.getLocation();
1002edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    Token Tok;
1003edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    PP.LexUnexpandedToken(Tok);
1004edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    if (Tok.isNot(tok::identifier)) {
10056493a4d7129673f7878da2382dedf4f9abc57e4cDouglas Gregor      PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1006edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      return;
1007edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    }
1008edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    IdentifierInfo *II = Tok.getIdentifierInfo();
1009c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor    PPCallbacks *Callbacks = PP.getPPCallbacks();
10101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1011edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    diag::Mapping Map;
1012edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    if (II->isStr("warning"))
1013edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      Map = diag::MAP_WARNING;
1014edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    else if (II->isStr("error"))
1015edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      Map = diag::MAP_ERROR;
1016edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    else if (II->isStr("ignored"))
1017edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      Map = diag::MAP_IGNORE;
1018edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    else if (II->isStr("fatal"))
1019edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      Map = diag::MAP_FATAL;
10206493a4d7129673f7878da2382dedf4f9abc57e4cDouglas Gregor    else if (II->isStr("pop")) {
10210827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis      if (!PP.getDiagnostics().popMappings(DiagLoc))
10226493a4d7129673f7878da2382dedf4f9abc57e4cDouglas Gregor        PP.Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
1023c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor      else if (Callbacks)
1024c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor        Callbacks->PragmaDiagnosticPop(DiagLoc, Namespace);
10256493a4d7129673f7878da2382dedf4f9abc57e4cDouglas Gregor      return;
10266493a4d7129673f7878da2382dedf4f9abc57e4cDouglas Gregor    } else if (II->isStr("push")) {
10270827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis      PP.getDiagnostics().pushMappings(DiagLoc);
1028c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor      if (Callbacks)
1029c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor        Callbacks->PragmaDiagnosticPush(DiagLoc, Namespace);
103004ae2df026b275aae5dddfc0db5ca55ff4e62179Chris Lattner      return;
103104ae2df026b275aae5dddfc0db5ca55ff4e62179Chris Lattner    } else {
10326493a4d7129673f7878da2382dedf4f9abc57e4cDouglas Gregor      PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1033edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      return;
1034edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    }
10351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1036edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    PP.LexUnexpandedToken(Tok);
103702a176871d91bba3004e4f94b2d4d588ae4b2122Andy Gibbs    SourceLocation StringLoc = Tok.getLocation();
1038edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner
103902a176871d91bba3004e4f94b2d4d588ae4b2122Andy Gibbs    std::string WarningName;
104097f8461a2c553f68a258612d2322e4281c3f0915Andy Gibbs    if (!PP.FinishLexStringLiteral(Tok, WarningName, "pragma diagnostic",
104197f8461a2c553f68a258612d2322e4281c3f0915Andy Gibbs                                   /*MacroExpansion=*/false))
1042edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      return;
10431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
104484021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne    if (Tok.isNot(tok::eod)) {
1045edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      PP.Diag(Tok.getLocation(), diag::warn_pragma_diagnostic_invalid_token);
1046edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      return;
1047edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    }
10481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1049edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    if (WarningName.size() < 3 || WarningName[0] != '-' ||
1050edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner        WarningName[1] != 'W') {
105102a176871d91bba3004e4f94b2d4d588ae4b2122Andy Gibbs      PP.Diag(StringLoc, diag::warn_pragma_diagnostic_invalid_option);
1052edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner      return;
1053edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner    }
10541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1055477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidis    if (PP.getDiagnostics().setDiagnosticGroupMapping(WarningName.substr(2),
10560827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis                                                      Map, DiagLoc))
105702a176871d91bba3004e4f94b2d4d588ae4b2122Andy Gibbs      PP.Diag(StringLoc, diag::warn_pragma_diagnostic_unknown_warning)
105802a176871d91bba3004e4f94b2d4d588ae4b2122Andy Gibbs        << WarningName;
1059c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor    else if (Callbacks)
1060c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor      Callbacks->PragmaDiagnostic(DiagLoc, Namespace, Map, WarningName);
1061edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner  }
1062edaf877d2469147ba818187a3e57a00b3f73b123Chris Lattner};
10631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1064b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaCommentHandler - "\#pragma comment ...".
1065636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattnerstruct PragmaCommentHandler : public PragmaHandler {
10669b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaCommentHandler() : PragmaHandler("comment") {}
106780c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
106880c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                            Token &CommentTok) {
1069636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner    PP.HandlePragmaComment(CommentTok);
1070636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner  }
1071636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner};
10721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1073b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaIncludeAliasHandler - "\#pragma include_alias("...")".
10744c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballmanstruct PragmaIncludeAliasHandler : public PragmaHandler {
10754c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  PragmaIncludeAliasHandler() : PragmaHandler("include_alias") {}
10764c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
10774c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman                            Token &IncludeAliasTok) {
10784c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      PP.HandlePragmaIncludeAlias(IncludeAliasTok);
10794c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
10804c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman};
10814c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
1082076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// PragmaMessageHandler - Handle the microsoft and gcc \#pragma message
1083076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// extension.  The syntax is:
1084076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// \code
1085076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs///   #pragma message(string)
1086076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// \endcode
1087076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// OR, in GCC mode:
1088076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// \code
1089076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs///   #pragma message string
1090076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// \endcode
1091076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// string is a string, which is fully macro expanded, and permits string
1092076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// concatenation, embedded escape characters, etc... See MSDN for more details.
1093076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// Also handles \#pragma GCC warning and \#pragma GCC error which take the same
1094076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs/// form as \#pragma message.
1095abfe094ce71c42656dcb84a3bdc3e79cb3c16fc3Chris Lattnerstruct PragmaMessageHandler : public PragmaHandler {
1096076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbsprivate:
1097076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  const PPCallbacks::PragmaMessageKind Kind;
1098076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  const StringRef Namespace;
1099076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1100076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  static const char* PragmaKind(PPCallbacks::PragmaMessageKind Kind,
1101076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                                bool PragmaNameOnly = false) {
1102076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    switch (Kind) {
1103076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      case PPCallbacks::PMK_Message:
1104076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs        return PragmaNameOnly ? "message" : "pragma message";
1105076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      case PPCallbacks::PMK_Warning:
1106076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs        return PragmaNameOnly ? "warning" : "pragma warning";
1107076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      case PPCallbacks::PMK_Error:
1108076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs        return PragmaNameOnly ? "error" : "pragma error";
1109076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    }
1110076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    llvm_unreachable("Unknown PragmaMessageKind!");
1111076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  }
1112076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1113076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbspublic:
1114076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  PragmaMessageHandler(PPCallbacks::PragmaMessageKind Kind,
1115076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                       StringRef Namespace = StringRef())
1116076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    : PragmaHandler(PragmaKind(Kind, true)), Kind(Kind), Namespace(Namespace) {}
1117076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
111880c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1119076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                            Token &Tok) {
1120076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    SourceLocation MessageLoc = Tok.getLocation();
1121076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    PP.Lex(Tok);
1122076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    bool ExpectClosingParen = false;
1123076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    switch (Tok.getKind()) {
1124076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    case tok::l_paren:
1125076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      // We have a MSVC style pragma message.
1126076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      ExpectClosingParen = true;
1127076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      // Read the string.
1128076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      PP.Lex(Tok);
1129076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      break;
1130076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    case tok::string_literal:
1131076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      // We have a GCC style pragma message, and we just read the string.
1132076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      break;
1133076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    default:
1134076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      PP.Diag(MessageLoc, diag::err_pragma_message_malformed) << Kind;
1135076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      return;
1136076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    }
1137076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1138076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    std::string MessageString;
1139076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    if (!PP.FinishLexStringLiteral(Tok, MessageString, PragmaKind(Kind),
1140076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                                   /*MacroExpansion=*/true))
1141076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      return;
1142076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1143076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    if (ExpectClosingParen) {
1144076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      if (Tok.isNot(tok::r_paren)) {
1145076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs        PP.Diag(Tok.getLocation(), diag::err_pragma_message_malformed) << Kind;
1146076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs        return;
1147076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      }
1148076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      PP.Lex(Tok);  // eat the r_paren.
1149076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    }
1150076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1151076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    if (Tok.isNot(tok::eod)) {
1152076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      PP.Diag(Tok.getLocation(), diag::err_pragma_message_malformed) << Kind;
1153076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      return;
1154076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    }
1155076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1156076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    // Output the message.
1157076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    PP.Diag(MessageLoc, (Kind == PPCallbacks::PMK_Error)
1158076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                          ? diag::err_pragma_message
1159076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                          : diag::warn_pragma_message) << MessageString;
1160076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs
1161076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    // If the pragma is lexically sound, notify any interested PPCallbacks.
1162076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs    if (PPCallbacks *Callbacks = PP.getPPCallbacks())
1163076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs      Callbacks->PragmaMessage(MessageLoc, Namespace, Kind, MessageString);
1164abfe094ce71c42656dcb84a3bdc3e79cb3c16fc3Chris Lattner  }
1165abfe094ce71c42656dcb84a3bdc3e79cb3c16fc3Chris Lattner};
1166abfe094ce71c42656dcb84a3bdc3e79cb3c16fc3Chris Lattner
1167b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaPushMacroHandler - "\#pragma push_macro" saves the value of the
1168f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner/// macro on the top of the stack.
1169f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattnerstruct PragmaPushMacroHandler : public PragmaHandler {
1170f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  PragmaPushMacroHandler() : PragmaHandler("push_macro") {}
117180c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
117280c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                            Token &PushMacroTok) {
1173f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    PP.HandlePragmaPushMacro(PushMacroTok);
1174f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
1175f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner};
1176f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
1177f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
1178b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaPopMacroHandler - "\#pragma pop_macro" sets the value of the
1179f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner/// macro to the value on the top of the stack.
1180f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattnerstruct PragmaPopMacroHandler : public PragmaHandler {
1181f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  PragmaPopMacroHandler() : PragmaHandler("pop_macro") {}
118280c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
118380c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                            Token &PopMacroTok) {
1184f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner    PP.HandlePragmaPopMacro(PopMacroTok);
1185f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  }
1186f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner};
1187f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner
1188062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner// Pragma STDC implementations.
11896c5cf4a2e234923ab66127de0874a71cb6bfdd83Chris Lattner
1190b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaSTDC_FENV_ACCESSHandler - "\#pragma STDC FENV_ACCESS ...".
1191062f23246510393c19b537b68ec88b6a08ee8996Chris Lattnerstruct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler {
11929b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaSTDC_FENV_ACCESSHandler() : PragmaHandler("FENV_ACCESS") {}
119380c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
119480c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                            Token &Tok) {
11959d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    tok::OnOffSwitch OOS;
11969d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    if (PP.LexOnOffSwitch(OOS))
11979d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne     return;
11989d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    if (OOS == tok::OOS_ON)
11994d8aac3778b40c161bed9964125948ee01c08821Chris Lattner      PP.Diag(Tok, diag::warn_stdc_fenv_access_not_supported);
1200062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner  }
1201062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner};
12021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1203b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaSTDC_CX_LIMITED_RANGEHandler - "\#pragma STDC CX_LIMITED_RANGE ...".
1204062f23246510393c19b537b68ec88b6a08ee8996Chris Lattnerstruct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler {
12059b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaSTDC_CX_LIMITED_RANGEHandler()
12069b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis    : PragmaHandler("CX_LIMITED_RANGE") {}
120780c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
120880c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                            Token &Tok) {
12099d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    tok::OnOffSwitch OOS;
12109d3f5f7550a2fab4178ed01425758c349b73a609Peter Collingbourne    PP.LexOnOffSwitch(OOS);
1211062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner  }
1212062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner};
12131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1214b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// PragmaSTDC_UnknownHandler - "\#pragma STDC ...".
1215062f23246510393c19b537b68ec88b6a08ee8996Chris Lattnerstruct PragmaSTDC_UnknownHandler : public PragmaHandler {
12169b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  PragmaSTDC_UnknownHandler() {}
121780c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
121880c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                            Token &UnknownTok) {
12196c5cf4a2e234923ab66127de0874a71cb6bfdd83Chris Lattner    // C99 6.10.6p2, unknown forms are not allowed.
1220f545be5552b6fd40a4c766fbf82dab0ab5305790Chris Lattner    PP.Diag(UnknownTok, diag::ext_stdc_pragma_ignored);
1221062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner  }
1222062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner};
12231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12248dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall/// PragmaARCCFCodeAuditedHandler -
1225b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett///   \#pragma clang arc_cf_code_audited begin/end
12268dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCallstruct PragmaARCCFCodeAuditedHandler : public PragmaHandler {
12278dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  PragmaARCCFCodeAuditedHandler() : PragmaHandler("arc_cf_code_audited") {}
12288dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
12298dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall                            Token &NameTok) {
12308dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    SourceLocation Loc = NameTok.getLocation();
12318dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    bool IsBegin;
12328dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
12338dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    Token Tok;
12348dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
12358dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    // Lex the 'begin' or 'end'.
12368dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    PP.LexUnexpandedToken(Tok);
12378dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    const IdentifierInfo *BeginEnd = Tok.getIdentifierInfo();
12388dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    if (BeginEnd && BeginEnd->isStr("begin")) {
12398dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      IsBegin = true;
12408dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    } else if (BeginEnd && BeginEnd->isStr("end")) {
12418dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      IsBegin = false;
12428dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    } else {
12438dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      PP.Diag(Tok.getLocation(), diag::err_pp_arc_cf_code_audited_syntax);
12448dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      return;
12458dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    }
12468dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
12478dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    // Verify that this is followed by EOD.
12488dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    PP.LexUnexpandedToken(Tok);
12498dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    if (Tok.isNot(tok::eod))
12508dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";
12518dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
12528dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    // The start location of the active audit.
12538dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    SourceLocation BeginLoc = PP.getPragmaARCCFCodeAuditedLoc();
12548dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
12558dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    // The start location we want after processing this.
12568dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    SourceLocation NewLoc;
12578dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
12588dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    if (IsBegin) {
12598dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      // Complain about attempts to re-enter an audit.
12608dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      if (BeginLoc.isValid()) {
12618dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall        PP.Diag(Loc, diag::err_pp_double_begin_of_arc_cf_code_audited);
12628dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall        PP.Diag(BeginLoc, diag::note_pragma_entered_here);
12638dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      }
12648dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      NewLoc = Loc;
12658dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    } else {
12668dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      // Complain about attempts to leave an audit that doesn't exist.
12678dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      if (!BeginLoc.isValid()) {
12688dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall        PP.Diag(Loc, diag::err_pp_unmatched_end_of_arc_cf_code_audited);
12698dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall        return;
12708dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      }
12718dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      NewLoc = SourceLocation();
12728dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    }
12738dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
12748dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    PP.setPragmaARCCFCodeAuditedLoc(NewLoc);
12758dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
12768dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall};
12778dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
1278fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman  /// \brief Handle "\#pragma region [...]"
1279fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman  ///
1280fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman  /// The syntax is
1281fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman  /// \code
1282e74dc199e95cc523c8806e0de41d8814e8bc5c42Dmitri Gribenko  ///   #pragma region [optional name]
1283e74dc199e95cc523c8806e0de41d8814e8bc5c42Dmitri Gribenko  ///   #pragma endregion [optional comment]
1284fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman  /// \endcode
1285fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman  ///
1286fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman  /// \note This is
1287fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman  /// <a href="http://msdn.microsoft.com/en-us/library/b6xkz944(v=vs.80).aspx">editor-only</a>
1288fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman  /// pragma, just skipped by compiler.
1289fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman  struct PragmaRegionHandler : public PragmaHandler {
1290fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman    PragmaRegionHandler(const char *pragma) : PragmaHandler(pragma) { }
1291fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman
1292fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman    virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
1293fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman                              Token &NameTok) {
1294fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman      // #pragma region: endregion matches can be verified
1295fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman      // __pragma(region): no sense, but ignored by msvc
1296fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman      // _Pragma is not valid for MSVC, but there isn't any point
1297fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman      // to handle a _Pragma differently.
1298fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman    }
1299fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman  };
1300fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman
13015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}  // end anonymous namespace
13025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
13035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
13045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// RegisterBuiltinPragmas - Install the standard preprocessor pragmas:
1305b6e95b7752893f66e9d067b4287dff2dbf4a5802James Dennett/// \#pragma GCC poison/system_header/dependency and \#pragma once.
13065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid Preprocessor::RegisterBuiltinPragmas() {
13079b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler(new PragmaOnceHandler());
13089b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler(new PragmaMarkHandler());
1309f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  AddPragmaHandler(new PragmaPushMacroHandler());
1310f47724bf78299c7a50f008e0443c5f9f9f279ddcChris Lattner  AddPragmaHandler(new PragmaPopMacroHandler());
1311076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  AddPragmaHandler(new PragmaMessageHandler(PPCallbacks::PMK_Message));
13121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1313e8fa06e07363b6d5e6c371bbd454d51bab78d01dChris Lattner  // #pragma GCC ...
13149b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("GCC", new PragmaPoisonHandler());
13159b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("GCC", new PragmaSystemHeaderHandler());
13169b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("GCC", new PragmaDependencyHandler());
1317c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor  AddPragmaHandler("GCC", new PragmaDiagnosticHandler("GCC"));
1318076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  AddPragmaHandler("GCC", new PragmaMessageHandler(PPCallbacks::PMK_Warning,
1319076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                                                   "GCC"));
1320076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs  AddPragmaHandler("GCC", new PragmaMessageHandler(PPCallbacks::PMK_Error,
1321076eea20b80024fc63bbd71fb019375983680ea6Andy Gibbs                                                   "GCC"));
1322e8fa06e07363b6d5e6c371bbd454d51bab78d01dChris Lattner  // #pragma clang ...
13239b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("clang", new PragmaPoisonHandler());
13249b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("clang", new PragmaSystemHeaderHandler());
1325abf7b72a965efba4a5ac6f85c66d5aba0c83f972Daniel Dunbar  AddPragmaHandler("clang", new PragmaDebugHandler());
13269b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("clang", new PragmaDependencyHandler());
1327c09ce1224dedc470fce9747e5936ff83cc6762ebDouglas Gregor  AddPragmaHandler("clang", new PragmaDiagnosticHandler("clang"));
13288dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  AddPragmaHandler("clang", new PragmaARCCFCodeAuditedHandler());
13299b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis
13309b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("STDC", new PragmaSTDC_FENV_ACCESSHandler());
13319b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis  AddPragmaHandler("STDC", new PragmaSTDC_CX_LIMITED_RANGEHandler());
1332062f23246510393c19b537b68ec88b6a08ee8996Chris Lattner  AddPragmaHandler("STDC", new PragmaSTDC_UnknownHandler());
13331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1334636c5ef6572e899d36cec1b0023fb28ba65189e1Chris Lattner  // MS extensions.
13354e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (LangOpts.MicrosoftExt) {
13369b36c3f0de0105e903130bbda3c4aea7d792c0afArgyrios Kyrtzidis    AddPragmaHandler(new PragmaCommentHandler());
13374c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    AddPragmaHandler(new PragmaIncludeAliasHandler());
1338fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman    AddPragmaHandler(new PragmaRegionHandler("region"));
1339fafd101e6b557595ffbb5e9e9b47a3fc0385dc19Aaron Ballman    AddPragmaHandler(new PragmaRegionHandler("endregion"));
1340abfe094ce71c42656dcb84a3bdc3e79cb3c16fc3Chris Lattner  }
13415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1342