12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- Preprocessor.h - C Language Family Preprocessor ----------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- /// \file
- /// Defines the clang::Preprocessor interface.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CLANG_LEX_PREPROCESSOR_H
- #define LLVM_CLANG_LEX_PREPROCESSOR_H
- #include "clang/Basic/Diagnostic.h"
- #include "clang/Basic/DiagnosticIDs.h"
- #include "clang/Basic/IdentifierTable.h"
- #include "clang/Basic/LLVM.h"
- #include "clang/Basic/LangOptions.h"
- #include "clang/Basic/Module.h"
- #include "clang/Basic/SourceLocation.h"
- #include "clang/Basic/SourceManager.h"
- #include "clang/Basic/TokenKinds.h"
- #include "clang/Lex/Lexer.h"
- #include "clang/Lex/MacroInfo.h"
- #include "clang/Lex/ModuleLoader.h"
- #include "clang/Lex/ModuleMap.h"
- #include "clang/Lex/PPCallbacks.h"
- #include "clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h"
- #include "clang/Lex/Token.h"
- #include "clang/Lex/TokenLexer.h"
- #include "llvm/ADT/ArrayRef.h"
- #include "llvm/ADT/DenseMap.h"
- #include "llvm/ADT/FoldingSet.h"
- #include "llvm/ADT/FunctionExtras.h"
- #include "llvm/ADT/None.h"
- #include "llvm/ADT/Optional.h"
- #include "llvm/ADT/PointerUnion.h"
- #include "llvm/ADT/STLExtras.h"
- #include "llvm/ADT/SmallPtrSet.h"
- #include "llvm/ADT/SmallVector.h"
- #include "llvm/ADT/StringRef.h"
- #include "llvm/ADT/TinyPtrVector.h"
- #include "llvm/ADT/iterator_range.h"
- #include "llvm/Support/Allocator.h"
- #include "llvm/Support/Casting.h"
- #include "llvm/Support/Registry.h"
- #include <cassert>
- #include <cstddef>
- #include <cstdint>
- #include <map>
- #include <memory>
- #include <string>
- #include <utility>
- #include <vector>
- namespace llvm {
- template<unsigned InternalLen> class SmallString;
- } // namespace llvm
- namespace clang {
- class CodeCompletionHandler;
- class CommentHandler;
- class DirectoryEntry;
- class DirectoryLookup;
- class EmptylineHandler;
- class ExternalPreprocessorSource;
- class FileEntry;
- class FileManager;
- class HeaderSearch;
- class MacroArgs;
- class PragmaHandler;
- class PragmaNamespace;
- class PreprocessingRecord;
- class PreprocessorLexer;
- class PreprocessorOptions;
- class ScratchBuffer;
- class TargetInfo;
- namespace Builtin {
- class Context;
- }
- /// Stores token information for comparing actual tokens with
- /// predefined values. Only handles simple tokens and identifiers.
- class TokenValue {
- tok::TokenKind Kind;
- IdentifierInfo *II;
- public:
- TokenValue(tok::TokenKind Kind) : Kind(Kind), II(nullptr) {
- assert(Kind != tok::raw_identifier && "Raw identifiers are not supported.");
- assert(Kind != tok::identifier &&
- "Identifiers should be created by TokenValue(IdentifierInfo *)");
- assert(!tok::isLiteral(Kind) && "Literals are not supported.");
- assert(!tok::isAnnotation(Kind) && "Annotations are not supported.");
- }
- TokenValue(IdentifierInfo *II) : Kind(tok::identifier), II(II) {}
- bool operator==(const Token &Tok) const {
- return Tok.getKind() == Kind &&
- (!II || II == Tok.getIdentifierInfo());
- }
- };
- /// Context in which macro name is used.
- enum MacroUse {
- // other than #define or #undef
- MU_Other = 0,
- // macro name specified in #define
- MU_Define = 1,
- // macro name specified in #undef
- MU_Undef = 2
- };
- /// Engages in a tight little dance with the lexer to efficiently
- /// preprocess tokens.
- ///
- /// Lexers know only about tokens within a single source file, and don't
- /// know anything about preprocessor-level issues like the \#include stack,
- /// token expansion, etc.
- class Preprocessor {
- friend class VAOptDefinitionContext;
- friend class VariadicMacroScopeGuard;
- llvm::unique_function<void(const clang::Token &)> OnToken;
- std::shared_ptr<PreprocessorOptions> PPOpts;
- DiagnosticsEngine *Diags;
- LangOptions &LangOpts;
- const TargetInfo *Target = nullptr;
- const TargetInfo *AuxTarget = nullptr;
- FileManager &FileMgr;
- SourceManager &SourceMgr;
- std::unique_ptr<ScratchBuffer> ScratchBuf;
- HeaderSearch &HeaderInfo;
- ModuleLoader &TheModuleLoader;
- /// External source of macros.
- ExternalPreprocessorSource *ExternalSource;
- /// A BumpPtrAllocator object used to quickly allocate and release
- /// objects internal to the Preprocessor.
- llvm::BumpPtrAllocator BP;
- /// Identifiers for builtin macros and other builtins.
- IdentifierInfo *Ident__LINE__, *Ident__FILE__; // __LINE__, __FILE__
- IdentifierInfo *Ident__DATE__, *Ident__TIME__; // __DATE__, __TIME__
- IdentifierInfo *Ident__INCLUDE_LEVEL__; // __INCLUDE_LEVEL__
- IdentifierInfo *Ident__BASE_FILE__; // __BASE_FILE__
- IdentifierInfo *Ident__FILE_NAME__; // __FILE_NAME__
- IdentifierInfo *Ident__TIMESTAMP__; // __TIMESTAMP__
- IdentifierInfo *Ident__COUNTER__; // __COUNTER__
- IdentifierInfo *Ident_Pragma, *Ident__pragma; // _Pragma, __pragma
- IdentifierInfo *Ident__identifier; // __identifier
- IdentifierInfo *Ident__VA_ARGS__; // __VA_ARGS__
- IdentifierInfo *Ident__VA_OPT__; // __VA_OPT__
- IdentifierInfo *Ident__has_feature; // __has_feature
- IdentifierInfo *Ident__has_extension; // __has_extension
- IdentifierInfo *Ident__has_builtin; // __has_builtin
- IdentifierInfo *Ident__has_attribute; // __has_attribute
- IdentifierInfo *Ident__has_include; // __has_include
- IdentifierInfo *Ident__has_include_next; // __has_include_next
- IdentifierInfo *Ident__has_warning; // __has_warning
- IdentifierInfo *Ident__is_identifier; // __is_identifier
- IdentifierInfo *Ident__building_module; // __building_module
- IdentifierInfo *Ident__MODULE__; // __MODULE__
- IdentifierInfo *Ident__has_cpp_attribute; // __has_cpp_attribute
- IdentifierInfo *Ident__has_c_attribute; // __has_c_attribute
- IdentifierInfo *Ident__has_declspec; // __has_declspec_attribute
- IdentifierInfo *Ident__is_target_arch; // __is_target_arch
- IdentifierInfo *Ident__is_target_vendor; // __is_target_vendor
- IdentifierInfo *Ident__is_target_os; // __is_target_os
- IdentifierInfo *Ident__is_target_environment; // __is_target_environment
- // Weak, only valid (and set) while InMacroArgs is true.
- Token* ArgMacro;
- SourceLocation DATELoc, TIMELoc;
- // Next __COUNTER__ value, starts at 0.
- unsigned CounterValue = 0;
- enum {
- /// Maximum depth of \#includes.
- MaxAllowedIncludeStackDepth = 200
- };
- // State that is set before the preprocessor begins.
- bool KeepComments : 1;
- bool KeepMacroComments : 1;
- bool SuppressIncludeNotFoundError : 1;
- // State that changes while the preprocessor runs:
- bool InMacroArgs : 1; // True if parsing fn macro invocation args.
- /// Whether the preprocessor owns the header search object.
- bool OwnsHeaderSearch : 1;
- /// True if macro expansion is disabled.
- bool DisableMacroExpansion : 1;
- /// Temporarily disables DisableMacroExpansion (i.e. enables expansion)
- /// when parsing preprocessor directives.
- bool MacroExpansionInDirectivesOverride : 1;
- class ResetMacroExpansionHelper;
- /// Whether we have already loaded macros from the external source.
- mutable bool ReadMacrosFromExternalSource : 1;
- /// True if pragmas are enabled.
- bool PragmasEnabled : 1;
- /// True if the current build action is a preprocessing action.
- bool PreprocessedOutput : 1;
- /// True if we are currently preprocessing a #if or #elif directive
- bool ParsingIfOrElifDirective;
- /// True if we are pre-expanding macro arguments.
- bool InMacroArgPreExpansion;
- /// Mapping/lookup information for all identifiers in
- /// the program, including program keywords.
- mutable IdentifierTable Identifiers;
- /// This table contains all the selectors in the program.
- ///
- /// Unlike IdentifierTable above, this table *isn't* populated by the
- /// preprocessor. It is declared/expanded here because its role/lifetime is
- /// conceptually similar to the IdentifierTable. In addition, the current
- /// control flow (in clang::ParseAST()), make it convenient to put here.
- ///
- /// FIXME: Make sure the lifetime of Identifiers/Selectors *isn't* tied to
- /// the lifetime of the preprocessor.
- SelectorTable Selectors;
- /// Information about builtins.
- std::unique_ptr<Builtin::Context> BuiltinInfo;
- /// Tracks all of the pragmas that the client registered
- /// with this preprocessor.
- std::unique_ptr<PragmaNamespace> PragmaHandlers;
- /// Pragma handlers of the original source is stored here during the
- /// parsing of a model file.
- std::unique_ptr<PragmaNamespace> PragmaHandlersBackup;
- /// Tracks all of the comment handlers that the client registered
- /// with this preprocessor.
- std::vector<CommentHandler *> CommentHandlers;
- /// Empty line handler.
- EmptylineHandler *Emptyline = nullptr;
- /// True if we want to ignore EOF token and continue later on (thus
- /// avoid tearing the Lexer and etc. down).
- bool IncrementalProcessing = false;
- public:
- /// The kind of translation unit we are processing.
- const TranslationUnitKind TUKind;
- private:
- /// The code-completion handler.
- CodeCompletionHandler *CodeComplete = nullptr;
- /// The file that we're performing code-completion for, if any.
- const FileEntry *CodeCompletionFile = nullptr;
- /// The offset in file for the code-completion point.
- unsigned CodeCompletionOffset = 0;
- /// The location for the code-completion point. This gets instantiated
- /// when the CodeCompletionFile gets \#include'ed for preprocessing.
- SourceLocation CodeCompletionLoc;
- /// The start location for the file of the code-completion point.
- ///
- /// This gets instantiated when the CodeCompletionFile gets \#include'ed
- /// for preprocessing.
- SourceLocation CodeCompletionFileLoc;
- /// The source location of the \c import contextual keyword we just
- /// lexed, if any.
- SourceLocation ModuleImportLoc;
- /// The module import path that we're currently processing.
- SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> ModuleImportPath;
- /// Whether the last token we lexed was an '@'.
- bool LastTokenWasAt = false;
- /// A position within a C++20 import-seq.
- class ImportSeq {
- public:
- enum State : int {
- // Positive values represent a number of unclosed brackets.
- AtTopLevel = 0,
- AfterTopLevelTokenSeq = -1,
- AfterExport = -2,
- AfterImportSeq = -3,
- };
- ImportSeq(State S) : S(S) {}
- /// Saw any kind of open bracket.
- void handleOpenBracket() {
- S = static_cast<State>(std::max<int>(S, 0) + 1);
- }
- /// Saw any kind of close bracket other than '}'.
- void handleCloseBracket() {
- S = static_cast<State>(std::max<int>(S, 1) - 1);
- }
- /// Saw a close brace.
- void handleCloseBrace() {
- handleCloseBracket();
- if (S == AtTopLevel && !AfterHeaderName)
- S = AfterTopLevelTokenSeq;
- }
- /// Saw a semicolon.
- void handleSemi() {
- if (atTopLevel()) {
- S = AfterTopLevelTokenSeq;
- AfterHeaderName = false;
- }
- }
- /// Saw an 'export' identifier.
- void handleExport() {
- if (S == AfterTopLevelTokenSeq)
- S = AfterExport;
- else if (S <= 0)
- S = AtTopLevel;
- }
- /// Saw an 'import' identifier.
- void handleImport() {
- if (S == AfterTopLevelTokenSeq || S == AfterExport)
- S = AfterImportSeq;
- else if (S <= 0)
- S = AtTopLevel;
- }
- /// Saw a 'header-name' token; do not recognize any more 'import' tokens
- /// until we reach a top-level semicolon.
- void handleHeaderName() {
- if (S == AfterImportSeq)
- AfterHeaderName = true;
- handleMisc();
- }
- /// Saw any other token.
- void handleMisc() {
- if (S <= 0)
- S = AtTopLevel;
- }
- bool atTopLevel() { return S <= 0; }
- bool afterImportSeq() { return S == AfterImportSeq; }
- private:
- State S;
- /// Whether we're in the pp-import-suffix following the header-name in a
- /// pp-import. If so, a close-brace is not sufficient to end the
- /// top-level-token-seq of an import-seq.
- bool AfterHeaderName = false;
- };
- /// Our current position within a C++20 import-seq.
- ImportSeq ImportSeqState = ImportSeq::AfterTopLevelTokenSeq;
- /// Whether the module import expects an identifier next. Otherwise,
- /// it expects a '.' or ';'.
- bool ModuleImportExpectsIdentifier = false;
- /// The identifier and source location of the currently-active
- /// \#pragma clang arc_cf_code_audited begin.
- std::pair<IdentifierInfo *, SourceLocation> PragmaARCCFCodeAuditedInfo;
- /// The source location of the currently-active
- /// \#pragma clang assume_nonnull begin.
- SourceLocation PragmaAssumeNonNullLoc;
- /// True if we hit the code-completion point.
- bool CodeCompletionReached = false;
- /// The code completion token containing the information
- /// on the stem that is to be code completed.
- IdentifierInfo *CodeCompletionII = nullptr;
- /// Range for the code completion token.
- SourceRange CodeCompletionTokenRange;
- /// The directory that the main file should be considered to occupy,
- /// if it does not correspond to a real file (as happens when building a
- /// module).
- const DirectoryEntry *MainFileDir = nullptr;
- /// The number of bytes that we will initially skip when entering the
- /// main file, along with a flag that indicates whether skipping this number
- /// of bytes will place the lexer at the start of a line.
- ///
- /// This is used when loading a precompiled preamble.
- std::pair<int, bool> SkipMainFilePreamble;
- /// Whether we hit an error due to reaching max allowed include depth. Allows
- /// to avoid hitting the same error over and over again.
- bool HasReachedMaxIncludeDepth = false;
- /// The number of currently-active calls to Lex.
- ///
- /// Lex is reentrant, and asking for an (end-of-phase-4) token can often
- /// require asking for multiple additional tokens. This counter makes it
- /// possible for Lex to detect whether it's producing a token for the end
- /// of phase 4 of translation or for some other situation.
- unsigned LexLevel = 0;
- /// The number of (LexLevel 0) preprocessor tokens.
- unsigned TokenCount = 0;
- /// Preprocess every token regardless of LexLevel.
- bool PreprocessToken = false;
- /// The maximum number of (LexLevel 0) tokens before issuing a -Wmax-tokens
- /// warning, or zero for unlimited.
- unsigned MaxTokens = 0;
- SourceLocation MaxTokensOverrideLoc;
- public:
- struct PreambleSkipInfo {
- SourceLocation HashTokenLoc;
- SourceLocation IfTokenLoc;
- bool FoundNonSkipPortion;
- bool FoundElse;
- SourceLocation ElseLoc;
- PreambleSkipInfo(SourceLocation HashTokenLoc, SourceLocation IfTokenLoc,
- bool FoundNonSkipPortion, bool FoundElse,
- SourceLocation ElseLoc)
- : HashTokenLoc(HashTokenLoc), IfTokenLoc(IfTokenLoc),
- FoundNonSkipPortion(FoundNonSkipPortion), FoundElse(FoundElse),
- ElseLoc(ElseLoc) {}
- };
- using IncludedFilesSet = llvm::DenseSet<const FileEntry *>;
- private:
- friend class ASTReader;
- friend class MacroArgs;
- class PreambleConditionalStackStore {
- enum State {
- Off = 0,
- Recording = 1,
- Replaying = 2,
- };
- public:
- PreambleConditionalStackStore() = default;
- void startRecording() { ConditionalStackState = Recording; }
- void startReplaying() { ConditionalStackState = Replaying; }
- bool isRecording() const { return ConditionalStackState == Recording; }
- bool isReplaying() const { return ConditionalStackState == Replaying; }
- ArrayRef<PPConditionalInfo> getStack() const {
- return ConditionalStack;
- }
- void doneReplaying() {
- ConditionalStack.clear();
- ConditionalStackState = Off;
- }
- void setStack(ArrayRef<PPConditionalInfo> s) {
- if (!isRecording() && !isReplaying())
- return;
- ConditionalStack.clear();
- ConditionalStack.append(s.begin(), s.end());
- }
- bool hasRecordedPreamble() const { return !ConditionalStack.empty(); }
- bool reachedEOFWhileSkipping() const { return SkipInfo.hasValue(); }
- void clearSkipInfo() { SkipInfo.reset(); }
- llvm::Optional<PreambleSkipInfo> SkipInfo;
- private:
- SmallVector<PPConditionalInfo, 4> ConditionalStack;
- State ConditionalStackState = Off;
- } PreambleConditionalStack;
- /// The current top of the stack that we're lexing from if
- /// not expanding a macro and we are lexing directly from source code.
- ///
- /// Only one of CurLexer, or CurTokenLexer will be non-null.
- std::unique_ptr<Lexer> CurLexer;
- /// The current top of the stack what we're lexing from
- /// if not expanding a macro.
- ///
- /// This is an alias for CurLexer.
- PreprocessorLexer *CurPPLexer = nullptr;
- /// Used to find the current FileEntry, if CurLexer is non-null
- /// and if applicable.
- ///
- /// This allows us to implement \#include_next and find directory-specific
- /// properties.
- const DirectoryLookup *CurDirLookup = nullptr;
- /// The current macro we are expanding, if we are expanding a macro.
- ///
- /// One of CurLexer and CurTokenLexer must be null.
- std::unique_ptr<TokenLexer> CurTokenLexer;
- /// The kind of lexer we're currently working with.
- enum CurLexerKind {
- CLK_Lexer,
- CLK_TokenLexer,
- CLK_CachingLexer,
- CLK_LexAfterModuleImport
- } CurLexerKind = CLK_Lexer;
- /// If the current lexer is for a submodule that is being built, this
- /// is that submodule.
- Module *CurLexerSubmodule = nullptr;
- /// Keeps track of the stack of files currently
- /// \#included, and macros currently being expanded from, not counting
- /// CurLexer/CurTokenLexer.
- struct IncludeStackInfo {
- enum CurLexerKind CurLexerKind;
- Module *TheSubmodule;
- std::unique_ptr<Lexer> TheLexer;
- PreprocessorLexer *ThePPLexer;
- std::unique_ptr<TokenLexer> TheTokenLexer;
- const DirectoryLookup *TheDirLookup;
- // The following constructors are completely useless copies of the default
- // versions, only needed to pacify MSVC.
- IncludeStackInfo(enum CurLexerKind CurLexerKind, Module *TheSubmodule,
- std::unique_ptr<Lexer> &&TheLexer,
- PreprocessorLexer *ThePPLexer,
- std::unique_ptr<TokenLexer> &&TheTokenLexer,
- const DirectoryLookup *TheDirLookup)
- : CurLexerKind(std::move(CurLexerKind)),
- TheSubmodule(std::move(TheSubmodule)), TheLexer(std::move(TheLexer)),
- ThePPLexer(std::move(ThePPLexer)),
- TheTokenLexer(std::move(TheTokenLexer)),
- TheDirLookup(std::move(TheDirLookup)) {}
- };
- std::vector<IncludeStackInfo> IncludeMacroStack;
- /// Actions invoked when some preprocessor activity is
- /// encountered (e.g. a file is \#included, etc).
- std::unique_ptr<PPCallbacks> Callbacks;
- struct MacroExpandsInfo {
- Token Tok;
- MacroDefinition MD;
- SourceRange Range;
- MacroExpandsInfo(Token Tok, MacroDefinition MD, SourceRange Range)
- : Tok(Tok), MD(MD), Range(Range) {}
- };
- SmallVector<MacroExpandsInfo, 2> DelayedMacroExpandsCallbacks;
- /// Information about a name that has been used to define a module macro.
- struct ModuleMacroInfo {
- /// The most recent macro directive for this identifier.
- MacroDirective *MD;
- /// The active module macros for this identifier.
- llvm::TinyPtrVector<ModuleMacro *> ActiveModuleMacros;
- /// The generation number at which we last updated ActiveModuleMacros.
- /// \see Preprocessor::VisibleModules.
- unsigned ActiveModuleMacrosGeneration = 0;
- /// Whether this macro name is ambiguous.
- bool IsAmbiguous = false;
- /// The module macros that are overridden by this macro.
- llvm::TinyPtrVector<ModuleMacro *> OverriddenMacros;
- ModuleMacroInfo(MacroDirective *MD) : MD(MD) {}
- };
- /// The state of a macro for an identifier.
- class MacroState {
- mutable llvm::PointerUnion<MacroDirective *, ModuleMacroInfo *> State;
- ModuleMacroInfo *getModuleInfo(Preprocessor &PP,
- const IdentifierInfo *II) const {
- if (II->isOutOfDate())
- PP.updateOutOfDateIdentifier(const_cast<IdentifierInfo&>(*II));
- // FIXME: Find a spare bit on IdentifierInfo and store a
- // HasModuleMacros flag.
- if (!II->hasMacroDefinition() ||
- (!PP.getLangOpts().Modules &&
- !PP.getLangOpts().ModulesLocalVisibility) ||
- !PP.CurSubmoduleState->VisibleModules.getGeneration())
- return nullptr;
- auto *Info = State.dyn_cast<ModuleMacroInfo*>();
- if (!Info) {
- Info = new (PP.getPreprocessorAllocator())
- ModuleMacroInfo(State.get<MacroDirective *>());
- State = Info;
- }
- if (PP.CurSubmoduleState->VisibleModules.getGeneration() !=
- Info->ActiveModuleMacrosGeneration)
- PP.updateModuleMacroInfo(II, *Info);
- return Info;
- }
- public:
- MacroState() : MacroState(nullptr) {}
- MacroState(MacroDirective *MD) : State(MD) {}
- MacroState(MacroState &&O) noexcept : State(O.State) {
- O.State = (MacroDirective *)nullptr;
- }
- MacroState &operator=(MacroState &&O) noexcept {
- auto S = O.State;
- O.State = (MacroDirective *)nullptr;
- State = S;
- return *this;
- }
- ~MacroState() {
- if (auto *Info = State.dyn_cast<ModuleMacroInfo*>())
- Info->~ModuleMacroInfo();
- }
- MacroDirective *getLatest() const {
- if (auto *Info = State.dyn_cast<ModuleMacroInfo*>())
- return Info->MD;
- return State.get<MacroDirective*>();
- }
- void setLatest(MacroDirective *MD) {
- if (auto *Info = State.dyn_cast<ModuleMacroInfo*>())
- Info->MD = MD;
- else
- State = MD;
- }
- bool isAmbiguous(Preprocessor &PP, const IdentifierInfo *II) const {
- auto *Info = getModuleInfo(PP, II);
- return Info ? Info->IsAmbiguous : false;
- }
- ArrayRef<ModuleMacro *>
- getActiveModuleMacros(Preprocessor &PP, const IdentifierInfo *II) const {
- if (auto *Info = getModuleInfo(PP, II))
- return Info->ActiveModuleMacros;
- return None;
- }
- MacroDirective::DefInfo findDirectiveAtLoc(SourceLocation Loc,
- SourceManager &SourceMgr) const {
- // FIXME: Incorporate module macros into the result of this.
- if (auto *Latest = getLatest())
- return Latest->findDirectiveAtLoc(Loc, SourceMgr);
- return {};
- }
- void overrideActiveModuleMacros(Preprocessor &PP, IdentifierInfo *II) {
- if (auto *Info = getModuleInfo(PP, II)) {
- Info->OverriddenMacros.insert(Info->OverriddenMacros.end(),
- Info->ActiveModuleMacros.begin(),
- Info->ActiveModuleMacros.end());
- Info->ActiveModuleMacros.clear();
- Info->IsAmbiguous = false;
- }
- }
- ArrayRef<ModuleMacro*> getOverriddenMacros() const {
- if (auto *Info = State.dyn_cast<ModuleMacroInfo*>())
- return Info->OverriddenMacros;
- return None;
- }
- void setOverriddenMacros(Preprocessor &PP,
- ArrayRef<ModuleMacro *> Overrides) {
- auto *Info = State.dyn_cast<ModuleMacroInfo*>();
- if (!Info) {
- if (Overrides.empty())
- return;
- Info = new (PP.getPreprocessorAllocator())
- ModuleMacroInfo(State.get<MacroDirective *>());
- State = Info;
- }
- Info->OverriddenMacros.clear();
- Info->OverriddenMacros.insert(Info->OverriddenMacros.end(),
- Overrides.begin(), Overrides.end());
- Info->ActiveModuleMacrosGeneration = 0;
- }
- };
- /// For each IdentifierInfo that was associated with a macro, we
- /// keep a mapping to the history of all macro definitions and #undefs in
- /// the reverse order (the latest one is in the head of the list).
- ///
- /// This mapping lives within the \p CurSubmoduleState.
- using MacroMap = llvm::DenseMap<const IdentifierInfo *, MacroState>;
- struct SubmoduleState;
- /// Information about a submodule that we're currently building.
- struct BuildingSubmoduleInfo {
- /// The module that we are building.
- Module *M;
- /// The location at which the module was included.
- SourceLocation ImportLoc;
- /// Whether we entered this submodule via a pragma.
- bool IsPragma;
- /// The previous SubmoduleState.
- SubmoduleState *OuterSubmoduleState;
- /// The number of pending module macro names when we started building this.
- unsigned OuterPendingModuleMacroNames;
- BuildingSubmoduleInfo(Module *M, SourceLocation ImportLoc, bool IsPragma,
- SubmoduleState *OuterSubmoduleState,
- unsigned OuterPendingModuleMacroNames)
- : M(M), ImportLoc(ImportLoc), IsPragma(IsPragma),
- OuterSubmoduleState(OuterSubmoduleState),
- OuterPendingModuleMacroNames(OuterPendingModuleMacroNames) {}
- };
- SmallVector<BuildingSubmoduleInfo, 8> BuildingSubmoduleStack;
- /// Information about a submodule's preprocessor state.
- struct SubmoduleState {
- /// The macros for the submodule.
- MacroMap Macros;
- /// The set of modules that are visible within the submodule.
- VisibleModuleSet VisibleModules;
- // FIXME: CounterValue?
- // FIXME: PragmaPushMacroInfo?
- };
- std::map<Module *, SubmoduleState> Submodules;
- /// The preprocessor state for preprocessing outside of any submodule.
- SubmoduleState NullSubmoduleState;
- /// The current submodule state. Will be \p NullSubmoduleState if we're not
- /// in a submodule.
- SubmoduleState *CurSubmoduleState;
- /// The files that have been included.
- IncludedFilesSet IncludedFiles;
- /// The set of known macros exported from modules.
- llvm::FoldingSet<ModuleMacro> ModuleMacros;
- /// The names of potential module macros that we've not yet processed.
- llvm::SmallVector<const IdentifierInfo *, 32> PendingModuleMacroNames;
- /// The list of module macros, for each identifier, that are not overridden by
- /// any other module macro.
- llvm::DenseMap<const IdentifierInfo *, llvm::TinyPtrVector<ModuleMacro *>>
- LeafModuleMacros;
- /// Macros that we want to warn because they are not used at the end
- /// of the translation unit.
- ///
- /// We store just their SourceLocations instead of
- /// something like MacroInfo*. The benefit of this is that when we are
- /// deserializing from PCH, we don't need to deserialize identifier & macros
- /// just so that we can report that they are unused, we just warn using
- /// the SourceLocations of this set (that will be filled by the ASTReader).
- using WarnUnusedMacroLocsTy = llvm::SmallDenseSet<SourceLocation, 32>;
- WarnUnusedMacroLocsTy WarnUnusedMacroLocs;
- /// This is a pair of an optional message and source location used for pragmas
- /// that annotate macros like pragma clang restrict_expansion and pragma clang
- /// deprecated. This pair stores the optional message and the location of the
- /// annotation pragma for use producing diagnostics and notes.
- using MsgLocationPair = std::pair<std::string, SourceLocation>;
- struct MacroAnnotationInfo {
- SourceLocation Location;
- std::string Message;
- };
- struct MacroAnnotations {
- llvm::Optional<MacroAnnotationInfo> DeprecationInfo;
- llvm::Optional<MacroAnnotationInfo> RestrictExpansionInfo;
- llvm::Optional<SourceLocation> FinalAnnotationLoc;
- static MacroAnnotations makeDeprecation(SourceLocation Loc,
- std::string Msg) {
- return MacroAnnotations{MacroAnnotationInfo{Loc, std::move(Msg)},
- llvm::None, llvm::None};
- }
- static MacroAnnotations makeRestrictExpansion(SourceLocation Loc,
- std::string Msg) {
- return MacroAnnotations{
- llvm::None, MacroAnnotationInfo{Loc, std::move(Msg)}, llvm::None};
- }
- static MacroAnnotations makeFinal(SourceLocation Loc) {
- return MacroAnnotations{llvm::None, llvm::None, Loc};
- }
- };
- /// Warning information for macro annotations.
- llvm::DenseMap<const IdentifierInfo *, MacroAnnotations> AnnotationInfos;
- /// A "freelist" of MacroArg objects that can be
- /// reused for quick allocation.
- MacroArgs *MacroArgCache = nullptr;
- /// For each IdentifierInfo used in a \#pragma push_macro directive,
- /// we keep a MacroInfo stack used to restore the previous macro value.
- llvm::DenseMap<IdentifierInfo *, std::vector<MacroInfo *>>
- PragmaPushMacroInfo;
- // Various statistics we track for performance analysis.
- unsigned NumDirectives = 0;
- unsigned NumDefined = 0;
- unsigned NumUndefined = 0;
- unsigned NumPragma = 0;
- unsigned NumIf = 0;
- unsigned NumElse = 0;
- unsigned NumEndif = 0;
- unsigned NumEnteredSourceFiles = 0;
- unsigned MaxIncludeStackDepth = 0;
- unsigned NumMacroExpanded = 0;
- unsigned NumFnMacroExpanded = 0;
- unsigned NumBuiltinMacroExpanded = 0;
- unsigned NumFastMacroExpanded = 0;
- unsigned NumTokenPaste = 0;
- unsigned NumFastTokenPaste = 0;
- unsigned NumSkipped = 0;
- /// The predefined macros that preprocessor should use from the
- /// command line etc.
- std::string Predefines;
- /// The file ID for the preprocessor predefines.
- FileID PredefinesFileID;
- /// The file ID for the PCH through header.
- FileID PCHThroughHeaderFileID;
- /// Whether tokens are being skipped until a #pragma hdrstop is seen.
- bool SkippingUntilPragmaHdrStop = false;
- /// Whether tokens are being skipped until the through header is seen.
- bool SkippingUntilPCHThroughHeader = false;
- /// \{
- /// Cache of macro expanders to reduce malloc traffic.
- enum { TokenLexerCacheSize = 8 };
- unsigned NumCachedTokenLexers;
- std::unique_ptr<TokenLexer> TokenLexerCache[TokenLexerCacheSize];
- /// \}
- /// Keeps macro expanded tokens for TokenLexers.
- //
- /// Works like a stack; a TokenLexer adds the macro expanded tokens that is
- /// going to lex in the cache and when it finishes the tokens are removed
- /// from the end of the cache.
- SmallVector<Token, 16> MacroExpandedTokens;
- std::vector<std::pair<TokenLexer *, size_t>> MacroExpandingLexersStack;
- /// A record of the macro definitions and expansions that
- /// occurred during preprocessing.
- ///
- /// This is an optional side structure that can be enabled with
- /// \c createPreprocessingRecord() prior to preprocessing.
- PreprocessingRecord *Record = nullptr;
- /// Cached tokens state.
- using CachedTokensTy = SmallVector<Token, 1>;
- /// Cached tokens are stored here when we do backtracking or
- /// lookahead. They are "lexed" by the CachingLex() method.
- CachedTokensTy CachedTokens;
- /// The position of the cached token that CachingLex() should
- /// "lex" next.
- ///
- /// If it points beyond the CachedTokens vector, it means that a normal
- /// Lex() should be invoked.
- CachedTokensTy::size_type CachedLexPos = 0;
- /// Stack of backtrack positions, allowing nested backtracks.
- ///
- /// The EnableBacktrackAtThisPos() method pushes a position to
- /// indicate where CachedLexPos should be set when the BackTrack() method is
- /// invoked (at which point the last position is popped).
- std::vector<CachedTokensTy::size_type> BacktrackPositions;
- struct MacroInfoChain {
- MacroInfo MI;
- MacroInfoChain *Next;
- };
- /// MacroInfos are managed as a chain for easy disposal. This is the head
- /// of that list.
- MacroInfoChain *MIChainHead = nullptr;
- void updateOutOfDateIdentifier(IdentifierInfo &II) const;
- public:
- Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
- DiagnosticsEngine &diags, LangOptions &opts, SourceManager &SM,
- HeaderSearch &Headers, ModuleLoader &TheModuleLoader,
- IdentifierInfoLookup *IILookup = nullptr,
- bool OwnsHeaderSearch = false,
- TranslationUnitKind TUKind = TU_Complete);
- ~Preprocessor();
- /// Initialize the preprocessor using information about the target.
- ///
- /// \param Target is owned by the caller and must remain valid for the
- /// lifetime of the preprocessor.
- /// \param AuxTarget is owned by the caller and must remain valid for
- /// the lifetime of the preprocessor.
- void Initialize(const TargetInfo &Target,
- const TargetInfo *AuxTarget = nullptr);
- /// Initialize the preprocessor to parse a model file
- ///
- /// To parse model files the preprocessor of the original source is reused to
- /// preserver the identifier table. However to avoid some duplicate
- /// information in the preprocessor some cleanup is needed before it is used
- /// to parse model files. This method does that cleanup.
- void InitializeForModelFile();
- /// Cleanup after model file parsing
- void FinalizeForModelFile();
- /// Retrieve the preprocessor options used to initialize this
- /// preprocessor.
- PreprocessorOptions &getPreprocessorOpts() const { return *PPOpts; }
- DiagnosticsEngine &getDiagnostics() const { return *Diags; }
- void setDiagnostics(DiagnosticsEngine &D) { Diags = &D; }
- const LangOptions &getLangOpts() const { return LangOpts; }
- const TargetInfo &getTargetInfo() const { return *Target; }
- const TargetInfo *getAuxTargetInfo() const { return AuxTarget; }
- FileManager &getFileManager() const { return FileMgr; }
- SourceManager &getSourceManager() const { return SourceMgr; }
- HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; }
- IdentifierTable &getIdentifierTable() { return Identifiers; }
- const IdentifierTable &getIdentifierTable() const { return Identifiers; }
- SelectorTable &getSelectorTable() { return Selectors; }
- Builtin::Context &getBuiltinInfo() { return *BuiltinInfo; }
- llvm::BumpPtrAllocator &getPreprocessorAllocator() { return BP; }
- void setExternalSource(ExternalPreprocessorSource *Source) {
- ExternalSource = Source;
- }
- ExternalPreprocessorSource *getExternalSource() const {
- return ExternalSource;
- }
- /// Retrieve the module loader associated with this preprocessor.
- ModuleLoader &getModuleLoader() const { return TheModuleLoader; }
- bool hadModuleLoaderFatalFailure() const {
- return TheModuleLoader.HadFatalFailure;
- }
- /// Retrieve the number of Directives that have been processed by the
- /// Preprocessor.
- unsigned getNumDirectives() const {
- return NumDirectives;
- }
- /// True if we are currently preprocessing a #if or #elif directive
- bool isParsingIfOrElifDirective() const {
- return ParsingIfOrElifDirective;
- }
- /// Control whether the preprocessor retains comments in output.
- void SetCommentRetentionState(bool KeepComments, bool KeepMacroComments) {
- this->KeepComments = KeepComments | KeepMacroComments;
- this->KeepMacroComments = KeepMacroComments;
- }
- bool getCommentRetentionState() const { return KeepComments; }
- void setPragmasEnabled(bool Enabled) { PragmasEnabled = Enabled; }
- bool getPragmasEnabled() const { return PragmasEnabled; }
- void SetSuppressIncludeNotFoundError(bool Suppress) {
- SuppressIncludeNotFoundError = Suppress;
- }
- bool GetSuppressIncludeNotFoundError() {
- return SuppressIncludeNotFoundError;
- }
- /// Sets whether the preprocessor is responsible for producing output or if
- /// it is producing tokens to be consumed by Parse and Sema.
- void setPreprocessedOutput(bool IsPreprocessedOutput) {
- PreprocessedOutput = IsPreprocessedOutput;
- }
- /// Returns true if the preprocessor is responsible for generating output,
- /// false if it is producing tokens to be consumed by Parse and Sema.
- bool isPreprocessedOutput() const { return PreprocessedOutput; }
- /// Return true if we are lexing directly from the specified lexer.
- bool isCurrentLexer(const PreprocessorLexer *L) const {
- return CurPPLexer == L;
- }
- /// Return the current lexer being lexed from.
- ///
- /// Note that this ignores any potentially active macro expansions and _Pragma
- /// expansions going on at the time.
- PreprocessorLexer *getCurrentLexer() const { return CurPPLexer; }
- /// Return the current file lexer being lexed from.
- ///
- /// Note that this ignores any potentially active macro expansions and _Pragma
- /// expansions going on at the time.
- PreprocessorLexer *getCurrentFileLexer() const;
- /// Return the submodule owning the file being lexed. This may not be
- /// the current module if we have changed modules since entering the file.
- Module *getCurrentLexerSubmodule() const { return CurLexerSubmodule; }
- /// Returns the FileID for the preprocessor predefines.
- FileID getPredefinesFileID() const { return PredefinesFileID; }
- /// \{
- /// Accessors for preprocessor callbacks.
- ///
- /// Note that this class takes ownership of any PPCallbacks object given to
- /// it.
- PPCallbacks *getPPCallbacks() const { return Callbacks.get(); }
- void addPPCallbacks(std::unique_ptr<PPCallbacks> C) {
- if (Callbacks)
- C = std::make_unique<PPChainedCallbacks>(std::move(C),
- std::move(Callbacks));
- Callbacks = std::move(C);
- }
- /// \}
- /// Get the number of tokens processed so far.
- unsigned getTokenCount() const { return TokenCount; }
- /// Get the max number of tokens before issuing a -Wmax-tokens warning.
- unsigned getMaxTokens() const { return MaxTokens; }
- void overrideMaxTokens(unsigned Value, SourceLocation Loc) {
- MaxTokens = Value;
- MaxTokensOverrideLoc = Loc;
- };
- SourceLocation getMaxTokensOverrideLoc() const { return MaxTokensOverrideLoc; }
- /// Register a function that would be called on each token in the final
- /// expanded token stream.
- /// This also reports annotation tokens produced by the parser.
- void setTokenWatcher(llvm::unique_function<void(const clang::Token &)> F) {
- OnToken = std::move(F);
- }
- void setPreprocessToken(bool Preprocess) { PreprocessToken = Preprocess; }
- bool isMacroDefined(StringRef Id) {
- return isMacroDefined(&Identifiers.get(Id));
- }
- bool isMacroDefined(const IdentifierInfo *II) {
- return II->hasMacroDefinition() &&
- (!getLangOpts().Modules || (bool)getMacroDefinition(II));
- }
- /// Determine whether II is defined as a macro within the module M,
- /// if that is a module that we've already preprocessed. Does not check for
- /// macros imported into M.
- bool isMacroDefinedInLocalModule(const IdentifierInfo *II, Module *M) {
- if (!II->hasMacroDefinition())
- return false;
- auto I = Submodules.find(M);
- if (I == Submodules.end())
- return false;
- auto J = I->second.Macros.find(II);
- if (J == I->second.Macros.end())
- return false;
- auto *MD = J->second.getLatest();
- return MD && MD->isDefined();
- }
- MacroDefinition getMacroDefinition(const IdentifierInfo *II) {
- if (!II->hasMacroDefinition())
- return {};
- MacroState &S = CurSubmoduleState->Macros[II];
- auto *MD = S.getLatest();
- while (MD && isa<VisibilityMacroDirective>(MD))
- MD = MD->getPrevious();
- return MacroDefinition(dyn_cast_or_null<DefMacroDirective>(MD),
- S.getActiveModuleMacros(*this, II),
- S.isAmbiguous(*this, II));
- }
- MacroDefinition getMacroDefinitionAtLoc(const IdentifierInfo *II,
- SourceLocation Loc) {
- if (!II->hadMacroDefinition())
- return {};
- MacroState &S = CurSubmoduleState->Macros[II];
- MacroDirective::DefInfo DI;
- if (auto *MD = S.getLatest())
- DI = MD->findDirectiveAtLoc(Loc, getSourceManager());
- // FIXME: Compute the set of active module macros at the specified location.
- return MacroDefinition(DI.getDirective(),
- S.getActiveModuleMacros(*this, II),
- S.isAmbiguous(*this, II));
- }
- /// Given an identifier, return its latest non-imported MacroDirective
- /// if it is \#define'd and not \#undef'd, or null if it isn't \#define'd.
- MacroDirective *getLocalMacroDirective(const IdentifierInfo *II) const {
- if (!II->hasMacroDefinition())
- return nullptr;
- auto *MD = getLocalMacroDirectiveHistory(II);
- if (!MD || MD->getDefinition().isUndefined())
- return nullptr;
- return MD;
- }
- const MacroInfo *getMacroInfo(const IdentifierInfo *II) const {
- return const_cast<Preprocessor*>(this)->getMacroInfo(II);
- }
- MacroInfo *getMacroInfo(const IdentifierInfo *II) {
- if (!II->hasMacroDefinition())
- return nullptr;
- if (auto MD = getMacroDefinition(II))
- return MD.getMacroInfo();
- return nullptr;
- }
- /// Given an identifier, return the latest non-imported macro
- /// directive for that identifier.
- ///
- /// One can iterate over all previous macro directives from the most recent
- /// one.
- MacroDirective *getLocalMacroDirectiveHistory(const IdentifierInfo *II) const;
- /// Add a directive to the macro directive history for this identifier.
- void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD);
- DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI,
- SourceLocation Loc) {
- DefMacroDirective *MD = AllocateDefMacroDirective(MI, Loc);
- appendMacroDirective(II, MD);
- return MD;
- }
- DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II,
- MacroInfo *MI) {
- return appendDefMacroDirective(II, MI, MI->getDefinitionLoc());
- }
- /// Set a MacroDirective that was loaded from a PCH file.
- void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *ED,
- MacroDirective *MD);
- /// Register an exported macro for a module and identifier.
- ModuleMacro *addModuleMacro(Module *Mod, IdentifierInfo *II, MacroInfo *Macro,
- ArrayRef<ModuleMacro *> Overrides, bool &IsNew);
- ModuleMacro *getModuleMacro(Module *Mod, const IdentifierInfo *II);
- /// Get the list of leaf (non-overridden) module macros for a name.
- ArrayRef<ModuleMacro*> getLeafModuleMacros(const IdentifierInfo *II) const {
- if (II->isOutOfDate())
- updateOutOfDateIdentifier(const_cast<IdentifierInfo&>(*II));
- auto I = LeafModuleMacros.find(II);
- if (I != LeafModuleMacros.end())
- return I->second;
- return None;
- }
- /// Get the list of submodules that we're currently building.
- ArrayRef<BuildingSubmoduleInfo> getBuildingSubmodules() const {
- return BuildingSubmoduleStack;
- }
- /// \{
- /// Iterators for the macro history table. Currently defined macros have
- /// IdentifierInfo::hasMacroDefinition() set and an empty
- /// MacroInfo::getUndefLoc() at the head of the list.
- using macro_iterator = MacroMap::const_iterator;
- macro_iterator macro_begin(bool IncludeExternalMacros = true) const;
- macro_iterator macro_end(bool IncludeExternalMacros = true) const;
- llvm::iterator_range<macro_iterator>
- macros(bool IncludeExternalMacros = true) const {
- macro_iterator begin = macro_begin(IncludeExternalMacros);
- macro_iterator end = macro_end(IncludeExternalMacros);
- return llvm::make_range(begin, end);
- }
- /// \}
- /// Mark the file as included.
- /// Returns true if this is the first time the file was included.
- bool markIncluded(const FileEntry *File) {
- HeaderInfo.getFileInfo(File);
- return IncludedFiles.insert(File).second;
- }
- /// Return true if this header has already been included.
- bool alreadyIncluded(const FileEntry *File) const {
- return IncludedFiles.count(File);
- }
- /// Get the set of included files.
- IncludedFilesSet &getIncludedFiles() { return IncludedFiles; }
- const IncludedFilesSet &getIncludedFiles() const { return IncludedFiles; }
- /// Return the name of the macro defined before \p Loc that has
- /// spelling \p Tokens. If there are multiple macros with same spelling,
- /// return the last one defined.
- StringRef getLastMacroWithSpelling(SourceLocation Loc,
- ArrayRef<TokenValue> Tokens) const;
- const std::string &getPredefines() const { return Predefines; }
- /// Set the predefines for this Preprocessor.
- ///
- /// These predefines are automatically injected when parsing the main file.
- void setPredefines(const char *P) { Predefines = P; }
- void setPredefines(StringRef P) { Predefines = std::string(P); }
- /// Return information about the specified preprocessor
- /// identifier token.
- IdentifierInfo *getIdentifierInfo(StringRef Name) const {
- return &Identifiers.get(Name);
- }
- /// Add the specified pragma handler to this preprocessor.
- ///
- /// If \p Namespace is non-null, then it is a token required to exist on the
- /// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
- void AddPragmaHandler(StringRef Namespace, PragmaHandler *Handler);
- void AddPragmaHandler(PragmaHandler *Handler) {
- AddPragmaHandler(StringRef(), Handler);
- }
- /// Remove the specific pragma handler from this preprocessor.
- ///
- /// If \p Namespace is non-null, then it should be the namespace that
- /// \p Handler was added to. It is an error to remove a handler that
- /// has not been registered.
- void RemovePragmaHandler(StringRef Namespace, PragmaHandler *Handler);
- void RemovePragmaHandler(PragmaHandler *Handler) {
- RemovePragmaHandler(StringRef(), Handler);
- }
- /// Install empty handlers for all pragmas (making them ignored).
- void IgnorePragmas();
- /// Set empty line handler.
- void setEmptylineHandler(EmptylineHandler *Handler) { Emptyline = Handler; }
- EmptylineHandler *getEmptylineHandler() const { return Emptyline; }
- /// Add the specified comment handler to the preprocessor.
- void addCommentHandler(CommentHandler *Handler);
- /// Remove the specified comment handler.
- ///
- /// It is an error to remove a handler that has not been registered.
- void removeCommentHandler(CommentHandler *Handler);
- /// Set the code completion handler to the given object.
- void setCodeCompletionHandler(CodeCompletionHandler &Handler) {
- CodeComplete = &Handler;
- }
- /// Retrieve the current code-completion handler.
- CodeCompletionHandler *getCodeCompletionHandler() const {
- return CodeComplete;
- }
- /// Clear out the code completion handler.
- void clearCodeCompletionHandler() {
- CodeComplete = nullptr;
- }
- /// Hook used by the lexer to invoke the "included file" code
- /// completion point.
- void CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled);
- /// Hook used by the lexer to invoke the "natural language" code
- /// completion point.
- void CodeCompleteNaturalLanguage();
- /// Set the code completion token for filtering purposes.
- void setCodeCompletionIdentifierInfo(IdentifierInfo *Filter) {
- CodeCompletionII = Filter;
- }
- /// Set the code completion token range for detecting replacement range later
- /// on.
- void setCodeCompletionTokenRange(const SourceLocation Start,
- const SourceLocation End) {
- CodeCompletionTokenRange = {Start, End};
- }
- SourceRange getCodeCompletionTokenRange() const {
- return CodeCompletionTokenRange;
- }
- /// Get the code completion token for filtering purposes.
- StringRef getCodeCompletionFilter() {
- if (CodeCompletionII)
- return CodeCompletionII->getName();
- return {};
- }
- /// Retrieve the preprocessing record, or NULL if there is no
- /// preprocessing record.
- PreprocessingRecord *getPreprocessingRecord() const { return Record; }
- /// Create a new preprocessing record, which will keep track of
- /// all macro expansions, macro definitions, etc.
- void createPreprocessingRecord();
- /// Returns true if the FileEntry is the PCH through header.
- bool isPCHThroughHeader(const FileEntry *FE);
- /// True if creating a PCH with a through header.
- bool creatingPCHWithThroughHeader();
- /// True if using a PCH with a through header.
- bool usingPCHWithThroughHeader();
- /// True if creating a PCH with a #pragma hdrstop.
- bool creatingPCHWithPragmaHdrStop();
- /// True if using a PCH with a #pragma hdrstop.
- bool usingPCHWithPragmaHdrStop();
- /// Skip tokens until after the #include of the through header or
- /// until after a #pragma hdrstop.
- void SkipTokensWhileUsingPCH();
- /// Process directives while skipping until the through header or
- /// #pragma hdrstop is found.
- void HandleSkippedDirectiveWhileUsingPCH(Token &Result,
- SourceLocation HashLoc);
- /// Enter the specified FileID as the main source file,
- /// which implicitly adds the builtin defines etc.
- void EnterMainSourceFile();
- /// Inform the preprocessor callbacks that processing is complete.
- void EndSourceFile();
- /// Add a source file to the top of the include stack and
- /// start lexing tokens from it instead of the current buffer.
- ///
- /// Emits a diagnostic, doesn't enter the file, and returns true on error.
- bool EnterSourceFile(FileID FID, const DirectoryLookup *Dir,
- SourceLocation Loc, bool IsFirstIncludeOfFile = true);
- /// Add a Macro to the top of the include stack and start lexing
- /// tokens from it instead of the current buffer.
- ///
- /// \param Args specifies the tokens input to a function-like macro.
- /// \param ILEnd specifies the location of the ')' for a function-like macro
- /// or the identifier for an object-like macro.
- void EnterMacro(Token &Tok, SourceLocation ILEnd, MacroInfo *Macro,
- MacroArgs *Args);
- private:
- /// Add a "macro" context to the top of the include stack,
- /// which will cause the lexer to start returning the specified tokens.
- ///
- /// If \p DisableMacroExpansion is true, tokens lexed from the token stream
- /// will not be subject to further macro expansion. Otherwise, these tokens
- /// will be re-macro-expanded when/if expansion is enabled.
- ///
- /// If \p OwnsTokens is false, this method assumes that the specified stream
- /// of tokens has a permanent owner somewhere, so they do not need to be
- /// copied. If it is true, it assumes the array of tokens is allocated with
- /// \c new[] and the Preprocessor will delete[] it.
- ///
- /// If \p IsReinject the resulting tokens will have Token::IsReinjected flag
- /// set, see the flag documentation for details.
- void EnterTokenStream(const Token *Toks, unsigned NumToks,
- bool DisableMacroExpansion, bool OwnsTokens,
- bool IsReinject);
- public:
- void EnterTokenStream(std::unique_ptr<Token[]> Toks, unsigned NumToks,
- bool DisableMacroExpansion, bool IsReinject) {
- EnterTokenStream(Toks.release(), NumToks, DisableMacroExpansion, true,
- IsReinject);
- }
- void EnterTokenStream(ArrayRef<Token> Toks, bool DisableMacroExpansion,
- bool IsReinject) {
- EnterTokenStream(Toks.data(), Toks.size(), DisableMacroExpansion, false,
- IsReinject);
- }
- /// Pop the current lexer/macro exp off the top of the lexer stack.
- ///
- /// This should only be used in situations where the current state of the
- /// top-of-stack lexer is known.
- void RemoveTopOfLexerStack();
- /// From the point that this method is called, and until
- /// CommitBacktrackedTokens() or Backtrack() is called, the Preprocessor
- /// keeps track of the lexed tokens so that a subsequent Backtrack() call will
- /// make the Preprocessor re-lex the same tokens.
- ///
- /// Nested backtracks are allowed, meaning that EnableBacktrackAtThisPos can
- /// be called multiple times and CommitBacktrackedTokens/Backtrack calls will
- /// be combined with the EnableBacktrackAtThisPos calls in reverse order.
- ///
- /// NOTE: *DO NOT* forget to call either CommitBacktrackedTokens or Backtrack
- /// at some point after EnableBacktrackAtThisPos. If you don't, caching of
- /// tokens will continue indefinitely.
- ///
- void EnableBacktrackAtThisPos();
- /// Disable the last EnableBacktrackAtThisPos call.
- void CommitBacktrackedTokens();
- /// Make Preprocessor re-lex the tokens that were lexed since
- /// EnableBacktrackAtThisPos() was previously called.
- void Backtrack();
- /// True if EnableBacktrackAtThisPos() was called and
- /// caching of tokens is on.
- bool isBacktrackEnabled() const { return !BacktrackPositions.empty(); }
- /// Lex the next token for this preprocessor.
- void Lex(Token &Result);
- /// Lex a token, forming a header-name token if possible.
- bool LexHeaderName(Token &Result, bool AllowMacroExpansion = true);
- bool LexAfterModuleImport(Token &Result);
- void CollectPpImportSuffix(SmallVectorImpl<Token> &Toks);
- void makeModuleVisible(Module *M, SourceLocation Loc);
- SourceLocation getModuleImportLoc(Module *M) const {
- return CurSubmoduleState->VisibleModules.getImportLoc(M);
- }
- /// Lex a string literal, which may be the concatenation of multiple
- /// string literals and may even come from macro expansion.
- /// \returns true on success, false if a error diagnostic has been generated.
- bool LexStringLiteral(Token &Result, std::string &String,
- const char *DiagnosticTag, bool AllowMacroExpansion) {
- if (AllowMacroExpansion)
- Lex(Result);
- else
- LexUnexpandedToken(Result);
- return FinishLexStringLiteral(Result, String, DiagnosticTag,
- AllowMacroExpansion);
- }
- /// Complete the lexing of a string literal where the first token has
- /// already been lexed (see LexStringLiteral).
- bool FinishLexStringLiteral(Token &Result, std::string &String,
- const char *DiagnosticTag,
- bool AllowMacroExpansion);
- /// Lex a token. If it's a comment, keep lexing until we get
- /// something not a comment.
- ///
- /// This is useful in -E -C mode where comments would foul up preprocessor
- /// directive handling.
- void LexNonComment(Token &Result) {
- do
- Lex(Result);
- while (Result.getKind() == tok::comment);
- }
- /// Just like Lex, but disables macro expansion of identifier tokens.
- void LexUnexpandedToken(Token &Result) {
- // Disable macro expansion.
- bool OldVal = DisableMacroExpansion;
- DisableMacroExpansion = true;
- // Lex the token.
- Lex(Result);
- // Reenable it.
- DisableMacroExpansion = OldVal;
- }
- /// Like LexNonComment, but this disables macro expansion of
- /// identifier tokens.
- void LexUnexpandedNonComment(Token &Result) {
- do
- LexUnexpandedToken(Result);
- while (Result.getKind() == tok::comment);
- }
- /// Parses a simple integer literal to get its numeric value. Floating
- /// point literals and user defined literals are rejected. Used primarily to
- /// handle pragmas that accept integer arguments.
- bool parseSimpleIntegerLiteral(Token &Tok, uint64_t &Value);
- /// Disables macro expansion everywhere except for preprocessor directives.
- void SetMacroExpansionOnlyInDirectives() {
- DisableMacroExpansion = true;
- MacroExpansionInDirectivesOverride = true;
- }
- /// Peeks ahead N tokens and returns that token without consuming any
- /// tokens.
- ///
- /// LookAhead(0) returns the next token that would be returned by Lex(),
- /// LookAhead(1) returns the token after it, etc. This returns normal
- /// tokens after phase 5. As such, it is equivalent to using
- /// 'Lex', not 'LexUnexpandedToken'.
- const Token &LookAhead(unsigned N) {
- assert(LexLevel == 0 && "cannot use lookahead while lexing");
- if (CachedLexPos + N < CachedTokens.size())
- return CachedTokens[CachedLexPos+N];
- else
- return PeekAhead(N+1);
- }
- /// When backtracking is enabled and tokens are cached,
- /// this allows to revert a specific number of tokens.
- ///
- /// Note that the number of tokens being reverted should be up to the last
- /// backtrack position, not more.
- void RevertCachedTokens(unsigned N) {
- assert(isBacktrackEnabled() &&
- "Should only be called when tokens are cached for backtracking");
- assert(signed(CachedLexPos) - signed(N) >= signed(BacktrackPositions.back())
- && "Should revert tokens up to the last backtrack position, not more");
- assert(signed(CachedLexPos) - signed(N) >= 0 &&
- "Corrupted backtrack positions ?");
- CachedLexPos -= N;
- }
- /// Enters a token in the token stream to be lexed next.
- ///
- /// If BackTrack() is called afterwards, the token will remain at the
- /// insertion point.
- /// If \p IsReinject is true, resulting token will have Token::IsReinjected
- /// flag set. See the flag documentation for details.
- void EnterToken(const Token &Tok, bool IsReinject) {
- if (LexLevel) {
- // It's not correct in general to enter caching lex mode while in the
- // middle of a nested lexing action.
- auto TokCopy = std::make_unique<Token[]>(1);
- TokCopy[0] = Tok;
- EnterTokenStream(std::move(TokCopy), 1, true, IsReinject);
- } else {
- EnterCachingLexMode();
- assert(IsReinject && "new tokens in the middle of cached stream");
- CachedTokens.insert(CachedTokens.begin()+CachedLexPos, Tok);
- }
- }
- /// We notify the Preprocessor that if it is caching tokens (because
- /// backtrack is enabled) it should replace the most recent cached tokens
- /// with the given annotation token. This function has no effect if
- /// backtracking is not enabled.
- ///
- /// Note that the use of this function is just for optimization, so that the
- /// cached tokens doesn't get re-parsed and re-resolved after a backtrack is
- /// invoked.
- void AnnotateCachedTokens(const Token &Tok) {
- assert(Tok.isAnnotation() && "Expected annotation token");
- if (CachedLexPos != 0 && isBacktrackEnabled())
- AnnotatePreviousCachedTokens(Tok);
- }
- /// Get the location of the last cached token, suitable for setting the end
- /// location of an annotation token.
- SourceLocation getLastCachedTokenLocation() const {
- assert(CachedLexPos != 0);
- return CachedTokens[CachedLexPos-1].getLastLoc();
- }
- /// Whether \p Tok is the most recent token (`CachedLexPos - 1`) in
- /// CachedTokens.
- bool IsPreviousCachedToken(const Token &Tok) const;
- /// Replace token in `CachedLexPos - 1` in CachedTokens by the tokens
- /// in \p NewToks.
- ///
- /// Useful when a token needs to be split in smaller ones and CachedTokens
- /// most recent token must to be updated to reflect that.
- void ReplacePreviousCachedToken(ArrayRef<Token> NewToks);
- /// Replace the last token with an annotation token.
- ///
- /// Like AnnotateCachedTokens(), this routine replaces an
- /// already-parsed (and resolved) token with an annotation
- /// token. However, this routine only replaces the last token with
- /// the annotation token; it does not affect any other cached
- /// tokens. This function has no effect if backtracking is not
- /// enabled.
- void ReplaceLastTokenWithAnnotation(const Token &Tok) {
- assert(Tok.isAnnotation() && "Expected annotation token");
- if (CachedLexPos != 0 && isBacktrackEnabled())
- CachedTokens[CachedLexPos-1] = Tok;
- }
- /// Enter an annotation token into the token stream.
- void EnterAnnotationToken(SourceRange Range, tok::TokenKind Kind,
- void *AnnotationVal);
- /// Determine whether it's possible for a future call to Lex to produce an
- /// annotation token created by a previous call to EnterAnnotationToken.
- bool mightHavePendingAnnotationTokens() {
- return CurLexerKind != CLK_Lexer;
- }
- /// Update the current token to represent the provided
- /// identifier, in order to cache an action performed by typo correction.
- void TypoCorrectToken(const Token &Tok) {
- assert(Tok.getIdentifierInfo() && "Expected identifier token");
- if (CachedLexPos != 0 && isBacktrackEnabled())
- CachedTokens[CachedLexPos-1] = Tok;
- }
- /// Recompute the current lexer kind based on the CurLexer/
- /// CurTokenLexer pointers.
- void recomputeCurLexerKind();
- /// Returns true if incremental processing is enabled
- bool isIncrementalProcessingEnabled() const { return IncrementalProcessing; }
- /// Enables the incremental processing
- void enableIncrementalProcessing(bool value = true) {
- IncrementalProcessing = value;
- }
- /// Specify the point at which code-completion will be performed.
- ///
- /// \param File the file in which code completion should occur. If
- /// this file is included multiple times, code-completion will
- /// perform completion the first time it is included. If NULL, this
- /// function clears out the code-completion point.
- ///
- /// \param Line the line at which code completion should occur
- /// (1-based).
- ///
- /// \param Column the column at which code completion should occur
- /// (1-based).
- ///
- /// \returns true if an error occurred, false otherwise.
- bool SetCodeCompletionPoint(const FileEntry *File,
- unsigned Line, unsigned Column);
- /// Determine if we are performing code completion.
- bool isCodeCompletionEnabled() const { return CodeCompletionFile != nullptr; }
- /// Returns the location of the code-completion point.
- ///
- /// Returns an invalid location if code-completion is not enabled or the file
- /// containing the code-completion point has not been lexed yet.
- SourceLocation getCodeCompletionLoc() const { return CodeCompletionLoc; }
- /// Returns the start location of the file of code-completion point.
- ///
- /// Returns an invalid location if code-completion is not enabled or the file
- /// containing the code-completion point has not been lexed yet.
- SourceLocation getCodeCompletionFileLoc() const {
- return CodeCompletionFileLoc;
- }
- /// Returns true if code-completion is enabled and we have hit the
- /// code-completion point.
- bool isCodeCompletionReached() const { return CodeCompletionReached; }
- /// Note that we hit the code-completion point.
- void setCodeCompletionReached() {
- assert(isCodeCompletionEnabled() && "Code-completion not enabled!");
- CodeCompletionReached = true;
- // Silence any diagnostics that occur after we hit the code-completion.
- getDiagnostics().setSuppressAllDiagnostics(true);
- }
- /// The location of the currently-active \#pragma clang
- /// arc_cf_code_audited begin.
- ///
- /// Returns an invalid location if there is no such pragma active.
- std::pair<IdentifierInfo *, SourceLocation>
- getPragmaARCCFCodeAuditedInfo() const {
- return PragmaARCCFCodeAuditedInfo;
- }
- /// Set the location of the currently-active \#pragma clang
- /// arc_cf_code_audited begin. An invalid location ends the pragma.
- void setPragmaARCCFCodeAuditedInfo(IdentifierInfo *Ident,
- SourceLocation Loc) {
- PragmaARCCFCodeAuditedInfo = {Ident, Loc};
- }
- /// The location of the currently-active \#pragma clang
- /// assume_nonnull begin.
- ///
- /// Returns an invalid location if there is no such pragma active.
- SourceLocation getPragmaAssumeNonNullLoc() const {
- return PragmaAssumeNonNullLoc;
- }
- /// Set the location of the currently-active \#pragma clang
- /// assume_nonnull begin. An invalid location ends the pragma.
- void setPragmaAssumeNonNullLoc(SourceLocation Loc) {
- PragmaAssumeNonNullLoc = Loc;
- }
- /// Set the directory in which the main file should be considered
- /// to have been found, if it is not a real file.
- void setMainFileDir(const DirectoryEntry *Dir) {
- MainFileDir = Dir;
- }
- /// Instruct the preprocessor to skip part of the main source file.
- ///
- /// \param Bytes The number of bytes in the preamble to skip.
- ///
- /// \param StartOfLine Whether skipping these bytes puts the lexer at the
- /// start of a line.
- void setSkipMainFilePreamble(unsigned Bytes, bool StartOfLine) {
- SkipMainFilePreamble.first = Bytes;
- SkipMainFilePreamble.second = StartOfLine;
- }
- /// Forwarding function for diagnostics. This emits a diagnostic at
- /// the specified Token's location, translating the token's start
- /// position in the current buffer into a SourcePosition object for rendering.
- DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const {
- return Diags->Report(Loc, DiagID);
- }
- DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID) const {
- return Diags->Report(Tok.getLocation(), DiagID);
- }
- /// Return the 'spelling' of the token at the given
- /// location; does not go up to the spelling location or down to the
- /// expansion location.
- ///
- /// \param buffer A buffer which will be used only if the token requires
- /// "cleaning", e.g. if it contains trigraphs or escaped newlines
- /// \param invalid If non-null, will be set \c true if an error occurs.
- StringRef getSpelling(SourceLocation loc,
- SmallVectorImpl<char> &buffer,
- bool *invalid = nullptr) const {
- return Lexer::getSpelling(loc, buffer, SourceMgr, LangOpts, invalid);
- }
- /// Return the 'spelling' of the Tok token.
- ///
- /// The spelling of a token is the characters used to represent the token in
- /// the source file after trigraph expansion and escaped-newline folding. In
- /// particular, this wants to get the true, uncanonicalized, spelling of
- /// things like digraphs, UCNs, etc.
- ///
- /// \param Invalid If non-null, will be set \c true if an error occurs.
- std::string getSpelling(const Token &Tok, bool *Invalid = nullptr) const {
- return Lexer::getSpelling(Tok, SourceMgr, LangOpts, Invalid);
- }
- /// Get the spelling of a token into a preallocated buffer, instead
- /// of as an std::string.
- ///
- /// The caller is required to allocate enough space for the token, which is
- /// guaranteed to be at least Tok.getLength() bytes long. The length of the
- /// actual result is returned.
- ///
- /// Note that this method may do two possible things: it may either fill in
- /// the buffer specified with characters, or it may *change the input pointer*
- /// to point to a constant buffer with the data already in it (avoiding a
- /// copy). The caller is not allowed to modify the returned buffer pointer
- /// if an internal buffer is returned.
- unsigned getSpelling(const Token &Tok, const char *&Buffer,
- bool *Invalid = nullptr) const {
- return Lexer::getSpelling(Tok, Buffer, SourceMgr, LangOpts, Invalid);
- }
- /// Get the spelling of a token into a SmallVector.
- ///
- /// Note that the returned StringRef may not point to the
- /// supplied buffer if a copy can be avoided.
- StringRef getSpelling(const Token &Tok,
- SmallVectorImpl<char> &Buffer,
- bool *Invalid = nullptr) const;
- /// Relex the token at the specified location.
- /// \returns true if there was a failure, false on success.
- bool getRawToken(SourceLocation Loc, Token &Result,
- bool IgnoreWhiteSpace = false) {
- return Lexer::getRawToken(Loc, Result, SourceMgr, LangOpts, IgnoreWhiteSpace);
- }
- /// Given a Token \p Tok that is a numeric constant with length 1,
- /// return the character.
- char
- getSpellingOfSingleCharacterNumericConstant(const Token &Tok,
- bool *Invalid = nullptr) const {
- assert(Tok.is(tok::numeric_constant) &&
- Tok.getLength() == 1 && "Called on unsupported token");
- assert(!Tok.needsCleaning() && "Token can't need cleaning with length 1");
- // If the token is carrying a literal data pointer, just use it.
- if (const char *D = Tok.getLiteralData())
- return *D;
- // Otherwise, fall back on getCharacterData, which is slower, but always
- // works.
- return *SourceMgr.getCharacterData(Tok.getLocation(), Invalid);
- }
- /// Retrieve the name of the immediate macro expansion.
- ///
- /// This routine starts from a source location, and finds the name of the
- /// macro responsible for its immediate expansion. It looks through any
- /// intervening macro argument expansions to compute this. It returns a
- /// StringRef that refers to the SourceManager-owned buffer of the source
- /// where that macro name is spelled. Thus, the result shouldn't out-live
- /// the SourceManager.
- StringRef getImmediateMacroName(SourceLocation Loc) {
- return Lexer::getImmediateMacroName(Loc, SourceMgr, getLangOpts());
- }
- /// Plop the specified string into a scratch buffer and set the
- /// specified token's location and length to it.
- ///
- /// If specified, the source location provides a location of the expansion
- /// point of the token.
- void CreateString(StringRef Str, Token &Tok,
- SourceLocation ExpansionLocStart = SourceLocation(),
- SourceLocation ExpansionLocEnd = SourceLocation());
- /// Split the first Length characters out of the token starting at TokLoc
- /// and return a location pointing to the split token. Re-lexing from the
- /// split token will return the split token rather than the original.
- SourceLocation SplitToken(SourceLocation TokLoc, unsigned Length);
- /// Computes the source location just past the end of the
- /// token at this source location.
- ///
- /// This routine can be used to produce a source location that
- /// points just past the end of the token referenced by \p Loc, and
- /// is generally used when a diagnostic needs to point just after a
- /// token where it expected something different that it received. If
- /// the returned source location would not be meaningful (e.g., if
- /// it points into a macro), this routine returns an invalid
- /// source location.
- ///
- /// \param Offset an offset from the end of the token, where the source
- /// location should refer to. The default offset (0) produces a source
- /// location pointing just past the end of the token; an offset of 1 produces
- /// a source location pointing to the last character in the token, etc.
- SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset = 0) {
- return Lexer::getLocForEndOfToken(Loc, Offset, SourceMgr, LangOpts);
- }
- /// Returns true if the given MacroID location points at the first
- /// token of the macro expansion.
- ///
- /// \param MacroBegin If non-null and function returns true, it is set to
- /// begin location of the macro.
- bool isAtStartOfMacroExpansion(SourceLocation loc,
- SourceLocation *MacroBegin = nullptr) const {
- return Lexer::isAtStartOfMacroExpansion(loc, SourceMgr, LangOpts,
- MacroBegin);
- }
- /// Returns true if the given MacroID location points at the last
- /// token of the macro expansion.
- ///
- /// \param MacroEnd If non-null and function returns true, it is set to
- /// end location of the macro.
- bool isAtEndOfMacroExpansion(SourceLocation loc,
- SourceLocation *MacroEnd = nullptr) const {
- return Lexer::isAtEndOfMacroExpansion(loc, SourceMgr, LangOpts, MacroEnd);
- }
- /// Print the token to stderr, used for debugging.
- void DumpToken(const Token &Tok, bool DumpFlags = false) const;
- void DumpLocation(SourceLocation Loc) const;
- void DumpMacro(const MacroInfo &MI) const;
- void dumpMacroInfo(const IdentifierInfo *II);
- /// Given a location that specifies the start of a
- /// token, return a new location that specifies a character within the token.
- SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart,
- unsigned Char) const {
- return Lexer::AdvanceToTokenCharacter(TokStart, Char, SourceMgr, LangOpts);
- }
- /// Increment the counters for the number of token paste operations
- /// performed.
- ///
- /// If fast was specified, this is a 'fast paste' case we handled.
- void IncrementPasteCounter(bool isFast) {
- if (isFast)
- ++NumFastTokenPaste;
- else
- ++NumTokenPaste;
- }
- void PrintStats();
- size_t getTotalMemory() const;
- /// When the macro expander pastes together a comment (/##/) in Microsoft
- /// mode, this method handles updating the current state, returning the
- /// token on the next source line.
- void HandleMicrosoftCommentPaste(Token &Tok);
- //===--------------------------------------------------------------------===//
- // Preprocessor callback methods. These are invoked by a lexer as various
- // directives and events are found.
- /// Given a tok::raw_identifier token, look up the
- /// identifier information for the token and install it into the token,
- /// updating the token kind accordingly.
- IdentifierInfo *LookUpIdentifierInfo(Token &Identifier) const;
- private:
- llvm::DenseMap<IdentifierInfo*,unsigned> PoisonReasons;
- public:
- /// Specifies the reason for poisoning an identifier.
- ///
- /// If that identifier is accessed while poisoned, then this reason will be
- /// used instead of the default "poisoned" diagnostic.
- void SetPoisonReason(IdentifierInfo *II, unsigned DiagID);
- /// Display reason for poisoned identifier.
- void HandlePoisonedIdentifier(Token & Identifier);
- void MaybeHandlePoisonedIdentifier(Token & Identifier) {
- if(IdentifierInfo * II = Identifier.getIdentifierInfo()) {
- if(II->isPoisoned()) {
- HandlePoisonedIdentifier(Identifier);
- }
- }
- }
- private:
- /// Identifiers used for SEH handling in Borland. These are only
- /// allowed in particular circumstances
- // __except block
- IdentifierInfo *Ident__exception_code,
- *Ident___exception_code,
- *Ident_GetExceptionCode;
- // __except filter expression
- IdentifierInfo *Ident__exception_info,
- *Ident___exception_info,
- *Ident_GetExceptionInfo;
- // __finally
- IdentifierInfo *Ident__abnormal_termination,
- *Ident___abnormal_termination,
- *Ident_AbnormalTermination;
- const char *getCurLexerEndPos();
- void diagnoseMissingHeaderInUmbrellaDir(const Module &Mod);
- public:
- void PoisonSEHIdentifiers(bool Poison = true); // Borland
- /// Callback invoked when the lexer reads an identifier and has
- /// filled in the tokens IdentifierInfo member.
- ///
- /// This callback potentially macro expands it or turns it into a named
- /// token (like 'for').
- ///
- /// \returns true if we actually computed a token, false if we need to
- /// lex again.
- bool HandleIdentifier(Token &Identifier);
- /// Callback invoked when the lexer hits the end of the current file.
- ///
- /// This either returns the EOF token and returns true, or
- /// pops a level off the include stack and returns false, at which point the
- /// client should call lex again.
- bool HandleEndOfFile(Token &Result, SourceLocation Loc,
- bool isEndOfMacro = false);
- /// Callback invoked when the current TokenLexer hits the end of its
- /// token stream.
- bool HandleEndOfTokenLexer(Token &Result);
- /// Callback invoked when the lexer sees a # token at the start of a
- /// line.
- ///
- /// This consumes the directive, modifies the lexer/preprocessor state, and
- /// advances the lexer(s) so that the next token read is the correct one.
- void HandleDirective(Token &Result);
- /// Ensure that the next token is a tok::eod token.
- ///
- /// If not, emit a diagnostic and consume up until the eod.
- /// If \p EnableMacros is true, then we consider macros that expand to zero
- /// tokens as being ok.
- ///
- /// \return The location of the end of the directive (the terminating
- /// newline).
- SourceLocation CheckEndOfDirective(const char *DirType,
- bool EnableMacros = false);
- /// Read and discard all tokens remaining on the current line until
- /// the tok::eod token is found. Returns the range of the skipped tokens.
- SourceRange DiscardUntilEndOfDirective();
- /// Returns true if the preprocessor has seen a use of
- /// __DATE__ or __TIME__ in the file so far.
- bool SawDateOrTime() const {
- return DATELoc != SourceLocation() || TIMELoc != SourceLocation();
- }
- unsigned getCounterValue() const { return CounterValue; }
- void setCounterValue(unsigned V) { CounterValue = V; }
- /// Retrieves the module that we're currently building, if any.
- Module *getCurrentModule();
- /// Allocate a new MacroInfo object with the provided SourceLocation.
- MacroInfo *AllocateMacroInfo(SourceLocation L);
- /// Turn the specified lexer token into a fully checked and spelled
- /// filename, e.g. as an operand of \#include.
- ///
- /// The caller is expected to provide a buffer that is large enough to hold
- /// the spelling of the filename, but is also expected to handle the case
- /// when this method decides to use a different buffer.
- ///
- /// \returns true if the input filename was in <>'s or false if it was
- /// in ""'s.
- bool GetIncludeFilenameSpelling(SourceLocation Loc,StringRef &Buffer);
- /// Given a "foo" or \<foo> reference, look up the indicated file.
- ///
- /// Returns None on failure. \p isAngled indicates whether the file
- /// reference is for system \#include's or not (i.e. using <> instead of "").
- Optional<FileEntryRef>
- LookupFile(SourceLocation FilenameLoc, StringRef Filename, bool isAngled,
- const DirectoryLookup *FromDir, const FileEntry *FromFile,
- const DirectoryLookup **CurDir, SmallVectorImpl<char> *SearchPath,
- SmallVectorImpl<char> *RelativePath,
- ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped,
- bool *IsFrameworkFound, bool SkipCache = false);
- /// Get the DirectoryLookup structure used to find the current
- /// FileEntry, if CurLexer is non-null and if applicable.
- ///
- /// This allows us to implement \#include_next and find directory-specific
- /// properties.
- const DirectoryLookup *GetCurDirLookup() { return CurDirLookup; }
- /// Return true if we're in the top-level file, not in a \#include.
- bool isInPrimaryFile() const;
- /// Lex an on-off-switch (C99 6.10.6p2) and verify that it is
- /// followed by EOD. Return true if the token is not a valid on-off-switch.
- bool LexOnOffSwitch(tok::OnOffSwitch &Result);
- bool CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef,
- bool *ShadowFlag = nullptr);
- void EnterSubmodule(Module *M, SourceLocation ImportLoc, bool ForPragma);
- Module *LeaveSubmodule(bool ForPragma);
- private:
- friend void TokenLexer::ExpandFunctionArguments();
- void PushIncludeMacroStack() {
- assert(CurLexerKind != CLK_CachingLexer && "cannot push a caching lexer");
- IncludeMacroStack.emplace_back(CurLexerKind, CurLexerSubmodule,
- std::move(CurLexer), CurPPLexer,
- std::move(CurTokenLexer), CurDirLookup);
- CurPPLexer = nullptr;
- }
- void PopIncludeMacroStack() {
- CurLexer = std::move(IncludeMacroStack.back().TheLexer);
- CurPPLexer = IncludeMacroStack.back().ThePPLexer;
- CurTokenLexer = std::move(IncludeMacroStack.back().TheTokenLexer);
- CurDirLookup = IncludeMacroStack.back().TheDirLookup;
- CurLexerSubmodule = IncludeMacroStack.back().TheSubmodule;
- CurLexerKind = IncludeMacroStack.back().CurLexerKind;
- IncludeMacroStack.pop_back();
- }
- void PropagateLineStartLeadingSpaceInfo(Token &Result);
- /// Determine whether we need to create module macros for #defines in the
- /// current context.
- bool needModuleMacros() const;
- /// Update the set of active module macros and ambiguity flag for a module
- /// macro name.
- void updateModuleMacroInfo(const IdentifierInfo *II, ModuleMacroInfo &Info);
- DefMacroDirective *AllocateDefMacroDirective(MacroInfo *MI,
- SourceLocation Loc);
- UndefMacroDirective *AllocateUndefMacroDirective(SourceLocation UndefLoc);
- VisibilityMacroDirective *AllocateVisibilityMacroDirective(SourceLocation Loc,
- bool isPublic);
- /// Lex and validate a macro name, which occurs after a
- /// \#define or \#undef.
- ///
- /// \param MacroNameTok Token that represents the name defined or undefined.
- /// \param IsDefineUndef Kind if preprocessor directive.
- /// \param ShadowFlag Points to flag that is set if macro name shadows
- /// a keyword.
- ///
- /// This emits a diagnostic, sets the token kind to eod,
- /// and discards the rest of the macro line if the macro name is invalid.
- void ReadMacroName(Token &MacroNameTok, MacroUse IsDefineUndef = MU_Other,
- bool *ShadowFlag = nullptr);
- /// ReadOptionalMacroParameterListAndBody - This consumes all (i.e. the
- /// entire line) of the macro's tokens and adds them to MacroInfo, and while
- /// doing so performs certain validity checks including (but not limited to):
- /// - # (stringization) is followed by a macro parameter
- /// \param MacroNameTok - Token that represents the macro name
- /// \param ImmediatelyAfterHeaderGuard - Macro follows an #ifdef header guard
- ///
- /// Either returns a pointer to a MacroInfo object OR emits a diagnostic and
- /// returns a nullptr if an invalid sequence of tokens is encountered.
- MacroInfo *ReadOptionalMacroParameterListAndBody(
- const Token &MacroNameTok, bool ImmediatelyAfterHeaderGuard);
- /// The ( starting an argument list of a macro definition has just been read.
- /// Lex the rest of the parameters and the closing ), updating \p MI with
- /// what we learn and saving in \p LastTok the last token read.
- /// Return true if an error occurs parsing the arg list.
- bool ReadMacroParameterList(MacroInfo *MI, Token& LastTok);
- /// We just read a \#if or related directive and decided that the
- /// subsequent tokens are in the \#if'd out portion of the
- /// file. Lex the rest of the file, until we see an \#endif. If \p
- /// FoundNonSkipPortion is true, then we have already emitted code for part of
- /// this \#if directive, so \#else/\#elif blocks should never be entered. If
- /// \p FoundElse is false, then \#else directives are ok, if not, then we have
- /// already seen one so a \#else directive is a duplicate. When this returns,
- /// the caller can lex the first valid token.
- void SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,
- SourceLocation IfTokenLoc,
- bool FoundNonSkipPortion, bool FoundElse,
- SourceLocation ElseLoc = SourceLocation());
- /// Information about the result for evaluating an expression for a
- /// preprocessor directive.
- struct DirectiveEvalResult {
- /// Whether the expression was evaluated as true or not.
- bool Conditional;
- /// True if the expression contained identifiers that were undefined.
- bool IncludedUndefinedIds;
- /// The source range for the expression.
- SourceRange ExprRange;
- };
- /// Evaluate an integer constant expression that may occur after a
- /// \#if or \#elif directive and return a \p DirectiveEvalResult object.
- ///
- /// If the expression is equivalent to "!defined(X)" return X in IfNDefMacro.
- DirectiveEvalResult EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro);
- /// Install the standard preprocessor pragmas:
- /// \#pragma GCC poison/system_header/dependency and \#pragma once.
- void RegisterBuiltinPragmas();
- /// Register builtin macros such as __LINE__ with the identifier table.
- void RegisterBuiltinMacros();
- /// If an identifier token is read that is to be expanded as a macro, handle
- /// it and return the next token as 'Tok'. If we lexed a token, return true;
- /// otherwise the caller should lex again.
- bool HandleMacroExpandedIdentifier(Token &Identifier, const MacroDefinition &MD);
- /// Cache macro expanded tokens for TokenLexers.
- //
- /// Works like a stack; a TokenLexer adds the macro expanded tokens that is
- /// going to lex in the cache and when it finishes the tokens are removed
- /// from the end of the cache.
- Token *cacheMacroExpandedTokens(TokenLexer *tokLexer,
- ArrayRef<Token> tokens);
- void removeCachedMacroExpandedTokensOfLastLexer();
- /// Determine whether the next preprocessor token to be
- /// lexed is a '('. If so, consume the token and return true, if not, this
- /// method should have no observable side-effect on the lexed tokens.
- bool isNextPPTokenLParen();
- /// After reading "MACRO(", this method is invoked to read all of the formal
- /// arguments specified for the macro invocation. Returns null on error.
- MacroArgs *ReadMacroCallArgumentList(Token &MacroName, MacroInfo *MI,
- SourceLocation &MacroEnd);
- /// If an identifier token is read that is to be expanded
- /// as a builtin macro, handle it and return the next token as 'Tok'.
- void ExpandBuiltinMacro(Token &Tok);
- /// Read a \c _Pragma directive, slice it up, process it, then
- /// return the first token after the directive.
- /// This assumes that the \c _Pragma token has just been read into \p Tok.
- void Handle_Pragma(Token &Tok);
- /// Like Handle_Pragma except the pragma text is not enclosed within
- /// a string literal.
- void HandleMicrosoft__pragma(Token &Tok);
- /// Add a lexer to the top of the include stack and
- /// start lexing tokens from it instead of the current buffer.
- void EnterSourceFileWithLexer(Lexer *TheLexer, const DirectoryLookup *Dir);
- /// Set the FileID for the preprocessor predefines.
- void setPredefinesFileID(FileID FID) {
- assert(PredefinesFileID.isInvalid() && "PredefinesFileID already set!");
- PredefinesFileID = FID;
- }
- /// Set the FileID for the PCH through header.
- void setPCHThroughHeaderFileID(FileID FID);
- /// Returns true if we are lexing from a file and not a
- /// pragma or a macro.
- static bool IsFileLexer(const Lexer* L, const PreprocessorLexer* P) {
- return L ? !L->isPragmaLexer() : P != nullptr;
- }
- static bool IsFileLexer(const IncludeStackInfo& I) {
- return IsFileLexer(I.TheLexer.get(), I.ThePPLexer);
- }
- bool IsFileLexer() const {
- return IsFileLexer(CurLexer.get(), CurPPLexer);
- }
- //===--------------------------------------------------------------------===//
- // Caching stuff.
- void CachingLex(Token &Result);
- bool InCachingLexMode() const {
- // If the Lexer pointers are 0 and IncludeMacroStack is empty, it means
- // that we are past EOF, not that we are in CachingLex mode.
- return !CurPPLexer && !CurTokenLexer && !IncludeMacroStack.empty();
- }
- void EnterCachingLexMode();
- void EnterCachingLexModeUnchecked();
- void ExitCachingLexMode() {
- if (InCachingLexMode())
- RemoveTopOfLexerStack();
- }
- const Token &PeekAhead(unsigned N);
- void AnnotatePreviousCachedTokens(const Token &Tok);
- //===--------------------------------------------------------------------===//
- /// Handle*Directive - implement the various preprocessor directives. These
- /// should side-effect the current preprocessor object so that the next call
- /// to Lex() will return the appropriate token next.
- void HandleLineDirective();
- void HandleDigitDirective(Token &Tok);
- void HandleUserDiagnosticDirective(Token &Tok, bool isWarning);
- void HandleIdentSCCSDirective(Token &Tok);
- void HandleMacroPublicDirective(Token &Tok);
- void HandleMacroPrivateDirective();
- /// An additional notification that can be produced by a header inclusion or
- /// import to tell the parser what happened.
- struct ImportAction {
- enum ActionKind {
- None,
- ModuleBegin,
- ModuleImport,
- SkippedModuleImport,
- Failure,
- } Kind;
- Module *ModuleForHeader = nullptr;
- ImportAction(ActionKind AK, Module *Mod = nullptr)
- : Kind(AK), ModuleForHeader(Mod) {
- assert((AK == None || Mod || AK == Failure) &&
- "no module for module action");
- }
- };
- Optional<FileEntryRef> LookupHeaderIncludeOrImport(
- const DirectoryLookup **CurDir, StringRef &Filename,
- SourceLocation FilenameLoc, CharSourceRange FilenameRange,
- const Token &FilenameTok, bool &IsFrameworkFound, bool IsImportDecl,
- bool &IsMapped, const DirectoryLookup *LookupFrom,
- const FileEntry *LookupFromFile, StringRef &LookupFilename,
- SmallVectorImpl<char> &RelativePath, SmallVectorImpl<char> &SearchPath,
- ModuleMap::KnownHeader &SuggestedModule, bool isAngled);
- // File inclusion.
- void HandleIncludeDirective(SourceLocation HashLoc, Token &Tok,
- const DirectoryLookup *LookupFrom = nullptr,
- const FileEntry *LookupFromFile = nullptr);
- ImportAction
- HandleHeaderIncludeOrImport(SourceLocation HashLoc, Token &IncludeTok,
- Token &FilenameTok, SourceLocation EndLoc,
- const DirectoryLookup *LookupFrom = nullptr,
- const FileEntry *LookupFromFile = nullptr);
- void HandleIncludeNextDirective(SourceLocation HashLoc, Token &Tok);
- void HandleIncludeMacrosDirective(SourceLocation HashLoc, Token &Tok);
- void HandleImportDirective(SourceLocation HashLoc, Token &Tok);
- void HandleMicrosoftImportDirective(Token &Tok);
- public:
- /// Check that the given module is available, producing a diagnostic if not.
- /// \return \c true if the check failed (because the module is not available).
- /// \c false if the module appears to be usable.
- static bool checkModuleIsAvailable(const LangOptions &LangOpts,
- const TargetInfo &TargetInfo,
- DiagnosticsEngine &Diags, Module *M);
- // Module inclusion testing.
- /// Find the module that owns the source or header file that
- /// \p Loc points to. If the location is in a file that was included
- /// into a module, or is outside any module, returns nullptr.
- Module *getModuleForLocation(SourceLocation Loc);
- /// We want to produce a diagnostic at location IncLoc concerning an
- /// unreachable effect at location MLoc (eg, where a desired entity was
- /// declared or defined). Determine whether the right way to make MLoc
- /// reachable is by #include, and if so, what header should be included.
- ///
- /// This is not necessarily fast, and might load unexpected module maps, so
- /// should only be called by code that intends to produce an error.
- ///
- /// \param IncLoc The location at which the missing effect was detected.
- /// \param MLoc A location within an unimported module at which the desired
- /// effect occurred.
- /// \return A file that can be #included to provide the desired effect. Null
- /// if no such file could be determined or if a #include is not
- /// appropriate (eg, if a module should be imported instead).
- const FileEntry *getHeaderToIncludeForDiagnostics(SourceLocation IncLoc,
- SourceLocation MLoc);
- bool isRecordingPreamble() const {
- return PreambleConditionalStack.isRecording();
- }
- bool hasRecordedPreamble() const {
- return PreambleConditionalStack.hasRecordedPreamble();
- }
- ArrayRef<PPConditionalInfo> getPreambleConditionalStack() const {
- return PreambleConditionalStack.getStack();
- }
- void setRecordedPreambleConditionalStack(ArrayRef<PPConditionalInfo> s) {
- PreambleConditionalStack.setStack(s);
- }
- void setReplayablePreambleConditionalStack(ArrayRef<PPConditionalInfo> s,
- llvm::Optional<PreambleSkipInfo> SkipInfo) {
- PreambleConditionalStack.startReplaying();
- PreambleConditionalStack.setStack(s);
- PreambleConditionalStack.SkipInfo = SkipInfo;
- }
- llvm::Optional<PreambleSkipInfo> getPreambleSkipInfo() const {
- return PreambleConditionalStack.SkipInfo;
- }
- private:
- /// After processing predefined file, initialize the conditional stack from
- /// the preamble.
- void replayPreambleConditionalStack();
- // Macro handling.
- void HandleDefineDirective(Token &Tok, bool ImmediatelyAfterHeaderGuard);
- void HandleUndefDirective();
- // Conditional Inclusion.
- void HandleIfdefDirective(Token &Result, const Token &HashToken,
- bool isIfndef, bool ReadAnyTokensBeforeDirective);
- void HandleIfDirective(Token &IfToken, const Token &HashToken,
- bool ReadAnyTokensBeforeDirective);
- void HandleEndifDirective(Token &EndifToken);
- void HandleElseDirective(Token &Result, const Token &HashToken);
- void HandleElifFamilyDirective(Token &ElifToken, const Token &HashToken,
- tok::PPKeywordKind Kind);
- // Pragmas.
- void HandlePragmaDirective(PragmaIntroducer Introducer);
- void ResolvePragmaIncludeInstead(SourceLocation Location) const;
- public:
- void HandlePragmaOnce(Token &OnceTok);
- void HandlePragmaMark(Token &MarkTok);
- void HandlePragmaPoison();
- void HandlePragmaSystemHeader(Token &SysHeaderTok);
- void HandlePragmaIncludeInstead(Token &Tok);
- void HandlePragmaDependency(Token &DependencyTok);
- void HandlePragmaPushMacro(Token &Tok);
- void HandlePragmaPopMacro(Token &Tok);
- void HandlePragmaIncludeAlias(Token &Tok);
- void HandlePragmaModuleBuild(Token &Tok);
- void HandlePragmaHdrstop(Token &Tok);
- IdentifierInfo *ParsePragmaPushOrPopMacro(Token &Tok);
- // Return true and store the first token only if any CommentHandler
- // has inserted some tokens and getCommentRetentionState() is false.
- bool HandleComment(Token &result, SourceRange Comment);
- /// A macro is used, update information about macros that need unused
- /// warnings.
- void markMacroAsUsed(MacroInfo *MI);
- void addMacroDeprecationMsg(const IdentifierInfo *II, std::string Msg,
- SourceLocation AnnotationLoc) {
- auto Annotations = AnnotationInfos.find(II);
- if (Annotations == AnnotationInfos.end())
- AnnotationInfos.insert(std::make_pair(
- II,
- MacroAnnotations::makeDeprecation(AnnotationLoc, std::move(Msg))));
- else
- Annotations->second.DeprecationInfo =
- MacroAnnotationInfo{AnnotationLoc, std::move(Msg)};
- }
- void addRestrictExpansionMsg(const IdentifierInfo *II, std::string Msg,
- SourceLocation AnnotationLoc) {
- auto Annotations = AnnotationInfos.find(II);
- if (Annotations == AnnotationInfos.end())
- AnnotationInfos.insert(
- std::make_pair(II, MacroAnnotations::makeRestrictExpansion(
- AnnotationLoc, std::move(Msg))));
- else
- Annotations->second.RestrictExpansionInfo =
- MacroAnnotationInfo{AnnotationLoc, std::move(Msg)};
- }
- void addFinalLoc(const IdentifierInfo *II, SourceLocation AnnotationLoc) {
- auto Annotations = AnnotationInfos.find(II);
- if (Annotations == AnnotationInfos.end())
- AnnotationInfos.insert(
- std::make_pair(II, MacroAnnotations::makeFinal(AnnotationLoc)));
- else
- Annotations->second.FinalAnnotationLoc = AnnotationLoc;
- }
- const MacroAnnotations &getMacroAnnotations(const IdentifierInfo *II) const {
- return AnnotationInfos.find(II)->second;
- }
- void emitMacroExpansionWarnings(const Token &Identifier) const {
- if (Identifier.getIdentifierInfo()->isDeprecatedMacro())
- emitMacroDeprecationWarning(Identifier);
- if (Identifier.getIdentifierInfo()->isRestrictExpansion() &&
- !SourceMgr.isInMainFile(Identifier.getLocation()))
- emitRestrictExpansionWarning(Identifier);
- }
- private:
- void emitMacroDeprecationWarning(const Token &Identifier) const;
- void emitRestrictExpansionWarning(const Token &Identifier) const;
- void emitFinalMacroWarning(const Token &Identifier, bool IsUndef) const;
- Optional<unsigned>
- getSkippedRangeForExcludedConditionalBlock(SourceLocation HashLoc);
- /// Contains the currently active skipped range mappings for skipping excluded
- /// conditional directives.
- ExcludedPreprocessorDirectiveSkipMapping
- *ExcludedConditionalDirectiveSkipMappings;
- };
- /// Abstract base class that describes a handler that will receive
- /// source ranges for each of the comments encountered in the source file.
- class CommentHandler {
- public:
- virtual ~CommentHandler();
- // The handler shall return true if it has pushed any tokens
- // to be read using e.g. EnterToken or EnterTokenStream.
- virtual bool HandleComment(Preprocessor &PP, SourceRange Comment) = 0;
- };
- /// Abstract base class that describes a handler that will receive
- /// source ranges for empty lines encountered in the source file.
- class EmptylineHandler {
- public:
- virtual ~EmptylineHandler();
- // The handler handles empty lines.
- virtual void HandleEmptyline(SourceRange Range) = 0;
- };
- /// Registry of pragma handlers added by plugins
- using PragmaHandlerRegistry = llvm::Registry<PragmaHandler>;
- } // namespace clang
- #endif // LLVM_CLANG_LEX_PREPROCESSOR_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|