PreprocessingRecord.h revision 4ae8f298b1ea51b4c2234f9148e2e4349c9bdd23
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/PointerUnion.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  /// \brief Base class that describes a preprocessed entity, which may be a
38  /// preprocessor directive or macro instantiation.
39  class PreprocessedEntity {
40  public:
41    /// \brief The kind of preprocessed entity an object describes.
42    enum EntityKind {
43      /// \brief A macro instantiation.
44      MacroInstantiationKind,
45
46      /// \brief A preprocessing directive whose kind is not specified.
47      ///
48      /// This kind will be used for any preprocessing directive that does not
49      /// have a more specific kind within the \c DirectiveKind enumeration.
50      PreprocessingDirectiveKind,
51
52      /// \brief A macro definition.
53      MacroDefinitionKind,
54
55      FirstPreprocessingDirective = PreprocessingDirectiveKind,
56      LastPreprocessingDirective = MacroDefinitionKind
57    };
58
59  private:
60    /// \brief The kind of preprocessed entity that this object describes.
61    EntityKind Kind;
62
63    /// \brief The source range that covers this preprocessed entity.
64    SourceRange Range;
65
66  protected:
67    PreprocessedEntity(EntityKind Kind, SourceRange Range)
68      : Kind(Kind), Range(Range) { }
69
70  public:
71    /// \brief Retrieve the kind of preprocessed entity stored in this object.
72    EntityKind getKind() const { return Kind; }
73
74    /// \brief Retrieve the source range that covers this entire preprocessed
75    /// entity.
76    SourceRange getSourceRange() const { return Range; }
77
78    // Implement isa/cast/dyncast/etc.
79    static bool classof(const PreprocessedEntity *) { return true; }
80
81    // Only allow allocation of preprocessed entities using the allocator
82    // in PreprocessingRecord or by doing a placement new.
83    void* operator new(size_t bytes, PreprocessingRecord& PR,
84                       unsigned alignment = 8) throw() {
85      return ::operator new(bytes, PR, alignment);
86    }
87
88    void* operator new(size_t bytes, void* mem) throw() {
89      return mem;
90    }
91
92    void operator delete(void* ptr, PreprocessingRecord& PR,
93                         unsigned alignment) throw() {
94      return ::operator delete(ptr, PR, alignment);
95    }
96
97    void operator delete(void*, std::size_t) throw() { }
98    void operator delete(void*, void*) throw() { }
99
100  private:
101    // Make vanilla 'new' and 'delete' illegal for preprocessed entities.
102    void* operator new(size_t bytes) throw();
103    void operator delete(void* data) throw();
104  };
105
106  /// \brief Records the location of a macro instantiation.
107  class MacroInstantiation : public PreprocessedEntity {
108    /// \brief The name of the macro being instantiation.
109    IdentifierInfo *Name;
110
111    /// \brief The location of the definition of the macro being instantiated.
112    SourceLocation DefinitionLocation;
113
114  public:
115    MacroInstantiation(IdentifierInfo *Name, SourceRange Range,
116                       SourceLocation DefinitionLocation)
117      : PreprocessedEntity(MacroInstantiationKind, Range), Name(Name),
118        DefinitionLocation(DefinitionLocation) { }
119
120    /// \brief The name of the macro being instantiated.
121    IdentifierInfo *getName() const { return Name; }
122
123    /// \brief The location of the definition of the macro being instantiated.
124    /// FIXME: Could we just provide MacroInfo pointers instead, by teaching
125    /// the preprocessor to hold on to them when we care to keep them around?
126    SourceLocation getDefinitionLocation() const { return DefinitionLocation; }
127
128    // Implement isa/cast/dyncast/etc.
129    static bool classof(const PreprocessedEntity *PE) {
130      return PE->getKind() == MacroInstantiationKind;
131    }
132    static bool classof(const MacroInstantiation *) { return true; }
133
134  };
135
136  /// \brief Records the presence of a preprocessor directive.
137  class PreprocessingDirective : public PreprocessedEntity {
138  public:
139    PreprocessingDirective(EntityKind Kind, SourceRange Range)
140      : PreprocessedEntity(Kind, Range) { }
141
142    // Implement isa/cast/dyncast/etc.
143    static bool classof(const PreprocessedEntity *PD) {
144      return PD->getKind() >= FirstPreprocessingDirective &&
145             PD->getKind() <= LastPreprocessingDirective;
146    }
147    static bool classof(const PreprocessingDirective *) { return true; }
148  };
149
150  /// \brief Record the location of a macro definition.
151  class MacroDefinition : public PreprocessingDirective {
152    /// \brief The name of the macro being defined.
153    const IdentifierInfo *Name;
154
155    /// \brief The location of the macro name in the macro definition.
156    SourceLocation Location;
157
158  public:
159    explicit MacroDefinition(const IdentifierInfo *Name, SourceLocation Location,
160                             SourceRange Range)
161      : PreprocessingDirective(MacroDefinitionKind, Range), Name(Name),
162        Location(Location) { }
163
164    /// \brief Retrieve the name of the macro being defined.
165    const IdentifierInfo *getMacroName() const { return Name; }
166
167    /// \brief Retrieve the location of the macro name in the definition.
168    SourceLocation getLocation() const { return Location; }
169
170    // Implement isa/cast/dyncast/etc.
171    static bool classof(const PreprocessingDirective *PD) {
172      return PD->getKind() == MacroDefinitionKind;
173    }
174    static bool classof(const MacroDefinition *) { return true; }
175  };
176
177  /// \brief A record of the steps taken while preprocessing a source file,
178  /// including the various preprocessing directives processed, macros
179  /// instantiated, etc.
180  class PreprocessingRecord {
181    /// \brief Allocator used to store preprocessing objects.
182    llvm::BumpPtrAllocator BumpAlloc;
183
184    /// \brief The set of preprocessed entities in this record, in order they
185    /// were seen.
186    std::vector<PreprocessedEntity *> PreprocessedEntities;
187
188  public:
189    /// \brief Allocate memory in the preprocessing record.
190    void *Allocate(unsigned Size, unsigned Align = 8) {
191      return BumpAlloc.Allocate(Size, Align);
192    }
193
194    /// \brief Deallocate memory in the preprocessing record.
195    void Deallocate(void *Ptr) { }
196
197    // Iteration over the preprocessed entities.
198    typedef std::vector<PreprocessedEntity *>::iterator iterator;
199    typedef std::vector<PreprocessedEntity *>::const_iterator const_iterator;
200    iterator begin() { return PreprocessedEntities.begin(); }
201    iterator end() { return PreprocessedEntities.end(); }
202    const_iterator begin() const { return PreprocessedEntities.begin(); }
203    const_iterator end() const { return PreprocessedEntities.end(); }
204
205    /// \brief Add a new preprocessed entity to this record.
206    void addPreprocessedEntity(PreprocessedEntity *Entity);
207  };
208
209  /// \brief Preprocessor callback action used to populate a preprocessing
210  /// record.
211  class PopulatePreprocessingRecord : public PPCallbacks {
212    /// \brief The preprocessing record this action will populate.
213    PreprocessingRecord &Record;
214
215  public:
216    explicit PopulatePreprocessingRecord(PreprocessingRecord &Record)
217      : Record(Record) { }
218
219    virtual void MacroExpands(const Token &Id, const MacroInfo* MI);
220    virtual void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI);
221  };
222
223} // end namespace clang
224
225inline void* operator new(size_t bytes, clang::PreprocessingRecord& PR,
226                          unsigned alignment) throw() {
227  return PR.Allocate(bytes, alignment);
228}
229
230inline void operator delete(void* ptr, clang::PreprocessingRecord& PR,
231                            unsigned) throw() {
232  PR.Deallocate(ptr);
233}
234
235#endif // LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
236