File indexing completed on 2026-05-10 08:36:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_LEX_PREPROCESSOR_H
0015 #define LLVM_CLANG_LEX_PREPROCESSOR_H
0016
0017 #include "clang/Basic/Diagnostic.h"
0018 #include "clang/Basic/DiagnosticIDs.h"
0019 #include "clang/Basic/IdentifierTable.h"
0020 #include "clang/Basic/LLVM.h"
0021 #include "clang/Basic/LangOptions.h"
0022 #include "clang/Basic/Module.h"
0023 #include "clang/Basic/SourceLocation.h"
0024 #include "clang/Basic/SourceManager.h"
0025 #include "clang/Basic/TokenKinds.h"
0026 #include "clang/Lex/HeaderSearch.h"
0027 #include "clang/Lex/Lexer.h"
0028 #include "clang/Lex/MacroInfo.h"
0029 #include "clang/Lex/ModuleLoader.h"
0030 #include "clang/Lex/ModuleMap.h"
0031 #include "clang/Lex/PPCallbacks.h"
0032 #include "clang/Lex/PPEmbedParameters.h"
0033 #include "clang/Lex/Token.h"
0034 #include "clang/Lex/TokenLexer.h"
0035 #include "clang/Support/Compiler.h"
0036 #include "llvm/ADT/APSInt.h"
0037 #include "llvm/ADT/ArrayRef.h"
0038 #include "llvm/ADT/DenseMap.h"
0039 #include "llvm/ADT/FoldingSet.h"
0040 #include "llvm/ADT/FunctionExtras.h"
0041 #include "llvm/ADT/PointerUnion.h"
0042 #include "llvm/ADT/STLExtras.h"
0043 #include "llvm/ADT/SmallPtrSet.h"
0044 #include "llvm/ADT/SmallVector.h"
0045 #include "llvm/ADT/StringRef.h"
0046 #include "llvm/ADT/TinyPtrVector.h"
0047 #include "llvm/ADT/iterator_range.h"
0048 #include "llvm/Support/Allocator.h"
0049 #include "llvm/Support/Casting.h"
0050 #include "llvm/Support/Registry.h"
0051 #include <cassert>
0052 #include <cstddef>
0053 #include <cstdint>
0054 #include <map>
0055 #include <memory>
0056 #include <optional>
0057 #include <string>
0058 #include <utility>
0059 #include <vector>
0060
0061 namespace llvm {
0062
0063 template<unsigned InternalLen> class SmallString;
0064
0065 }
0066
0067 namespace clang {
0068
0069 class CodeCompletionHandler;
0070 class CommentHandler;
0071 class DirectoryEntry;
0072 class EmptylineHandler;
0073 class ExternalPreprocessorSource;
0074 class FileEntry;
0075 class FileManager;
0076 class HeaderSearch;
0077 class MacroArgs;
0078 class PragmaHandler;
0079 class PragmaNamespace;
0080 class PreprocessingRecord;
0081 class PreprocessorLexer;
0082 class PreprocessorOptions;
0083 class ScratchBuffer;
0084 class TargetInfo;
0085
0086 namespace Builtin {
0087 class Context;
0088 }
0089
0090
0091
0092 class TokenValue {
0093 tok::TokenKind Kind;
0094 IdentifierInfo *II;
0095
0096 public:
0097 TokenValue(tok::TokenKind Kind) : Kind(Kind), II(nullptr) {
0098 assert(Kind != tok::raw_identifier && "Raw identifiers are not supported.");
0099 assert(Kind != tok::identifier &&
0100 "Identifiers should be created by TokenValue(IdentifierInfo *)");
0101 assert(!tok::isLiteral(Kind) && "Literals are not supported.");
0102 assert(!tok::isAnnotation(Kind) && "Annotations are not supported.");
0103 }
0104
0105 TokenValue(IdentifierInfo *II) : Kind(tok::identifier), II(II) {}
0106
0107 bool operator==(const Token &Tok) const {
0108 return Tok.getKind() == Kind &&
0109 (!II || II == Tok.getIdentifierInfo());
0110 }
0111 };
0112
0113
0114 enum MacroUse {
0115
0116 MU_Other = 0,
0117
0118
0119 MU_Define = 1,
0120
0121
0122 MU_Undef = 2
0123 };
0124
0125 enum class EmbedResult {
0126 Invalid = -1,
0127 NotFound = 0,
0128 Found = 1,
0129 Empty = 2,
0130 };
0131
0132
0133
0134
0135
0136
0137
0138 class Preprocessor {
0139 friend class VAOptDefinitionContext;
0140 friend class VariadicMacroScopeGuard;
0141
0142 llvm::unique_function<void(const clang::Token &)> OnToken;
0143 std::shared_ptr<PreprocessorOptions> PPOpts;
0144 DiagnosticsEngine *Diags;
0145 const LangOptions &LangOpts;
0146 const TargetInfo *Target = nullptr;
0147 const TargetInfo *AuxTarget = nullptr;
0148 FileManager &FileMgr;
0149 SourceManager &SourceMgr;
0150 std::unique_ptr<ScratchBuffer> ScratchBuf;
0151 HeaderSearch &HeaderInfo;
0152 ModuleLoader &TheModuleLoader;
0153
0154
0155 ExternalPreprocessorSource *ExternalSource;
0156
0157
0158
0159 llvm::BumpPtrAllocator BP;
0160
0161
0162 IdentifierInfo *Ident__LINE__, *Ident__FILE__;
0163 IdentifierInfo *Ident__DATE__, *Ident__TIME__;
0164 IdentifierInfo *Ident__INCLUDE_LEVEL__;
0165 IdentifierInfo *Ident__BASE_FILE__;
0166 IdentifierInfo *Ident__FILE_NAME__;
0167 IdentifierInfo *Ident__TIMESTAMP__;
0168 IdentifierInfo *Ident__COUNTER__;
0169 IdentifierInfo *Ident_Pragma, *Ident__pragma;
0170 IdentifierInfo *Ident__identifier;
0171 IdentifierInfo *Ident__VA_ARGS__;
0172 IdentifierInfo *Ident__VA_OPT__;
0173 IdentifierInfo *Ident__has_feature;
0174 IdentifierInfo *Ident__has_extension;
0175 IdentifierInfo *Ident__has_builtin;
0176 IdentifierInfo *Ident__has_constexpr_builtin;
0177 IdentifierInfo *Ident__has_attribute;
0178 IdentifierInfo *Ident__has_embed;
0179 IdentifierInfo *Ident__has_include;
0180 IdentifierInfo *Ident__has_include_next;
0181 IdentifierInfo *Ident__has_warning;
0182 IdentifierInfo *Ident__is_identifier;
0183 IdentifierInfo *Ident__building_module;
0184 IdentifierInfo *Ident__MODULE__;
0185 IdentifierInfo *Ident__has_cpp_attribute;
0186 IdentifierInfo *Ident__has_c_attribute;
0187 IdentifierInfo *Ident__has_declspec;
0188 IdentifierInfo *Ident__is_target_arch;
0189 IdentifierInfo *Ident__is_target_vendor;
0190 IdentifierInfo *Ident__is_target_os;
0191 IdentifierInfo *Ident__is_target_environment;
0192 IdentifierInfo *Ident__is_target_variant_os;
0193 IdentifierInfo *Ident__is_target_variant_environment;
0194 IdentifierInfo *Ident__FLT_EVAL_METHOD__;
0195
0196
0197 Token* ArgMacro;
0198
0199 SourceLocation DATELoc, TIMELoc;
0200
0201
0202
0203
0204 LangOptions::FPEvalMethodKind CurrentFPEvalMethod =
0205 LangOptions::FPEvalMethodKind::FEM_UnsetOnCommandLine;
0206
0207
0208
0209
0210 SourceLocation LastFPEvalPragmaLocation;
0211
0212 LangOptions::FPEvalMethodKind TUFPEvalMethod =
0213 LangOptions::FPEvalMethodKind::FEM_UnsetOnCommandLine;
0214
0215
0216 unsigned CounterValue = 0;
0217
0218 enum {
0219
0220 MaxAllowedIncludeStackDepth = 200
0221 };
0222
0223
0224 bool KeepComments : 1;
0225 bool KeepMacroComments : 1;
0226 bool SuppressIncludeNotFoundError : 1;
0227
0228
0229 bool InMacroArgs : 1;
0230
0231
0232 bool OwnsHeaderSearch : 1;
0233
0234
0235 bool DisableMacroExpansion : 1;
0236
0237
0238
0239 bool MacroExpansionInDirectivesOverride : 1;
0240
0241 class ResetMacroExpansionHelper;
0242
0243
0244 mutable bool ReadMacrosFromExternalSource : 1;
0245
0246
0247 bool PragmasEnabled : 1;
0248
0249
0250 bool PreprocessedOutput : 1;
0251
0252
0253 bool ParsingIfOrElifDirective;
0254
0255
0256 bool InMacroArgPreExpansion;
0257
0258
0259
0260 mutable IdentifierTable Identifiers;
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271 SelectorTable Selectors;
0272
0273
0274 std::unique_ptr<Builtin::Context> BuiltinInfo;
0275
0276
0277
0278 std::unique_ptr<PragmaNamespace> PragmaHandlers;
0279
0280
0281
0282 std::unique_ptr<PragmaNamespace> PragmaHandlersBackup;
0283
0284
0285
0286 std::vector<CommentHandler *> CommentHandlers;
0287
0288
0289 EmptylineHandler *Emptyline = nullptr;
0290
0291
0292 bool IncrementalProcessing = false;
0293
0294 public:
0295
0296 const TranslationUnitKind TUKind;
0297
0298
0299
0300
0301
0302
0303 const char *getCheckPoint(FileID FID, const char *Start) const;
0304
0305 private:
0306
0307 CodeCompletionHandler *CodeComplete = nullptr;
0308
0309
0310 const FileEntry *CodeCompletionFile = nullptr;
0311
0312
0313 unsigned CodeCompletionOffset = 0;
0314
0315
0316
0317 SourceLocation CodeCompletionLoc;
0318
0319
0320
0321
0322
0323 SourceLocation CodeCompletionFileLoc;
0324
0325
0326
0327 SourceLocation ModuleImportLoc;
0328
0329
0330 SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> NamedModuleImportPath;
0331
0332 llvm::DenseMap<FileID, SmallVector<const char *>> CheckPoints;
0333 unsigned CheckPointCounter = 0;
0334
0335
0336 bool IsAtImport = false;
0337
0338
0339 bool LastTokenWasAt = false;
0340
0341
0342 class StdCXXImportSeq {
0343 public:
0344 enum State : int {
0345
0346 AtTopLevel = 0,
0347 AfterTopLevelTokenSeq = -1,
0348 AfterExport = -2,
0349 AfterImportSeq = -3,
0350 };
0351
0352 StdCXXImportSeq(State S) : S(S) {}
0353
0354
0355 void handleOpenBracket() {
0356 S = static_cast<State>(std::max<int>(S, 0) + 1);
0357 }
0358
0359 void handleCloseBracket() {
0360 S = static_cast<State>(std::max<int>(S, 1) - 1);
0361 }
0362
0363 void handleCloseBrace() {
0364 handleCloseBracket();
0365 if (S == AtTopLevel && !AfterHeaderName)
0366 S = AfterTopLevelTokenSeq;
0367 }
0368
0369 void handleSemi() {
0370 if (atTopLevel()) {
0371 S = AfterTopLevelTokenSeq;
0372 AfterHeaderName = false;
0373 }
0374 }
0375
0376
0377 void handleExport() {
0378 if (S == AfterTopLevelTokenSeq)
0379 S = AfterExport;
0380 else if (S <= 0)
0381 S = AtTopLevel;
0382 }
0383
0384 void handleImport() {
0385 if (S == AfterTopLevelTokenSeq || S == AfterExport)
0386 S = AfterImportSeq;
0387 else if (S <= 0)
0388 S = AtTopLevel;
0389 }
0390
0391
0392
0393 void handleHeaderName() {
0394 if (S == AfterImportSeq)
0395 AfterHeaderName = true;
0396 handleMisc();
0397 }
0398
0399
0400 void handleMisc() {
0401 if (S <= 0)
0402 S = AtTopLevel;
0403 }
0404
0405 bool atTopLevel() { return S <= 0; }
0406 bool afterImportSeq() { return S == AfterImportSeq; }
0407 bool afterTopLevelSeq() { return S == AfterTopLevelTokenSeq; }
0408
0409 private:
0410 State S;
0411
0412
0413
0414 bool AfterHeaderName = false;
0415 };
0416
0417
0418 StdCXXImportSeq StdCXXImportSeqState = StdCXXImportSeq::AfterTopLevelTokenSeq;
0419
0420
0421 class TrackGMF {
0422 public:
0423 enum GMFState : int {
0424 GMFActive = 1,
0425 MaybeGMF = 0,
0426 BeforeGMFIntroducer = -1,
0427 GMFAbsentOrEnded = -2,
0428 };
0429
0430 TrackGMF(GMFState S) : S(S) {}
0431
0432
0433 void handleSemi() {
0434
0435
0436 if (S == MaybeGMF)
0437 S = GMFActive;
0438 }
0439
0440
0441 void handleExport() {
0442
0443 S = GMFAbsentOrEnded;
0444 }
0445
0446
0447 void handleImport(bool AfterTopLevelTokenSeq) {
0448
0449 if (AfterTopLevelTokenSeq && S == BeforeGMFIntroducer)
0450 S = GMFAbsentOrEnded;
0451 }
0452
0453
0454 void handleModule(bool AfterTopLevelTokenSeq) {
0455
0456
0457
0458 if (AfterTopLevelTokenSeq && S == BeforeGMFIntroducer)
0459 S = MaybeGMF;
0460 else
0461 S = GMFAbsentOrEnded;
0462 }
0463
0464
0465 void handleMisc() {
0466
0467 if (S == MaybeGMF)
0468 S = GMFAbsentOrEnded;
0469 }
0470
0471 bool inGMF() { return S == GMFActive; }
0472
0473 private:
0474
0475
0476 GMFState S;
0477 };
0478
0479 TrackGMF TrackGMFState = TrackGMF::BeforeGMFIntroducer;
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515 class ModuleDeclSeq {
0516 enum ModuleDeclState : int {
0517 NotAModuleDecl,
0518 FoundExport,
0519 InterfaceCandidate,
0520 ImplementationCandidate,
0521 NamedModuleInterface,
0522 NamedModuleImplementation,
0523 };
0524
0525 public:
0526 ModuleDeclSeq() = default;
0527
0528 void handleExport() {
0529 if (State == NotAModuleDecl)
0530 State = FoundExport;
0531 else if (!isNamedModule())
0532 reset();
0533 }
0534
0535 void handleModule() {
0536 if (State == FoundExport)
0537 State = InterfaceCandidate;
0538 else if (State == NotAModuleDecl)
0539 State = ImplementationCandidate;
0540 else if (!isNamedModule())
0541 reset();
0542 }
0543
0544 void handleIdentifier(IdentifierInfo *Identifier) {
0545 if (isModuleCandidate() && Identifier)
0546 Name += Identifier->getName().str();
0547 else if (!isNamedModule())
0548 reset();
0549 }
0550
0551 void handleColon() {
0552 if (isModuleCandidate())
0553 Name += ":";
0554 else if (!isNamedModule())
0555 reset();
0556 }
0557
0558 void handlePeriod() {
0559 if (isModuleCandidate())
0560 Name += ".";
0561 else if (!isNamedModule())
0562 reset();
0563 }
0564
0565 void handleSemi() {
0566 if (!Name.empty() && isModuleCandidate()) {
0567 if (State == InterfaceCandidate)
0568 State = NamedModuleInterface;
0569 else if (State == ImplementationCandidate)
0570 State = NamedModuleImplementation;
0571 else
0572 llvm_unreachable("Unimaged ModuleDeclState.");
0573 } else if (!isNamedModule())
0574 reset();
0575 }
0576
0577 void handleMisc() {
0578 if (!isNamedModule())
0579 reset();
0580 }
0581
0582 bool isModuleCandidate() const {
0583 return State == InterfaceCandidate || State == ImplementationCandidate;
0584 }
0585
0586 bool isNamedModule() const {
0587 return State == NamedModuleInterface ||
0588 State == NamedModuleImplementation;
0589 }
0590
0591 bool isNamedInterface() const { return State == NamedModuleInterface; }
0592
0593 bool isImplementationUnit() const {
0594 return State == NamedModuleImplementation && !getName().contains(':');
0595 }
0596
0597 StringRef getName() const {
0598 assert(isNamedModule() && "Can't get name from a non named module");
0599 return Name;
0600 }
0601
0602 StringRef getPrimaryName() const {
0603 assert(isNamedModule() && "Can't get name from a non named module");
0604 return getName().split(':').first;
0605 }
0606
0607 void reset() {
0608 Name.clear();
0609 State = NotAModuleDecl;
0610 }
0611
0612 private:
0613 ModuleDeclState State = NotAModuleDecl;
0614 std::string Name;
0615 };
0616
0617 ModuleDeclSeq ModuleDeclState;
0618
0619
0620
0621 bool ModuleImportExpectsIdentifier = false;
0622
0623
0624
0625 std::pair<IdentifierInfo *, SourceLocation> PragmaARCCFCodeAuditedInfo;
0626
0627
0628
0629 SourceLocation PragmaAssumeNonNullLoc;
0630
0631
0632
0633
0634
0635
0636
0637 SourceLocation PreambleRecordedPragmaAssumeNonNullLoc;
0638
0639
0640 bool CodeCompletionReached = false;
0641
0642
0643
0644 IdentifierInfo *CodeCompletionII = nullptr;
0645
0646
0647 SourceRange CodeCompletionTokenRange;
0648
0649
0650
0651
0652 OptionalDirectoryEntryRef MainFileDir;
0653
0654
0655
0656
0657
0658
0659 std::pair<int, bool> SkipMainFilePreamble;
0660
0661
0662
0663 bool HasReachedMaxIncludeDepth = false;
0664
0665
0666
0667
0668
0669
0670
0671 unsigned LexLevel = 0;
0672
0673
0674 unsigned TokenCount = 0;
0675
0676
0677 bool PreprocessToken = false;
0678
0679
0680
0681 unsigned MaxTokens = 0;
0682 SourceLocation MaxTokensOverrideLoc;
0683
0684 public:
0685 struct PreambleSkipInfo {
0686 SourceLocation HashTokenLoc;
0687 SourceLocation IfTokenLoc;
0688 bool FoundNonSkipPortion;
0689 bool FoundElse;
0690 SourceLocation ElseLoc;
0691
0692 PreambleSkipInfo(SourceLocation HashTokenLoc, SourceLocation IfTokenLoc,
0693 bool FoundNonSkipPortion, bool FoundElse,
0694 SourceLocation ElseLoc)
0695 : HashTokenLoc(HashTokenLoc), IfTokenLoc(IfTokenLoc),
0696 FoundNonSkipPortion(FoundNonSkipPortion), FoundElse(FoundElse),
0697 ElseLoc(ElseLoc) {}
0698 };
0699
0700 using IncludedFilesSet = llvm::DenseSet<const FileEntry *>;
0701
0702 private:
0703 friend class ASTReader;
0704 friend class MacroArgs;
0705
0706 class PreambleConditionalStackStore {
0707 enum State {
0708 Off = 0,
0709 Recording = 1,
0710 Replaying = 2,
0711 };
0712
0713 public:
0714 PreambleConditionalStackStore() = default;
0715
0716 void startRecording() { ConditionalStackState = Recording; }
0717 void startReplaying() { ConditionalStackState = Replaying; }
0718 bool isRecording() const { return ConditionalStackState == Recording; }
0719 bool isReplaying() const { return ConditionalStackState == Replaying; }
0720
0721 ArrayRef<PPConditionalInfo> getStack() const {
0722 return ConditionalStack;
0723 }
0724
0725 void doneReplaying() {
0726 ConditionalStack.clear();
0727 ConditionalStackState = Off;
0728 }
0729
0730 void setStack(ArrayRef<PPConditionalInfo> s) {
0731 if (!isRecording() && !isReplaying())
0732 return;
0733 ConditionalStack.clear();
0734 ConditionalStack.append(s.begin(), s.end());
0735 }
0736
0737 bool hasRecordedPreamble() const { return !ConditionalStack.empty(); }
0738
0739 bool reachedEOFWhileSkipping() const { return SkipInfo.has_value(); }
0740
0741 void clearSkipInfo() { SkipInfo.reset(); }
0742
0743 std::optional<PreambleSkipInfo> SkipInfo;
0744
0745 private:
0746 SmallVector<PPConditionalInfo, 4> ConditionalStack;
0747 State ConditionalStackState = Off;
0748 } PreambleConditionalStack;
0749
0750
0751
0752
0753
0754 std::unique_ptr<Lexer> CurLexer;
0755
0756
0757
0758
0759
0760 PreprocessorLexer *CurPPLexer = nullptr;
0761
0762
0763
0764
0765
0766
0767 ConstSearchDirIterator CurDirLookup = nullptr;
0768
0769
0770
0771
0772 std::unique_ptr<TokenLexer> CurTokenLexer;
0773
0774
0775 typedef bool (*LexerCallback)(Preprocessor &, Token &);
0776 LexerCallback CurLexerCallback = &CLK_Lexer;
0777
0778
0779
0780 Module *CurLexerSubmodule = nullptr;
0781
0782
0783
0784
0785 struct IncludeStackInfo {
0786 LexerCallback CurLexerCallback;
0787 Module *TheSubmodule;
0788 std::unique_ptr<Lexer> TheLexer;
0789 PreprocessorLexer *ThePPLexer;
0790 std::unique_ptr<TokenLexer> TheTokenLexer;
0791 ConstSearchDirIterator TheDirLookup;
0792
0793
0794
0795 IncludeStackInfo(LexerCallback CurLexerCallback, Module *TheSubmodule,
0796 std::unique_ptr<Lexer> &&TheLexer,
0797 PreprocessorLexer *ThePPLexer,
0798 std::unique_ptr<TokenLexer> &&TheTokenLexer,
0799 ConstSearchDirIterator TheDirLookup)
0800 : CurLexerCallback(std::move(CurLexerCallback)),
0801 TheSubmodule(std::move(TheSubmodule)), TheLexer(std::move(TheLexer)),
0802 ThePPLexer(std::move(ThePPLexer)),
0803 TheTokenLexer(std::move(TheTokenLexer)),
0804 TheDirLookup(std::move(TheDirLookup)) {}
0805 };
0806 std::vector<IncludeStackInfo> IncludeMacroStack;
0807
0808
0809
0810 std::unique_ptr<PPCallbacks> Callbacks;
0811
0812 struct MacroExpandsInfo {
0813 Token Tok;
0814 MacroDefinition MD;
0815 SourceRange Range;
0816
0817 MacroExpandsInfo(Token Tok, MacroDefinition MD, SourceRange Range)
0818 : Tok(Tok), MD(MD), Range(Range) {}
0819 };
0820 SmallVector<MacroExpandsInfo, 2> DelayedMacroExpandsCallbacks;
0821
0822
0823 struct ModuleMacroInfo {
0824
0825 MacroDirective *MD;
0826
0827
0828 llvm::TinyPtrVector<ModuleMacro *> ActiveModuleMacros;
0829
0830
0831
0832 unsigned ActiveModuleMacrosGeneration = 0;
0833
0834
0835 bool IsAmbiguous = false;
0836
0837
0838 llvm::TinyPtrVector<ModuleMacro *> OverriddenMacros;
0839
0840 ModuleMacroInfo(MacroDirective *MD) : MD(MD) {}
0841 };
0842
0843
0844 class MacroState {
0845 mutable llvm::PointerUnion<MacroDirective *, ModuleMacroInfo *> State;
0846
0847 ModuleMacroInfo *getModuleInfo(Preprocessor &PP,
0848 const IdentifierInfo *II) const {
0849 if (II->isOutOfDate())
0850 PP.updateOutOfDateIdentifier(*II);
0851
0852
0853 if (!II->hasMacroDefinition() ||
0854 (!PP.getLangOpts().Modules &&
0855 !PP.getLangOpts().ModulesLocalVisibility) ||
0856 !PP.CurSubmoduleState->VisibleModules.getGeneration())
0857 return nullptr;
0858
0859 auto *Info = dyn_cast_if_present<ModuleMacroInfo *>(State);
0860 if (!Info) {
0861 Info = new (PP.getPreprocessorAllocator())
0862 ModuleMacroInfo(cast<MacroDirective *>(State));
0863 State = Info;
0864 }
0865
0866 if (PP.CurSubmoduleState->VisibleModules.getGeneration() !=
0867 Info->ActiveModuleMacrosGeneration)
0868 PP.updateModuleMacroInfo(II, *Info);
0869 return Info;
0870 }
0871
0872 public:
0873 MacroState() : MacroState(nullptr) {}
0874 MacroState(MacroDirective *MD) : State(MD) {}
0875
0876 MacroState(MacroState &&O) noexcept : State(O.State) {
0877 O.State = (MacroDirective *)nullptr;
0878 }
0879
0880 MacroState &operator=(MacroState &&O) noexcept {
0881 auto S = O.State;
0882 O.State = (MacroDirective *)nullptr;
0883 State = S;
0884 return *this;
0885 }
0886
0887 ~MacroState() {
0888 if (auto *Info = dyn_cast_if_present<ModuleMacroInfo *>(State))
0889 Info->~ModuleMacroInfo();
0890 }
0891
0892 MacroDirective *getLatest() const {
0893 if (auto *Info = dyn_cast_if_present<ModuleMacroInfo *>(State))
0894 return Info->MD;
0895 return cast<MacroDirective *>(State);
0896 }
0897
0898 void setLatest(MacroDirective *MD) {
0899 if (auto *Info = dyn_cast_if_present<ModuleMacroInfo *>(State))
0900 Info->MD = MD;
0901 else
0902 State = MD;
0903 }
0904
0905 bool isAmbiguous(Preprocessor &PP, const IdentifierInfo *II) const {
0906 auto *Info = getModuleInfo(PP, II);
0907 return Info ? Info->IsAmbiguous : false;
0908 }
0909
0910 ArrayRef<ModuleMacro *>
0911 getActiveModuleMacros(Preprocessor &PP, const IdentifierInfo *II) const {
0912 if (auto *Info = getModuleInfo(PP, II))
0913 return Info->ActiveModuleMacros;
0914 return {};
0915 }
0916
0917 MacroDirective::DefInfo findDirectiveAtLoc(SourceLocation Loc,
0918 SourceManager &SourceMgr) const {
0919
0920 if (auto *Latest = getLatest())
0921 return Latest->findDirectiveAtLoc(Loc, SourceMgr);
0922 return {};
0923 }
0924
0925 void overrideActiveModuleMacros(Preprocessor &PP, IdentifierInfo *II) {
0926 if (auto *Info = getModuleInfo(PP, II)) {
0927 Info->OverriddenMacros.insert(Info->OverriddenMacros.end(),
0928 Info->ActiveModuleMacros.begin(),
0929 Info->ActiveModuleMacros.end());
0930 Info->ActiveModuleMacros.clear();
0931 Info->IsAmbiguous = false;
0932 }
0933 }
0934
0935 ArrayRef<ModuleMacro*> getOverriddenMacros() const {
0936 if (auto *Info = State.dyn_cast<ModuleMacroInfo*>())
0937 return Info->OverriddenMacros;
0938 return {};
0939 }
0940
0941 void setOverriddenMacros(Preprocessor &PP,
0942 ArrayRef<ModuleMacro *> Overrides) {
0943 auto *Info = dyn_cast_if_present<ModuleMacroInfo *>(State);
0944 if (!Info) {
0945 if (Overrides.empty())
0946 return;
0947 Info = new (PP.getPreprocessorAllocator())
0948 ModuleMacroInfo(cast<MacroDirective *>(State));
0949 State = Info;
0950 }
0951 Info->OverriddenMacros.clear();
0952 Info->OverriddenMacros.insert(Info->OverriddenMacros.end(),
0953 Overrides.begin(), Overrides.end());
0954 Info->ActiveModuleMacrosGeneration = 0;
0955 }
0956 };
0957
0958
0959
0960
0961
0962
0963 using MacroMap = llvm::DenseMap<const IdentifierInfo *, MacroState>;
0964
0965 struct SubmoduleState;
0966
0967
0968 struct BuildingSubmoduleInfo {
0969
0970 Module *M;
0971
0972
0973 SourceLocation ImportLoc;
0974
0975
0976 bool IsPragma;
0977
0978
0979 SubmoduleState *OuterSubmoduleState;
0980
0981
0982 unsigned OuterPendingModuleMacroNames;
0983
0984 BuildingSubmoduleInfo(Module *M, SourceLocation ImportLoc, bool IsPragma,
0985 SubmoduleState *OuterSubmoduleState,
0986 unsigned OuterPendingModuleMacroNames)
0987 : M(M), ImportLoc(ImportLoc), IsPragma(IsPragma),
0988 OuterSubmoduleState(OuterSubmoduleState),
0989 OuterPendingModuleMacroNames(OuterPendingModuleMacroNames) {}
0990 };
0991 SmallVector<BuildingSubmoduleInfo, 8> BuildingSubmoduleStack;
0992
0993
0994 struct SubmoduleState {
0995
0996 MacroMap Macros;
0997
0998
0999 VisibleModuleSet VisibleModules;
1000
1001
1002
1003 };
1004 std::map<Module *, SubmoduleState> Submodules;
1005
1006
1007 SubmoduleState NullSubmoduleState;
1008
1009
1010
1011 SubmoduleState *CurSubmoduleState;
1012
1013
1014 IncludedFilesSet IncludedFiles;
1015
1016
1017
1018 llvm::SmallSetVector<Module *, 2> AffectingClangModules;
1019
1020
1021 llvm::FoldingSet<ModuleMacro> ModuleMacros;
1022
1023
1024 llvm::SmallVector<IdentifierInfo *, 32> PendingModuleMacroNames;
1025
1026
1027
1028 llvm::DenseMap<const IdentifierInfo *, llvm::TinyPtrVector<ModuleMacro *>>
1029 LeafModuleMacros;
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039 using WarnUnusedMacroLocsTy = llvm::SmallDenseSet<SourceLocation, 32>;
1040 WarnUnusedMacroLocsTy WarnUnusedMacroLocs;
1041
1042
1043
1044
1045
1046 using MsgLocationPair = std::pair<std::string, SourceLocation>;
1047
1048 struct MacroAnnotationInfo {
1049 SourceLocation Location;
1050 std::string Message;
1051 };
1052
1053 struct MacroAnnotations {
1054 std::optional<MacroAnnotationInfo> DeprecationInfo;
1055 std::optional<MacroAnnotationInfo> RestrictExpansionInfo;
1056 std::optional<SourceLocation> FinalAnnotationLoc;
1057 };
1058
1059
1060 llvm::DenseMap<const IdentifierInfo *, MacroAnnotations> AnnotationInfos;
1061
1062
1063
1064 MacroArgs *MacroArgCache = nullptr;
1065
1066
1067
1068 llvm::DenseMap<IdentifierInfo *, std::vector<MacroInfo *>>
1069 PragmaPushMacroInfo;
1070
1071
1072 unsigned NumDirectives = 0;
1073 unsigned NumDefined = 0;
1074 unsigned NumUndefined = 0;
1075 unsigned NumPragma = 0;
1076 unsigned NumIf = 0;
1077 unsigned NumElse = 0;
1078 unsigned NumEndif = 0;
1079 unsigned NumEnteredSourceFiles = 0;
1080 unsigned MaxIncludeStackDepth = 0;
1081 unsigned NumMacroExpanded = 0;
1082 unsigned NumFnMacroExpanded = 0;
1083 unsigned NumBuiltinMacroExpanded = 0;
1084 unsigned NumFastMacroExpanded = 0;
1085 unsigned NumTokenPaste = 0;
1086 unsigned NumFastTokenPaste = 0;
1087 unsigned NumSkipped = 0;
1088
1089
1090
1091 std::string Predefines;
1092
1093
1094 FileID PredefinesFileID;
1095
1096
1097 FileID PCHThroughHeaderFileID;
1098
1099
1100 bool SkippingUntilPragmaHdrStop = false;
1101
1102
1103 bool SkippingUntilPCHThroughHeader = false;
1104
1105
1106
1107 enum { TokenLexerCacheSize = 8 };
1108 unsigned NumCachedTokenLexers;
1109 std::unique_ptr<TokenLexer> TokenLexerCache[TokenLexerCacheSize];
1110
1111
1112
1113
1114
1115
1116
1117 SmallVector<Token, 16> MacroExpandedTokens;
1118 std::vector<std::pair<TokenLexer *, size_t>> MacroExpandingLexersStack;
1119
1120
1121
1122
1123
1124
1125 PreprocessingRecord *Record = nullptr;
1126
1127
1128 using CachedTokensTy = SmallVector<Token, 1>;
1129
1130
1131
1132 CachedTokensTy CachedTokens;
1133
1134
1135
1136
1137
1138
1139 CachedTokensTy::size_type CachedLexPos = 0;
1140
1141
1142
1143
1144
1145
1146 std::vector<CachedTokensTy::size_type> BacktrackPositions;
1147
1148
1149
1150 std::vector<std::pair<CachedTokensTy, CachedTokensTy::size_type>>
1151 UnannotatedBacktrackTokens;
1152
1153
1154
1155
1156
1157 bool SkippingExcludedConditionalBlock = false;
1158
1159
1160
1161
1162
1163 llvm::DenseMap<const char *, unsigned> RecordedSkippedRanges;
1164
1165 void updateOutOfDateIdentifier(const IdentifierInfo &II) const;
1166
1167 public:
1168 Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
1169 DiagnosticsEngine &diags, const LangOptions &LangOpts,
1170 SourceManager &SM, HeaderSearch &Headers,
1171 ModuleLoader &TheModuleLoader,
1172 IdentifierInfoLookup *IILookup = nullptr,
1173 bool OwnsHeaderSearch = false,
1174 TranslationUnitKind TUKind = TU_Complete);
1175
1176 ~Preprocessor();
1177
1178
1179
1180
1181
1182
1183
1184 void Initialize(const TargetInfo &Target,
1185 const TargetInfo *AuxTarget = nullptr);
1186
1187
1188
1189
1190
1191
1192
1193 void InitializeForModelFile();
1194
1195
1196 void FinalizeForModelFile();
1197
1198
1199
1200 PreprocessorOptions &getPreprocessorOpts() const { return *PPOpts; }
1201
1202 DiagnosticsEngine &getDiagnostics() const { return *Diags; }
1203 void setDiagnostics(DiagnosticsEngine &D) { Diags = &D; }
1204
1205 const LangOptions &getLangOpts() const { return LangOpts; }
1206 const TargetInfo &getTargetInfo() const { return *Target; }
1207 const TargetInfo *getAuxTargetInfo() const { return AuxTarget; }
1208 FileManager &getFileManager() const { return FileMgr; }
1209 SourceManager &getSourceManager() const { return SourceMgr; }
1210 HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; }
1211
1212 IdentifierTable &getIdentifierTable() { return Identifiers; }
1213 const IdentifierTable &getIdentifierTable() const { return Identifiers; }
1214 SelectorTable &getSelectorTable() { return Selectors; }
1215 Builtin::Context &getBuiltinInfo() { return *BuiltinInfo; }
1216 llvm::BumpPtrAllocator &getPreprocessorAllocator() { return BP; }
1217
1218 void setExternalSource(ExternalPreprocessorSource *Source) {
1219 ExternalSource = Source;
1220 }
1221
1222 ExternalPreprocessorSource *getExternalSource() const {
1223 return ExternalSource;
1224 }
1225
1226
1227 ModuleLoader &getModuleLoader() const { return TheModuleLoader; }
1228
1229 bool hadModuleLoaderFatalFailure() const {
1230 return TheModuleLoader.HadFatalFailure;
1231 }
1232
1233
1234
1235 unsigned getNumDirectives() const {
1236 return NumDirectives;
1237 }
1238
1239
1240 bool isParsingIfOrElifDirective() const {
1241 return ParsingIfOrElifDirective;
1242 }
1243
1244
1245 void SetCommentRetentionState(bool KeepComments, bool KeepMacroComments) {
1246 this->KeepComments = KeepComments | KeepMacroComments;
1247 this->KeepMacroComments = KeepMacroComments;
1248 }
1249
1250 bool getCommentRetentionState() const { return KeepComments; }
1251
1252 void setPragmasEnabled(bool Enabled) { PragmasEnabled = Enabled; }
1253 bool getPragmasEnabled() const { return PragmasEnabled; }
1254
1255 void SetSuppressIncludeNotFoundError(bool Suppress) {
1256 SuppressIncludeNotFoundError = Suppress;
1257 }
1258
1259 bool GetSuppressIncludeNotFoundError() {
1260 return SuppressIncludeNotFoundError;
1261 }
1262
1263
1264
1265 void setPreprocessedOutput(bool IsPreprocessedOutput) {
1266 PreprocessedOutput = IsPreprocessedOutput;
1267 }
1268
1269
1270
1271 bool isPreprocessedOutput() const { return PreprocessedOutput; }
1272
1273
1274 bool isCurrentLexer(const PreprocessorLexer *L) const {
1275 return CurPPLexer == L;
1276 }
1277
1278
1279
1280
1281
1282 PreprocessorLexer *getCurrentLexer() const { return CurPPLexer; }
1283
1284
1285
1286
1287
1288 PreprocessorLexer *getCurrentFileLexer() const;
1289
1290
1291
1292 Module *getCurrentLexerSubmodule() const { return CurLexerSubmodule; }
1293
1294
1295 FileID getPredefinesFileID() const { return PredefinesFileID; }
1296
1297
1298
1299
1300
1301
1302 PPCallbacks *getPPCallbacks() const { return Callbacks.get(); }
1303 void addPPCallbacks(std::unique_ptr<PPCallbacks> C) {
1304 if (Callbacks)
1305 C = std::make_unique<PPChainedCallbacks>(std::move(C),
1306 std::move(Callbacks));
1307 Callbacks = std::move(C);
1308 }
1309
1310
1311
1312 unsigned getTokenCount() const { return TokenCount; }
1313
1314
1315 unsigned getMaxTokens() const { return MaxTokens; }
1316
1317 void overrideMaxTokens(unsigned Value, SourceLocation Loc) {
1318 MaxTokens = Value;
1319 MaxTokensOverrideLoc = Loc;
1320 };
1321
1322 SourceLocation getMaxTokensOverrideLoc() const { return MaxTokensOverrideLoc; }
1323
1324
1325
1326
1327 void setTokenWatcher(llvm::unique_function<void(const clang::Token &)> F) {
1328 OnToken = std::move(F);
1329 }
1330
1331 void setPreprocessToken(bool Preprocess) { PreprocessToken = Preprocess; }
1332
1333 bool isMacroDefined(StringRef Id) {
1334 return isMacroDefined(&Identifiers.get(Id));
1335 }
1336 bool isMacroDefined(const IdentifierInfo *II) {
1337 return II->hasMacroDefinition() &&
1338 (!getLangOpts().Modules || (bool)getMacroDefinition(II));
1339 }
1340
1341
1342
1343
1344 bool isMacroDefinedInLocalModule(const IdentifierInfo *II, Module *M) {
1345 if (!II->hasMacroDefinition())
1346 return false;
1347 auto I = Submodules.find(M);
1348 if (I == Submodules.end())
1349 return false;
1350 auto J = I->second.Macros.find(II);
1351 if (J == I->second.Macros.end())
1352 return false;
1353 auto *MD = J->second.getLatest();
1354 return MD && MD->isDefined();
1355 }
1356
1357 MacroDefinition getMacroDefinition(const IdentifierInfo *II) {
1358 if (!II->hasMacroDefinition())
1359 return {};
1360
1361 MacroState &S = CurSubmoduleState->Macros[II];
1362 auto *MD = S.getLatest();
1363 while (isa_and_nonnull<VisibilityMacroDirective>(MD))
1364 MD = MD->getPrevious();
1365 return MacroDefinition(dyn_cast_or_null<DefMacroDirective>(MD),
1366 S.getActiveModuleMacros(*this, II),
1367 S.isAmbiguous(*this, II));
1368 }
1369
1370 MacroDefinition getMacroDefinitionAtLoc(const IdentifierInfo *II,
1371 SourceLocation Loc) {
1372 if (!II->hadMacroDefinition())
1373 return {};
1374
1375 MacroState &S = CurSubmoduleState->Macros[II];
1376 MacroDirective::DefInfo DI;
1377 if (auto *MD = S.getLatest())
1378 DI = MD->findDirectiveAtLoc(Loc, getSourceManager());
1379
1380 return MacroDefinition(DI.getDirective(),
1381 S.getActiveModuleMacros(*this, II),
1382 S.isAmbiguous(*this, II));
1383 }
1384
1385
1386
1387 MacroDirective *getLocalMacroDirective(const IdentifierInfo *II) const {
1388 if (!II->hasMacroDefinition())
1389 return nullptr;
1390
1391 auto *MD = getLocalMacroDirectiveHistory(II);
1392 if (!MD || MD->getDefinition().isUndefined())
1393 return nullptr;
1394
1395 return MD;
1396 }
1397
1398 const MacroInfo *getMacroInfo(const IdentifierInfo *II) const {
1399 return const_cast<Preprocessor*>(this)->getMacroInfo(II);
1400 }
1401
1402 MacroInfo *getMacroInfo(const IdentifierInfo *II) {
1403 if (!II->hasMacroDefinition())
1404 return nullptr;
1405 if (auto MD = getMacroDefinition(II))
1406 return MD.getMacroInfo();
1407 return nullptr;
1408 }
1409
1410
1411
1412
1413
1414
1415 MacroDirective *getLocalMacroDirectiveHistory(const IdentifierInfo *II) const;
1416
1417
1418 void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD);
1419 DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI,
1420 SourceLocation Loc) {
1421 DefMacroDirective *MD = AllocateDefMacroDirective(MI, Loc);
1422 appendMacroDirective(II, MD);
1423 return MD;
1424 }
1425 DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II,
1426 MacroInfo *MI) {
1427 return appendDefMacroDirective(II, MI, MI->getDefinitionLoc());
1428 }
1429
1430
1431 void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *ED,
1432 MacroDirective *MD);
1433
1434
1435 ModuleMacro *addModuleMacro(Module *Mod, IdentifierInfo *II,
1436 MacroInfo *Macro,
1437 ArrayRef<ModuleMacro *> Overrides, bool &IsNew);
1438 ModuleMacro *getModuleMacro(Module *Mod, const IdentifierInfo *II);
1439
1440
1441 ArrayRef<ModuleMacro*> getLeafModuleMacros(const IdentifierInfo *II) const {
1442 if (II->isOutOfDate())
1443 updateOutOfDateIdentifier(*II);
1444 auto I = LeafModuleMacros.find(II);
1445 if (I != LeafModuleMacros.end())
1446 return I->second;
1447 return {};
1448 }
1449
1450
1451 ArrayRef<BuildingSubmoduleInfo> getBuildingSubmodules() const {
1452 return BuildingSubmoduleStack;
1453 }
1454
1455
1456
1457
1458
1459 using macro_iterator = MacroMap::const_iterator;
1460
1461 macro_iterator macro_begin(bool IncludeExternalMacros = true) const;
1462 macro_iterator macro_end(bool IncludeExternalMacros = true) const;
1463
1464 llvm::iterator_range<macro_iterator>
1465 macros(bool IncludeExternalMacros = true) const {
1466 macro_iterator begin = macro_begin(IncludeExternalMacros);
1467 macro_iterator end = macro_end(IncludeExternalMacros);
1468 return llvm::make_range(begin, end);
1469 }
1470
1471
1472
1473
1474 void markClangModuleAsAffecting(Module *M) {
1475 assert(M->isModuleMapModule());
1476 if (!BuildingSubmoduleStack.empty()) {
1477 if (M != BuildingSubmoduleStack.back().M)
1478 BuildingSubmoduleStack.back().M->AffectingClangModules.insert(M);
1479 } else {
1480 AffectingClangModules.insert(M);
1481 }
1482 }
1483
1484
1485
1486 const llvm::SmallSetVector<Module *, 2> &getAffectingClangModules() const {
1487 return AffectingClangModules;
1488 }
1489
1490
1491
1492 bool markIncluded(FileEntryRef File) {
1493 HeaderInfo.getFileInfo(File).IsLocallyIncluded = true;
1494 return IncludedFiles.insert(File).second;
1495 }
1496
1497
1498 bool alreadyIncluded(FileEntryRef File) const {
1499 HeaderInfo.getFileInfo(File);
1500 return IncludedFiles.count(File);
1501 }
1502
1503
1504 IncludedFilesSet &getIncludedFiles() { return IncludedFiles; }
1505 const IncludedFilesSet &getIncludedFiles() const { return IncludedFiles; }
1506
1507
1508
1509
1510 StringRef getLastMacroWithSpelling(SourceLocation Loc,
1511 ArrayRef<TokenValue> Tokens) const;
1512
1513
1514
1515
1516 const std::string &getPredefines() const { return Predefines; }
1517
1518
1519
1520
1521 void setPredefines(std::string P) { Predefines = std::move(P); }
1522
1523
1524
1525 IdentifierInfo *getIdentifierInfo(StringRef Name) const {
1526 return &Identifiers.get(Name);
1527 }
1528
1529
1530
1531
1532
1533 void AddPragmaHandler(StringRef Namespace, PragmaHandler *Handler);
1534 void AddPragmaHandler(PragmaHandler *Handler) {
1535 AddPragmaHandler(StringRef(), Handler);
1536 }
1537
1538
1539
1540
1541
1542
1543 void RemovePragmaHandler(StringRef Namespace, PragmaHandler *Handler);
1544 void RemovePragmaHandler(PragmaHandler *Handler) {
1545 RemovePragmaHandler(StringRef(), Handler);
1546 }
1547
1548
1549 void IgnorePragmas();
1550
1551
1552 void setEmptylineHandler(EmptylineHandler *Handler) { Emptyline = Handler; }
1553
1554 EmptylineHandler *getEmptylineHandler() const { return Emptyline; }
1555
1556
1557 void addCommentHandler(CommentHandler *Handler);
1558
1559
1560
1561
1562 void removeCommentHandler(CommentHandler *Handler);
1563
1564
1565 void setCodeCompletionHandler(CodeCompletionHandler &Handler) {
1566 CodeComplete = &Handler;
1567 }
1568
1569
1570 CodeCompletionHandler *getCodeCompletionHandler() const {
1571 return CodeComplete;
1572 }
1573
1574
1575 void clearCodeCompletionHandler() {
1576 CodeComplete = nullptr;
1577 }
1578
1579
1580
1581 void CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled);
1582
1583
1584
1585 void CodeCompleteNaturalLanguage();
1586
1587
1588 void setCodeCompletionIdentifierInfo(IdentifierInfo *Filter) {
1589 CodeCompletionII = Filter;
1590 }
1591
1592
1593
1594 void setCodeCompletionTokenRange(const SourceLocation Start,
1595 const SourceLocation End) {
1596 CodeCompletionTokenRange = {Start, End};
1597 }
1598 SourceRange getCodeCompletionTokenRange() const {
1599 return CodeCompletionTokenRange;
1600 }
1601
1602
1603 StringRef getCodeCompletionFilter() {
1604 if (CodeCompletionII)
1605 return CodeCompletionII->getName();
1606 return {};
1607 }
1608
1609
1610
1611 PreprocessingRecord *getPreprocessingRecord() const { return Record; }
1612
1613
1614
1615 void createPreprocessingRecord();
1616
1617
1618 bool isPCHThroughHeader(const FileEntry *FE);
1619
1620
1621 bool creatingPCHWithThroughHeader();
1622
1623
1624 bool usingPCHWithThroughHeader();
1625
1626
1627 bool creatingPCHWithPragmaHdrStop();
1628
1629
1630 bool usingPCHWithPragmaHdrStop();
1631
1632
1633
1634 void SkipTokensWhileUsingPCH();
1635
1636
1637
1638 void HandleSkippedDirectiveWhileUsingPCH(Token &Result,
1639 SourceLocation HashLoc);
1640
1641
1642
1643 void EnterMainSourceFile();
1644
1645
1646 void EndSourceFile();
1647
1648
1649
1650
1651
1652 bool EnterSourceFile(FileID FID, ConstSearchDirIterator Dir,
1653 SourceLocation Loc, bool IsFirstIncludeOfFile = true);
1654
1655
1656
1657
1658
1659
1660
1661 void EnterMacro(Token &Tok, SourceLocation ILEnd, MacroInfo *Macro,
1662 MacroArgs *Args);
1663
1664 private:
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679 void EnterTokenStream(const Token *Toks, unsigned NumToks,
1680 bool DisableMacroExpansion, bool OwnsTokens,
1681 bool IsReinject);
1682
1683 public:
1684 void EnterTokenStream(std::unique_ptr<Token[]> Toks, unsigned NumToks,
1685 bool DisableMacroExpansion, bool IsReinject) {
1686 EnterTokenStream(Toks.release(), NumToks, DisableMacroExpansion, true,
1687 IsReinject);
1688 }
1689
1690 void EnterTokenStream(ArrayRef<Token> Toks, bool DisableMacroExpansion,
1691 bool IsReinject) {
1692 EnterTokenStream(Toks.data(), Toks.size(), DisableMacroExpansion, false,
1693 IsReinject);
1694 }
1695
1696
1697
1698
1699
1700 void RemoveTopOfLexerStack();
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717 void EnableBacktrackAtThisPos(bool Unannotated = false);
1718
1719 private:
1720 std::pair<CachedTokensTy::size_type, bool> LastBacktrackPos();
1721
1722 CachedTokensTy PopUnannotatedBacktrackTokens();
1723
1724 public:
1725
1726 void CommitBacktrackedTokens();
1727
1728
1729
1730 void Backtrack();
1731
1732
1733
1734 bool isBacktrackEnabled() const { return !BacktrackPositions.empty(); }
1735
1736
1737
1738 bool isUnannotatedBacktrackEnabled() const {
1739 return !UnannotatedBacktrackTokens.empty();
1740 }
1741
1742
1743 void Lex(Token &Result);
1744
1745
1746 void LexTokensUntilEOF(std::vector<Token> *Tokens = nullptr);
1747
1748
1749 bool LexHeaderName(Token &Result, bool AllowMacroExpansion = true);
1750
1751
1752 std::optional<LexEmbedParametersResult> LexEmbedParameters(Token &Current,
1753 bool ForHasEmbed);
1754
1755 bool LexAfterModuleImport(Token &Result);
1756 void CollectPpImportSuffix(SmallVectorImpl<Token> &Toks);
1757
1758 void makeModuleVisible(Module *M, SourceLocation Loc);
1759
1760 SourceLocation getModuleImportLoc(Module *M) const {
1761 return CurSubmoduleState->VisibleModules.getImportLoc(M);
1762 }
1763
1764
1765
1766
1767 bool LexStringLiteral(Token &Result, std::string &String,
1768 const char *DiagnosticTag, bool AllowMacroExpansion) {
1769 if (AllowMacroExpansion)
1770 Lex(Result);
1771 else
1772 LexUnexpandedToken(Result);
1773 return FinishLexStringLiteral(Result, String, DiagnosticTag,
1774 AllowMacroExpansion);
1775 }
1776
1777
1778
1779 bool FinishLexStringLiteral(Token &Result, std::string &String,
1780 const char *DiagnosticTag,
1781 bool AllowMacroExpansion);
1782
1783
1784
1785
1786
1787
1788 void LexNonComment(Token &Result) {
1789 do
1790 Lex(Result);
1791 while (Result.getKind() == tok::comment);
1792 }
1793
1794
1795 void LexUnexpandedToken(Token &Result) {
1796
1797 bool OldVal = DisableMacroExpansion;
1798 DisableMacroExpansion = true;
1799
1800 Lex(Result);
1801
1802
1803 DisableMacroExpansion = OldVal;
1804 }
1805
1806
1807
1808 void LexUnexpandedNonComment(Token &Result) {
1809 do
1810 LexUnexpandedToken(Result);
1811 while (Result.getKind() == tok::comment);
1812 }
1813
1814
1815
1816
1817 bool parseSimpleIntegerLiteral(Token &Tok, uint64_t &Value);
1818
1819
1820 void SetMacroExpansionOnlyInDirectives() {
1821 DisableMacroExpansion = true;
1822 MacroExpansionInDirectivesOverride = true;
1823 }
1824
1825
1826
1827
1828
1829
1830
1831
1832 const Token &LookAhead(unsigned N) {
1833 assert(LexLevel == 0 && "cannot use lookahead while lexing");
1834 if (CachedLexPos + N < CachedTokens.size())
1835 return CachedTokens[CachedLexPos+N];
1836 else
1837 return PeekAhead(N+1);
1838 }
1839
1840
1841
1842
1843
1844
1845 void RevertCachedTokens(unsigned N) {
1846 assert(isBacktrackEnabled() &&
1847 "Should only be called when tokens are cached for backtracking");
1848 assert(signed(CachedLexPos) - signed(N) >=
1849 signed(LastBacktrackPos().first) &&
1850 "Should revert tokens up to the last backtrack position, not more");
1851 assert(signed(CachedLexPos) - signed(N) >= 0 &&
1852 "Corrupted backtrack positions ?");
1853 CachedLexPos -= N;
1854 }
1855
1856
1857
1858
1859
1860
1861
1862 void EnterToken(const Token &Tok, bool IsReinject) {
1863 if (LexLevel) {
1864
1865
1866 auto TokCopy = std::make_unique<Token[]>(1);
1867 TokCopy[0] = Tok;
1868 EnterTokenStream(std::move(TokCopy), 1, true, IsReinject);
1869 } else {
1870 EnterCachingLexMode();
1871 assert(IsReinject && "new tokens in the middle of cached stream");
1872 CachedTokens.insert(CachedTokens.begin()+CachedLexPos, Tok);
1873 }
1874 }
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884 void AnnotateCachedTokens(const Token &Tok) {
1885 assert(Tok.isAnnotation() && "Expected annotation token");
1886 if (CachedLexPos != 0 && isBacktrackEnabled())
1887 AnnotatePreviousCachedTokens(Tok);
1888 }
1889
1890
1891
1892 SourceLocation getLastCachedTokenLocation() const {
1893 assert(CachedLexPos != 0);
1894 return CachedTokens[CachedLexPos-1].getLastLoc();
1895 }
1896
1897
1898
1899 bool IsPreviousCachedToken(const Token &Tok) const;
1900
1901
1902
1903
1904
1905
1906 void ReplacePreviousCachedToken(ArrayRef<Token> NewToks);
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916 void ReplaceLastTokenWithAnnotation(const Token &Tok) {
1917 assert(Tok.isAnnotation() && "Expected annotation token");
1918 if (CachedLexPos != 0 && isBacktrackEnabled())
1919 CachedTokens[CachedLexPos-1] = Tok;
1920 }
1921
1922
1923 void EnterAnnotationToken(SourceRange Range, tok::TokenKind Kind,
1924 void *AnnotationVal);
1925
1926
1927
1928 bool mightHavePendingAnnotationTokens() {
1929 return CurLexerCallback != CLK_Lexer;
1930 }
1931
1932
1933
1934 void TypoCorrectToken(const Token &Tok) {
1935 assert(Tok.getIdentifierInfo() && "Expected identifier token");
1936 if (CachedLexPos != 0 && isBacktrackEnabled())
1937 CachedTokens[CachedLexPos-1] = Tok;
1938 }
1939
1940
1941
1942 void recomputeCurLexerKind();
1943
1944
1945 bool isIncrementalProcessingEnabled() const { return IncrementalProcessing; }
1946
1947
1948 void enableIncrementalProcessing(bool value = true) {
1949 IncrementalProcessing = value;
1950 }
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966 bool SetCodeCompletionPoint(FileEntryRef File, unsigned Line,
1967 unsigned Column);
1968
1969
1970 bool isCodeCompletionEnabled() const { return CodeCompletionFile != nullptr; }
1971
1972
1973
1974
1975
1976 SourceLocation getCodeCompletionLoc() const { return CodeCompletionLoc; }
1977
1978
1979
1980
1981
1982 SourceLocation getCodeCompletionFileLoc() const {
1983 return CodeCompletionFileLoc;
1984 }
1985
1986
1987
1988 bool isCodeCompletionReached() const { return CodeCompletionReached; }
1989
1990
1991 void setCodeCompletionReached() {
1992 assert(isCodeCompletionEnabled() && "Code-completion not enabled!");
1993 CodeCompletionReached = true;
1994
1995 getDiagnostics().setSuppressAllDiagnostics(true);
1996 }
1997
1998
1999
2000
2001
2002 std::pair<IdentifierInfo *, SourceLocation>
2003 getPragmaARCCFCodeAuditedInfo() const {
2004 return PragmaARCCFCodeAuditedInfo;
2005 }
2006
2007
2008
2009 void setPragmaARCCFCodeAuditedInfo(IdentifierInfo *Ident,
2010 SourceLocation Loc) {
2011 PragmaARCCFCodeAuditedInfo = {Ident, Loc};
2012 }
2013
2014
2015
2016
2017
2018 SourceLocation getPragmaAssumeNonNullLoc() const {
2019 return PragmaAssumeNonNullLoc;
2020 }
2021
2022
2023
2024 void setPragmaAssumeNonNullLoc(SourceLocation Loc) {
2025 PragmaAssumeNonNullLoc = Loc;
2026 }
2027
2028
2029
2030
2031
2032
2033 SourceLocation getPreambleRecordedPragmaAssumeNonNullLoc() const {
2034 return PreambleRecordedPragmaAssumeNonNullLoc;
2035 }
2036
2037
2038
2039 void setPreambleRecordedPragmaAssumeNonNullLoc(SourceLocation Loc) {
2040 PreambleRecordedPragmaAssumeNonNullLoc = Loc;
2041 }
2042
2043
2044
2045 void setMainFileDir(DirectoryEntryRef Dir) { MainFileDir = Dir; }
2046
2047
2048
2049
2050
2051
2052
2053 void setSkipMainFilePreamble(unsigned Bytes, bool StartOfLine) {
2054 SkipMainFilePreamble.first = Bytes;
2055 SkipMainFilePreamble.second = StartOfLine;
2056 }
2057
2058
2059
2060
2061 DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const {
2062 return Diags->Report(Loc, DiagID);
2063 }
2064
2065 DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID) const {
2066 return Diags->Report(Tok.getLocation(), DiagID);
2067 }
2068
2069
2070
2071
2072
2073
2074
2075
2076 StringRef getSpelling(SourceLocation loc,
2077 SmallVectorImpl<char> &buffer,
2078 bool *invalid = nullptr) const {
2079 return Lexer::getSpelling(loc, buffer, SourceMgr, LangOpts, invalid);
2080 }
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090 std::string getSpelling(const Token &Tok, bool *Invalid = nullptr) const {
2091 return Lexer::getSpelling(Tok, SourceMgr, LangOpts, Invalid);
2092 }
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106 unsigned getSpelling(const Token &Tok, const char *&Buffer,
2107 bool *Invalid = nullptr) const {
2108 return Lexer::getSpelling(Tok, Buffer, SourceMgr, LangOpts, Invalid);
2109 }
2110
2111
2112
2113
2114
2115 StringRef getSpelling(const Token &Tok,
2116 SmallVectorImpl<char> &Buffer,
2117 bool *Invalid = nullptr) const;
2118
2119
2120
2121 bool getRawToken(SourceLocation Loc, Token &Result,
2122 bool IgnoreWhiteSpace = false) {
2123 return Lexer::getRawToken(Loc, Result, SourceMgr, LangOpts, IgnoreWhiteSpace);
2124 }
2125
2126
2127
2128 uint8_t
2129 getSpellingOfSingleCharacterNumericConstant(const Token &Tok,
2130 bool *Invalid = nullptr) const {
2131 assert((Tok.is(tok::numeric_constant) || Tok.is(tok::binary_data)) &&
2132 Tok.getLength() == 1 && "Called on unsupported token");
2133 assert(!Tok.needsCleaning() && "Token can't need cleaning with length 1");
2134
2135
2136 if (const char *D = Tok.getLiteralData())
2137 return (Tok.getKind() == tok::binary_data) ? *D : *D - '0';
2138
2139 assert(Tok.is(tok::numeric_constant) && "binary data with no data");
2140
2141
2142 return *SourceMgr.getCharacterData(Tok.getLocation(), Invalid) - '0';
2143 }
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153 StringRef getImmediateMacroName(SourceLocation Loc) {
2154 return Lexer::getImmediateMacroName(Loc, SourceMgr, getLangOpts());
2155 }
2156
2157
2158
2159
2160
2161
2162 void CreateString(StringRef Str, Token &Tok,
2163 SourceLocation ExpansionLocStart = SourceLocation(),
2164 SourceLocation ExpansionLocEnd = SourceLocation());
2165
2166
2167
2168
2169 SourceLocation SplitToken(SourceLocation TokLoc, unsigned Length);
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186 SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset = 0) {
2187 return Lexer::getLocForEndOfToken(Loc, Offset, SourceMgr, LangOpts);
2188 }
2189
2190
2191
2192
2193
2194
2195 bool isAtStartOfMacroExpansion(SourceLocation loc,
2196 SourceLocation *MacroBegin = nullptr) const {
2197 return Lexer::isAtStartOfMacroExpansion(loc, SourceMgr, LangOpts,
2198 MacroBegin);
2199 }
2200
2201
2202
2203
2204
2205
2206 bool isAtEndOfMacroExpansion(SourceLocation loc,
2207 SourceLocation *MacroEnd = nullptr) const {
2208 return Lexer::isAtEndOfMacroExpansion(loc, SourceMgr, LangOpts, MacroEnd);
2209 }
2210
2211
2212 void DumpToken(const Token &Tok, bool DumpFlags = false) const;
2213 void DumpLocation(SourceLocation Loc) const;
2214 void DumpMacro(const MacroInfo &MI) const;
2215 void dumpMacroInfo(const IdentifierInfo *II);
2216
2217
2218
2219 SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart,
2220 unsigned Char) const {
2221 return Lexer::AdvanceToTokenCharacter(TokStart, Char, SourceMgr, LangOpts);
2222 }
2223
2224
2225
2226
2227
2228 void IncrementPasteCounter(bool isFast) {
2229 if (isFast)
2230 ++NumFastTokenPaste;
2231 else
2232 ++NumTokenPaste;
2233 }
2234
2235 void PrintStats();
2236
2237 size_t getTotalMemory() const;
2238
2239
2240
2241
2242 void HandleMicrosoftCommentPaste(Token &Tok);
2243
2244
2245
2246
2247
2248
2249
2250
2251 IdentifierInfo *LookUpIdentifierInfo(Token &Identifier) const;
2252
2253 private:
2254 llvm::DenseMap<IdentifierInfo*,unsigned> PoisonReasons;
2255
2256 public:
2257
2258
2259
2260
2261 void SetPoisonReason(IdentifierInfo *II, unsigned DiagID);
2262
2263
2264 void HandlePoisonedIdentifier(Token & Identifier);
2265
2266 void MaybeHandlePoisonedIdentifier(Token & Identifier) {
2267 if(IdentifierInfo * II = Identifier.getIdentifierInfo()) {
2268 if(II->isPoisoned()) {
2269 HandlePoisonedIdentifier(Identifier);
2270 }
2271 }
2272 }
2273
2274
2275
2276
2277 bool isNextPPTokenLParen();
2278
2279 private:
2280
2281
2282
2283 IdentifierInfo *Ident__exception_code,
2284 *Ident___exception_code,
2285 *Ident_GetExceptionCode;
2286
2287 IdentifierInfo *Ident__exception_info,
2288 *Ident___exception_info,
2289 *Ident_GetExceptionInfo;
2290
2291 IdentifierInfo *Ident__abnormal_termination,
2292 *Ident___abnormal_termination,
2293 *Ident_AbnormalTermination;
2294
2295 const char *getCurLexerEndPos();
2296 void diagnoseMissingHeaderInUmbrellaDir(const Module &Mod);
2297
2298 public:
2299 void PoisonSEHIdentifiers(bool Poison = true);
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309 bool HandleIdentifier(Token &Identifier);
2310
2311
2312
2313
2314
2315
2316 bool HandleEndOfFile(Token &Result, bool isEndOfMacro = false);
2317
2318
2319
2320 bool HandleEndOfTokenLexer(Token &Result);
2321
2322
2323
2324
2325
2326
2327 void HandleDirective(Token &Result);
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337 SourceLocation CheckEndOfDirective(const char *DirType,
2338 bool EnableMacros = false);
2339
2340
2341
2342 SourceRange DiscardUntilEndOfDirective() {
2343 Token Tmp;
2344 return DiscardUntilEndOfDirective(Tmp);
2345 }
2346
2347
2348 SourceRange DiscardUntilEndOfDirective(Token &Tok);
2349
2350
2351
2352 bool SawDateOrTime() const {
2353 return DATELoc != SourceLocation() || TIMELoc != SourceLocation();
2354 }
2355 unsigned getCounterValue() const { return CounterValue; }
2356 void setCounterValue(unsigned V) { CounterValue = V; }
2357
2358 LangOptions::FPEvalMethodKind getCurrentFPEvalMethod() const {
2359 assert(CurrentFPEvalMethod != LangOptions::FEM_UnsetOnCommandLine &&
2360 "FPEvalMethod should be set either from command line or from the "
2361 "target info");
2362 return CurrentFPEvalMethod;
2363 }
2364
2365 LangOptions::FPEvalMethodKind getTUFPEvalMethod() const {
2366 return TUFPEvalMethod;
2367 }
2368
2369 SourceLocation getLastFPEvalPragmaLocation() const {
2370 return LastFPEvalPragmaLocation;
2371 }
2372
2373 void setCurrentFPEvalMethod(SourceLocation PragmaLoc,
2374 LangOptions::FPEvalMethodKind Val) {
2375 assert(Val != LangOptions::FEM_UnsetOnCommandLine &&
2376 "FPEvalMethod should never be set to FEM_UnsetOnCommandLine");
2377
2378
2379 LastFPEvalPragmaLocation = PragmaLoc;
2380 CurrentFPEvalMethod = Val;
2381 TUFPEvalMethod = Val;
2382 }
2383
2384 void setTUFPEvalMethod(LangOptions::FPEvalMethodKind Val) {
2385 assert(Val != LangOptions::FEM_UnsetOnCommandLine &&
2386 "TUPEvalMethod should never be set to FEM_UnsetOnCommandLine");
2387 TUFPEvalMethod = Val;
2388 }
2389
2390
2391 Module *getCurrentModule();
2392
2393
2394 Module *getCurrentModuleImplementation();
2395
2396
2397 bool isInNamedModule() const { return ModuleDeclState.isNamedModule(); }
2398
2399
2400
2401
2402
2403 bool isInNamedInterfaceUnit() const {
2404 return ModuleDeclState.isNamedInterface();
2405 }
2406
2407
2408
2409 StringRef getNamedModuleName() const { return ModuleDeclState.getName(); }
2410
2411
2412
2413
2414 bool isInImplementationUnit() const {
2415 return ModuleDeclState.isImplementationUnit();
2416 }
2417
2418
2419 bool isInImportingCXXNamedModules() const {
2420
2421
2422 return !NamedModuleImportPath.empty() && getLangOpts().CPlusPlusModules &&
2423 !IsAtImport;
2424 }
2425
2426
2427 MacroInfo *AllocateMacroInfo(SourceLocation L);
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438 bool GetIncludeFilenameSpelling(SourceLocation Loc,StringRef &Buffer);
2439
2440
2441
2442
2443
2444 OptionalFileEntryRef
2445 LookupFile(SourceLocation FilenameLoc, StringRef Filename, bool isAngled,
2446 ConstSearchDirIterator FromDir, const FileEntry *FromFile,
2447 ConstSearchDirIterator *CurDir, SmallVectorImpl<char> *SearchPath,
2448 SmallVectorImpl<char> *RelativePath,
2449 ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped,
2450 bool *IsFrameworkFound, bool SkipCache = false,
2451 bool OpenFile = true, bool CacheFailures = true);
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461 OptionalFileEntryRef
2462 LookupEmbedFile(StringRef Filename, bool isAngled, bool OpenFile,
2463 const FileEntry *LookupFromFile = nullptr);
2464
2465
2466 bool isInPrimaryFile() const;
2467
2468
2469
2470 bool LexOnOffSwitch(tok::OnOffSwitch &Result);
2471
2472 bool CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef,
2473 bool *ShadowFlag = nullptr);
2474
2475 void EnterSubmodule(Module *M, SourceLocation ImportLoc, bool ForPragma);
2476 Module *LeaveSubmodule(bool ForPragma);
2477
2478 private:
2479 friend void TokenLexer::ExpandFunctionArguments();
2480
2481 void PushIncludeMacroStack() {
2482 assert(CurLexerCallback != CLK_CachingLexer &&
2483 "cannot push a caching lexer");
2484 IncludeMacroStack.emplace_back(CurLexerCallback, CurLexerSubmodule,
2485 std::move(CurLexer), CurPPLexer,
2486 std::move(CurTokenLexer), CurDirLookup);
2487 CurPPLexer = nullptr;
2488 }
2489
2490 void PopIncludeMacroStack() {
2491 CurLexer = std::move(IncludeMacroStack.back().TheLexer);
2492 CurPPLexer = IncludeMacroStack.back().ThePPLexer;
2493 CurTokenLexer = std::move(IncludeMacroStack.back().TheTokenLexer);
2494 CurDirLookup = IncludeMacroStack.back().TheDirLookup;
2495 CurLexerSubmodule = IncludeMacroStack.back().TheSubmodule;
2496 CurLexerCallback = IncludeMacroStack.back().CurLexerCallback;
2497 IncludeMacroStack.pop_back();
2498 }
2499
2500 void PropagateLineStartLeadingSpaceInfo(Token &Result);
2501
2502
2503
2504 bool needModuleMacros() const;
2505
2506
2507
2508 void updateModuleMacroInfo(const IdentifierInfo *II, ModuleMacroInfo &Info);
2509
2510 DefMacroDirective *AllocateDefMacroDirective(MacroInfo *MI,
2511 SourceLocation Loc);
2512 UndefMacroDirective *AllocateUndefMacroDirective(SourceLocation UndefLoc);
2513 VisibilityMacroDirective *AllocateVisibilityMacroDirective(SourceLocation Loc,
2514 bool isPublic);
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526 void ReadMacroName(Token &MacroNameTok, MacroUse IsDefineUndef = MU_Other,
2527 bool *ShadowFlag = nullptr);
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538 MacroInfo *ReadOptionalMacroParameterListAndBody(
2539 const Token &MacroNameTok, bool ImmediatelyAfterHeaderGuard);
2540
2541
2542
2543
2544
2545 bool ReadMacroParameterList(MacroInfo *MI, Token& LastTok);
2546
2547
2548
2549
2550
2551
2552 void SuggestTypoedDirective(const Token &Tok, StringRef Directive) const;
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562 void SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,
2563 SourceLocation IfTokenLoc,
2564 bool FoundNonSkipPortion, bool FoundElse,
2565 SourceLocation ElseLoc = SourceLocation());
2566
2567
2568
2569 struct DirectiveEvalResult {
2570
2571 std::optional<llvm::APSInt> Value;
2572
2573
2574 bool Conditional;
2575
2576
2577 bool IncludedUndefinedIds;
2578
2579
2580 SourceRange ExprRange;
2581 };
2582
2583
2584
2585
2586
2587 DirectiveEvalResult EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro,
2588 bool CheckForEoD = true);
2589
2590
2591
2592
2593
2594
2595
2596 DirectiveEvalResult EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro,
2597 Token &Tok,
2598 bool &EvaluatedDefined,
2599 bool CheckForEoD = true);
2600
2601
2602
2603
2604
2605 EmbedResult EvaluateHasEmbed(Token &Tok, IdentifierInfo *II);
2606
2607
2608
2609
2610 bool EvaluateHasInclude(Token &Tok, IdentifierInfo *II);
2611
2612
2613
2614
2615 bool EvaluateHasIncludeNext(Token &Tok, IdentifierInfo *II);
2616
2617
2618 std::pair<ConstSearchDirIterator, const FileEntry *>
2619 getIncludeNextStart(const Token &IncludeNextTok) const;
2620
2621
2622
2623 void RegisterBuiltinPragmas();
2624
2625
2626
2627 IdentifierInfo *RegisterBuiltinMacro(const char *Name) {
2628
2629 IdentifierInfo *Id = getIdentifierInfo(Name);
2630
2631
2632 MacroInfo *MI = AllocateMacroInfo(SourceLocation());
2633 MI->setIsBuiltinMacro();
2634 appendDefMacroDirective(Id, MI);
2635 return Id;
2636 }
2637
2638
2639 void RegisterBuiltinMacros();
2640
2641
2642
2643
2644 bool HandleMacroExpandedIdentifier(Token &Identifier, const MacroDefinition &MD);
2645
2646
2647
2648
2649
2650
2651 Token *cacheMacroExpandedTokens(TokenLexer *tokLexer,
2652 ArrayRef<Token> tokens);
2653
2654 void removeCachedMacroExpandedTokensOfLastLexer();
2655
2656
2657
2658 MacroArgs *ReadMacroCallArgumentList(Token &MacroName, MacroInfo *MI,
2659 SourceLocation &MacroEnd);
2660
2661
2662
2663 void ExpandBuiltinMacro(Token &Tok);
2664
2665
2666
2667
2668 void Handle_Pragma(Token &Tok);
2669
2670
2671
2672 void HandleMicrosoft__pragma(Token &Tok);
2673
2674
2675
2676 void EnterSourceFileWithLexer(Lexer *TheLexer, ConstSearchDirIterator Dir);
2677
2678
2679 void setPredefinesFileID(FileID FID) {
2680 assert(PredefinesFileID.isInvalid() && "PredefinesFileID already set!");
2681 PredefinesFileID = FID;
2682 }
2683
2684
2685 void setPCHThroughHeaderFileID(FileID FID);
2686
2687
2688
2689 static bool IsFileLexer(const Lexer* L, const PreprocessorLexer* P) {
2690 return L ? !L->isPragmaLexer() : P != nullptr;
2691 }
2692
2693 static bool IsFileLexer(const IncludeStackInfo& I) {
2694 return IsFileLexer(I.TheLexer.get(), I.ThePPLexer);
2695 }
2696
2697 bool IsFileLexer() const {
2698 return IsFileLexer(CurLexer.get(), CurPPLexer);
2699 }
2700
2701
2702
2703 void CachingLex(Token &Result);
2704
2705 bool InCachingLexMode() const {
2706
2707
2708 return !CurPPLexer && !CurTokenLexer && !IncludeMacroStack.empty();
2709 }
2710
2711 void EnterCachingLexMode();
2712 void EnterCachingLexModeUnchecked();
2713
2714 void ExitCachingLexMode() {
2715 if (InCachingLexMode())
2716 RemoveTopOfLexerStack();
2717 }
2718
2719 const Token &PeekAhead(unsigned N);
2720 void AnnotatePreviousCachedTokens(const Token &Tok);
2721
2722
2723
2724
2725
2726 void HandleLineDirective();
2727 void HandleDigitDirective(Token &Tok);
2728 void HandleUserDiagnosticDirective(Token &Tok, bool isWarning);
2729 void HandleIdentSCCSDirective(Token &Tok);
2730 void HandleMacroPublicDirective(Token &Tok);
2731 void HandleMacroPrivateDirective();
2732
2733
2734
2735 struct ImportAction {
2736 enum ActionKind {
2737 None,
2738 ModuleBegin,
2739 ModuleImport,
2740 HeaderUnitImport,
2741 SkippedModuleImport,
2742 Failure,
2743 } Kind;
2744 Module *ModuleForHeader = nullptr;
2745
2746 ImportAction(ActionKind AK, Module *Mod = nullptr)
2747 : Kind(AK), ModuleForHeader(Mod) {
2748 assert((AK == None || Mod || AK == Failure) &&
2749 "no module for module action");
2750 }
2751 };
2752
2753 OptionalFileEntryRef LookupHeaderIncludeOrImport(
2754 ConstSearchDirIterator *CurDir, StringRef &Filename,
2755 SourceLocation FilenameLoc, CharSourceRange FilenameRange,
2756 const Token &FilenameTok, bool &IsFrameworkFound, bool IsImportDecl,
2757 bool &IsMapped, ConstSearchDirIterator LookupFrom,
2758 const FileEntry *LookupFromFile, StringRef &LookupFilename,
2759 SmallVectorImpl<char> &RelativePath, SmallVectorImpl<char> &SearchPath,
2760 ModuleMap::KnownHeader &SuggestedModule, bool isAngled);
2761
2762 void HandleEmbedDirective(SourceLocation HashLoc, Token &Tok,
2763 const FileEntry *LookupFromFile = nullptr);
2764 void HandleEmbedDirectiveImpl(SourceLocation HashLoc,
2765 const LexEmbedParametersResult &Params,
2766 StringRef BinaryContents);
2767
2768
2769 void HandleIncludeDirective(SourceLocation HashLoc, Token &Tok,
2770 ConstSearchDirIterator LookupFrom = nullptr,
2771 const FileEntry *LookupFromFile = nullptr);
2772 ImportAction
2773 HandleHeaderIncludeOrImport(SourceLocation HashLoc, Token &IncludeTok,
2774 Token &FilenameTok, SourceLocation EndLoc,
2775 ConstSearchDirIterator LookupFrom = nullptr,
2776 const FileEntry *LookupFromFile = nullptr);
2777 void HandleIncludeNextDirective(SourceLocation HashLoc, Token &Tok);
2778 void HandleIncludeMacrosDirective(SourceLocation HashLoc, Token &Tok);
2779 void HandleImportDirective(SourceLocation HashLoc, Token &Tok);
2780 void HandleMicrosoftImportDirective(Token &Tok);
2781
2782 public:
2783
2784
2785
2786 static bool checkModuleIsAvailable(const LangOptions &LangOpts,
2787 const TargetInfo &TargetInfo,
2788 const Module &M, DiagnosticsEngine &Diags);
2789
2790
2791
2792
2793
2794 Module *getModuleForLocation(SourceLocation Loc, bool AllowTextual);
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810 OptionalFileEntryRef getHeaderToIncludeForDiagnostics(SourceLocation IncLoc,
2811 SourceLocation MLoc);
2812
2813 bool isRecordingPreamble() const {
2814 return PreambleConditionalStack.isRecording();
2815 }
2816
2817 bool hasRecordedPreamble() const {
2818 return PreambleConditionalStack.hasRecordedPreamble();
2819 }
2820
2821 ArrayRef<PPConditionalInfo> getPreambleConditionalStack() const {
2822 return PreambleConditionalStack.getStack();
2823 }
2824
2825 void setRecordedPreambleConditionalStack(ArrayRef<PPConditionalInfo> s) {
2826 PreambleConditionalStack.setStack(s);
2827 }
2828
2829 void setReplayablePreambleConditionalStack(
2830 ArrayRef<PPConditionalInfo> s, std::optional<PreambleSkipInfo> SkipInfo) {
2831 PreambleConditionalStack.startReplaying();
2832 PreambleConditionalStack.setStack(s);
2833 PreambleConditionalStack.SkipInfo = SkipInfo;
2834 }
2835
2836 std::optional<PreambleSkipInfo> getPreambleSkipInfo() const {
2837 return PreambleConditionalStack.SkipInfo;
2838 }
2839
2840 private:
2841
2842
2843 void replayPreambleConditionalStack();
2844
2845
2846 void HandleDefineDirective(Token &Tok, bool ImmediatelyAfterHeaderGuard);
2847 void HandleUndefDirective();
2848
2849
2850 void HandleIfdefDirective(Token &Result, const Token &HashToken,
2851 bool isIfndef, bool ReadAnyTokensBeforeDirective);
2852 void HandleIfDirective(Token &IfToken, const Token &HashToken,
2853 bool ReadAnyTokensBeforeDirective);
2854 void HandleEndifDirective(Token &EndifToken);
2855 void HandleElseDirective(Token &Result, const Token &HashToken);
2856 void HandleElifFamilyDirective(Token &ElifToken, const Token &HashToken,
2857 tok::PPKeywordKind Kind);
2858
2859
2860 void HandlePragmaDirective(PragmaIntroducer Introducer);
2861
2862 public:
2863 void HandlePragmaOnce(Token &OnceTok);
2864 void HandlePragmaMark(Token &MarkTok);
2865 void HandlePragmaPoison();
2866 void HandlePragmaSystemHeader(Token &SysHeaderTok);
2867 void HandlePragmaDependency(Token &DependencyTok);
2868 void HandlePragmaPushMacro(Token &Tok);
2869 void HandlePragmaPopMacro(Token &Tok);
2870 void HandlePragmaIncludeAlias(Token &Tok);
2871 void HandlePragmaModuleBuild(Token &Tok);
2872 void HandlePragmaHdrstop(Token &Tok);
2873 IdentifierInfo *ParsePragmaPushOrPopMacro(Token &Tok);
2874
2875
2876
2877 bool HandleComment(Token &result, SourceRange Comment);
2878
2879
2880
2881 void markMacroAsUsed(MacroInfo *MI);
2882
2883 void addMacroDeprecationMsg(const IdentifierInfo *II, std::string Msg,
2884 SourceLocation AnnotationLoc) {
2885 AnnotationInfos[II].DeprecationInfo =
2886 MacroAnnotationInfo{AnnotationLoc, std::move(Msg)};
2887 }
2888
2889 void addRestrictExpansionMsg(const IdentifierInfo *II, std::string Msg,
2890 SourceLocation AnnotationLoc) {
2891 AnnotationInfos[II].RestrictExpansionInfo =
2892 MacroAnnotationInfo{AnnotationLoc, std::move(Msg)};
2893 }
2894
2895 void addFinalLoc(const IdentifierInfo *II, SourceLocation AnnotationLoc) {
2896 AnnotationInfos[II].FinalAnnotationLoc = AnnotationLoc;
2897 }
2898
2899 const MacroAnnotations &getMacroAnnotations(const IdentifierInfo *II) const {
2900 return AnnotationInfos.find(II)->second;
2901 }
2902
2903 void emitMacroExpansionWarnings(const Token &Identifier,
2904 bool IsIfnDef = false) const {
2905 IdentifierInfo *Info = Identifier.getIdentifierInfo();
2906 if (Info->isDeprecatedMacro())
2907 emitMacroDeprecationWarning(Identifier);
2908
2909 if (Info->isRestrictExpansion() &&
2910 !SourceMgr.isInMainFile(Identifier.getLocation()))
2911 emitRestrictExpansionWarning(Identifier);
2912
2913 if (!IsIfnDef) {
2914 if (Info->getName() == "INFINITY" && getLangOpts().NoHonorInfs)
2915 emitRestrictInfNaNWarning(Identifier, 0);
2916 if (Info->getName() == "NAN" && getLangOpts().NoHonorNaNs)
2917 emitRestrictInfNaNWarning(Identifier, 1);
2918 }
2919 }
2920
2921 static void processPathForFileMacro(SmallVectorImpl<char> &Path,
2922 const LangOptions &LangOpts,
2923 const TargetInfo &TI);
2924
2925 static void processPathToFileName(SmallVectorImpl<char> &FileName,
2926 const PresumedLoc &PLoc,
2927 const LangOptions &LangOpts,
2928 const TargetInfo &TI);
2929
2930 private:
2931 void emitMacroDeprecationWarning(const Token &Identifier) const;
2932 void emitRestrictExpansionWarning(const Token &Identifier) const;
2933 void emitFinalMacroWarning(const Token &Identifier, bool IsUndef) const;
2934 void emitRestrictInfNaNWarning(const Token &Identifier,
2935 unsigned DiagSelection) const;
2936
2937
2938
2939
2940 bool InSafeBufferOptOutRegion = false;
2941
2942
2943
2944
2945 SourceLocation CurrentSafeBufferOptOutStart;
2946
2947 using SafeBufferOptOutRegionsTy =
2948 SmallVector<std::pair<SourceLocation, SourceLocation>, 16>;
2949
2950
2951
2952 SafeBufferOptOutRegionsTy SafeBufferOptOutMap;
2953
2954
2955
2956 struct {
2957
2958
2959 llvm::DenseMap<FileID, SafeBufferOptOutRegionsTy> LoadedRegions;
2960
2961
2962
2963 SafeBufferOptOutRegionsTy &
2964 findAndConsLoadedOptOutMap(SourceLocation Loc, SourceManager &SrcMgr) {
2965 return LoadedRegions[SrcMgr.getUniqueLoadedASTFileID(Loc)];
2966 }
2967
2968
2969
2970
2971 const SafeBufferOptOutRegionsTy *
2972 lookupLoadedOptOutMap(SourceLocation Loc,
2973 const SourceManager &SrcMgr) const {
2974 FileID FID = SrcMgr.getUniqueLoadedASTFileID(Loc);
2975 auto Iter = LoadedRegions.find(FID);
2976
2977 if (Iter == LoadedRegions.end())
2978 return nullptr;
2979 return &Iter->getSecond();
2980 }
2981 } LoadedSafeBufferOptOutMap;
2982
2983 public:
2984
2985
2986 bool isSafeBufferOptOut(const SourceManager&SourceMgr, const SourceLocation &Loc) const;
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998 bool enterOrExitSafeBufferOptOutRegion(bool isEnter,
2999 const SourceLocation &Loc);
3000
3001
3002
3003 bool isPPInSafeBufferOptOutRegion();
3004
3005
3006
3007
3008
3009
3010 bool isPPInSafeBufferOptOutRegion(SourceLocation &StartLoc);
3011
3012
3013
3014
3015 SmallVector<SourceLocation, 64> serializeSafeBufferOptOutMap() const;
3016
3017
3018
3019
3020
3021 bool setDeserializedSafeBufferOptOutMap(
3022 const SmallVectorImpl<SourceLocation> &SrcLocSeqs);
3023
3024 private:
3025
3026
3027 static bool CLK_Lexer(Preprocessor &P, Token &Result) {
3028 return P.CurLexer->Lex(Result);
3029 }
3030 static bool CLK_TokenLexer(Preprocessor &P, Token &Result) {
3031 return P.CurTokenLexer->Lex(Result);
3032 }
3033 static bool CLK_CachingLexer(Preprocessor &P, Token &Result) {
3034 P.CachingLex(Result);
3035 return true;
3036 }
3037 static bool CLK_DependencyDirectivesLexer(Preprocessor &P, Token &Result) {
3038 return P.CurLexer->LexDependencyDirectiveToken(Result);
3039 }
3040 static bool CLK_LexAfterModuleImport(Preprocessor &P, Token &Result) {
3041 return P.LexAfterModuleImport(Result);
3042 }
3043 };
3044
3045
3046
3047 class CommentHandler {
3048 public:
3049 virtual ~CommentHandler();
3050
3051
3052
3053 virtual bool HandleComment(Preprocessor &PP, SourceRange Comment) = 0;
3054 };
3055
3056
3057
3058 class EmptylineHandler {
3059 public:
3060 virtual ~EmptylineHandler();
3061
3062
3063 virtual void HandleEmptyline(SourceRange Range) = 0;
3064 };
3065
3066
3067
3068 struct EmbedAnnotationData {
3069 StringRef BinaryData;
3070 };
3071
3072
3073 using PragmaHandlerRegistry = llvm::Registry<PragmaHandler>;
3074
3075 }
3076
3077 namespace llvm {
3078 extern template class CLANG_TEMPLATE_ABI Registry<clang::PragmaHandler>;
3079 }
3080
3081 #endif