Coverage Report

Created: 2019-02-21 13:17

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/include/clang/AST/APValue.h
Line
Count
Source (jump to first uncovered line)
1
//===--- APValue.h - Union class for APFloat/APSInt/Complex -----*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
//  This file defines the APValue class.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#ifndef LLVM_CLANG_AST_APVALUE_H
14
#define LLVM_CLANG_AST_APVALUE_H
15
16
#include "clang/Basic/FixedPoint.h"
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
    FixedPoint,
47
    ComplexInt,
48
    ComplexFloat,
49
    LValue,
50
    Vector,
51
    Array,
52
    Struct,
53
    Union,
54
    MemberPointer,
55
    AddrLabelDiff
56
  };
57
58
  class LValueBase {
59
  public:
60
    typedef llvm::PointerUnion<const ValueDecl *, const Expr *> PtrTy;
61
62
13.5M
    LValueBase() : CallIndex(0), Version(0) {}
63
64
    template <class T>
65
    LValueBase(T P, unsigned I = 0, unsigned V = 0)
66
28.9M
        : Ptr(P), CallIndex(I), Version(V) {}
clang::APValue::LValueBase::LValueBase<llvm::PointerUnion<clang::ValueDecl const*, clang::Expr const*> >(llvm::PointerUnion<clang::ValueDecl const*, clang::Expr const*>, unsigned int, unsigned int)
Line
Count
Source
66
3.07M
        : Ptr(P), CallIndex(I), Version(V) {}
clang::APValue::LValueBase::LValueBase<clang::ValueDecl const*>(clang::ValueDecl const*, unsigned int, unsigned int)
Line
Count
Source
66
16.4M
        : Ptr(P), CallIndex(I), Version(V) {}
clang::APValue::LValueBase::LValueBase<clang::Expr const*>(clang::Expr const*, unsigned int, unsigned int)
Line
Count
Source
66
6.44k
        : Ptr(P), CallIndex(I), Version(V) {}
clang::APValue::LValueBase::LValueBase<clang::Expr*>(clang::Expr*, unsigned int, unsigned int)
Line
Count
Source
66
97.0k
        : Ptr(P), CallIndex(I), Version(V) {}
clang::APValue::LValueBase::LValueBase<clang::CallExpr const*>(clang::CallExpr const*, unsigned int, unsigned int)
Line
Count
Source
66
135
        : Ptr(P), CallIndex(I), Version(V) {}
clang::APValue::LValueBase::LValueBase<clang::CXXTypeidExpr const*>(clang::CXXTypeidExpr const*, unsigned int, unsigned int)
Line
Count
Source
66
406
        : Ptr(P), CallIndex(I), Version(V) {}
clang::APValue::LValueBase::LValueBase<clang::CXXUuidofExpr const*>(clang::CXXUuidofExpr const*, unsigned int, unsigned int)
Line
Count
Source
66
85
        : Ptr(P), CallIndex(I), Version(V) {}
clang::APValue::LValueBase::LValueBase<clang::CompoundLiteralExpr const*>(clang::CompoundLiteralExpr const*, unsigned int, unsigned int)
Line
Count
Source
66
632
        : Ptr(P), CallIndex(I), Version(V) {}
clang::APValue::LValueBase::LValueBase<clang::FunctionDecl const*>(clang::FunctionDecl const*, unsigned int, unsigned int)
Line
Count
Source
66
580k
        : Ptr(P), CallIndex(I), Version(V) {}
clang::APValue::LValueBase::LValueBase<clang::MaterializeTemporaryExpr const*>(clang::MaterializeTemporaryExpr const*, unsigned int, unsigned int)
Line
Count
Source
66
9.00k
        : Ptr(P), CallIndex(I), Version(V) {}
clang::APValue::LValueBase::LValueBase<clang::CXXMethodDecl const*>(clang::CXXMethodDecl const*, unsigned int, unsigned int)
Line
Count
Source
66
141
        : Ptr(P), CallIndex(I), Version(V) {}
clang::APValue::LValueBase::LValueBase<clang::MemberExpr const*>(clang::MemberExpr const*, unsigned int, unsigned int)
Line
Count
Source
66
1.81k
        : Ptr(P), CallIndex(I), Version(V) {}
clang::APValue::LValueBase::LValueBase<clang::ObjCEncodeExpr const*>(clang::ObjCEncodeExpr const*, unsigned int, unsigned int)
Line
Count
Source
66
64
        : Ptr(P), CallIndex(I), Version(V) {}
clang::APValue::LValueBase::LValueBase<clang::PredefinedExpr const*>(clang::PredefinedExpr const*, unsigned int, unsigned int)
Line
Count
Source
66
34
        : Ptr(P), CallIndex(I), Version(V) {}
clang::APValue::LValueBase::LValueBase<clang::StringLiteral const*>(clang::StringLiteral const*, unsigned int, unsigned int)
Line
Count
Source
66
38.3k
        : Ptr(P), CallIndex(I), Version(V) {}
clang::APValue::LValueBase::LValueBase<clang::VarDecl const*>(clang::VarDecl const*, unsigned int, unsigned int)
Line
Count
Source
66
8.62M
        : Ptr(P), CallIndex(I), Version(V) {}
clang::APValue::LValueBase::LValueBase<clang::ImplicitValueInitExpr*>(clang::ImplicitValueInitExpr*, unsigned int, unsigned int)
Line
Count
Source
66
39.7k
        : Ptr(P), CallIndex(I), Version(V) {}
67
68
    template <class T>
69
5
    bool is() const { return Ptr.is<T>(); }
70
71
    template <class T>
72
192k
    T get() const { return Ptr.get<T>(); }
73
74
    template <class T>
75
34.2M
    T dyn_cast() const { return Ptr.dyn_cast<T>(); }
clang::ValueDecl const* clang::APValue::LValueBase::dyn_cast<clang::ValueDecl const*>() const
Line
Count
Source
75
27.4M
    T dyn_cast() const { return Ptr.dyn_cast<T>(); }
clang::Expr const* clang::APValue::LValueBase::dyn_cast<clang::Expr const*>() const
Line
Count
Source
75
6.83M
    T dyn_cast() const { return Ptr.dyn_cast<T>(); }
76
77
    void *getOpaqueValue() const;
78
79
    bool isNull() const;
80
81
    explicit operator bool () const;
82
83
0
    PtrTy getPointer() const {
84
0
      return Ptr;
85
0
    }
86
87
9.58M
    unsigned getCallIndex() const {
88
9.58M
      return CallIndex;
89
9.58M
    }
90
91
0
    void setCallIndex(unsigned Index) {
92
0
      CallIndex = Index;
93
0
    }
94
95
2.51M
    unsigned getVersion() const {
96
2.51M
      return Version;
97
2.51M
    }
98
99
30.3M
    bool operator==(const LValueBase &Other) const {
100
30.3M
      return Ptr == Other.Ptr && 
CallIndex == Other.CallIndex28.5M
&&
101
30.3M
             
Version == Other.Version28.5M
;
102
30.3M
    }
103
104
  private:
105
    PtrTy Ptr;
106
    unsigned CallIndex, Version;
107
  };
