Path: blob/main/contrib/llvm-project/clang/lib/Lex/Pragma.cpp
35233 views
//===- Pragma.cpp - Pragma registration and handling ----------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements the PragmaHandler/PragmaTable interfaces and implements9// pragma related methods of the Preprocessor class.10//11//===----------------------------------------------------------------------===//1213#include "clang/Lex/Pragma.h"14#include "clang/Basic/CLWarnings.h"15#include "clang/Basic/Diagnostic.h"16#include "clang/Basic/FileManager.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/STLExtras.h"39#include "llvm/ADT/SmallString.h"40#include "llvm/ADT/SmallVector.h"41#include "llvm/ADT/StringRef.h"42#include "llvm/Support/Compiler.h"43#include "llvm/Support/ErrorHandling.h"44#include "llvm/Support/Timer.h"45#include <algorithm>46#include <cassert>47#include <cstddef>48#include <cstdint>49#include <limits>50#include <optional>51#include <string>52#include <utility>53#include <vector>5455using namespace clang;5657// Out-of-line destructor to provide a home for the class.58PragmaHandler::~PragmaHandler() = default;5960//===----------------------------------------------------------------------===//61// EmptyPragmaHandler Implementation.62//===----------------------------------------------------------------------===//6364EmptyPragmaHandler::EmptyPragmaHandler(StringRef Name) : PragmaHandler(Name) {}6566void EmptyPragmaHandler::HandlePragma(Preprocessor &PP,67PragmaIntroducer Introducer,68Token &FirstToken) {}6970//===----------------------------------------------------------------------===//71// PragmaNamespace Implementation.72//===----------------------------------------------------------------------===//7374/// FindHandler - Check to see if there is already a handler for the75/// specified name. If not, return the handler for the null identifier if it76/// exists, otherwise return null. If IgnoreNull is true (the default) then77/// the null handler isn't returned on failure to match.78PragmaHandler *PragmaNamespace::FindHandler(StringRef Name,79bool IgnoreNull) const {80auto I = Handlers.find(Name);81if (I != Handlers.end())82return I->getValue().get();83if (IgnoreNull)84return nullptr;85I = Handlers.find(StringRef());86if (I != Handlers.end())87return I->getValue().get();88return nullptr;89}9091void PragmaNamespace::AddPragma(PragmaHandler *Handler) {92assert(!Handlers.count(Handler->getName()) &&93"A handler with this name is already registered in this namespace");94Handlers[Handler->getName()].reset(Handler);95}9697void PragmaNamespace::RemovePragmaHandler(PragmaHandler *Handler) {98auto I = Handlers.find(Handler->getName());99assert(I != Handlers.end() &&100"Handler not registered in this namespace");101// Release ownership back to the caller.102I->getValue().release();103Handlers.erase(I);104}105106void PragmaNamespace::HandlePragma(Preprocessor &PP,107PragmaIntroducer Introducer, Token &Tok) {108// Read the 'namespace' that the directive is in, e.g. STDC. Do not macro109// expand it, the user can have a STDC #define, that should not affect this.110PP.LexUnexpandedToken(Tok);111112// Get the handler for this token. If there is no handler, ignore the pragma.113PragmaHandler *Handler114= FindHandler(Tok.getIdentifierInfo() ? Tok.getIdentifierInfo()->getName()115: StringRef(),116/*IgnoreNull=*/false);117if (!Handler) {118PP.Diag(Tok, diag::warn_pragma_ignored);119return;120}121122// Otherwise, pass it down.123Handler->HandlePragma(PP, Introducer, Tok);124}125126//===----------------------------------------------------------------------===//127// Preprocessor Pragma Directive Handling.128//===----------------------------------------------------------------------===//129130namespace {131// TokenCollector provides the option to collect tokens that were "read"132// and return them to the stream to be read later.133// Currently used when reading _Pragma/__pragma directives.134struct TokenCollector {135Preprocessor &Self;136bool Collect;137SmallVector<Token, 3> Tokens;138Token &Tok;139140void lex() {141if (Collect)142Tokens.push_back(Tok);143Self.Lex(Tok);144}145146void revert() {147assert(Collect && "did not collect tokens");148assert(!Tokens.empty() && "collected unexpected number of tokens");149150// Push the ( "string" ) tokens into the token stream.151auto Toks = std::make_unique<Token[]>(Tokens.size());152std::copy(Tokens.begin() + 1, Tokens.end(), Toks.get());153Toks[Tokens.size() - 1] = Tok;154Self.EnterTokenStream(std::move(Toks), Tokens.size(),155/*DisableMacroExpansion*/ true,156/*IsReinject*/ true);157158// ... and return the pragma token unchanged.159Tok = *Tokens.begin();160}161};162} // namespace163164/// HandlePragmaDirective - The "\#pragma" directive has been parsed. Lex the165/// rest of the pragma, passing it to the registered pragma handlers.166void Preprocessor::HandlePragmaDirective(PragmaIntroducer Introducer) {167if (Callbacks)168Callbacks->PragmaDirective(Introducer.Loc, Introducer.Kind);169170if (!PragmasEnabled)171return;172173++NumPragma;174175// Invoke the first level of pragma handlers which reads the namespace id.176Token Tok;177PragmaHandlers->HandlePragma(*this, Introducer, Tok);178179// If the pragma handler didn't read the rest of the line, consume it now.180if ((CurTokenLexer && CurTokenLexer->isParsingPreprocessorDirective())181|| (CurPPLexer && CurPPLexer->ParsingPreprocessorDirective))182DiscardUntilEndOfDirective();183}184185/// Handle_Pragma - Read a _Pragma directive, slice it up, process it, then186/// return the first token after the directive. The _Pragma token has just187/// been read into 'Tok'.188void Preprocessor::Handle_Pragma(Token &Tok) {189// C11 6.10.3.4/3:190// all pragma unary operator expressions within [a completely191// macro-replaced preprocessing token sequence] are [...] processed [after192// rescanning is complete]193//194// This means that we execute _Pragma operators in two cases:195//196// 1) on token sequences that would otherwise be produced as the output of197// phase 4 of preprocessing, and198// 2) on token sequences formed as the macro-replaced token sequence of a199// macro argument200//201// Case #2 appears to be a wording bug: only _Pragmas that would survive to202// the end of phase 4 should actually be executed. Discussion on the WG14203// mailing list suggests that a _Pragma operator is notionally checked early,204// but only pragmas that survive to the end of phase 4 should be executed.205//206// In Case #2, we check the syntax now, but then put the tokens back into the207// token stream for later consumption.208209TokenCollector Toks = {*this, InMacroArgPreExpansion, {}, Tok};210211// Remember the pragma token location.212SourceLocation PragmaLoc = Tok.getLocation();213214// Read the '('.215Toks.lex();216if (Tok.isNot(tok::l_paren)) {217Diag(PragmaLoc, diag::err__Pragma_malformed);218return;219}220221// Read the '"..."'.222Toks.lex();223if (!tok::isStringLiteral(Tok.getKind())) {224Diag(PragmaLoc, diag::err__Pragma_malformed);225// Skip bad tokens, and the ')', if present.226if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::eof))227Lex(Tok);228while (Tok.isNot(tok::r_paren) &&229!Tok.isAtStartOfLine() &&230Tok.isNot(tok::eof))231Lex(Tok);232if (Tok.is(tok::r_paren))233Lex(Tok);234return;235}236237if (Tok.hasUDSuffix()) {238Diag(Tok, diag::err_invalid_string_udl);239// Skip this token, and the ')', if present.240Lex(Tok);241if (Tok.is(tok::r_paren))242Lex(Tok);243return;244}245246// Remember the string.247Token StrTok = Tok;248249// Read the ')'.250Toks.lex();251if (Tok.isNot(tok::r_paren)) {252Diag(PragmaLoc, diag::err__Pragma_malformed);253return;254}255256// If we're expanding a macro argument, put the tokens back.257if (InMacroArgPreExpansion) {258Toks.revert();259return;260}261262SourceLocation RParenLoc = Tok.getLocation();263bool Invalid = false;264SmallString<64> StrVal;265StrVal.resize(StrTok.getLength());266StringRef StrValRef = getSpelling(StrTok, StrVal, &Invalid);267if (Invalid) {268Diag(PragmaLoc, diag::err__Pragma_malformed);269return;270}271272assert(StrValRef.size() <= StrVal.size());273274// If the token was spelled somewhere else, copy it.275if (StrValRef.begin() != StrVal.begin())276StrVal.assign(StrValRef);277// Truncate if necessary.278else if (StrValRef.size() != StrVal.size())279StrVal.resize(StrValRef.size());280281// The _Pragma is lexically sound. Destringize according to C11 6.10.9.1.282prepare_PragmaString(StrVal);283284// Plop the string (including the newline and trailing null) into a buffer285// where we can lex it.286Token TmpTok;287TmpTok.startToken();288CreateString(StrVal, TmpTok);289SourceLocation TokLoc = TmpTok.getLocation();290291// Make and enter a lexer object so that we lex and expand the tokens just292// like any others.293Lexer *TL = Lexer::Create_PragmaLexer(TokLoc, PragmaLoc, RParenLoc,294StrVal.size(), *this);295296EnterSourceFileWithLexer(TL, nullptr);297298// With everything set up, lex this as a #pragma directive.299HandlePragmaDirective({PIK__Pragma, PragmaLoc});300301// Finally, return whatever came after the pragma directive.302return Lex(Tok);303}304305void clang::prepare_PragmaString(SmallVectorImpl<char> &StrVal) {306if (StrVal[0] == 'L' || StrVal[0] == 'U' ||307(StrVal[0] == 'u' && StrVal[1] != '8'))308StrVal.erase(StrVal.begin());309else if (StrVal[0] == 'u')310StrVal.erase(StrVal.begin(), StrVal.begin() + 2);311312if (StrVal[0] == 'R') {313// FIXME: C++11 does not specify how to handle raw-string-literals here.314// We strip off the 'R', the quotes, the d-char-sequences, and the parens.315assert(StrVal[1] == '"' && StrVal[StrVal.size() - 1] == '"' &&316"Invalid raw string token!");317318// Measure the length of the d-char-sequence.319unsigned NumDChars = 0;320while (StrVal[2 + NumDChars] != '(') {321assert(NumDChars < (StrVal.size() - 5) / 2 &&322"Invalid raw string token!");323++NumDChars;324}325assert(StrVal[StrVal.size() - 2 - NumDChars] == ')');326327// Remove 'R " d-char-sequence' and 'd-char-sequence "'. We'll replace the328// parens below.329StrVal.erase(StrVal.begin(), StrVal.begin() + 2 + NumDChars);330StrVal.erase(StrVal.end() - 1 - NumDChars, StrVal.end());331} else {332assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' &&333"Invalid string token!");334335// Remove escaped quotes and escapes.336unsigned ResultPos = 1;337for (size_t i = 1, e = StrVal.size() - 1; i != e; ++i) {338// Skip escapes. \\ -> '\' and \" -> '"'.339if (StrVal[i] == '\\' && i + 1 < e &&340(StrVal[i + 1] == '\\' || StrVal[i + 1] == '"'))341++i;342StrVal[ResultPos++] = StrVal[i];343}344StrVal.erase(StrVal.begin() + ResultPos, StrVal.end() - 1);345}346347// Remove the front quote, replacing it with a space, so that the pragma348// contents appear to have a space before them.349StrVal[0] = ' ';350351// Replace the terminating quote with a \n.352StrVal[StrVal.size() - 1] = '\n';353}354355/// HandleMicrosoft__pragma - Like Handle_Pragma except the pragma text356/// is not enclosed within a string literal.357void Preprocessor::HandleMicrosoft__pragma(Token &Tok) {358// During macro pre-expansion, check the syntax now but put the tokens back359// into the token stream for later consumption. Same as Handle_Pragma.360TokenCollector Toks = {*this, InMacroArgPreExpansion, {}, Tok};361362// Remember the pragma token location.363SourceLocation PragmaLoc = Tok.getLocation();364365// Read the '('.366Toks.lex();367if (Tok.isNot(tok::l_paren)) {368Diag(PragmaLoc, diag::err__Pragma_malformed);369return;370}371372// Get the tokens enclosed within the __pragma(), as well as the final ')'.373SmallVector<Token, 32> PragmaToks;374int NumParens = 0;375Toks.lex();376while (Tok.isNot(tok::eof)) {377PragmaToks.push_back(Tok);378if (Tok.is(tok::l_paren))379NumParens++;380else if (Tok.is(tok::r_paren) && NumParens-- == 0)381break;382Toks.lex();383}384385if (Tok.is(tok::eof)) {386Diag(PragmaLoc, diag::err_unterminated___pragma);387return;388}389390// If we're expanding a macro argument, put the tokens back.391if (InMacroArgPreExpansion) {392Toks.revert();393return;394}395396PragmaToks.front().setFlag(Token::LeadingSpace);397398// Replace the ')' with an EOD to mark the end of the pragma.399PragmaToks.back().setKind(tok::eod);400401Token *TokArray = new Token[PragmaToks.size()];402std::copy(PragmaToks.begin(), PragmaToks.end(), TokArray);403404// Push the tokens onto the stack.405EnterTokenStream(TokArray, PragmaToks.size(), true, true,406/*IsReinject*/ false);407408// With everything set up, lex this as a #pragma directive.409HandlePragmaDirective({PIK___pragma, PragmaLoc});410411// Finally, return whatever came after the pragma directive.412return Lex(Tok);413}414415/// HandlePragmaOnce - Handle \#pragma once. OnceTok is the 'once'.416void Preprocessor::HandlePragmaOnce(Token &OnceTok) {417// Don't honor the 'once' when handling the primary source file, unless418// this is a prefix to a TU, which indicates we're generating a PCH file, or419// when the main file is a header (e.g. when -xc-header is provided on the420// commandline).421if (isInPrimaryFile() && TUKind != TU_Prefix && !getLangOpts().IsHeaderFile) {422Diag(OnceTok, diag::pp_pragma_once_in_main_file);423return;424}425426// Get the current file lexer we're looking at. Ignore _Pragma 'files' etc.427// Mark the file as a once-only file now.428HeaderInfo.MarkFileIncludeOnce(*getCurrentFileLexer()->getFileEntry());429}430431void Preprocessor::HandlePragmaMark(Token &MarkTok) {432assert(CurPPLexer && "No current lexer?");433434SmallString<64> Buffer;435CurLexer->ReadToEndOfLine(&Buffer);436if (Callbacks)437Callbacks->PragmaMark(MarkTok.getLocation(), Buffer);438}439440/// HandlePragmaPoison - Handle \#pragma GCC poison. PoisonTok is the 'poison'.441void Preprocessor::HandlePragmaPoison() {442Token Tok;443444while (true) {445// Read the next token to poison. While doing this, pretend that we are446// skipping while reading the identifier to poison.447// This avoids errors on code like:448// #pragma GCC poison X449// #pragma GCC poison X450if (CurPPLexer) CurPPLexer->LexingRawMode = true;451LexUnexpandedToken(Tok);452if (CurPPLexer) CurPPLexer->LexingRawMode = false;453454// If we reached the end of line, we're done.455if (Tok.is(tok::eod)) return;456457// Can only poison identifiers.458if (Tok.isNot(tok::raw_identifier)) {459Diag(Tok, diag::err_pp_invalid_poison);460return;461}462463// Look up the identifier info for the token. We disabled identifier lookup464// by saying we're skipping contents, so we need to do this manually.465IdentifierInfo *II = LookUpIdentifierInfo(Tok);466467// Already poisoned.468if (II->isPoisoned()) continue;469470// If this is a macro identifier, emit a warning.471if (isMacroDefined(II))472Diag(Tok, diag::pp_poisoning_existing_macro);473474// Finally, poison it!475II->setIsPoisoned();476if (II->isFromAST())477II->setChangedSinceDeserialization();478}479}480481/// HandlePragmaSystemHeader - Implement \#pragma GCC system_header. We know482/// that the whole directive has been parsed.483void Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) {484if (isInPrimaryFile()) {485Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);486return;487}488489// Get the current file lexer we're looking at. Ignore _Pragma 'files' etc.490PreprocessorLexer *TheLexer = getCurrentFileLexer();491492// Mark the file as a system header.493HeaderInfo.MarkFileSystemHeader(*TheLexer->getFileEntry());494495PresumedLoc PLoc = SourceMgr.getPresumedLoc(SysHeaderTok.getLocation());496if (PLoc.isInvalid())497return;498499unsigned FilenameID = SourceMgr.getLineTableFilenameID(PLoc.getFilename());500501// Notify the client, if desired, that we are in a new source file.502if (Callbacks)503Callbacks->FileChanged(SysHeaderTok.getLocation(),504PPCallbacks::SystemHeaderPragma, SrcMgr::C_System);505506// Emit a line marker. This will change any source locations from this point507// forward to realize they are in a system header.508// Create a line note with this information.509SourceMgr.AddLineNote(SysHeaderTok.getLocation(), PLoc.getLine() + 1,510FilenameID, /*IsEntry=*/false, /*IsExit=*/false,511SrcMgr::C_System);512}513514/// HandlePragmaDependency - Handle \#pragma GCC dependency "foo" blah.515void Preprocessor::HandlePragmaDependency(Token &DependencyTok) {516Token FilenameTok;517if (LexHeaderName(FilenameTok, /*AllowConcatenation*/false))518return;519520// If the next token wasn't a header-name, diagnose the error.521if (FilenameTok.isNot(tok::header_name)) {522Diag(FilenameTok.getLocation(), diag::err_pp_expects_filename);523return;524}525526// Reserve a buffer to get the spelling.527SmallString<128> FilenameBuffer;528bool Invalid = false;529StringRef Filename = getSpelling(FilenameTok, FilenameBuffer, &Invalid);530if (Invalid)531return;532533bool isAngled =534GetIncludeFilenameSpelling(FilenameTok.getLocation(), Filename);535// If GetIncludeFilenameSpelling set the start ptr to null, there was an536// error.537if (Filename.empty())538return;539540// Search include directories for this file.541OptionalFileEntryRef File =542LookupFile(FilenameTok.getLocation(), Filename, isAngled, nullptr,543nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);544if (!File) {545if (!SuppressIncludeNotFoundError)546Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;547return;548}549550OptionalFileEntryRef CurFile = getCurrentFileLexer()->getFileEntry();551552// If this file is older than the file it depends on, emit a diagnostic.553if (CurFile && CurFile->getModificationTime() < File->getModificationTime()) {554// Lex tokens at the end of the message and include them in the message.555std::string Message;556Lex(DependencyTok);557while (DependencyTok.isNot(tok::eod)) {558Message += getSpelling(DependencyTok) + " ";559Lex(DependencyTok);560}561562// Remove the trailing ' ' if present.563if (!Message.empty())564Message.erase(Message.end()-1);565Diag(FilenameTok, diag::pp_out_of_date_dependency) << Message;566}567}568569/// ParsePragmaPushOrPopMacro - Handle parsing of pragma push_macro/pop_macro.570/// Return the IdentifierInfo* associated with the macro to push or pop.571IdentifierInfo *Preprocessor::ParsePragmaPushOrPopMacro(Token &Tok) {572// Remember the pragma token location.573Token PragmaTok = Tok;574575// Read the '('.576Lex(Tok);577if (Tok.isNot(tok::l_paren)) {578Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)579<< getSpelling(PragmaTok);580return nullptr;581}582583// Read the macro name string.584Lex(Tok);585if (Tok.isNot(tok::string_literal)) {586Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)587<< getSpelling(PragmaTok);588return nullptr;589}590591if (Tok.hasUDSuffix()) {592Diag(Tok, diag::err_invalid_string_udl);593return nullptr;594}595596// Remember the macro string.597std::string StrVal = getSpelling(Tok);598599// Read the ')'.600Lex(Tok);601if (Tok.isNot(tok::r_paren)) {602Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)603<< getSpelling(PragmaTok);604return nullptr;605}606607assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' &&608"Invalid string token!");609610// Create a Token from the string.611Token MacroTok;612MacroTok.startToken();613MacroTok.setKind(tok::raw_identifier);614CreateString(StringRef(&StrVal[1], StrVal.size() - 2), MacroTok);615616// Get the IdentifierInfo of MacroToPushTok.617return LookUpIdentifierInfo(MacroTok);618}619620/// Handle \#pragma push_macro.621///622/// The syntax is:623/// \code624/// #pragma push_macro("macro")625/// \endcode626void Preprocessor::HandlePragmaPushMacro(Token &PushMacroTok) {627// Parse the pragma directive and get the macro IdentifierInfo*.628IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PushMacroTok);629if (!IdentInfo) return;630631// Get the MacroInfo associated with IdentInfo.632MacroInfo *MI = getMacroInfo(IdentInfo);633634if (MI) {635// Allow the original MacroInfo to be redefined later.636MI->setIsAllowRedefinitionsWithoutWarning(true);637}638639// Push the cloned MacroInfo so we can retrieve it later.640PragmaPushMacroInfo[IdentInfo].push_back(MI);641}642643/// Handle \#pragma pop_macro.644///645/// The syntax is:646/// \code647/// #pragma pop_macro("macro")648/// \endcode649void Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) {650SourceLocation MessageLoc = PopMacroTok.getLocation();651652// Parse the pragma directive and get the macro IdentifierInfo*.653IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PopMacroTok);654if (!IdentInfo) return;655656// Find the vector<MacroInfo*> associated with the macro.657llvm::DenseMap<IdentifierInfo *, std::vector<MacroInfo *>>::iterator iter =658PragmaPushMacroInfo.find(IdentInfo);659if (iter != PragmaPushMacroInfo.end()) {660// Forget the MacroInfo currently associated with IdentInfo.661if (MacroInfo *MI = getMacroInfo(IdentInfo)) {662if (MI->isWarnIfUnused())663WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());664appendMacroDirective(IdentInfo, AllocateUndefMacroDirective(MessageLoc));665}666667// Get the MacroInfo we want to reinstall.668MacroInfo *MacroToReInstall = iter->second.back();669670if (MacroToReInstall)671// Reinstall the previously pushed macro.672appendDefMacroDirective(IdentInfo, MacroToReInstall, MessageLoc);673674// Pop PragmaPushMacroInfo stack.675iter->second.pop_back();676if (iter->second.empty())677PragmaPushMacroInfo.erase(iter);678} else {679Diag(MessageLoc, diag::warn_pragma_pop_macro_no_push)680<< IdentInfo->getName();681}682}683684void Preprocessor::HandlePragmaIncludeAlias(Token &Tok) {685// We will either get a quoted filename or a bracketed filename, and we686// have to track which we got. The first filename is the source name,687// and the second name is the mapped filename. If the first is quoted,688// the second must be as well (cannot mix and match quotes and brackets).689690// Get the open paren691Lex(Tok);692if (Tok.isNot(tok::l_paren)) {693Diag(Tok, diag::warn_pragma_include_alias_expected) << "(";694return;695}696697// We expect either a quoted string literal, or a bracketed name698Token SourceFilenameTok;699if (LexHeaderName(SourceFilenameTok))700return;701702StringRef SourceFileName;703SmallString<128> FileNameBuffer;704if (SourceFilenameTok.is(tok::header_name)) {705SourceFileName = getSpelling(SourceFilenameTok, FileNameBuffer);706} else {707Diag(Tok, diag::warn_pragma_include_alias_expected_filename);708return;709}710FileNameBuffer.clear();711712// Now we expect a comma, followed by another include name713Lex(Tok);714if (Tok.isNot(tok::comma)) {715Diag(Tok, diag::warn_pragma_include_alias_expected) << ",";716return;717}718719Token ReplaceFilenameTok;720if (LexHeaderName(ReplaceFilenameTok))721return;722723StringRef ReplaceFileName;724if (ReplaceFilenameTok.is(tok::header_name)) {725ReplaceFileName = getSpelling(ReplaceFilenameTok, FileNameBuffer);726} else {727Diag(Tok, diag::warn_pragma_include_alias_expected_filename);728return;729}730731// Finally, we expect the closing paren732Lex(Tok);733if (Tok.isNot(tok::r_paren)) {734Diag(Tok, diag::warn_pragma_include_alias_expected) << ")";735return;736}737738// Now that we have the source and target filenames, we need to make sure739// they're both of the same type (angled vs non-angled)740StringRef OriginalSource = SourceFileName;741742bool SourceIsAngled =743GetIncludeFilenameSpelling(SourceFilenameTok.getLocation(),744SourceFileName);745bool ReplaceIsAngled =746GetIncludeFilenameSpelling(ReplaceFilenameTok.getLocation(),747ReplaceFileName);748if (!SourceFileName.empty() && !ReplaceFileName.empty() &&749(SourceIsAngled != ReplaceIsAngled)) {750unsigned int DiagID;751if (SourceIsAngled)752DiagID = diag::warn_pragma_include_alias_mismatch_angle;753else754DiagID = diag::warn_pragma_include_alias_mismatch_quote;755756Diag(SourceFilenameTok.getLocation(), DiagID)757<< SourceFileName758<< ReplaceFileName;759760return;761}762763// Now we can let the include handler know about this mapping764getHeaderSearchInfo().AddIncludeAlias(OriginalSource, ReplaceFileName);765}766767// Lex a component of a module name: either an identifier or a string literal;768// for components that can be expressed both ways, the two forms are equivalent.769static bool LexModuleNameComponent(770Preprocessor &PP, Token &Tok,771std::pair<IdentifierInfo *, SourceLocation> &ModuleNameComponent,772bool First) {773PP.LexUnexpandedToken(Tok);774if (Tok.is(tok::string_literal) && !Tok.hasUDSuffix()) {775StringLiteralParser Literal(Tok, PP);776if (Literal.hadError)777return true;778ModuleNameComponent = std::make_pair(779PP.getIdentifierInfo(Literal.GetString()), Tok.getLocation());780} else if (!Tok.isAnnotation() && Tok.getIdentifierInfo()) {781ModuleNameComponent =782std::make_pair(Tok.getIdentifierInfo(), Tok.getLocation());783} else {784PP.Diag(Tok.getLocation(), diag::err_pp_expected_module_name) << First;785return true;786}787return false;788}789790static bool LexModuleName(791Preprocessor &PP, Token &Tok,792llvm::SmallVectorImpl<std::pair<IdentifierInfo *, SourceLocation>>793&ModuleName) {794while (true) {795std::pair<IdentifierInfo*, SourceLocation> NameComponent;796if (LexModuleNameComponent(PP, Tok, NameComponent, ModuleName.empty()))797return true;798ModuleName.push_back(NameComponent);799800PP.LexUnexpandedToken(Tok);801if (Tok.isNot(tok::period))802return false;803}804}805806void Preprocessor::HandlePragmaModuleBuild(Token &Tok) {807SourceLocation Loc = Tok.getLocation();808809std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc;810if (LexModuleNameComponent(*this, Tok, ModuleNameLoc, true))811return;812IdentifierInfo *ModuleName = ModuleNameLoc.first;813814LexUnexpandedToken(Tok);815if (Tok.isNot(tok::eod)) {816Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";817DiscardUntilEndOfDirective();818}819820CurLexer->LexingRawMode = true;821822auto TryConsumeIdentifier = [&](StringRef Ident) -> bool {823if (Tok.getKind() != tok::raw_identifier ||824Tok.getRawIdentifier() != Ident)825return false;826CurLexer->Lex(Tok);827return true;828};829830// Scan forward looking for the end of the module.831const char *Start = CurLexer->getBufferLocation();832const char *End = nullptr;833unsigned NestingLevel = 1;834while (true) {835End = CurLexer->getBufferLocation();836CurLexer->Lex(Tok);837838if (Tok.is(tok::eof)) {839Diag(Loc, diag::err_pp_module_build_missing_end);840break;841}842843if (Tok.isNot(tok::hash) || !Tok.isAtStartOfLine()) {844// Token was part of module; keep going.845continue;846}847848// We hit something directive-shaped; check to see if this is the end849// of the module build.850CurLexer->ParsingPreprocessorDirective = true;851CurLexer->Lex(Tok);852if (TryConsumeIdentifier("pragma") && TryConsumeIdentifier("clang") &&853TryConsumeIdentifier("module")) {854if (TryConsumeIdentifier("build"))855// #pragma clang module build -> entering a nested module build.856++NestingLevel;857else if (TryConsumeIdentifier("endbuild")) {858// #pragma clang module endbuild -> leaving a module build.859if (--NestingLevel == 0)860break;861}862// We should either be looking at the EOD or more of the current directive863// preceding the EOD. Either way we can ignore this token and keep going.864assert(Tok.getKind() != tok::eof && "missing EOD before EOF");865}866}867868CurLexer->LexingRawMode = false;869870// Load the extracted text as a preprocessed module.871assert(CurLexer->getBuffer().begin() <= Start &&872Start <= CurLexer->getBuffer().end() &&873CurLexer->getBuffer().begin() <= End &&874End <= CurLexer->getBuffer().end() &&875"module source range not contained within same file buffer");876TheModuleLoader.createModuleFromSource(Loc, ModuleName->getName(),877StringRef(Start, End - Start));878}879880void Preprocessor::HandlePragmaHdrstop(Token &Tok) {881Lex(Tok);882if (Tok.is(tok::l_paren)) {883Diag(Tok.getLocation(), diag::warn_pp_hdrstop_filename_ignored);884885std::string FileName;886if (!LexStringLiteral(Tok, FileName, "pragma hdrstop", false))887return;888889if (Tok.isNot(tok::r_paren)) {890Diag(Tok, diag::err_expected) << tok::r_paren;891return;892}893Lex(Tok);894}895if (Tok.isNot(tok::eod))896Diag(Tok.getLocation(), diag::ext_pp_extra_tokens_at_eol)897<< "pragma hdrstop";898899if (creatingPCHWithPragmaHdrStop() &&900SourceMgr.isInMainFile(Tok.getLocation())) {901assert(CurLexer && "no lexer for #pragma hdrstop processing");902Token &Result = Tok;903Result.startToken();904CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd, tok::eof);905CurLexer->cutOffLexing();906}907if (usingPCHWithPragmaHdrStop())908SkippingUntilPragmaHdrStop = false;909}910911/// AddPragmaHandler - Add the specified pragma handler to the preprocessor.912/// If 'Namespace' is non-null, then it is a token required to exist on the913/// pragma line before the pragma string starts, e.g. "STDC" or "GCC".914void Preprocessor::AddPragmaHandler(StringRef Namespace,915PragmaHandler *Handler) {916PragmaNamespace *InsertNS = PragmaHandlers.get();917918// If this is specified to be in a namespace, step down into it.919if (!Namespace.empty()) {920// If there is already a pragma handler with the name of this namespace,921// we either have an error (directive with the same name as a namespace) or922// we already have the namespace to insert into.923if (PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace)) {924InsertNS = Existing->getIfNamespace();925assert(InsertNS != nullptr && "Cannot have a pragma namespace and pragma"926" handler with the same name!");927} else {928// Otherwise, this namespace doesn't exist yet, create and insert the929// handler for it.930InsertNS = new PragmaNamespace(Namespace);931PragmaHandlers->AddPragma(InsertNS);932}933}934935// Check to make sure we don't already have a pragma for this identifier.936assert(!InsertNS->FindHandler(Handler->getName()) &&937"Pragma handler already exists for this identifier!");938InsertNS->AddPragma(Handler);939}940941/// RemovePragmaHandler - Remove the specific pragma handler from the942/// preprocessor. If \arg Namespace is non-null, then it should be the943/// namespace that \arg Handler was added to. It is an error to remove944/// a handler that has not been registered.945void Preprocessor::RemovePragmaHandler(StringRef Namespace,946PragmaHandler *Handler) {947PragmaNamespace *NS = PragmaHandlers.get();948949// If this is specified to be in a namespace, step down into it.950if (!Namespace.empty()) {951PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace);952assert(Existing && "Namespace containing handler does not exist!");953954NS = Existing->getIfNamespace();955assert(NS && "Invalid namespace, registered as a regular pragma handler!");956}957958NS->RemovePragmaHandler(Handler);959960// If this is a non-default namespace and it is now empty, remove it.961if (NS != PragmaHandlers.get() && NS->IsEmpty()) {962PragmaHandlers->RemovePragmaHandler(NS);963delete NS;964}965}966967bool Preprocessor::LexOnOffSwitch(tok::OnOffSwitch &Result) {968Token Tok;969LexUnexpandedToken(Tok);970971if (Tok.isNot(tok::identifier)) {972Diag(Tok, diag::ext_on_off_switch_syntax);973return true;974}975IdentifierInfo *II = Tok.getIdentifierInfo();976if (II->isStr("ON"))977Result = tok::OOS_ON;978else if (II->isStr("OFF"))979Result = tok::OOS_OFF;980else if (II->isStr("DEFAULT"))981Result = tok::OOS_DEFAULT;982else {983Diag(Tok, diag::ext_on_off_switch_syntax);984return true;985}986987// Verify that this is followed by EOD.988LexUnexpandedToken(Tok);989if (Tok.isNot(tok::eod))990Diag(Tok, diag::ext_pragma_syntax_eod);991return false;992}993994namespace {995996/// PragmaOnceHandler - "\#pragma once" marks the file as atomically included.997struct PragmaOnceHandler : public PragmaHandler {998PragmaOnceHandler() : PragmaHandler("once") {}9991000void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1001Token &OnceTok) override {1002PP.CheckEndOfDirective("pragma once");1003PP.HandlePragmaOnce(OnceTok);1004}1005};10061007/// PragmaMarkHandler - "\#pragma mark ..." is ignored by the compiler, and the1008/// rest of the line is not lexed.1009struct PragmaMarkHandler : public PragmaHandler {1010PragmaMarkHandler() : PragmaHandler("mark") {}10111012void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1013Token &MarkTok) override {1014PP.HandlePragmaMark(MarkTok);1015}1016};10171018/// PragmaPoisonHandler - "\#pragma poison x" marks x as not usable.1019struct PragmaPoisonHandler : public PragmaHandler {1020PragmaPoisonHandler() : PragmaHandler("poison") {}10211022void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1023Token &PoisonTok) override {1024PP.HandlePragmaPoison();1025}1026};10271028/// PragmaSystemHeaderHandler - "\#pragma system_header" marks the current file1029/// as a system header, which silences warnings in it.1030struct PragmaSystemHeaderHandler : public PragmaHandler {1031PragmaSystemHeaderHandler() : PragmaHandler("system_header") {}10321033void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1034Token &SHToken) override {1035PP.HandlePragmaSystemHeader(SHToken);1036PP.CheckEndOfDirective("pragma");1037}1038};10391040struct PragmaDependencyHandler : public PragmaHandler {1041PragmaDependencyHandler() : PragmaHandler("dependency") {}10421043void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1044Token &DepToken) override {1045PP.HandlePragmaDependency(DepToken);1046}1047};10481049struct PragmaDebugHandler : public PragmaHandler {1050PragmaDebugHandler() : PragmaHandler("__debug") {}10511052void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1053Token &DebugToken) override {1054Token Tok;1055PP.LexUnexpandedToken(Tok);1056if (Tok.isNot(tok::identifier)) {1057PP.Diag(Tok, diag::warn_pragma_debug_missing_command);1058return;1059}1060IdentifierInfo *II = Tok.getIdentifierInfo();10611062if (II->isStr("assert")) {1063if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash)1064llvm_unreachable("This is an assertion!");1065} else if (II->isStr("crash")) {1066llvm::Timer T("crash", "pragma crash");1067llvm::TimeRegion R(&T);1068if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash)1069LLVM_BUILTIN_TRAP;1070} else if (II->isStr("parser_crash")) {1071if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash) {1072Token Crasher;1073Crasher.startToken();1074Crasher.setKind(tok::annot_pragma_parser_crash);1075Crasher.setAnnotationRange(SourceRange(Tok.getLocation()));1076PP.EnterToken(Crasher, /*IsReinject*/ false);1077}1078} else if (II->isStr("dump")) {1079Token DumpAnnot;1080DumpAnnot.startToken();1081DumpAnnot.setKind(tok::annot_pragma_dump);1082DumpAnnot.setAnnotationRange(SourceRange(Tok.getLocation()));1083PP.EnterToken(DumpAnnot, /*IsReinject*/false);1084} else if (II->isStr("diag_mapping")) {1085Token DiagName;1086PP.LexUnexpandedToken(DiagName);1087if (DiagName.is(tok::eod))1088PP.getDiagnostics().dump();1089else if (DiagName.is(tok::string_literal) && !DiagName.hasUDSuffix()) {1090StringLiteralParser Literal(DiagName, PP,1091StringLiteralEvalMethod::Unevaluated);1092if (Literal.hadError)1093return;1094PP.getDiagnostics().dump(Literal.GetString());1095} else {1096PP.Diag(DiagName, diag::warn_pragma_debug_missing_argument)1097<< II->getName();1098}1099} else if (II->isStr("llvm_fatal_error")) {1100if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash)1101llvm::report_fatal_error("#pragma clang __debug llvm_fatal_error");1102} else if (II->isStr("llvm_unreachable")) {1103if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash)1104llvm_unreachable("#pragma clang __debug llvm_unreachable");1105} else if (II->isStr("macro")) {1106Token MacroName;1107PP.LexUnexpandedToken(MacroName);1108auto *MacroII = MacroName.getIdentifierInfo();1109if (MacroII)1110PP.dumpMacroInfo(MacroII);1111else1112PP.Diag(MacroName, diag::warn_pragma_debug_missing_argument)1113<< II->getName();1114} else if (II->isStr("module_map")) {1115llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 8>1116ModuleName;1117if (LexModuleName(PP, Tok, ModuleName))1118return;1119ModuleMap &MM = PP.getHeaderSearchInfo().getModuleMap();1120Module *M = nullptr;1121for (auto IIAndLoc : ModuleName) {1122M = MM.lookupModuleQualified(IIAndLoc.first->getName(), M);1123if (!M) {1124PP.Diag(IIAndLoc.second, diag::warn_pragma_debug_unknown_module)1125<< IIAndLoc.first;1126return;1127}1128}1129M->dump();1130} else if (II->isStr("overflow_stack")) {1131if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash)1132DebugOverflowStack();1133} else if (II->isStr("captured")) {1134HandleCaptured(PP);1135} else if (II->isStr("modules")) {1136struct ModuleVisitor {1137Preprocessor &PP;1138void visit(Module *M, bool VisibleOnly) {1139SourceLocation ImportLoc = PP.getModuleImportLoc(M);1140if (!VisibleOnly || ImportLoc.isValid()) {1141llvm::errs() << M->getFullModuleName() << " ";1142if (ImportLoc.isValid()) {1143llvm::errs() << M << " visible ";1144ImportLoc.print(llvm::errs(), PP.getSourceManager());1145}1146llvm::errs() << "\n";1147}1148for (Module *Sub : M->submodules()) {1149if (!VisibleOnly || ImportLoc.isInvalid() || Sub->IsExplicit)1150visit(Sub, VisibleOnly);1151}1152}1153void visitAll(bool VisibleOnly) {1154for (auto &NameAndMod :1155PP.getHeaderSearchInfo().getModuleMap().modules())1156visit(NameAndMod.second, VisibleOnly);1157}1158} Visitor{PP};11591160Token Kind;1161PP.LexUnexpandedToken(Kind);1162auto *DumpII = Kind.getIdentifierInfo();1163if (!DumpII) {1164PP.Diag(Kind, diag::warn_pragma_debug_missing_argument)1165<< II->getName();1166} else if (DumpII->isStr("all")) {1167Visitor.visitAll(false);1168} else if (DumpII->isStr("visible")) {1169Visitor.visitAll(true);1170} else if (DumpII->isStr("building")) {1171for (auto &Building : PP.getBuildingSubmodules()) {1172llvm::errs() << "in " << Building.M->getFullModuleName();1173if (Building.ImportLoc.isValid()) {1174llvm::errs() << " imported ";1175if (Building.IsPragma)1176llvm::errs() << "via pragma ";1177llvm::errs() << "at ";1178Building.ImportLoc.print(llvm::errs(), PP.getSourceManager());1179llvm::errs() << "\n";1180}1181}1182} else {1183PP.Diag(Tok, diag::warn_pragma_debug_unexpected_command)1184<< DumpII->getName();1185}1186} else if (II->isStr("sloc_usage")) {1187// An optional integer literal argument specifies the number of files to1188// specifically report information about.1189std::optional<unsigned> MaxNotes;1190Token ArgToken;1191PP.Lex(ArgToken);1192uint64_t Value;1193if (ArgToken.is(tok::numeric_constant) &&1194PP.parseSimpleIntegerLiteral(ArgToken, Value)) {1195MaxNotes = Value;1196} else if (ArgToken.isNot(tok::eod)) {1197PP.Diag(ArgToken, diag::warn_pragma_debug_unexpected_argument);1198}11991200PP.Diag(Tok, diag::remark_sloc_usage);1201PP.getSourceManager().noteSLocAddressSpaceUsage(PP.getDiagnostics(),1202MaxNotes);1203} else {1204PP.Diag(Tok, diag::warn_pragma_debug_unexpected_command)1205<< II->getName();1206}12071208PPCallbacks *Callbacks = PP.getPPCallbacks();1209if (Callbacks)1210Callbacks->PragmaDebug(Tok.getLocation(), II->getName());1211}12121213void HandleCaptured(Preprocessor &PP) {1214Token Tok;1215PP.LexUnexpandedToken(Tok);12161217if (Tok.isNot(tok::eod)) {1218PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol)1219<< "pragma clang __debug captured";1220return;1221}12221223SourceLocation NameLoc = Tok.getLocation();1224MutableArrayRef<Token> Toks(1225PP.getPreprocessorAllocator().Allocate<Token>(1), 1);1226Toks[0].startToken();1227Toks[0].setKind(tok::annot_pragma_captured);1228Toks[0].setLocation(NameLoc);12291230PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,1231/*IsReinject=*/false);1232}12331234// Disable MSVC warning about runtime stack overflow.1235#ifdef _MSC_VER1236#pragma warning(disable : 4717)1237#endif1238static void DebugOverflowStack(void (*P)() = nullptr) {1239void (*volatile Self)(void(*P)()) = DebugOverflowStack;1240Self(reinterpret_cast<void(*)()>(Self));1241}1242#ifdef _MSC_VER1243#pragma warning(default : 4717)1244#endif1245};12461247struct PragmaUnsafeBufferUsageHandler : public PragmaHandler {1248PragmaUnsafeBufferUsageHandler() : PragmaHandler("unsafe_buffer_usage") {}1249void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1250Token &FirstToken) override {1251Token Tok;12521253PP.LexUnexpandedToken(Tok);1254if (Tok.isNot(tok::identifier)) {1255PP.Diag(Tok, diag::err_pp_pragma_unsafe_buffer_usage_syntax);1256return;1257}12581259IdentifierInfo *II = Tok.getIdentifierInfo();1260SourceLocation Loc = Tok.getLocation();12611262if (II->isStr("begin")) {1263if (PP.enterOrExitSafeBufferOptOutRegion(true, Loc))1264PP.Diag(Loc, diag::err_pp_double_begin_pragma_unsafe_buffer_usage);1265} else if (II->isStr("end")) {1266if (PP.enterOrExitSafeBufferOptOutRegion(false, Loc))1267PP.Diag(Loc, diag::err_pp_unmatched_end_begin_pragma_unsafe_buffer_usage);1268} else1269PP.Diag(Tok, diag::err_pp_pragma_unsafe_buffer_usage_syntax);1270}1271};12721273/// PragmaDiagnosticHandler - e.g. '\#pragma GCC diagnostic ignored "-Wformat"'1274struct PragmaDiagnosticHandler : public PragmaHandler {1275private:1276const char *Namespace;12771278public:1279explicit PragmaDiagnosticHandler(const char *NS)1280: PragmaHandler("diagnostic"), Namespace(NS) {}12811282void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1283Token &DiagToken) override {1284SourceLocation DiagLoc = DiagToken.getLocation();1285Token Tok;1286PP.LexUnexpandedToken(Tok);1287if (Tok.isNot(tok::identifier)) {1288PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);1289return;1290}1291IdentifierInfo *II = Tok.getIdentifierInfo();1292PPCallbacks *Callbacks = PP.getPPCallbacks();12931294// Get the next token, which is either an EOD or a string literal. We lex1295// it now so that we can early return if the previous token was push or pop.1296PP.LexUnexpandedToken(Tok);12971298if (II->isStr("pop")) {1299if (!PP.getDiagnostics().popMappings(DiagLoc))1300PP.Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);1301else if (Callbacks)1302Callbacks->PragmaDiagnosticPop(DiagLoc, Namespace);13031304if (Tok.isNot(tok::eod))1305PP.Diag(Tok.getLocation(), diag::warn_pragma_diagnostic_invalid_token);1306return;1307} else if (II->isStr("push")) {1308PP.getDiagnostics().pushMappings(DiagLoc);1309if (Callbacks)1310Callbacks->PragmaDiagnosticPush(DiagLoc, Namespace);13111312if (Tok.isNot(tok::eod))1313PP.Diag(Tok.getLocation(), diag::warn_pragma_diagnostic_invalid_token);1314return;1315}13161317diag::Severity SV = llvm::StringSwitch<diag::Severity>(II->getName())1318.Case("ignored", diag::Severity::Ignored)1319.Case("warning", diag::Severity::Warning)1320.Case("error", diag::Severity::Error)1321.Case("fatal", diag::Severity::Fatal)1322.Default(diag::Severity());13231324if (SV == diag::Severity()) {1325PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);1326return;1327}13281329// At this point, we expect a string literal.1330SourceLocation StringLoc = Tok.getLocation();1331std::string WarningName;1332if (!PP.FinishLexStringLiteral(Tok, WarningName, "pragma diagnostic",1333/*AllowMacroExpansion=*/false))1334return;13351336if (Tok.isNot(tok::eod)) {1337PP.Diag(Tok.getLocation(), diag::warn_pragma_diagnostic_invalid_token);1338return;1339}13401341if (WarningName.size() < 3 || WarningName[0] != '-' ||1342(WarningName[1] != 'W' && WarningName[1] != 'R')) {1343PP.Diag(StringLoc, diag::warn_pragma_diagnostic_invalid_option);1344return;1345}13461347diag::Flavor Flavor = WarningName[1] == 'W' ? diag::Flavor::WarningOrError1348: diag::Flavor::Remark;1349StringRef Group = StringRef(WarningName).substr(2);1350bool unknownDiag = false;1351if (Group == "everything") {1352// Special handling for pragma clang diagnostic ... "-Weverything".1353// There is no formal group named "everything", so there has to be a1354// special case for it.1355PP.getDiagnostics().setSeverityForAll(Flavor, SV, DiagLoc);1356} else1357unknownDiag = PP.getDiagnostics().setSeverityForGroup(Flavor, Group, SV,1358DiagLoc);1359if (unknownDiag)1360PP.Diag(StringLoc, diag::warn_pragma_diagnostic_unknown_warning)1361<< WarningName;1362else if (Callbacks)1363Callbacks->PragmaDiagnostic(DiagLoc, Namespace, SV, WarningName);1364}1365};13661367/// "\#pragma hdrstop [<header-name-string>]"1368struct PragmaHdrstopHandler : public PragmaHandler {1369PragmaHdrstopHandler() : PragmaHandler("hdrstop") {}1370void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1371Token &DepToken) override {1372PP.HandlePragmaHdrstop(DepToken);1373}1374};13751376/// "\#pragma warning(...)". MSVC's diagnostics do not map cleanly to clang's1377/// diagnostics, so we don't really implement this pragma. We parse it and1378/// ignore it to avoid -Wunknown-pragma warnings.1379struct PragmaWarningHandler : public PragmaHandler {1380PragmaWarningHandler() : PragmaHandler("warning") {}13811382void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1383Token &Tok) override {1384// Parse things like:1385// warning(push, 1)1386// warning(pop)1387// warning(disable : 1 2 3 ; error : 4 5 6 ; suppress : 7 8 9)1388SourceLocation DiagLoc = Tok.getLocation();1389PPCallbacks *Callbacks = PP.getPPCallbacks();13901391PP.Lex(Tok);1392if (Tok.isNot(tok::l_paren)) {1393PP.Diag(Tok, diag::warn_pragma_warning_expected) << "(";1394return;1395}13961397PP.Lex(Tok);1398IdentifierInfo *II = Tok.getIdentifierInfo();13991400if (II && II->isStr("push")) {1401// #pragma warning( push[ ,n ] )1402int Level = -1;1403PP.Lex(Tok);1404if (Tok.is(tok::comma)) {1405PP.Lex(Tok);1406uint64_t Value;1407if (Tok.is(tok::numeric_constant) &&1408PP.parseSimpleIntegerLiteral(Tok, Value))1409Level = int(Value);1410if (Level < 0 || Level > 4) {1411PP.Diag(Tok, diag::warn_pragma_warning_push_level);1412return;1413}1414}1415PP.getDiagnostics().pushMappings(DiagLoc);1416if (Callbacks)1417Callbacks->PragmaWarningPush(DiagLoc, Level);1418} else if (II && II->isStr("pop")) {1419// #pragma warning( pop )1420PP.Lex(Tok);1421if (!PP.getDiagnostics().popMappings(DiagLoc))1422PP.Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);1423else if (Callbacks)1424Callbacks->PragmaWarningPop(DiagLoc);1425} else {1426// #pragma warning( warning-specifier : warning-number-list1427// [; warning-specifier : warning-number-list...] )1428while (true) {1429II = Tok.getIdentifierInfo();1430if (!II && !Tok.is(tok::numeric_constant)) {1431PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid);1432return;1433}14341435// Figure out which warning specifier this is.1436bool SpecifierValid;1437PPCallbacks::PragmaWarningSpecifier Specifier;1438if (II) {1439int SpecifierInt = llvm::StringSwitch<int>(II->getName())1440.Case("default", PPCallbacks::PWS_Default)1441.Case("disable", PPCallbacks::PWS_Disable)1442.Case("error", PPCallbacks::PWS_Error)1443.Case("once", PPCallbacks::PWS_Once)1444.Case("suppress", PPCallbacks::PWS_Suppress)1445.Default(-1);1446SpecifierValid = SpecifierInt != -1;1447if (SpecifierValid)1448Specifier =1449static_cast<PPCallbacks::PragmaWarningSpecifier>(SpecifierInt);14501451// If we read a correct specifier, snatch next token (that should be1452// ":", checked later).1453if (SpecifierValid)1454PP.Lex(Tok);1455} else {1456// Token is a numeric constant. It should be either 1, 2, 3 or 4.1457uint64_t Value;1458if (PP.parseSimpleIntegerLiteral(Tok, Value)) {1459if ((SpecifierValid = (Value >= 1) && (Value <= 4)))1460Specifier = static_cast<PPCallbacks::PragmaWarningSpecifier>(1461PPCallbacks::PWS_Level1 + Value - 1);1462} else1463SpecifierValid = false;1464// Next token already snatched by parseSimpleIntegerLiteral.1465}14661467if (!SpecifierValid) {1468PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid);1469return;1470}1471if (Tok.isNot(tok::colon)) {1472PP.Diag(Tok, diag::warn_pragma_warning_expected) << ":";1473return;1474}14751476// Collect the warning ids.1477SmallVector<int, 4> Ids;1478PP.Lex(Tok);1479while (Tok.is(tok::numeric_constant)) {1480uint64_t Value;1481if (!PP.parseSimpleIntegerLiteral(Tok, Value) || Value == 0 ||1482Value > INT_MAX) {1483PP.Diag(Tok, diag::warn_pragma_warning_expected_number);1484return;1485}1486Ids.push_back(int(Value));1487}14881489// Only act on disable for now.1490diag::Severity SV = diag::Severity();1491if (Specifier == PPCallbacks::PWS_Disable)1492SV = diag::Severity::Ignored;1493if (SV != diag::Severity())1494for (int Id : Ids) {1495if (auto Group = diagGroupFromCLWarningID(Id)) {1496bool unknownDiag = PP.getDiagnostics().setSeverityForGroup(1497diag::Flavor::WarningOrError, *Group, SV, DiagLoc);1498assert(!unknownDiag &&1499"wd table should only contain known diags");1500(void)unknownDiag;1501}1502}15031504if (Callbacks)1505Callbacks->PragmaWarning(DiagLoc, Specifier, Ids);15061507// Parse the next specifier if there is a semicolon.1508if (Tok.isNot(tok::semi))1509break;1510PP.Lex(Tok);1511}1512}15131514if (Tok.isNot(tok::r_paren)) {1515PP.Diag(Tok, diag::warn_pragma_warning_expected) << ")";1516return;1517}15181519PP.Lex(Tok);1520if (Tok.isNot(tok::eod))1521PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma warning";1522}1523};15241525/// "\#pragma execution_character_set(...)". MSVC supports this pragma only1526/// for "UTF-8". We parse it and ignore it if UTF-8 is provided and warn1527/// otherwise to avoid -Wunknown-pragma warnings.1528struct PragmaExecCharsetHandler : public PragmaHandler {1529PragmaExecCharsetHandler() : PragmaHandler("execution_character_set") {}15301531void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1532Token &Tok) override {1533// Parse things like:1534// execution_character_set(push, "UTF-8")1535// execution_character_set(pop)1536SourceLocation DiagLoc = Tok.getLocation();1537PPCallbacks *Callbacks = PP.getPPCallbacks();15381539PP.Lex(Tok);1540if (Tok.isNot(tok::l_paren)) {1541PP.Diag(Tok, diag::warn_pragma_exec_charset_expected) << "(";1542return;1543}15441545PP.Lex(Tok);1546IdentifierInfo *II = Tok.getIdentifierInfo();15471548if (II && II->isStr("push")) {1549// #pragma execution_character_set( push[ , string ] )1550PP.Lex(Tok);1551if (Tok.is(tok::comma)) {1552PP.Lex(Tok);15531554std::string ExecCharset;1555if (!PP.FinishLexStringLiteral(Tok, ExecCharset,1556"pragma execution_character_set",1557/*AllowMacroExpansion=*/false))1558return;15591560// MSVC supports either of these, but nothing else.1561if (ExecCharset != "UTF-8" && ExecCharset != "utf-8") {1562PP.Diag(Tok, diag::warn_pragma_exec_charset_push_invalid) << ExecCharset;1563return;1564}1565}1566if (Callbacks)1567Callbacks->PragmaExecCharsetPush(DiagLoc, "UTF-8");1568} else if (II && II->isStr("pop")) {1569// #pragma execution_character_set( pop )1570PP.Lex(Tok);1571if (Callbacks)1572Callbacks->PragmaExecCharsetPop(DiagLoc);1573} else {1574PP.Diag(Tok, diag::warn_pragma_exec_charset_spec_invalid);1575return;1576}15771578if (Tok.isNot(tok::r_paren)) {1579PP.Diag(Tok, diag::warn_pragma_exec_charset_expected) << ")";1580return;1581}15821583PP.Lex(Tok);1584if (Tok.isNot(tok::eod))1585PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma execution_character_set";1586}1587};15881589/// PragmaIncludeAliasHandler - "\#pragma include_alias("...")".1590struct PragmaIncludeAliasHandler : public PragmaHandler {1591PragmaIncludeAliasHandler() : PragmaHandler("include_alias") {}15921593void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1594Token &IncludeAliasTok) override {1595PP.HandlePragmaIncludeAlias(IncludeAliasTok);1596}1597};15981599/// PragmaMessageHandler - Handle the microsoft and gcc \#pragma message1600/// extension. The syntax is:1601/// \code1602/// #pragma message(string)1603/// \endcode1604/// OR, in GCC mode:1605/// \code1606/// #pragma message string1607/// \endcode1608/// string is a string, which is fully macro expanded, and permits string1609/// concatenation, embedded escape characters, etc... See MSDN for more details.1610/// Also handles \#pragma GCC warning and \#pragma GCC error which take the same1611/// form as \#pragma message.1612struct PragmaMessageHandler : public PragmaHandler {1613private:1614const PPCallbacks::PragmaMessageKind Kind;1615const StringRef Namespace;16161617static const char* PragmaKind(PPCallbacks::PragmaMessageKind Kind,1618bool PragmaNameOnly = false) {1619switch (Kind) {1620case PPCallbacks::PMK_Message:1621return PragmaNameOnly ? "message" : "pragma message";1622case PPCallbacks::PMK_Warning:1623return PragmaNameOnly ? "warning" : "pragma warning";1624case PPCallbacks::PMK_Error:1625return PragmaNameOnly ? "error" : "pragma error";1626}1627llvm_unreachable("Unknown PragmaMessageKind!");1628}16291630public:1631PragmaMessageHandler(PPCallbacks::PragmaMessageKind Kind,1632StringRef Namespace = StringRef())1633: PragmaHandler(PragmaKind(Kind, true)), Kind(Kind),1634Namespace(Namespace) {}16351636void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1637Token &Tok) override {1638SourceLocation MessageLoc = Tok.getLocation();1639PP.Lex(Tok);1640bool ExpectClosingParen = false;1641switch (Tok.getKind()) {1642case tok::l_paren:1643// We have a MSVC style pragma message.1644ExpectClosingParen = true;1645// Read the string.1646PP.Lex(Tok);1647break;1648case tok::string_literal:1649// We have a GCC style pragma message, and we just read the string.1650break;1651default:1652PP.Diag(MessageLoc, diag::err_pragma_message_malformed) << Kind;1653return;1654}16551656std::string MessageString;1657if (!PP.FinishLexStringLiteral(Tok, MessageString, PragmaKind(Kind),1658/*AllowMacroExpansion=*/true))1659return;16601661if (ExpectClosingParen) {1662if (Tok.isNot(tok::r_paren)) {1663PP.Diag(Tok.getLocation(), diag::err_pragma_message_malformed) << Kind;1664return;1665}1666PP.Lex(Tok); // eat the r_paren.1667}16681669if (Tok.isNot(tok::eod)) {1670PP.Diag(Tok.getLocation(), diag::err_pragma_message_malformed) << Kind;1671return;1672}16731674// Output the message.1675PP.Diag(MessageLoc, (Kind == PPCallbacks::PMK_Error)1676? diag::err_pragma_message1677: diag::warn_pragma_message) << MessageString;16781679// If the pragma is lexically sound, notify any interested PPCallbacks.1680if (PPCallbacks *Callbacks = PP.getPPCallbacks())1681Callbacks->PragmaMessage(MessageLoc, Namespace, Kind, MessageString);1682}1683};16841685/// Handle the clang \#pragma module import extension. The syntax is:1686/// \code1687/// #pragma clang module import some.module.name1688/// \endcode1689struct PragmaModuleImportHandler : public PragmaHandler {1690PragmaModuleImportHandler() : PragmaHandler("import") {}16911692void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1693Token &Tok) override {1694SourceLocation ImportLoc = Tok.getLocation();16951696// Read the module name.1697llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 8>1698ModuleName;1699if (LexModuleName(PP, Tok, ModuleName))1700return;17011702if (Tok.isNot(tok::eod))1703PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";17041705// If we have a non-empty module path, load the named module.1706Module *Imported =1707PP.getModuleLoader().loadModule(ImportLoc, ModuleName, Module::Hidden,1708/*IsInclusionDirective=*/false);1709if (!Imported)1710return;17111712PP.makeModuleVisible(Imported, ImportLoc);1713PP.EnterAnnotationToken(SourceRange(ImportLoc, ModuleName.back().second),1714tok::annot_module_include, Imported);1715if (auto *CB = PP.getPPCallbacks())1716CB->moduleImport(ImportLoc, ModuleName, Imported);1717}1718};17191720/// Handle the clang \#pragma module begin extension. The syntax is:1721/// \code1722/// #pragma clang module begin some.module.name1723/// ...1724/// #pragma clang module end1725/// \endcode1726struct PragmaModuleBeginHandler : public PragmaHandler {1727PragmaModuleBeginHandler() : PragmaHandler("begin") {}17281729void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1730Token &Tok) override {1731SourceLocation BeginLoc = Tok.getLocation();17321733// Read the module name.1734llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 8>1735ModuleName;1736if (LexModuleName(PP, Tok, ModuleName))1737return;17381739if (Tok.isNot(tok::eod))1740PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";17411742// We can only enter submodules of the current module.1743StringRef Current = PP.getLangOpts().CurrentModule;1744if (ModuleName.front().first->getName() != Current) {1745PP.Diag(ModuleName.front().second, diag::err_pp_module_begin_wrong_module)1746<< ModuleName.front().first << (ModuleName.size() > 1)1747<< Current.empty() << Current;1748return;1749}17501751// Find the module we're entering. We require that a module map for it1752// be loaded or implicitly loadable.1753auto &HSI = PP.getHeaderSearchInfo();1754Module *M = HSI.lookupModule(Current, ModuleName.front().second);1755if (!M) {1756PP.Diag(ModuleName.front().second,1757diag::err_pp_module_begin_no_module_map) << Current;1758return;1759}1760for (unsigned I = 1; I != ModuleName.size(); ++I) {1761auto *NewM = M->findOrInferSubmodule(ModuleName[I].first->getName());1762if (!NewM) {1763PP.Diag(ModuleName[I].second, diag::err_pp_module_begin_no_submodule)1764<< M->getFullModuleName() << ModuleName[I].first;1765return;1766}1767M = NewM;1768}17691770// If the module isn't available, it doesn't make sense to enter it.1771if (Preprocessor::checkModuleIsAvailable(1772PP.getLangOpts(), PP.getTargetInfo(), *M, PP.getDiagnostics())) {1773PP.Diag(BeginLoc, diag::note_pp_module_begin_here)1774<< M->getTopLevelModuleName();1775return;1776}17771778// Enter the scope of the submodule.1779PP.EnterSubmodule(M, BeginLoc, /*ForPragma*/true);1780PP.EnterAnnotationToken(SourceRange(BeginLoc, ModuleName.back().second),1781tok::annot_module_begin, M);1782}1783};17841785/// Handle the clang \#pragma module end extension.1786struct PragmaModuleEndHandler : public PragmaHandler {1787PragmaModuleEndHandler() : PragmaHandler("end") {}17881789void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1790Token &Tok) override {1791SourceLocation Loc = Tok.getLocation();17921793PP.LexUnexpandedToken(Tok);1794if (Tok.isNot(tok::eod))1795PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";17961797Module *M = PP.LeaveSubmodule(/*ForPragma*/true);1798if (M)1799PP.EnterAnnotationToken(SourceRange(Loc), tok::annot_module_end, M);1800else1801PP.Diag(Loc, diag::err_pp_module_end_without_module_begin);1802}1803};18041805/// Handle the clang \#pragma module build extension.1806struct PragmaModuleBuildHandler : public PragmaHandler {1807PragmaModuleBuildHandler() : PragmaHandler("build") {}18081809void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1810Token &Tok) override {1811PP.HandlePragmaModuleBuild(Tok);1812}1813};18141815/// Handle the clang \#pragma module load extension.1816struct PragmaModuleLoadHandler : public PragmaHandler {1817PragmaModuleLoadHandler() : PragmaHandler("load") {}18181819void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1820Token &Tok) override {1821SourceLocation Loc = Tok.getLocation();18221823// Read the module name.1824llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 8>1825ModuleName;1826if (LexModuleName(PP, Tok, ModuleName))1827return;18281829if (Tok.isNot(tok::eod))1830PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";18311832// Load the module, don't make it visible.1833PP.getModuleLoader().loadModule(Loc, ModuleName, Module::Hidden,1834/*IsInclusionDirective=*/false);1835}1836};18371838/// PragmaPushMacroHandler - "\#pragma push_macro" saves the value of the1839/// macro on the top of the stack.1840struct PragmaPushMacroHandler : public PragmaHandler {1841PragmaPushMacroHandler() : PragmaHandler("push_macro") {}18421843void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1844Token &PushMacroTok) override {1845PP.HandlePragmaPushMacro(PushMacroTok);1846}1847};18481849/// PragmaPopMacroHandler - "\#pragma pop_macro" sets the value of the1850/// macro to the value on the top of the stack.1851struct PragmaPopMacroHandler : public PragmaHandler {1852PragmaPopMacroHandler() : PragmaHandler("pop_macro") {}18531854void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1855Token &PopMacroTok) override {1856PP.HandlePragmaPopMacro(PopMacroTok);1857}1858};18591860/// PragmaARCCFCodeAuditedHandler -1861/// \#pragma clang arc_cf_code_audited begin/end1862struct PragmaARCCFCodeAuditedHandler : public PragmaHandler {1863PragmaARCCFCodeAuditedHandler() : PragmaHandler("arc_cf_code_audited") {}18641865void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1866Token &NameTok) override {1867SourceLocation Loc = NameTok.getLocation();1868bool IsBegin;18691870Token Tok;18711872// Lex the 'begin' or 'end'.1873PP.LexUnexpandedToken(Tok);1874const IdentifierInfo *BeginEnd = Tok.getIdentifierInfo();1875if (BeginEnd && BeginEnd->isStr("begin")) {1876IsBegin = true;1877} else if (BeginEnd && BeginEnd->isStr("end")) {1878IsBegin = false;1879} else {1880PP.Diag(Tok.getLocation(), diag::err_pp_arc_cf_code_audited_syntax);1881return;1882}18831884// Verify that this is followed by EOD.1885PP.LexUnexpandedToken(Tok);1886if (Tok.isNot(tok::eod))1887PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";18881889// The start location of the active audit.1890SourceLocation BeginLoc = PP.getPragmaARCCFCodeAuditedInfo().second;18911892// The start location we want after processing this.1893SourceLocation NewLoc;18941895if (IsBegin) {1896// Complain about attempts to re-enter an audit.1897if (BeginLoc.isValid()) {1898PP.Diag(Loc, diag::err_pp_double_begin_of_arc_cf_code_audited);1899PP.Diag(BeginLoc, diag::note_pragma_entered_here);1900}1901NewLoc = Loc;1902} else {1903// Complain about attempts to leave an audit that doesn't exist.1904if (!BeginLoc.isValid()) {1905PP.Diag(Loc, diag::err_pp_unmatched_end_of_arc_cf_code_audited);1906return;1907}1908NewLoc = SourceLocation();1909}19101911PP.setPragmaARCCFCodeAuditedInfo(NameTok.getIdentifierInfo(), NewLoc);1912}1913};19141915/// PragmaAssumeNonNullHandler -1916/// \#pragma clang assume_nonnull begin/end1917struct PragmaAssumeNonNullHandler : public PragmaHandler {1918PragmaAssumeNonNullHandler() : PragmaHandler("assume_nonnull") {}19191920void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1921Token &NameTok) override {1922SourceLocation Loc = NameTok.getLocation();1923bool IsBegin;19241925Token Tok;19261927// Lex the 'begin' or 'end'.1928PP.LexUnexpandedToken(Tok);1929const IdentifierInfo *BeginEnd = Tok.getIdentifierInfo();1930if (BeginEnd && BeginEnd->isStr("begin")) {1931IsBegin = true;1932} else if (BeginEnd && BeginEnd->isStr("end")) {1933IsBegin = false;1934} else {1935PP.Diag(Tok.getLocation(), diag::err_pp_assume_nonnull_syntax);1936return;1937}19381939// Verify that this is followed by EOD.1940PP.LexUnexpandedToken(Tok);1941if (Tok.isNot(tok::eod))1942PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";19431944// The start location of the active audit.1945SourceLocation BeginLoc = PP.getPragmaAssumeNonNullLoc();19461947// The start location we want after processing this.1948SourceLocation NewLoc;1949PPCallbacks *Callbacks = PP.getPPCallbacks();19501951if (IsBegin) {1952// Complain about attempts to re-enter an audit.1953if (BeginLoc.isValid()) {1954PP.Diag(Loc, diag::err_pp_double_begin_of_assume_nonnull);1955PP.Diag(BeginLoc, diag::note_pragma_entered_here);1956}1957NewLoc = Loc;1958if (Callbacks)1959Callbacks->PragmaAssumeNonNullBegin(NewLoc);1960} else {1961// Complain about attempts to leave an audit that doesn't exist.1962if (!BeginLoc.isValid()) {1963PP.Diag(Loc, diag::err_pp_unmatched_end_of_assume_nonnull);1964return;1965}1966NewLoc = SourceLocation();1967if (Callbacks)1968Callbacks->PragmaAssumeNonNullEnd(NewLoc);1969}19701971PP.setPragmaAssumeNonNullLoc(NewLoc);1972}1973};19741975/// Handle "\#pragma region [...]"1976///1977/// The syntax is1978/// \code1979/// #pragma region [optional name]1980/// #pragma endregion [optional comment]1981/// \endcode1982///1983/// \note This is1984/// <a href="http://msdn.microsoft.com/en-us/library/b6xkz944(v=vs.80).aspx">editor-only</a>1985/// pragma, just skipped by compiler.1986struct PragmaRegionHandler : public PragmaHandler {1987PragmaRegionHandler(const char *pragma) : PragmaHandler(pragma) {}19881989void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,1990Token &NameTok) override {1991// #pragma region: endregion matches can be verified1992// __pragma(region): no sense, but ignored by msvc1993// _Pragma is not valid for MSVC, but there isn't any point1994// to handle a _Pragma differently.1995}1996};19971998/// "\#pragma managed"1999/// "\#pragma managed(...)"2000/// "\#pragma unmanaged"2001/// MSVC ignores this pragma when not compiling using /clr, which clang doesn't2002/// support. We parse it and ignore it to avoid -Wunknown-pragma warnings.2003struct PragmaManagedHandler : public EmptyPragmaHandler {2004PragmaManagedHandler(const char *pragma) : EmptyPragmaHandler(pragma) {}2005};20062007/// This handles parsing pragmas that take a macro name and optional message2008static IdentifierInfo *HandleMacroAnnotationPragma(Preprocessor &PP, Token &Tok,2009const char *Pragma,2010std::string &MessageString) {2011PP.Lex(Tok);2012if (Tok.isNot(tok::l_paren)) {2013PP.Diag(Tok, diag::err_expected) << "(";2014return nullptr;2015}20162017PP.LexUnexpandedToken(Tok);2018if (!Tok.is(tok::identifier)) {2019PP.Diag(Tok, diag::err_expected) << tok::identifier;2020return nullptr;2021}2022IdentifierInfo *II = Tok.getIdentifierInfo();20232024if (!II->hasMacroDefinition()) {2025PP.Diag(Tok, diag::err_pp_visibility_non_macro) << II;2026return nullptr;2027}20282029PP.Lex(Tok);2030if (Tok.is(tok::comma)) {2031PP.Lex(Tok);2032if (!PP.FinishLexStringLiteral(Tok, MessageString, Pragma,2033/*AllowMacroExpansion=*/true))2034return nullptr;2035}20362037if (Tok.isNot(tok::r_paren)) {2038PP.Diag(Tok, diag::err_expected) << ")";2039return nullptr;2040}2041return II;2042}20432044/// "\#pragma clang deprecated(...)"2045///2046/// The syntax is2047/// \code2048/// #pragma clang deprecate(MACRO_NAME [, Message])2049/// \endcode2050struct PragmaDeprecatedHandler : public PragmaHandler {2051PragmaDeprecatedHandler() : PragmaHandler("deprecated") {}20522053void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,2054Token &Tok) override {2055std::string MessageString;20562057if (IdentifierInfo *II = HandleMacroAnnotationPragma(2058PP, Tok, "#pragma clang deprecated", MessageString)) {2059II->setIsDeprecatedMacro(true);2060PP.addMacroDeprecationMsg(II, std::move(MessageString),2061Tok.getLocation());2062}2063}2064};20652066/// "\#pragma clang restrict_expansion(...)"2067///2068/// The syntax is2069/// \code2070/// #pragma clang restrict_expansion(MACRO_NAME [, Message])2071/// \endcode2072struct PragmaRestrictExpansionHandler : public PragmaHandler {2073PragmaRestrictExpansionHandler() : PragmaHandler("restrict_expansion") {}20742075void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,2076Token &Tok) override {2077std::string MessageString;20782079if (IdentifierInfo *II = HandleMacroAnnotationPragma(2080PP, Tok, "#pragma clang restrict_expansion", MessageString)) {2081II->setIsRestrictExpansion(true);2082PP.addRestrictExpansionMsg(II, std::move(MessageString),2083Tok.getLocation());2084}2085}2086};20872088/// "\#pragma clang final(...)"2089///2090/// The syntax is2091/// \code2092/// #pragma clang final(MACRO_NAME)2093/// \endcode2094struct PragmaFinalHandler : public PragmaHandler {2095PragmaFinalHandler() : PragmaHandler("final") {}20962097void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,2098Token &Tok) override {2099PP.Lex(Tok);2100if (Tok.isNot(tok::l_paren)) {2101PP.Diag(Tok, diag::err_expected) << "(";2102return;2103}21042105PP.LexUnexpandedToken(Tok);2106if (!Tok.is(tok::identifier)) {2107PP.Diag(Tok, diag::err_expected) << tok::identifier;2108return;2109}2110IdentifierInfo *II = Tok.getIdentifierInfo();21112112if (!II->hasMacroDefinition()) {2113PP.Diag(Tok, diag::err_pp_visibility_non_macro) << II;2114return;2115}21162117PP.Lex(Tok);2118if (Tok.isNot(tok::r_paren)) {2119PP.Diag(Tok, diag::err_expected) << ")";2120return;2121}2122II->setIsFinal(true);2123PP.addFinalLoc(II, Tok.getLocation());2124}2125};21262127} // namespace21282129/// RegisterBuiltinPragmas - Install the standard preprocessor pragmas:2130/// \#pragma GCC poison/system_header/dependency and \#pragma once.2131void Preprocessor::RegisterBuiltinPragmas() {2132AddPragmaHandler(new PragmaOnceHandler());2133AddPragmaHandler(new PragmaMarkHandler());2134AddPragmaHandler(new PragmaPushMacroHandler());2135AddPragmaHandler(new PragmaPopMacroHandler());2136AddPragmaHandler(new PragmaMessageHandler(PPCallbacks::PMK_Message));21372138// #pragma GCC ...2139AddPragmaHandler("GCC", new PragmaPoisonHandler());2140AddPragmaHandler("GCC", new PragmaSystemHeaderHandler());2141AddPragmaHandler("GCC", new PragmaDependencyHandler());2142AddPragmaHandler("GCC", new PragmaDiagnosticHandler("GCC"));2143AddPragmaHandler("GCC", new PragmaMessageHandler(PPCallbacks::PMK_Warning,2144"GCC"));2145AddPragmaHandler("GCC", new PragmaMessageHandler(PPCallbacks::PMK_Error,2146"GCC"));2147// #pragma clang ...2148AddPragmaHandler("clang", new PragmaPoisonHandler());2149AddPragmaHandler("clang", new PragmaSystemHeaderHandler());2150AddPragmaHandler("clang", new PragmaDebugHandler());2151AddPragmaHandler("clang", new PragmaDependencyHandler());2152AddPragmaHandler("clang", new PragmaDiagnosticHandler("clang"));2153AddPragmaHandler("clang", new PragmaARCCFCodeAuditedHandler());2154AddPragmaHandler("clang", new PragmaAssumeNonNullHandler());2155AddPragmaHandler("clang", new PragmaDeprecatedHandler());2156AddPragmaHandler("clang", new PragmaRestrictExpansionHandler());2157AddPragmaHandler("clang", new PragmaFinalHandler());21582159// #pragma clang module ...2160auto *ModuleHandler = new PragmaNamespace("module");2161AddPragmaHandler("clang", ModuleHandler);2162ModuleHandler->AddPragma(new PragmaModuleImportHandler());2163ModuleHandler->AddPragma(new PragmaModuleBeginHandler());2164ModuleHandler->AddPragma(new PragmaModuleEndHandler());2165ModuleHandler->AddPragma(new PragmaModuleBuildHandler());2166ModuleHandler->AddPragma(new PragmaModuleLoadHandler());21672168// Safe Buffers pragmas2169AddPragmaHandler("clang", new PragmaUnsafeBufferUsageHandler);21702171// Add region pragmas.2172AddPragmaHandler(new PragmaRegionHandler("region"));2173AddPragmaHandler(new PragmaRegionHandler("endregion"));21742175// MS extensions.2176if (LangOpts.MicrosoftExt) {2177AddPragmaHandler(new PragmaWarningHandler());2178AddPragmaHandler(new PragmaExecCharsetHandler());2179AddPragmaHandler(new PragmaIncludeAliasHandler());2180AddPragmaHandler(new PragmaHdrstopHandler());2181AddPragmaHandler(new PragmaSystemHeaderHandler());2182AddPragmaHandler(new PragmaManagedHandler("managed"));2183AddPragmaHandler(new PragmaManagedHandler("unmanaged"));2184}21852186// Pragmas added by plugins2187for (const PragmaHandlerRegistry::entry &handler :2188PragmaHandlerRegistry::entries()) {2189AddPragmaHandler(handler.instantiate().release());2190}2191}21922193/// Ignore all pragmas, useful for modes such as -Eonly which would otherwise2194/// warn about those pragmas being unknown.2195void Preprocessor::IgnorePragmas() {2196AddPragmaHandler(new EmptyPragmaHandler());2197// Also ignore all pragmas in all namespaces created2198// in Preprocessor::RegisterBuiltinPragmas().2199AddPragmaHandler("GCC", new EmptyPragmaHandler());2200AddPragmaHandler("clang", new EmptyPragmaHandler());2201}220222032204