PreprocessingRecord.h revision a3e9a969fd25022805a9e0ad827f3729286f6d58
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
23namespace clang {
24  class IdentifierInfo;
25  class PreprocessingRecord;
26}
27
28/// \brief Allocates memory within a Clang preprocessing record.
29void* operator new(size_t bytes, clang::PreprocessingRecord& PR,
30                   unsigned alignment = 8) throw();
31
32/// \brief Frees memory allocated in a Clang preprocessing record.
33void operator delete(void* ptr, clang::PreprocessingRecord& PR,
34                     unsigned) throw();
35
36namespace 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    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, 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    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 The set of preprocessed entities in this record that have been
273    /// loaded from external sources.
274    ///
275    /// The entries in this vector are loaded lazily from the external source,
276    /// and are referenced by the iterator using negative indices.
277    std::vector<PreprocessedEntity *> LoadedPreprocessedEntities;
278
279    /// \brief Mapping from MacroInfo structures to their definitions.
280    llvm::DenseMap<const MacroInfo *, MacroDefinition *> MacroDefinitions;
281
282    /// \brief External source of preprocessed entities.
283    ExternalPreprocessingRecordSource *ExternalSource;
284
285    /// \brief Whether we have already loaded all of the preallocated entities.
286    mutable bool LoadedPreallocatedEntities;
287
288    void MaybeLoadPreallocatedEntities() const ;
289
290  public:
291    /// \brief Construct a new preprocessing record.
292    explicit PreprocessingRecord(bool IncludeNestedMacroExpansions);
293
294    /// \brief Allocate memory in the preprocessing record.
295    void *Allocate(unsigned Size, unsigned Align = 8) {
296      return BumpAlloc.Allocate(Size, Align);
297    }
298
299    /// \brief Deallocate memory in the preprocessing record.
300    void Deallocate(void *Ptr) { }
301
302    size_t getTotalMemory() const;
303
304    // Iteration over the preprocessed entities.
305    class iterator {
306      PreprocessingRecord *Self;
307
308      /// \brief Position within the preprocessed entity sequence.
309      ///
310      /// In a complete iteration, the Position field walks the range [-M, N),
311      /// where negative values are used to indicate preprocessed entities
312      /// loaded from the external source while non-negative values are used to
313      /// indicate preprocessed entities introduced by the current preprocessor.
314      /// However, to provide iteration in source order (for, e.g., chained
315      /// precompiled headers), dereferencing the iterator flips the negative
316      /// values (corresponding to loaded entities), so that position -M
317      /// corresponds to element 0 in the loaded entities vector, position -M+1
318      /// corresponds to element 1 in the loaded entities vector, etc. This
319      /// gives us a reasonably efficient, source-order walk.
320      int Position;
321
322    public:
323      typedef PreprocessedEntity *value_type;
324      typedef value_type&         reference;
325      typedef value_type*         pointer;
326      typedef std::random_access_iterator_tag iterator_category;
327      typedef int                 difference_type;
328
329      iterator() : Self(0), Position(0) { }
330
331      iterator(PreprocessingRecord *Self, int Position)
332        : Self(Self), Position(Position) { }
333
334      reference operator*() const {
335        if (Position < 0)
336          return Self->LoadedPreprocessedEntities.end()[Position];
337        return Self->PreprocessedEntities[Position];
338      }
339
340      pointer operator->() const {
341        if (Position < 0)
342          return &Self->LoadedPreprocessedEntities.end()[Position];
343
344        return &Self->PreprocessedEntities[Position];
345      }
346
347      reference operator[](difference_type D) {
348        return *(*this + D);
349      }
350
351      iterator &operator++() {
352        ++Position;
353        return *this;
354      }
355
356      iterator operator++(int) {
357        iterator Prev(*this);
358        ++Position;
359        return Prev;
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      friend bool operator==(const iterator &X, const iterator &Y) {
374        return X.Position == Y.Position;
375      }
376
377      friend bool operator!=(const iterator &X, const iterator &Y) {
378        return X.Position != Y.Position;
379      }
380
381      friend bool operator<(const iterator &X, const iterator &Y) {
382        return X.Position < Y.Position;
383      }
384
385      friend bool operator>(const iterator &X, const iterator &Y) {
386        return X.Position > Y.Position;
387      }
388
389      friend bool operator<=(const iterator &X, const iterator &Y) {
390        return X.Position < Y.Position;
391      }
392
393      friend bool operator>=(const iterator &X, const iterator &Y) {
394        return X.Position > Y.Position;
395      }
396
397      friend iterator& operator+=(iterator &X, difference_type D) {
398        X.Position += D;
399        return X;
400      }
401
402      friend iterator& operator-=(iterator &X, difference_type D) {
403        X.Position -= D;
404        return X;
405      }
406
407      friend iterator operator+(iterator X, difference_type D) {
408        X.Position += D;
409        return X;
410      }
411
412      friend iterator operator+(difference_type D, iterator X) {
413        X.Position += D;
414        return X;
415      }
416
417      friend difference_type operator-(const iterator &X, const iterator &Y) {
418        return X.Position - Y.Position;
419      }
420
421      friend iterator operator-(iterator X, difference_type D) {
422        X.Position -= D;
423        return X;
424      }
425    };
426    friend class iterator;
427
428    iterator begin(bool OnlyLocalEntities = false);
429    iterator end(bool OnlyLocalEntities = false);
430
431    /// \brief Add a new preprocessed entity to this record.
432    void addPreprocessedEntity(PreprocessedEntity *Entity);
433
434    /// \brief Set the external source for preprocessed entities.
435    void SetExternalSource(ExternalPreprocessingRecordSource &Source);
436
437    /// \brief Retrieve the external source for preprocessed entities.
438    ExternalPreprocessingRecordSource *getExternalSource() const {
439      return ExternalSource;
440    }
441
442    /// \brief Allocate space for a new set of loaded preprocessed entities.
443    ///
444    /// \returns The index into the set of loaded preprocessed entities, which
445    /// corresponds to the first newly-allocated entity.
446    unsigned allocateLoadedEntities(unsigned NumEntities);
447
448    /// \brief Set the preallocated entry at the given index to the given
449    /// preprocessed entity, which was loaded from the external source.
450    void setLoadedPreallocatedEntity(unsigned Index,
451                                     PreprocessedEntity *Entity);
452
453    /// \brief Register a new macro definition.
454    void RegisterMacroDefinition(MacroInfo *Macro, MacroDefinition *MD);
455
456    /// \brief Retrieve the loaded preprocessed entity at the given index.
457    PreprocessedEntity *getLoadedPreprocessedEntity(unsigned Index) {
458      assert(Index < LoadedPreprocessedEntities.size() &&
459             "Out-of bounds loaded preprocessed entity");
460      return LoadedPreprocessedEntities[Index];
461    }
462
463    /// \brief Determine the number of preprocessed entities that were
464    /// loaded (or can be loaded) from an external source.
465    unsigned getNumLoadedPreprocessedEntities() const {
466      return LoadedPreprocessedEntities.size();
467    }
468
469    /// \brief Retrieve the macro definition that corresponds to the given
470    /// \c MacroInfo.
471    MacroDefinition *findMacroDefinition(const MacroInfo *MI);
472
473    virtual void MacroExpands(const Token &Id, const MacroInfo* MI,
474                              SourceRange Range);
475    virtual void MacroDefined(const Token &Id, const MacroInfo *MI);
476    virtual void MacroUndefined(const Token &Id, const MacroInfo *MI);
477    virtual void InclusionDirective(SourceLocation HashLoc,
478                                    const Token &IncludeTok,
479                                    StringRef FileName,
480                                    bool IsAngled,
481                                    const FileEntry *File,
482                                    SourceLocation EndLoc,
483                                    StringRef SearchPath,
484                                    StringRef RelativePath);
485  };
486} // end namespace clang
487
488inline void* operator new(size_t bytes, clang::PreprocessingRecord& PR,
489                          unsigned alignment) throw() {
490  return PR.Allocate(bytes, alignment);
491}
492
493inline void operator delete(void* ptr, clang::PreprocessingRecord& PR,
494                            unsigned) throw() {
495  PR.Deallocate(ptr);
496}
497
498#endif // LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
499