| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | #ifndef LLVM_CLANG_LIB_SEMA_TYPELOCBUILDER_H |
| 15 | #define LLVM_CLANG_LIB_SEMA_TYPELOCBUILDER_H |
| 16 | |
| 17 | #include "clang/AST/ASTContext.h" |
| 18 | #include "clang/AST/TypeLoc.h" |
| 19 | |
| 20 | namespace clang { |
| 21 | |
| 22 | class TypeLocBuilder { |
| 23 | enum { InlineCapacity = 8 * sizeof(SourceLocation) }; |
| 24 | |
| 25 | |
| 26 | |
| 27 | char *Buffer; |
| 28 | |
| 29 | |
| 30 | size_t Capacity; |
| 31 | |
| 32 | |
| 33 | size_t Index; |
| 34 | |
| 35 | #ifndef NDEBUG |
| 36 | |
| 37 | QualType LastTy; |
| 38 | #endif |
| 39 | |
| 40 | |
| 41 | enum { BufferMaxAlignment = alignof(void *) }; |
| 42 | llvm::AlignedCharArray<BufferMaxAlignment, InlineCapacity> InlineBuffer; |
| 43 | unsigned NumBytesAtAlign4, NumBytesAtAlign8; |
| 44 | |
| 45 | public: |
| 46 | TypeLocBuilder() |
| 47 | : Buffer(InlineBuffer.buffer), Capacity(InlineCapacity), |
| 48 | Index(InlineCapacity), NumBytesAtAlign4(0), NumBytesAtAlign8(0) |
| 49 | { |
| 50 | } |
| 51 | |
| 52 | ~TypeLocBuilder() { |
| 53 | if (Buffer != InlineBuffer.buffer) |
| 54 | delete[] Buffer; |
| 55 | } |
| 56 | |
| 57 | |
| 58 | void reserve(size_t Requested) { |
| 59 | if (Requested > Capacity) |
| 60 | |
| 61 | grow(Requested); |
| 62 | } |
| 63 | |
| 64 | |
| 65 | |
| 66 | void pushFullCopy(TypeLoc L); |
| 67 | |
| 68 | |
| 69 | |
| 70 | TypeSpecTypeLoc pushTypeSpec(QualType T) { |
| 71 | size_t LocalSize = TypeSpecTypeLoc::LocalDataSize; |
| 72 | unsigned LocalAlign = TypeSpecTypeLoc::LocalDataAlignment; |
| 73 | return pushImpl(T, LocalSize, LocalAlign).castAs<TypeSpecTypeLoc>(); |
| 74 | } |
| 75 | |
| 76 | |
| 77 | void clear() { |
| 78 | #ifndef NDEBUG |
| 79 | LastTy = QualType(); |
| 80 | #endif |
| 81 | Index = Capacity; |
| 82 | NumBytesAtAlign4 = NumBytesAtAlign8 = 0; |
| 83 | } |
| 84 | |
| 85 | |
| 86 | |
| 87 | void TypeWasModifiedSafely(QualType T) { |
| 88 | #ifndef NDEBUG |
| 89 | LastTy = T; |
| 90 | #endif |
| 91 | } |
| 92 | |
| 93 | |
| 94 | |
| 95 | template <class TyLocType> TyLocType push(QualType T) { |
| 96 | TyLocType Loc = TypeLoc(T, nullptr).castAs<TyLocType>(); |
| 97 | size_t LocalSize = Loc.getLocalDataSize(); |
| 98 | unsigned LocalAlign = Loc.getLocalDataAlignment(); |
| 99 | return pushImpl(T, LocalSize, LocalAlign).castAs<TyLocType>(); |
| 100 | } |
| 101 | |
| 102 | |
| 103 | TypeSourceInfo *getTypeSourceInfo(ASTContext& Context, QualType T) { |
| 104 | #ifndef NDEBUG |
| 105 | (0) . __assert_fail ("T == LastTy && \"type doesn't match last type pushed!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/TypeLocBuilder.h", 105, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(T == LastTy && "type doesn't match last type pushed!"); |
| 106 | #endif |
| 107 | |
| 108 | size_t FullDataSize = Capacity - Index; |
| 109 | TypeSourceInfo *DI = Context.CreateTypeSourceInfo(T, FullDataSize); |
| 110 | memcpy(DI->getTypeLoc().getOpaqueData(), &Buffer[Index], FullDataSize); |
| 111 | return DI; |
| 112 | } |
| 113 | |
| 114 | |
| 115 | |
| 116 | TypeLoc getTypeLocInContext(ASTContext &Context, QualType T) { |
| 117 | #ifndef NDEBUG |
| 118 | (0) . __assert_fail ("T == LastTy && \"type doesn't match last type pushed!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/TypeLocBuilder.h", 118, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(T == LastTy && "type doesn't match last type pushed!"); |
| 119 | #endif |
| 120 | |
| 121 | size_t FullDataSize = Capacity - Index; |
| 122 | void *Mem = Context.Allocate(FullDataSize); |
| 123 | memcpy(Mem, &Buffer[Index], FullDataSize); |
| 124 | return TypeLoc(T, Mem); |
| 125 | } |
| 126 | |
| 127 | private: |
| 128 | |
| 129 | TypeLoc pushImpl(QualType T, size_t LocalSize, unsigned LocalAlignment); |
| 130 | |
| 131 | |
| 132 | void grow(size_t NewCapacity); |
| 133 | |
| 134 | |
| 135 | |
| 136 | |
| 137 | |
| 138 | |
| 139 | |
| 140 | TypeLoc getTemporaryTypeLoc(QualType T) { |
| 141 | #ifndef NDEBUG |
| 142 | (0) . __assert_fail ("LastTy == T && \"type doesn't match last type pushed!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/TypeLocBuilder.h", 142, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(LastTy == T && "type doesn't match last type pushed!"); |
| 143 | #endif |
| 144 | return TypeLoc(T, &Buffer[Index]); |
| 145 | } |
| 146 | }; |
| 147 | |
| 148 | } |
| 149 | |
| 150 | #endif |
| 151 | |