1 //===- PreprocessingRecord.h - Record of Preprocessing ----------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines the PreprocessingRecord class, which maintains a record 10 // of what occurred during preprocessing. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_LEX_PREPROCESSINGRECORD_H 15 #define LLVM_CLANG_LEX_PREPROCESSINGRECORD_H 16 17 #include "clang/Basic/IdentifierTable.h" 18 #include "clang/Basic/LLVM.h" 19 #include "clang/Basic/SourceLocation.h" 20 #include "clang/Lex/PPCallbacks.h" 21 #include "llvm/ADT/DenseMap.h" 22 #include "llvm/ADT/None.h" 23 #include "llvm/ADT/Optional.h" 24 #include "llvm/ADT/PointerUnion.h" 25 #include "llvm/ADT/StringRef.h" 26 #include "llvm/ADT/iterator.h" 27 #include "llvm/ADT/iterator_range.h" 28 #include "llvm/Support/Allocator.h" 29 #include "llvm/Support/Compiler.h" 30 #include <cassert> 31 #include <cstddef> 32 #include <iterator> 33 #include <utility> 34 #include <vector> 35 36 namespace clang { 37 38 class PreprocessingRecord; 39 40 } // namespace clang 41 42 /// Allocates memory within a Clang preprocessing record. 43 void *operator new(size_t bytes, clang::PreprocessingRecord &PR, 44 unsigned alignment = 8) noexcept; 45 46 /// Frees memory allocated in a Clang preprocessing record. 47 void operator delete(void *ptr, clang::PreprocessingRecord &PR, 48 unsigned) noexcept; 49 50 namespace clang { 51 52 class IdentifierInfo; 53 class MacroInfo; 54 class SourceManager; 55 class Token; 56 57 /// Base class that describes a preprocessed entity, which may be a 58 /// preprocessor directive or macro expansion. 59 class PreprocessedEntity { 60 public: 61 /// The kind of preprocessed entity an object describes. 62 enum EntityKind { 63 /// Indicates a problem trying to load the preprocessed entity. 64 InvalidKind, 65 66 /// A macro expansion. 67 MacroExpansionKind, 68 69 /// \defgroup Preprocessing directives 70 /// @{ 71 72 /// A macro definition. 73 MacroDefinitionKind, 74 75 /// An inclusion directive, such as \c \#include, \c 76 /// \#import, or \c \#include_next. 77 InclusionDirectiveKind, 78 79 /// @} 80 81 FirstPreprocessingDirective = MacroDefinitionKind, 82 LastPreprocessingDirective = InclusionDirectiveKind 83 }; 84 85 private: 86 /// The kind of preprocessed entity that this object describes. 87 EntityKind Kind; 88 89 /// The source range that covers this preprocessed entity. 90 SourceRange Range; 91 92 protected: 93 friend class PreprocessingRecord; 94 95 PreprocessedEntity(EntityKind Kind, SourceRange Range) 96 : Kind(Kind), Range(Range) {} 97 98 public: 99 /// Retrieve the kind of preprocessed entity stored in this object. 100 EntityKind getKind() const { return Kind; } 101 102 /// Retrieve the source range that covers this entire preprocessed 103 /// entity. 104 SourceRange getSourceRange() const LLVM_READONLY { return Range; } 105 106 /// Returns true if there was a problem loading the preprocessed 107 /// entity. 108 bool isInvalid() const { return Kind == InvalidKind; } 109 110 // Only allow allocation of preprocessed entities using the allocator 111 // in PreprocessingRecord or by doing a placement new. 112 void *operator new(size_t bytes, PreprocessingRecord &PR, 113 unsigned alignment = 8) noexcept { 114 return ::operator new(bytes, PR, alignment); 115 } 116 117 void *operator new(size_t bytes, void *mem) noexcept { return mem; } 118 119 void operator delete(void *ptr, PreprocessingRecord &PR, 120 unsigned alignment) noexcept { 121 return ::operator delete(ptr, PR, alignment); 122 } 123 124 void operator delete(void *, std::size_t) noexcept {} 125 void operator delete(void *, void *) noexcept {} 126 127 private: 128 // Make vanilla 'new' and 'delete' illegal for preprocessed entities. 129 void *operator new(size_t bytes) noexcept; 130 void operator delete(void *data) noexcept; 131 }; 132 133 /// Records the presence of a preprocessor directive. 134 class PreprocessingDirective : public PreprocessedEntity { 135 public: 136 PreprocessingDirective(EntityKind Kind, SourceRange Range) 137 : PreprocessedEntity(Kind, Range) {} 138 139 // Implement isa/cast/dyncast/etc. 140 static bool classof(const PreprocessedEntity *PD) { 141 return PD->getKind() >= FirstPreprocessingDirective && 142 PD->getKind() <= LastPreprocessingDirective; 143 } 144 }; 145 146 /// Record the location of a macro definition. 147 class MacroDefinitionRecord : public PreprocessingDirective { 148 /// The name of the macro being defined. 149 const IdentifierInfo *Name; 150 151 public: 152 explicit MacroDefinitionRecord(const IdentifierInfo *Name, 153 SourceRange Range) 154 : PreprocessingDirective(MacroDefinitionKind, Range), Name(Name) {} 155 156 /// Retrieve the name of the macro being defined. 157 const IdentifierInfo *getName() const { return Name; } 158 159 /// Retrieve the location of the macro name in the definition. 160 SourceLocation getLocation() const { return getSourceRange().getBegin(); } 161 162 // Implement isa/cast/dyncast/etc. 163 static bool classof(const PreprocessedEntity *PE) { 164 return PE->getKind() == MacroDefinitionKind; 165 } 166 }; 167 168 /// Records the location of a macro expansion. 169 class MacroExpansion : public PreprocessedEntity { 170 /// The definition of this macro or the name of the macro if it is 171 /// a builtin macro. 172 llvm::PointerUnion<IdentifierInfo *, MacroDefinitionRecord *> NameOrDef; 173 174 public: 175 MacroExpansion(IdentifierInfo *BuiltinName, SourceRange Range) 176 : PreprocessedEntity(MacroExpansionKind, Range), 177 NameOrDef(BuiltinName) {} 178 179 MacroExpansion(MacroDefinitionRecord *Definition, SourceRange Range) 180 : PreprocessedEntity(MacroExpansionKind, Range), NameOrDef(Definition) { 181 } 182 183 /// True if it is a builtin macro. 184 bool isBuiltinMacro() const { return NameOrDef.is<IdentifierInfo *>(); } 185 186 /// The name of the macro being expanded. 187 const IdentifierInfo *getName() const { 188 if (MacroDefinitionRecord *Def = getDefinition()) 189 return Def->getName(); 190 return NameOrDef.get<IdentifierInfo *>(); 191 } 192 193 /// The definition of the macro being expanded. May return null if 194 /// this is a builtin macro. 195 MacroDefinitionRecord *getDefinition() const { 196 return NameOrDef.dyn_cast<MacroDefinitionRecord *>(); 197 } 198 199 // Implement isa/cast/dyncast/etc. 200 static bool classof(const PreprocessedEntity *PE) { 201 return PE->getKind() == MacroExpansionKind; 202 } 203 }; 204 205 /// Record the location of an inclusion directive, such as an 206 /// \c \#include or \c \#import statement. 207 class InclusionDirective : public PreprocessingDirective { 208 public: 209 /// The kind of inclusion directives known to the 210 /// preprocessor. 211 enum InclusionKind { 212 /// An \c \#include directive. 213 Include, 214 215 /// An Objective-C \c \#import directive. 216 Import, 217 218 /// A GNU \c \#include_next directive. 219 IncludeNext, 220 221 /// A Clang \c \#__include_macros directive. 222 IncludeMacros 223 }; 224 225 private: 226 /// The name of the file that was included, as written in 227 /// the source. 228 StringRef FileName; 229 230 /// Whether the file name was in quotation marks; otherwise, it was 231 /// in angle brackets. 232 unsigned InQuotes : 1; 233 234 /// The kind of inclusion directive we have. 235 /// 236 /// This is a value of type InclusionKind. 237 unsigned Kind : 2; 238 239 /// Whether the inclusion directive was automatically turned into 240 /// a module import. 241 unsigned ImportedModule : 1; 242 243 /// The file that was included. 244 Optional<FileEntryRef> File; 245 246 public: 247 InclusionDirective(PreprocessingRecord &PPRec, InclusionKind Kind, 248 StringRef FileName, bool InQuotes, bool ImportedModule, 249 Optional<FileEntryRef> File, SourceRange Range); 250 251 /// Determine what kind of inclusion directive this is. 252 InclusionKind getKind() const { return static_cast<InclusionKind>(Kind); } 253 254 /// Retrieve the included file name as it was written in the source. 255 StringRef getFileName() const { return FileName; } 256 257 /// Determine whether the included file name was written in quotes; 258 /// otherwise, it was written in angle brackets. 259 bool wasInQuotes() const { return InQuotes; } 260 261 /// Determine whether the inclusion directive was automatically 262 /// turned into a module import. 263 bool importedModule() const { return ImportedModule; } 264 265 /// Retrieve the file entry for the actual file that was included 266 /// by this directive. 267 Optional<FileEntryRef> getFile() const { return File; } 268 269 // Implement isa/cast/dyncast/etc. 270 static bool classof(const PreprocessedEntity *PE) { 271 return PE->getKind() == InclusionDirectiveKind; 272 } 273 }; 274 275 /// An abstract class that should be subclassed by any external source 276 /// of preprocessing record entries. 277 class ExternalPreprocessingRecordSource { 278 public: 279 virtual ~ExternalPreprocessingRecordSource(); 280 281 /// Read a preallocated preprocessed entity from the external source. 282 /// 283 /// \returns null if an error occurred that prevented the preprocessed 284 /// entity from being loaded. 285 virtual PreprocessedEntity *ReadPreprocessedEntity(unsigned Index) = 0; 286 287 /// Returns a pair of [Begin, End) indices of preallocated 288 /// preprocessed entities that \p Range encompasses. 289 virtual std::pair<unsigned, unsigned> 290 findPreprocessedEntitiesInRange(SourceRange Range) = 0; 291 292 /// Optionally returns true or false if the preallocated preprocessed 293 /// entity with index \p Index came from file \p FID. 294 virtual Optional<bool> isPreprocessedEntityInFileID(unsigned Index, 295 FileID FID) { 296 return None; 297 } 298 299 /// Read a preallocated skipped range from the external source. 300 virtual SourceRange ReadSkippedRange(unsigned Index) = 0; 301 }; 302 303 /// A record of the steps taken while preprocessing a source file, 304 /// including the various preprocessing directives processed, macros 305 /// expanded, etc. 306 class PreprocessingRecord : public PPCallbacks { 307 SourceManager &SourceMgr; 308 309 /// Allocator used to store preprocessing objects. 310 llvm::BumpPtrAllocator BumpAlloc; 311 312 /// The set of preprocessed entities in this record, in order they 313 /// were seen. 314 std::vector<PreprocessedEntity *> PreprocessedEntities; 315 316 /// The set of preprocessed entities in this record that have been 317 /// loaded from external sources. 318 /// 319 /// The entries in this vector are loaded lazily from the external source, 320 /// and are referenced by the iterator using negative indices. 321 std::vector<PreprocessedEntity *> LoadedPreprocessedEntities; 322 323 /// The set of ranges that were skipped by the preprocessor, 324 std::vector<SourceRange> SkippedRanges; 325 326 bool SkippedRangesAllLoaded = true; 327 328 /// Global (loaded or local) ID for a preprocessed entity. 329 /// Negative values are used to indicate preprocessed entities 330 /// loaded from the external source while non-negative values are used to 331 /// indicate preprocessed entities introduced by the current preprocessor. 332 /// Value -1 corresponds to element 0 in the loaded entities vector, 333 /// value -2 corresponds to element 1 in the loaded entities vector, etc. 334 /// Value 0 is an invalid value, the index to local entities is 1-based, 335 /// value 1 corresponds to element 0 in the local entities vector, 336 /// value 2 corresponds to element 1 in the local entities vector, etc. 337 class PPEntityID { 338 friend class PreprocessingRecord; 339 340 int ID = 0; 341 342 explicit PPEntityID(int ID) : ID(ID) {} 343 344 public: 345 PPEntityID() = default; 346 }; 347 348 static PPEntityID getPPEntityID(unsigned Index, bool isLoaded) { 349 return isLoaded ? PPEntityID(-int(Index)-1) : PPEntityID(Index+1); 350 } 351 352 /// Mapping from MacroInfo structures to their definitions. 353 llvm::DenseMap<const MacroInfo *, MacroDefinitionRecord *> MacroDefinitions; 354 355 /// External source of preprocessed entities. 356 ExternalPreprocessingRecordSource *ExternalSource = nullptr; 357 358 /// Retrieve the preprocessed entity at the given ID. 359 PreprocessedEntity *getPreprocessedEntity(PPEntityID PPID); 360 361 /// Retrieve the loaded preprocessed entity at the given index. 362 PreprocessedEntity *getLoadedPreprocessedEntity(unsigned Index); 363 364 /// Determine the number of preprocessed entities that were 365 /// loaded (or can be loaded) from an external source. 366 unsigned getNumLoadedPreprocessedEntities() const { 367 return LoadedPreprocessedEntities.size(); 368 } 369 370 /// Returns a pair of [Begin, End) indices of local preprocessed 371 /// entities that \p Range encompasses. 372 std::pair<unsigned, unsigned> 373 findLocalPreprocessedEntitiesInRange(SourceRange Range) const; 374 unsigned findBeginLocalPreprocessedEntity(SourceLocation Loc) const; 375 unsigned findEndLocalPreprocessedEntity(SourceLocation Loc) const; 376 377 /// Allocate space for a new set of loaded preprocessed entities. 378 /// 379 /// \returns The index into the set of loaded preprocessed entities, which 380 /// corresponds to the first newly-allocated entity. 381 unsigned allocateLoadedEntities(unsigned NumEntities); 382 383 /// Allocate space for a new set of loaded preprocessed skipped 384 /// ranges. 385 /// 386 /// \returns The index into the set of loaded preprocessed ranges, which 387 /// corresponds to the first newly-allocated range. 388 unsigned allocateSkippedRanges(unsigned NumRanges); 389 390 /// Ensures that all external skipped ranges have been loaded. 391 void ensureSkippedRangesLoaded(); 392 393 /// Register a new macro definition. 394 void RegisterMacroDefinition(MacroInfo *Macro, MacroDefinitionRecord *Def); 395 396 public: 397 /// Construct a new preprocessing record. 398 explicit PreprocessingRecord(SourceManager &SM); 399 400 /// Allocate memory in the preprocessing record. 401 void *Allocate(unsigned Size, unsigned Align = 8) { 402 return BumpAlloc.Allocate(Size, Align); 403 } 404 405 /// Deallocate memory in the preprocessing record. 406 void Deallocate(void *Ptr) {} 407 408 size_t getTotalMemory() const; 409 410 SourceManager &getSourceManager() const { return SourceMgr; } 411 412 /// Iteration over the preprocessed entities. 413 /// 414 /// In a complete iteration, the iterator walks the range [-M, N), 415 /// where negative values are used to indicate preprocessed entities 416 /// loaded from the external source while non-negative values are used to 417 /// indicate preprocessed entities introduced by the current preprocessor. 418 /// However, to provide iteration in source order (for, e.g., chained 419 /// precompiled headers), dereferencing the iterator flips the negative 420 /// values (corresponding to loaded entities), so that position -M 421 /// corresponds to element 0 in the loaded entities vector, position -M+1 422 /// corresponds to element 1 in the loaded entities vector, etc. This 423 /// gives us a reasonably efficient, source-order walk. 424 /// 425 /// We define this as a wrapping iterator around an int. The 426 /// iterator_adaptor_base class forwards the iterator methods to basic 427 /// integer arithmetic. 428 class iterator : public llvm::iterator_adaptor_base< 429 iterator, int, std::random_access_iterator_tag, 430 PreprocessedEntity *, int, PreprocessedEntity *, 431 PreprocessedEntity *> { 432 friend class PreprocessingRecord; 433 434 PreprocessingRecord *Self; 435 436 iterator(PreprocessingRecord *Self, int Position) 437 : iterator::iterator_adaptor_base(Position), Self(Self) {} 438 439 public: 440 iterator() : iterator(nullptr, 0) {} 441 442 PreprocessedEntity *operator*() const { 443 bool isLoaded = this->I < 0; 444 unsigned Index = isLoaded ? 445 Self->LoadedPreprocessedEntities.size() + this->I : this->I; 446 PPEntityID ID = Self->getPPEntityID(Index, isLoaded); 447 return Self->getPreprocessedEntity(ID); 448 } 449 PreprocessedEntity *operator->() const { return **this; } 450 }; 451 452 /// Begin iterator for all preprocessed entities. 453 iterator begin() { 454 return iterator(this, -(int)LoadedPreprocessedEntities.size()); 455 } 456 457 /// End iterator for all preprocessed entities. 458 iterator end() { 459 return iterator(this, PreprocessedEntities.size()); 460 } 461 462 /// Begin iterator for local, non-loaded, preprocessed entities. 463 iterator local_begin() { 464 return iterator(this, 0); 465 } 466 467 /// End iterator for local, non-loaded, preprocessed entities. 468 iterator local_end() { 469 return iterator(this, PreprocessedEntities.size()); 470 } 471 472 /// iterator range for the given range of loaded 473 /// preprocessed entities. 474 llvm::iterator_range<iterator> getIteratorsForLoadedRange(unsigned start, 475 unsigned count) { 476 unsigned end = start + count; 477 assert(end <= LoadedPreprocessedEntities.size()); 478 return llvm::make_range( 479 iterator(this, int(start) - LoadedPreprocessedEntities.size()), 480 iterator(this, int(end) - LoadedPreprocessedEntities.size())); 481 } 482 483 /// Returns a range of preprocessed entities that source range \p R 484 /// encompasses. 485 /// 486 /// \param R the range to look for preprocessed entities. 487 llvm::iterator_range<iterator> 488 getPreprocessedEntitiesInRange(SourceRange R); 489 490 /// Returns true if the preprocessed entity that \p PPEI iterator 491 /// points to is coming from the file \p FID. 492 /// 493 /// Can be used to avoid implicit deserializations of preallocated 494 /// preprocessed entities if we only care about entities of a specific file 495 /// and not from files \#included in the range given at 496 /// \see getPreprocessedEntitiesInRange. 497 bool isEntityInFileID(iterator PPEI, FileID FID); 498 499 /// Add a new preprocessed entity to this record. 500 PPEntityID addPreprocessedEntity(PreprocessedEntity *Entity); 501 502 /// Set the external source for preprocessed entities. 503 void SetExternalSource(ExternalPreprocessingRecordSource &Source); 504 505 /// Retrieve the external source for preprocessed entities. 506 ExternalPreprocessingRecordSource *getExternalSource() const { 507 return ExternalSource; 508 } 509 510 /// Retrieve the macro definition that corresponds to the given 511 /// \c MacroInfo. 512 MacroDefinitionRecord *findMacroDefinition(const MacroInfo *MI); 513 514 /// Retrieve all ranges that got skipped while preprocessing. 515 const std::vector<SourceRange> &getSkippedRanges() { 516 ensureSkippedRangesLoaded(); 517 return SkippedRanges; 518 } 519 520 private: 521 friend class ASTReader; 522 friend class ASTWriter; 523 524 void MacroExpands(const Token &Id, const MacroDefinition &MD, 525 SourceRange Range, const MacroArgs *Args) override; 526 void MacroDefined(const Token &Id, const MacroDirective *MD) override; 527 void MacroUndefined(const Token &Id, const MacroDefinition &MD, 528 const MacroDirective *Undef) override; 529 void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, 530 StringRef FileName, bool IsAngled, 531 CharSourceRange FilenameRange, 532 Optional<FileEntryRef> File, StringRef SearchPath, 533 StringRef RelativePath, const Module *Imported, 534 SrcMgr::CharacteristicKind FileType) override; 535 void Ifdef(SourceLocation Loc, const Token &MacroNameTok, 536 const MacroDefinition &MD) override; 537 void Ifndef(SourceLocation Loc, const Token &MacroNameTok, 538 const MacroDefinition &MD) override; 539 540 using PPCallbacks::Elifdef; 541 using PPCallbacks::Elifndef; 542 void Elifdef(SourceLocation Loc, const Token &MacroNameTok, 543 const MacroDefinition &MD) override; 544 void Elifndef(SourceLocation Loc, const Token &MacroNameTok, 545 const MacroDefinition &MD) override; 546 547 /// Hook called whenever the 'defined' operator is seen. 548 void Defined(const Token &MacroNameTok, const MacroDefinition &MD, 549 SourceRange Range) override; 550 551 void SourceRangeSkipped(SourceRange Range, 552 SourceLocation EndifLoc) override; 553 554 void addMacroExpansion(const Token &Id, const MacroInfo *MI, 555 SourceRange Range); 556 557 /// Cached result of the last \see getPreprocessedEntitiesInRange 558 /// query. 559 struct { 560 SourceRange Range; 561 std::pair<int, int> Result; 562 } CachedRangeQuery; 563 564 std::pair<int, int> getPreprocessedEntitiesInRangeSlow(SourceRange R); 565 }; 566 567 } // namespace clang 568 569 inline void *operator new(size_t bytes, clang::PreprocessingRecord &PR, 570 unsigned alignment) noexcept { 571 return PR.Allocate(bytes, alignment); 572 } 573 574 inline void operator delete(void *ptr, clang::PreprocessingRecord &PR, 575 unsigned) noexcept { 576 PR.Deallocate(ptr); 577 } 578 579 #endif // LLVM_CLANG_LEX_PREPROCESSINGRECORD_H 580