PreprocessingRecord.h revision 8f7c540ac42370c40ebcdc4b69018c938faf94ec
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/DenseMap.h"
21#include "llvm/Support/Allocator.h"
22#include <vector>
23
24namespace clang {
25  class IdentifierInfo;
26  class PreprocessingRecord;
27}
28
29/// \brief Allocates memory within a Clang preprocessing record.
30void* operator new(size_t bytes, clang::PreprocessingRecord& PR,
31                   unsigned alignment = 8) throw();
32
33/// \brief Frees memory allocated in a Clang preprocessing record.
34void operator delete(void* ptr, clang::PreprocessingRecord& PR,
35                     unsigned) throw();
36
37namespace clang {
38  class MacroDefinition;
39  class FileEntry;
40
41  /// \brief Base class that describes a preprocessed entity, which may be a
42  /// preprocessor directive or macro expansion.
43  class PreprocessedEntity {
44  public:
45    /// \brief The kind of preprocessed entity an object describes.
46    enum EntityKind {
47      /// \brief A macro expansion.
48      MacroExpansionKind,
49
50      /// \brief A preprocessing directive whose kind is not specified.
51      ///
52      /// This kind will be used for any preprocessing directive that does not
53      /// have a more specific kind within the \c DirectiveKind enumeration.
54      PreprocessingDirectiveKind,
55
56      /// \brief A macro definition.
57      MacroDefinitionKind,
58
59      /// \brief An inclusion directive, such as \c #include, \c
60      /// #import, or \c #include_next.
61      InclusionDirectiveKind,
62
63      FirstPreprocessingDirective = PreprocessingDirectiveKind,
64      LastPreprocessingDirective = InclusionDirectiveKind
65    };
66
67  private:
68    /// \brief The kind of preprocessed entity that this object describes.
69    EntityKind Kind;
70
71    /// \brief The source range that covers this preprocessed entity.
72    SourceRange Range;
73
74  protected:
75    PreprocessedEntity(EntityKind Kind, SourceRange Range)
76      : Kind(Kind), Range(Range) { }
77
78  public:
79    /// \brief Retrieve the kind of preprocessed entity stored in this object.
80    EntityKind getKind() const { return Kind; }
81
82    /// \brief Retrieve the source range that covers this entire preprocessed
83    /// entity.
84    SourceRange getSourceRange() const { return Range; }
85
86    // Implement isa/cast/dyncast/etc.
87    static bool classof(const PreprocessedEntity *) { return true; }
88
89    // Only allow allocation of preprocessed entities using the allocator
90    // in PreprocessingRecord or by doing a placement new.
91    void* operator new(size_t bytes, PreprocessingRecord& PR,
92                       unsigned alignment = 8) throw() {
93      return ::operator new(bytes, PR, alignment);
94    }
95
96    void* operator new(size_t bytes, void* mem) throw() {
97      return mem;
98    }
99
100    void operator delete(void* ptr, PreprocessingRecord& PR,
101                         unsigned alignment) throw() {
102      return ::operator delete(ptr, PR, alignment);
103    }
104
105    void operator delete(void*, std::size_t) throw() { }
106    void operator delete(void*, void*) throw() { }
107
108  private:
109    // Make vanilla 'new' and 'delete' illegal for preprocessed entities.
110    void* operator new(size_t bytes) throw();
111    void operator delete(void* data) throw();
112  };
113
114  /// \brief Records the presence of a preprocessor directive.
115  class PreprocessingDirective : public PreprocessedEntity {
116  public:
117    PreprocessingDirective(EntityKind Kind, SourceRange Range)
118      : PreprocessedEntity(Kind, Range) { }
119
120    // Implement isa/cast/dyncast/etc.
121    static bool classof(const PreprocessedEntity *PD) {
122      return PD->getKind() >= FirstPreprocessingDirective &&
123             PD->getKind() <= LastPreprocessingDirective;
124    }
125    static bool classof(const PreprocessingDirective *) { return true; }
126  };
127
128  /// \brief Record the location of a macro definition.
129  class MacroDefinition : public PreprocessingDirective {
130    /// \brief The name of the macro being defined.
131    const IdentifierInfo *Name;
132
133    /// \brief The location of the macro name in the macro definition.
134    SourceLocation Location;
135
136  public:
137    explicit MacroDefinition(const IdentifierInfo *Name, SourceLocation Location,
138                             SourceRange Range)
139      : PreprocessingDirective(MacroDefinitionKind, Range), Name(Name),
140        Location(Location) { }
141
142    /// \brief Retrieve the name of the macro being defined.
143    const IdentifierInfo *getName() const { return Name; }
144
145    /// \brief Retrieve the location of the macro name in the definition.
146    SourceLocation getLocation() const { return Location; }
147
148    // Implement isa/cast/dyncast/etc.
149    static bool classof(const PreprocessedEntity *PE) {
150      return PE->getKind() == MacroDefinitionKind;
151    }
152    static bool classof(const MacroDefinition *) { return true; }
153  };
154
155  /// \brief Records the location of a macro expansion.
156  class MacroExpansion : public PreprocessedEntity {
157    /// \brief The definition of this macro or the name of the macro if it is
158    /// a builtin macro.
159    llvm::PointerUnion<IdentifierInfo *, MacroDefinition *> NameOrDef;
160
161  public:
162    MacroExpansion(IdentifierInfo *BuiltinName, SourceRange Range)
163      : PreprocessedEntity(MacroExpansionKind, Range),
164        NameOrDef(BuiltinName) { }
165
166    MacroExpansion(MacroDefinition *Definition, SourceRange Range)
167      : PreprocessedEntity(MacroExpansionKind, Range),
168        NameOrDef(Definition) { }
169
170    /// \brief True if it is a builtin macro.
171    bool isBuiltinMacro() const { return NameOrDef.is<IdentifierInfo *>(); }
172
173    /// \brief The name of the macro being expanded.
174    const IdentifierInfo *getName() const {
175      if (MacroDefinition *Def = getDefinition())
176        return Def->getName();
177      return NameOrDef.get<IdentifierInfo*>();
178    }
179
180    /// \brief The definition of the macro being expanded. May return null if
181    /// this is a builtin macro.
182    MacroDefinition *getDefinition() const {
183      return NameOrDef.dyn_cast<MacroDefinition *>();
184    }
185
186    // Implement isa/cast/dyncast/etc.
187    static bool classof(const PreprocessedEntity *PE) {
188      return PE->getKind() == MacroExpansionKind;
189    }
190    static bool classof(const MacroExpansion *) { return true; }
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 The file that was included.
225    const FileEntry *File;
226
227  public:
228    InclusionDirective(PreprocessingRecord &PPRec,
229                       InclusionKind Kind, StringRef FileName,
230                       bool InQuotes, const FileEntry *File, SourceRange Range);
231
232    /// \brief Determine what kind of inclusion directive this is.
233    InclusionKind getKind() const { return static_cast<InclusionKind>(Kind); }
234
235    /// \brief Retrieve the included file name as it was written in the source.
236    StringRef getFileName() const { return FileName; }
237
238    /// \brief Determine whether the included file name was written in quotes;
239    /// otherwise, it was written in angle brackets.
240    bool wasInQuotes() const { return InQuotes; }
241
242    /// \brief Retrieve the file entry for the actual file that was included
243    /// by this directive.
244    const FileEntry *getFile() const { return File; }
245
246    // Implement isa/cast/dyncast/etc.
247    static bool classof(const PreprocessedEntity *PE) {
248      return PE->getKind() == InclusionDirectiveKind;
249    }
250    static bool classof(const InclusionDirective *) { return true; }
251  };
252
253  /// \brief An abstract class that should be subclassed by any external source
254  /// of preprocessing record entries.
255  class ExternalPreprocessingRecordSource {
256  public:
257    virtual ~ExternalPreprocessingRecordSource();
258
259    /// \brief Read any preallocated preprocessed entities from the external
260    /// source.
261    virtual void ReadPreprocessedEntities() = 0;
262
263    /// \brief Read the preprocessed entity at the given offset.
264    virtual PreprocessedEntity *
265    ReadPreprocessedEntityAtOffset(uint64_t Offset) = 0;
266  };
267
268  /// \brief A record of the steps taken while preprocessing a source file,
269  /// including the various preprocessing directives processed, macros
270  /// expanded, etc.
271  class PreprocessingRecord : public PPCallbacks {
272    /// \brief Whether we should include nested macro expansions in
273    /// the preprocessing record.
274    bool IncludeNestedMacroExpansions;
275
276    /// \brief Allocator used to store preprocessing objects.
277    llvm::BumpPtrAllocator BumpAlloc;
278
279    /// \brief The set of preprocessed entities in this record, in order they
280    /// were seen.
281    std::vector<PreprocessedEntity *> PreprocessedEntities;
282
283    /// \brief The set of preprocessed entities in this record that have been
284    /// loaded from external sources.
285    ///
286    /// The entries in this vector are loaded lazily from the external source,
287    /// and are referenced by the iterator using negative indices.
288    std::vector<PreprocessedEntity *> LoadedPreprocessedEntities;
289
290    /// \brief Mapping from MacroInfo structures to their definitions.
291    llvm::DenseMap<const MacroInfo *, MacroDefinition *> MacroDefinitions;
292
293    /// \brief External source of preprocessed entities.
294    ExternalPreprocessingRecordSource *ExternalSource;
295
296    /// \brief Whether we have already loaded all of the preallocated entities.
297    mutable bool LoadedPreallocatedEntities;
298
299    void MaybeLoadPreallocatedEntities() const ;
300
301  public:
302    /// \brief Construct a new preprocessing record.
303    explicit PreprocessingRecord(bool IncludeNestedMacroExpansions);
304
305    /// \brief Allocate memory in the preprocessing record.
306    void *Allocate(unsigned Size, unsigned Align = 8) {
307      return BumpAlloc.Allocate(Size, Align);
308    }
309
310    /// \brief Deallocate memory in the preprocessing record.
311    void Deallocate(void *Ptr) { }
312
313    size_t getTotalMemory() const;
314
315    // Iteration over the preprocessed entities.
316    class iterator {
317      PreprocessingRecord *Self;
318
319      /// \brief Position within the preprocessed entity sequence.
320      ///
321      /// In a complete iteration, the Position field walks the range [-M, N),
322      /// where negative values are used to indicate preprocessed entities
323      /// loaded from the external source while non-negative values are used to
324      /// indicate preprocessed entities introduced by the current preprocessor.
325      /// However, to provide iteration in source order (for, e.g., chained
326      /// precompiled headers), dereferencing the iterator flips the negative
327      /// values (corresponding to loaded entities), so that position -M
328      /// corresponds to element 0 in the loaded entities vector, position -M+1
329      /// corresponds to element 1 in the loaded entities vector, etc. This
330      /// gives us a reasonably efficient, source-order walk.
331      int Position;
332
333    public:
334      typedef PreprocessedEntity *value_type;
335      typedef value_type&         reference;
336      typedef value_type*         pointer;
337      typedef std::random_access_iterator_tag iterator_category;
338      typedef int                 difference_type;
339
340      iterator() : Self(0), Position(0) { }
341
342      iterator(PreprocessingRecord *Self, int Position)
343        : Self(Self), Position(Position) { }
344
345      reference operator*() const {
346        if (Position < 0)
347          return Self->LoadedPreprocessedEntities.end()[Position];
348        return Self->PreprocessedEntities[Position];
349      }
350
351      pointer operator->() const {
352        if (Position < 0)
353          return &Self->LoadedPreprocessedEntities.end()[Position];
354
355        return &Self->PreprocessedEntities[Position];
356      }
357
358      reference operator[](difference_type D) {
359        return *(*this + D);
360      }
361
362      iterator &operator++() {
363        ++Position;
364        return *this;
365      }
366
367      iterator operator++(int) {
368        iterator Prev(*this);
369        ++Position;
370        return Prev;
371      }
372
373      iterator &operator--() {
374        --Position;
375        return *this;
376      }
377
378      iterator operator--(int) {
379        iterator Prev(*this);
380        --Position;
381        return Prev;
382      }
383
384      friend bool operator==(const iterator &X, const iterator &Y) {
385        return X.Position == Y.Position;
386      }
387
388      friend bool operator!=(const iterator &X, const iterator &Y) {
389        return X.Position != Y.Position;
390      }
391
392      friend bool operator<(const iterator &X, const iterator &Y) {
393        return X.Position < Y.Position;
394      }
395
396      friend bool operator>(const iterator &X, const iterator &Y) {
397        return X.Position > Y.Position;
398      }
399
400      friend bool operator<=(const iterator &X, const iterator &Y) {
401        return X.Position < Y.Position;
402      }
403
404      friend bool operator>=(const iterator &X, const iterator &Y) {
405        return X.Position > Y.Position;
406      }
407
408      friend iterator& operator+=(iterator &X, difference_type D) {
409        X.Position += D;
410        return X;
411      }
412
413      friend iterator& operator-=(iterator &X, difference_type D) {
414        X.Position -= D;
415        return X;
416      }
417
418      friend iterator operator+(iterator X, difference_type D) {
419        X.Position += D;
420        return X;
421      }
422
423      friend iterator operator+(difference_type D, iterator X) {
424        X.Position += D;
425        return X;
426      }
427
428      friend difference_type operator-(const iterator &X, const iterator &Y) {
429        return X.Position - Y.Position;
430      }
431
432      friend iterator operator-(iterator X, difference_type D) {
433        X.Position -= D;
434        return X;
435      }
436    };
437    friend class iterator;
438
439    iterator begin(bool OnlyLocalEntities = false);
440    iterator end(bool OnlyLocalEntities = false);
441
442    /// \brief Add a new preprocessed entity to this record.
443    void addPreprocessedEntity(PreprocessedEntity *Entity);
444
445    /// \brief Set the external source for preprocessed entities.
446    void SetExternalSource(ExternalPreprocessingRecordSource &Source);
447
448    /// \brief Retrieve the external source for preprocessed entities.
449    ExternalPreprocessingRecordSource *getExternalSource() const {
450      return ExternalSource;
451    }
452
453    /// \brief Allocate space for a new set of loaded preprocessed entities.
454    ///
455    /// \returns The index into the set of loaded preprocessed entities, which
456    /// corresponds to the first newly-allocated entity.
457    unsigned allocateLoadedEntities(unsigned NumEntities);
458
459    /// \brief Set the preallocated entry at the given index to the given
460    /// preprocessed entity, which was loaded from the external source.
461    void setLoadedPreallocatedEntity(unsigned Index,
462                                     PreprocessedEntity *Entity);
463
464    /// \brief Register a new macro definition.
465    void RegisterMacroDefinition(MacroInfo *Macro, MacroDefinition *MD);
466
467    /// \brief Retrieve the loaded preprocessed entity at the given index.
468    PreprocessedEntity *getLoadedPreprocessedEntity(unsigned Index) {
469      assert(Index < LoadedPreprocessedEntities.size() &&
470             "Out-of bounds loaded preprocessed entity");
471      return LoadedPreprocessedEntities[Index];
472    }
473
474    /// \brief Determine the number of preprocessed entities that were
475    /// loaded (or can be loaded) from an external source.
476    unsigned getNumLoadedPreprocessedEntities() const {
477      return LoadedPreprocessedEntities.size();
478    }
479
480    /// \brief Retrieve the macro definition that corresponds to the given
481    /// \c MacroInfo.
482    MacroDefinition *findMacroDefinition(const MacroInfo *MI);
483
484    virtual void MacroExpands(const Token &Id, const MacroInfo* MI,
485                              SourceRange Range);
486    virtual void MacroDefined(const Token &Id, const MacroInfo *MI);
487    virtual void MacroUndefined(const Token &Id, const MacroInfo *MI);
488    virtual void InclusionDirective(SourceLocation HashLoc,
489                                    const Token &IncludeTok,
490                                    StringRef FileName,
491                                    bool IsAngled,
492                                    const FileEntry *File,
493                                    SourceLocation EndLoc,
494                                    StringRef SearchPath,
495                                    StringRef RelativePath);
496  };
497} // end namespace clang
498
499inline void* operator new(size_t bytes, clang::PreprocessingRecord& PR,
500                          unsigned alignment) throw() {
501  return PR.Allocate(bytes, alignment);
502}
503
504inline void operator delete(void* ptr, clang::PreprocessingRecord& PR,
505                            unsigned) throw() {
506  PR.Deallocate(ptr);
507}
508
509#endif // LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
510