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/IdentifierTable.h"
18 #include "clang/Basic/SourceLocation.h"
19 #include "clang/Lex/PPCallbacks.h"
20 #include "llvm/ADT/DenseMap.h"
21 #include "llvm/ADT/Optional.h"
22 #include "llvm/ADT/SmallVector.h"
23 #include "llvm/ADT/iterator.h"
24 #include "llvm/Support/Allocator.h"
25 #include "llvm/Support/Compiler.h"
26 #include <vector>
27
28 namespace clang {
29 class IdentifierInfo;
30 class MacroInfo;
31 class PreprocessingRecord;
32 }
33
34 /// \brief Allocates memory within a Clang preprocessing record.
35 void* operator new(size_t bytes, clang::PreprocessingRecord& PR,
36 unsigned alignment = 8) throw();
37
38 /// \brief Frees memory allocated in a Clang preprocessing record.
39 void operator delete(void* ptr, clang::PreprocessingRecord& PR,
40 unsigned) throw();
41
42 namespace clang {
43 class MacroDefinition;
44 class FileEntry;
45
46 /// \brief Base class that describes a preprocessed entity, which may be a
47 /// preprocessor directive or macro expansion.
48 class PreprocessedEntity {
49 public:
50 /// \brief The kind of preprocessed entity an object describes.
51 enum EntityKind {
52 /// \brief Indicates a problem trying to load the preprocessed entity.
53 InvalidKind,
54
55 /// \brief A macro expansion.
56 MacroExpansionKind,
57
58 /// \defgroup Preprocessing directives
59 /// @{
60
61 /// \brief A macro definition.
62 MacroDefinitionKind,
63
64 /// \brief An inclusion directive, such as \c \#include, \c
65 /// \#import, or \c \#include_next.
66 InclusionDirectiveKind,
67
68 /// @}
69
70 FirstPreprocessingDirective = MacroDefinitionKind,
71 LastPreprocessingDirective = InclusionDirectiveKind
72 };
73
74 private:
75 /// \brief The kind of preprocessed entity that this object describes.
76 EntityKind Kind;
77
78 /// \brief The source range that covers this preprocessed entity.
79 SourceRange Range;
80
81 protected:
PreprocessedEntity(EntityKind Kind,SourceRange Range)82 PreprocessedEntity(EntityKind Kind, SourceRange Range)
83 : Kind(Kind), Range(Range) { }
84
85 friend class PreprocessingRecord;
86
87 public:
88 /// \brief Retrieve the kind of preprocessed entity stored in this object.
getKind()89 EntityKind getKind() const { return Kind; }
90
91 /// \brief Retrieve the source range that covers this entire preprocessed
92 /// entity.
getSourceRange()93 SourceRange getSourceRange() const LLVM_READONLY { return Range; }
94
95 /// \brief Returns true if there was a problem loading the preprocessed
96 /// entity.
isInvalid()97 bool isInvalid() const { return Kind == InvalidKind; }
98
99 // Only allow allocation of preprocessed entities using the allocator
100 // in PreprocessingRecord or by doing a placement new.
101 void* operator new(size_t bytes, PreprocessingRecord& PR,
throw()102 unsigned alignment = 8) throw() {
103 return ::operator new(bytes, PR, alignment);
104 }
105
new(size_t bytes,void * mem)106 void* operator new(size_t bytes, void* mem) throw() {
107 return mem;
108 }
109
delete(void * ptr,PreprocessingRecord & PR,unsigned alignment)110 void operator delete(void* ptr, PreprocessingRecord& PR,
111 unsigned alignment) throw() {
112 return ::operator delete(ptr, PR, alignment);
113 }
114
delete(void *,std::size_t)115 void operator delete(void*, std::size_t) throw() { }
delete(void *,void *)116 void operator delete(void*, void*) throw() { }
117
118 private:
119 // Make vanilla 'new' and 'delete' illegal for preprocessed entities.
120 void* operator new(size_t bytes) throw();
121 void operator delete(void* data) throw();
122 };
123
124 /// \brief Records the presence of a preprocessor directive.
125 class PreprocessingDirective : public PreprocessedEntity {
126 public:
PreprocessingDirective(EntityKind Kind,SourceRange Range)127 PreprocessingDirective(EntityKind Kind, SourceRange Range)
128 : PreprocessedEntity(Kind, Range) { }
129
130 // Implement isa/cast/dyncast/etc.
classof(const PreprocessedEntity * PD)131 static bool classof(const PreprocessedEntity *PD) {
132 return PD->getKind() >= FirstPreprocessingDirective &&
133 PD->getKind() <= LastPreprocessingDirective;
134 }
135 };
136
137 /// \brief Record the location of a macro definition.
138 class MacroDefinition : public PreprocessingDirective {
139 /// \brief The name of the macro being defined.
140 const IdentifierInfo *Name;
141
142 public:
MacroDefinition(const IdentifierInfo * Name,SourceRange Range)143 explicit MacroDefinition(const IdentifierInfo *Name, SourceRange Range)
144 : PreprocessingDirective(MacroDefinitionKind, Range), Name(Name) { }
145
146 /// \brief Retrieve the name of the macro being defined.
getName()147 const IdentifierInfo *getName() const { return Name; }
148
149 /// \brief Retrieve the location of the macro name in the definition.
getLocation()150 SourceLocation getLocation() const { return getSourceRange().getBegin(); }
151
152 // Implement isa/cast/dyncast/etc.
classof(const PreprocessedEntity * PE)153 static bool classof(const PreprocessedEntity *PE) {
154 return PE->getKind() == MacroDefinitionKind;
155 }
156 };
157
158 /// \brief Records the location of a macro expansion.
159 class MacroExpansion : public PreprocessedEntity {
160 /// \brief The definition of this macro or the name of the macro if it is
161 /// a builtin macro.
162 llvm::PointerUnion<IdentifierInfo *, MacroDefinition *> NameOrDef;
163
164 public:
MacroExpansion(IdentifierInfo * BuiltinName,SourceRange Range)165 MacroExpansion(IdentifierInfo *BuiltinName, SourceRange Range)
166 : PreprocessedEntity(MacroExpansionKind, Range),
167 NameOrDef(BuiltinName) { }
168
MacroExpansion(MacroDefinition * Definition,SourceRange Range)169 MacroExpansion(MacroDefinition *Definition, SourceRange Range)
170 : PreprocessedEntity(MacroExpansionKind, Range),
171 NameOrDef(Definition) { }
172
173 /// \brief True if it is a builtin macro.
isBuiltinMacro()174 bool isBuiltinMacro() const { return NameOrDef.is<IdentifierInfo *>(); }
175
176 /// \brief The name of the macro being expanded.
getName()177 const IdentifierInfo *getName() const {
178 if (MacroDefinition *Def = getDefinition())
179 return Def->getName();
180 return NameOrDef.get<IdentifierInfo*>();
181 }
182
183 /// \brief The definition of the macro being expanded. May return null if
184 /// this is a builtin macro.
getDefinition()185 MacroDefinition *getDefinition() const {
186 return NameOrDef.dyn_cast<MacroDefinition *>();
187 }
188
189 // Implement isa/cast/dyncast/etc.
classof(const PreprocessedEntity * PE)190 static bool classof(const PreprocessedEntity *PE) {
191 return PE->getKind() == MacroExpansionKind;
192 }
193 };
194
195 /// \brief Record the location of an inclusion directive, such as an
196 /// \c \#include or \c \#import statement.
197 class InclusionDirective : public PreprocessingDirective {
198 public:
199 /// \brief The kind of inclusion directives known to the
200 /// preprocessor.
201 enum InclusionKind {
202 /// \brief An \c \#include directive.
203 Include,
204 /// \brief An Objective-C \c \#import directive.
205 Import,
206 /// \brief A GNU \c \#include_next directive.
207 IncludeNext,
208 /// \brief A Clang \c \#__include_macros directive.
209 IncludeMacros
210 };
211
212 private:
213 /// \brief The name of the file that was included, as written in
214 /// the source.
215 StringRef FileName;
216
217 /// \brief Whether the file name was in quotation marks; otherwise, it was
218 /// in angle brackets.
219 unsigned InQuotes : 1;
220
221 /// \brief The kind of inclusion directive we have.
222 ///
223 /// This is a value of type InclusionKind.
224 unsigned Kind : 2;
225
226 /// \brief Whether the inclusion directive was automatically turned into
227 /// a module import.
228 unsigned ImportedModule : 1;
229
230 /// \brief The file that was included.
231 const FileEntry *File;
232
233 public:
234 InclusionDirective(PreprocessingRecord &PPRec,
235 InclusionKind Kind, StringRef FileName,
236 bool InQuotes, bool ImportedModule,
237 const FileEntry *File, SourceRange Range);
238
239 /// \brief Determine what kind of inclusion directive this is.
getKind()240 InclusionKind getKind() const { return static_cast<InclusionKind>(Kind); }
241
242 /// \brief Retrieve the included file name as it was written in the source.
getFileName()243 StringRef getFileName() const { return FileName; }
244
245 /// \brief Determine whether the included file name was written in quotes;
246 /// otherwise, it was written in angle brackets.
wasInQuotes()247 bool wasInQuotes() const { return InQuotes; }
248
249 /// \brief Determine whether the inclusion directive was automatically
250 /// turned into a module import.
importedModule()251 bool importedModule() const { return ImportedModule; }
252
253 /// \brief Retrieve the file entry for the actual file that was included
254 /// by this directive.
getFile()255 const FileEntry *getFile() const { return File; }
256
257 // Implement isa/cast/dyncast/etc.
classof(const PreprocessedEntity * PE)258 static bool classof(const PreprocessedEntity *PE) {
259 return PE->getKind() == InclusionDirectiveKind;
260 }
261 };
262
263 /// \brief An abstract class that should be subclassed by any external source
264 /// of preprocessing record entries.
265 class ExternalPreprocessingRecordSource {
266 public:
267 virtual ~ExternalPreprocessingRecordSource();
268
269 /// \brief Read a preallocated preprocessed entity from the external source.
270 ///
271 /// \returns null if an error occurred that prevented the preprocessed
272 /// entity from being loaded.
273 virtual PreprocessedEntity *ReadPreprocessedEntity(unsigned Index) = 0;
274
275 /// \brief Returns a pair of [Begin, End) indices of preallocated
276 /// preprocessed entities that \p Range encompasses.
277 virtual std::pair<unsigned, unsigned>
278 findPreprocessedEntitiesInRange(SourceRange Range) = 0;
279
280 /// \brief Optionally returns true or false if the preallocated preprocessed
281 /// entity with index \p Index came from file \p FID.
isPreprocessedEntityInFileID(unsigned Index,FileID FID)282 virtual Optional<bool> isPreprocessedEntityInFileID(unsigned Index,
283 FileID FID) {
284 return None;
285 }
286 };
287
288 /// \brief A record of the steps taken while preprocessing a source file,
289 /// including the various preprocessing directives processed, macros
290 /// expanded, etc.
291 class PreprocessingRecord : public PPCallbacks {
292 SourceManager &SourceMgr;
293
294 /// \brief Allocator used to store preprocessing objects.
295 llvm::BumpPtrAllocator BumpAlloc;
296
297 /// \brief The set of preprocessed entities in this record, in order they
298 /// were seen.
299 std::vector<PreprocessedEntity *> PreprocessedEntities;
300
301 /// \brief The set of preprocessed entities in this record that have been
302 /// loaded from external sources.
303 ///
304 /// The entries in this vector are loaded lazily from the external source,
305 /// and are referenced by the iterator using negative indices.
306 std::vector<PreprocessedEntity *> LoadedPreprocessedEntities;
307
308 /// \brief The set of ranges that were skipped by the preprocessor,
309 std::vector<SourceRange> SkippedRanges;
310
311 /// \brief Global (loaded or local) ID for a preprocessed entity.
312 /// Negative values are used to indicate preprocessed entities
313 /// loaded from the external source while non-negative values are used to
314 /// indicate preprocessed entities introduced by the current preprocessor.
315 /// Value -1 corresponds to element 0 in the loaded entities vector,
316 /// value -2 corresponds to element 1 in the loaded entities vector, etc.
317 /// Value 0 is an invalid value, the index to local entities is 1-based,
318 /// value 1 corresponds to element 0 in the local entities vector,
319 /// value 2 corresponds to element 1 in the local entities vector, etc.
320 class PPEntityID {
321 int ID;
PPEntityID(int ID)322 explicit PPEntityID(int ID) : ID(ID) {}
323 friend class PreprocessingRecord;
324 public:
PPEntityID()325 PPEntityID() : ID(0) {}
326 };
327
getPPEntityID(unsigned Index,bool isLoaded)328 static PPEntityID getPPEntityID(unsigned Index, bool isLoaded) {
329 return isLoaded ? PPEntityID(-int(Index)-1) : PPEntityID(Index+1);
330 }
331
332 /// \brief Mapping from MacroInfo structures to their definitions.
333 llvm::DenseMap<const MacroInfo *, MacroDefinition *> MacroDefinitions;
334
335 /// \brief External source of preprocessed entities.
336 ExternalPreprocessingRecordSource *ExternalSource;
337
338 /// \brief Retrieve the preprocessed entity at the given ID.
339 PreprocessedEntity *getPreprocessedEntity(PPEntityID PPID);
340
341 /// \brief Retrieve the loaded preprocessed entity at the given index.
342 PreprocessedEntity *getLoadedPreprocessedEntity(unsigned Index);
343
344 /// \brief Determine the number of preprocessed entities that were
345 /// loaded (or can be loaded) from an external source.
getNumLoadedPreprocessedEntities()346 unsigned getNumLoadedPreprocessedEntities() const {
347 return LoadedPreprocessedEntities.size();
348 }
349
350 /// \brief Returns a pair of [Begin, End) indices of local preprocessed
351 /// entities that \p Range encompasses.
352 std::pair<unsigned, unsigned>
353 findLocalPreprocessedEntitiesInRange(SourceRange Range) const;
354 unsigned findBeginLocalPreprocessedEntity(SourceLocation Loc) const;
355 unsigned findEndLocalPreprocessedEntity(SourceLocation Loc) const;
356
357 /// \brief Allocate space for a new set of loaded preprocessed entities.
358 ///
359 /// \returns The index into the set of loaded preprocessed entities, which
360 /// corresponds to the first newly-allocated entity.
361 unsigned allocateLoadedEntities(unsigned NumEntities);
362
363 /// \brief Register a new macro definition.
364 void RegisterMacroDefinition(MacroInfo *Macro, MacroDefinition *Def);
365
366 public:
367 /// \brief Construct a new preprocessing record.
368 explicit PreprocessingRecord(SourceManager &SM);
369
370 /// \brief Allocate memory in the preprocessing record.
371 void *Allocate(unsigned Size, unsigned Align = 8) {
372 return BumpAlloc.Allocate(Size, Align);
373 }
374
375 /// \brief Deallocate memory in the preprocessing record.
Deallocate(void * Ptr)376 void Deallocate(void *Ptr) { }
377
378 size_t getTotalMemory() const;
379
getSourceManager()380 SourceManager &getSourceManager() const { return SourceMgr; }
381
382 /// Iteration over the preprocessed entities.
383 ///
384 /// In a complete iteration, the iterator walks the range [-M, N),
385 /// where negative values are used to indicate preprocessed entities
386 /// loaded from the external source while non-negative values are used to
387 /// indicate preprocessed entities introduced by the current preprocessor.
388 /// However, to provide iteration in source order (for, e.g., chained
389 /// precompiled headers), dereferencing the iterator flips the negative
390 /// values (corresponding to loaded entities), so that position -M
391 /// corresponds to element 0 in the loaded entities vector, position -M+1
392 /// corresponds to element 1 in the loaded entities vector, etc. This
393 /// gives us a reasonably efficient, source-order walk.
394 ///
395 /// We define this as a wrapping iterator around an int. The
396 /// iterator_adaptor_base class forwards the iterator methods to basic
397 /// integer arithmetic.
398 class iterator : public llvm::iterator_adaptor_base<
399 iterator, int, std::random_access_iterator_tag,
400 PreprocessedEntity *, int, PreprocessedEntity *,
401 PreprocessedEntity *> {
402 PreprocessingRecord *Self;
403
iterator(PreprocessingRecord * Self,int Position)404 iterator(PreprocessingRecord *Self, int Position)
405 : iterator::iterator_adaptor_base(Position), Self(Self) {}
406 friend class PreprocessingRecord;
407
408 public:
iterator()409 iterator() : iterator(nullptr, 0) {}
410
411 PreprocessedEntity *operator*() const {
412 bool isLoaded = this->I < 0;
413 unsigned Index = isLoaded ?
414 Self->LoadedPreprocessedEntities.size() + this->I : this->I;
415 PPEntityID ID = Self->getPPEntityID(Index, isLoaded);
416 return Self->getPreprocessedEntity(ID);
417 }
418 PreprocessedEntity *operator->() const { return **this; }
419 };
420
421 /// \brief Begin iterator for all preprocessed entities.
begin()422 iterator begin() {
423 return iterator(this, -(int)LoadedPreprocessedEntities.size());
424 }
425
426 /// \brief End iterator for all preprocessed entities.
end()427 iterator end() {
428 return iterator(this, PreprocessedEntities.size());
429 }
430
431 /// \brief Begin iterator for local, non-loaded, preprocessed entities.
local_begin()432 iterator local_begin() {
433 return iterator(this, 0);
434 }
435
436 /// \brief End iterator for local, non-loaded, preprocessed entities.
local_end()437 iterator local_end() {
438 return iterator(this, PreprocessedEntities.size());
439 }
440
441 /// \brief iterator range for the given range of loaded
442 /// preprocessed entities.
getIteratorsForLoadedRange(unsigned start,unsigned count)443 llvm::iterator_range<iterator> getIteratorsForLoadedRange(unsigned start,
444 unsigned count) {
445 unsigned end = start + count;
446 assert(end <= LoadedPreprocessedEntities.size());
447 return llvm::make_range(
448 iterator(this, int(start) - LoadedPreprocessedEntities.size()),
449 iterator(this, int(end) - LoadedPreprocessedEntities.size()));
450 }
451
452 /// \brief Returns a range of preprocessed entities that source range \p R
453 /// encompasses.
454 ///
455 /// \param R the range to look for preprocessed entities.
456 ///
457 llvm::iterator_range<iterator>
458 getPreprocessedEntitiesInRange(SourceRange R);
459
460 /// \brief Returns true if the preprocessed entity that \p PPEI iterator
461 /// points to is coming from the file \p FID.
462 ///
463 /// Can be used to avoid implicit deserializations of preallocated
464 /// preprocessed entities if we only care about entities of a specific file
465 /// and not from files \#included in the range given at
466 /// \see getPreprocessedEntitiesInRange.
467 bool isEntityInFileID(iterator PPEI, FileID FID);
468
469 /// \brief Add a new preprocessed entity to this record.
470 PPEntityID addPreprocessedEntity(PreprocessedEntity *Entity);
471
472 /// \brief Set the external source for preprocessed entities.
473 void SetExternalSource(ExternalPreprocessingRecordSource &Source);
474
475 /// \brief Retrieve the external source for preprocessed entities.
getExternalSource()476 ExternalPreprocessingRecordSource *getExternalSource() const {
477 return ExternalSource;
478 }
479
480 /// \brief Retrieve the macro definition that corresponds to the given
481 /// \c MacroInfo.
482 MacroDefinition *findMacroDefinition(const MacroInfo *MI);
483
484 /// \brief Retrieve all ranges that got skipped while preprocessing.
getSkippedRanges()485 const std::vector<SourceRange> &getSkippedRanges() const {
486 return SkippedRanges;
487 }
488
489 private:
490 void MacroExpands(const Token &Id, const MacroDirective *MD,
491 SourceRange Range, const MacroArgs *Args) override;
492 void MacroDefined(const Token &Id, const MacroDirective *MD) override;
493 void MacroUndefined(const Token &Id, const MacroDirective *MD) override;
494 void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
495 StringRef FileName, bool IsAngled,
496 CharSourceRange FilenameRange,
497 const FileEntry *File, StringRef SearchPath,
498 StringRef RelativePath,
499 const Module *Imported) override;
500 void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
501 const MacroDirective *MD) override;
502 void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
503 const MacroDirective *MD) override;
504 /// \brief Hook called whenever the 'defined' operator is seen.
505 void Defined(const Token &MacroNameTok, const MacroDirective *MD,
506 SourceRange Range) override;
507
508 void SourceRangeSkipped(SourceRange Range) override;
509
510 void addMacroExpansion(const Token &Id, const MacroInfo *MI,
511 SourceRange Range);
512
513 /// \brief Cached result of the last \see getPreprocessedEntitiesInRange
514 /// query.
515 struct {
516 SourceRange Range;
517 std::pair<int, int> Result;
518 } CachedRangeQuery;
519
520 std::pair<int, int> getPreprocessedEntitiesInRangeSlow(SourceRange R);
521
522 friend class ASTReader;
523 friend class ASTWriter;
524 };
525 } // end namespace clang
526
new(size_t bytes,clang::PreprocessingRecord & PR,unsigned alignment)527 inline void* operator new(size_t bytes, clang::PreprocessingRecord& PR,
528 unsigned alignment) throw() {
529 return PR.Allocate(bytes, alignment);
530 }
531
delete(void * ptr,clang::PreprocessingRecord & PR,unsigned)532 inline void operator delete(void* ptr, clang::PreprocessingRecord& PR,
533 unsigned) throw() {
534 PR.Deallocate(ptr);
535 }
536
537 #endif // LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
538