1205408Srdivacky//===--- PreprocessingRecord.h - Record of Preprocessing --------*- C++ -*-===// 2205408Srdivacky// 3205408Srdivacky// The LLVM Compiler Infrastructure 4205408Srdivacky// 5205408Srdivacky// This file is distributed under the University of Illinois Open Source 6205408Srdivacky// License. See LICENSE.TXT for details. 7205408Srdivacky// 8205408Srdivacky//===----------------------------------------------------------------------===// 9205408Srdivacky// 10205408Srdivacky// This file defines the PreprocessingRecord class, which maintains a record 11205408Srdivacky// of what occurred during preprocessing. 12205408Srdivacky// 13205408Srdivacky//===----------------------------------------------------------------------===// 14205408Srdivacky#ifndef LLVM_CLANG_LEX_PREPROCESSINGRECORD_H 15205408Srdivacky#define LLVM_CLANG_LEX_PREPROCESSINGRECORD_H 16205408Srdivacky 17249423Sdim#include "clang/Basic/IdentifierTable.h" 18249423Sdim#include "clang/Basic/SourceLocation.h" 19205408Srdivacky#include "clang/Lex/PPCallbacks.h" 20205408Srdivacky#include "llvm/ADT/DenseMap.h" 21234353Sdim#include "llvm/ADT/Optional.h" 22249423Sdim#include "llvm/ADT/SmallVector.h" 23205408Srdivacky#include "llvm/Support/Allocator.h" 24234353Sdim#include "llvm/Support/Compiler.h" 25205408Srdivacky#include <vector> 26205408Srdivacky 27205408Srdivackynamespace clang { 28205408Srdivacky class IdentifierInfo; 29249423Sdim class MacroInfo; 30205408Srdivacky class PreprocessingRecord; 31205408Srdivacky} 32205408Srdivacky 33205408Srdivacky/// \brief Allocates memory within a Clang preprocessing record. 34205408Srdivackyvoid* operator new(size_t bytes, clang::PreprocessingRecord& PR, 35205408Srdivacky unsigned alignment = 8) throw(); 36205408Srdivacky 37205408Srdivacky/// \brief Frees memory allocated in a Clang preprocessing record. 38205408Srdivackyvoid operator delete(void* ptr, clang::PreprocessingRecord& PR, 39205408Srdivacky unsigned) throw(); 40205408Srdivacky 41205408Srdivackynamespace clang { 42205408Srdivacky class MacroDefinition; 43218893Sdim class FileEntry; 44205408Srdivacky 45205408Srdivacky /// \brief Base class that describes a preprocessed entity, which may be a 46224145Sdim /// preprocessor directive or macro expansion. 47205408Srdivacky class PreprocessedEntity { 48205408Srdivacky public: 49205408Srdivacky /// \brief The kind of preprocessed entity an object describes. 50205408Srdivacky enum EntityKind { 51226633Sdim /// \brief Indicates a problem trying to load the preprocessed entity. 52226633Sdim InvalidKind, 53226633Sdim 54224145Sdim /// \brief A macro expansion. 55224145Sdim MacroExpansionKind, 56205408Srdivacky 57226633Sdim /// \defgroup Preprocessing directives 58226633Sdim /// @{ 59205408Srdivacky 60205408Srdivacky /// \brief A macro definition. 61205408Srdivacky MacroDefinitionKind, 62205408Srdivacky 63239462Sdim /// \brief An inclusion directive, such as \c \#include, \c 64239462Sdim /// \#import, or \c \#include_next. 65218893Sdim InclusionDirectiveKind, 66218893Sdim 67226633Sdim /// @} 68226633Sdim 69226633Sdim FirstPreprocessingDirective = MacroDefinitionKind, 70218893Sdim LastPreprocessingDirective = InclusionDirectiveKind 71205408Srdivacky }; 72205408Srdivacky 73205408Srdivacky private: 74205408Srdivacky /// \brief The kind of preprocessed entity that this object describes. 75205408Srdivacky EntityKind Kind; 76205408Srdivacky 77205408Srdivacky /// \brief The source range that covers this preprocessed entity. 78205408Srdivacky SourceRange Range; 79205408Srdivacky 80205408Srdivacky protected: 81205408Srdivacky PreprocessedEntity(EntityKind Kind, SourceRange Range) 82205408Srdivacky : Kind(Kind), Range(Range) { } 83226633Sdim 84226633Sdim friend class PreprocessingRecord; 85226633Sdim 86205408Srdivacky public: 87205408Srdivacky /// \brief Retrieve the kind of preprocessed entity stored in this object. 88205408Srdivacky EntityKind getKind() const { return Kind; } 89205408Srdivacky 90205408Srdivacky /// \brief Retrieve the source range that covers this entire preprocessed 91205408Srdivacky /// entity. 92234353Sdim SourceRange getSourceRange() const LLVM_READONLY { return Range; } 93226633Sdim 94226633Sdim /// \brief Returns true if there was a problem loading the preprocessed 95226633Sdim /// entity. 96226633Sdim bool isInvalid() const { return Kind == InvalidKind; } 97226633Sdim 98205408Srdivacky // Only allow allocation of preprocessed entities using the allocator 99205408Srdivacky // in PreprocessingRecord or by doing a placement new. 100205408Srdivacky void* operator new(size_t bytes, PreprocessingRecord& PR, 101205408Srdivacky unsigned alignment = 8) throw() { 102205408Srdivacky return ::operator new(bytes, PR, alignment); 103205408Srdivacky } 104205408Srdivacky 105205408Srdivacky void* operator new(size_t bytes, void* mem) throw() { 106205408Srdivacky return mem; 107205408Srdivacky } 108205408Srdivacky 109205408Srdivacky void operator delete(void* ptr, PreprocessingRecord& PR, 110205408Srdivacky unsigned alignment) throw() { 111205408Srdivacky return ::operator delete(ptr, PR, alignment); 112205408Srdivacky } 113205408Srdivacky 114205408Srdivacky void operator delete(void*, std::size_t) throw() { } 115205408Srdivacky void operator delete(void*, void*) throw() { } 116205408Srdivacky 117205408Srdivacky private: 118205408Srdivacky // Make vanilla 'new' and 'delete' illegal for preprocessed entities. 119205408Srdivacky void* operator new(size_t bytes) throw(); 120205408Srdivacky void operator delete(void* data) throw(); 121205408Srdivacky }; 122205408Srdivacky 123205408Srdivacky /// \brief Records the presence of a preprocessor directive. 124205408Srdivacky class PreprocessingDirective : public PreprocessedEntity { 125205408Srdivacky public: 126205408Srdivacky PreprocessingDirective(EntityKind Kind, SourceRange Range) 127205408Srdivacky : PreprocessedEntity(Kind, Range) { } 128205408Srdivacky 129205408Srdivacky // Implement isa/cast/dyncast/etc. 130205408Srdivacky static bool classof(const PreprocessedEntity *PD) { 131205408Srdivacky return PD->getKind() >= FirstPreprocessingDirective && 132205408Srdivacky PD->getKind() <= LastPreprocessingDirective; 133205408Srdivacky } 134205408Srdivacky }; 135205408Srdivacky 136205408Srdivacky /// \brief Record the location of a macro definition. 137205408Srdivacky class MacroDefinition : public PreprocessingDirective { 138205408Srdivacky /// \brief The name of the macro being defined. 139205408Srdivacky const IdentifierInfo *Name; 140205408Srdivacky 141205408Srdivacky public: 142226633Sdim explicit MacroDefinition(const IdentifierInfo *Name, SourceRange Range) 143226633Sdim : PreprocessingDirective(MacroDefinitionKind, Range), Name(Name) { } 144205408Srdivacky 145205408Srdivacky /// \brief Retrieve the name of the macro being defined. 146205408Srdivacky const IdentifierInfo *getName() const { return Name; } 147205408Srdivacky 148205408Srdivacky /// \brief Retrieve the location of the macro name in the definition. 149226633Sdim SourceLocation getLocation() const { return getSourceRange().getBegin(); } 150205408Srdivacky 151205408Srdivacky // Implement isa/cast/dyncast/etc. 152205408Srdivacky static bool classof(const PreprocessedEntity *PE) { 153205408Srdivacky return PE->getKind() == MacroDefinitionKind; 154205408Srdivacky } 155205408Srdivacky }; 156226633Sdim 157226633Sdim /// \brief Records the location of a macro expansion. 158226633Sdim class MacroExpansion : public PreprocessedEntity { 159226633Sdim /// \brief The definition of this macro or the name of the macro if it is 160226633Sdim /// a builtin macro. 161226633Sdim llvm::PointerUnion<IdentifierInfo *, MacroDefinition *> NameOrDef; 162218893Sdim 163226633Sdim public: 164226633Sdim MacroExpansion(IdentifierInfo *BuiltinName, SourceRange Range) 165226633Sdim : PreprocessedEntity(MacroExpansionKind, Range), 166226633Sdim NameOrDef(BuiltinName) { } 167226633Sdim 168226633Sdim MacroExpansion(MacroDefinition *Definition, SourceRange Range) 169226633Sdim : PreprocessedEntity(MacroExpansionKind, Range), 170226633Sdim NameOrDef(Definition) { } 171226633Sdim 172226633Sdim /// \brief True if it is a builtin macro. 173226633Sdim bool isBuiltinMacro() const { return NameOrDef.is<IdentifierInfo *>(); } 174226633Sdim 175226633Sdim /// \brief The name of the macro being expanded. 176226633Sdim const IdentifierInfo *getName() const { 177226633Sdim if (MacroDefinition *Def = getDefinition()) 178226633Sdim return Def->getName(); 179226633Sdim return NameOrDef.get<IdentifierInfo*>(); 180226633Sdim } 181226633Sdim 182226633Sdim /// \brief The definition of the macro being expanded. May return null if 183226633Sdim /// this is a builtin macro. 184226633Sdim MacroDefinition *getDefinition() const { 185226633Sdim return NameOrDef.dyn_cast<MacroDefinition *>(); 186226633Sdim } 187226633Sdim 188226633Sdim // Implement isa/cast/dyncast/etc. 189226633Sdim static bool classof(const PreprocessedEntity *PE) { 190226633Sdim return PE->getKind() == MacroExpansionKind; 191226633Sdim } 192226633Sdim }; 193226633Sdim 194218893Sdim /// \brief Record the location of an inclusion directive, such as an 195239462Sdim /// \c \#include or \c \#import statement. 196218893Sdim class InclusionDirective : public PreprocessingDirective { 197218893Sdim public: 198218893Sdim /// \brief The kind of inclusion directives known to the 199218893Sdim /// preprocessor. 200218893Sdim enum InclusionKind { 201239462Sdim /// \brief An \c \#include directive. 202218893Sdim Include, 203239462Sdim /// \brief An Objective-C \c \#import directive. 204218893Sdim Import, 205239462Sdim /// \brief A GNU \c \#include_next directive. 206218893Sdim IncludeNext, 207239462Sdim /// \brief A Clang \c \#__include_macros directive. 208218893Sdim IncludeMacros 209218893Sdim }; 210218893Sdim 211218893Sdim private: 212218893Sdim /// \brief The name of the file that was included, as written in 213218893Sdim /// the source. 214226633Sdim StringRef FileName; 215218893Sdim 216218893Sdim /// \brief Whether the file name was in quotation marks; otherwise, it was 217218893Sdim /// in angle brackets. 218218893Sdim unsigned InQuotes : 1; 219218893Sdim 220218893Sdim /// \brief The kind of inclusion directive we have. 221218893Sdim /// 222218893Sdim /// This is a value of type InclusionKind. 223218893Sdim unsigned Kind : 2; 224218893Sdim 225243830Sdim /// \brief Whether the inclusion directive was automatically turned into 226243830Sdim /// a module import. 227243830Sdim unsigned ImportedModule : 1; 228243830Sdim 229218893Sdim /// \brief The file that was included. 230218893Sdim const FileEntry *File; 231218893Sdim 232218893Sdim public: 233218893Sdim InclusionDirective(PreprocessingRecord &PPRec, 234226633Sdim InclusionKind Kind, StringRef FileName, 235243830Sdim bool InQuotes, bool ImportedModule, 236243830Sdim const FileEntry *File, SourceRange Range); 237218893Sdim 238218893Sdim /// \brief Determine what kind of inclusion directive this is. 239218893Sdim InclusionKind getKind() const { return static_cast<InclusionKind>(Kind); } 240218893Sdim 241218893Sdim /// \brief Retrieve the included file name as it was written in the source. 242226633Sdim StringRef getFileName() const { return FileName; } 243218893Sdim 244218893Sdim /// \brief Determine whether the included file name was written in quotes; 245218893Sdim /// otherwise, it was written in angle brackets. 246218893Sdim bool wasInQuotes() const { return InQuotes; } 247243830Sdim 248243830Sdim /// \brief Determine whether the inclusion directive was automatically 249243830Sdim /// turned into a module import. 250243830Sdim bool importedModule() const { return ImportedModule; } 251218893Sdim 252218893Sdim /// \brief Retrieve the file entry for the actual file that was included 253218893Sdim /// by this directive. 254218893Sdim const FileEntry *getFile() const { return File; } 255218893Sdim 256218893Sdim // Implement isa/cast/dyncast/etc. 257218893Sdim static bool classof(const PreprocessedEntity *PE) { 258218893Sdim return PE->getKind() == InclusionDirectiveKind; 259218893Sdim } 260218893Sdim }; 261205408Srdivacky 262205408Srdivacky /// \brief An abstract class that should be subclassed by any external source 263205408Srdivacky /// of preprocessing record entries. 264205408Srdivacky class ExternalPreprocessingRecordSource { 265205408Srdivacky public: 266205408Srdivacky virtual ~ExternalPreprocessingRecordSource(); 267205408Srdivacky 268226633Sdim /// \brief Read a preallocated preprocessed entity from the external source. 269226633Sdim /// 270226633Sdim /// \returns null if an error occurred that prevented the preprocessed 271226633Sdim /// entity from being loaded. 272226633Sdim virtual PreprocessedEntity *ReadPreprocessedEntity(unsigned Index) = 0; 273226633Sdim 274226633Sdim /// \brief Returns a pair of [Begin, End) indices of preallocated 275243830Sdim /// preprocessed entities that \p Range encompasses. 276226633Sdim virtual std::pair<unsigned, unsigned> 277226633Sdim findPreprocessedEntitiesInRange(SourceRange Range) = 0; 278234353Sdim 279234353Sdim /// \brief Optionally returns true or false if the preallocated preprocessed 280243830Sdim /// entity with index \p Index came from file \p FID. 281249423Sdim virtual Optional<bool> isPreprocessedEntityInFileID(unsigned Index, 282249423Sdim FileID FID) { 283249423Sdim return None; 284234353Sdim } 285205408Srdivacky }; 286205408Srdivacky 287205408Srdivacky /// \brief A record of the steps taken while preprocessing a source file, 288205408Srdivacky /// including the various preprocessing directives processed, macros 289224145Sdim /// expanded, etc. 290205408Srdivacky class PreprocessingRecord : public PPCallbacks { 291226633Sdim SourceManager &SourceMgr; 292223017Sdim 293205408Srdivacky /// \brief Allocator used to store preprocessing objects. 294205408Srdivacky llvm::BumpPtrAllocator BumpAlloc; 295205408Srdivacky 296205408Srdivacky /// \brief The set of preprocessed entities in this record, in order they 297205408Srdivacky /// were seen. 298205408Srdivacky std::vector<PreprocessedEntity *> PreprocessedEntities; 299205408Srdivacky 300226633Sdim /// \brief The set of preprocessed entities in this record that have been 301226633Sdim /// loaded from external sources. 302226633Sdim /// 303226633Sdim /// The entries in this vector are loaded lazily from the external source, 304226633Sdim /// and are referenced by the iterator using negative indices. 305226633Sdim std::vector<PreprocessedEntity *> LoadedPreprocessedEntities; 306226633Sdim 307226633Sdim /// \brief Global (loaded or local) ID for a preprocessed entity. 308226633Sdim /// Negative values are used to indicate preprocessed entities 309226633Sdim /// loaded from the external source while non-negative values are used to 310226633Sdim /// indicate preprocessed entities introduced by the current preprocessor. 311243830Sdim /// Value -1 corresponds to element 0 in the loaded entities vector, 312243830Sdim /// value -2 corresponds to element 1 in the loaded entities vector, etc. 313243830Sdim /// Value 0 is an invalid value, the index to local entities is 1-based, 314243830Sdim /// value 1 corresponds to element 0 in the local entities vector, 315243830Sdim /// value 2 corresponds to element 1 in the local entities vector, etc. 316243830Sdim class PPEntityID { 317243830Sdim int ID; 318243830Sdim explicit PPEntityID(int ID) : ID(ID) {} 319243830Sdim friend class PreprocessingRecord; 320243830Sdim public: 321243830Sdim PPEntityID() : ID(0) {} 322243830Sdim }; 323226633Sdim 324243830Sdim static PPEntityID getPPEntityID(unsigned Index, bool isLoaded) { 325243830Sdim return isLoaded ? PPEntityID(-int(Index)-1) : PPEntityID(Index+1); 326226633Sdim } 327226633Sdim 328205408Srdivacky /// \brief Mapping from MacroInfo structures to their definitions. 329249423Sdim llvm::DenseMap<const MacroInfo *, MacroDefinition *> MacroDefinitions; 330205408Srdivacky 331205408Srdivacky /// \brief External source of preprocessed entities. 332205408Srdivacky ExternalPreprocessingRecordSource *ExternalSource; 333226633Sdim 334226633Sdim /// \brief Retrieve the preprocessed entity at the given ID. 335226633Sdim PreprocessedEntity *getPreprocessedEntity(PPEntityID PPID); 336226633Sdim 337226633Sdim /// \brief Retrieve the loaded preprocessed entity at the given index. 338226633Sdim PreprocessedEntity *getLoadedPreprocessedEntity(unsigned Index); 339205408Srdivacky 340226633Sdim /// \brief Determine the number of preprocessed entities that were 341226633Sdim /// loaded (or can be loaded) from an external source. 342226633Sdim unsigned getNumLoadedPreprocessedEntities() const { 343226633Sdim return LoadedPreprocessedEntities.size(); 344226633Sdim } 345226633Sdim 346226633Sdim /// \brief Returns a pair of [Begin, End) indices of local preprocessed 347243830Sdim /// entities that \p Range encompasses. 348226633Sdim std::pair<unsigned, unsigned> 349226633Sdim findLocalPreprocessedEntitiesInRange(SourceRange Range) const; 350226633Sdim unsigned findBeginLocalPreprocessedEntity(SourceLocation Loc) const; 351226633Sdim unsigned findEndLocalPreprocessedEntity(SourceLocation Loc) const; 352226633Sdim 353226633Sdim /// \brief Allocate space for a new set of loaded preprocessed entities. 354226633Sdim /// 355226633Sdim /// \returns The index into the set of loaded preprocessed entities, which 356226633Sdim /// corresponds to the first newly-allocated entity. 357226633Sdim unsigned allocateLoadedEntities(unsigned NumEntities); 358226633Sdim 359226633Sdim /// \brief Register a new macro definition. 360249423Sdim void RegisterMacroDefinition(MacroInfo *Macro, MacroDefinition *Def); 361205408Srdivacky 362205408Srdivacky public: 363226633Sdim /// \brief Construct a new preprocessing record. 364249423Sdim explicit PreprocessingRecord(SourceManager &SM); 365205408Srdivacky 366205408Srdivacky /// \brief Allocate memory in the preprocessing record. 367205408Srdivacky void *Allocate(unsigned Size, unsigned Align = 8) { 368205408Srdivacky return BumpAlloc.Allocate(Size, Align); 369205408Srdivacky } 370205408Srdivacky 371205408Srdivacky /// \brief Deallocate memory in the preprocessing record. 372205408Srdivacky void Deallocate(void *Ptr) { } 373226633Sdim 374226633Sdim size_t getTotalMemory() const; 375226633Sdim 376226633Sdim SourceManager &getSourceManager() const { return SourceMgr; } 377226633Sdim 378205408Srdivacky // Iteration over the preprocessed entities. 379226633Sdim class iterator { 380226633Sdim PreprocessingRecord *Self; 381226633Sdim 382226633Sdim /// \brief Position within the preprocessed entity sequence. 383226633Sdim /// 384226633Sdim /// In a complete iteration, the Position field walks the range [-M, N), 385226633Sdim /// where negative values are used to indicate preprocessed entities 386226633Sdim /// loaded from the external source while non-negative values are used to 387226633Sdim /// indicate preprocessed entities introduced by the current preprocessor. 388226633Sdim /// However, to provide iteration in source order (for, e.g., chained 389226633Sdim /// precompiled headers), dereferencing the iterator flips the negative 390226633Sdim /// values (corresponding to loaded entities), so that position -M 391226633Sdim /// corresponds to element 0 in the loaded entities vector, position -M+1 392226633Sdim /// corresponds to element 1 in the loaded entities vector, etc. This 393226633Sdim /// gives us a reasonably efficient, source-order walk. 394243830Sdim int Position; 395226633Sdim 396226633Sdim public: 397226633Sdim typedef PreprocessedEntity *value_type; 398226633Sdim typedef value_type& reference; 399226633Sdim typedef value_type* pointer; 400226633Sdim typedef std::random_access_iterator_tag iterator_category; 401226633Sdim typedef int difference_type; 402226633Sdim 403226633Sdim iterator() : Self(0), Position(0) { } 404226633Sdim 405243830Sdim iterator(PreprocessingRecord *Self, int Position) 406226633Sdim : Self(Self), Position(Position) { } 407226633Sdim 408226633Sdim value_type operator*() const { 409243830Sdim bool isLoaded = Position < 0; 410243830Sdim unsigned Index = isLoaded ? 411243830Sdim Self->LoadedPreprocessedEntities.size() + Position : Position; 412243830Sdim PPEntityID ID = Self->getPPEntityID(Index, isLoaded); 413243830Sdim return Self->getPreprocessedEntity(ID); 414226633Sdim } 415226633Sdim 416226633Sdim value_type operator[](difference_type D) { 417226633Sdim return *(*this + D); 418226633Sdim } 419226633Sdim 420226633Sdim iterator &operator++() { 421226633Sdim ++Position; 422226633Sdim return *this; 423226633Sdim } 424226633Sdim 425226633Sdim iterator operator++(int) { 426226633Sdim iterator Prev(*this); 427226633Sdim ++Position; 428226633Sdim return Prev; 429226633Sdim } 430218893Sdim 431226633Sdim iterator &operator--() { 432226633Sdim --Position; 433226633Sdim return *this; 434226633Sdim } 435226633Sdim 436226633Sdim iterator operator--(int) { 437226633Sdim iterator Prev(*this); 438226633Sdim --Position; 439226633Sdim return Prev; 440226633Sdim } 441226633Sdim 442226633Sdim friend bool operator==(const iterator &X, const iterator &Y) { 443226633Sdim return X.Position == Y.Position; 444226633Sdim } 445226633Sdim 446226633Sdim friend bool operator!=(const iterator &X, const iterator &Y) { 447226633Sdim return X.Position != Y.Position; 448226633Sdim } 449226633Sdim 450226633Sdim friend bool operator<(const iterator &X, const iterator &Y) { 451226633Sdim return X.Position < Y.Position; 452226633Sdim } 453226633Sdim 454226633Sdim friend bool operator>(const iterator &X, const iterator &Y) { 455226633Sdim return X.Position > Y.Position; 456226633Sdim } 457226633Sdim 458226633Sdim friend bool operator<=(const iterator &X, const iterator &Y) { 459226633Sdim return X.Position < Y.Position; 460226633Sdim } 461226633Sdim 462226633Sdim friend bool operator>=(const iterator &X, const iterator &Y) { 463226633Sdim return X.Position > Y.Position; 464226633Sdim } 465226633Sdim 466226633Sdim friend iterator& operator+=(iterator &X, difference_type D) { 467226633Sdim X.Position += D; 468226633Sdim return X; 469226633Sdim } 470226633Sdim 471226633Sdim friend iterator& operator-=(iterator &X, difference_type D) { 472226633Sdim X.Position -= D; 473226633Sdim return X; 474226633Sdim } 475226633Sdim 476226633Sdim friend iterator operator+(iterator X, difference_type D) { 477226633Sdim X.Position += D; 478226633Sdim return X; 479226633Sdim } 480226633Sdim 481226633Sdim friend iterator operator+(difference_type D, iterator X) { 482226633Sdim X.Position += D; 483226633Sdim return X; 484226633Sdim } 485226633Sdim 486226633Sdim friend difference_type operator-(const iterator &X, const iterator &Y) { 487226633Sdim return X.Position - Y.Position; 488226633Sdim } 489226633Sdim 490226633Sdim friend iterator operator-(iterator X, difference_type D) { 491226633Sdim X.Position -= D; 492226633Sdim return X; 493226633Sdim } 494234353Sdim friend class PreprocessingRecord; 495226633Sdim }; 496226633Sdim friend class iterator; 497226633Sdim 498226633Sdim /// \brief Begin iterator for all preprocessed entities. 499226633Sdim iterator begin() { 500226633Sdim return iterator(this, -(int)LoadedPreprocessedEntities.size()); 501226633Sdim } 502226633Sdim 503226633Sdim /// \brief End iterator for all preprocessed entities. 504226633Sdim iterator end() { 505226633Sdim return iterator(this, PreprocessedEntities.size()); 506226633Sdim } 507226633Sdim 508226633Sdim /// \brief Begin iterator for local, non-loaded, preprocessed entities. 509226633Sdim iterator local_begin() { 510226633Sdim return iterator(this, 0); 511226633Sdim } 512226633Sdim 513226633Sdim /// \brief End iterator for local, non-loaded, preprocessed entities. 514226633Sdim iterator local_end() { 515226633Sdim return iterator(this, PreprocessedEntities.size()); 516226633Sdim } 517226633Sdim 518243830Sdim /// \brief begin/end iterator pair for the given range of loaded 519243830Sdim /// preprocessed entities. 520243830Sdim std::pair<iterator, iterator> 521243830Sdim getIteratorsForLoadedRange(unsigned start, unsigned count) { 522243830Sdim unsigned end = start + count; 523243830Sdim assert(end <= LoadedPreprocessedEntities.size()); 524243830Sdim return std::make_pair( 525243830Sdim iterator(this, int(start)-LoadedPreprocessedEntities.size()), 526243830Sdim iterator(this, int(end)-LoadedPreprocessedEntities.size())); 527243830Sdim } 528243830Sdim 529226633Sdim /// \brief Returns a pair of [Begin, End) iterators of preprocessed entities 530243830Sdim /// that source range \p R encompasses. 531234353Sdim /// 532234353Sdim /// \param R the range to look for preprocessed entities. 533234353Sdim /// 534226633Sdim std::pair<iterator, iterator> getPreprocessedEntitiesInRange(SourceRange R); 535226633Sdim 536243830Sdim /// \brief Returns true if the preprocessed entity that \p PPEI iterator 537243830Sdim /// points to is coming from the file \p FID. 538234353Sdim /// 539234353Sdim /// Can be used to avoid implicit deserializations of preallocated 540234353Sdim /// preprocessed entities if we only care about entities of a specific file 541239462Sdim /// and not from files \#included in the range given at 542234353Sdim /// \see getPreprocessedEntitiesInRange. 543234353Sdim bool isEntityInFileID(iterator PPEI, FileID FID); 544234353Sdim 545205408Srdivacky /// \brief Add a new preprocessed entity to this record. 546234353Sdim PPEntityID addPreprocessedEntity(PreprocessedEntity *Entity); 547234353Sdim 548205408Srdivacky /// \brief Set the external source for preprocessed entities. 549226633Sdim void SetExternalSource(ExternalPreprocessingRecordSource &Source); 550218893Sdim 551218893Sdim /// \brief Retrieve the external source for preprocessed entities. 552218893Sdim ExternalPreprocessingRecordSource *getExternalSource() const { 553218893Sdim return ExternalSource; 554218893Sdim } 555205408Srdivacky 556205408Srdivacky /// \brief Retrieve the macro definition that corresponds to the given 557205408Srdivacky /// \c MacroInfo. 558205408Srdivacky MacroDefinition *findMacroDefinition(const MacroInfo *MI); 559226633Sdim 560234353Sdim private: 561249423Sdim virtual void MacroExpands(const Token &Id, const MacroDirective *MD, 562251662Sdim SourceRange Range, const MacroArgs *Args); 563249423Sdim virtual void MacroDefined(const Token &Id, const MacroDirective *MD); 564249423Sdim virtual void MacroUndefined(const Token &Id, const MacroDirective *MD); 565218893Sdim virtual void InclusionDirective(SourceLocation HashLoc, 566218893Sdim const Token &IncludeTok, 567226633Sdim StringRef FileName, 568218893Sdim bool IsAngled, 569243830Sdim CharSourceRange FilenameRange, 570218893Sdim const FileEntry *File, 571226633Sdim StringRef SearchPath, 572243830Sdim StringRef RelativePath, 573243830Sdim const Module *Imported); 574249423Sdim virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok, 575249423Sdim const MacroDirective *MD); 576249423Sdim virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok, 577249423Sdim const MacroDirective *MD); 578249423Sdim /// \brief Hook called whenever the 'defined' operator is seen. 579249423Sdim virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD); 580226633Sdim 581249423Sdim void addMacroExpansion(const Token &Id, const MacroInfo *MI, 582249423Sdim SourceRange Range); 583249423Sdim 584234353Sdim /// \brief Cached result of the last \see getPreprocessedEntitiesInRange 585234353Sdim /// query. 586234353Sdim struct { 587234353Sdim SourceRange Range; 588243830Sdim std::pair<int, int> Result; 589234353Sdim } CachedRangeQuery; 590234353Sdim 591243830Sdim std::pair<int, int> getPreprocessedEntitiesInRangeSlow(SourceRange R); 592234353Sdim 593226633Sdim friend class ASTReader; 594226633Sdim friend class ASTWriter; 595205408Srdivacky }; 596205408Srdivacky} // end namespace clang 597205408Srdivacky 598205408Srdivackyinline void* operator new(size_t bytes, clang::PreprocessingRecord& PR, 599205408Srdivacky unsigned alignment) throw() { 600205408Srdivacky return PR.Allocate(bytes, alignment); 601205408Srdivacky} 602205408Srdivacky 603205408Srdivackyinline void operator delete(void* ptr, clang::PreprocessingRecord& PR, 604205408Srdivacky unsigned) throw() { 605205408Srdivacky PR.Deallocate(ptr); 606205408Srdivacky} 607205408Srdivacky 608205408Srdivacky#endif // LLVM_CLANG_LEX_PREPROCESSINGRECORD_H 609