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