/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/clang/include/clang/AST/APValue.h
Line | Count | Source |
1 | | //===--- APValue.h - Union class for APFloat/APSInt/Complex -----*- 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 APValue class. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #ifndef LLVM_CLANG_AST_APVALUE_H |
15 | | #define LLVM_CLANG_AST_APVALUE_H |
16 | | |
17 | | #include "clang/Basic/LLVM.h" |
18 | | #include "llvm/ADT/APFloat.h" |
19 | | #include "llvm/ADT/APSInt.h" |
20 | | #include "llvm/ADT/PointerIntPair.h" |
21 | | #include "llvm/ADT/PointerUnion.h" |
22 | | |
23 | | namespace clang { |
24 | | class AddrLabelExpr; |
25 | | class ASTContext; |
26 | | class CharUnits; |
27 | | class DiagnosticBuilder; |
28 | | class Expr; |
29 | | class FieldDecl; |
30 | | class Decl; |
31 | | class ValueDecl; |
32 | | class CXXRecordDecl; |
33 | | class QualType; |
34 | | |
35 | | /// APValue - This class implements a discriminated union of [uninitialized] |
36 | | /// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset], |
37 | | /// [Vector: N * APValue], [Array: N * APValue] |
38 | | class APValue { |
39 | | typedef llvm::APSInt APSInt; |
40 | | typedef llvm::APFloat APFloat; |
41 | | public: |
42 | | enum ValueKind { |
43 | | Uninitialized, |
44 | | Int, |
45 | | Float, |
46 | | ComplexInt, |
47 | | ComplexFloat, |
48 | | LValue, |
49 | | Vector, |
50 | | Array, |
51 | | Struct, |
52 | | Union, |
53 | | MemberPointer, |
54 | | AddrLabelDiff |
55 | | }; |
56 | | typedef llvm::PointerUnion<const ValueDecl *, const Expr *> LValueBase; |
57 | | typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType; |
58 | | union LValuePathEntry { |
59 | | /// BaseOrMember - The FieldDecl or CXXRecordDecl indicating the next item |
60 | | /// in the path. An opaque value of type BaseOrMemberType. |
61 | | void *BaseOrMember; |
62 | | /// ArrayIndex - The array index of the next item in the path. |
63 | | uint64_t ArrayIndex; |
64 | | }; |
65 | | struct NoLValuePath {}; |
66 | | struct UninitArray {}; |
67 | | struct UninitStruct {}; |
68 | | private: |
69 | | ValueKind Kind; |
70 | | |
71 | | struct ComplexAPSInt { |
72 | | APSInt Real, Imag; |
73 | 44 | ComplexAPSInt() : Real(1), Imag(1) {} |
74 | | }; |
75 | | struct ComplexAPFloat { |
76 | | APFloat Real, Imag; |
77 | 135 | ComplexAPFloat() : Real(0.0), Imag(0.0) {} |
78 | | }; |
79 | | struct LV; |
80 | | struct Vec { |
81 | | APValue *Elts; |
82 | | unsigned NumElts; |
83 | 1.64k | Vec() : Elts(nullptr), NumElts(0) {} |
84 | 1.64k | ~Vec() { delete[] Elts; } |
85 | | }; |
86 | | struct Arr { |
87 | | APValue *Elts; |
88 | | unsigned NumElts, ArrSize; |
89 | | Arr(unsigned NumElts, unsigned ArrSize); |
90 | | ~Arr(); |
91 | | }; |
92 | | struct StructData { |
93 | | APValue *Elts; |
94 | | unsigned NumBases; |
95 | | unsigned NumFields; |
96 | | StructData(unsigned NumBases, unsigned NumFields); |
97 | | ~StructData(); |
98 | | }; |
99 | | struct UnionData { |
100 | | const FieldDecl *Field; |
101 | | APValue *Value; |
102 | | UnionData(); |
103 | | ~UnionData(); |
104 | | }; |
105 | | struct AddrLabelDiffData { |
106 | | const AddrLabelExpr* LHSExpr; |
107 | | const AddrLabelExpr* RHSExpr; |
108 | | }; |
109 | | struct MemberPointerData; |
110 | | |
111 | | // We ensure elsewhere that Data is big enough for LV and MemberPointerData. |
112 | | typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt, |
113 | | ComplexAPFloat, Vec, Arr, StructData, |
114 | | UnionData, AddrLabelDiffData> DataType; |
115 | | static const size_t DataSize = sizeof(DataType); |
116 | | |
117 | | DataType Data; |
118 | | |
119 | | public: |
120 | 31.7M | APValue() : Kind(Uninitialized) {} |
121 | 12.7M | explicit APValue(APSInt I) : Kind(Uninitialized) { |
122 | 12.7M | MakeInt(); setInt(std::move(I)); |
123 | 12.7M | } |
124 | 154k | explicit APValue(APFloat F) : Kind(Uninitialized) { |
125 | 154k | MakeFloat(); setFloat(std::move(F)); |
126 | 154k | } |
127 | 1.26k | explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) { |
128 | 1.26k | MakeVector(); setVector(E, N); |
129 | 1.26k | } |
130 | 43 | APValue(APSInt R, APSInt I) : Kind(Uninitialized) { |
131 | 43 | MakeComplexInt(); setComplexInt(std::move(R), std::move(I)); |
132 | 43 | } |
133 | 125 | APValue(APFloat R, APFloat I) : Kind(Uninitialized) { |
134 | 125 | MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I)); |
135 | 125 | } |
136 | | APValue(const APValue &RHS); |
137 | 38.8k | APValue(APValue &&RHS) : Kind(Uninitialized) { swap(RHS); } |
138 | | APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex, |
139 | | bool IsNullPtr = false) |
140 | 26.0k | : Kind(Uninitialized) { |
141 | 26.0k | MakeLValue(); setLValue(B, O, N, CallIndex, IsNullPtr); |
142 | 26.0k | } |
143 | | APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path, |
144 | | bool OnePastTheEnd, unsigned CallIndex, bool IsNullPtr = false) |
145 | 933k | : Kind(Uninitialized) { |
146 | 933k | MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex, IsNullPtr); |
147 | 933k | } |
148 | 3.41k | APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) { |
149 | 3.41k | MakeArray(InitElts, Size); |
150 | 3.41k | } |
151 | 6.34k | APValue(UninitStruct, unsigned B, unsigned M) : Kind(Uninitialized) { |
152 | 6.34k | MakeStruct(B, M); |
153 | 6.34k | } |
154 | | explicit APValue(const FieldDecl *D, const APValue &V = APValue()) |
155 | 705 | : Kind(Uninitialized) { |
156 | 705 | MakeUnion(); setUnion(D, V); |
157 | 705 | } |
158 | | APValue(const ValueDecl *Member, bool IsDerivedMember, |
159 | 1.26k | ArrayRef<const CXXRecordDecl*> Path) : Kind(Uninitialized) { |
160 | 1.26k | MakeMemberPointer(Member, IsDerivedMember, Path); |
161 | 1.26k | } |
162 | | APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr) |
163 | 28 | : Kind(Uninitialized) { |
164 | 28 | MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr); |
165 | 28 | } |
166 | | |
167 | 45.9M | ~APValue() { |
168 | 45.9M | MakeUninit(); |
169 | 45.9M | } |
170 | | |
171 | | /// \brief Returns whether the object performed allocations. |
172 | | /// |
173 | | /// If APValues are constructed via placement new, \c needsCleanup() |
174 | | /// indicates whether the destructor must be called in order to correctly |
175 | | /// free all allocated memory. |
176 | | bool needsCleanup() const; |
177 | | |
178 | | /// \brief Swaps the contents of this and the given APValue. |
179 | | void swap(APValue &RHS); |
180 | | |
181 | 2.15M | ValueKind getKind() const { return Kind; } |
182 | 3.44M | bool isUninit() const { return Kind == Uninitialized; } |
183 | 8.70M | bool isInt() const { return Kind == Int; } |
184 | 25.4k | bool isFloat() const { return Kind == Float; } |
185 | 28 | bool isComplexInt() const { return Kind == ComplexInt; } |
186 | 3 | bool isComplexFloat() const { return Kind == ComplexFloat; } |
187 | 4.99M | bool isLValue() const { return Kind == LValue; } |
188 | 68 | bool isVector() const { return Kind == Vector; } |
189 | 2.92M | bool isArray() const { return Kind == Array; } |
190 | 2.92M | bool isStruct() const { return Kind == Struct; } |
191 | 2.92M | bool isUnion() const { return Kind == Union; } |
192 | 2.76M | bool isMemberPointer() const { return Kind == MemberPointer; } |
193 | 232k | bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; } |
194 | | |
195 | | void dump() const; |
196 | | void dump(raw_ostream &OS) const; |
197 | | |
198 | | void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const; |
199 | | std::string getAsString(ASTContext &Ctx, QualType Ty) const; |
200 | | |
201 | 15.4M | APSInt &getInt() { |
202 | 15.4M | assert(isInt() && "Invalid accessor"); |
203 | 15.4M | return *(APSInt*)(char*)Data.buffer; |
204 | 15.4M | } |
205 | 3.94M | const APSInt &getInt() const { |
206 | 3.94M | return const_cast<APValue*>(this)->getInt(); |
207 | 3.94M | } |
208 | | |
209 | 91.9k | APFloat &getFloat() { |
210 | 91.9k | assert(isFloat() && "Invalid accessor"); |
211 | 91.9k | return *(APFloat*)(char*)Data.buffer; |
212 | 91.9k | } |
213 | 89.9k | const APFloat &getFloat() const { |
214 | 89.9k | return const_cast<APValue*>(this)->getFloat(); |
215 | 89.9k | } |
216 | | |
217 | 29 | APSInt &getComplexIntReal() { |
218 | 29 | assert(isComplexInt() && "Invalid accessor"); |
219 | 29 | return ((ComplexAPSInt*)(char*)Data.buffer)->Real; |
220 | 29 | } |
221 | 20 | const APSInt &getComplexIntReal() const { |
222 | 20 | return const_cast<APValue*>(this)->getComplexIntReal(); |
223 | 20 | } |
224 | | |
225 | 20 | APSInt &getComplexIntImag() { |
226 | 20 | assert(isComplexInt() && "Invalid accessor"); |
227 | 20 | return ((ComplexAPSInt*)(char*)Data.buffer)->Imag; |
228 | 20 | } |
229 | 11 | const APSInt &getComplexIntImag() const { |
230 | 11 | return const_cast<APValue*>(this)->getComplexIntImag(); |
231 | 11 | } |
232 | | |
233 | 84 | APFloat &getComplexFloatReal() { |
234 | 84 | assert(isComplexFloat() && "Invalid accessor"); |
235 | 84 | return ((ComplexAPFloat*)(char*)Data.buffer)->Real; |
236 | 84 | } |
237 | 80 | const APFloat &getComplexFloatReal() const { |
238 | 80 | return const_cast<APValue*>(this)->getComplexFloatReal(); |
239 | 80 | } |
240 | | |
241 | 59 | APFloat &getComplexFloatImag() { |
242 | 59 | assert(isComplexFloat() && "Invalid accessor"); |
243 | 59 | return ((ComplexAPFloat*)(char*)Data.buffer)->Imag; |
244 | 59 | } |
245 | 55 | const APFloat &getComplexFloatImag() const { |
246 | 55 | return const_cast<APValue*>(this)->getComplexFloatImag(); |
247 | 55 | } |
248 | | |
249 | | const LValueBase getLValueBase() const; |
250 | | CharUnits &getLValueOffset(); |
251 | 818k | const CharUnits &getLValueOffset() const { |
252 | 818k | return const_cast<APValue*>(this)->getLValueOffset(); |
253 | 818k | } |
254 | | bool isLValueOnePastTheEnd() const; |
255 | | bool hasLValuePath() const; |
256 | | ArrayRef<LValuePathEntry> getLValuePath() const; |
257 | | unsigned getLValueCallIndex() const; |
258 | | bool isNullPointer() const; |
259 | | |
260 | 5.53k | APValue &getVectorElt(unsigned I) { |
261 | 5.53k | assert(isVector() && "Invalid accessor"); |
262 | 5.53k | assert(I < getVectorLength() && "Index out of range"); |
263 | 5.53k | return ((Vec*)(char*)Data.buffer)->Elts[I]; |
264 | 5.53k | } |
265 | 5.03k | const APValue &getVectorElt(unsigned I) const { |
266 | 5.03k | return const_cast<APValue*>(this)->getVectorElt(I); |
267 | 5.03k | } |
268 | 1.67k | unsigned getVectorLength() const { |
269 | 1.67k | assert(isVector() && "Invalid accessor"); |
270 | 1.67k | return ((const Vec*)(const void *)Data.buffer)->NumElts; |
271 | 1.67k | } |
272 | | |
273 | 20.4k | APValue &getArrayInitializedElt(unsigned I) { |
274 | 20.4k | assert(isArray() && "Invalid accessor"); |
275 | 20.4k | assert(I < getArrayInitializedElts() && "Index out of range"); |
276 | 20.4k | return ((Arr*)(char*)Data.buffer)->Elts[I]; |
277 | 20.4k | } |
278 | 4.05k | const APValue &getArrayInitializedElt(unsigned I) const { |
279 | 4.05k | return const_cast<APValue*>(this)->getArrayInitializedElt(I); |
280 | 4.05k | } |
281 | 7.50k | bool hasArrayFiller() const { |
282 | 7.50k | return getArrayInitializedElts() != getArraySize(); |
283 | 7.50k | } |
284 | 11.6k | APValue &getArrayFiller() { |
285 | 11.6k | assert(isArray() && "Invalid accessor"); |
286 | 11.6k | assert(hasArrayFiller() && "No array filler"); |
287 | 11.6k | return ((Arr*)(char*)Data.buffer)->Elts[getArrayInitializedElts()]; |
288 | 11.6k | } |
289 | 1.68k | const APValue &getArrayFiller() const { |
290 | 1.68k | return const_cast<APValue*>(this)->getArrayFiller(); |
291 | 1.68k | } |
292 | 26.9k | unsigned getArrayInitializedElts() const { |
293 | 26.9k | assert(isArray() && "Invalid accessor"); |
294 | 26.9k | return ((const Arr*)(const void *)Data.buffer)->NumElts; |
295 | 26.9k | } |
296 | 8.80k | unsigned getArraySize() const { |
297 | 8.80k | assert(isArray() && "Invalid accessor"); |
298 | 8.80k | return ((const Arr*)(const void *)Data.buffer)->ArrSize; |
299 | 8.80k | } |
300 | | |
301 | 35.7k | unsigned getStructNumBases() const { |
302 | 35.7k | assert(isStruct() && "Invalid accessor"); |
303 | 35.7k | return ((const StructData*)(const char*)Data.buffer)->NumBases; |
304 | 35.7k | } |
305 | 5.13k | unsigned getStructNumFields() const { |
306 | 5.13k | assert(isStruct() && "Invalid accessor"); |
307 | 5.13k | return ((const StructData*)(const char*)Data.buffer)->NumFields; |
308 | 5.13k | } |
309 | 1.81k | APValue &getStructBase(unsigned i) { |
310 | 1.81k | assert(isStruct() && "Invalid accessor"); |
311 | 1.81k | return ((StructData*)(char*)Data.buffer)->Elts[i]; |
312 | 1.81k | } |
313 | 30.6k | APValue &getStructField(unsigned i) { |
314 | 30.6k | assert(isStruct() && "Invalid accessor"); |
315 | 30.6k | return ((StructData*)(char*)Data.buffer)->Elts[getStructNumBases() + i]; |
316 | 30.6k | } |
317 | 422 | const APValue &getStructBase(unsigned i) const { |
318 | 422 | return const_cast<APValue*>(this)->getStructBase(i); |
319 | 422 | } |
320 | 6.06k | const APValue &getStructField(unsigned i) const { |
321 | 6.06k | return const_cast<APValue*>(this)->getStructField(i); |
322 | 6.06k | } |
323 | | |
324 | 586 | const FieldDecl *getUnionField() const { |
325 | 586 | assert(isUnion() && "Invalid accessor"); |
326 | 586 | return ((const UnionData*)(const char*)Data.buffer)->Field; |
327 | 586 | } |
328 | 959 | APValue &getUnionValue() { |
329 | 959 | assert(isUnion() && "Invalid accessor"); |
330 | 959 | return *((UnionData*)(char*)Data.buffer)->Value; |
331 | 959 | } |
332 | 125 | const APValue &getUnionValue() const { |
333 | 125 | return const_cast<APValue*>(this)->getUnionValue(); |
334 | 125 | } |
335 | | |
336 | | const ValueDecl *getMemberPointerDecl() const; |
337 | | bool isMemberPointerToDerivedMember() const; |
338 | | ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const; |
339 | | |
340 | 17 | const AddrLabelExpr* getAddrLabelDiffLHS() const { |
341 | 17 | assert(isAddrLabelDiff() && "Invalid accessor"); |
342 | 17 | return ((const AddrLabelDiffData*)(const char*)Data.buffer)->LHSExpr; |
343 | 17 | } |
344 | 17 | const AddrLabelExpr* getAddrLabelDiffRHS() const { |
345 | 17 | assert(isAddrLabelDiff() && "Invalid accessor"); |
346 | 17 | return ((const AddrLabelDiffData*)(const char*)Data.buffer)->RHSExpr; |
347 | 17 | } |
348 | | |
349 | 13.0M | void setInt(APSInt I) { |
350 | 13.0M | assert(isInt() && "Invalid accessor"); |
351 | 13.0M | *(APSInt *)(char *)Data.buffer = std::move(I); |
352 | 13.0M | } |
353 | 158k | void setFloat(APFloat F) { |
354 | 158k | assert(isFloat() && "Invalid accessor"); |
355 | 158k | *(APFloat *)(char *)Data.buffer = std::move(F); |
356 | 158k | } |
357 | 1.64k | void setVector(const APValue *E, unsigned N) { |
358 | 1.64k | assert(isVector() && "Invalid accessor"); |
359 | 1.64k | ((Vec*)(char*)Data.buffer)->Elts = new APValue[N]; |
360 | 1.64k | ((Vec*)(char*)Data.buffer)->NumElts = N; |
361 | 11.2k | for (unsigned i = 0; i != N11.2k ; ++i9.56k ) |
362 | 9.56k | ((Vec*)(char*)Data.buffer)->Elts[i] = E[i]; |
363 | 1.64k | } |
364 | 44 | void setComplexInt(APSInt R, APSInt I) { |
365 | 44 | assert(R.getBitWidth() == I.getBitWidth() && |
366 | 44 | "Invalid complex int (type mismatch)."); |
367 | 44 | assert(isComplexInt() && "Invalid accessor"); |
368 | 44 | ((ComplexAPSInt *)(char *)Data.buffer)->Real = std::move(R); |
369 | 44 | ((ComplexAPSInt *)(char *)Data.buffer)->Imag = std::move(I); |
370 | 44 | } |
371 | 135 | void setComplexFloat(APFloat R, APFloat I) { |
372 | 135 | assert(&R.getSemantics() == &I.getSemantics() && |
373 | 135 | "Invalid complex float (type mismatch)."); |
374 | 135 | assert(isComplexFloat() && "Invalid accessor"); |
375 | 135 | ((ComplexAPFloat *)(char *)Data.buffer)->Real = std::move(R); |
376 | 135 | ((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I); |
377 | 135 | } |
378 | | void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, |
379 | | unsigned CallIndex, bool IsNullPtr); |
380 | | void setLValue(LValueBase B, const CharUnits &O, |
381 | | ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd, |
382 | | unsigned CallIndex, bool IsNullPtr); |
383 | 721 | void setUnion(const FieldDecl *Field, const APValue &Value) { |
384 | 721 | assert(isUnion() && "Invalid accessor"); |
385 | 721 | ((UnionData*)(char*)Data.buffer)->Field = Field; |
386 | 721 | *((UnionData*)(char*)Data.buffer)->Value = Value; |
387 | 721 | } |
388 | | void setAddrLabelDiff(const AddrLabelExpr* LHSExpr, |
389 | 39 | const AddrLabelExpr* RHSExpr) { |
390 | 39 | ((AddrLabelDiffData*)(char*)Data.buffer)->LHSExpr = LHSExpr; |
391 | 39 | ((AddrLabelDiffData*)(char*)Data.buffer)->RHSExpr = RHSExpr; |
392 | 39 | } |
393 | | |
394 | | /// Assign by swapping from a copy of the RHS. |
395 | 16.3M | APValue &operator=(APValue RHS) { |
396 | 16.3M | swap(RHS); |
397 | 16.3M | return *this; |
398 | 16.3M | } |
399 | | |
400 | | private: |
401 | | void DestroyDataAndMakeUninit(); |
402 | 45.9M | void MakeUninit() { |
403 | 45.9M | if (Kind != Uninitialized) |
404 | 14.1M | DestroyDataAndMakeUninit(); |
405 | 45.9M | } |
406 | 13.0M | void MakeInt() { |
407 | 13.0M | assert(isUninit() && "Bad state change"); |
408 | 13.0M | new ((void*)Data.buffer) APSInt(1); |
409 | 13.0M | Kind = Int; |
410 | 13.0M | } |
411 | 158k | void MakeFloat() { |
412 | 158k | assert(isUninit() && "Bad state change"); |
413 | 158k | new ((void*)(char*)Data.buffer) APFloat(0.0); |
414 | 158k | Kind = Float; |
415 | 158k | } |
416 | 1.64k | void MakeVector() { |
417 | 1.64k | assert(isUninit() && "Bad state change"); |
418 | 1.64k | new ((void*)(char*)Data.buffer) Vec(); |
419 | 1.64k | Kind = Vector; |
420 | 1.64k | } |
421 | 44 | void MakeComplexInt() { |
422 | 44 | assert(isUninit() && "Bad state change"); |
423 | 44 | new ((void*)(char*)Data.buffer) ComplexAPSInt(); |
424 | 44 | Kind = ComplexInt; |
425 | 44 | } |
426 | 135 | void MakeComplexFloat() { |
427 | 135 | assert(isUninit() && "Bad state change"); |
428 | 135 | new ((void*)(char*)Data.buffer) ComplexAPFloat(); |
429 | 135 | Kind = ComplexFloat; |
430 | 135 | } |
431 | | void MakeLValue(); |
432 | | void MakeArray(unsigned InitElts, unsigned Size); |
433 | 8.90k | void MakeStruct(unsigned B, unsigned M) { |
434 | 8.90k | assert(isUninit() && "Bad state change"); |
435 | 8.90k | new ((void*)(char*)Data.buffer) StructData(B, M); |
436 | 8.90k | Kind = Struct; |
437 | 8.90k | } |
438 | 721 | void MakeUnion() { |
439 | 721 | assert(isUninit() && "Bad state change"); |
440 | 721 | new ((void*)(char*)Data.buffer) UnionData(); |
441 | 721 | Kind = Union; |
442 | 721 | } |
443 | | void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember, |
444 | | ArrayRef<const CXXRecordDecl*> Path); |
445 | 39 | void MakeAddrLabelDiff() { |
446 | 39 | assert(isUninit() && "Bad state change"); |
447 | 39 | new ((void*)(char*)Data.buffer) AddrLabelDiffData(); |
448 | 39 | Kind = AddrLabelDiff; |
449 | 39 | } |
450 | | }; |
451 | | |
452 | | } // end namespace clang. |
453 | | |
454 | | #endif |