Pragma.cpp revision 99831e4677a7e2e051af636221694d60ba31fcdb
176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman//===--- Pragma.cpp - Pragma registration and handling --------------------===// 276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman// 376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman// The LLVM Compiler Infrastructure 476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman// 576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman// This file is distributed under the University of Illinois Open Source 676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman// License. See LICENSE.TXT for details. 776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman// 876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman//===----------------------------------------------------------------------===// 976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman// 1076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman// This file implements the PragmaHandler/PragmaTable interfaces and implements 1176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman// pragma related methods of the Preprocessor class. 1276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman// 1376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman//===----------------------------------------------------------------------===// 1476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include "clang/Lex/Pragma.h" 1676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include "clang/Lex/HeaderSearch.h" 1776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include "clang/Lex/LiteralSupport.h" 1876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include "clang/Lex/Preprocessor.h" 1976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include "clang/Lex/MacroInfo.h" 2076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include "clang/Lex/LexDiagnostic.h" 2176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include "clang/Basic/FileManager.h" 2276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include "clang/Basic/SourceManager.h" 2376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include "llvm/Support/CrashRecoveryContext.h" 2476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include "llvm/Support/ErrorHandling.h" 2576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <algorithm> 2676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanusing namespace clang; 2776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman// Out-of-line destructor to provide a home for the class. 2976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert AkkermanPragmaHandler::~PragmaHandler() { 3076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 3176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 3276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman//===----------------------------------------------------------------------===// 3376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman// EmptyPragmaHandler Implementation. 3476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman//===----------------------------------------------------------------------===// 3576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 3676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert AkkermanEmptyPragmaHandler::EmptyPragmaHandler() {} 3776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 3876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid EmptyPragmaHandler::HandlePragma(Preprocessor &PP, 3976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman PragmaIntroducerKind Introducer, 4076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Token &FirstToken) {} 4176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 4276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman//===----------------------------------------------------------------------===// 4376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman// PragmaNamespace Implementation. 4476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman//===----------------------------------------------------------------------===// 4576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 4676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 4776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert AkkermanPragmaNamespace::~PragmaNamespace() { 4876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (llvm::StringMap<PragmaHandler*>::iterator 4976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman I = Handlers.begin(), E = Handlers.end(); I != E; ++I) 5076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman delete I->second; 5176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 5276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 5376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// FindHandler - Check to see if there is already a handler for the 5476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// specified name. If not, return the handler for the null identifier if it 5576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// exists, otherwise return null. If IgnoreNull is true (the default) then 5676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// the null handler isn't returned on failure to match. 5776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert AkkermanPragmaHandler *PragmaNamespace::FindHandler(StringRef Name, 5876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman bool IgnoreNull) const { 5976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (PragmaHandler *Handler = Handlers.lookup(Name)) 6076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return Handler; 6176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return IgnoreNull ? 0 : Handlers.lookup(StringRef()); 6276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 6376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 6476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid PragmaNamespace::AddPragma(PragmaHandler *Handler) { 6576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman assert(!Handlers.lookup(Handler->getName()) && 6676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "A handler with this name is already registered in this namespace"); 6776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman llvm::StringMapEntry<PragmaHandler *> &Entry = 6876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Handlers.GetOrCreateValue(Handler->getName()); 6976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Entry.setValue(Handler); 7076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 7176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 7276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid PragmaNamespace::RemovePragmaHandler(PragmaHandler *Handler) { 7376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman assert(Handlers.lookup(Handler->getName()) && 7476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "Handler not registered in this namespace"); 7576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Handlers.erase(Handler->getName()); 7676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 7776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 7876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid PragmaNamespace::HandlePragma(Preprocessor &PP, 7976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman PragmaIntroducerKind Introducer, 8076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Token &Tok) { 8176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Read the 'namespace' that the directive is in, e.g. STDC. Do not macro 8276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // expand it, the user can have a STDC #define, that should not affect this. 8376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman PP.LexUnexpandedToken(Tok); 8476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 8576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Get the handler for this token. If there is no handler, ignore the pragma. 8676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman PragmaHandler *Handler 8776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman = FindHandler(Tok.getIdentifierInfo() ? Tok.getIdentifierInfo()->getName() 8876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman : StringRef(), 8976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /*IgnoreNull=*/false); 9076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Handler == 0) { 9176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman PP.Diag(Tok, diag::warn_pragma_ignored); 9276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 9376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 9476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 9576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Otherwise, pass it down. 9676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Handler->HandlePragma(PP, Introducer, Tok); 9776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 9876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 9976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman//===----------------------------------------------------------------------===// 10076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman// Preprocessor Pragma Directive Handling. 10176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman//===----------------------------------------------------------------------===// 10276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 10376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// HandlePragmaDirective - The "#pragma" directive has been parsed. Lex the 10476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// rest of the pragma, passing it to the registered pragma handlers. 10576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid Preprocessor::HandlePragmaDirective(unsigned Introducer) { 10676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ++NumPragma; 10776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 10876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Invoke the first level of pragma handlers which reads the namespace id. 10976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Token Tok; 11076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman PragmaHandlers->HandlePragma(*this, PragmaIntroducerKind(Introducer), Tok); 11176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 11276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // If the pragma handler didn't read the rest of the line, consume it now. 11376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((CurTokenLexer && CurTokenLexer->isParsingPreprocessorDirective()) 11476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman || (CurPPLexer && CurPPLexer->ParsingPreprocessorDirective)) 11576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman DiscardUntilEndOfDirective(); 11676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 11776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 11876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// Handle_Pragma - Read a _Pragma directive, slice it up, process it, then 11976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// return the first token after the directive. The _Pragma token has just 12076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// been read into 'Tok'. 12176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid Preprocessor::Handle_Pragma(Token &Tok) { 12276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Remember the pragma token location. 12376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman SourceLocation PragmaLoc = Tok.getLocation(); 12476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 12576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Read the '('. 12676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(Tok); 12776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.isNot(tok::l_paren)) { 12876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(PragmaLoc, diag::err__Pragma_malformed); 12976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 13076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 13176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 13276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Read the '"..."'. 13376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(Tok); 13476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.isNot(tok::string_literal) && Tok.isNot(tok::wide_string_literal)) { 13576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(PragmaLoc, diag::err__Pragma_malformed); 13676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Skip this token, and the ')', if present. 13776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.isNot(tok::r_paren)) 13876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(Tok); 13976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.is(tok::r_paren)) 14076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(Tok); 14176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 14276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 14376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 14476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.hasUDSuffix()) { 14576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(Tok, diag::err_invalid_string_udl); 14676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Skip this token, and the ')', if present. 14776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(Tok); 14876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.is(tok::r_paren)) 14976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(Tok); 15076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 15176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 15276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 15376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Remember the string. 15476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman std::string StrVal = getSpelling(Tok); 15576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 15676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Read the ')'. 15776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(Tok); 15876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.isNot(tok::r_paren)) { 15976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(PragmaLoc, diag::err__Pragma_malformed); 16076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 16176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 16276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman SourceLocation RParenLoc = Tok.getLocation(); 16476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // The _Pragma is lexically sound. Destringize according to C99 6.10.9.1: 16676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // "The string literal is destringized by deleting the L prefix, if present, 16776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // deleting the leading and trailing double-quotes, replacing each escape 16876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // sequence \" by a double-quote, and replacing each escape sequence \\ by a 16976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // single backslash." 17076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (StrVal[0] == 'L') // Remove L prefix. 17176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman StrVal.erase(StrVal.begin()); 17276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' && 17376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "Invalid string token!"); 17476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 17576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Remove the front quote, replacing it with a space, so that the pragma 17676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // contents appear to have a space before them. 17776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman StrVal[0] = ' '; 17876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 17976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Replace the terminating quote with a \n. 18076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman StrVal[StrVal.size()-1] = '\n'; 18176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 18276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Remove escaped quotes and escapes. 18376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (unsigned i = 0, e = StrVal.size(); i != e-1; ++i) { 18476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (StrVal[i] == '\\' && 18576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (StrVal[i+1] == '\\' || StrVal[i+1] == '"')) { 18676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // \\ -> '\' and \" -> '"'. 18776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman StrVal.erase(StrVal.begin()+i); 18876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman --e; 18976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 19076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 19176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 19276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Plop the string (including the newline and trailing null) into a buffer 19376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // where we can lex it. 19476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Token TmpTok; 19576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman TmpTok.startToken(); 19676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman CreateString(&StrVal[0], StrVal.size(), TmpTok); 19776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman SourceLocation TokLoc = TmpTok.getLocation(); 19876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 19976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Make and enter a lexer object so that we lex and expand the tokens just 20076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // like any others. 20176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lexer *TL = Lexer::Create_PragmaLexer(TokLoc, PragmaLoc, RParenLoc, 20276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman StrVal.size(), *this); 20376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 20476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman EnterSourceFileWithLexer(TL, 0); 20576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 20676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // With everything set up, lex this as a #pragma directive. 20776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman HandlePragmaDirective(PIK__Pragma); 20876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 20976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Finally, return whatever came after the pragma directive. 21076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return Lex(Tok); 21176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 21276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 21376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// HandleMicrosoft__pragma - Like Handle_Pragma except the pragma text 21476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// is not enclosed within a string literal. 21576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid Preprocessor::HandleMicrosoft__pragma(Token &Tok) { 21676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Remember the pragma token location. 21776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman SourceLocation PragmaLoc = Tok.getLocation(); 21876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 21976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Read the '('. 22076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(Tok); 22176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.isNot(tok::l_paren)) { 22276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(PragmaLoc, diag::err__Pragma_malformed); 22376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 22476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 22576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 22676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Get the tokens enclosed within the __pragma(), as well as the final ')'. 22776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman SmallVector<Token, 32> PragmaToks; 22876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int NumParens = 0; 22976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(Tok); 23076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (Tok.isNot(tok::eof)) { 23176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman PragmaToks.push_back(Tok); 23276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.is(tok::l_paren)) 23376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman NumParens++; 23476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (Tok.is(tok::r_paren) && NumParens-- == 0) 23576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 23676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(Tok); 23776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 23876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 23976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.is(tok::eof)) { 24076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(PragmaLoc, diag::err_unterminated___pragma); 24176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 24276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 24376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 24476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman PragmaToks.front().setFlag(Token::LeadingSpace); 24576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 24676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Replace the ')' with an EOD to mark the end of the pragma. 24776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman PragmaToks.back().setKind(tok::eod); 24876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 24976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Token *TokArray = new Token[PragmaToks.size()]; 25076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman std::copy(PragmaToks.begin(), PragmaToks.end(), TokArray); 25176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 25276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Push the tokens onto the stack. 25376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman EnterTokenStream(TokArray, PragmaToks.size(), true, true); 25476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 25576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // With everything set up, lex this as a #pragma directive. 25676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman HandlePragmaDirective(PIK___pragma); 25776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 25876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Finally, return whatever came after the pragma directive. 25976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return Lex(Tok); 26076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 26176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 26276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// HandlePragmaOnce - Handle #pragma once. OnceTok is the 'once'. 26376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// 26476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid Preprocessor::HandlePragmaOnce(Token &OnceTok) { 26576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (isInPrimaryFile()) { 26676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(OnceTok, diag::pp_pragma_once_in_main_file); 26776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 26876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 26976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 27076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Get the current file lexer we're looking at. Ignore _Pragma 'files' etc. 27176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Mark the file as a once-only file now. 27276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman HeaderInfo.MarkFileIncludeOnce(getCurrentFileLexer()->getFileEntry()); 27376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 27476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 27576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid Preprocessor::HandlePragmaMark() { 27676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman assert(CurPPLexer && "No current lexer?"); 27776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (CurLexer) 27876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman CurLexer->ReadToEndOfLine(); 27976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 28076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman CurPTHLexer->DiscardToEndOfLine(); 28176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 28276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 28376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 28476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// HandlePragmaPoison - Handle #pragma GCC poison. PoisonTok is the 'poison'. 28576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// 28676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid Preprocessor::HandlePragmaPoison(Token &PoisonTok) { 28776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Token Tok; 28876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 28976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (1) { 29076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Read the next token to poison. While doing this, pretend that we are 29176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // skipping while reading the identifier to poison. 29276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // This avoids errors on code like: 29376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // #pragma GCC poison X 29476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // #pragma GCC poison X 29576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (CurPPLexer) CurPPLexer->LexingRawMode = true; 29676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman LexUnexpandedToken(Tok); 29776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (CurPPLexer) CurPPLexer->LexingRawMode = false; 29876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 29976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // If we reached the end of line, we're done. 30076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.is(tok::eod)) return; 30176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 30276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Can only poison identifiers. 30376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.isNot(tok::raw_identifier)) { 30476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(Tok, diag::err_pp_invalid_poison); 30576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 30676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 30776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 30876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Look up the identifier info for the token. We disabled identifier lookup 30976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // by saying we're skipping contents, so we need to do this manually. 31076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman IdentifierInfo *II = LookUpIdentifierInfo(Tok); 31176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 31276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Already poisoned. 31376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (II->isPoisoned()) continue; 31476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 31576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // If this is a macro identifier, emit a warning. 31676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (II->hasMacroDefinition()) 31776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(Tok, diag::pp_poisoning_existing_macro); 31876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 31976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Finally, poison it! 32076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman II->setIsPoisoned(); 32176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (II->isFromAST()) 32276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman II->setChangedSinceDeserialization(); 32376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 32476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 32576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 32676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// HandlePragmaSystemHeader - Implement #pragma GCC system_header. We know 32776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// that the whole directive has been parsed. 32876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) { 32976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (isInPrimaryFile()) { 33076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file); 33176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 33276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 33376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 33476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Get the current file lexer we're looking at. Ignore _Pragma 'files' etc. 33576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman PreprocessorLexer *TheLexer = getCurrentFileLexer(); 33676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 33776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Mark the file as a system header. 33876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman HeaderInfo.MarkFileSystemHeader(TheLexer->getFileEntry()); 33976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 34076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 34176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman PresumedLoc PLoc = SourceMgr.getPresumedLoc(SysHeaderTok.getLocation()); 34276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (PLoc.isInvalid()) 34376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 34476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 34576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman unsigned FilenameID = SourceMgr.getLineTableFilenameID(PLoc.getFilename()); 34676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 34776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Notify the client, if desired, that we are in a new source file. 34876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Callbacks) 34976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Callbacks->FileChanged(SysHeaderTok.getLocation(), 35076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman PPCallbacks::SystemHeaderPragma, SrcMgr::C_System); 35176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 35276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Emit a line marker. This will change any source locations from this point 35376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // forward to realize they are in a system header. 35476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Create a line note with this information. 35576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman SourceMgr.AddLineNote(SysHeaderTok.getLocation(), PLoc.getLine(), FilenameID, 35676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman false, false, true, false); 35776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 3586bfcd3287759af376cfcc7670da3f048261fab90Nate Sammons 35976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// HandlePragmaDependency - Handle #pragma GCC dependency "foo" blah. 36076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// 36176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid Preprocessor::HandlePragmaDependency(Token &DependencyTok) { 36276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Token FilenameTok; 36376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman CurPPLexer->LexIncludeFilename(FilenameTok); 36476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 36576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // If the token kind is EOD, the error has already been diagnosed. 36676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (FilenameTok.is(tok::eod)) 36776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 36876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 36976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Reserve a buffer to get the spelling. 37076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman SmallString<128> FilenameBuffer; 37176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman bool Invalid = false; 37276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman StringRef Filename = getSpelling(FilenameTok, FilenameBuffer, &Invalid); 37376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Invalid) 37476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 37576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 37676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman bool isAngled = 37776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman GetIncludeFilenameSpelling(FilenameTok.getLocation(), Filename); 37876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // If GetIncludeFilenameSpelling set the start ptr to null, there was an 37976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // error. 38076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Filename.empty()) 38176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 38276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 38376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Search include directories for this file. 38476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman const DirectoryLookup *CurDir; 38576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman const FileEntry *File = LookupFile(Filename, isAngled, 0, CurDir, NULL, NULL, 38676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman NULL); 3872e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman if (File == 0) { 3882e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman if (!SuppressIncludeNotFoundError) 3892e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman Diag(FilenameTok, diag::err_pp_file_not_found) << Filename; 3902e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman return; 3912e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman } 3922e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman 3932e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman const FileEntry *CurFile = getCurrentFileLexer()->getFileEntry(); 3942e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman 39576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // If this file is older than the file it depends on, emit a diagnostic. 39676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (CurFile && CurFile->getModificationTime() < File->getModificationTime()) { 39776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Lex tokens at the end of the message and include them in the message. 39876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman std::string Message; 39976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(DependencyTok); 40076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (DependencyTok.isNot(tok::eod)) { 40176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Message += getSpelling(DependencyTok) + " "; 40276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(DependencyTok); 40376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 40476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 40576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Remove the trailing ' ' if present. 40676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!Message.empty()) 40776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Message.erase(Message.end()-1); 40876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(FilenameTok, diag::pp_out_of_date_dependency) << Message; 40976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 41076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 41176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 41276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// HandlePragmaComment - Handle the microsoft #pragma comment extension. The 41376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// syntax is: 41476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// #pragma comment(linker, "foo") 41576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// 'linker' is one of five identifiers: compiler, exestr, lib, linker, user. 41676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// "foo" is a string, which is fully macro expanded, and permits string 41776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// concatenation, embedded escape characters etc. See MSDN for more details. 41876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid Preprocessor::HandlePragmaComment(Token &Tok) { 41976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman SourceLocation CommentLoc = Tok.getLocation(); 42076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(Tok); 42176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.isNot(tok::l_paren)) { 42276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(CommentLoc, diag::err_pragma_comment_malformed); 42376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 42476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 42576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 42676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Read the identifier. 42776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(Tok); 42876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.isNot(tok::identifier)) { 42976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(CommentLoc, diag::err_pragma_comment_malformed); 43076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 43176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 43276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 43376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Verify that this is one of the 5 whitelisted options. 43476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // FIXME: warn that 'exestr' is deprecated. 43576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman const IdentifierInfo *II = Tok.getIdentifierInfo(); 43676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!II->isStr("compiler") && !II->isStr("exestr") && !II->isStr("lib") && 43776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman !II->isStr("linker") && !II->isStr("user")) { 43876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind); 43976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 44076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 44176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 44276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Read the optional string if present. 44376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(Tok); 44476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman std::string ArgumentString; 44576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.is(tok::comma)) { 44676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(Tok); // eat the comma. 44776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 44876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // We need at least one string. 44976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.isNot(tok::string_literal)) { 45076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(Tok.getLocation(), diag::err_pragma_comment_malformed); 45176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 45276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 45376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 45476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // String concatenation allows multiple strings, which can even come from 45576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // macro expansion. 45676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // "foo " "bar" "Baz" 45776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman SmallVector<Token, 4> StrToks; 45876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (Tok.is(tok::string_literal)) { 45976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.hasUDSuffix()) 46076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(Tok, diag::err_invalid_string_udl); 46176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman StrToks.push_back(Tok); 46276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(Tok); 46376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 46476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 46576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Concatenate and parse the strings. 46676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman StringLiteralParser Literal(&StrToks[0], StrToks.size(), *this); 46776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman assert(Literal.isAscii() && "Didn't allow wide strings in"); 46876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Literal.hadError) 46976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 47076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Literal.Pascal) { 47176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(StrToks[0].getLocation(), diag::err_pragma_comment_malformed); 47276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 47376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 47476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 47576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ArgumentString = Literal.GetString(); 47676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 47776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 47876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // FIXME: If the kind is "compiler" warn if the string is present (it is 47976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // ignored). 48076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // FIXME: 'lib' requires a comment string. 48176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // FIXME: 'linker' requires a comment string, and has a specific list of 48276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // things that are allowable. 48376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 48476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.isNot(tok::r_paren)) { 48576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(Tok.getLocation(), diag::err_pragma_comment_malformed); 48676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 48776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 48876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(Tok); // eat the r_paren. 48976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 49076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.isNot(tok::eod)) { 49176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(Tok.getLocation(), diag::err_pragma_comment_malformed); 49276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 49376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 49476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 49576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // If the pragma is lexically sound, notify any interested PPCallbacks. 49676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Callbacks) 49776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Callbacks->PragmaComment(CommentLoc, II, ArgumentString); 49876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 49976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 50076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// HandlePragmaMessage - Handle the microsoft and gcc #pragma message 50176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// extension. The syntax is: 50276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// #pragma message(string) 50376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// OR, in GCC mode: 50476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// #pragma message string 50576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// string is a string, which is fully macro expanded, and permits string 50676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// concatenation, embedded escape characters, etc... See MSDN for more details. 50776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid Preprocessor::HandlePragmaMessage(Token &Tok) { 50876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman SourceLocation MessageLoc = Tok.getLocation(); 50976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(Tok); 51076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman bool ExpectClosingParen = false; 51176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (Tok.getKind()) { 51276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case tok::l_paren: 51376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // We have a MSVC style pragma message. 51476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ExpectClosingParen = true; 51576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Read the string. 51676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(Tok); 51776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 51876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case tok::string_literal: 51976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // We have a GCC style pragma message, and we just read the string. 52076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 52176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 52276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(MessageLoc, diag::err_pragma_message_malformed); 52376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 52476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 52576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 52676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // We need at least one string. 52776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.isNot(tok::string_literal)) { 52876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(Tok.getLocation(), diag::err_pragma_message_malformed); 52976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 53076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 53176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 53276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // String concatenation allows multiple strings, which can even come from 53376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // macro expansion. 53476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // "foo " "bar" "Baz" 53576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman SmallVector<Token, 4> StrToks; 53676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (Tok.is(tok::string_literal)) { 53776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.hasUDSuffix()) 53876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(Tok, diag::err_invalid_string_udl); 53976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman StrToks.push_back(Tok); 54076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(Tok); 54176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 54276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 54376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Concatenate and parse the strings. 54476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman StringLiteralParser Literal(&StrToks[0], StrToks.size(), *this); 54576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman assert(Literal.isAscii() && "Didn't allow wide strings in"); 54676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Literal.hadError) 54776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 54876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Literal.Pascal) { 54976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(StrToks[0].getLocation(), diag::err_pragma_message_malformed); 55076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 55176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 55276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 55376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman StringRef MessageString(Literal.GetString()); 55476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 55576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ExpectClosingParen) { 55676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.isNot(tok::r_paren)) { 55776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(Tok.getLocation(), diag::err_pragma_message_malformed); 55876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 55976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 56076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(Tok); // eat the r_paren. 56176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 56276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 56376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.isNot(tok::eod)) { 56476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(Tok.getLocation(), diag::err_pragma_message_malformed); 56576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 56676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 56776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 56876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Output the message. 56976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(MessageLoc, diag::warn_pragma_message) << MessageString; 57076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 57176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // If the pragma is lexically sound, notify any interested PPCallbacks. 57276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Callbacks) 57376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Callbacks->PragmaMessage(MessageLoc, MessageString); 57476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 57576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 57676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// ParsePragmaPushOrPopMacro - Handle parsing of pragma push_macro/pop_macro. 57776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// Return the IdentifierInfo* associated with the macro to push or pop. 57876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert AkkermanIdentifierInfo *Preprocessor::ParsePragmaPushOrPopMacro(Token &Tok) { 57976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Remember the pragma token location. 58076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Token PragmaTok = Tok; 58176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 58276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Read the '('. 58376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(Tok); 58476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.isNot(tok::l_paren)) { 58576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed) 58676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman << getSpelling(PragmaTok); 58776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 58876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 58976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 59076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Read the macro name string. 59176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(Tok); 59276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.isNot(tok::string_literal)) { 59376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed) 59476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman << getSpelling(PragmaTok); 59576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 59676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 59776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 59876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.hasUDSuffix()) { 59976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(Tok, diag::err_invalid_string_udl); 60076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 60176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 60276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 60376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Remember the macro string. 60476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman std::string StrVal = getSpelling(Tok); 60576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 60676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Read the ')'. 60776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(Tok); 60876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.isNot(tok::r_paren)) { 60976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed) 61076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman << getSpelling(PragmaTok); 61176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 61276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 61376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 61476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' && 61576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "Invalid string token!"); 61676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 61776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Create a Token from the string. 61876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Token MacroTok; 61976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman MacroTok.startToken(); 62076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman MacroTok.setKind(tok::raw_identifier); 62176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman CreateString(&StrVal[1], StrVal.size() - 2, MacroTok); 62276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 62376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Get the IdentifierInfo of MacroToPushTok. 62476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return LookUpIdentifierInfo(MacroTok); 62576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 62676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 62776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// HandlePragmaPushMacro - Handle #pragma push_macro. 62876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// The syntax is: 62976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// #pragma push_macro("macro") 63076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid Preprocessor::HandlePragmaPushMacro(Token &PushMacroTok) { 63176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Parse the pragma directive and get the macro IdentifierInfo*. 63276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PushMacroTok); 63376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!IdentInfo) return; 63476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 63576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Get the MacroInfo associated with IdentInfo. 63676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman MacroInfo *MI = getMacroInfo(IdentInfo); 63776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 63876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman MacroInfo *MacroCopyToPush = 0; 63976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (MI) { 64076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Make a clone of MI. 64176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman MacroCopyToPush = CloneMacroInfo(*MI); 64276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 64376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Allow the original MacroInfo to be redefined later. 64476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman MI->setIsAllowRedefinitionsWithoutWarning(true); 64576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 64676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 64776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Push the cloned MacroInfo so we can retrieve it later. 64876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman PragmaPushMacroInfo[IdentInfo].push_back(MacroCopyToPush); 64976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 65076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 65176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// HandlePragmaPopMacro - Handle #pragma pop_macro. 65276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// The syntax is: 65376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// #pragma pop_macro("macro") 65476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) { 65576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman SourceLocation MessageLoc = PopMacroTok.getLocation(); 65676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 65776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Parse the pragma directive and get the macro IdentifierInfo*. 65876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PopMacroTok); 65976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!IdentInfo) return; 66076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 66176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Find the vector<MacroInfo*> associated with the macro. 66276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> >::iterator iter = 66376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman PragmaPushMacroInfo.find(IdentInfo); 66476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (iter != PragmaPushMacroInfo.end()) { 66576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Release the MacroInfo currently associated with IdentInfo. 66676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman MacroInfo *CurrentMI = getMacroInfo(IdentInfo); 66776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (CurrentMI) { 66876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (CurrentMI->isWarnIfUnused()) 66976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman WarnUnusedMacroLocs.erase(CurrentMI->getDefinitionLoc()); 67076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ReleaseMacroInfo(CurrentMI); 67176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 67276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 67376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Get the MacroInfo we want to reinstall. 67476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman MacroInfo *MacroToReInstall = iter->second.back(); 67576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 67676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Reinstall the previously pushed macro. 67776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman setMacroInfo(IdentInfo, MacroToReInstall); 67876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 67976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Pop PragmaPushMacroInfo stack. 68076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman iter->second.pop_back(); 6815daa028ca314e4c36c1f38e0149834d9a0520128Wichert Akkerman if (iter->second.size() == 0) 68276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman PragmaPushMacroInfo.erase(iter); 68376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } else { 68476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(MessageLoc, diag::warn_pragma_pop_macro_no_push) 68576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman << IdentInfo->getName(); 68676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 68776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 68876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 68976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid Preprocessor::HandlePragmaIncludeAlias(Token &Tok) { 69076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // We will either get a quoted filename or a bracketed filename, and we 69176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // have to track which we got. The first filename is the source name, 69276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // and the second name is the mapped filename. If the first is quoted, 69376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // the second must be as well (cannot mix and match quotes and brackets). 69476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 69576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Get the open paren 69676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(Tok); 69776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.isNot(tok::l_paren)) { 69876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(Tok, diag::warn_pragma_include_alias_expected) << "("; 69976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 70076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 70176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 70276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // We expect either a quoted string literal, or a bracketed name 70376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Token SourceFilenameTok; 70476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman CurPPLexer->LexIncludeFilename(SourceFilenameTok); 70576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (SourceFilenameTok.is(tok::eod)) { 70676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // The diagnostic has already been handled 70776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 70876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 70976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 71076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman StringRef SourceFileName; 71176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman SmallString<128> FileNameBuffer; 71276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (SourceFilenameTok.is(tok::string_literal) || 71376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman SourceFilenameTok.is(tok::angle_string_literal)) { 7142e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman SourceFileName = getSpelling(SourceFilenameTok, FileNameBuffer); 71576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } else if (SourceFilenameTok.is(tok::less)) { 71676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // This could be a path instead of just a name 71776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman FileNameBuffer.push_back('<'); 71876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman SourceLocation End; 7192e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman if (ConcatenateIncludeName(FileNameBuffer, End)) 72076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; // Diagnostic already emitted 72176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman SourceFileName = FileNameBuffer.str(); 72276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } else { 72376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(Tok, diag::warn_pragma_include_alias_expected_filename); 7242e2553a534f532a1546ea2b2f3dc3cd2276d020dWichert Akkerman return; 72576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 72676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman FileNameBuffer.clear(); 72776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 72876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Now we expect a comma, followed by another include name 72976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(Tok); 73076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.isNot(tok::comma)) { 73176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(Tok, diag::warn_pragma_include_alias_expected) << ","; 73276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 73376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 73476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 73576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Token ReplaceFilenameTok; 73676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman CurPPLexer->LexIncludeFilename(ReplaceFilenameTok); 73776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ReplaceFilenameTok.is(tok::eod)) { 73876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // The diagnostic has already been handled 73976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 74076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 74176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 74276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman StringRef ReplaceFileName; 74376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ReplaceFilenameTok.is(tok::string_literal) || 74476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ReplaceFilenameTok.is(tok::angle_string_literal)) { 74576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ReplaceFileName = getSpelling(ReplaceFilenameTok, FileNameBuffer); 74676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } else if (ReplaceFilenameTok.is(tok::less)) { 74776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // This could be a path instead of just a name 74876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman FileNameBuffer.push_back('<'); 74976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman SourceLocation End; 75076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ConcatenateIncludeName(FileNameBuffer, End)) 75176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; // Diagnostic already emitted 75276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ReplaceFileName = FileNameBuffer.str(); 75376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } else { 75476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(Tok, diag::warn_pragma_include_alias_expected_filename); 75576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 75676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 75776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 75876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Finally, we expect the closing paren 75976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Lex(Tok); 76076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (Tok.isNot(tok::r_paren)) { 76176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(Tok, diag::warn_pragma_include_alias_expected) << ")"; 76276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 76376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 76476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 76576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Now that we have the source and target filenames, we need to make sure 76676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // they're both of the same type (angled vs non-angled) 76776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman StringRef OriginalSource = SourceFileName; 76876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 76976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman bool SourceIsAngled = 77076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman GetIncludeFilenameSpelling(SourceFilenameTok.getLocation(), 77176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman SourceFileName); 77276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman bool ReplaceIsAngled = 77376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman GetIncludeFilenameSpelling(ReplaceFilenameTok.getLocation(), 77476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ReplaceFileName); 77576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!SourceFileName.empty() && !ReplaceFileName.empty() && 77676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (SourceIsAngled != ReplaceIsAngled)) { 77776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman unsigned int DiagID; 77876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (SourceIsAngled) 77976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman DiagID = diag::warn_pragma_include_alias_mismatch_angle; 78076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 78176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman DiagID = diag::warn_pragma_include_alias_mismatch_quote; 78276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 78376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman Diag(SourceFilenameTok.getLocation(), DiagID) 78476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman << SourceFileName 78576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman << ReplaceFileName; 78676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 78776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 78876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 78976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 79076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Now we can let the include handler know about this mapping 79176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman getHeaderSearchInfo().AddIncludeAlias(OriginalSource, ReplaceFileName); 79276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 79376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 79476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// AddPragmaHandler - Add the specified pragma handler to the preprocessor. 79576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// If 'Namespace' is non-null, then it is a token required to exist on the 79676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// pragma line before the pragma string starts, e.g. "STDC" or "GCC". 79776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid Preprocessor::AddPragmaHandler(StringRef Namespace, 79876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman PragmaHandler *Handler) { 79976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman PragmaNamespace *InsertNS = PragmaHandlers; 80076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 80176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // If this is specified to be in a namespace, step down into it. 80276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!Namespace.empty()) { 80376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // If there is already a pragma handler with the name of this namespace, 80476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // we either have an error (directive with the same name as a namespace) or 80576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // we already have the namespace to insert into. 80676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace)) { 80776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman InsertNS = Existing->getIfNamespace(); 80876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman assert(InsertNS != 0 && "Cannot have a pragma namespace and pragma" 80976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman " handler with the same name!"); 81076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } else { 81176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Otherwise, this namespace doesn't exist yet, create and insert the 81276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // handler for it. 81376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman InsertNS = new PragmaNamespace(Namespace); 81476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman PragmaHandlers->AddPragma(InsertNS); 81576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 81676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 81776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 81876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // Check to make sure we don't already have a pragma for this identifier. 81976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman assert(!InsertNS->FindHandler(Handler->getName()) && 82076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "Pragma handler already exists for this identifier!"); 82176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman InsertNS->AddPragma(Handler); 82276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 82376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 82476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// RemovePragmaHandler - Remove the specific pragma handler from the 82576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// preprocessor. If \arg Namespace is non-null, then it should be the 82676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// namespace that \arg Handler was added to. It is an error to remove 82776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/// a handler that has not been registered. 82876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid Preprocessor::RemovePragmaHandler(StringRef Namespace, 82976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman PragmaHandler *Handler) { 83076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman PragmaNamespace *NS = PragmaHandlers; 83176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 83276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman // If this is specified to be in a namespace, step down into it. 83376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!Namespace.empty()) { 83476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace); 83576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman assert(Existing && "Namespace containing handler does not exist!"); 83676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 83776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman NS = Existing->getIfNamespace(); 83876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman assert(NS && "Invalid namespace, registered as a regular pragma handler!"); 83976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 840 841 NS->RemovePragmaHandler(Handler); 842 843 // If this is a non-default namespace and it is now empty, remove 844 // it. 845 if (NS != PragmaHandlers && NS->IsEmpty()) { 846 PragmaHandlers->RemovePragmaHandler(NS); 847 delete NS; 848 } 849} 850 851bool Preprocessor::LexOnOffSwitch(tok::OnOffSwitch &Result) { 852 Token Tok; 853 LexUnexpandedToken(Tok); 854 855 if (Tok.isNot(tok::identifier)) { 856 Diag(Tok, diag::ext_on_off_switch_syntax); 857 return true; 858 } 859 IdentifierInfo *II = Tok.getIdentifierInfo(); 860 if (II->isStr("ON")) 861 Result = tok::OOS_ON; 862 else if (II->isStr("OFF")) 863 Result = tok::OOS_OFF; 864 else if (II->isStr("DEFAULT")) 865 Result = tok::OOS_DEFAULT; 866 else { 867 Diag(Tok, diag::ext_on_off_switch_syntax); 868 return true; 869 } 870 871 // Verify that this is followed by EOD. 872 LexUnexpandedToken(Tok); 873 if (Tok.isNot(tok::eod)) 874 Diag(Tok, diag::ext_pragma_syntax_eod); 875 return false; 876} 877 878namespace { 879/// PragmaOnceHandler - "#pragma once" marks the file as atomically included. 880struct PragmaOnceHandler : public PragmaHandler { 881 PragmaOnceHandler() : PragmaHandler("once") {} 882 virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 883 Token &OnceTok) { 884 PP.CheckEndOfDirective("pragma once"); 885 PP.HandlePragmaOnce(OnceTok); 886 } 887}; 888 889/// PragmaMarkHandler - "#pragma mark ..." is ignored by the compiler, and the 890/// rest of the line is not lexed. 891struct PragmaMarkHandler : public PragmaHandler { 892 PragmaMarkHandler() : PragmaHandler("mark") {} 893 virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 894 Token &MarkTok) { 895 PP.HandlePragmaMark(); 896 } 897}; 898 899/// PragmaPoisonHandler - "#pragma poison x" marks x as not usable. 900struct PragmaPoisonHandler : public PragmaHandler { 901 PragmaPoisonHandler() : PragmaHandler("poison") {} 902 virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 903 Token &PoisonTok) { 904 PP.HandlePragmaPoison(PoisonTok); 905 } 906}; 907 908/// PragmaSystemHeaderHandler - "#pragma system_header" marks the current file 909/// as a system header, which silences warnings in it. 910struct PragmaSystemHeaderHandler : public PragmaHandler { 911 PragmaSystemHeaderHandler() : PragmaHandler("system_header") {} 912 virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 913 Token &SHToken) { 914 PP.HandlePragmaSystemHeader(SHToken); 915 PP.CheckEndOfDirective("pragma"); 916 } 917}; 918struct PragmaDependencyHandler : public PragmaHandler { 919 PragmaDependencyHandler() : PragmaHandler("dependency") {} 920 virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 921 Token &DepToken) { 922 PP.HandlePragmaDependency(DepToken); 923 } 924}; 925 926struct PragmaDebugHandler : public PragmaHandler { 927 PragmaDebugHandler() : PragmaHandler("__debug") {} 928 virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 929 Token &DepToken) { 930 Token Tok; 931 PP.LexUnexpandedToken(Tok); 932 if (Tok.isNot(tok::identifier)) { 933 PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid); 934 return; 935 } 936 IdentifierInfo *II = Tok.getIdentifierInfo(); 937 938 if (II->isStr("assert")) { 939 llvm_unreachable("This is an assertion!"); 940 } else if (II->isStr("crash")) { 941 *(volatile int*) 0x11 = 0; 942 } else if (II->isStr("llvm_fatal_error")) { 943 llvm::report_fatal_error("#pragma clang __debug llvm_fatal_error"); 944 } else if (II->isStr("llvm_unreachable")) { 945 llvm_unreachable("#pragma clang __debug llvm_unreachable"); 946 } else if (II->isStr("overflow_stack")) { 947 DebugOverflowStack(); 948 } else if (II->isStr("handle_crash")) { 949 llvm::CrashRecoveryContext *CRC =llvm::CrashRecoveryContext::GetCurrent(); 950 if (CRC) 951 CRC->HandleCrash(); 952 } else { 953 PP.Diag(Tok, diag::warn_pragma_debug_unexpected_command) 954 << II->getName(); 955 } 956 } 957 958// Disable MSVC warning about runtime stack overflow. 959#ifdef _MSC_VER 960 #pragma warning(disable : 4717) 961#endif 962 void DebugOverflowStack() { 963 DebugOverflowStack(); 964 } 965#ifdef _MSC_VER 966 #pragma warning(default : 4717) 967#endif 968 969}; 970 971/// PragmaDiagnosticHandler - e.g. '#pragma GCC diagnostic ignored "-Wformat"' 972struct PragmaDiagnosticHandler : public PragmaHandler { 973private: 974 const char *Namespace; 975public: 976 explicit PragmaDiagnosticHandler(const char *NS) : 977 PragmaHandler("diagnostic"), Namespace(NS) {} 978 virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 979 Token &DiagToken) { 980 SourceLocation DiagLoc = DiagToken.getLocation(); 981 Token Tok; 982 PP.LexUnexpandedToken(Tok); 983 if (Tok.isNot(tok::identifier)) { 984 PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid); 985 return; 986 } 987 IdentifierInfo *II = Tok.getIdentifierInfo(); 988 PPCallbacks *Callbacks = PP.getPPCallbacks(); 989 990 diag::Mapping Map; 991 if (II->isStr("warning")) 992 Map = diag::MAP_WARNING; 993 else if (II->isStr("error")) 994 Map = diag::MAP_ERROR; 995 else if (II->isStr("ignored")) 996 Map = diag::MAP_IGNORE; 997 else if (II->isStr("fatal")) 998 Map = diag::MAP_FATAL; 999 else if (II->isStr("pop")) { 1000 if (!PP.getDiagnostics().popMappings(DiagLoc)) 1001 PP.Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop); 1002 else if (Callbacks) 1003 Callbacks->PragmaDiagnosticPop(DiagLoc, Namespace); 1004 return; 1005 } else if (II->isStr("push")) { 1006 PP.getDiagnostics().pushMappings(DiagLoc); 1007 if (Callbacks) 1008 Callbacks->PragmaDiagnosticPush(DiagLoc, Namespace); 1009 return; 1010 } else { 1011 PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid); 1012 return; 1013 } 1014 1015 PP.LexUnexpandedToken(Tok); 1016 1017 // We need at least one string. 1018 if (Tok.isNot(tok::string_literal)) { 1019 PP.Diag(Tok.getLocation(), diag::warn_pragma_diagnostic_invalid_token); 1020 return; 1021 } 1022 1023 // String concatenation allows multiple strings, which can even come from 1024 // macro expansion. 1025 // "foo " "bar" "Baz" 1026 SmallVector<Token, 4> StrToks; 1027 while (Tok.is(tok::string_literal)) { 1028 StrToks.push_back(Tok); 1029 PP.LexUnexpandedToken(Tok); 1030 } 1031 1032 if (Tok.isNot(tok::eod)) { 1033 PP.Diag(Tok.getLocation(), diag::warn_pragma_diagnostic_invalid_token); 1034 return; 1035 } 1036 1037 // Concatenate and parse the strings. 1038 StringLiteralParser Literal(&StrToks[0], StrToks.size(), PP); 1039 assert(Literal.isAscii() && "Didn't allow wide strings in"); 1040 if (Literal.hadError) 1041 return; 1042 if (Literal.Pascal) { 1043 PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid); 1044 return; 1045 } 1046 1047 StringRef WarningName(Literal.GetString()); 1048 1049 if (WarningName.size() < 3 || WarningName[0] != '-' || 1050 WarningName[1] != 'W') { 1051 PP.Diag(StrToks[0].getLocation(), 1052 diag::warn_pragma_diagnostic_invalid_option); 1053 return; 1054 } 1055 1056 if (PP.getDiagnostics().setDiagnosticGroupMapping(WarningName.substr(2), 1057 Map, DiagLoc)) 1058 PP.Diag(StrToks[0].getLocation(), 1059 diag::warn_pragma_diagnostic_unknown_warning) << WarningName; 1060 else if (Callbacks) 1061 Callbacks->PragmaDiagnostic(DiagLoc, Namespace, Map, WarningName); 1062 } 1063}; 1064 1065/// PragmaCommentHandler - "#pragma comment ...". 1066struct PragmaCommentHandler : public PragmaHandler { 1067 PragmaCommentHandler() : PragmaHandler("comment") {} 1068 virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 1069 Token &CommentTok) { 1070 PP.HandlePragmaComment(CommentTok); 1071 } 1072}; 1073 1074/// PragmaIncludeAliasHandler - "#pragma include_alias("...")". 1075struct PragmaIncludeAliasHandler : public PragmaHandler { 1076 PragmaIncludeAliasHandler() : PragmaHandler("include_alias") {} 1077 virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 1078 Token &IncludeAliasTok) { 1079 PP.HandlePragmaIncludeAlias(IncludeAliasTok); 1080 } 1081}; 1082 1083/// PragmaMessageHandler - "#pragma message("...")". 1084struct PragmaMessageHandler : public PragmaHandler { 1085 PragmaMessageHandler() : PragmaHandler("message") {} 1086 virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 1087 Token &CommentTok) { 1088 PP.HandlePragmaMessage(CommentTok); 1089 } 1090}; 1091 1092/// PragmaPushMacroHandler - "#pragma push_macro" saves the value of the 1093/// macro on the top of the stack. 1094struct PragmaPushMacroHandler : public PragmaHandler { 1095 PragmaPushMacroHandler() : PragmaHandler("push_macro") {} 1096 virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 1097 Token &PushMacroTok) { 1098 PP.HandlePragmaPushMacro(PushMacroTok); 1099 } 1100}; 1101 1102 1103/// PragmaPopMacroHandler - "#pragma pop_macro" sets the value of the 1104/// macro to the value on the top of the stack. 1105struct PragmaPopMacroHandler : public PragmaHandler { 1106 PragmaPopMacroHandler() : PragmaHandler("pop_macro") {} 1107 virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 1108 Token &PopMacroTok) { 1109 PP.HandlePragmaPopMacro(PopMacroTok); 1110 } 1111}; 1112 1113// Pragma STDC implementations. 1114 1115/// PragmaSTDC_FENV_ACCESSHandler - "#pragma STDC FENV_ACCESS ...". 1116struct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler { 1117 PragmaSTDC_FENV_ACCESSHandler() : PragmaHandler("FENV_ACCESS") {} 1118 virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 1119 Token &Tok) { 1120 tok::OnOffSwitch OOS; 1121 if (PP.LexOnOffSwitch(OOS)) 1122 return; 1123 if (OOS == tok::OOS_ON) 1124 PP.Diag(Tok, diag::warn_stdc_fenv_access_not_supported); 1125 } 1126}; 1127 1128/// PragmaSTDC_CX_LIMITED_RANGEHandler - "#pragma STDC CX_LIMITED_RANGE ...". 1129struct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler { 1130 PragmaSTDC_CX_LIMITED_RANGEHandler() 1131 : PragmaHandler("CX_LIMITED_RANGE") {} 1132 virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 1133 Token &Tok) { 1134 tok::OnOffSwitch OOS; 1135 PP.LexOnOffSwitch(OOS); 1136 } 1137}; 1138 1139/// PragmaSTDC_UnknownHandler - "#pragma STDC ...". 1140struct PragmaSTDC_UnknownHandler : public PragmaHandler { 1141 PragmaSTDC_UnknownHandler() {} 1142 virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 1143 Token &UnknownTok) { 1144 // C99 6.10.6p2, unknown forms are not allowed. 1145 PP.Diag(UnknownTok, diag::ext_stdc_pragma_ignored); 1146 } 1147}; 1148 1149/// PragmaARCCFCodeAuditedHandler - 1150/// #pragma clang arc_cf_code_audited begin/end 1151struct PragmaARCCFCodeAuditedHandler : public PragmaHandler { 1152 PragmaARCCFCodeAuditedHandler() : PragmaHandler("arc_cf_code_audited") {} 1153 virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, 1154 Token &NameTok) { 1155 SourceLocation Loc = NameTok.getLocation(); 1156 bool IsBegin; 1157 1158 Token Tok; 1159 1160 // Lex the 'begin' or 'end'. 1161 PP.LexUnexpandedToken(Tok); 1162 const IdentifierInfo *BeginEnd = Tok.getIdentifierInfo(); 1163 if (BeginEnd && BeginEnd->isStr("begin")) { 1164 IsBegin = true; 1165 } else if (BeginEnd && BeginEnd->isStr("end")) { 1166 IsBegin = false; 1167 } else { 1168 PP.Diag(Tok.getLocation(), diag::err_pp_arc_cf_code_audited_syntax); 1169 return; 1170 } 1171 1172 // Verify that this is followed by EOD. 1173 PP.LexUnexpandedToken(Tok); 1174 if (Tok.isNot(tok::eod)) 1175 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma"; 1176 1177 // The start location of the active audit. 1178 SourceLocation BeginLoc = PP.getPragmaARCCFCodeAuditedLoc(); 1179 1180 // The start location we want after processing this. 1181 SourceLocation NewLoc; 1182 1183 if (IsBegin) { 1184 // Complain about attempts to re-enter an audit. 1185 if (BeginLoc.isValid()) { 1186 PP.Diag(Loc, diag::err_pp_double_begin_of_arc_cf_code_audited); 1187 PP.Diag(BeginLoc, diag::note_pragma_entered_here); 1188 } 1189 NewLoc = Loc; 1190 } else { 1191 // Complain about attempts to leave an audit that doesn't exist. 1192 if (!BeginLoc.isValid()) { 1193 PP.Diag(Loc, diag::err_pp_unmatched_end_of_arc_cf_code_audited); 1194 return; 1195 } 1196 NewLoc = SourceLocation(); 1197 } 1198 1199 PP.setPragmaARCCFCodeAuditedLoc(NewLoc); 1200 } 1201}; 1202 1203} // end anonymous namespace 1204 1205 1206/// RegisterBuiltinPragmas - Install the standard preprocessor pragmas: 1207/// #pragma GCC poison/system_header/dependency and #pragma once. 1208void Preprocessor::RegisterBuiltinPragmas() { 1209 AddPragmaHandler(new PragmaOnceHandler()); 1210 AddPragmaHandler(new PragmaMarkHandler()); 1211 AddPragmaHandler(new PragmaPushMacroHandler()); 1212 AddPragmaHandler(new PragmaPopMacroHandler()); 1213 AddPragmaHandler(new PragmaMessageHandler()); 1214 1215 // #pragma GCC ... 1216 AddPragmaHandler("GCC", new PragmaPoisonHandler()); 1217 AddPragmaHandler("GCC", new PragmaSystemHeaderHandler()); 1218 AddPragmaHandler("GCC", new PragmaDependencyHandler()); 1219 AddPragmaHandler("GCC", new PragmaDiagnosticHandler("GCC")); 1220 // #pragma clang ... 1221 AddPragmaHandler("clang", new PragmaPoisonHandler()); 1222 AddPragmaHandler("clang", new PragmaSystemHeaderHandler()); 1223 AddPragmaHandler("clang", new PragmaDebugHandler()); 1224 AddPragmaHandler("clang", new PragmaDependencyHandler()); 1225 AddPragmaHandler("clang", new PragmaDiagnosticHandler("clang")); 1226 AddPragmaHandler("clang", new PragmaARCCFCodeAuditedHandler()); 1227 1228 AddPragmaHandler("STDC", new PragmaSTDC_FENV_ACCESSHandler()); 1229 AddPragmaHandler("STDC", new PragmaSTDC_CX_LIMITED_RANGEHandler()); 1230 AddPragmaHandler("STDC", new PragmaSTDC_UnknownHandler()); 1231 1232 // MS extensions. 1233 if (Features.MicrosoftExt) { 1234 AddPragmaHandler(new PragmaCommentHandler()); 1235 AddPragmaHandler(new PragmaIncludeAliasHandler()); 1236 } 1237} 1238