File indexing completed on 2026-05-10 08:36:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
0015 #define LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
0016
0017 #include "clang/Basic/IdentifierTable.h"
0018 #include "clang/Basic/LLVM.h"
0019 #include "clang/Basic/SourceLocation.h"
0020 #include "clang/Lex/PPCallbacks.h"
0021 #include "llvm/ADT/DenseMap.h"
0022 #include "llvm/ADT/PointerUnion.h"
0023 #include "llvm/ADT/StringRef.h"
0024 #include "llvm/ADT/iterator.h"
0025 #include "llvm/ADT/iterator_range.h"
0026 #include "llvm/Support/Allocator.h"
0027 #include "llvm/Support/Compiler.h"
0028 #include <cassert>
0029 #include <cstddef>
0030 #include <iterator>
0031 #include <optional>
0032 #include <utility>
0033 #include <vector>
0034
0035 namespace clang {
0036
0037 class PreprocessingRecord;
0038
0039 }
0040
0041
0042 void *operator new(size_t bytes, clang::PreprocessingRecord &PR,
0043 unsigned alignment = 8) noexcept;
0044
0045
0046 void operator delete(void *ptr, clang::PreprocessingRecord &PR,
0047 unsigned) noexcept;
0048
0049 namespace clang {
0050
0051 class IdentifierInfo;
0052 class MacroInfo;
0053 class SourceManager;
0054 class Token;
0055
0056
0057
0058 class PreprocessedEntity {
0059 public:
0060
0061 enum EntityKind {
0062
0063 InvalidKind,
0064
0065
0066 MacroExpansionKind,
0067
0068
0069
0070
0071
0072 MacroDefinitionKind,
0073
0074
0075
0076 InclusionDirectiveKind,
0077
0078
0079
0080 FirstPreprocessingDirective = MacroDefinitionKind,
0081 LastPreprocessingDirective = InclusionDirectiveKind
0082 };
0083
0084 private:
0085
0086 EntityKind Kind;
0087
0088
0089 SourceRange Range;
0090
0091 protected:
0092 friend class PreprocessingRecord;
0093
0094 PreprocessedEntity(EntityKind Kind, SourceRange Range)
0095 : Kind(Kind), Range(Range) {}
0096
0097 public:
0098
0099 EntityKind getKind() const { return Kind; }
0100
0101
0102
0103 SourceRange getSourceRange() const LLVM_READONLY { return Range; }
0104
0105
0106
0107 bool isInvalid() const { return Kind == InvalidKind; }
0108
0109
0110
0111 void *operator new(size_t bytes, PreprocessingRecord &PR,
0112 unsigned alignment = 8) noexcept {
0113 return ::operator new(bytes, PR, alignment);
0114 }
0115
0116 void *operator new(size_t bytes, void *mem) noexcept { return mem; }
0117
0118 void operator delete(void *ptr, PreprocessingRecord &PR,
0119 unsigned alignment) noexcept {
0120 return ::operator delete(ptr, PR, alignment);
0121 }
0122
0123 void operator delete(void *, std::size_t) noexcept {}
0124 void operator delete(void *, void *) noexcept {}
0125
0126 private:
0127
0128 void *operator new(size_t bytes) noexcept;
0129 void operator delete(void *data) noexcept;
0130 };
0131
0132
0133 class PreprocessingDirective : public PreprocessedEntity {
0134 public:
0135 PreprocessingDirective(EntityKind Kind, SourceRange Range)
0136 : PreprocessedEntity(Kind, Range) {}
0137
0138
0139 static bool classof(const PreprocessedEntity *PD) {
0140 return PD->getKind() >= FirstPreprocessingDirective &&
0141 PD->getKind() <= LastPreprocessingDirective;
0142 }
0143 };
0144
0145
0146 class MacroDefinitionRecord : public PreprocessingDirective {
0147
0148 const IdentifierInfo *Name;
0149
0150 public:
0151 explicit MacroDefinitionRecord(const IdentifierInfo *Name,
0152 SourceRange Range)
0153 : PreprocessingDirective(MacroDefinitionKind, Range), Name(Name) {}
0154
0155
0156 const IdentifierInfo *getName() const { return Name; }
0157
0158
0159 SourceLocation getLocation() const { return getSourceRange().getBegin(); }
0160
0161
0162 static bool classof(const PreprocessedEntity *PE) {
0163 return PE->getKind() == MacroDefinitionKind;
0164 }
0165 };
0166
0167
0168 class MacroExpansion : public PreprocessedEntity {
0169
0170
0171 llvm::PointerUnion<IdentifierInfo *, MacroDefinitionRecord *> NameOrDef;
0172
0173 public:
0174 MacroExpansion(IdentifierInfo *BuiltinName, SourceRange Range)
0175 : PreprocessedEntity(MacroExpansionKind, Range),
0176 NameOrDef(BuiltinName) {}
0177
0178 MacroExpansion(MacroDefinitionRecord *Definition, SourceRange Range)
0179 : PreprocessedEntity(MacroExpansionKind, Range), NameOrDef(Definition) {
0180 }
0181
0182
0183 bool isBuiltinMacro() const { return isa<IdentifierInfo *>(NameOrDef); }
0184
0185
0186 const IdentifierInfo *getName() const {
0187 if (MacroDefinitionRecord *Def = getDefinition())
0188 return Def->getName();
0189 return cast<IdentifierInfo *>(NameOrDef);
0190 }
0191
0192
0193
0194 MacroDefinitionRecord *getDefinition() const {
0195 return NameOrDef.dyn_cast<MacroDefinitionRecord *>();
0196 }
0197
0198
0199 static bool classof(const PreprocessedEntity *PE) {
0200 return PE->getKind() == MacroExpansionKind;
0201 }
0202 };
0203
0204
0205
0206 class InclusionDirective : public PreprocessingDirective {
0207 public:
0208
0209
0210 enum InclusionKind {
0211
0212 Include,
0213
0214
0215 Import,
0216
0217
0218 IncludeNext,
0219
0220
0221 IncludeMacros
0222 };
0223
0224 private:
0225
0226
0227 StringRef FileName;
0228
0229
0230
0231 LLVM_PREFERRED_TYPE(bool)
0232 unsigned InQuotes : 1;
0233
0234
0235
0236
0237 LLVM_PREFERRED_TYPE(InclusionKind)
0238 unsigned Kind : 2;
0239
0240
0241
0242 LLVM_PREFERRED_TYPE(bool)
0243 unsigned ImportedModule : 1;
0244
0245
0246 OptionalFileEntryRef File;
0247
0248 public:
0249 InclusionDirective(PreprocessingRecord &PPRec, InclusionKind Kind,
0250 StringRef FileName, bool InQuotes, bool ImportedModule,
0251 OptionalFileEntryRef File, SourceRange Range);
0252
0253
0254 InclusionKind getKind() const { return static_cast<InclusionKind>(Kind); }
0255
0256
0257 StringRef getFileName() const { return FileName; }
0258
0259
0260
0261 bool wasInQuotes() const { return InQuotes; }
0262
0263
0264
0265 bool importedModule() const { return ImportedModule; }
0266
0267
0268
0269 OptionalFileEntryRef getFile() const { return File; }
0270
0271
0272 static bool classof(const PreprocessedEntity *PE) {
0273 return PE->getKind() == InclusionDirectiveKind;
0274 }
0275 };
0276
0277
0278
0279 class ExternalPreprocessingRecordSource {
0280 public:
0281 virtual ~ExternalPreprocessingRecordSource();
0282
0283
0284
0285
0286
0287 virtual PreprocessedEntity *ReadPreprocessedEntity(unsigned Index) = 0;
0288
0289
0290
0291 virtual std::pair<unsigned, unsigned>
0292 findPreprocessedEntitiesInRange(SourceRange Range) = 0;
0293
0294
0295
0296 virtual std::optional<bool> isPreprocessedEntityInFileID(unsigned Index,
0297 FileID FID) {
0298 return std::nullopt;
0299 }
0300
0301
0302 virtual SourceRange ReadSkippedRange(unsigned Index) = 0;
0303 };
0304
0305
0306
0307
0308 class PreprocessingRecord : public PPCallbacks {
0309 SourceManager &SourceMgr;
0310
0311
0312 llvm::BumpPtrAllocator BumpAlloc;
0313
0314
0315
0316 std::vector<PreprocessedEntity *> PreprocessedEntities;
0317
0318
0319
0320
0321
0322
0323 std::vector<PreprocessedEntity *> LoadedPreprocessedEntities;
0324
0325
0326 std::vector<SourceRange> SkippedRanges;
0327
0328 bool SkippedRangesAllLoaded = true;
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339 class PPEntityID {
0340 friend class PreprocessingRecord;
0341
0342 int ID = 0;
0343
0344 explicit PPEntityID(int ID) : ID(ID) {}
0345
0346 public:
0347 PPEntityID() = default;
0348 };
0349
0350 static PPEntityID getPPEntityID(unsigned Index, bool isLoaded) {
0351 return isLoaded ? PPEntityID(-int(Index)-1) : PPEntityID(Index+1);
0352 }
0353
0354
0355 llvm::DenseMap<const MacroInfo *, MacroDefinitionRecord *> MacroDefinitions;
0356
0357
0358 ExternalPreprocessingRecordSource *ExternalSource = nullptr;
0359
0360
0361 PreprocessedEntity *getPreprocessedEntity(PPEntityID PPID);
0362
0363
0364 PreprocessedEntity *getLoadedPreprocessedEntity(unsigned Index);
0365
0366
0367
0368 unsigned getNumLoadedPreprocessedEntities() const {
0369 return LoadedPreprocessedEntities.size();
0370 }
0371
0372
0373
0374 std::pair<unsigned, unsigned>
0375 findLocalPreprocessedEntitiesInRange(SourceRange Range) const;
0376 unsigned findBeginLocalPreprocessedEntity(SourceLocation Loc) const;
0377 unsigned findEndLocalPreprocessedEntity(SourceLocation Loc) const;
0378
0379
0380
0381
0382
0383 unsigned allocateLoadedEntities(unsigned NumEntities);
0384
0385
0386
0387
0388
0389
0390 unsigned allocateSkippedRanges(unsigned NumRanges);
0391
0392
0393 void ensureSkippedRangesLoaded();
0394
0395
0396 void RegisterMacroDefinition(MacroInfo *Macro, MacroDefinitionRecord *Def);
0397
0398 public:
0399
0400 explicit PreprocessingRecord(SourceManager &SM);
0401
0402
0403 void *Allocate(unsigned Size, unsigned Align = 8) {
0404 return BumpAlloc.Allocate(Size, Align);
0405 }
0406
0407
0408 void Deallocate(void *Ptr) {}
0409
0410 size_t getTotalMemory() const;
0411
0412 SourceManager &getSourceManager() const { return SourceMgr; }
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430 class iterator : public llvm::iterator_adaptor_base<
0431 iterator, int, std::random_access_iterator_tag,
0432 PreprocessedEntity *, int, PreprocessedEntity *,
0433 PreprocessedEntity *> {
0434 friend class PreprocessingRecord;
0435
0436 PreprocessingRecord *Self;
0437
0438 iterator(PreprocessingRecord *Self, int Position)
0439 : iterator::iterator_adaptor_base(Position), Self(Self) {}
0440
0441 public:
0442 iterator() : iterator(nullptr, 0) {}
0443
0444 PreprocessedEntity *operator*() const {
0445 bool isLoaded = this->I < 0;
0446 unsigned Index = isLoaded ?
0447 Self->LoadedPreprocessedEntities.size() + this->I : this->I;
0448 PPEntityID ID = Self->getPPEntityID(Index, isLoaded);
0449 return Self->getPreprocessedEntity(ID);
0450 }
0451 PreprocessedEntity *operator->() const { return **this; }
0452 };
0453
0454
0455 iterator begin() {
0456 return iterator(this, -(int)LoadedPreprocessedEntities.size());
0457 }
0458
0459
0460 iterator end() {
0461 return iterator(this, PreprocessedEntities.size());
0462 }
0463
0464
0465 iterator local_begin() {
0466 return iterator(this, 0);
0467 }
0468
0469
0470 iterator local_end() {
0471 return iterator(this, PreprocessedEntities.size());
0472 }
0473
0474
0475
0476 llvm::iterator_range<iterator> getIteratorsForLoadedRange(unsigned start,
0477 unsigned count) {
0478 unsigned end = start + count;
0479 assert(end <= LoadedPreprocessedEntities.size());
0480 return llvm::make_range(
0481 iterator(this, int(start) - LoadedPreprocessedEntities.size()),
0482 iterator(this, int(end) - LoadedPreprocessedEntities.size()));
0483 }
0484
0485
0486
0487
0488
0489 llvm::iterator_range<iterator>
0490 getPreprocessedEntitiesInRange(SourceRange R);
0491
0492
0493
0494
0495
0496
0497
0498
0499 bool isEntityInFileID(iterator PPEI, FileID FID);
0500
0501
0502 PPEntityID addPreprocessedEntity(PreprocessedEntity *Entity);
0503
0504
0505 void SetExternalSource(ExternalPreprocessingRecordSource &Source);
0506
0507
0508 ExternalPreprocessingRecordSource *getExternalSource() const {
0509 return ExternalSource;
0510 }
0511
0512
0513
0514 MacroDefinitionRecord *findMacroDefinition(const MacroInfo *MI);
0515
0516
0517 const std::vector<SourceRange> &getSkippedRanges() {
0518 ensureSkippedRangesLoaded();
0519 return SkippedRanges;
0520 }
0521
0522 private:
0523 friend class ASTReader;
0524 friend class ASTWriter;
0525
0526 void MacroExpands(const Token &Id, const MacroDefinition &MD,
0527 SourceRange Range, const MacroArgs *Args) override;
0528 void MacroDefined(const Token &Id, const MacroDirective *MD) override;
0529 void MacroUndefined(const Token &Id, const MacroDefinition &MD,
0530 const MacroDirective *Undef) override;
0531 void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
0532 StringRef FileName, bool IsAngled,
0533 CharSourceRange FilenameRange,
0534 OptionalFileEntryRef File, StringRef SearchPath,
0535 StringRef RelativePath,
0536 const Module *SuggestedModule, bool ModuleImported,
0537 SrcMgr::CharacteristicKind FileType) override;
0538 void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
0539 const MacroDefinition &MD) override;
0540 void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
0541 const MacroDefinition &MD) override;
0542
0543 using PPCallbacks::Elifdef;
0544 using PPCallbacks::Elifndef;
0545 void Elifdef(SourceLocation Loc, const Token &MacroNameTok,
0546 const MacroDefinition &MD) override;
0547 void Elifndef(SourceLocation Loc, const Token &MacroNameTok,
0548 const MacroDefinition &MD) override;
0549
0550
0551 void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
0552 SourceRange Range) override;
0553
0554 void SourceRangeSkipped(SourceRange Range,
0555 SourceLocation EndifLoc) override;
0556
0557 void addMacroExpansion(const Token &Id, const MacroInfo *MI,
0558 SourceRange Range);
0559
0560
0561
0562 struct {
0563 SourceRange Range;
0564 std::pair<int, int> Result;
0565 } CachedRangeQuery;
0566
0567 std::pair<int, int> getPreprocessedEntitiesInRangeSlow(SourceRange R);
0568 };
0569
0570 }
0571
0572 inline void *operator new(size_t bytes, clang::PreprocessingRecord &PR,
0573 unsigned alignment) noexcept {
0574 return PR.Allocate(bytes, alignment);
0575 }
0576
0577 inline void operator delete(void *ptr, clang::PreprocessingRecord &PR,
0578 unsigned) noexcept {
0579 PR.Deallocate(ptr);
0580 }
0581
0582 #endif