2223 lines · cpp
1//===- Pragma.cpp - Pragma registration and handling ----------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the PragmaHandler/PragmaTable interfaces and implements10// pragma related methods of the Preprocessor class.11//12//===----------------------------------------------------------------------===//13 14#include "clang/Lex/Pragma.h"15#include "clang/Basic/CLWarnings.h"16#include "clang/Basic/Diagnostic.h"17#include "clang/Basic/IdentifierTable.h"18#include "clang/Basic/LLVM.h"19#include "clang/Basic/LangOptions.h"20#include "clang/Basic/Module.h"21#include "clang/Basic/SourceLocation.h"22#include "clang/Basic/SourceManager.h"23#include "clang/Basic/TokenKinds.h"24#include "clang/Lex/HeaderSearch.h"25#include "clang/Lex/LexDiagnostic.h"26#include "clang/Lex/Lexer.h"27#include "clang/Lex/LiteralSupport.h"28#include "clang/Lex/MacroInfo.h"29#include "clang/Lex/ModuleLoader.h"30#include "clang/Lex/PPCallbacks.h"31#include "clang/Lex/Preprocessor.h"32#include "clang/Lex/PreprocessorLexer.h"33#include "clang/Lex/PreprocessorOptions.h"34#include "clang/Lex/Token.h"35#include "clang/Lex/TokenLexer.h"36#include "llvm/ADT/ArrayRef.h"37#include "llvm/ADT/DenseMap.h"38#include "llvm/ADT/SmallVector.h"39#include "llvm/ADT/StringRef.h"40#include "llvm/Support/Compiler.h"41#include "llvm/Support/ErrorHandling.h"42#include "llvm/Support/Timer.h"43#include <algorithm>44#include <cassert>45#include <cstddef>46#include <cstdint>47#include <optional>48#include <string>49#include <utility>50#include <vector>51 52using namespace clang;53 54// Out-of-line destructor to provide a home for the class.55PragmaHandler::~PragmaHandler() = default;56 57//===----------------------------------------------------------------------===//58// EmptyPragmaHandler Implementation.59//===----------------------------------------------------------------------===//60 61EmptyPragmaHandler::EmptyPragmaHandler(StringRef Name) : PragmaHandler(Name) {}62 63void EmptyPragmaHandler::HandlePragma(Preprocessor &PP,64 PragmaIntroducer Introducer,65 Token &FirstToken) {}66 67//===----------------------------------------------------------------------===//68// PragmaNamespace Implementation.69//===----------------------------------------------------------------------===//70 71/// FindHandler - Check to see if there is already a handler for the72/// specified name. If not, return the handler for the null identifier if it73/// exists, otherwise return null. If IgnoreNull is true (the default) then74/// the null handler isn't returned on failure to match.75PragmaHandler *PragmaNamespace::FindHandler(StringRef Name,76 bool IgnoreNull) const {77 auto I = Handlers.find(Name);78 if (I != Handlers.end())79 return I->getValue().get();80 if (IgnoreNull)81 return nullptr;82 I = Handlers.find(StringRef());83 if (I != Handlers.end())84 return I->getValue().get();85 return nullptr;86}87 88void PragmaNamespace::AddPragma(PragmaHandler *Handler) {89 assert(!Handlers.count(Handler->getName()) &&90 "A handler with this name is already registered in this namespace");91 Handlers[Handler->getName()].reset(Handler);92}93 94void PragmaNamespace::RemovePragmaHandler(PragmaHandler *Handler) {95 auto I = Handlers.find(Handler->getName());96 assert(I != Handlers.end() &&97 "Handler not registered in this namespace");98 // Release ownership back to the caller.99 I->getValue().release();100 Handlers.erase(I);101}102 103void PragmaNamespace::HandlePragma(Preprocessor &PP,104 PragmaIntroducer Introducer, Token &Tok) {105 // Read the 'namespace' that the directive is in, e.g. STDC. Do not macro106 // expand it, the user can have a STDC #define, that should not affect this.107 PP.LexUnexpandedToken(Tok);108 109 // Get the handler for this token. If there is no handler, ignore the pragma.110 PragmaHandler *Handler111 = FindHandler(Tok.getIdentifierInfo() ? Tok.getIdentifierInfo()->getName()112 : StringRef(),113 /*IgnoreNull=*/false);114 if (!Handler) {115 PP.Diag(Tok, diag::warn_pragma_ignored);116 return;117 }118 119 // Otherwise, pass it down.120 Handler->HandlePragma(PP, Introducer, Tok);121}122 123//===----------------------------------------------------------------------===//124// Preprocessor Pragma Directive Handling.125//===----------------------------------------------------------------------===//126 127namespace {128// TokenCollector provides the option to collect tokens that were "read"129// and return them to the stream to be read later.130// Currently used when reading _Pragma/__pragma directives.131struct TokenCollector {132 Preprocessor &Self;133 bool Collect;134 SmallVector<Token, 3> Tokens;135 Token &Tok;136 137 void lex() {138 if (Collect)139 Tokens.push_back(Tok);140 Self.Lex(Tok);141 }142 143 void revert() {144 assert(Collect && "did not collect tokens");145 assert(!Tokens.empty() && "collected unexpected number of tokens");146 147 // Push the ( "string" ) tokens into the token stream.148 auto Toks = std::make_unique<Token[]>(Tokens.size());149 std::copy(Tokens.begin() + 1, Tokens.end(), Toks.get());150 Toks[Tokens.size() - 1] = Tok;151 Self.EnterTokenStream(std::move(Toks), Tokens.size(),152 /*DisableMacroExpansion*/ true,153 /*IsReinject*/ true);154 155 // ... and return the pragma token unchanged.156 Tok = *Tokens.begin();157 }158};159} // namespace160 161/// HandlePragmaDirective - The "\#pragma" directive has been parsed. Lex the162/// rest of the pragma, passing it to the registered pragma handlers.163void Preprocessor::HandlePragmaDirective(PragmaIntroducer Introducer) {164 if (Callbacks)165 Callbacks->PragmaDirective(Introducer.Loc, Introducer.Kind);166 167 if (!PragmasEnabled)168 return;169 170 ++NumPragma;171 172 // Invoke the first level of pragma handlers which reads the namespace id.173 Token Tok;174 PragmaHandlers->HandlePragma(*this, Introducer, Tok);175 176 // If the pragma handler didn't read the rest of the line, consume it now.177 if ((CurTokenLexer && CurTokenLexer->isParsingPreprocessorDirective())178 || (CurPPLexer && CurPPLexer->ParsingPreprocessorDirective))179 DiscardUntilEndOfDirective();180}181 182/// Handle_Pragma - Read a _Pragma directive, slice it up, process it, then183/// return the first token after the directive. The _Pragma token has just184/// been read into 'Tok'.185void Preprocessor::Handle_Pragma(Token &Tok) {186 // C11 6.10.3.4/3:187 // all pragma unary operator expressions within [a completely188 // macro-replaced preprocessing token sequence] are [...] processed [after189 // rescanning is complete]190 //191 // This means that we execute _Pragma operators in two cases:192 //193 // 1) on token sequences that would otherwise be produced as the output of194 // phase 4 of preprocessing, and195 // 2) on token sequences formed as the macro-replaced token sequence of a196 // macro argument197 //198 // Case #2 appears to be a wording bug: only _Pragmas that would survive to199 // the end of phase 4 should actually be executed. Discussion on the WG14200 // mailing list suggests that a _Pragma operator is notionally checked early,201 // but only pragmas that survive to the end of phase 4 should be executed.202 //203 // In Case #2, we check the syntax now, but then put the tokens back into the204 // token stream for later consumption.205 206 TokenCollector Toks = {*this, InMacroArgPreExpansion, {}, Tok};207 208 // Remember the pragma token location.209 SourceLocation PragmaLoc = Tok.getLocation();210 211 // Read the '('.212 Toks.lex();213 if (Tok.isNot(tok::l_paren)) {214 Diag(PragmaLoc, diag::err__Pragma_malformed);215 return;216 }217 218 // Read the '"..."'.219 Toks.lex();220 if (!tok::isStringLiteral(Tok.getKind())) {221 Diag(PragmaLoc, diag::err__Pragma_malformed);222 // Skip bad tokens, and the ')', if present.223 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::eof) && Tok.isNot(tok::eod))224 Lex(Tok);225 while (Tok.isNot(tok::r_paren) &&226 !Tok.isAtStartOfLine() &&227 Tok.isNot(tok::eof) && Tok.isNot(tok::eod))228 Lex(Tok);229 if (Tok.is(tok::r_paren))230 Lex(Tok);231 return;232 }233 234 if (Tok.hasUDSuffix()) {235 Diag(Tok, diag::err_invalid_string_udl);236 // Skip this token, and the ')', if present.237 Lex(Tok);238 if (Tok.is(tok::r_paren))239 Lex(Tok);240 return;241 }242 243 // Remember the string.244 Token StrTok = Tok;245 246 // Read the ')'.247 Toks.lex();248 if (Tok.isNot(tok::r_paren)) {249 Diag(PragmaLoc, diag::err__Pragma_malformed);250 return;251 }252 253 // If we're expanding a macro argument, put the tokens back.254 if (InMacroArgPreExpansion) {255 Toks.revert();256 return;257 }258 259 SourceLocation RParenLoc = Tok.getLocation();260 bool Invalid = false;261 SmallString<64> StrVal;262 StrVal.resize(StrTok.getLength());263 StringRef StrValRef = getSpelling(StrTok, StrVal, &Invalid);264 if (Invalid) {265 Diag(PragmaLoc, diag::err__Pragma_malformed);266 return;267 }268 269 assert(StrValRef.size() <= StrVal.size());270 271 // If the token was spelled somewhere else, copy it.272 if (StrValRef.begin() != StrVal.begin())273 StrVal.assign(StrValRef);274 // Truncate if necessary.275 else if (StrValRef.size() != StrVal.size())276 StrVal.resize(StrValRef.size());277 278 // The _Pragma is lexically sound. Destringize according to C11 6.10.9.1.279 prepare_PragmaString(StrVal);280 281 // Plop the string (including the newline and trailing null) into a buffer282 // where we can lex it.283 Token TmpTok;284 TmpTok.startToken();285 CreateString(StrVal, TmpTok);286 SourceLocation TokLoc = TmpTok.getLocation();287 288 // Make and enter a lexer object so that we lex and expand the tokens just289 // like any others.290 Lexer *TL = Lexer::Create_PragmaLexer(TokLoc, PragmaLoc, RParenLoc,291 StrVal.size(), *this);292 293 EnterSourceFileWithLexer(TL, nullptr);294 295 // With everything set up, lex this as a #pragma directive.296 HandlePragmaDirective({PIK__Pragma, PragmaLoc});297 298 // Finally, return whatever came after the pragma directive.299 return Lex(Tok);300}301 302void clang::prepare_PragmaString(SmallVectorImpl<char> &StrVal) {303 if (StrVal[0] == 'L' || StrVal[0] == 'U' ||304 (StrVal[0] == 'u' && StrVal[1] != '8'))305 StrVal.erase(StrVal.begin());306 else if (StrVal[0] == 'u')307 StrVal.erase(StrVal.begin(), StrVal.begin() + 2);308 309 if (StrVal[0] == 'R') {310 // FIXME: C++11 does not specify how to handle raw-string-literals here.311 // We strip off the 'R', the quotes, the d-char-sequences, and the parens.312 assert(StrVal[1] == '"' && StrVal[StrVal.size() - 1] == '"' &&313 "Invalid raw string token!");314 315 // Measure the length of the d-char-sequence.316 unsigned NumDChars = 0;317 while (StrVal[2 + NumDChars] != '(') {318 assert(NumDChars < (StrVal.size() - 5) / 2 &&319 "Invalid raw string token!");320 ++NumDChars;321 }322 assert(StrVal[StrVal.size() - 2 - NumDChars] == ')');323 324 // Remove 'R " d-char-sequence' and 'd-char-sequence "'. We'll replace the325 // parens below.326 StrVal.erase(StrVal.begin(), StrVal.begin() + 2 + NumDChars);327 StrVal.erase(StrVal.end() - 1 - NumDChars, StrVal.end());328 } else {329 assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' &&330 "Invalid string token!");331 332 // Remove escaped quotes and escapes.333 unsigned ResultPos = 1;334 for (size_t i = 1, e = StrVal.size() - 1; i != e; ++i) {335 // Skip escapes. \\ -> '\' and \" -> '"'.336 if (StrVal[i] == '\\' && i + 1 < e &&337 (StrVal[i + 1] == '\\' || StrVal[i + 1] == '"'))338 ++i;339 StrVal[ResultPos++] = StrVal[i];340 }341 StrVal.erase(StrVal.begin() + ResultPos, StrVal.end() - 1);342 }343 344 // Remove the front quote, replacing it with a space, so that the pragma345 // contents appear to have a space before them.346 StrVal[0] = ' ';347 348 // Replace the terminating quote with a \n.349 StrVal[StrVal.size() - 1] = '\n';350}351 352/// HandleMicrosoft__pragma - Like Handle_Pragma except the pragma text353/// is not enclosed within a string literal.354void Preprocessor::HandleMicrosoft__pragma(Token &Tok) {355 // During macro pre-expansion, check the syntax now but put the tokens back356 // into the token stream for later consumption. Same as Handle_Pragma.357 TokenCollector Toks = {*this, InMacroArgPreExpansion, {}, Tok};358 359 // Remember the pragma token location.360 SourceLocation PragmaLoc = Tok.getLocation();361 362 // Read the '('.363 Toks.lex();364 if (Tok.isNot(tok::l_paren)) {365 Diag(PragmaLoc, diag::err__Pragma_malformed);366 return;367 }368 369 // Get the tokens enclosed within the __pragma(), as well as the final ')'.370 SmallVector<Token, 32> PragmaToks;371 int NumParens = 0;372 Toks.lex();373 while (Tok.isNot(tok::eof)) {374 PragmaToks.push_back(Tok);375 if (Tok.is(tok::l_paren))376 NumParens++;377 else if (Tok.is(tok::r_paren) && NumParens-- == 0)378 break;379 Toks.lex();380 }381 382 if (Tok.is(tok::eof)) {383 Diag(PragmaLoc, diag::err_unterminated___pragma);384 return;385 }386 387 // If we're expanding a macro argument, put the tokens back.388 if (InMacroArgPreExpansion) {389 Toks.revert();390 return;391 }392 393 PragmaToks.front().setFlag(Token::LeadingSpace);394 395 // Replace the ')' with an EOD to mark the end of the pragma.396 PragmaToks.back().setKind(tok::eod);397 398 Token *TokArray = new Token[PragmaToks.size()];399 std::copy(PragmaToks.begin(), PragmaToks.end(), TokArray);400 401 // Push the tokens onto the stack.402 EnterTokenStream(TokArray, PragmaToks.size(), true, true,403 /*IsReinject*/ false);404 405 // With everything set up, lex this as a #pragma directive.406 HandlePragmaDirective({PIK___pragma, PragmaLoc});407 408 // Finally, return whatever came after the pragma directive.409 return Lex(Tok);410}411 412/// HandlePragmaOnce - Handle \#pragma once. OnceTok is the 'once'.413void Preprocessor::HandlePragmaOnce(Token &OnceTok) {414 // Don't honor the 'once' when handling the primary source file, unless415 // this is a prefix to a TU, which indicates we're generating a PCH file, or416 // when the main file is a header (e.g. when -xc-header is provided on the417 // commandline).418 if (isInPrimaryFile() && TUKind != TU_Prefix && !getLangOpts().IsHeaderFile) {419 Diag(OnceTok, diag::pp_pragma_once_in_main_file);420 return;421 }422 423 // Get the current file lexer we're looking at. Ignore _Pragma 'files' etc.424 // Mark the file as a once-only file now.425 HeaderInfo.MarkFileIncludeOnce(*getCurrentFileLexer()->getFileEntry());426}427 428void Preprocessor::HandlePragmaMark(Token &MarkTok) {429 assert(CurPPLexer && "No current lexer?");430 431 SmallString<64> Buffer;432 CurLexer->ReadToEndOfLine(&Buffer);433 if (Callbacks)434 Callbacks->PragmaMark(MarkTok.getLocation(), Buffer);435}436 437/// HandlePragmaPoison - Handle \#pragma GCC poison. PoisonTok is the 'poison'.438void Preprocessor::HandlePragmaPoison() {439 Token Tok;440 441 while (true) {442 // Read the next token to poison. While doing this, pretend that we are443 // skipping while reading the identifier to poison.444 // This avoids errors on code like:445 // #pragma GCC poison X446 // #pragma GCC poison X447 if (CurPPLexer) CurPPLexer->LexingRawMode = true;448 LexUnexpandedToken(Tok);449 if (CurPPLexer) CurPPLexer->LexingRawMode = false;450 451 // If we reached the end of line, we're done.452 if (Tok.is(tok::eod)) return;453 454 // Can only poison identifiers.455 if (Tok.isNot(tok::raw_identifier)) {456 Diag(Tok, diag::err_pp_invalid_poison);457 return;458 }459 460 // Look up the identifier info for the token. We disabled identifier lookup461 // by saying we're skipping contents, so we need to do this manually.462 IdentifierInfo *II = LookUpIdentifierInfo(Tok);463 464 // Already poisoned.465 if (II->isPoisoned()) continue;466 467 // If this is a macro identifier, emit a warning.468 if (isMacroDefined(II))469 Diag(Tok, diag::pp_poisoning_existing_macro);470 471 // Finally, poison it!472 II->setIsPoisoned();473 if (II->isFromAST())474 II->setChangedSinceDeserialization();475 }476}477 478/// HandlePragmaSystemHeader - Implement \#pragma GCC system_header. We know479/// that the whole directive has been parsed.480void Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) {481 if (isInPrimaryFile()) {482 Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);483 return;484 }485 486 // Get the current file lexer we're looking at. Ignore _Pragma 'files' etc.487 PreprocessorLexer *TheLexer = getCurrentFileLexer();488 489 // Mark the file as a system header.490 HeaderInfo.MarkFileSystemHeader(*TheLexer->getFileEntry());491 492 PresumedLoc PLoc = SourceMgr.getPresumedLoc(SysHeaderTok.getLocation());493 if (PLoc.isInvalid())494 return;495 496 unsigned FilenameID = SourceMgr.getLineTableFilenameID(PLoc.getFilename());497 498 // Notify the client, if desired, that we are in a new source file.499 if (Callbacks)500 Callbacks->FileChanged(SysHeaderTok.getLocation(),501 PPCallbacks::SystemHeaderPragma, SrcMgr::C_System);502 503 // Emit a line marker. This will change any source locations from this point504 // forward to realize they are in a system header.505 // Create a line note with this information.506 SourceMgr.AddLineNote(SysHeaderTok.getLocation(), PLoc.getLine() + 1,507 FilenameID, /*IsEntry=*/false, /*IsExit=*/false,508 SrcMgr::C_System);509}510 511/// HandlePragmaDependency - Handle \#pragma GCC dependency "foo" blah.512void Preprocessor::HandlePragmaDependency(Token &DependencyTok) {513 Token FilenameTok;514 if (LexHeaderName(FilenameTok, /*AllowConcatenation*/false))515 return;516 517 // If the next token wasn't a header-name, diagnose the error.518 if (FilenameTok.isNot(tok::header_name)) {519 Diag(FilenameTok.getLocation(), diag::err_pp_expects_filename);520 return;521 }522 523 // Reserve a buffer to get the spelling.524 SmallString<128> FilenameBuffer;525 bool Invalid = false;526 StringRef Filename = getSpelling(FilenameTok, FilenameBuffer, &Invalid);527 if (Invalid)528 return;529 530 bool isAngled =531 GetIncludeFilenameSpelling(FilenameTok.getLocation(), Filename);532 // If GetIncludeFilenameSpelling set the start ptr to null, there was an533 // error.534 if (Filename.empty())535 return;536 537 // Search include directories for this file.538 OptionalFileEntryRef File =539 LookupFile(FilenameTok.getLocation(), Filename, isAngled, nullptr,540 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);541 if (!File) {542 if (!SuppressIncludeNotFoundError)543 Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;544 return;545 }546 547 OptionalFileEntryRef CurFile = getCurrentFileLexer()->getFileEntry();548 549 // If this file is older than the file it depends on, emit a diagnostic.550 if (CurFile && CurFile->getModificationTime() < File->getModificationTime()) {551 // Lex tokens at the end of the message and include them in the message.552 std::string Message;553 Lex(DependencyTok);554 while (DependencyTok.isNot(tok::eod)) {555 Message += getSpelling(DependencyTok) + " ";556 Lex(DependencyTok);557 }558 559 // Remove the trailing ' ' if present.560 if (!Message.empty())561 Message.erase(Message.end()-1);562 Diag(FilenameTok, diag::pp_out_of_date_dependency) << Message;563 }564}565 566/// ParsePragmaPushOrPopMacro - Handle parsing of pragma push_macro/pop_macro.567/// Return the IdentifierInfo* associated with the macro to push or pop.568IdentifierInfo *Preprocessor::ParsePragmaPushOrPopMacro(Token &Tok) {569 // Remember the pragma token location.570 Token PragmaTok = Tok;571 572 // Read the '('.573 Lex(Tok);574 if (Tok.isNot(tok::l_paren)) {575 Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)576 << getSpelling(PragmaTok);577 return nullptr;578 }579 580 // Read the macro name string.581 Lex(Tok);582 if (Tok.isNot(tok::string_literal)) {583 Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)584 << getSpelling(PragmaTok);585 return nullptr;586 }587 588 if (Tok.hasUDSuffix()) {589 Diag(Tok, diag::err_invalid_string_udl);590 return nullptr;591 }592 593 // Remember the macro string.594 Token StrTok = Tok;595 std::string StrVal = getSpelling(StrTok);596 597 // Read the ')'.598 Lex(Tok);599 if (Tok.isNot(tok::r_paren)) {600 Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)601 << getSpelling(PragmaTok);602 return nullptr;603 }604 605 assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' &&606 "Invalid string token!");607 608 if (StrVal.size() <= 2) {609 Diag(StrTok.getLocation(), diag::warn_pargma_push_pop_macro_empty_string)610 << SourceRange(611 StrTok.getLocation(),612 StrTok.getLocation().getLocWithOffset(StrTok.getLength()))613 << PragmaTok.getIdentifierInfo()->isStr("pop_macro");614 return nullptr;615 }616 617 // Create a Token from the string.618 Token MacroTok;619 MacroTok.startToken();620 MacroTok.setKind(tok::raw_identifier);621 CreateString(StringRef(&StrVal[1], StrVal.size() - 2), MacroTok);622 623 // Get the IdentifierInfo of MacroToPushTok.624 return LookUpIdentifierInfo(MacroTok);625}626 627/// Handle \#pragma push_macro.628///629/// The syntax is:630/// \code631/// #pragma push_macro("macro")632/// \endcode633void Preprocessor::HandlePragmaPushMacro(Token &PushMacroTok) {634 // Parse the pragma directive and get the macro IdentifierInfo*.635 IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PushMacroTok);636 if (!IdentInfo) return;637 638 // Get the MacroInfo associated with IdentInfo.639 MacroInfo *MI = getMacroInfo(IdentInfo);640 641 if (MI) {642 // Allow the original MacroInfo to be redefined later.643 MI->setIsAllowRedefinitionsWithoutWarning(true);644 }645 646 // Push the cloned MacroInfo so we can retrieve it later.647 PragmaPushMacroInfo[IdentInfo].push_back(MI);648}649 650/// Handle \#pragma pop_macro.651///652/// The syntax is:653/// \code654/// #pragma pop_macro("macro")655/// \endcode656void Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) {657 SourceLocation MessageLoc = PopMacroTok.getLocation();658 659 // Parse the pragma directive and get the macro IdentifierInfo*.660 IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PopMacroTok);661 if (!IdentInfo) return;662 663 // Find the vector<MacroInfo*> associated with the macro.664 llvm::DenseMap<IdentifierInfo *, std::vector<MacroInfo *>>::iterator iter =665 PragmaPushMacroInfo.find(IdentInfo);666 if (iter != PragmaPushMacroInfo.end()) {667 // Forget the MacroInfo currently associated with IdentInfo.668 if (MacroInfo *MI = getMacroInfo(IdentInfo)) {669 if (MI->isWarnIfUnused())670 WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());671 appendMacroDirective(IdentInfo, AllocateUndefMacroDirective(MessageLoc));672 }673 674 // Get the MacroInfo we want to reinstall.675 MacroInfo *MacroToReInstall = iter->second.back();676 677 if (MacroToReInstall)678 // Reinstall the previously pushed macro.679 appendDefMacroDirective(IdentInfo, MacroToReInstall, MessageLoc);680 681 // Pop PragmaPushMacroInfo stack.682 iter->second.pop_back();683 if (iter->second.empty())684 PragmaPushMacroInfo.erase(iter);685 } else {686 Diag(MessageLoc, diag::warn_pragma_pop_macro_no_push)687 << IdentInfo->getName();688 }689}690 691void Preprocessor::HandlePragmaIncludeAlias(Token &Tok) {692 // We will either get a quoted filename or a bracketed filename, and we693 // have to track which we got. The first filename is the source name,694 // and the second name is the mapped filename. If the first is quoted,695 // the second must be as well (cannot mix and match quotes and brackets).696 697 // Get the open paren698 Lex(Tok);699 if (Tok.isNot(tok::l_paren)) {700 Diag(Tok, diag::warn_pragma_include_alias_expected) << "(";701 return;702 }703 704 // We expect either a quoted string literal, or a bracketed name705 Token SourceFilenameTok;706 if (LexHeaderName(SourceFilenameTok))707 return;708 709 StringRef SourceFileName;710 SmallString<128> FileNameBuffer;711 if (SourceFilenameTok.is(tok::header_name)) {712 SourceFileName = getSpelling(SourceFilenameTok, FileNameBuffer);713 } else {714 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);715 return;716 }717 FileNameBuffer.clear();718 719 // Now we expect a comma, followed by another include name720 Lex(Tok);721 if (Tok.isNot(tok::comma)) {722 Diag(Tok, diag::warn_pragma_include_alias_expected) << ",";723 return;724 }725 726 Token ReplaceFilenameTok;727 if (LexHeaderName(ReplaceFilenameTok))728 return;729 730 StringRef ReplaceFileName;731 if (ReplaceFilenameTok.is(tok::header_name)) {732 ReplaceFileName = getSpelling(ReplaceFilenameTok, FileNameBuffer);733 } else {734 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);735 return;736 }737 738 // Finally, we expect the closing paren739 Lex(Tok);740 if (Tok.isNot(tok::r_paren)) {741 Diag(Tok, diag::warn_pragma_include_alias_expected) << ")";742 return;743 }744 745 // Now that we have the source and target filenames, we need to make sure746 // they're both of the same type (angled vs non-angled)747 StringRef OriginalSource = SourceFileName;748 749 bool SourceIsAngled =750 GetIncludeFilenameSpelling(SourceFilenameTok.getLocation(),751 SourceFileName);752 bool ReplaceIsAngled =753 GetIncludeFilenameSpelling(ReplaceFilenameTok.getLocation(),754 ReplaceFileName);755 if (!SourceFileName.empty() && !ReplaceFileName.empty() &&756 (SourceIsAngled != ReplaceIsAngled)) {757 unsigned int DiagID;758 if (SourceIsAngled)759 DiagID = diag::warn_pragma_include_alias_mismatch_angle;760 else761 DiagID = diag::warn_pragma_include_alias_mismatch_quote;762 763 Diag(SourceFilenameTok.getLocation(), DiagID)764 << SourceFileName765 << ReplaceFileName;766 767 return;768 }769 770 // Now we can let the include handler know about this mapping771 getHeaderSearchInfo().AddIncludeAlias(OriginalSource, ReplaceFileName);772}773 774// Lex a component of a module name: either an identifier or a string literal;775// for components that can be expressed both ways, the two forms are equivalent.776static bool LexModuleNameComponent(Preprocessor &PP, Token &Tok,777 IdentifierLoc &ModuleNameComponent,778 bool First) {779 PP.LexUnexpandedToken(Tok);780 if (Tok.is(tok::string_literal) && !Tok.hasUDSuffix()) {781 StringLiteralParser Literal(Tok, PP);782 if (Literal.hadError)783 return true;784 ModuleNameComponent = IdentifierLoc(785 Tok.getLocation(), PP.getIdentifierInfo(Literal.GetString()));786 } else if (!Tok.isAnnotation() && Tok.getIdentifierInfo()) {787 ModuleNameComponent =788 IdentifierLoc(Tok.getLocation(), Tok.getIdentifierInfo());789 } else {790 PP.Diag(Tok.getLocation(), diag::err_pp_expected_module_name) << First;791 return true;792 }793 return false;794}795 796static bool LexModuleName(Preprocessor &PP, Token &Tok,797 llvm::SmallVectorImpl<IdentifierLoc> &ModuleName) {798 while (true) {799 IdentifierLoc NameComponent;800 if (LexModuleNameComponent(PP, Tok, NameComponent, ModuleName.empty()))801 return true;802 ModuleName.push_back(NameComponent);803 804 PP.LexUnexpandedToken(Tok);805 if (Tok.isNot(tok::period))806 return false;807 }808}809 810void Preprocessor::HandlePragmaModuleBuild(Token &Tok) {811 SourceLocation Loc = Tok.getLocation();812 813 IdentifierLoc ModuleNameLoc;814 if (LexModuleNameComponent(*this, Tok, ModuleNameLoc, true))815 return;816 IdentifierInfo *ModuleName = ModuleNameLoc.getIdentifierInfo();817 818 LexUnexpandedToken(Tok);819 if (Tok.isNot(tok::eod)) {820 Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";821 DiscardUntilEndOfDirective();822 }823 824 CurLexer->LexingRawMode = true;825 826 auto TryConsumeIdentifier = [&](StringRef Ident) -> bool {827 if (Tok.getKind() != tok::raw_identifier ||828 Tok.getRawIdentifier() != Ident)829 return false;830 CurLexer->Lex(Tok);831 return true;832 };833 834 // Scan forward looking for the end of the module.835 const char *Start = CurLexer->getBufferLocation();836 const char *End = nullptr;837 unsigned NestingLevel = 1;838 while (true) {839 End = CurLexer->getBufferLocation();840 CurLexer->Lex(Tok);841 842 if (Tok.is(tok::eof)) {843 Diag(Loc, diag::err_pp_module_build_missing_end);844 break;845 }846 847 if (Tok.isNot(tok::hash) || !Tok.isAtStartOfLine()) {848 // Token was part of module; keep going.849 continue;850 }851 852 // We hit something directive-shaped; check to see if this is the end853 // of the module build.854 CurLexer->ParsingPreprocessorDirective = true;855 CurLexer->Lex(Tok);856 if (TryConsumeIdentifier("pragma") && TryConsumeIdentifier("clang") &&857 TryConsumeIdentifier("module")) {858 if (TryConsumeIdentifier("build"))859 // #pragma clang module build -> entering a nested module build.860 ++NestingLevel;861 else if (TryConsumeIdentifier("endbuild")) {862 // #pragma clang module endbuild -> leaving a module build.863 if (--NestingLevel == 0)864 break;865 }866 // We should either be looking at the EOD or more of the current directive867 // preceding the EOD. Either way we can ignore this token and keep going.868 assert(Tok.getKind() != tok::eof && "missing EOD before EOF");869 }870 }871 872 CurLexer->LexingRawMode = false;873 874 // Load the extracted text as a preprocessed module.875 assert(CurLexer->getBuffer().begin() <= Start &&876 Start <= CurLexer->getBuffer().end() &&877 CurLexer->getBuffer().begin() <= End &&878 End <= CurLexer->getBuffer().end() &&879 "module source range not contained within same file buffer");880 TheModuleLoader.createModuleFromSource(Loc, ModuleName->getName(),881 StringRef(Start, End - Start));882}883 884void Preprocessor::HandlePragmaHdrstop(Token &Tok) {885 Lex(Tok);886 if (Tok.is(tok::l_paren)) {887 Diag(Tok.getLocation(), diag::warn_pp_hdrstop_filename_ignored);888 889 std::string FileName;890 if (!LexStringLiteral(Tok, FileName, "pragma hdrstop", false))891 return;892 893 if (Tok.isNot(tok::r_paren)) {894 Diag(Tok, diag::err_expected) << tok::r_paren;895 return;896 }897 Lex(Tok);898 }899 if (Tok.isNot(tok::eod))900 Diag(Tok.getLocation(), diag::ext_pp_extra_tokens_at_eol)901 << "pragma hdrstop";902 903 if (creatingPCHWithPragmaHdrStop() &&904 SourceMgr.isInMainFile(Tok.getLocation())) {905 assert(CurLexer && "no lexer for #pragma hdrstop processing");906 Token &Result = Tok;907 Result.startToken();908 CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd, tok::eof);909 CurLexer->cutOffLexing();910 }911 if (usingPCHWithPragmaHdrStop())912 SkippingUntilPragmaHdrStop = false;913}914 915/// AddPragmaHandler - Add the specified pragma handler to the preprocessor.916/// If 'Namespace' is non-null, then it is a token required to exist on the917/// pragma line before the pragma string starts, e.g. "STDC" or "GCC".918void Preprocessor::AddPragmaHandler(StringRef Namespace,919 PragmaHandler *Handler) {920 PragmaNamespace *InsertNS = PragmaHandlers.get();921 922 // If this is specified to be in a namespace, step down into it.923 if (!Namespace.empty()) {924 // If there is already a pragma handler with the name of this namespace,925 // we either have an error (directive with the same name as a namespace) or926 // we already have the namespace to insert into.927 if (PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace)) {928 InsertNS = Existing->getIfNamespace();929 assert(InsertNS != nullptr && "Cannot have a pragma namespace and pragma"930 " handler with the same name!");931 } else {932 // Otherwise, this namespace doesn't exist yet, create and insert the933 // handler for it.934 InsertNS = new PragmaNamespace(Namespace);935 PragmaHandlers->AddPragma(InsertNS);936 }937 }938 939 // Check to make sure we don't already have a pragma for this identifier.940 assert(!InsertNS->FindHandler(Handler->getName()) &&941 "Pragma handler already exists for this identifier!");942 InsertNS->AddPragma(Handler);943}944 945/// RemovePragmaHandler - Remove the specific pragma handler from the946/// preprocessor. If \arg Namespace is non-null, then it should be the947/// namespace that \arg Handler was added to. It is an error to remove948/// a handler that has not been registered.949void Preprocessor::RemovePragmaHandler(StringRef Namespace,950 PragmaHandler *Handler) {951 PragmaNamespace *NS = PragmaHandlers.get();952 953 // If this is specified to be in a namespace, step down into it.954 if (!Namespace.empty()) {955 PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace);956 assert(Existing && "Namespace containing handler does not exist!");957 958 NS = Existing->getIfNamespace();959 assert(NS && "Invalid namespace, registered as a regular pragma handler!");960 }961 962 NS->RemovePragmaHandler(Handler);963 964 // If this is a non-default namespace and it is now empty, remove it.965 if (NS != PragmaHandlers.get() && NS->IsEmpty()) {966 PragmaHandlers->RemovePragmaHandler(NS);967 delete NS;968 }969}970 971bool Preprocessor::LexOnOffSwitch(tok::OnOffSwitch &Result) {972 Token Tok;973 LexUnexpandedToken(Tok);974 975 if (Tok.isNot(tok::identifier)) {976 Diag(Tok, diag::ext_on_off_switch_syntax);977 return true;978 }979 IdentifierInfo *II = Tok.getIdentifierInfo();980 if (II->isStr("ON"))981 Result = tok::OOS_ON;982 else if (II->isStr("OFF"))983 Result = tok::OOS_OFF;984 else if (II->isStr("DEFAULT"))985 Result = tok::OOS_DEFAULT;986 else {987 Diag(Tok, diag::ext_on_off_switch_syntax);988 return true;989 }990 991 // Verify that this is followed by EOD.992 LexUnexpandedToken(Tok);993 if (Tok.isNot(tok::eod))994 Diag(Tok, diag::ext_pragma_syntax_eod);995 return false;996}997 998namespace {999 1000/// PragmaOnceHandler - "\#pragma once" marks the file as atomically included.1001struct PragmaOnceHandler : public PragmaHandler {1002 PragmaOnceHandler() : PragmaHandler("once") {}1003 1004 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1005 Token &OnceTok) override {1006 PP.CheckEndOfDirective("pragma once");1007 PP.HandlePragmaOnce(OnceTok);1008 }1009};1010 1011/// PragmaMarkHandler - "\#pragma mark ..." is ignored by the compiler, and the1012/// rest of the line is not lexed.1013struct PragmaMarkHandler : public PragmaHandler {1014 PragmaMarkHandler() : PragmaHandler("mark") {}1015 1016 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1017 Token &MarkTok) override {1018 PP.HandlePragmaMark(MarkTok);1019 }1020};1021 1022/// PragmaPoisonHandler - "\#pragma poison x" marks x as not usable.1023struct PragmaPoisonHandler : public PragmaHandler {1024 PragmaPoisonHandler() : PragmaHandler("poison") {}1025 1026 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1027 Token &PoisonTok) override {1028 PP.HandlePragmaPoison();1029 }1030};1031 1032/// PragmaSystemHeaderHandler - "\#pragma system_header" marks the current file1033/// as a system header, which silences warnings in it.1034struct PragmaSystemHeaderHandler : public PragmaHandler {1035 PragmaSystemHeaderHandler() : PragmaHandler("system_header") {}1036 1037 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1038 Token &SHToken) override {1039 PP.HandlePragmaSystemHeader(SHToken);1040 PP.CheckEndOfDirective("pragma");1041 }1042};1043 1044struct PragmaDependencyHandler : public PragmaHandler {1045 PragmaDependencyHandler() : PragmaHandler("dependency") {}1046 1047 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1048 Token &DepToken) override {1049 PP.HandlePragmaDependency(DepToken);1050 }1051};1052 1053struct PragmaDebugHandler : public PragmaHandler {1054 PragmaDebugHandler() : PragmaHandler("__debug") {}1055 1056 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1057 Token &DebugToken) override {1058 Token Tok;1059 PP.LexUnexpandedToken(Tok);1060 if (Tok.isNot(tok::identifier)) {1061 PP.Diag(Tok, diag::warn_pragma_debug_missing_command);1062 return;1063 }1064 IdentifierInfo *II = Tok.getIdentifierInfo();1065 1066 if (II->isStr("assert")) {1067 if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash)1068 llvm_unreachable("This is an assertion!");1069 } else if (II->isStr("crash")) {1070 llvm::Timer T("crash", "pragma crash");1071 llvm::TimeRegion R(&T);1072 if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash)1073 LLVM_BUILTIN_TRAP;1074 } else if (II->isStr("parser_crash")) {1075 if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash) {1076 Token Crasher;1077 Crasher.startToken();1078 Crasher.setKind(tok::annot_pragma_parser_crash);1079 Crasher.setAnnotationRange(SourceRange(Tok.getLocation()));1080 PP.EnterToken(Crasher, /*IsReinject*/ false);1081 }1082 } else if (II->isStr("dump")) {1083 Token DumpAnnot;1084 DumpAnnot.startToken();1085 DumpAnnot.setKind(tok::annot_pragma_dump);1086 DumpAnnot.setAnnotationRange(SourceRange(Tok.getLocation()));1087 PP.EnterToken(DumpAnnot, /*IsReinject*/false);1088 } else if (II->isStr("diag_mapping")) {1089 Token DiagName;1090 PP.LexUnexpandedToken(DiagName);1091 if (DiagName.is(tok::eod))1092 PP.getDiagnostics().dump();1093 else if (DiagName.is(tok::string_literal) && !DiagName.hasUDSuffix()) {1094 StringLiteralParser Literal(DiagName, PP,1095 StringLiteralEvalMethod::Unevaluated);1096 if (Literal.hadError)1097 return;1098 PP.getDiagnostics().dump(Literal.GetString());1099 } else {1100 PP.Diag(DiagName, diag::warn_pragma_debug_missing_argument)1101 << II->getName();1102 }1103 } else if (II->isStr("llvm_fatal_error")) {1104 if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash)1105 llvm::report_fatal_error("#pragma clang __debug llvm_fatal_error");1106 } else if (II->isStr("llvm_unreachable")) {1107 if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash)1108 llvm_unreachable("#pragma clang __debug llvm_unreachable");1109 } else if (II->isStr("macro")) {1110 Token MacroName;1111 PP.LexUnexpandedToken(MacroName);1112 auto *MacroII = MacroName.getIdentifierInfo();1113 if (MacroII)1114 PP.dumpMacroInfo(MacroII);1115 else1116 PP.Diag(MacroName, diag::warn_pragma_debug_missing_argument)1117 << II->getName();1118 } else if (II->isStr("module_map")) {1119 llvm::SmallVector<IdentifierLoc, 8> ModuleName;1120 if (LexModuleName(PP, Tok, ModuleName))1121 return;1122 ModuleMap &MM = PP.getHeaderSearchInfo().getModuleMap();1123 Module *M = nullptr;1124 for (auto IIAndLoc : ModuleName) {1125 M = MM.lookupModuleQualified(IIAndLoc.getIdentifierInfo()->getName(),1126 M);1127 if (!M) {1128 PP.Diag(IIAndLoc.getLoc(), diag::warn_pragma_debug_unknown_module)1129 << IIAndLoc.getIdentifierInfo()->getName();1130 return;1131 }1132 }1133 M->dump();1134 } else if (II->isStr("module_lookup")) {1135 Token MName;1136 PP.LexUnexpandedToken(MName);1137 auto *MNameII = MName.getIdentifierInfo();1138 if (!MNameII) {1139 PP.Diag(MName, diag::warn_pragma_debug_missing_argument)1140 << II->getName();1141 return;1142 }1143 Module *M = PP.getHeaderSearchInfo().lookupModule(MNameII->getName());1144 if (!M) {1145 PP.Diag(MName, diag::warn_pragma_debug_unable_to_find_module)1146 << MNameII->getName();1147 return;1148 }1149 M->dump();1150 } else if (II->isStr("overflow_stack")) {1151 if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash)1152 DebugOverflowStack();1153 } else if (II->isStr("captured")) {1154 HandleCaptured(PP);1155 } else if (II->isStr("modules")) {1156 struct ModuleVisitor {1157 Preprocessor &PP;1158 void visit(Module *M, bool VisibleOnly) {1159 SourceLocation ImportLoc = PP.getModuleImportLoc(M);1160 if (!VisibleOnly || ImportLoc.isValid()) {1161 llvm::errs() << M->getFullModuleName() << " ";1162 if (ImportLoc.isValid()) {1163 llvm::errs() << M << " visible ";1164 ImportLoc.print(llvm::errs(), PP.getSourceManager());1165 }1166 llvm::errs() << "\n";1167 }1168 for (Module *Sub : M->submodules()) {1169 if (!VisibleOnly || ImportLoc.isInvalid() || Sub->IsExplicit)1170 visit(Sub, VisibleOnly);1171 }1172 }1173 void visitAll(bool VisibleOnly) {1174 for (auto &NameAndMod :1175 PP.getHeaderSearchInfo().getModuleMap().modules())1176 visit(NameAndMod.second, VisibleOnly);1177 }1178 } Visitor{PP};1179 1180 Token Kind;1181 PP.LexUnexpandedToken(Kind);1182 auto *DumpII = Kind.getIdentifierInfo();1183 if (!DumpII) {1184 PP.Diag(Kind, diag::warn_pragma_debug_missing_argument)1185 << II->getName();1186 } else if (DumpII->isStr("all")) {1187 Visitor.visitAll(false);1188 } else if (DumpII->isStr("visible")) {1189 Visitor.visitAll(true);1190 } else if (DumpII->isStr("building")) {1191 for (auto &Building : PP.getBuildingSubmodules()) {1192 llvm::errs() << "in " << Building.M->getFullModuleName();1193 if (Building.ImportLoc.isValid()) {1194 llvm::errs() << " imported ";1195 if (Building.IsPragma)1196 llvm::errs() << "via pragma ";1197 llvm::errs() << "at ";1198 Building.ImportLoc.print(llvm::errs(), PP.getSourceManager());1199 llvm::errs() << "\n";1200 }1201 }1202 } else {1203 PP.Diag(Tok, diag::warn_pragma_debug_unexpected_command)1204 << DumpII->getName();1205 }1206 } else if (II->isStr("sloc_usage")) {1207 // An optional integer literal argument specifies the number of files to1208 // specifically report information about.1209 std::optional<unsigned> MaxNotes;1210 Token ArgToken;1211 PP.Lex(ArgToken);1212 uint64_t Value;1213 if (ArgToken.is(tok::numeric_constant) &&1214 PP.parseSimpleIntegerLiteral(ArgToken, Value)) {1215 MaxNotes = Value;1216 } else if (ArgToken.isNot(tok::eod)) {1217 PP.Diag(ArgToken, diag::warn_pragma_debug_unexpected_argument);1218 }1219 1220 PP.Diag(Tok, diag::remark_sloc_usage);1221 PP.getSourceManager().noteSLocAddressSpaceUsage(PP.getDiagnostics(),1222 MaxNotes);1223 } else {1224 PP.Diag(Tok, diag::warn_pragma_debug_unexpected_command)1225 << II->getName();1226 }1227 1228 PPCallbacks *Callbacks = PP.getPPCallbacks();1229 if (Callbacks)1230 Callbacks->PragmaDebug(Tok.getLocation(), II->getName());1231 }1232 1233 void HandleCaptured(Preprocessor &PP) {1234 Token Tok;1235 PP.LexUnexpandedToken(Tok);1236 1237 if (Tok.isNot(tok::eod)) {1238 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol)1239 << "pragma clang __debug captured";1240 return;1241 }1242 1243 SourceLocation NameLoc = Tok.getLocation();1244 MutableArrayRef<Token> Toks(1245 PP.getPreprocessorAllocator().Allocate<Token>(1), 1);1246 Toks[0].startToken();1247 Toks[0].setKind(tok::annot_pragma_captured);1248 Toks[0].setLocation(NameLoc);1249 1250 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,1251 /*IsReinject=*/false);1252 }1253 1254// Disable MSVC warning about runtime stack overflow.1255#ifdef _MSC_VER1256 #pragma warning(disable : 4717)1257#endif1258 static void DebugOverflowStack(void (*P)() = nullptr) {1259 void (*volatile Self)(void(*P)()) = DebugOverflowStack;1260 Self(reinterpret_cast<void(*)()>(Self));1261 }1262#ifdef _MSC_VER1263 #pragma warning(default : 4717)1264#endif1265};1266 1267struct PragmaUnsafeBufferUsageHandler : public PragmaHandler {1268 PragmaUnsafeBufferUsageHandler() : PragmaHandler("unsafe_buffer_usage") {}1269 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1270 Token &FirstToken) override {1271 Token Tok;1272 1273 PP.LexUnexpandedToken(Tok);1274 if (Tok.isNot(tok::identifier)) {1275 PP.Diag(Tok, diag::err_pp_pragma_unsafe_buffer_usage_syntax);1276 return;1277 }1278 1279 IdentifierInfo *II = Tok.getIdentifierInfo();1280 SourceLocation Loc = Tok.getLocation();1281 1282 if (II->isStr("begin")) {1283 if (PP.enterOrExitSafeBufferOptOutRegion(true, Loc))1284 PP.Diag(Loc, diag::err_pp_double_begin_pragma_unsafe_buffer_usage);1285 } else if (II->isStr("end")) {1286 if (PP.enterOrExitSafeBufferOptOutRegion(false, Loc))1287 PP.Diag(Loc, diag::err_pp_unmatched_end_begin_pragma_unsafe_buffer_usage);1288 } else1289 PP.Diag(Tok, diag::err_pp_pragma_unsafe_buffer_usage_syntax);1290 }1291};1292 1293/// PragmaDiagnosticHandler - e.g. '\#pragma GCC diagnostic ignored "-Wformat"'1294struct PragmaDiagnosticHandler : public PragmaHandler {1295private:1296 const char *Namespace;1297 1298public:1299 explicit PragmaDiagnosticHandler(const char *NS)1300 : PragmaHandler("diagnostic"), Namespace(NS) {}1301 1302 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1303 Token &DiagToken) override {1304 SourceLocation DiagLoc = DiagToken.getLocation();1305 Token Tok;1306 PP.LexUnexpandedToken(Tok);1307 if (Tok.isNot(tok::identifier)) {1308 PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);1309 return;1310 }1311 IdentifierInfo *II = Tok.getIdentifierInfo();1312 PPCallbacks *Callbacks = PP.getPPCallbacks();1313 1314 // Get the next token, which is either an EOD or a string literal. We lex1315 // it now so that we can early return if the previous token was push or pop.1316 PP.LexUnexpandedToken(Tok);1317 1318 if (II->isStr("pop")) {1319 if (!PP.getDiagnostics().popMappings(DiagLoc))1320 PP.Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);1321 else if (Callbacks)1322 Callbacks->PragmaDiagnosticPop(DiagLoc, Namespace);1323 1324 if (Tok.isNot(tok::eod))1325 PP.Diag(Tok.getLocation(), diag::warn_pragma_diagnostic_invalid_token);1326 return;1327 } else if (II->isStr("push")) {1328 PP.getDiagnostics().pushMappings(DiagLoc);1329 if (Callbacks)1330 Callbacks->PragmaDiagnosticPush(DiagLoc, Namespace);1331 1332 if (Tok.isNot(tok::eod))1333 PP.Diag(Tok.getLocation(), diag::warn_pragma_diagnostic_invalid_token);1334 return;1335 }1336 1337 diag::Severity SV = llvm::StringSwitch<diag::Severity>(II->getName())1338 .Case("ignored", diag::Severity::Ignored)1339 .Case("warning", diag::Severity::Warning)1340 .Case("error", diag::Severity::Error)1341 .Case("fatal", diag::Severity::Fatal)1342 .Default(diag::Severity());1343 1344 if (SV == diag::Severity()) {1345 PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);1346 return;1347 }1348 1349 // At this point, we expect a string literal.1350 SourceLocation StringLoc = Tok.getLocation();1351 std::string WarningName;1352 if (!PP.FinishLexStringLiteral(Tok, WarningName, "pragma diagnostic",1353 /*AllowMacroExpansion=*/false))1354 return;1355 1356 if (Tok.isNot(tok::eod)) {1357 PP.Diag(Tok.getLocation(), diag::warn_pragma_diagnostic_invalid_token);1358 return;1359 }1360 1361 if (WarningName.size() < 3 || WarningName[0] != '-' ||1362 (WarningName[1] != 'W' && WarningName[1] != 'R')) {1363 PP.Diag(StringLoc, diag::warn_pragma_diagnostic_invalid_option);1364 return;1365 }1366 1367 diag::Flavor Flavor = WarningName[1] == 'W' ? diag::Flavor::WarningOrError1368 : diag::Flavor::Remark;1369 StringRef Group = StringRef(WarningName).substr(2);1370 bool unknownDiag = false;1371 if (Group == "everything") {1372 // Special handling for pragma clang diagnostic ... "-Weverything".1373 // There is no formal group named "everything", so there has to be a1374 // special case for it.1375 PP.getDiagnostics().setSeverityForAll(Flavor, SV, DiagLoc);1376 } else1377 unknownDiag = PP.getDiagnostics().setSeverityForGroup(Flavor, Group, SV,1378 DiagLoc);1379 if (unknownDiag)1380 PP.Diag(StringLoc, diag::warn_pragma_diagnostic_unknown_warning)1381 << WarningName;1382 else if (Callbacks)1383 Callbacks->PragmaDiagnostic(DiagLoc, Namespace, SV, WarningName);1384 }1385};1386 1387/// "\#pragma hdrstop [<header-name-string>]"1388struct PragmaHdrstopHandler : public PragmaHandler {1389 PragmaHdrstopHandler() : PragmaHandler("hdrstop") {}1390 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1391 Token &DepToken) override {1392 PP.HandlePragmaHdrstop(DepToken);1393 }1394};1395 1396/// "\#pragma warning(...)". MSVC's diagnostics do not map cleanly to clang's1397/// diagnostics, so we don't really implement this pragma. We parse it and1398/// ignore it to avoid -Wunknown-pragma warnings.1399struct PragmaWarningHandler : public PragmaHandler {1400 PragmaWarningHandler() : PragmaHandler("warning") {}1401 1402 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1403 Token &Tok) override {1404 // Parse things like:1405 // warning(push, 1)1406 // warning(pop)1407 // warning(disable : 1 2 3 ; error : 4 5 6 ; suppress : 7 8 9)1408 SourceLocation DiagLoc = Tok.getLocation();1409 PPCallbacks *Callbacks = PP.getPPCallbacks();1410 1411 PP.Lex(Tok);1412 if (Tok.isNot(tok::l_paren)) {1413 PP.Diag(Tok, diag::warn_pragma_warning_expected) << "(";1414 return;1415 }1416 1417 PP.Lex(Tok);1418 IdentifierInfo *II = Tok.getIdentifierInfo();1419 1420 if (II && II->isStr("push")) {1421 // #pragma warning( push[ ,n ] )1422 int Level = -1;1423 PP.Lex(Tok);1424 if (Tok.is(tok::comma)) {1425 PP.Lex(Tok);1426 uint64_t Value;1427 if (Tok.is(tok::numeric_constant) &&1428 PP.parseSimpleIntegerLiteral(Tok, Value))1429 Level = int(Value);1430 if (Level < 0 || Level > 4) {1431 PP.Diag(Tok, diag::warn_pragma_warning_push_level);1432 return;1433 }1434 }1435 PP.getDiagnostics().pushMappings(DiagLoc);1436 if (Callbacks)1437 Callbacks->PragmaWarningPush(DiagLoc, Level);1438 } else if (II && II->isStr("pop")) {1439 // #pragma warning( pop )1440 PP.Lex(Tok);1441 if (!PP.getDiagnostics().popMappings(DiagLoc))1442 PP.Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);1443 else if (Callbacks)1444 Callbacks->PragmaWarningPop(DiagLoc);1445 } else {1446 // #pragma warning( warning-specifier : warning-number-list1447 // [; warning-specifier : warning-number-list...] )1448 while (true) {1449 II = Tok.getIdentifierInfo();1450 if (!II && !Tok.is(tok::numeric_constant)) {1451 PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid);1452 return;1453 }1454 1455 // Figure out which warning specifier this is.1456 bool SpecifierValid;1457 PPCallbacks::PragmaWarningSpecifier Specifier;1458 if (II) {1459 int SpecifierInt = llvm::StringSwitch<int>(II->getName())1460 .Case("default", PPCallbacks::PWS_Default)1461 .Case("disable", PPCallbacks::PWS_Disable)1462 .Case("error", PPCallbacks::PWS_Error)1463 .Case("once", PPCallbacks::PWS_Once)1464 .Case("suppress", PPCallbacks::PWS_Suppress)1465 .Default(-1);1466 SpecifierValid = SpecifierInt != -1;1467 if (SpecifierValid)1468 Specifier =1469 static_cast<PPCallbacks::PragmaWarningSpecifier>(SpecifierInt);1470 1471 // If we read a correct specifier, snatch next token (that should be1472 // ":", checked later).1473 if (SpecifierValid)1474 PP.Lex(Tok);1475 } else {1476 // Token is a numeric constant. It should be either 1, 2, 3 or 4.1477 uint64_t Value;1478 if (PP.parseSimpleIntegerLiteral(Tok, Value)) {1479 if ((SpecifierValid = (Value >= 1) && (Value <= 4)))1480 Specifier = static_cast<PPCallbacks::PragmaWarningSpecifier>(1481 PPCallbacks::PWS_Level1 + Value - 1);1482 } else1483 SpecifierValid = false;1484 // Next token already snatched by parseSimpleIntegerLiteral.1485 }1486 1487 if (!SpecifierValid) {1488 PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid);1489 return;1490 }1491 if (Tok.isNot(tok::colon)) {1492 PP.Diag(Tok, diag::warn_pragma_warning_expected) << ":";1493 return;1494 }1495 1496 // Collect the warning ids.1497 SmallVector<int, 4> Ids;1498 PP.Lex(Tok);1499 while (Tok.is(tok::numeric_constant)) {1500 uint64_t Value;1501 if (!PP.parseSimpleIntegerLiteral(Tok, Value) || Value == 0 ||1502 Value > INT_MAX) {1503 PP.Diag(Tok, diag::warn_pragma_warning_expected_number);1504 return;1505 }1506 Ids.push_back(int(Value));1507 }1508 1509 // Only act on disable for now.1510 diag::Severity SV = diag::Severity();1511 if (Specifier == PPCallbacks::PWS_Disable)1512 SV = diag::Severity::Ignored;1513 if (SV != diag::Severity())1514 for (int Id : Ids) {1515 if (auto Group = diagGroupFromCLWarningID(Id)) {1516 bool unknownDiag = PP.getDiagnostics().setSeverityForGroup(1517 diag::Flavor::WarningOrError, *Group, SV, DiagLoc);1518 assert(!unknownDiag &&1519 "wd table should only contain known diags");1520 (void)unknownDiag;1521 }1522 }1523 1524 if (Callbacks)1525 Callbacks->PragmaWarning(DiagLoc, Specifier, Ids);1526 1527 // Parse the next specifier if there is a semicolon.1528 if (Tok.isNot(tok::semi))1529 break;1530 PP.Lex(Tok);1531 }1532 }1533 1534 if (Tok.isNot(tok::r_paren)) {1535 PP.Diag(Tok, diag::warn_pragma_warning_expected) << ")";1536 return;1537 }1538 1539 PP.Lex(Tok);1540 if (Tok.isNot(tok::eod))1541 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma warning";1542 }1543};1544 1545/// "\#pragma execution_character_set(...)". MSVC supports this pragma only1546/// for "UTF-8". We parse it and ignore it if UTF-8 is provided and warn1547/// otherwise to avoid -Wunknown-pragma warnings.1548struct PragmaExecCharsetHandler : public PragmaHandler {1549 PragmaExecCharsetHandler() : PragmaHandler("execution_character_set") {}1550 1551 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1552 Token &Tok) override {1553 // Parse things like:1554 // execution_character_set(push, "UTF-8")1555 // execution_character_set(pop)1556 SourceLocation DiagLoc = Tok.getLocation();1557 PPCallbacks *Callbacks = PP.getPPCallbacks();1558 1559 PP.Lex(Tok);1560 if (Tok.isNot(tok::l_paren)) {1561 PP.Diag(Tok, diag::warn_pragma_exec_charset_expected) << "(";1562 return;1563 }1564 1565 PP.Lex(Tok);1566 IdentifierInfo *II = Tok.getIdentifierInfo();1567 1568 if (II && II->isStr("push")) {1569 // #pragma execution_character_set( push[ , string ] )1570 PP.Lex(Tok);1571 if (Tok.is(tok::comma)) {1572 PP.Lex(Tok);1573 1574 std::string ExecCharset;1575 if (!PP.FinishLexStringLiteral(Tok, ExecCharset,1576 "pragma execution_character_set",1577 /*AllowMacroExpansion=*/false))1578 return;1579 1580 // MSVC supports either of these, but nothing else.1581 if (ExecCharset != "UTF-8" && ExecCharset != "utf-8") {1582 PP.Diag(Tok, diag::warn_pragma_exec_charset_push_invalid) << ExecCharset;1583 return;1584 }1585 }1586 if (Callbacks)1587 Callbacks->PragmaExecCharsetPush(DiagLoc, "UTF-8");1588 } else if (II && II->isStr("pop")) {1589 // #pragma execution_character_set( pop )1590 PP.Lex(Tok);1591 if (Callbacks)1592 Callbacks->PragmaExecCharsetPop(DiagLoc);1593 } else {1594 PP.Diag(Tok, diag::warn_pragma_exec_charset_spec_invalid);1595 return;1596 }1597 1598 if (Tok.isNot(tok::r_paren)) {1599 PP.Diag(Tok, diag::warn_pragma_exec_charset_expected) << ")";1600 return;1601 }1602 1603 PP.Lex(Tok);1604 if (Tok.isNot(tok::eod))1605 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma execution_character_set";1606 }1607};1608 1609/// PragmaIncludeAliasHandler - "\#pragma include_alias("...")".1610struct PragmaIncludeAliasHandler : public PragmaHandler {1611 PragmaIncludeAliasHandler() : PragmaHandler("include_alias") {}1612 1613 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1614 Token &IncludeAliasTok) override {1615 PP.HandlePragmaIncludeAlias(IncludeAliasTok);1616 }1617};1618 1619/// PragmaMessageHandler - Handle the microsoft and gcc \#pragma message1620/// extension. The syntax is:1621/// \code1622/// #pragma message(string)1623/// \endcode1624/// OR, in GCC mode:1625/// \code1626/// #pragma message string1627/// \endcode1628/// string is a string, which is fully macro expanded, and permits string1629/// concatenation, embedded escape characters, etc... See MSDN for more details.1630/// Also handles \#pragma GCC warning and \#pragma GCC error which take the same1631/// form as \#pragma message.1632struct PragmaMessageHandler : public PragmaHandler {1633private:1634 const PPCallbacks::PragmaMessageKind Kind;1635 const StringRef Namespace;1636 1637 static const char* PragmaKind(PPCallbacks::PragmaMessageKind Kind,1638 bool PragmaNameOnly = false) {1639 switch (Kind) {1640 case PPCallbacks::PMK_Message:1641 return PragmaNameOnly ? "message" : "pragma message";1642 case PPCallbacks::PMK_Warning:1643 return PragmaNameOnly ? "warning" : "pragma warning";1644 case PPCallbacks::PMK_Error:1645 return PragmaNameOnly ? "error" : "pragma error";1646 }1647 llvm_unreachable("Unknown PragmaMessageKind!");1648 }1649 1650public:1651 PragmaMessageHandler(PPCallbacks::PragmaMessageKind Kind,1652 StringRef Namespace = StringRef())1653 : PragmaHandler(PragmaKind(Kind, true)), Kind(Kind),1654 Namespace(Namespace) {}1655 1656 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1657 Token &Tok) override {1658 SourceLocation MessageLoc = Tok.getLocation();1659 PP.Lex(Tok);1660 bool ExpectClosingParen = false;1661 switch (Tok.getKind()) {1662 case tok::l_paren:1663 // We have a MSVC style pragma message.1664 ExpectClosingParen = true;1665 // Read the string.1666 PP.Lex(Tok);1667 break;1668 case tok::string_literal:1669 // We have a GCC style pragma message, and we just read the string.1670 break;1671 default:1672 PP.Diag(MessageLoc, diag::err_pragma_message_malformed) << Kind;1673 return;1674 }1675 1676 std::string MessageString;1677 if (!PP.FinishLexStringLiteral(Tok, MessageString, PragmaKind(Kind),1678 /*AllowMacroExpansion=*/true))1679 return;1680 1681 if (ExpectClosingParen) {1682 if (Tok.isNot(tok::r_paren)) {1683 PP.Diag(Tok.getLocation(), diag::err_pragma_message_malformed) << Kind;1684 return;1685 }1686 PP.Lex(Tok); // eat the r_paren.1687 }1688 1689 if (Tok.isNot(tok::eod)) {1690 PP.Diag(Tok.getLocation(), diag::err_pragma_message_malformed) << Kind;1691 return;1692 }1693 1694 // Output the message.1695 PP.Diag(MessageLoc, (Kind == PPCallbacks::PMK_Error)1696 ? diag::err_pragma_message1697 : diag::warn_pragma_message) << MessageString;1698 1699 // If the pragma is lexically sound, notify any interested PPCallbacks.1700 if (PPCallbacks *Callbacks = PP.getPPCallbacks())1701 Callbacks->PragmaMessage(MessageLoc, Namespace, Kind, MessageString);1702 }1703};1704 1705/// Handle the clang \#pragma module import extension. The syntax is:1706/// \code1707/// #pragma clang module import some.module.name1708/// \endcode1709struct PragmaModuleImportHandler : public PragmaHandler {1710 PragmaModuleImportHandler() : PragmaHandler("import") {}1711 1712 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1713 Token &Tok) override {1714 SourceLocation ImportLoc = Tok.getLocation();1715 1716 // Read the module name.1717 llvm::SmallVector<IdentifierLoc, 8> ModuleName;1718 if (LexModuleName(PP, Tok, ModuleName))1719 return;1720 1721 if (Tok.isNot(tok::eod))1722 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";1723 1724 // If we have a non-empty module path, load the named module.1725 Module *Imported =1726 PP.getModuleLoader().loadModule(ImportLoc, ModuleName, Module::Hidden,1727 /*IsInclusionDirective=*/false);1728 if (!Imported)1729 return;1730 1731 PP.makeModuleVisible(Imported, ImportLoc);1732 PP.EnterAnnotationToken(SourceRange(ImportLoc, ModuleName.back().getLoc()),1733 tok::annot_module_include, Imported);1734 if (auto *CB = PP.getPPCallbacks())1735 CB->moduleImport(ImportLoc, ModuleName, Imported);1736 }1737};1738 1739/// Handle the clang \#pragma module begin extension. The syntax is:1740/// \code1741/// #pragma clang module begin some.module.name1742/// ...1743/// #pragma clang module end1744/// \endcode1745struct PragmaModuleBeginHandler : public PragmaHandler {1746 PragmaModuleBeginHandler() : PragmaHandler("begin") {}1747 1748 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1749 Token &Tok) override {1750 SourceLocation BeginLoc = Tok.getLocation();1751 1752 // Read the module name.1753 llvm::SmallVector<IdentifierLoc, 8> ModuleName;1754 if (LexModuleName(PP, Tok, ModuleName))1755 return;1756 1757 if (Tok.isNot(tok::eod))1758 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";1759 1760 // We can only enter submodules of the current module.1761 StringRef Current = PP.getLangOpts().CurrentModule;1762 if (ModuleName.front().getIdentifierInfo()->getName() != Current) {1763 PP.Diag(ModuleName.front().getLoc(),1764 diag::err_pp_module_begin_wrong_module)1765 << ModuleName.front().getIdentifierInfo() << (ModuleName.size() > 1)1766 << Current.empty() << Current;1767 return;1768 }1769 1770 // Find the module we're entering. We require that a module map for it1771 // be loaded or implicitly loadable.1772 auto &HSI = PP.getHeaderSearchInfo();1773 auto &MM = HSI.getModuleMap();1774 Module *M = HSI.lookupModule(Current, ModuleName.front().getLoc());1775 if (!M) {1776 PP.Diag(ModuleName.front().getLoc(),1777 diag::err_pp_module_begin_no_module_map)1778 << Current;1779 return;1780 }1781 for (unsigned I = 1; I != ModuleName.size(); ++I) {1782 auto *NewM = MM.findOrInferSubmodule(1783 M, ModuleName[I].getIdentifierInfo()->getName());1784 if (!NewM) {1785 PP.Diag(ModuleName[I].getLoc(), diag::err_pp_module_begin_no_submodule)1786 << M->getFullModuleName() << ModuleName[I].getIdentifierInfo();1787 return;1788 }1789 M = NewM;1790 }1791 1792 // If the module isn't available, it doesn't make sense to enter it.1793 if (Preprocessor::checkModuleIsAvailable(1794 PP.getLangOpts(), PP.getTargetInfo(), *M, PP.getDiagnostics())) {1795 PP.Diag(BeginLoc, diag::note_pp_module_begin_here)1796 << M->getTopLevelModuleName();1797 return;1798 }1799 1800 // Enter the scope of the submodule.1801 PP.EnterSubmodule(M, BeginLoc, /*ForPragma*/true);1802 PP.EnterAnnotationToken(SourceRange(BeginLoc, ModuleName.back().getLoc()),1803 tok::annot_module_begin, M);1804 }1805};1806 1807/// Handle the clang \#pragma module end extension.1808struct PragmaModuleEndHandler : public PragmaHandler {1809 PragmaModuleEndHandler() : PragmaHandler("end") {}1810 1811 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1812 Token &Tok) override {1813 SourceLocation Loc = Tok.getLocation();1814 1815 PP.LexUnexpandedToken(Tok);1816 if (Tok.isNot(tok::eod))1817 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";1818 1819 Module *M = PP.LeaveSubmodule(/*ForPragma*/true);1820 if (M)1821 PP.EnterAnnotationToken(SourceRange(Loc), tok::annot_module_end, M);1822 else1823 PP.Diag(Loc, diag::err_pp_module_end_without_module_begin);1824 }1825};1826 1827/// Handle the clang \#pragma module build extension.1828struct PragmaModuleBuildHandler : public PragmaHandler {1829 PragmaModuleBuildHandler() : PragmaHandler("build") {}1830 1831 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1832 Token &Tok) override {1833 PP.HandlePragmaModuleBuild(Tok);1834 }1835};1836 1837/// Handle the clang \#pragma module load extension.1838struct PragmaModuleLoadHandler : public PragmaHandler {1839 PragmaModuleLoadHandler() : PragmaHandler("load") {}1840 1841 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1842 Token &Tok) override {1843 SourceLocation Loc = Tok.getLocation();1844 1845 // Read the module name.1846 llvm::SmallVector<IdentifierLoc, 8> ModuleName;1847 if (LexModuleName(PP, Tok, ModuleName))1848 return;1849 1850 if (Tok.isNot(tok::eod))1851 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";1852 1853 // Load the module, don't make it visible.1854 PP.getModuleLoader().loadModule(Loc, ModuleName, Module::Hidden,1855 /*IsInclusionDirective=*/false);1856 }1857};1858 1859/// PragmaPushMacroHandler - "\#pragma push_macro" saves the value of the1860/// macro on the top of the stack.1861struct PragmaPushMacroHandler : public PragmaHandler {1862 PragmaPushMacroHandler() : PragmaHandler("push_macro") {}1863 1864 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1865 Token &PushMacroTok) override {1866 PP.HandlePragmaPushMacro(PushMacroTok);1867 }1868};1869 1870/// PragmaPopMacroHandler - "\#pragma pop_macro" sets the value of the1871/// macro to the value on the top of the stack.1872struct PragmaPopMacroHandler : public PragmaHandler {1873 PragmaPopMacroHandler() : PragmaHandler("pop_macro") {}1874 1875 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1876 Token &PopMacroTok) override {1877 PP.HandlePragmaPopMacro(PopMacroTok);1878 }1879};1880 1881/// PragmaARCCFCodeAuditedHandler -1882/// \#pragma clang arc_cf_code_audited begin/end1883struct PragmaARCCFCodeAuditedHandler : public PragmaHandler {1884 PragmaARCCFCodeAuditedHandler() : PragmaHandler("arc_cf_code_audited") {}1885 1886 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1887 Token &NameTok) override {1888 SourceLocation Loc = NameTok.getLocation();1889 bool IsBegin;1890 1891 Token Tok;1892 1893 // Lex the 'begin' or 'end'.1894 PP.LexUnexpandedToken(Tok);1895 const IdentifierInfo *BeginEnd = Tok.getIdentifierInfo();1896 if (BeginEnd && BeginEnd->isStr("begin")) {1897 IsBegin = true;1898 } else if (BeginEnd && BeginEnd->isStr("end")) {1899 IsBegin = false;1900 } else {1901 PP.Diag(Tok.getLocation(), diag::err_pp_arc_cf_code_audited_syntax);1902 return;1903 }1904 1905 // Verify that this is followed by EOD.1906 PP.LexUnexpandedToken(Tok);1907 if (Tok.isNot(tok::eod))1908 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";1909 1910 // The start location of the active audit.1911 SourceLocation BeginLoc = PP.getPragmaARCCFCodeAuditedInfo().getLoc();1912 1913 // The start location we want after processing this.1914 SourceLocation NewLoc;1915 1916 if (IsBegin) {1917 // Complain about attempts to re-enter an audit.1918 if (BeginLoc.isValid()) {1919 PP.Diag(Loc, diag::err_pp_double_begin_of_arc_cf_code_audited);1920 PP.Diag(BeginLoc, diag::note_pragma_entered_here);1921 }1922 NewLoc = Loc;1923 } else {1924 // Complain about attempts to leave an audit that doesn't exist.1925 if (!BeginLoc.isValid()) {1926 PP.Diag(Loc, diag::err_pp_unmatched_end_of_arc_cf_code_audited);1927 return;1928 }1929 NewLoc = SourceLocation();1930 }1931 1932 PP.setPragmaARCCFCodeAuditedInfo(NameTok.getIdentifierInfo(), NewLoc);1933 }1934};1935 1936/// PragmaAssumeNonNullHandler -1937/// \#pragma clang assume_nonnull begin/end1938struct PragmaAssumeNonNullHandler : public PragmaHandler {1939 PragmaAssumeNonNullHandler() : PragmaHandler("assume_nonnull") {}1940 1941 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1942 Token &NameTok) override {1943 SourceLocation Loc = NameTok.getLocation();1944 bool IsBegin;1945 1946 Token Tok;1947 1948 // Lex the 'begin' or 'end'.1949 PP.LexUnexpandedToken(Tok);1950 const IdentifierInfo *BeginEnd = Tok.getIdentifierInfo();1951 if (BeginEnd && BeginEnd->isStr("begin")) {1952 IsBegin = true;1953 } else if (BeginEnd && BeginEnd->isStr("end")) {1954 IsBegin = false;1955 } else {1956 PP.Diag(Tok.getLocation(), diag::err_pp_assume_nonnull_syntax);1957 return;1958 }1959 1960 // Verify that this is followed by EOD.1961 PP.LexUnexpandedToken(Tok);1962 if (Tok.isNot(tok::eod))1963 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";1964 1965 // The start location of the active audit.1966 SourceLocation BeginLoc = PP.getPragmaAssumeNonNullLoc();1967 1968 // The start location we want after processing this.1969 SourceLocation NewLoc;1970 PPCallbacks *Callbacks = PP.getPPCallbacks();1971 1972 if (IsBegin) {1973 // Complain about attempts to re-enter an audit.1974 if (BeginLoc.isValid()) {1975 PP.Diag(Loc, diag::err_pp_double_begin_of_assume_nonnull);1976 PP.Diag(BeginLoc, diag::note_pragma_entered_here);1977 }1978 NewLoc = Loc;1979 if (Callbacks)1980 Callbacks->PragmaAssumeNonNullBegin(NewLoc);1981 } else {1982 // Complain about attempts to leave an audit that doesn't exist.1983 if (!BeginLoc.isValid()) {1984 PP.Diag(Loc, diag::err_pp_unmatched_end_of_assume_nonnull);1985 return;1986 }1987 NewLoc = SourceLocation();1988 if (Callbacks)1989 Callbacks->PragmaAssumeNonNullEnd(NewLoc);1990 }1991 1992 PP.setPragmaAssumeNonNullLoc(NewLoc);1993 }1994};1995 1996/// Handle "\#pragma region [...]"1997///1998/// The syntax is1999/// \code2000/// #pragma region [optional name]2001/// #pragma endregion [optional comment]2002/// \endcode2003///2004/// \note This is2005/// <a href="http://msdn.microsoft.com/en-us/library/b6xkz944(v=vs.80).aspx">editor-only</a>2006/// pragma, just skipped by compiler.2007struct PragmaRegionHandler : public PragmaHandler {2008 PragmaRegionHandler(const char *pragma) : PragmaHandler(pragma) {}2009 2010 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,2011 Token &NameTok) override {2012 // #pragma region: endregion matches can be verified2013 // __pragma(region): no sense, but ignored by msvc2014 // _Pragma is not valid for MSVC, but there isn't any point2015 // to handle a _Pragma differently.2016 }2017};2018 2019/// "\#pragma managed"2020/// "\#pragma managed(...)"2021/// "\#pragma unmanaged"2022/// MSVC ignores this pragma when not compiling using /clr, which clang doesn't2023/// support. We parse it and ignore it to avoid -Wunknown-pragma warnings.2024struct PragmaManagedHandler : public EmptyPragmaHandler {2025 PragmaManagedHandler(const char *pragma) : EmptyPragmaHandler(pragma) {}2026};2027 2028/// This handles parsing pragmas that take a macro name and optional message2029static IdentifierInfo *HandleMacroAnnotationPragma(Preprocessor &PP, Token &Tok,2030 const char *Pragma,2031 std::string &MessageString) {2032 PP.Lex(Tok);2033 if (Tok.isNot(tok::l_paren)) {2034 PP.Diag(Tok, diag::err_expected) << "(";2035 return nullptr;2036 }2037 2038 PP.LexUnexpandedToken(Tok);2039 if (!Tok.is(tok::identifier)) {2040 PP.Diag(Tok, diag::err_expected) << tok::identifier;2041 return nullptr;2042 }2043 IdentifierInfo *II = Tok.getIdentifierInfo();2044 2045 if (!II->hasMacroDefinition()) {2046 PP.Diag(Tok, diag::err_pp_visibility_non_macro) << II;2047 return nullptr;2048 }2049 2050 PP.Lex(Tok);2051 if (Tok.is(tok::comma)) {2052 PP.Lex(Tok);2053 if (!PP.FinishLexStringLiteral(Tok, MessageString, Pragma,2054 /*AllowMacroExpansion=*/true))2055 return nullptr;2056 }2057 2058 if (Tok.isNot(tok::r_paren)) {2059 PP.Diag(Tok, diag::err_expected) << ")";2060 return nullptr;2061 }2062 return II;2063}2064 2065/// "\#pragma clang deprecated(...)"2066///2067/// The syntax is2068/// \code2069/// #pragma clang deprecate(MACRO_NAME [, Message])2070/// \endcode2071struct PragmaDeprecatedHandler : public PragmaHandler {2072 PragmaDeprecatedHandler() : PragmaHandler("deprecated") {}2073 2074 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,2075 Token &Tok) override {2076 std::string MessageString;2077 2078 if (IdentifierInfo *II = HandleMacroAnnotationPragma(2079 PP, Tok, "#pragma clang deprecated", MessageString)) {2080 II->setIsDeprecatedMacro(true);2081 PP.addMacroDeprecationMsg(II, std::move(MessageString),2082 Tok.getLocation());2083 }2084 }2085};2086 2087/// "\#pragma clang restrict_expansion(...)"2088///2089/// The syntax is2090/// \code2091/// #pragma clang restrict_expansion(MACRO_NAME [, Message])2092/// \endcode2093struct PragmaRestrictExpansionHandler : public PragmaHandler {2094 PragmaRestrictExpansionHandler() : PragmaHandler("restrict_expansion") {}2095 2096 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,2097 Token &Tok) override {2098 std::string MessageString;2099 2100 if (IdentifierInfo *II = HandleMacroAnnotationPragma(2101 PP, Tok, "#pragma clang restrict_expansion", MessageString)) {2102 II->setIsRestrictExpansion(true);2103 PP.addRestrictExpansionMsg(II, std::move(MessageString),2104 Tok.getLocation());2105 }2106 }2107};2108 2109/// "\#pragma clang final(...)"2110///2111/// The syntax is2112/// \code2113/// #pragma clang final(MACRO_NAME)2114/// \endcode2115struct PragmaFinalHandler : public PragmaHandler {2116 PragmaFinalHandler() : PragmaHandler("final") {}2117 2118 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,2119 Token &Tok) override {2120 PP.Lex(Tok);2121 if (Tok.isNot(tok::l_paren)) {2122 PP.Diag(Tok, diag::err_expected) << "(";2123 return;2124 }2125 2126 PP.LexUnexpandedToken(Tok);2127 if (!Tok.is(tok::identifier)) {2128 PP.Diag(Tok, diag::err_expected) << tok::identifier;2129 return;2130 }2131 IdentifierInfo *II = Tok.getIdentifierInfo();2132 2133 if (!II->hasMacroDefinition()) {2134 PP.Diag(Tok, diag::err_pp_visibility_non_macro) << II;2135 return;2136 }2137 2138 PP.Lex(Tok);2139 if (Tok.isNot(tok::r_paren)) {2140 PP.Diag(Tok, diag::err_expected) << ")";2141 return;2142 }2143 II->setIsFinal(true);2144 PP.addFinalLoc(II, Tok.getLocation());2145 }2146};2147 2148} // namespace2149 2150/// RegisterBuiltinPragmas - Install the standard preprocessor pragmas:2151/// \#pragma GCC poison/system_header/dependency and \#pragma once.2152void Preprocessor::RegisterBuiltinPragmas() {2153 AddPragmaHandler(new PragmaOnceHandler());2154 AddPragmaHandler(new PragmaMarkHandler());2155 AddPragmaHandler(new PragmaPushMacroHandler());2156 AddPragmaHandler(new PragmaPopMacroHandler());2157 AddPragmaHandler(new PragmaMessageHandler(PPCallbacks::PMK_Message));2158 2159 // #pragma GCC ...2160 AddPragmaHandler("GCC", new PragmaPoisonHandler());2161 AddPragmaHandler("GCC", new PragmaSystemHeaderHandler());2162 AddPragmaHandler("GCC", new PragmaDependencyHandler());2163 AddPragmaHandler("GCC", new PragmaDiagnosticHandler("GCC"));2164 AddPragmaHandler("GCC", new PragmaMessageHandler(PPCallbacks::PMK_Warning,2165 "GCC"));2166 AddPragmaHandler("GCC", new PragmaMessageHandler(PPCallbacks::PMK_Error,2167 "GCC"));2168 // #pragma clang ...2169 AddPragmaHandler("clang", new PragmaPoisonHandler());2170 AddPragmaHandler("clang", new PragmaSystemHeaderHandler());2171 AddPragmaHandler("clang", new PragmaDebugHandler());2172 AddPragmaHandler("clang", new PragmaDependencyHandler());2173 AddPragmaHandler("clang", new PragmaDiagnosticHandler("clang"));2174 AddPragmaHandler("clang", new PragmaARCCFCodeAuditedHandler());2175 AddPragmaHandler("clang", new PragmaAssumeNonNullHandler());2176 AddPragmaHandler("clang", new PragmaDeprecatedHandler());2177 AddPragmaHandler("clang", new PragmaRestrictExpansionHandler());2178 AddPragmaHandler("clang", new PragmaFinalHandler());2179 2180 // #pragma clang module ...2181 auto *ModuleHandler = new PragmaNamespace("module");2182 AddPragmaHandler("clang", ModuleHandler);2183 ModuleHandler->AddPragma(new PragmaModuleImportHandler());2184 ModuleHandler->AddPragma(new PragmaModuleBeginHandler());2185 ModuleHandler->AddPragma(new PragmaModuleEndHandler());2186 ModuleHandler->AddPragma(new PragmaModuleBuildHandler());2187 ModuleHandler->AddPragma(new PragmaModuleLoadHandler());2188 2189 // Safe Buffers pragmas2190 AddPragmaHandler("clang", new PragmaUnsafeBufferUsageHandler);2191 2192 // Add region pragmas.2193 AddPragmaHandler(new PragmaRegionHandler("region"));2194 AddPragmaHandler(new PragmaRegionHandler("endregion"));2195 2196 // MS extensions.2197 if (LangOpts.MicrosoftExt) {2198 AddPragmaHandler(new PragmaWarningHandler());2199 AddPragmaHandler(new PragmaExecCharsetHandler());2200 AddPragmaHandler(new PragmaIncludeAliasHandler());2201 AddPragmaHandler(new PragmaHdrstopHandler());2202 AddPragmaHandler(new PragmaSystemHeaderHandler());2203 AddPragmaHandler(new PragmaManagedHandler("managed"));2204 AddPragmaHandler(new PragmaManagedHandler("unmanaged"));2205 }2206 2207 // Pragmas added by plugins2208 for (const PragmaHandlerRegistry::entry &handler :2209 PragmaHandlerRegistry::entries()) {2210 AddPragmaHandler(handler.instantiate().release());2211 }2212}2213 2214/// Ignore all pragmas, useful for modes such as -Eonly which would otherwise2215/// warn about those pragmas being unknown.2216void Preprocessor::IgnorePragmas() {2217 AddPragmaHandler(new EmptyPragmaHandler());2218 // Also ignore all pragmas in all namespaces created2219 // in Preprocessor::RegisterBuiltinPragmas().2220 AddPragmaHandler("GCC", new EmptyPragmaHandler());2221 AddPragmaHandler("clang", new EmptyPragmaHandler());2222}2223