]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/tools/clang/include/clang/Lex/PreprocessingRecord.h
Copy head to stable/9 as part of 9.0-RELEASE release cycle.
[FreeBSD/stable/9.git] / contrib / llvm / tools / clang / include / clang / Lex / PreprocessingRecord.h
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
23 namespace clang {
24   class IdentifierInfo;
25   class PreprocessingRecord;
26 }
27
28 /// \brief Allocates memory within a Clang preprocessing record.
29 void* operator new(size_t bytes, clang::PreprocessingRecord& PR,
30                    unsigned alignment = 8) throw();
31
32 /// \brief Frees memory allocated in a Clang preprocessing record.
33 void operator delete(void* ptr, clang::PreprocessingRecord& PR,
34                      unsigned) throw();
35
36 namespace 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     llvm::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, llvm::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     llvm::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 Mapping from MacroInfo structures to their definitions.
273     llvm::DenseMap<const MacroInfo *, MacroDefinition *> MacroDefinitions;
274
275     /// \brief External source of preprocessed entities.
276     ExternalPreprocessingRecordSource *ExternalSource;
277     
278     /// \brief The number of preallocated entities (that are known to the
279     /// external source).
280     unsigned NumPreallocatedEntities;
281     
282     /// \brief Whether we have already loaded all of the preallocated entities.
283     mutable bool LoadedPreallocatedEntities;
284     
285     void MaybeLoadPreallocatedEntities() const ;
286     
287   public:
288     /// \brief Construct 
289     explicit PreprocessingRecord(bool IncludeNestedMacroExpansions);
290     
291     /// \brief Allocate memory in the preprocessing record.
292     void *Allocate(unsigned Size, unsigned Align = 8) {
293       return BumpAlloc.Allocate(Size, Align);
294     }
295     
296     /// \brief Deallocate memory in the preprocessing record.
297     void Deallocate(void *Ptr) { }
298     
299     size_t getTotalMemory() const {
300       return BumpAlloc.getTotalMemory();
301     }
302     
303     // Iteration over the preprocessed entities.
304     typedef std::vector<PreprocessedEntity *>::iterator iterator;
305     typedef std::vector<PreprocessedEntity *>::const_iterator const_iterator;
306     iterator begin(bool OnlyLocalEntities = false);
307     iterator end(bool OnlyLocalEntities = false);
308     const_iterator begin(bool OnlyLocalEntities = false) const;
309     const_iterator end(bool OnlyLocalEntities = false) const;
310
311     /// \brief Add a new preprocessed entity to this record.
312     void addPreprocessedEntity(PreprocessedEntity *Entity);
313     
314     /// \brief Set the external source for preprocessed entities.
315     void SetExternalSource(ExternalPreprocessingRecordSource &Source,
316                            unsigned NumPreallocatedEntities);
317
318     /// \brief Retrieve the external source for preprocessed entities.
319     ExternalPreprocessingRecordSource *getExternalSource() const {
320       return ExternalSource;
321     }
322     
323     unsigned getNumPreallocatedEntities() const {
324       return NumPreallocatedEntities;
325     }
326     
327     /// \brief Set the preallocated entry at the given index to the given
328     /// preprocessed entity.
329     void SetPreallocatedEntity(unsigned Index, PreprocessedEntity *Entity);
330
331     /// \brief Register a new macro definition.
332     void RegisterMacroDefinition(MacroInfo *Macro, MacroDefinition *MD);
333                            
334     /// \brief Retrieve the preprocessed entity at the given index.
335     PreprocessedEntity *getPreprocessedEntity(unsigned Index) {
336       assert(Index < PreprocessedEntities.size() &&
337              "Out-of-bounds preprocessed entity");
338       return PreprocessedEntities[Index];
339     }
340     
341     /// \brief Retrieve the macro definition that corresponds to the given
342     /// \c MacroInfo.
343     MacroDefinition *findMacroDefinition(const MacroInfo *MI);
344     
345     virtual void MacroExpands(const Token &Id, const MacroInfo* MI);
346     virtual void MacroDefined(const Token &Id, const MacroInfo *MI);
347     virtual void MacroUndefined(const Token &Id, const MacroInfo *MI);
348     virtual void InclusionDirective(SourceLocation HashLoc,
349                                     const Token &IncludeTok,
350                                     llvm::StringRef FileName,
351                                     bool IsAngled,
352                                     const FileEntry *File,
353                                     SourceLocation EndLoc,
354                                     llvm::StringRef SearchPath,
355                                     llvm::StringRef RelativePath);
356   };
357 } // end namespace clang
358
359 inline void* operator new(size_t bytes, clang::PreprocessingRecord& PR,
360                           unsigned alignment) throw() {
361   return PR.Allocate(bytes, alignment);
362 }
363
364 inline void operator delete(void* ptr, clang::PreprocessingRecord& PR,
365                             unsigned) throw() {
366   PR.Deallocate(ptr);
367 }
368
369 #endif // LLVM_CLANG_LEX_PREPROCESSINGRECORD_H