108
109
  typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
110
  union LValuePathEntry {
111
    /// BaseOrMember - The FieldDecl or CXXRecordDecl indicating the next item
112
    /// in the path. An opaque value of type BaseOrMemberType.
113
    void *BaseOrMember;
114
    /// ArrayIndex - The array index of the next item in the path.
115
    uint64_t ArrayIndex;
116
  };
117
  struct NoLValuePath {};
118
  struct UninitArray {};
119
  struct UninitStruct {};
120
private:
121
  ValueKind Kind;
122
123
  struct ComplexAPSInt {
124
    APSInt Real, Imag;
125
72
    ComplexAPSInt() : Real(1), Imag(1) {}
126
  };
127
  struct ComplexAPFloat {
128
    APFloat Real, Imag;
129
172
    ComplexAPFloat() : Real(0.0), Imag(0.0) {}
130
  };
131
  struct LV;
132
  struct Vec {
133
    APValue *Elts;
134
    unsigned NumElts;
135
1.85k
    Vec() : Elts(nullptr), NumElts(0) {}
136
1.85k
    ~Vec() { delete[] Elts; }
137
  };
138
  struct Arr {
139
    APValue *Elts;
140
    unsigned NumElts, ArrSize;
141
    Arr(unsigned NumElts, unsigned ArrSize);
142
    ~Arr();
143
  };
