PreprocessingRecord.h revision 94dc8f640ebea52241412512ed48601626edbc58
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/Basic/SourceLocation.h"
18#include "llvm/Support/Allocator.h"
19#include <vector>
20
21namespace clang {
22  class IdentifierInfo;
23  class PreprocessingRecord;
24}
25
26/// \brief Allocates memory within a Clang preprocessing record.
27void* operator new(size_t bytes, clang::PreprocessingRecord& PR,
28                   unsigned alignment = 8) throw();
29
30/// \brief Frees memory allocated in a Clang preprocessing record.
31void operator delete(void* ptr, clang::PreprocessingRecord& PR,
32                     unsigned) throw();
33
34namespace clang {
35  class MacroDefinition;
36
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 definition of this macro.
112    MacroDefinition *Definition;
113
114  public:
115    MacroInstantiation(IdentifierInfo *Name, SourceRange Range,
116                       MacroDefinition *Definition)
117      : PreprocessedEntity(MacroInstantiationKind, Range), Name(Name),
118        Definition(Definition) { }
119
120    /// \brief The name of the macro being instantiated.
121    IdentifierInfo *getName() const { return Name; }
122
123    /// \brief The definition of the macro being instantiated.
124    MacroDefinition *getDefinition() const { return Definition; }
125
126    // Implement isa/cast/dyncast/etc.
127    static bool classof(const PreprocessedEntity *PE) {
128      return PE->getKind() == MacroInstantiationKind;
129    }
130    static bool classof(const MacroInstantiation *) { return true; }
131
132  };
133
134  /// \brief Records the presence of a preprocessor directive.
135  class PreprocessingDirective : public PreprocessedEntity {
136  public:
137    PreprocessingDirective(EntityKind Kind, SourceRange Range)
138      : PreprocessedEntity(Kind, Range) { }
139
140    // Implement isa/cast/dyncast/etc.
141    static bool classof(const PreprocessedEntity *PD) {
142      return PD->getKind() >= FirstPreprocessingDirective &&
143             PD->getKind() <= LastPreprocessingDirective;
144    }
145    static bool classof(const PreprocessingDirective *) { return true; }
146  };
147
148  /// \brief Record the location of a macro definition.
149  class MacroDefinition : public PreprocessingDirective {
150    /// \brief The name of the macro being defined.
151    const IdentifierInfo *Name;
152
153    /// \brief The location of the macro name in the macro definition.
154    SourceLocation Location;
155
156  public:
157    explicit MacroDefinition(const IdentifierInfo *Name, SourceLocation Location,
158                             SourceRange Range)
159      : PreprocessingDirective(MacroDefinitionKind, Range), Name(Name),
160        Location(Location) { }
161
162    /// \brief Retrieve the name of the macro being defined.
163    const IdentifierInfo *getName() const { return Name; }
164
165    /// \brief Retrieve the location of the macro name in the definition.
166    SourceLocation getLocation() const { return Location; }
167
168    // Implement isa/cast/dyncast/etc.
169    static bool classof(const PreprocessedEntity *PE) {
170      return PE->getKind() == MacroDefinitionKind;
171    }
172    static bool classof(const MacroDefinition *) { return true; }
173  };
174
175  /// \brief A record of the steps taken while preprocessing a source file,
176  /// including the various preprocessing directives processed, macros
177  /// instantiated, etc.
178  class PreprocessingRecord {
179    /// \brief Allocator used to store preprocessing objects.
180    llvm::BumpPtrAllocator BumpAlloc;
181
182    /// \brief The set of preprocessed entities in this record, in order they
183    /// were seen.
184    std::vector<PreprocessedEntity *> PreprocessedEntities;
185
186  public:
187    /// \brief Allocate memory in the preprocessing record.
188    void *Allocate(unsigned Size, unsigned Align = 8) {
189      return BumpAlloc.Allocate(Size, Align);
190    }
191
192    /// \brief Deallocate memory in the preprocessing record.
193    void Deallocate(void *Ptr) { }
194
195    // Iteration over the preprocessed entities.
196    typedef std::vector<PreprocessedEntity *>::iterator iterator;
197    typedef std::vector<PreprocessedEntity *>::const_iterator const_iterator;
198    iterator begin() { return PreprocessedEntities.begin(); }
199    iterator end() { return PreprocessedEntities.end(); }
200    const_iterator begin() const { return PreprocessedEntities.begin(); }
201    const_iterator end() const { return PreprocessedEntities.end(); }
202
203    /// \brief Add a new preprocessed entity to this record.
204    void addPreprocessedEntity(PreprocessedEntity *Entity);
205  };
206} // end namespace clang
207
208inline void* operator new(size_t bytes, clang::PreprocessingRecord& PR,
209                          unsigned alignment) throw() {
210  return PR.Allocate(bytes, alignment);
211}
212
213inline void operator delete(void* ptr, clang::PreprocessingRecord& PR,
214                            unsigned) throw() {
215  PR.Deallocate(ptr);
216}
217
218#endif // LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
219