1109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall//===--- TypeLocBuilder.h - Type Source Info collector ----------*- C++ -*-===// 2109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall// 3109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall// The LLVM Compiler Infrastructure 4109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall// 5109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall// This file is distributed under the University of Illinois Open Source 6109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall// License. See LICENSE.TXT for details. 7109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall// 8109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall//===----------------------------------------------------------------------===// 9109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall// 10109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall// This files defines TypeLocBuilder, a class for building TypeLocs 11109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall// bottom-up. 12109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall// 13109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall//===----------------------------------------------------------------------===// 14109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall 157e44e3fcd75147f229f42e6912898ce62d6b4d08Douglas Gregor#ifndef LLVM_CLANG_SEMA_TYPELOCBUILDER_H 167e44e3fcd75147f229f42e6912898ce62d6b4d08Douglas Gregor#define LLVM_CLANG_SEMA_TYPELOCBUILDER_H 17109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall 187745cab137b9d91205f13a7adaebe6ed801595f7Douglas Gregor#include "clang/AST/ASTContext.h" 1955fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/TypeLoc.h" 20109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall 21109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCallnamespace clang { 22109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall 23109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCallclass TypeLocBuilder { 24109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall enum { InlineCapacity = 8 * sizeof(SourceLocation) }; 25109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall 26109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall /// The underlying location-data buffer. Data grows from the end 27109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall /// of the buffer backwards. 28109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall char *Buffer; 29109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall 30109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall /// The capacity of the current buffer. 31109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall size_t Capacity; 32109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall 33109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall /// The index of the first occupied byte in the buffer. 34109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall size_t Index; 35109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall 36109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall#ifndef NDEBUG 37109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall /// The last type pushed on this builder. 38109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall QualType LastTy; 39109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall#endif 40109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall 41109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall /// The inline buffer. 4244ee0a710c59d8e6793189f903bae21c16814324Eli Friedman enum { BufferMaxAlignment = llvm::AlignOf<void*>::Alignment }; 4344ee0a710c59d8e6793189f903bae21c16814324Eli Friedman llvm::AlignedCharArray<BufferMaxAlignment, InlineCapacity> InlineBuffer; 4444ee0a710c59d8e6793189f903bae21c16814324Eli Friedman unsigned NumBytesAtAlign4, NumBytesAtAlign8; 45109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall 46109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall public: 47109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall TypeLocBuilder() 4844ee0a710c59d8e6793189f903bae21c16814324Eli Friedman : Buffer(InlineBuffer.buffer), Capacity(InlineCapacity), 4944ee0a710c59d8e6793189f903bae21c16814324Eli Friedman Index(InlineCapacity), NumBytesAtAlign4(0), NumBytesAtAlign8(0) 5044ee0a710c59d8e6793189f903bae21c16814324Eli Friedman { 5144ee0a710c59d8e6793189f903bae21c16814324Eli Friedman } 52109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall 53109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall ~TypeLocBuilder() { 5444ee0a710c59d8e6793189f903bae21c16814324Eli Friedman if (Buffer != InlineBuffer.buffer) 55109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall delete[] Buffer; 56109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall } 57109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall 58109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall /// Ensures that this buffer has at least as much capacity as described. 59109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall void reserve(size_t Requested) { 60109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall if (Requested > Capacity) 61109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall // For now, match the request exactly. 62109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall grow(Requested); 63109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall } 64109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall 65c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall /// Pushes a copy of the given TypeLoc onto this builder. The builder 66c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall /// must be empty for this to work. 6744ee0a710c59d8e6793189f903bae21c16814324Eli Friedman void pushFullCopy(TypeLoc L); 6841bafb1b62dfb2577c5aa7ba7fbd6ba5bebdbfeeJohn McCall 69ed97649e9574b9d854fa4d6109c9333ae0993554John McCall /// Pushes space for a typespec TypeLoc. Invalidates any TypeLocs 70ed97649e9574b9d854fa4d6109c9333ae0993554John McCall /// previously retrieved from this builder. 71ed97649e9574b9d854fa4d6109c9333ae0993554John McCall TypeSpecTypeLoc pushTypeSpec(QualType T) { 72ed97649e9574b9d854fa4d6109c9333ae0993554John McCall size_t LocalSize = TypeSpecTypeLoc::LocalDataSize; 7344ee0a710c59d8e6793189f903bae21c16814324Eli Friedman unsigned LocalAlign = TypeSpecTypeLoc::LocalDataAlignment; 7444ee0a710c59d8e6793189f903bae21c16814324Eli Friedman return pushImpl(T, LocalSize, LocalAlign).castAs<TypeSpecTypeLoc>(); 75ed97649e9574b9d854fa4d6109c9333ae0993554John McCall } 76480076c3defdcaf07e8a87c81930da467a702425John McCall 77480076c3defdcaf07e8a87c81930da467a702425John McCall /// Resets this builder to the newly-initialized state. 78480076c3defdcaf07e8a87c81930da467a702425John McCall void clear() { 79480076c3defdcaf07e8a87c81930da467a702425John McCall#ifndef NDEBUG 80480076c3defdcaf07e8a87c81930da467a702425John McCall LastTy = QualType(); 81480076c3defdcaf07e8a87c81930da467a702425John McCall#endif 82480076c3defdcaf07e8a87c81930da467a702425John McCall Index = Capacity; 8344ee0a710c59d8e6793189f903bae21c16814324Eli Friedman NumBytesAtAlign4 = NumBytesAtAlign8 = 0; 84480076c3defdcaf07e8a87c81930da467a702425John McCall } 85ed97649e9574b9d854fa4d6109c9333ae0993554John McCall 86f85e193739c953358c865005855253af4f68a497John McCall /// \brief Tell the TypeLocBuilder that the type it is storing has been 87f85e193739c953358c865005855253af4f68a497John McCall /// modified in some safe way that doesn't affect type-location information. 88f85e193739c953358c865005855253af4f68a497John McCall void TypeWasModifiedSafely(QualType T) { 89f85e193739c953358c865005855253af4f68a497John McCall#ifndef NDEBUG 90f85e193739c953358c865005855253af4f68a497John McCall LastTy = T; 91f85e193739c953358c865005855253af4f68a497John McCall#endif 92f85e193739c953358c865005855253af4f68a497John McCall } 93f85e193739c953358c865005855253af4f68a497John McCall 94ed97649e9574b9d854fa4d6109c9333ae0993554John McCall /// Pushes space for a new TypeLoc of the given type. Invalidates 95109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall /// any TypeLocs previously retrieved from this builder. 96109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall template <class TyLocType> TyLocType push(QualType T) { 976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TyLocType Loc = TypeLoc(T, nullptr).castAs<TyLocType>(); 9844ee0a710c59d8e6793189f903bae21c16814324Eli Friedman size_t LocalSize = Loc.getLocalDataSize(); 9944ee0a710c59d8e6793189f903bae21c16814324Eli Friedman unsigned LocalAlign = Loc.getLocalDataAlignment(); 10044ee0a710c59d8e6793189f903bae21c16814324Eli Friedman return pushImpl(T, LocalSize, LocalAlign).castAs<TyLocType>(); 101ed97649e9574b9d854fa4d6109c9333ae0993554John McCall } 102ed97649e9574b9d854fa4d6109c9333ae0993554John McCall 103a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall /// Creates a TypeSourceInfo for the given type. 104a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall TypeSourceInfo *getTypeSourceInfo(ASTContext& Context, QualType T) { 105ed97649e9574b9d854fa4d6109c9333ae0993554John McCall#ifndef NDEBUG 106ed97649e9574b9d854fa4d6109c9333ae0993554John McCall assert(T == LastTy && "type doesn't match last type pushed!"); 107ed97649e9574b9d854fa4d6109c9333ae0993554John McCall#endif 108ed97649e9574b9d854fa4d6109c9333ae0993554John McCall 109ed97649e9574b9d854fa4d6109c9333ae0993554John McCall size_t FullDataSize = Capacity - Index; 110a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall TypeSourceInfo *DI = Context.CreateTypeSourceInfo(T, FullDataSize); 111ed97649e9574b9d854fa4d6109c9333ae0993554John McCall memcpy(DI->getTypeLoc().getOpaqueData(), &Buffer[Index], FullDataSize); 112ed97649e9574b9d854fa4d6109c9333ae0993554John McCall return DI; 113ed97649e9574b9d854fa4d6109c9333ae0993554John McCall } 114ed97649e9574b9d854fa4d6109c9333ae0993554John McCall 1152e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor /// \brief Copies the type-location information to the given AST context and 1162e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor /// returns a \c TypeLoc referring into the AST context. 1172e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor TypeLoc getTypeLocInContext(ASTContext &Context, QualType T) { 1182e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor#ifndef NDEBUG 1192e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor assert(T == LastTy && "type doesn't match last type pushed!"); 1202e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor#endif 1212e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor 1222e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor size_t FullDataSize = Capacity - Index; 1232e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor void *Mem = Context.Allocate(FullDataSize); 1242e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor memcpy(Mem, &Buffer[Index], FullDataSize); 1252e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor return TypeLoc(T, Mem); 1262e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor } 1272e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor 128ed97649e9574b9d854fa4d6109c9333ae0993554John McCallprivate: 129109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall 13044ee0a710c59d8e6793189f903bae21c16814324Eli Friedman TypeLoc pushImpl(QualType T, size_t LocalSize, unsigned LocalAlignment); 131109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall 132109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall /// Grow to the given capacity. 13344ee0a710c59d8e6793189f903bae21c16814324Eli Friedman void grow(size_t NewCapacity); 13441bafb1b62dfb2577c5aa7ba7fbd6ba5bebdbfeeJohn McCall 1354020caec546d221170072d2388b57d151cb26111Douglas Gregor /// \brief Retrieve a temporary TypeLoc that refers into this \c TypeLocBuilder 1364020caec546d221170072d2388b57d151cb26111Douglas Gregor /// object. 1374020caec546d221170072d2388b57d151cb26111Douglas Gregor /// 1384020caec546d221170072d2388b57d151cb26111Douglas Gregor /// The resulting \c TypeLoc should only be used so long as the 1394020caec546d221170072d2388b57d151cb26111Douglas Gregor /// \c TypeLocBuilder is active and has not had more type information 1404020caec546d221170072d2388b57d151cb26111Douglas Gregor /// pushed into it. 1414020caec546d221170072d2388b57d151cb26111Douglas Gregor TypeLoc getTemporaryTypeLoc(QualType T) { 14241bafb1b62dfb2577c5aa7ba7fbd6ba5bebdbfeeJohn McCall#ifndef NDEBUG 14341bafb1b62dfb2577c5aa7ba7fbd6ba5bebdbfeeJohn McCall assert(LastTy == T && "type doesn't match last type pushed!"); 14441bafb1b62dfb2577c5aa7ba7fbd6ba5bebdbfeeJohn McCall#endif 14541bafb1b62dfb2577c5aa7ba7fbd6ba5bebdbfeeJohn McCall return TypeLoc(T, &Buffer[Index]); 14641bafb1b62dfb2577c5aa7ba7fbd6ba5bebdbfeeJohn McCall } 147109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall}; 148109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall 149109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall} 150109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall 151109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall#endif 152