PreprocessingRecord.h revision 4ae8f298b1ea51b4c2234f9148e2e4349c9bdd23
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/PointerUnion.h" 20#include "llvm/Support/Allocator.h" 21#include <vector> 22 23namespace clang { 24 class IdentifierInfo; 25 class PreprocessingRecord; 26} 27 28/// \brief Allocates memory within a Clang preprocessing record. 29void* operator new(size_t bytes, clang::PreprocessingRecord& PR, 30 unsigned alignment = 8) throw(); 31 32/// \brief Frees memory allocated in a Clang preprocessing record. 33void operator delete(void* ptr, clang::PreprocessingRecord& PR, 34 unsigned) throw(); 35 36namespace clang { 37 /// \brief Base class that describes a preprocessed entity, which may be a 38 /// preprocessor directive or macro instantiation. 39 class PreprocessedEntity { 40 public: 41 /// \brief The kind of preprocessed entity an object describes. 42 enum EntityKind { 43 /// \brief A macro instantiation. 44 MacroInstantiationKind, 45 46 /// \brief A preprocessing directive whose kind is not specified. 47 /// 48 /// This kind will be used for any preprocessing directive that does not 49 /// have a more specific kind within the \c DirectiveKind enumeration. 50 PreprocessingDirectiveKind, 51 52 /// \brief A macro definition. 53 MacroDefinitionKind, 54 55 FirstPreprocessingDirective = PreprocessingDirectiveKind, 56 LastPreprocessingDirective = MacroDefinitionKind 57 }; 58 59 private: 60 /// \brief The kind of preprocessed entity that this object describes. 61 EntityKind Kind; 62 63 /// \brief The source range that covers this preprocessed entity. 64 SourceRange Range; 65 66 protected: 67 PreprocessedEntity(EntityKind Kind, SourceRange Range) 68 : Kind(Kind), Range(Range) { } 69 70 public: 71 /// \brief Retrieve the kind of preprocessed entity stored in this object. 72 EntityKind getKind() const { return Kind; } 73 74 /// \brief Retrieve the source range that covers this entire preprocessed 75 /// entity. 76 SourceRange getSourceRange() const { return Range; } 77 78 // Implement isa/cast/dyncast/etc. 79 static bool classof(const PreprocessedEntity *) { return true; } 80 81 // Only allow allocation of preprocessed entities using the allocator 82 // in PreprocessingRecord or by doing a placement new. 83 void* operator new(size_t bytes, PreprocessingRecord& PR, 84 unsigned alignment = 8) throw() { 85 return ::operator new(bytes, PR, alignment); 86 } 87 88 void* operator new(size_t bytes, void* mem) throw() { 89 return mem; 90 } 91 92 void operator delete(void* ptr, PreprocessingRecord& PR, 93 unsigned alignment) throw() { 94 return ::operator delete(ptr, PR, alignment); 95 } 96 97 void operator delete(void*, std::size_t) throw() { } 98 void operator delete(void*, void*) throw() { } 99 100 private: 101 // Make vanilla 'new' and 'delete' illegal for preprocessed entities. 102 void* operator new(size_t bytes) throw(); 103 void operator delete(void* data) throw(); 104 }; 105 106 /// \brief Records the location of a macro instantiation. 107 class MacroInstantiation : public PreprocessedEntity { 108 /// \brief The name of the macro being instantiation. 109 IdentifierInfo *Name; 110 111 /// \brief The location of the definition of the macro being instantiated. 112 SourceLocation DefinitionLocation; 113 114 public: 115 MacroInstantiation(IdentifierInfo *Name, SourceRange Range, 116 SourceLocation DefinitionLocation) 117 : PreprocessedEntity(MacroInstantiationKind, Range), Name(Name), 118 DefinitionLocation(DefinitionLocation) { } 119 120 /// \brief The name of the macro being instantiated. 121 IdentifierInfo *getName() const { return Name; } 122 123 /// \brief The location of the definition of the macro being instantiated. 124 /// FIXME: Could we just provide MacroInfo pointers instead, by teaching 125 /// the preprocessor to hold on to them when we care to keep them around? 126 SourceLocation getDefinitionLocation() const { return DefinitionLocation; } 127 128 // Implement isa/cast/dyncast/etc. 129 static bool classof(const PreprocessedEntity *PE) { 130 return PE->getKind() == MacroInstantiationKind; 131 } 132 static bool classof(const MacroInstantiation *) { return true; } 133 134 }; 135 136 /// \brief Records the presence of a preprocessor directive. 137 class PreprocessingDirective : public PreprocessedEntity { 138 public: 139 PreprocessingDirective(EntityKind Kind, SourceRange Range) 140 : PreprocessedEntity(Kind, Range) { } 141 142 // Implement isa/cast/dyncast/etc. 143 static bool classof(const PreprocessedEntity *PD) { 144 return PD->getKind() >= FirstPreprocessingDirective && 145 PD->getKind() <= LastPreprocessingDirective; 146 } 147 static bool classof(const PreprocessingDirective *) { return true; } 148 }; 149 150 /// \brief Record the location of a macro definition. 151 class MacroDefinition : public PreprocessingDirective { 152 /// \brief The name of the macro being defined. 153 const IdentifierInfo *Name; 154 155 /// \brief The location of the macro name in the macro definition. 156 SourceLocation Location; 157 158 public: 159 explicit MacroDefinition(const IdentifierInfo *Name, SourceLocation Location, 160 SourceRange Range) 161 : PreprocessingDirective(MacroDefinitionKind, Range), Name(Name), 162 Location(Location) { } 163 164 /// \brief Retrieve the name of the macro being defined. 165 const IdentifierInfo *getMacroName() const { return Name; } 166 167 /// \brief Retrieve the location of the macro name in the definition. 168 SourceLocation getLocation() const { return Location; } 169 170 // Implement isa/cast/dyncast/etc. 171 static bool classof(const PreprocessingDirective *PD) { 172 return PD->getKind() == MacroDefinitionKind; 173 } 174 static bool classof(const MacroDefinition *) { return true; } 175 }; 176 177 /// \brief A record of the steps taken while preprocessing a source file, 178 /// including the various preprocessing directives processed, macros 179 /// instantiated, etc. 180 class PreprocessingRecord { 181 /// \brief Allocator used to store preprocessing objects. 182 llvm::BumpPtrAllocator BumpAlloc; 183 184 /// \brief The set of preprocessed entities in this record, in order they 185 /// were seen. 186 std::vector<PreprocessedEntity *> PreprocessedEntities; 187 188 public: 189 /// \brief Allocate memory in the preprocessing record. 190 void *Allocate(unsigned Size, unsigned Align = 8) { 191 return BumpAlloc.Allocate(Size, Align); 192 } 193 194 /// \brief Deallocate memory in the preprocessing record. 195 void Deallocate(void *Ptr) { } 196 197 // Iteration over the preprocessed entities. 198 typedef std::vector<PreprocessedEntity *>::iterator iterator; 199 typedef std::vector<PreprocessedEntity *>::const_iterator const_iterator; 200 iterator begin() { return PreprocessedEntities.begin(); } 201 iterator end() { return PreprocessedEntities.end(); } 202 const_iterator begin() const { return PreprocessedEntities.begin(); } 203 const_iterator end() const { return PreprocessedEntities.end(); } 204 205 /// \brief Add a new preprocessed entity to this record. 206 void addPreprocessedEntity(PreprocessedEntity *Entity); 207 }; 208 209 /// \brief Preprocessor callback action used to populate a preprocessing 210 /// record. 211 class PopulatePreprocessingRecord : public PPCallbacks { 212 /// \brief The preprocessing record this action will populate. 213 PreprocessingRecord &Record; 214 215 public: 216 explicit PopulatePreprocessingRecord(PreprocessingRecord &Record) 217 : Record(Record) { } 218 219 virtual void MacroExpands(const Token &Id, const MacroInfo* MI); 220 virtual void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI); 221 }; 222 223} // end namespace clang 224 225inline void* operator new(size_t bytes, clang::PreprocessingRecord& PR, 226 unsigned alignment) throw() { 227 return PR.Allocate(bytes, alignment); 228} 229 230inline void operator delete(void* ptr, clang::PreprocessingRecord& PR, 231 unsigned) throw() { 232 PR.Deallocate(ptr); 233} 234 235#endif // LLVM_CLANG_LEX_PREPROCESSINGRECORD_H 236