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