144
  struct StructData {
145
    APValue *Elts;
146
    unsigned NumBases;
147
    unsigned NumFields;
148
    StructData(unsigned NumBases, unsigned NumFields);
149
    ~StructData();
150
  };
151
  struct UnionData {
152
    const FieldDecl *Field;
153
    APValue *Value;
154
    UnionData();
155
    ~UnionData();
156
  };
157
  struct AddrLabelDiffData {
158
    const AddrLabelExpr* LHSExpr;
159
    const AddrLabelExpr* RHSExpr;
160
  };
161
  struct MemberPointerData;
162
163
  // We ensure elsewhere that Data is big enough for LV and MemberPointerData.
164
  typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt,
165
                                      ComplexAPFloat, Vec, Arr, StructData,
166
                                      UnionData, AddrLabelDiffData> DataType;
167
  static const size_t DataSize = sizeof(DataType);
168
169
  DataType Data;
170
171
public:
172
58.1M
  APValue() : Kind(Uninitialized) {}
173
20.5M
  explicit APValue(APSInt I) : Kind(Uninitialized) {
174
20.5M
    MakeInt(); setInt(std::move(I));
175
20.5M
  }
176
237k
  explicit APValue(APFloat F) : Kind(Uninitialized) {
177
237k
    MakeFloat(); setFloat(std::move(F));
178
237k
  }
179
732
  explicit APValue(APFixedPoint FX) : Kind(Uninitialized) {
180
732
    MakeFixedPoint(std::move(FX));
181
732
  }
182
1.37k
  explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) {
183
1.37k
    MakeVector(); setVector(E, N);
184
1.37k
  }
185
63
  APValue(APSInt R, APSInt I) : Kind(Uninitialized) {
186
63
    MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
187
63
  }
188
150
  APValue(APFloat R, APFloat I) : Kind(Uninitialized) {
189
150
    MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
190
150
  }
191
  APValue(const APValue &RHS);
192
41.6k
  APValue(APValue &&RHS) : Kind(Uninitialized) { swap(RHS); }
193
  APValue(LValueBase B, const CharUnits &O, NoLValuePath N,
194
          bool IsNullPtr = false)
195
23.1k
      : Kind(Uninitialized) {
196
23.1k
    MakeLValue(); setLValue(B, O, N, IsNullPtr);
197
23.1k
  }
198
  APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
199
          bool OnePastTheEnd, bool IsNullPtr = false)
200
846k
      : Kind(Uninitialized) {
201
846k
    MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr);
202
846k
  }
203
28.3k
  APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) {
204
28.3k
    MakeArray(InitElts, Size);
205
28.3k
  }
206
31.9k
  APValue(UninitStruct, unsigned B, unsigned M) : Kind(Uninitialized) {
207
31.9k
    MakeStruct(B, M);
208
31.9k
  }
209
  explicit APValue(const FieldDecl *D, const APValue &V = APValue())
210
892
      : Kind(Uninitialized) {
211
892
    MakeUnion(); setUnion(D, V);
212
892
  }
213
  APValue(const ValueDecl *Member, bool IsDerivedMember,
214
1.47k
          ArrayRef<const CXXRecordDecl*> Path) : Kind(Uninitialized) {
215
1.47k
    MakeMemberPointer(Member, IsDerivedMember, Path);
216
1.47k
  }
217
  APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr)
218
27
      : Kind(Uninitialized) {
219
27
    MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
220
27
  }
