]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - include/clang/Lex/PreprocessingRecord.h
Vendor import of clang trunk r130700:
[FreeBSD/FreeBSD.git] / 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 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     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   /// instantiated, etc.
260   class PreprocessingRecord : public PPCallbacks {
261     /// \brief Allocator used to store preprocessing objects.
262     llvm::BumpPtrAllocator BumpAlloc;
263
264     /// \brief The set of preprocessed entities in this record, in order they
265     /// were seen.
266     std::vector<PreprocessedEntity *> PreprocessedEntities;
267     
268     /// \brief Mapping from MacroInfo structures to their definitions.
269     llvm::DenseMap<const MacroInfo *, MacroDefinition *> MacroDefinitions;
270
271     /// \brief External source of preprocessed entities.
272     ExternalPreprocessingRecordSource *ExternalSource;
273     
274     /// \brief The number of preallocated entities (that are known to the
275     /// external source).
276     unsigned NumPreallocatedEntities;
277     
278     /// \brief Whether we have already loaded all of the preallocated entities.
279     mutable bool LoadedPreallocatedEntities;
280     
281     void MaybeLoadPreallocatedEntities() const ;
282     
283   public:
284     PreprocessingRecord();
285     
286     /// \brief Allocate memory in the preprocessing record.
287     void *Allocate(unsigned Size, unsigned Align = 8) {
288       return BumpAlloc.Allocate(Size, Align);
289     }
290     
291     /// \brief Deallocate memory in the preprocessing record.
292     void Deallocate(void *Ptr) { }
293     
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;
301
302     /// \brief Add a new preprocessed entity to this record.
303     void addPreprocessedEntity(PreprocessedEntity *Entity);
304     
305     /// \brief Set the external source for preprocessed entities.
306     void SetExternalSource(ExternalPreprocessingRecordSource &Source,
307                            unsigned NumPreallocatedEntities);
308
309     /// \brief Retrieve the external source for preprocessed entities.
310     ExternalPreprocessingRecordSource *getExternalSource() const {
311       return ExternalSource;
312     }
313     
314     unsigned getNumPreallocatedEntities() const {
315       return NumPreallocatedEntities;
316     }
317     
318     /// \brief Set the preallocated entry at the given index to the given
319     /// preprocessed entity.
320     void SetPreallocatedEntity(unsigned Index, PreprocessedEntity *Entity);
321
322     /// \brief Register a new macro definition.
323     void RegisterMacroDefinition(MacroInfo *Macro, MacroDefinition *MD);
324                            
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];
330     }
331     
332     /// \brief Retrieve the macro definition that corresponds to the given
333     /// \c MacroInfo.
334     MacroDefinition *findMacroDefinition(const MacroInfo *MI);
335     
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,
342                                     bool IsAngled,
343                                     const FileEntry *File,
344                                     SourceLocation EndLoc,
345                                     llvm::StringRef SearchPath,
346                                     llvm::StringRef RelativePath);
347   };
348 } // end namespace clang
349
350 inline void* operator new(size_t bytes, clang::PreprocessingRecord& PR,
351                           unsigned alignment) throw() {
352   return PR.Allocate(bytes, alignment);
353 }
354
355 inline void operator delete(void* ptr, clang::PreprocessingRecord& PR,
356                             unsigned) throw() {
357   PR.Deallocate(ptr);
358 }
359
360 #endif // LLVM_CLANG_LEX_PREPROCESSINGRECORD_H