clang API Documentation
00001 //===--- TypeLocBuilder.h - Type Source Info collector ----------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This files defines TypeLocBuilder, a class for building TypeLocs 00011 // bottom-up. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_CLANG_LIB_SEMA_TYPELOCBUILDER_H 00016 #define LLVM_CLANG_LIB_SEMA_TYPELOCBUILDER_H 00017 00018 #include "clang/AST/ASTContext.h" 00019 #include "clang/AST/TypeLoc.h" 00020 00021 namespace clang { 00022 00023 class TypeLocBuilder { 00024 enum { InlineCapacity = 8 * sizeof(SourceLocation) }; 00025 00026 /// The underlying location-data buffer. Data grows from the end 00027 /// of the buffer backwards. 00028 char *Buffer; 00029 00030 /// The capacity of the current buffer. 00031 size_t Capacity; 00032 00033 /// The index of the first occupied byte in the buffer. 00034 size_t Index; 00035 00036 #ifndef NDEBUG 00037 /// The last type pushed on this builder. 00038 QualType LastTy; 00039 #endif 00040 00041 /// The inline buffer. 00042 enum { BufferMaxAlignment = llvm::AlignOf<void*>::Alignment }; 00043 llvm::AlignedCharArray<BufferMaxAlignment, InlineCapacity> InlineBuffer; 00044 unsigned NumBytesAtAlign4, NumBytesAtAlign8; 00045 00046 public: 00047 TypeLocBuilder() 00048 : Buffer(InlineBuffer.buffer), Capacity(InlineCapacity), 00049 Index(InlineCapacity), NumBytesAtAlign4(0), NumBytesAtAlign8(0) 00050 { 00051 } 00052 00053 ~TypeLocBuilder() { 00054 if (Buffer != InlineBuffer.buffer) 00055 delete[] Buffer; 00056 } 00057 00058 /// Ensures that this buffer has at least as much capacity as described. 00059 void reserve(size_t Requested) { 00060 if (Requested > Capacity) 00061 // For now, match the request exactly. 00062 grow(Requested); 00063 } 00064 00065 /// Pushes a copy of the given TypeLoc onto this builder. The builder 00066 /// must be empty for this to work. 00067 void pushFullCopy(TypeLoc L); 00068 00069 /// Pushes space for a typespec TypeLoc. Invalidates any TypeLocs 00070 /// previously retrieved from this builder. 00071 TypeSpecTypeLoc pushTypeSpec(QualType T) { 00072 size_t LocalSize = TypeSpecTypeLoc::LocalDataSize; 00073 unsigned LocalAlign = TypeSpecTypeLoc::LocalDataAlignment; 00074 return pushImpl(T, LocalSize, LocalAlign).castAs<TypeSpecTypeLoc>(); 00075 } 00076 00077 /// Resets this builder to the newly-initialized state. 00078 void clear() { 00079 #ifndef NDEBUG 00080 LastTy = QualType(); 00081 #endif 00082 Index = Capacity; 00083 NumBytesAtAlign4 = NumBytesAtAlign8 = 0; 00084 } 00085 00086 /// \brief Tell the TypeLocBuilder that the type it is storing has been 00087 /// modified in some safe way that doesn't affect type-location information. 00088 void TypeWasModifiedSafely(QualType T) { 00089 #ifndef NDEBUG 00090 LastTy = T; 00091 #endif 00092 } 00093 00094 /// Pushes space for a new TypeLoc of the given type. Invalidates 00095 /// any TypeLocs previously retrieved from this builder. 00096 template <class TyLocType> TyLocType push(QualType T) { 00097 TyLocType Loc = TypeLoc(T, nullptr).castAs<TyLocType>(); 00098 size_t LocalSize = Loc.getLocalDataSize(); 00099 unsigned LocalAlign = Loc.getLocalDataAlignment(); 00100 return pushImpl(T, LocalSize, LocalAlign).castAs<TyLocType>(); 00101 } 00102 00103 /// Creates a TypeSourceInfo for the given type. 00104 TypeSourceInfo *getTypeSourceInfo(ASTContext& Context, QualType T) { 00105 #ifndef NDEBUG 00106 assert(T == LastTy && "type doesn't match last type pushed!"); 00107 #endif 00108 00109 size_t FullDataSize = Capacity - Index; 00110 TypeSourceInfo *DI = Context.CreateTypeSourceInfo(T, FullDataSize); 00111 memcpy(DI->getTypeLoc().getOpaqueData(), &Buffer[Index], FullDataSize); 00112 return DI; 00113 } 00114 00115 /// \brief Copies the type-location information to the given AST context and 00116 /// returns a \c TypeLoc referring into the AST context. 00117 TypeLoc getTypeLocInContext(ASTContext &Context, QualType T) { 00118 #ifndef NDEBUG 00119 assert(T == LastTy && "type doesn't match last type pushed!"); 00120 #endif 00121 00122 size_t FullDataSize = Capacity - Index; 00123 void *Mem = Context.Allocate(FullDataSize); 00124 memcpy(Mem, &Buffer[Index], FullDataSize); 00125 return TypeLoc(T, Mem); 00126 } 00127 00128 private: 00129 00130 TypeLoc pushImpl(QualType T, size_t LocalSize, unsigned LocalAlignment); 00131 00132 /// Grow to the given capacity. 00133 void grow(size_t NewCapacity); 00134 00135 /// \brief Retrieve a temporary TypeLoc that refers into this \c TypeLocBuilder 00136 /// object. 00137 /// 00138 /// The resulting \c TypeLoc should only be used so long as the 00139 /// \c TypeLocBuilder is active and has not had more type information 00140 /// pushed into it. 00141 TypeLoc getTemporaryTypeLoc(QualType T) { 00142 #ifndef NDEBUG 00143 assert(LastTy == T && "type doesn't match last type pushed!"); 00144 #endif 00145 return TypeLoc(T, &Buffer[Index]); 00146 } 00147 }; 00148 00149 } 00150 00151 #endif