221
222
82.9M
  ~APValue() {
223
82.9M
    MakeUninit();
224
82.9M
  }
225
226
  /// Returns whether the object performed allocations.
227
  ///
228
  /// If APValues are constructed via placement new, \c needsCleanup()
229
  /// indicates whether the destructor must be called in order to correctly
230
  /// free all allocated memory.
231
  bool needsCleanup() const;
232
233
  /// Swaps the contents of this and the given APValue.
234
  void swap(APValue &RHS);
235
236
6.63M
  ValueKind getKind() const { return Kind; }
237
10.0M
  bool isUninit() const { return Kind == Uninitialized; }
238
14.9M
  bool isInt() const { return Kind == Int; }
239
16.7k
  bool isFloat() const { return Kind == Float; }
240
323
  bool isFixedPoint() const { return Kind == FixedPoint; }
241
27
  bool isComplexInt() const { return Kind == ComplexInt; }
242
33
  bool isComplexFloat() const { return Kind == ComplexFloat; }
243
11.4M
  bool isLValue() const { return Kind == LValue; }
244
107
  bool isVector() const { return Kind == Vector; }
245
6.55M
  bool isArray() const { return Kind == Array; }
246
6.53M
  bool isStruct() const { return Kind == Struct; }
247
6.53M
  bool isUnion() const { return Kind == Union; }
248
6.40M
  bool isMemberPointer() const { return Kind == MemberPointer; }
249
1.69M
  bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
250
251
  void dump() const;
252
  void dump(raw_ostream &OS) const;
253
254
  void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const;
255
  std::string getAsString(ASTContext &Ctx, QualType Ty) const;
256
257
29.5M
  APSInt &getInt() {
258
29.5M
    assert(isInt() && "Invalid accessor");
259
29.5M
    return *(APSInt*)(char*)Data.buffer;
260
29.5M
  }
261
12.2M
  const APSInt &getInt() const {
262
12.2M
    return const_cast<APValue*>(this)->getInt();
263
12.2M
  }
264
265
207k
  APFloat &getFloat() {
266
207k
    assert(isFloat() && "Invalid accessor");
267
207k
    return *(APFloat*)(char*)Data.buffer;
268
207k
  }
269
205k
  const APFloat &getFloat() const {
270
205k
    return const_cast<APValue*>(this)->getFloat();
271
205k
  }
272
273
607
  APFixedPoint &getFixedPoint() {
274
607
    assert(isFixedPoint() && "Invalid accessor");
275
607
    return *(APFixedPoint *)(char *)Data.buffer;
276
607
  }
277
260
  const APFixedPoint &getFixedPoint() const {
278
260
    return const_cast<APValue *>(this)->getFixedPoint();
279
260
  }
280
281
52
  APSInt &getComplexIntReal() {
282
52
    assert(isComplexInt() && "Invalid accessor");
283
52
    return ((ComplexAPSInt*)(char*)Data.buffer)->Real;
284
52
  }
285
40
  const APSInt &getComplexIntReal() const {
286
40
    return const_cast<APValue*>(this)->getComplexIntReal();
287
40
  }
288
289
43
  APSInt &getComplexIntImag() {
290
43
    assert(isComplexInt() && "Invalid accessor");
291
43
    return ((ComplexAPSInt*)(char*)Data.buffer)->Imag;
292
43
  }
293
31
  const APSInt &getComplexIntImag() const {
294
31
    return const_cast<APValue*>(this)->getComplexIntImag();
295
31
  }
296
297
112
  APFloat &getComplexFloatReal() {
298
112
    assert(isComplexFloat() && "Invalid accessor");
299
112
    return ((ComplexAPFloat*)(char*)Data.buffer)->Real;
300
112
  }
301
110
  const APFloat &getComplexFloatReal() const {
302
110
    return const_cast<APValue*>(this)->getComplexFloatReal();
303
110
  }
304
305
87
  APFloat &getComplexFloatImag() {
306
87
    assert(isComplexFloat() && "Invalid accessor");
307
87
    return ((ComplexAPFloat*)(char*)Data.buffer)->Imag;
308
87
  }
