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 | |