1 //===--- PreprocessingRecord.h - Record of Preprocessing --------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the PreprocessingRecord class, which maintains a record
11 // of what occurred during preprocessing.
13 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
15 #define LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
17 #include "clang/Lex/PPCallbacks.h"
18 #include "clang/Basic/SourceLocation.h"
19 #include "llvm/ADT/DenseMap.h"
20 #include "llvm/Support/Allocator.h"
25 class PreprocessingRecord;
28 /// \brief Allocates memory within a Clang preprocessing record.
29 void* operator new(size_t bytes, clang::PreprocessingRecord& PR,
30 unsigned alignment = 8) throw();
32 /// \brief Frees memory allocated in a Clang preprocessing record.
33 void operator delete(void* ptr, clang::PreprocessingRecord& PR,
37 class MacroDefinition;
40 /// \brief Base class that describes a preprocessed entity, which may be a
41 /// preprocessor directive or macro instantiation.
42 class PreprocessedEntity {
44 /// \brief The kind of preprocessed entity an object describes.
46 /// \brief A macro instantiation.
47 MacroInstantiationKind,
49 /// \brief A preprocessing directive whose kind is not specified.
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,
55 /// \brief A macro definition.
58 /// \brief An inclusion directive, such as \c #include, \c
59 /// #import, or \c #include_next.
60 InclusionDirectiveKind,
62 FirstPreprocessingDirective = PreprocessingDirectiveKind,
63 LastPreprocessingDirective = InclusionDirectiveKind
67 /// \brief The kind of preprocessed entity that this object describes.
70 /// \brief The source range that covers this preprocessed entity.
74 PreprocessedEntity(EntityKind Kind, SourceRange Range)
75 : Kind(Kind), Range(Range) { }
78 /// \brief Retrieve the kind of preprocessed entity stored in this object.
79 EntityKind getKind() const { return Kind; }
81 /// \brief Retrieve the source range that covers this entire preprocessed
83 SourceRange getSourceRange() const { return Range; }
85 // Implement isa/cast/dyncast/etc.
86 static bool classof(const PreprocessedEntity *) { return true; }
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);
95 void* operator new(size_t bytes, void* mem) throw() {
99 void operator delete(void* ptr, PreprocessingRecord& PR,
100 unsigned alignment) throw() {
101 return ::operator delete(ptr, PR, alignment);
104 void operator delete(void*, std::size_t) throw() { }
105 void operator delete(void*, void*) throw() { }
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();
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;
118 /// \brief The definition of this macro.
119 MacroDefinition *Definition;
122 MacroInstantiation(IdentifierInfo *Name, SourceRange Range,
123 MacroDefinition *Definition)
124 : PreprocessedEntity(MacroInstantiationKind, Range), Name(Name),
125 Definition(Definition) { }
127 /// \brief The name of the macro being instantiated.
128 IdentifierInfo *getName() const { return Name; }
130 /// \brief The definition of the macro being instantiated.
131 MacroDefinition *getDefinition() const { return Definition; }
133 // Implement isa/cast/dyncast/etc.
134 static bool classof(const PreprocessedEntity *PE) {
135 return PE->getKind() == MacroInstantiationKind;
137 static bool classof(const MacroInstantiation *) { return true; }
141 /// \brief Records the presence of a preprocessor directive.
142 class PreprocessingDirective : public PreprocessedEntity {
144 PreprocessingDirective(EntityKind Kind, SourceRange Range)
145 : PreprocessedEntity(Kind, Range) { }
147 // Implement isa/cast/dyncast/etc.
148 static bool classof(const PreprocessedEntity *PD) {
149 return PD->getKind() >= FirstPreprocessingDirective &&
150 PD->getKind() <= LastPreprocessingDirective;
152 static bool classof(const PreprocessingDirective *) { return true; }
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;
160 /// \brief The location of the macro name in the macro definition.
161 SourceLocation Location;
164 explicit MacroDefinition(const IdentifierInfo *Name, SourceLocation Location,
166 : PreprocessingDirective(MacroDefinitionKind, Range), Name(Name),
167 Location(Location) { }
169 /// \brief Retrieve the name of the macro being defined.
170 const IdentifierInfo *getName() const { return Name; }
172 /// \brief Retrieve the location of the macro name in the definition.
173 SourceLocation getLocation() const { return Location; }
175 // Implement isa/cast/dyncast/etc.
176 static bool classof(const PreprocessedEntity *PE) {
177 return PE->getKind() == MacroDefinitionKind;
179 static bool classof(const MacroDefinition *) { return true; }
182 /// \brief Record the location of an inclusion directive, such as an
183 /// \c #include or \c #import statement.
184 class InclusionDirective : public PreprocessingDirective {
186 /// \brief The kind of inclusion directives known to the
189 /// \brief An \c #include directive.
191 /// \brief An Objective-C \c #import directive.
193 /// \brief A GNU \c #include_next directive.
195 /// \brief A Clang \c #__include_macros directive.
200 /// \brief The name of the file that was included, as written in
202 llvm::StringRef FileName;
204 /// \brief Whether the file name was in quotation marks; otherwise, it was
205 /// in angle brackets.
206 unsigned InQuotes : 1;
208 /// \brief The kind of inclusion directive we have.
210 /// This is a value of type InclusionKind.
213 /// \brief The file that was included.
214 const FileEntry *File;
217 InclusionDirective(PreprocessingRecord &PPRec,
218 InclusionKind Kind, llvm::StringRef FileName,
219 bool InQuotes, const FileEntry *File, SourceRange Range);
221 /// \brief Determine what kind of inclusion directive this is.
222 InclusionKind getKind() const { return static_cast<InclusionKind>(Kind); }
224 /// \brief Retrieve the included file name as it was written in the source.
225 llvm::StringRef getFileName() const { return FileName; }
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; }
231 /// \brief Retrieve the file entry for the actual file that was included
232 /// by this directive.
233 const FileEntry *getFile() const { return File; }
235 // Implement isa/cast/dyncast/etc.
236 static bool classof(const PreprocessedEntity *PE) {
237 return PE->getKind() == InclusionDirectiveKind;
239 static bool classof(const InclusionDirective *) { return true; }
242 /// \brief An abstract class that should be subclassed by any external source
243 /// of preprocessing record entries.
244 class ExternalPreprocessingRecordSource {
246 virtual ~ExternalPreprocessingRecordSource();
248 /// \brief Read any preallocated preprocessed entities from the external
250 virtual void ReadPreprocessedEntities() = 0;
252 /// \brief Read the preprocessed entity at the given offset.
253 virtual PreprocessedEntity *
254 ReadPreprocessedEntityAtOffset(uint64_t Offset) = 0;
257 /// \brief A record of the steps taken while preprocessing a source file,
258 /// including the various preprocessing directives processed, macros
259 /// instantiated, etc.
260 class PreprocessingRecord : public PPCallbacks {
261 /// \brief Allocator used to store preprocessing objects.
262 llvm::BumpPtrAllocator BumpAlloc;
264 /// \brief The set of preprocessed entities in this record, in order they
266 std::vector<PreprocessedEntity *> PreprocessedEntities;
268 /// \brief Mapping from MacroInfo structures to their definitions.
269 llvm::DenseMap<const MacroInfo *, MacroDefinition *> MacroDefinitions;
271 /// \brief External source of preprocessed entities.
272 ExternalPreprocessingRecordSource *ExternalSource;
274 /// \brief The number of preallocated entities (that are known to the
275 /// external source).
276 unsigned NumPreallocatedEntities;
278 /// \brief Whether we have already loaded all of the preallocated entities.
279 mutable bool LoadedPreallocatedEntities;
281 void MaybeLoadPreallocatedEntities() const ;
284 PreprocessingRecord();
286 /// \brief Allocate memory in the preprocessing record.
287 void *Allocate(unsigned Size, unsigned Align = 8) {
288 return BumpAlloc.Allocate(Size, Align);
291 /// \brief Deallocate memory in the preprocessing record.
292 void Deallocate(void *Ptr) { }
294 // Iteration over the preprocessed entities.
295 typedef std::vector<PreprocessedEntity *>::iterator iterator;
296 typedef std::vector<PreprocessedEntity *>::const_iterator const_iterator;
297 iterator begin(bool OnlyLocalEntities = false);
298 iterator end(bool OnlyLocalEntities = false);
299 const_iterator begin(bool OnlyLocalEntities = false) const;
300 const_iterator end(bool OnlyLocalEntities = false) const;
302 /// \brief Add a new preprocessed entity to this record.
303 void addPreprocessedEntity(PreprocessedEntity *Entity);
305 /// \brief Set the external source for preprocessed entities.
306 void SetExternalSource(ExternalPreprocessingRecordSource &Source,
307 unsigned NumPreallocatedEntities);
309 /// \brief Retrieve the external source for preprocessed entities.
310 ExternalPreprocessingRecordSource *getExternalSource() const {
311 return ExternalSource;
314 unsigned getNumPreallocatedEntities() const {
315 return NumPreallocatedEntities;
318 /// \brief Set the preallocated entry at the given index to the given
319 /// preprocessed entity.
320 void SetPreallocatedEntity(unsigned Index, PreprocessedEntity *Entity);
322 /// \brief Register a new macro definition.
323 void RegisterMacroDefinition(MacroInfo *Macro, MacroDefinition *MD);
325 /// \brief Retrieve the preprocessed entity at the given index.
326 PreprocessedEntity *getPreprocessedEntity(unsigned Index) {
327 assert(Index < PreprocessedEntities.size() &&
328 "Out-of-bounds preprocessed entity");
329 return PreprocessedEntities[Index];
332 /// \brief Retrieve the macro definition that corresponds to the given
334 MacroDefinition *findMacroDefinition(const MacroInfo *MI);
336 virtual void MacroExpands(const Token &Id, const MacroInfo* MI);
337 virtual void MacroDefined(const Token &Id, const MacroInfo *MI);
338 virtual void MacroUndefined(const Token &Id, const MacroInfo *MI);
339 virtual void InclusionDirective(SourceLocation HashLoc,
340 const Token &IncludeTok,
341 llvm::StringRef FileName,
343 const FileEntry *File,
344 SourceLocation EndLoc);
346 } // end namespace clang
348 inline void* operator new(size_t bytes, clang::PreprocessingRecord& PR,
349 unsigned alignment) throw() {
350 return PR.Allocate(bytes, alignment);
353 inline void operator delete(void* ptr, clang::PreprocessingRecord& PR,
358 #endif // LLVM_CLANG_LEX_PREPROCESSINGRECORD_H