309
85
  const APFloat &getComplexFloatImag() const {
310
85
    return const_cast<APValue*>(this)->getComplexFloatImag();
311
85
  }
312
313
  const LValueBase getLValueBase() const;
314
  CharUnits &getLValueOffset();
315
749k
  const CharUnits &getLValueOffset() const {
316
749k
    return const_cast<APValue*>(this)->getLValueOffset();
317
749k
  }
318
  bool isLValueOnePastTheEnd() const;
319
  bool hasLValuePath() const;
320
  ArrayRef<LValuePathEntry> getLValuePath() const;
321
  unsigned getLValueCallIndex() const;
322
  unsigned getLValueVersion() const;
323
  bool isNullPointer() const;
324
325
5.66k
  APValue &getVectorElt(unsigned I) {
326
5.66k
    assert(isVector() && "Invalid accessor");
327
5.66k
    assert(I < getVectorLength() && "Index out of range");
328
5.66k
    return ((Vec*)(char*)Data.buffer)->Elts[I];
329
5.66k
  }
330
5.20k
  const APValue &getVectorElt(unsigned I) const {
331
5.20k
    return const_cast<APValue*>(this)->getVectorElt(I);
332
5.20k
  }
333
1.81k
  unsigned getVectorLength() const {
334
1.81k
    assert(isVector() && "Invalid accessor");
335
1.81k
    return ((const Vec*)(const void *)Data.buffer)->NumElts;
336
1.81k
  }
337
338
254k
  APValue &getArrayInitializedElt(unsigned I) {
339
254k
    assert(isArray() && "Invalid accessor");
340
254k
    assert(I < getArrayInitializedElts() && "Index out of range");
341
254k
    return ((Arr*)(char*)Data.buffer)->Elts[I];
342
254k
  }
343
120k
  const APValue &getArrayInitializedElt(unsigned I) const {
344
120k
    return const_cast<APValue*>(this)->getArrayInitializedElt(I);
345
120k
  }
346
75.1k
  bool hasArrayFiller() const {
347
75.1k
    return getArrayInitializedElts() != getArraySize();
348
75.1k
  }
349
45.8k
  APValue &getArrayFiller() {
350
45.8k
    assert(isArray() && "Invalid accessor");
351
45.8k
    assert(hasArrayFiller() && "No array filler");
352
45.8k
    return ((Arr*)(char*)Data.buffer)->Elts[getArrayInitializedElts()];
353
45.8k
  }
354
7.67k
  const APValue &getArrayFiller() const {
355
7.67k
    return const_cast<APValue*>(this)->getArrayFiller();
356
7.67k
  }
357
171k
  unsigned getArrayInitializedElts() const {
358
171k
    assert(isArray() && "Invalid accessor");
359
171k
    return ((const Arr*)(const void *)Data.buffer)->NumElts;
360
171k
  }
361
88.7k
  unsigned getArraySize() const {
362
88.7k
    assert(isArray() && "Invalid accessor");
363
88.7k
    return ((const Arr*)(const void *)Data.buffer)->ArrSize;
364
88.7k
  }
365
366
447k
  unsigned getStructNumBases() const {
367
447k
    assert(isStruct() && "Invalid accessor");
368
447k
    return ((const StructData*)(const char*)Data.buffer)->NumBases;
369
447k
  }
370
141k
  unsigned getStructNumFields() const {
371
141k
    assert(isStruct() && "Invalid accessor");
372
141k
    return ((const StructData*)(const char*)Data.buffer)->NumFields;
373
141k
  }
374
3.48k
  APValue &getStructBase(unsigned i) {
375
3.48k
    assert(isStruct() && "Invalid accessor");
376
3.48k
    return ((StructData*)(char*)Data.buffer)->Elts[i];
377
3.48k
  }
378
306k
  APValue &getStructField(unsigned i) {
379
306k
    assert(isStruct() && "Invalid accessor");
380
306k
    return ((StructData*)(char*)Data.buffer)->Elts[getStructNumBases() + i];
381
306k
  }
