PreprocessingRecord.h revision ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0ed
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 instantiation.
42  class PreprocessedEntity {
43  public:
44    /// \brief The kind of preprocessed entity an object describes.
45    enum EntityKind {
46      /// \brief A macro instantiation.
47      MacroInstantiationKind,
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 instantiation.
114  class MacroInstantiation : public PreprocessedEntity {
115    /// \brief The name of the macro being instantiation.
116    IdentifierInfo *Name;
117
118    /// \brief The definition of this macro.
119    MacroDefinition *Definition;
120
121  public:
122    MacroInstantiation(IdentifierInfo *Name, SourceRange Range,
123                       MacroDefinition *Definition)
124      : PreprocessedEntity(MacroInstantiationKind, Range), Name(Name),
125        Definition(Definition) { }
126
127    /// \brief The name of the macro being instantiated.
128    IdentifierInfo *getName() const { return Name; }
129
130    /// \brief The definition of the macro being instantiated.
131    MacroDefinition *getDefinition() const { return Definition; }
132
133    // Implement isa/cast/dyncast/etc.
134    static bool classof(const PreprocessedEntity *PE) {
135      return PE->getKind() == MacroInstantiationKind;
136    }
137    static bool classof(const MacroInstantiation *) { 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    std::string 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    explicit InclusionDirective(InclusionKind Kind,
218                                const std::string &FileName, bool InQuotes,
219                                const FileEntry *File, SourceRange Range)
220      : PreprocessingDirective(InclusionDirectiveKind, Range),
221        FileName(FileName), InQuotes(InQuotes), Kind(Kind), File(File) { }
222
223    /// \brief Determine what kind of inclusion directive this is.
224    InclusionKind getKind() const { return static_cast<InclusionKind>(Kind); }
225
226    /// \brief Retrieve the included file name as it was written in the source.
227    llvm::StringRef getFileName() const { return FileName; }
228
229    /// \brief Determine whether the included file name was written in quotes;
230    /// otherwise, it was written in angle brackets.
231    bool wasInQuotes() const { return InQuotes; }
232
233    /// \brief Retrieve the file entry for the actual file that was included
234    /// by this directive.
235    const FileEntry *getFile() const { return File; }
236
237    // Implement isa/cast/dyncast/etc.
238    static bool classof(const PreprocessedEntity *PE) {
239      return PE->getKind() == InclusionDirectiveKind;
240    }
241    static bool classof(const InclusionDirective *) { return true; }
242  };
243
244  /// \brief An abstract class that should be subclassed by any external source
245  /// of preprocessing record entries.
246  class ExternalPreprocessingRecordSource {
247  public:
248    virtual ~ExternalPreprocessingRecordSource();
249
250    /// \brief Read any preallocated preprocessed entities from the external
251    /// source.
252    virtual void ReadPreprocessedEntities() = 0;
253  };
254
255  /// \brief A record of the steps taken while preprocessing a source file,
256  /// including the various preprocessing directives processed, macros
257  /// instantiated, etc.
258  class PreprocessingRecord : public PPCallbacks {
259    /// \brief Allocator used to store preprocessing objects.
260    llvm::BumpPtrAllocator BumpAlloc;
261
262    /// \brief The set of preprocessed entities in this record, in order they
263    /// were seen.
264    std::vector<PreprocessedEntity *> PreprocessedEntities;
265
266    /// \brief Mapping from MacroInfo structures to their definitions.
267    llvm::DenseMap<const MacroInfo *, MacroDefinition *> MacroDefinitions;
268
269    /// \brief External source of preprocessed entities.
270    ExternalPreprocessingRecordSource *ExternalSource;
271
272    /// \brief The number of preallocated entities (that are known to the
273    /// external source).
274    unsigned NumPreallocatedEntities;
275
276    /// \brief Whether we have already loaded all of the preallocated entities.
277    mutable bool LoadedPreallocatedEntities;
278
279    void MaybeLoadPreallocatedEntities() const ;
280
281  public:
282    PreprocessingRecord();
283
284    /// \brief Allocate memory in the preprocessing record.
285    void *Allocate(unsigned Size, unsigned Align = 8) {
286      return BumpAlloc.Allocate(Size, Align);
287    }
288
289    /// \brief Deallocate memory in the preprocessing record.
290    void Deallocate(void *Ptr) { }
291
292    // Iteration over the preprocessed entities.
293    typedef std::vector<PreprocessedEntity *>::iterator iterator;
294    typedef std::vector<PreprocessedEntity *>::const_iterator const_iterator;
295    iterator begin(bool OnlyLocalEntities = false);
296    iterator end(bool OnlyLocalEntities = false);
297    const_iterator begin(bool OnlyLocalEntities = false) const;
298    const_iterator end(bool OnlyLocalEntities = false) const;
299
300    /// \brief Add a new preprocessed entity to this record.
301    void addPreprocessedEntity(PreprocessedEntity *Entity);
302
303    /// \brief Set the external source for preprocessed entities.
304    void SetExternalSource(ExternalPreprocessingRecordSource &Source,
305                           unsigned NumPreallocatedEntities);
306
307    unsigned getNumPreallocatedEntities() const {
308      return NumPreallocatedEntities;
309    }
310
311    /// \brief Set the preallocated entry at the given index to the given
312    /// preprocessed entity.
313    void SetPreallocatedEntity(unsigned Index, PreprocessedEntity *Entity);
314
315    /// \brief Register a new macro definition.
316    void RegisterMacroDefinition(MacroInfo *Macro, MacroDefinition *MD);
317
318    /// \brief Retrieve the preprocessed entity at the given index.
319    PreprocessedEntity *getPreprocessedEntity(unsigned Index) {
320      assert(Index < PreprocessedEntities.size() &&
321             "Out-of-bounds preprocessed entity");
322      return PreprocessedEntities[Index];
323    }
324
325    /// \brief Retrieve the macro definition that corresponds to the given
326    /// \c MacroInfo.
327    MacroDefinition *findMacroDefinition(const MacroInfo *MI);
328
329    virtual void MacroExpands(const Token &Id, const MacroInfo* MI);
330    virtual void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI);
331    virtual void MacroUndefined(SourceLocation Loc, const IdentifierInfo *II,
332                                const MacroInfo *MI);
333    virtual void InclusionDirective(SourceLocation HashLoc,
334                                    const Token &IncludeTok,
335                                    llvm::StringRef FileName,
336                                    bool IsAngled,
337                                    const FileEntry *File,
338                                    SourceLocation EndLoc);
339  };
340} // end namespace clang
341
342inline void* operator new(size_t bytes, clang::PreprocessingRecord& PR,
343                          unsigned alignment) throw() {
344  return PR.Allocate(bytes, alignment);
345}
346
347inline void operator delete(void* ptr, clang::PreprocessingRecord& PR,
348                            unsigned) throw() {
349  PR.Deallocate(ptr);
350}
351
352#endif // LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
353