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/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