382
647
  const APValue &getStructBase(unsigned i) const {
383
647
    return const_cast<APValue*>(this)->getStructBase(i);
384
647
  }
385
139k
  const APValue &getStructField(unsigned i) const {
386
139k
    return const_cast<APValue*>(this)->getStructField(i);
387
139k
  }
388
389
949
  const FieldDecl *getUnionField() const {
390
949
    assert(isUnion() && "Invalid accessor");
391
949
    return ((const UnionData*)(const char*)Data.buffer)->Field;
392
949
  }
393
1.33k
  APValue &getUnionValue() {
394
1.33k
    assert(isUnion() && "Invalid accessor");
395
1.33k
    return *((UnionData*)(char*)Data.buffer)->Value;
396
1.33k
  }
397
305
  const APValue &getUnionValue() const {
398
305
    return const_cast<APValue*>(this)->getUnionValue();
399
305
  }
400
401
  const ValueDecl *getMemberPointerDecl() const;
402
  bool isMemberPointerToDerivedMember() const;
403
  ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const;
404
405
14
  const AddrLabelExpr* getAddrLabelDiffLHS() const {
406
14
    assert(isAddrLabelDiff() && "Invalid accessor");
407
14
    return ((const AddrLabelDiffData*)(const char*)Data.buffer)->LHSExpr;
408
14
  }
409
14
  const AddrLabelExpr* getAddrLabelDiffRHS() const {
410
14
    assert(isAddrLabelDiff() && "Invalid accessor");
411
14
    return ((const AddrLabelDiffData*)(const char*)Data.buffer)->RHSExpr;
412
14
  }
413
414
23.9M
  void setInt(APSInt I) {
415
23.9M
    assert(isInt() && "Invalid accessor");
416
23.9M
    *(APSInt *)(char *)Data.buffer = std::move(I);
417
23.9M
  }
418
257k
  void setFloat(APFloat F) {
419
257k
    assert(isFloat() && "Invalid accessor");
420
257k
    *(APFloat *)(char *)Data.buffer = std::move(F);
421
257k
  }
422
0
  void setFixedPoint(APFixedPoint FX) {
423
0
    assert(isFixedPoint() && "Invalid accessor");
424
0
    *(APFixedPoint *)(char *)Data.buffer = std::move(FX);
425
0
  }
426
1.85k
  void setVector(const APValue *E, unsigned N) {
427
1.85k
    assert(isVector() && "Invalid accessor");
428
1.85k
    ((Vec*)(char*)Data.buffer)->Elts = new APValue[N];
429
1.85k
    ((Vec*)(char*)Data.buffer)->NumElts = N;
430
12.0k
    for (unsigned i = 0; i != N; 
++i10.1k
)
431
10.1k
      ((Vec*)(char*)Data.buffer)->Elts[i] = E[i];
432
1.85k
  }
433
72
  void setComplexInt(APSInt R, APSInt I) {
434
72
    assert(R.getBitWidth() == I.getBitWidth() &&
435
72
           "Invalid complex int (type mismatch).");
436
72
    assert(isComplexInt() && "Invalid accessor");
437
72
    ((ComplexAPSInt *)(char *)Data.buffer)->Real = std::move(R);
438
72
    ((ComplexAPSInt *)(char *)Data.buffer)->Imag = std::move(I);
439
72
  }
440
172
  void setComplexFloat(APFloat R, APFloat I) {
441
172
    assert(&R.getSemantics() == &I.getSemantics() &&
442
172
           "Invalid complex float (type mismatch).");
443
172
    assert(isComplexFloat() && "Invalid accessor");
444
172
    ((ComplexAPFloat *)(char *)Data.buffer)->Real = std::move(R);
445
172
    ((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I);
446
172
  }
447
  void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
448
                 bool IsNullPtr);
449
  void setLValue(LValueBase B, const CharUnits &O,
450
                 ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
451
                 bool IsNullPtr);
