PreprocessingRecord.h revision c6c54521f95760a5eaf29b668d4bf41fe2af49d7
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 "clang/Basic/IdentifierTable.h"
20#include "llvm/ADT/SmallVector.h"
21#include "llvm/ADT/DenseMap.h"
22#include "llvm/ADT/Optional.h"
23#include "llvm/Support/Allocator.h"
24#include <vector>
25
26namespace clang {
27  class IdentifierInfo;
28  class PreprocessingRecord;
29}
30
31/// \brief Allocates memory within a Clang preprocessing record.
32void* operator new(size_t bytes, clang::PreprocessingRecord& PR,
33                   unsigned alignment = 8) throw();
34
35/// \brief Frees memory allocated in a Clang preprocessing record.
36void operator delete(void* ptr, clang::PreprocessingRecord& PR,
37                     unsigned) throw();
38
39namespace clang {
40  class MacroDefinition;
41  class FileEntry;
42
43  /// \brief Base class that describes a preprocessed entity, which may be a
44  /// preprocessor directive or macro expansion.
45  class PreprocessedEntity {
46  public:
47    /// \brief The kind of preprocessed entity an object describes.
48    enum EntityKind {
49      /// \brief Indicates a problem trying to load the preprocessed entity.
50      InvalidKind,
51
52      /// \brief A macro expansion.
53      MacroExpansionKind,
54
55      /// \defgroup Preprocessing directives
56      /// @{
57
58      /// \brief A macro definition.
59      MacroDefinitionKind,
60
61      /// \brief An inclusion directive, such as \c #include, \c
62      /// #import, or \c #include_next.
63      InclusionDirectiveKind,
64
65      /// @}
66
67      FirstPreprocessingDirective = MacroDefinitionKind,
68      LastPreprocessingDirective = InclusionDirectiveKind
69    };
70
71  private:
72    /// \brief The kind of preprocessed entity that this object describes.
73    EntityKind Kind;
74
75    /// \brief The source range that covers this preprocessed entity.
76    SourceRange Range;
77
78  protected:
79    PreprocessedEntity(EntityKind Kind, SourceRange Range)
80      : Kind(Kind), Range(Range) { }
81
82    friend class PreprocessingRecord;
83
84  public:
85    /// \brief Retrieve the kind of preprocessed entity stored in this object.
86    EntityKind getKind() const { return Kind; }
87
88    /// \brief Retrieve the source range that covers this entire preprocessed
89    /// entity.
90    SourceRange getSourceRange() const { return Range; }
91
92    /// \brief Returns true if there was a problem loading the preprocessed
93    /// entity.
94    bool isInvalid() const { return Kind == InvalidKind; }
95
96    // Implement isa/cast/dyncast/etc.
97    static bool classof(const PreprocessedEntity *) { return true; }
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,
102                       unsigned alignment = 8) throw() {
103      return ::operator new(bytes, PR, alignment);
104    }
105
106    void* operator new(size_t bytes, void* mem) throw() {
107      return mem;
108    }
109
110    void operator delete(void* ptr, PreprocessingRecord& PR,
111                         unsigned alignment) throw() {
112      return ::operator delete(ptr, PR, alignment);
113    }
114
115    void operator delete(void*, std::size_t) throw() { }
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:
127    PreprocessingDirective(EntityKind Kind, SourceRange Range)
128      : PreprocessedEntity(Kind, Range) { }
129
130    // Implement isa/cast/dyncast/etc.
131    static bool classof(const PreprocessedEntity *PD) {
132      return PD->getKind() >= FirstPreprocessingDirective &&
133             PD->getKind() <= LastPreprocessingDirective;
134    }
135    static bool classof(const PreprocessingDirective *) { return true; }
136  };
137
138  /// \brief Record the location of a macro definition.
139  class MacroDefinition : public PreprocessingDirective {
140    /// \brief The name of the macro being defined.
141    const IdentifierInfo *Name;
142
143  public:
144    explicit MacroDefinition(const IdentifierInfo *Name, SourceRange Range)
145      : PreprocessingDirective(MacroDefinitionKind, Range), Name(Name) { }
146
147    /// \brief Retrieve the name of the macro being defined.
148    const IdentifierInfo *getName() const { return Name; }
149
150    /// \brief Retrieve the location of the macro name in the definition.
151    SourceLocation getLocation() const { return getSourceRange().getBegin(); }
152
153    // Implement isa/cast/dyncast/etc.
154    static bool classof(const PreprocessedEntity *PE) {
155      return PE->getKind() == MacroDefinitionKind;
156    }
157    static bool classof(const MacroDefinition *) { return true; }
158  };
159
160  /// \brief Records the location of a macro expansion.
161  class MacroExpansion : public PreprocessedEntity {
162    /// \brief The definition of this macro or the name of the macro if it is
163    /// a builtin macro.
164    llvm::PointerUnion<IdentifierInfo *, MacroDefinition *> NameOrDef;
165
166  public:
167    MacroExpansion(IdentifierInfo *BuiltinName, SourceRange Range)
168      : PreprocessedEntity(MacroExpansionKind, Range),
169        NameOrDef(BuiltinName) { }
170
171    MacroExpansion(MacroDefinition *Definition, SourceRange Range)
172      : PreprocessedEntity(MacroExpansionKind, Range),
173        NameOrDef(Definition) { }
174
175    /// \brief True if it is a builtin macro.
176    bool isBuiltinMacro() const { return NameOrDef.is<IdentifierInfo *>(); }
177
178    /// \brief The name of the macro being expanded.
179    const IdentifierInfo *getName() const {
180      if (MacroDefinition *Def = getDefinition())
181        return Def->getName();
182      return NameOrDef.get<IdentifierInfo*>();
183    }
184
185    /// \brief The definition of the macro being expanded. May return null if
186    /// this is a builtin macro.
187    MacroDefinition *getDefinition() const {
188      return NameOrDef.dyn_cast<MacroDefinition *>();
189    }
190
191    // Implement isa/cast/dyncast/etc.
192    static bool classof(const PreprocessedEntity *PE) {
193      return PE->getKind() == MacroExpansionKind;
194    }
195    static bool classof(const MacroExpansion *) { return true; }
196  };
197
198  /// \brief Record the location of an inclusion directive, such as an
199  /// \c #include or \c #import statement.
200  class InclusionDirective : public PreprocessingDirective {
201  public:
202    /// \brief The kind of inclusion directives known to the
203    /// preprocessor.
204    enum InclusionKind {
205      /// \brief An \c #include directive.
206      Include,
207      /// \brief An Objective-C \c #import directive.
208      Import,
209      /// \brief A GNU \c #include_next directive.
210      IncludeNext,
211      /// \brief A Clang \c #__include_macros directive.
212      IncludeMacros
213    };
214
215  private:
216    /// \brief The name of the file that was included, as written in
217    /// the source.
218    StringRef FileName;
219
220    /// \brief Whether the file name was in quotation marks; otherwise, it was
221    /// in angle brackets.
222    unsigned InQuotes : 1;
223
224    /// \brief The kind of inclusion directive we have.
225    ///
226    /// This is a value of type InclusionKind.
227    unsigned Kind : 2;
228
229    /// \brief The file that was included.
230    const FileEntry *File;
231
232  public:
233    InclusionDirective(PreprocessingRecord &PPRec,
234                       InclusionKind Kind, StringRef FileName,
235                       bool InQuotes, const FileEntry *File, SourceRange Range);
236
237    /// \brief Determine what kind of inclusion directive this is.
238    InclusionKind getKind() const { return static_cast<InclusionKind>(Kind); }
239
240    /// \brief Retrieve the included file name as it was written in the source.
241    StringRef getFileName() const { return FileName; }
242
243    /// \brief Determine whether the included file name was written in quotes;
244    /// otherwise, it was written in angle brackets.
245    bool wasInQuotes() const { return InQuotes; }
246
247    /// \brief Retrieve the file entry for the actual file that was included
248    /// by this directive.
249    const FileEntry *getFile() const { return File; }
250
251    // Implement isa/cast/dyncast/etc.
252    static bool classof(const PreprocessedEntity *PE) {
253      return PE->getKind() == InclusionDirectiveKind;
254    }
255    static bool classof(const InclusionDirective *) { return true; }
256  };
257
258  /// \brief An abstract class that should be subclassed by any external source
259  /// of preprocessing record entries.
260  class ExternalPreprocessingRecordSource {
261  public:
262    virtual ~ExternalPreprocessingRecordSource();
263
264    /// \brief Read a preallocated preprocessed entity from the external source.
265    ///
266    /// \returns null if an error occurred that prevented the preprocessed
267    /// entity from being loaded.
268    virtual PreprocessedEntity *ReadPreprocessedEntity(unsigned Index) = 0;
269
270    /// \brief Returns a pair of [Begin, End) indices of preallocated
271    /// preprocessed entities that \arg Range encompasses.
272    virtual std::pair<unsigned, unsigned>
273        findPreprocessedEntitiesInRange(SourceRange Range) = 0;
274
275    /// \brief Optionally returns true or false if the preallocated preprocessed
276    /// entity with index \arg Index came from file \arg FID.
277    virtual llvm::Optional<bool> isPreprocessedEntityInFileID(unsigned Index,
278                                                              FileID FID) {
279      return llvm::Optional<bool>();
280    }
281  };
282
283  /// \brief A record of the steps taken while preprocessing a source file,
284  /// including the various preprocessing directives processed, macros
285  /// expanded, etc.
286  class PreprocessingRecord : public PPCallbacks {
287    SourceManager &SourceMgr;
288
289    /// \brief Allocator used to store preprocessing objects.
290    llvm::BumpPtrAllocator BumpAlloc;
291
292    /// \brief The set of preprocessed entities in this record, in order they
293    /// were seen.
294    std::vector<PreprocessedEntity *> PreprocessedEntities;
295
296    /// \brief The set of preprocessed entities in this record that have been
297    /// loaded from external sources.
298    ///
299    /// The entries in this vector are loaded lazily from the external source,
300    /// and are referenced by the iterator using negative indices.
301    std::vector<PreprocessedEntity *> LoadedPreprocessedEntities;
302
303    bool RecordCondDirectives;
304    unsigned CondDirectiveNextIdx;
305    SmallVector<unsigned, 6> CondDirectiveStack;
306
307    class CondDirectiveLoc {
308      SourceLocation Loc;
309      unsigned Idx;
310
311    public:
312      CondDirectiveLoc(SourceLocation Loc, unsigned Idx) : Loc(Loc), Idx(Idx) {}
313
314      SourceLocation getLoc() const { return Loc; }
315      unsigned getIdx() const { return Idx; }
316
317      class Comp {
318        SourceManager &SM;
319      public:
320        explicit Comp(SourceManager &SM) : SM(SM) {}
321        bool operator()(const CondDirectiveLoc &LHS,
322                        const CondDirectiveLoc &RHS) {
323          return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS.getLoc());
324        }
325        bool operator()(const CondDirectiveLoc &LHS, SourceLocation RHS) {
326          return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS);
327        }
328        bool operator()(SourceLocation LHS, const CondDirectiveLoc &RHS) {
329          return SM.isBeforeInTranslationUnit(LHS, RHS.getLoc());
330        }
331      };
332    };
333
334    typedef std::vector<CondDirectiveLoc> CondDirectiveLocsTy;
335    /// \brief The locations of conditional directives in source order.
336    CondDirectiveLocsTy CondDirectiveLocs;
337
338    void addCondDirectiveLoc(CondDirectiveLoc DirLoc);
339    unsigned findCondDirectiveIdx(SourceLocation Loc) const;
340
341    /// \brief Global (loaded or local) ID for a preprocessed entity.
342    /// Negative values are used to indicate preprocessed entities
343    /// loaded from the external source while non-negative values are used to
344    /// indicate preprocessed entities introduced by the current preprocessor.
345    /// If M is the number of loaded preprocessed entities, value -M
346    /// corresponds to element 0 in the loaded entities vector, position -M+1
347    /// corresponds to element 1 in the loaded entities vector, etc.
348    typedef int PPEntityID;
349
350    PPEntityID getPPEntityID(unsigned Index, bool isLoaded) const {
351      return isLoaded ? PPEntityID(Index) - LoadedPreprocessedEntities.size()
352                      : Index;
353    }
354
355    /// \brief Mapping from MacroInfo structures to their definitions.
356    llvm::DenseMap<const MacroInfo *, PPEntityID> MacroDefinitions;
357
358    /// \brief External source of preprocessed entities.
359    ExternalPreprocessingRecordSource *ExternalSource;
360
361    /// \brief Retrieve the preprocessed entity at the given ID.
362    PreprocessedEntity *getPreprocessedEntity(PPEntityID PPID);
363
364    /// \brief Retrieve the loaded preprocessed entity at the given index.
365    PreprocessedEntity *getLoadedPreprocessedEntity(unsigned Index);
366
367    /// \brief Determine the number of preprocessed entities that were
368    /// loaded (or can be loaded) from an external source.
369    unsigned getNumLoadedPreprocessedEntities() const {
370      return LoadedPreprocessedEntities.size();
371    }
372
373    /// \brief Returns a pair of [Begin, End) indices of local preprocessed
374    /// entities that \arg Range encompasses.
375    std::pair<unsigned, unsigned>
376      findLocalPreprocessedEntitiesInRange(SourceRange Range) const;
377    unsigned findBeginLocalPreprocessedEntity(SourceLocation Loc) const;
378    unsigned findEndLocalPreprocessedEntity(SourceLocation Loc) const;
379
380    /// \brief Allocate space for a new set of loaded preprocessed entities.
381    ///
382    /// \returns The index into the set of loaded preprocessed entities, which
383    /// corresponds to the first newly-allocated entity.
384    unsigned allocateLoadedEntities(unsigned NumEntities);
385
386    /// \brief Register a new macro definition.
387    void RegisterMacroDefinition(MacroInfo *Macro, PPEntityID PPID);
388
389  public:
390    /// \brief Construct a new preprocessing record.
391    PreprocessingRecord(SourceManager &SM, bool RecordConditionalDirectives);
392
393    /// \brief Allocate memory in the preprocessing record.
394    void *Allocate(unsigned Size, unsigned Align = 8) {
395      return BumpAlloc.Allocate(Size, Align);
396    }
397
398    /// \brief Deallocate memory in the preprocessing record.
399    void Deallocate(void *Ptr) { }
400
401    size_t getTotalMemory() const;
402
403    SourceManager &getSourceManager() const { return SourceMgr; }
404
405    // Iteration over the preprocessed entities.
406    class iterator {
407      PreprocessingRecord *Self;
408
409      /// \brief Position within the preprocessed entity sequence.
410      ///
411      /// In a complete iteration, the Position field walks the range [-M, N),
412      /// where negative values are used to indicate preprocessed entities
413      /// loaded from the external source while non-negative values are used to
414      /// indicate preprocessed entities introduced by the current preprocessor.
415      /// However, to provide iteration in source order (for, e.g., chained
416      /// precompiled headers), dereferencing the iterator flips the negative
417      /// values (corresponding to loaded entities), so that position -M
418      /// corresponds to element 0 in the loaded entities vector, position -M+1
419      /// corresponds to element 1 in the loaded entities vector, etc. This
420      /// gives us a reasonably efficient, source-order walk.
421      PPEntityID Position;
422
423    public:
424      typedef PreprocessedEntity *value_type;
425      typedef value_type&         reference;
426      typedef value_type*         pointer;
427      typedef std::random_access_iterator_tag iterator_category;
428      typedef int                 difference_type;
429
430      iterator() : Self(0), Position(0) { }
431
432      iterator(PreprocessingRecord *Self, PPEntityID Position)
433        : Self(Self), Position(Position) { }
434
435      value_type operator*() const {
436        return Self->getPreprocessedEntity(Position);
437      }
438
439      value_type operator[](difference_type D) {
440        return *(*this + D);
441      }
442
443      iterator &operator++() {
444        ++Position;
445        return *this;
446      }
447
448      iterator operator++(int) {
449        iterator Prev(*this);
450        ++Position;
451        return Prev;
452      }
453
454      iterator &operator--() {
455        --Position;
456        return *this;
457      }
458
459      iterator operator--(int) {
460        iterator Prev(*this);
461        --Position;
462        return Prev;
463      }
464
465      friend bool operator==(const iterator &X, const iterator &Y) {
466        return X.Position == Y.Position;
467      }
468
469      friend bool operator!=(const iterator &X, const iterator &Y) {
470        return X.Position != Y.Position;
471      }
472
473      friend bool operator<(const iterator &X, const iterator &Y) {
474        return X.Position < Y.Position;
475      }
476
477      friend bool operator>(const iterator &X, const iterator &Y) {
478        return X.Position > Y.Position;
479      }
480
481      friend bool operator<=(const iterator &X, const iterator &Y) {
482        return X.Position < Y.Position;
483      }
484
485      friend bool operator>=(const iterator &X, const iterator &Y) {
486        return X.Position > Y.Position;
487      }
488
489      friend iterator& operator+=(iterator &X, difference_type D) {
490        X.Position += D;
491        return X;
492      }
493
494      friend iterator& operator-=(iterator &X, difference_type D) {
495        X.Position -= D;
496        return X;
497      }
498
499      friend iterator operator+(iterator X, difference_type D) {
500        X.Position += D;
501        return X;
502      }
503
504      friend iterator operator+(difference_type D, iterator X) {
505        X.Position += D;
506        return X;
507      }
508
509      friend difference_type operator-(const iterator &X, const iterator &Y) {
510        return X.Position - Y.Position;
511      }
512
513      friend iterator operator-(iterator X, difference_type D) {
514        X.Position -= D;
515        return X;
516      }
517      friend class PreprocessingRecord;
518    };
519    friend class iterator;
520
521    /// \brief Begin iterator for all preprocessed entities.
522    iterator begin() {
523      return iterator(this, -(int)LoadedPreprocessedEntities.size());
524    }
525
526    /// \brief End iterator for all preprocessed entities.
527    iterator end() {
528      return iterator(this, PreprocessedEntities.size());
529    }
530
531    /// \brief Begin iterator for local, non-loaded, preprocessed entities.
532    iterator local_begin() {
533      return iterator(this, 0);
534    }
535
536    /// \brief End iterator for local, non-loaded, preprocessed entities.
537    iterator local_end() {
538      return iterator(this, PreprocessedEntities.size());
539    }
540
541    /// \brief Returns a pair of [Begin, End) iterators of preprocessed entities
542    /// that source range \arg R encompasses.
543    ///
544    /// \param R the range to look for preprocessed entities.
545    ///
546    std::pair<iterator, iterator> getPreprocessedEntitiesInRange(SourceRange R);
547
548    /// \brief Returns true if the preprocessed entity that \arg PPEI iterator
549    /// points to is coming from the file \arg FID.
550    ///
551    /// Can be used to avoid implicit deserializations of preallocated
552    /// preprocessed entities if we only care about entities of a specific file
553    /// and not from files #included in the range given at
554    /// \see getPreprocessedEntitiesInRange.
555    bool isEntityInFileID(iterator PPEI, FileID FID);
556
557    /// \brief Add a new preprocessed entity to this record.
558    void addPreprocessedEntity(PreprocessedEntity *Entity);
559
560    /// \brief Returns true if this PreprocessingRecord is keeping track of
561    /// conditional directives locations.
562    bool isRecordingConditionalDirectives() const {
563      return RecordCondDirectives;
564    }
565
566    /// \brief Returns true if the given range intersects with a conditional
567    /// directive. if a #if/#endif block is fully contained within the range,
568    /// this function will return false.
569    bool rangeIntersectsConditionalDirective(SourceRange Range) const;
570
571    /// \brief Returns true if the given locations are in different regions,
572    /// separated by conditional directive blocks.
573    bool areInDifferentConditionalDirectiveRegion(SourceLocation LHS,
574                                                  SourceLocation RHS) const {
575      return findCondDirectiveIdx(LHS) != findCondDirectiveIdx(RHS);
576    }
577
578    /// \brief Set the external source for preprocessed entities.
579    void SetExternalSource(ExternalPreprocessingRecordSource &Source);
580
581    /// \brief Retrieve the external source for preprocessed entities.
582    ExternalPreprocessingRecordSource *getExternalSource() const {
583      return ExternalSource;
584    }
585
586    /// \brief Retrieve the macro definition that corresponds to the given
587    /// \c MacroInfo.
588    MacroDefinition *findMacroDefinition(const MacroInfo *MI);
589
590  private:
591    virtual void MacroExpands(const Token &Id, const MacroInfo* MI,
592                              SourceRange Range);
593    virtual void MacroDefined(const Token &Id, const MacroInfo *MI);
594    virtual void MacroUndefined(const Token &Id, const MacroInfo *MI);
595    virtual void InclusionDirective(SourceLocation HashLoc,
596                                    const Token &IncludeTok,
597                                    StringRef FileName,
598                                    bool IsAngled,
599                                    const FileEntry *File,
600                                    SourceLocation EndLoc,
601                                    StringRef SearchPath,
602                                    StringRef RelativePath);
603    virtual void If(SourceLocation Loc, SourceRange ConditionRange);
604    virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
605                      SourceLocation IfLoc);
606    virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok);
607    virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok);
608    virtual void Else(SourceLocation Loc, SourceLocation IfLoc);
609    virtual void Endif(SourceLocation Loc, SourceLocation IfLoc);
610
611    /// \brief Cached result of the last \see getPreprocessedEntitiesInRange
612    /// query.
613    struct {
614      SourceRange Range;
615      std::pair<PPEntityID, PPEntityID> Result;
616    } CachedRangeQuery;
617
618    std::pair<PPEntityID, PPEntityID>
619      getPreprocessedEntitiesInRangeSlow(SourceRange R);
620
621    friend class ASTReader;
622    friend class ASTWriter;
623  };
624} // end namespace clang
625
626inline void* operator new(size_t bytes, clang::PreprocessingRecord& PR,
627                          unsigned alignment) throw() {
628  return PR.Allocate(bytes, alignment);
629}
630
631inline void operator delete(void* ptr, clang::PreprocessingRecord& PR,
632                            unsigned) throw() {
633  PR.Deallocate(ptr);
634}
635
636#endif // LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
637