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 "llvm/ADT/DenseMap.h"
     20 #include "llvm/Support/Allocator.h"
     21 #include <vector>
     22 
     23 namespace clang {
     24   class IdentifierInfo;
     25   class PreprocessingRecord;
     26 }
     27 
     28 /// \brief Allocates memory within a Clang preprocessing record.
     29 void* operator new(size_t bytes, clang::PreprocessingRecord& PR,
     30                    unsigned alignment = 8) throw();
     31 
     32 /// \brief Frees memory allocated in a Clang preprocessing record.
     33 void operator delete(void* ptr, clang::PreprocessingRecord& PR,
     34                      unsigned) throw();
     35 
     36 namespace clang {
     37   class MacroDefinition;
     38   class FileEntry;
     39 
     40   /// \brief Base class that describes a preprocessed entity, which may be a
     41   /// preprocessor directive or macro expansion.
     42   class PreprocessedEntity {
     43   public:
     44     /// \brief The kind of preprocessed entity an object describes.
     45     enum EntityKind {
     46       /// \brief A macro expansion.
     47       MacroExpansionKind,
     48 
     49       /// \brief A preprocessing directive whose kind is not specified.
     50       ///
     51       /// This kind will be used for any preprocessing directive that does not
     52       /// have a more specific kind within the \c DirectiveKind enumeration.
     53       PreprocessingDirectiveKind,
     54 
     55       /// \brief A macro definition.
     56       MacroDefinitionKind,
     57 
     58       /// \brief An inclusion directive, such as \c #include, \c
     59       /// #import, or \c #include_next.
     60       InclusionDirectiveKind,
     61 
     62       FirstPreprocessingDirective = PreprocessingDirectiveKind,
     63       LastPreprocessingDirective = InclusionDirectiveKind
     64     };
     65 
     66   private:
     67     /// \brief The kind of preprocessed entity that this object describes.
     68     EntityKind Kind;
     69 
     70     /// \brief The source range that covers this preprocessed entity.
     71     SourceRange Range;
     72 
     73   protected:
     74     PreprocessedEntity(EntityKind Kind, SourceRange Range)
     75       : Kind(Kind), Range(Range) { }
     76 
     77   public:
     78     /// \brief Retrieve the kind of preprocessed entity stored in this object.
     79     EntityKind getKind() const { return Kind; }
     80 
     81     /// \brief Retrieve the source range that covers this entire preprocessed
     82     /// entity.
     83     SourceRange getSourceRange() const { return Range; }
     84 
     85     // Implement isa/cast/dyncast/etc.
     86     static bool classof(const PreprocessedEntity *) { return true; }
     87 
     88     // Only allow allocation of preprocessed entities using the allocator
     89     // in PreprocessingRecord or by doing a placement new.
     90     void* operator new(size_t bytes, PreprocessingRecord& PR,
     91                        unsigned alignment = 8) throw() {
     92       return ::operator new(bytes, PR, alignment);
     93     }
     94 
     95     void* operator new(size_t bytes, void* mem) throw() {
     96       return mem;
     97     }
     98 
     99     void operator delete(void* ptr, PreprocessingRecord& PR,
    100                          unsigned alignment) throw() {
    101       return ::operator delete(ptr, PR, alignment);
    102     }
    103 
    104     void operator delete(void*, std::size_t) throw() { }
    105     void operator delete(void*, void*) throw() { }
    106 
    107   private:
    108     // Make vanilla 'new' and 'delete' illegal for preprocessed entities.
    109     void* operator new(size_t bytes) throw();
    110     void operator delete(void* data) throw();
    111   };
    112 
    113   /// \brief Records the location of a macro expansion.
    114   class MacroExpansion : public PreprocessedEntity {
    115     /// \brief The name of the macro being expanded.
    116     IdentifierInfo *Name;
    117 
    118     /// \brief The definition of this macro.
    119     MacroDefinition *Definition;
    120 
    121   public:
    122     MacroExpansion(IdentifierInfo *Name, SourceRange Range,
    123                    MacroDefinition *Definition)
    124       : PreprocessedEntity(MacroExpansionKind, Range), Name(Name),
    125         Definition(Definition) { }
    126 
    127     /// \brief The name of the macro being expanded.
    128     IdentifierInfo *getName() const { return Name; }
    129 
    130     /// \brief The definition of the macro being expanded.
    131     MacroDefinition *getDefinition() const { return Definition; }
    132 
    133     // Implement isa/cast/dyncast/etc.
    134     static bool classof(const PreprocessedEntity *PE) {
    135       return PE->getKind() == MacroExpansionKind;
    136     }
    137     static bool classof(const MacroExpansion *) { return true; }
    138 
    139   };
    140 
    141   /// \brief Records the presence of a preprocessor directive.
    142   class PreprocessingDirective : public PreprocessedEntity {
    143   public:
    144     PreprocessingDirective(EntityKind Kind, SourceRange Range)
    145       : PreprocessedEntity(Kind, Range) { }
    146 
    147     // Implement isa/cast/dyncast/etc.
    148     static bool classof(const PreprocessedEntity *PD) {
    149       return PD->getKind() >= FirstPreprocessingDirective &&
    150              PD->getKind() <= LastPreprocessingDirective;
    151     }
    152     static bool classof(const PreprocessingDirective *) { return true; }
    153   };
    154 
    155   /// \brief Record the location of a macro definition.
    156   class MacroDefinition : public PreprocessingDirective {
    157     /// \brief The name of the macro being defined.
    158     const IdentifierInfo *Name;
    159 
    160     /// \brief The location of the macro name in the macro definition.
    161     SourceLocation Location;
    162 
    163   public:
    164     explicit MacroDefinition(const IdentifierInfo *Name, SourceLocation Location,
    165                              SourceRange Range)
    166       : PreprocessingDirective(MacroDefinitionKind, Range), Name(Name),
    167         Location(Location) { }
    168 
    169     /// \brief Retrieve the name of the macro being defined.
    170     const IdentifierInfo *getName() const { return Name; }
    171 
    172     /// \brief Retrieve the location of the macro name in the definition.
    173     SourceLocation getLocation() const { return Location; }
    174 
    175     // Implement isa/cast/dyncast/etc.
    176     static bool classof(const PreprocessedEntity *PE) {
    177       return PE->getKind() == MacroDefinitionKind;
    178     }
    179     static bool classof(const MacroDefinition *) { return true; }
    180   };
    181 
    182   /// \brief Record the location of an inclusion directive, such as an
    183   /// \c #include or \c #import statement.
    184   class InclusionDirective : public PreprocessingDirective {
    185   public:
    186     /// \brief The kind of inclusion directives known to the
    187     /// preprocessor.
    188     enum InclusionKind {
    189       /// \brief An \c #include directive.
    190       Include,
    191       /// \brief An Objective-C \c #import directive.
    192       Import,
    193       /// \brief A GNU \c #include_next directive.
    194       IncludeNext,
    195       /// \brief A Clang \c #__include_macros directive.
    196       IncludeMacros
    197     };
    198 
    199   private:
    200     /// \brief The name of the file that was included, as written in
    201     /// the source.
    202     llvm::StringRef FileName;
    203 
    204     /// \brief Whether the file name was in quotation marks; otherwise, it was
    205     /// in angle brackets.
    206     unsigned InQuotes : 1;
    207 
    208     /// \brief The kind of inclusion directive we have.
    209     ///
    210     /// This is a value of type InclusionKind.
    211     unsigned Kind : 2;
    212 
    213     /// \brief The file that was included.
    214     const FileEntry *File;
    215 
    216   public:
    217     InclusionDirective(PreprocessingRecord &PPRec,
    218                        InclusionKind Kind, llvm::StringRef FileName,
    219                        bool InQuotes, const FileEntry *File, SourceRange Range);
    220 
    221     /// \brief Determine what kind of inclusion directive this is.
    222     InclusionKind getKind() const { return static_cast<InclusionKind>(Kind); }
    223 
    224     /// \brief Retrieve the included file name as it was written in the source.
    225     llvm::StringRef getFileName() const { return FileName; }
    226 
    227     /// \brief Determine whether the included file name was written in quotes;
    228     /// otherwise, it was written in angle brackets.
    229     bool wasInQuotes() const { return InQuotes; }
    230 
    231     /// \brief Retrieve the file entry for the actual file that was included
    232     /// by this directive.
    233     const FileEntry *getFile() const { return File; }
    234 
    235     // Implement isa/cast/dyncast/etc.
    236     static bool classof(const PreprocessedEntity *PE) {
    237       return PE->getKind() == InclusionDirectiveKind;
    238     }
    239     static bool classof(const InclusionDirective *) { return true; }
    240   };
    241 
    242   /// \brief An abstract class that should be subclassed by any external source
    243   /// of preprocessing record entries.
    244   class ExternalPreprocessingRecordSource {
    245   public:
    246     virtual ~ExternalPreprocessingRecordSource();
    247 
    248     /// \brief Read any preallocated preprocessed entities from the external
    249     /// source.
    250     virtual void ReadPreprocessedEntities() = 0;
    251 
    252     /// \brief Read the preprocessed entity at the given offset.
    253     virtual PreprocessedEntity *
    254     ReadPreprocessedEntityAtOffset(uint64_t Offset) = 0;
    255   };
    256 
    257   /// \brief A record of the steps taken while preprocessing a source file,
    258   /// including the various preprocessing directives processed, macros
    259   /// expanded, etc.
    260   class PreprocessingRecord : public PPCallbacks {
    261     /// \brief Whether we should include nested macro expansions in
    262     /// the preprocessing record.
    263     bool IncludeNestedMacroExpansions;
    264 
    265     /// \brief Allocator used to store preprocessing objects.
    266     llvm::BumpPtrAllocator BumpAlloc;
    267 
    268     /// \brief The set of preprocessed entities in this record, in order they
    269     /// were seen.
    270     std::vector<PreprocessedEntity *> PreprocessedEntities;
    271 
    272     /// \brief Mapping from MacroInfo structures to their definitions.
    273     llvm::DenseMap<const MacroInfo *, MacroDefinition *> MacroDefinitions;
    274 
    275     /// \brief External source of preprocessed entities.
    276     ExternalPreprocessingRecordSource *ExternalSource;
    277 
    278     /// \brief The number of preallocated entities (that are known to the
    279     /// external source).
    280     unsigned NumPreallocatedEntities;
    281 
    282     /// \brief Whether we have already loaded all of the preallocated entities.
    283     mutable bool LoadedPreallocatedEntities;
    284 
    285     void MaybeLoadPreallocatedEntities() const ;
    286 
    287   public:
    288     /// \brief Construct
    289     explicit PreprocessingRecord(bool IncludeNestedMacroExpansions);
    290 
    291     /// \brief Allocate memory in the preprocessing record.
    292     void *Allocate(unsigned Size, unsigned Align = 8) {
    293       return BumpAlloc.Allocate(Size, Align);
    294     }
    295 
    296     /// \brief Deallocate memory in the preprocessing record.
    297     void Deallocate(void *Ptr) { }
    298 
    299     size_t getTotalMemory() const {
    300       return BumpAlloc.getTotalMemory();
    301     }
    302 
    303     // Iteration over the preprocessed entities.
    304     typedef std::vector<PreprocessedEntity *>::iterator iterator;
    305     typedef std::vector<PreprocessedEntity *>::const_iterator const_iterator;
    306     iterator begin(bool OnlyLocalEntities = false);
    307     iterator end(bool OnlyLocalEntities = false);
    308     const_iterator begin(bool OnlyLocalEntities = false) const;
    309     const_iterator end(bool OnlyLocalEntities = false) const;
    310 
    311     /// \brief Add a new preprocessed entity to this record.
    312     void addPreprocessedEntity(PreprocessedEntity *Entity);
    313 
    314     /// \brief Set the external source for preprocessed entities.
    315     void SetExternalSource(ExternalPreprocessingRecordSource &Source,
    316                            unsigned NumPreallocatedEntities);
    317 
    318     /// \brief Retrieve the external source for preprocessed entities.
    319     ExternalPreprocessingRecordSource *getExternalSource() const {
    320       return ExternalSource;
    321     }
    322 
    323     unsigned getNumPreallocatedEntities() const {
    324       return NumPreallocatedEntities;
    325     }
    326 
    327     /// \brief Set the preallocated entry at the given index to the given
    328     /// preprocessed entity.
    329     void SetPreallocatedEntity(unsigned Index, PreprocessedEntity *Entity);
    330 
    331     /// \brief Register a new macro definition.
    332     void RegisterMacroDefinition(MacroInfo *Macro, MacroDefinition *MD);
    333 
    334     /// \brief Retrieve the preprocessed entity at the given index.
    335     PreprocessedEntity *getPreprocessedEntity(unsigned Index) {
    336       assert(Index < PreprocessedEntities.size() &&
    337              "Out-of-bounds preprocessed entity");
    338       return PreprocessedEntities[Index];
    339     }
    340 
    341     /// \brief Retrieve the macro definition that corresponds to the given
    342     /// \c MacroInfo.
    343     MacroDefinition *findMacroDefinition(const MacroInfo *MI);
    344 
    345     virtual void MacroExpands(const Token &Id, const MacroInfo* MI);
    346     virtual void MacroDefined(const Token &Id, const MacroInfo *MI);
    347     virtual void MacroUndefined(const Token &Id, const MacroInfo *MI);
    348     virtual void InclusionDirective(SourceLocation HashLoc,
    349                                     const Token &IncludeTok,
    350                                     llvm::StringRef FileName,
    351                                     bool IsAngled,
    352                                     const FileEntry *File,
    353                                     SourceLocation EndLoc,
    354                                     llvm::StringRef SearchPath,
    355                                     llvm::StringRef RelativePath);
    356   };
    357 } // end namespace clang
    358 
    359 inline void* operator new(size_t bytes, clang::PreprocessingRecord& PR,
    360                           unsigned alignment) throw() {
    361   return PR.Allocate(bytes, alignment);
    362 }
    363 
    364 inline void operator delete(void* ptr, clang::PreprocessingRecord& PR,
    365                             unsigned) throw() {
    366   PR.Deallocate(ptr);
    367 }
    368 
    369 #endif // LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
    370