452
935
  void setUnion(const FieldDecl *Field, const APValue &Value) {
453
935
    assert(isUnion() && "Invalid accessor");
454
935
    ((UnionData*)(char*)Data.buffer)->Field = Field;
455
935
    *((UnionData*)(char*)Data.buffer)->Value = Value;
456
935
  }
457
  void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
458
36
                        const AddrLabelExpr* RHSExpr) {
459
36
    ((AddrLabelDiffData*)(char*)Data.buffer)->LHSExpr = LHSExpr;
460
36
    ((AddrLabelDiffData*)(char*)Data.buffer)->RHSExpr = RHSExpr;
461
36
  }
462
463
  /// Assign by swapping from a copy of the RHS.
464
28.5M
  APValue &operator=(APValue RHS) {
465
28.5M
    swap(RHS);
466
28.5M
    return *this;
467
28.5M
  }
468
469
private:
470
  void DestroyDataAndMakeUninit();
471
82.9M
  void MakeUninit() {
472
82.9M
    if (Kind != Uninitialized)
473
24.7M
      DestroyDataAndMakeUninit();
474
82.9M
  }
475
23.9M
  void MakeInt() {
476
23.9M
    assert(isUninit() && "Bad state change");
477
23.9M
    new ((void*)Data.buffer) APSInt(1);
478
23.9M
    Kind = Int;
479
23.9M
  }
480
257k
  void MakeFloat() {
481
257k
    assert(isUninit() && "Bad state change");
482
257k
    new ((void*)(char*)Data.buffer) APFloat(0.0);
483
257k
    Kind = Float;
484
257k
  }
485
732
  void MakeFixedPoint(APFixedPoint &&FX) {
486
732
    assert(isUninit() && "Bad state change");
487
732
    new ((void *)(char *)Data.buffer) APFixedPoint(std::move(FX));
488
732
    Kind = FixedPoint;
489
732
  }
490
1.85k
  void MakeVector() {
491
1.85k
    assert(isUninit() && "Bad state change");
492
1.85k
    new ((void*)(char*)Data.buffer) Vec();
493
1.85k
    Kind = Vector;
494
1.85k
  }
495
72
  void MakeComplexInt() {
496
72
    assert(isUninit() && "Bad state change");
497
72
    new ((void*)(char*)Data.buffer) ComplexAPSInt();
498
72
    Kind = ComplexInt;
499
72
  }
500
172
  void MakeComplexFloat() {
501
172
    assert(isUninit() && "Bad state change");
502
172
    new ((void*)(char*)Data.buffer) ComplexAPFloat();
503
172
    Kind = ComplexFloat;
504
172
  }
505
  void MakeLValue();
506
  void MakeArray(unsigned InitElts, unsigned Size);
507
102k
  void MakeStruct(unsigned B, unsigned M) {
508
102k
    assert(isUninit() && "Bad state change");
509
102k
    new ((void*)(char*)Data.buffer) StructData(B, M);
510
102k
    Kind = Struct;
511
102k
  }
512
935
  void MakeUnion() {
513
935
    assert(isUninit() && "Bad state change");
514
935
    new ((void*)(char*)Data.buffer) UnionData();
515
935
    Kind = Union;
516
935
  }
517
  void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
518
                         ArrayRef<const CXXRecordDecl*> Path);
519
36
  void MakeAddrLabelDiff() {
520
36
    assert(isUninit() && "Bad state change");
521
36
    new ((void*)(char*)Data.buffer) AddrLabelDiffData();
522
36
    Kind = AddrLabelDiff;
523
36
  }
524
};
525
526
} // end namespace clang.
527
528
namespace llvm {
529
template<> struct DenseMapInfo<clang::APValue::LValueBase> {
530
  static clang::APValue::LValueBase getEmptyKey();
531
  static clang::APValue::LValueBase getTombstoneKey();
532
  static unsigned getHashValue(const clang::APValue::LValueBase &Base);
533
  static bool isEqual(const clang::APValue::LValueBase &LHS,
534
                      const clang::APValue::LValueBase &RHS);
535
};
536
}
537
538
#endif