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