Coverage Report

Created: 2019-07-24 05:18

/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 CXXRecordDecl;
28
  class Decl;
29
  class DiagnosticBuilder;
30
  class Expr;
31
  class FieldDecl;
32
  struct PrintingPolicy;
33
  class Type;
34
  class ValueDecl;
35
36
/// Symbolic representation of typeid(T) for some type T.
37
class TypeInfoLValue {
38
  const Type *T;
39
40
public:
41
15.2k
  TypeInfoLValue() : T() {}
42
  explicit TypeInfoLValue(const Type *T);
43
44
56
  const Type *getType() const { return T; }
45
14.7k
  explicit operator bool() const { return T; }
46
47
445
  void *getOpaqueValue() { return const_cast<Type*>(T); }
48
56
  static TypeInfoLValue getFromOpaqueValue(void *Value) {
49
56
    TypeInfoLValue V;
50
56
    V.T = reinterpret_cast<const Type*>(Value);
51
56
    return V;
52
56
  }
53
54
  void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const;
55
};
56
}
57
58
namespace llvm {
59
template<> struct PointerLikeTypeTraits<clang::TypeInfoLValue> {
60
445
  static void *getAsVoidPointer(clang::TypeInfoLValue V) {
61
445
    return V.getOpaqueValue();
62
445
  }
63
56
  static clang::TypeInfoLValue getFromVoidPointer(void *P) {
64
56
    return clang::TypeInfoLValue::getFromOpaqueValue(P);
65
56
  }
66
  // Validated by static_assert in APValue.cpp; hardcoded to avoid needing
67
  // to include Type.h.
68
  static constexpr int NumLowBitsAvailable = 3;
69
};
70
}
71
72
namespace clang {
73
/// APValue - This class implements a discriminated union of [uninitialized]
74
/// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset],
75
/// [Vector: N * APValue], [Array: N * APValue]
76
class APValue {
77
  typedef llvm::APSInt APSInt;
78
  typedef llvm::APFloat APFloat;
79
public:
80
  enum ValueKind {
81
    /// There is no such object (it's outside its lifetime).
82
    None,
83
    /// This object has an indeterminate value (C++ [basic.indet]).
84
    Indeterminate,
85
    Int,
86
    Float,
87
    FixedPoint,
88
    ComplexInt,
89
    ComplexFloat,
90
    LValue,
91
    Vector,
92
    Array,
93
    Struct,
94
    Union,
95
    MemberPointer,
96
    AddrLabelDiff
97
  };
98
99
  class LValueBase {
100
    typedef llvm::PointerUnion<const ValueDecl *, const Expr *, TypeInfoLValue>
101
        PtrTy;
102
103
  public:
104
19.3M
    LValueBase() : Local{} {}
105
    LValueBase(const ValueDecl *P, unsigned I = 0, unsigned V = 0);
106
    LValueBase(const Expr *P, unsigned I = 0, unsigned V = 0);
107
    static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo);
108
109
    template <class T>
110
9.47M
    bool is() const { return Ptr.is<T>(); }
bool clang::APValue::LValueBase::is<clang::TypeInfoLValue>() const
Line
Count
Source
110
9.47M
    bool is() const { return Ptr.is<T>(); }
bool clang::APValue::LValueBase::is<clang::ValueDecl const*>() const
Line
Count
Source
110
10
    bool is() const { return Ptr.is<T>(); }
111
112
    template <class T>
113
226k
    T get() const { return Ptr.get<T>(); }
114
115
    template <class T>
116
35.7M
    T dyn_cast() const { return Ptr.dyn_cast<T>(); }
clang::ValueDecl const* clang::APValue::LValueBase::dyn_cast<clang::ValueDecl const*>() const
Line
Count
Source
116
28.5M
    T dyn_cast() const { return Ptr.dyn_cast<T>(); }
clang::TypeInfoLValue clang::APValue::LValueBase::dyn_cast<clang::TypeInfoLValue>() const
Line
Count
Source
116
14.7k
    T dyn_cast() const { return Ptr.dyn_cast<T>(); }
clang::Expr const* clang::APValue::LValueBase::dyn_cast<clang::Expr const*>() const
Line
Count
Source
116
7.10M
    T dyn_cast() const { return Ptr.dyn_cast<T>(); }
117
118
    void *getOpaqueValue() const;
119
120
    bool isNull() const;
121
122
    explicit operator bool() const;
123
124
    unsigned getCallIndex() const;
125
    unsigned getVersion() const;
126
    QualType getTypeInfoType() const;
127
128
    friend bool operator==(const LValueBase &LHS, const LValueBase &RHS);
129
0
    friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS) {
130
0
      return !(LHS == RHS);
131
0
    }
132
    friend llvm::hash_code hash_value(const LValueBase &Base);
133
134
  private:
135
    PtrTy Ptr;
136
    struct LocalState {
137
      unsigned CallIndex, Version;
138
    };
139
    union {
140
      LocalState Local;
141
      /// The type std::type_info, if this is a TypeInfoLValue.
142
      void *TypeInfoType;
143
    };
144
  };
145
146
  /// A FieldDecl or CXXRecordDecl, along with a flag indicating whether we
147
  /// mean a virtual or non-virtual base class subobject.
148
  typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
149
150
  /// A non-discriminated union of a base, field, or array index.
151
  class LValuePathEntry {
152
    static_assert(sizeof(uintptr_t) <= sizeof(uint64_t),
153
                  "pointer doesn't fit in 64 bits?");
154
    uint64_t Value;
155
156
  public:
157
317k
    LValuePathEntry() : Value() {}
158
    LValuePathEntry(BaseOrMemberType BaseOrMember)
159
272k
        : Value{reinterpret_cast<uintptr_t>(BaseOrMember.getOpaqueValue())} {}
160
317k
    static LValuePathEntry ArrayIndex(uint64_t Index) {
161
317k
      LValuePathEntry Result;
162
317k
      Result.Value = Index;
163
317k
      return Result;
164
317k
    }
165
166
67.6k
    BaseOrMemberType getAsBaseOrMember() const {
167
67.6k
      return BaseOrMemberType::getFromOpaqueValue(
168
67.6k
          reinterpret_cast<void *>(Value));
169
67.6k
    }
170
208k
    uint64_t getAsArrayIndex() const { return Value; }
171
172
9.38k
    friend bool operator==(LValuePathEntry A, LValuePathEntry B) {
173
9.38k
      return A.Value == B.Value;
174
9.38k
    }
175
0
    friend bool operator!=(LValuePathEntry A, LValuePathEntry B) {
176
0
      return A.Value != B.Value;
177
0
    }
178
19.9k
    friend llvm::hash_code hash_value(LValuePathEntry A) {
179
19.9k
      return llvm::hash_value(A.Value);
180
19.9k
    }
181
  };
182
  struct NoLValuePath {};
183
  struct UninitArray {};
184
  struct UninitStruct {};
185
186
  friend class ASTReader;
187
  friend class ASTWriter;
188
189
private:
190
  ValueKind Kind;
191
192
  struct ComplexAPSInt {
193
    APSInt Real, Imag;
194
74
    ComplexAPSInt() : Real(1), Imag(1) {}
195
  };
196
  struct ComplexAPFloat {
197
    APFloat Real, Imag;
198
180
    ComplexAPFloat() : Real(0.0), Imag(0.0) {}
199
  };
200
  struct LV;
201
  struct Vec {
202
    APValue *Elts;
203
    unsigned NumElts;
204
2.50k
    Vec() : Elts(nullptr), NumElts(0) {}
205
2.39k
    ~Vec() { delete[] Elts; }
206
  };
207
  struct Arr {
208
    APValue *Elts;
209
    unsigned NumElts, ArrSize;
210
    Arr(unsigned NumElts, unsigned ArrSize);
211
    ~Arr();
212
  };
213
  struct StructData {
214
    APValue *Elts;
215
    unsigned NumBases;
216
    unsigned NumFields;
217
    StructData(unsigned NumBases, unsigned NumFields);
218
    ~StructData();
219
  };
220
  struct UnionData {
221
    const FieldDecl *Field;
222
    APValue *Value;
223
    UnionData();
224
    ~UnionData();
225
  };
226
  struct AddrLabelDiffData {
227
    const AddrLabelExpr* LHSExpr;
228
    const AddrLabelExpr* RHSExpr;
229
  };
230
  struct MemberPointerData;
231
232
  // We ensure elsewhere that Data is big enough for LV and MemberPointerData.
233
  typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt,
234
                                      ComplexAPFloat, Vec, Arr, StructData,
235
                                      UnionData, AddrLabelDiffData> DataType;
236
  static const size_t DataSize = sizeof(DataType);
237
238
  DataType Data;
239
240
public:
241
63.7M
  APValue() : Kind(None) {}
242
23.9M
  explicit APValue(APSInt I) : Kind(None) {
243
23.9M
    MakeInt(); setInt(std::move(I));
244
23.9M
  }
245
243k
  explicit APValue(APFloat F) : Kind(None) {
246
243k
    MakeFloat(); setFloat(std::move(F));
247
243k
  }
248
1.15k
  explicit APValue(APFixedPoint FX) : Kind(None) {
249
1.15k
    MakeFixedPoint(std::move(FX));
250
1.15k
  }
251
1.83k
  explicit APValue(const APValue *E, unsigned N) : Kind(None) {
252
1.83k
    MakeVector(); setVector(E, N);
253
1.83k
  }
254
65
  APValue(APSInt R, APSInt I) : Kind(None) {
255
65
    MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
256
65
  }
257
158
  APValue(APFloat R, APFloat I) : Kind(None) {
258
158
    MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
259
158
  }
260
  APValue(const APValue &RHS);
261
47.3k
  APValue(APValue &&RHS) : Kind(None) { swap(RHS); }
262
  APValue(LValueBase B, const CharUnits &O, NoLValuePath N,
263
          bool IsNullPtr = false)
264
23.8k
      : Kind(None) {
265
23.8k
    MakeLValue(); setLValue(B, O, N, IsNullPtr);
266
23.8k
  }
267
  APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
268
          bool OnePastTheEnd, bool IsNullPtr = false)
269
879k
      : Kind(None) {
270
879k
    MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr);
271
879k
  }
272
29.2k
  APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(None) {
273
29.2k
    MakeArray(InitElts, Size);
274
29.2k
  }
275
33.9k
  APValue(UninitStruct, unsigned B, unsigned M) : Kind(None) {
276
33.9k
    MakeStruct(B, M);
277
33.9k
  }
278
  explicit APValue(const FieldDecl *D, const APValue &V = APValue())
279
1.06k
      : Kind(None) {
280
1.06k
    MakeUnion(); setUnion(D, V);
281
1.06k
  }
282
  APValue(const ValueDecl *Member, bool IsDerivedMember,
283
1.51k
          ArrayRef<const CXXRecordDecl*> Path) : Kind(None) {
284
1.51k
    MakeMemberPointer(Member, IsDerivedMember, Path);
285
1.51k
  }
286
  APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr)
287
28
      : Kind(None) {
288
28
    MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
289
28
  }
290
300
  static APValue IndeterminateValue() {
291
300
    APValue Result;
292
300
    Result.Kind = Indeterminate;
293
300
    return Result;
294
300
  }
295
296
94.4M
  ~APValue() {
297
94.4M
    if (Kind != None && 
Kind != Indeterminate30.6M
)
298
30.6M
      DestroyDataAndMakeUninit();
299
94.4M
  }
300
301
  /// Returns whether the object performed allocations.
302
  ///
303
  /// If APValues are constructed via placement new, \c needsCleanup()
304
  /// indicates whether the destructor must be called in order to correctly
305
  /// free all allocated memory.
306
  bool needsCleanup() const;
307
308
  /// Swaps the contents of this and the given APValue.
309
  void swap(APValue &RHS);
310
311
15.7M
  ValueKind getKind() const { return Kind; }
312
313
3.60M
  bool isAbsent() const { return Kind == None; }
314
3.75M
  bool isIndeterminate() const { return Kind == Indeterminate; }
315
6.87M
  bool hasValue() const { return Kind != None && 
Kind != Indeterminate6.86M
; }
316
317
15.8M
  bool isInt() const { return Kind == Int; }
318
17.2k
  bool isFloat() const { return Kind == Float; }
319
694
  bool isFixedPoint() const { return Kind == FixedPoint; }
320
27
  bool isComplexInt() const { return Kind == ComplexInt; }
321
33
  bool isComplexFloat() const { return Kind == ComplexFloat; }
322
12.0M
  bool isLValue() const { return Kind == LValue; }
323
114
  bool isVector() const { return Kind == Vector; }
324
6.83M
  bool isArray() const { return Kind == Array; }
325
6.80M
  bool isStruct() const { return Kind == Struct; }
326
6.81M
  bool isUnion() const { return Kind == Union; }
327
6.68M
  bool isMemberPointer() const { return Kind == MemberPointer; }
328
1.90M
  bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
329
330
  void dump() const;
331
  void dump(raw_ostream &OS) const;
332
333
  void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const;
334
  std::string getAsString(const ASTContext &Ctx, QualType Ty) const;
335
336
44.9M
  APSInt &getInt() {
337
44.9M
    assert(isInt() && "Invalid accessor");
338
44.9M
    return *(APSInt*)(char*)Data.buffer;
339
44.9M
  }
340
19.4M
  const APSInt &getInt() const {
341
19.4M
    return const_cast<APValue*>(this)->getInt();
342
19.4M
  }
343
344
  /// Try to convert this value to an integral constant. This works if it's an
345
  /// integer, null pointer, or offset from a null pointer. Returns true on
346
  /// success.
347
  bool toIntegralConstant(APSInt &Result, QualType SrcTy,
348
                          const ASTContext &Ctx) const;
349
350
214k
  APFloat &getFloat() {
351
214k
    assert(isFloat() && "Invalid accessor");
352
214k
    return *(APFloat*)(char*)Data.buffer;
353
214k
  }
354
211k
  const APFloat &getFloat() const {
355
211k
    return const_cast<APValue*>(this)->getFloat();
356
211k
  }
357
358
1.02k
  APFixedPoint &getFixedPoint() {
359
1.02k
    assert(isFixedPoint() && "Invalid accessor");
360
1.02k
    return *(APFixedPoint *)(char *)Data.buffer;
361
1.02k
  }
362
304
  const APFixedPoint &getFixedPoint() const {
363
304
    return const_cast<APValue *>(this)->getFixedPoint();
364
304
  }
365
366
52
  APSInt &getComplexIntReal() {
367
52
    assert(isComplexInt() && "Invalid accessor");
368
52
    return ((ComplexAPSInt*)(char*)Data.buffer)->Real;
369
52
  }
370
40
  const APSInt &getComplexIntReal() const {
371
40
    return const_cast<APValue*>(this)->getComplexIntReal();
372
40
  }
373
374
43
  APSInt &getComplexIntImag() {
375
43
    assert(isComplexInt() && "Invalid accessor");
376
43
    return ((ComplexAPSInt*)(char*)Data.buffer)->Imag;
377
43
  }
378
31
  const APSInt &getComplexIntImag() const {
379
31
    return const_cast<APValue*>(this)->getComplexIntImag();
380
31
  }
381
382
112
  APFloat &getComplexFloatReal() {
383
112
    assert(isComplexFloat() && "Invalid accessor");
384
112
    return ((ComplexAPFloat*)(char*)Data.buffer)->Real;
385
112
  }
386
110
  const APFloat &getComplexFloatReal() const {
387
110
    return const_cast<APValue*>(this)->getComplexFloatReal();
388
110
  }
389
390
87
  APFloat &getComplexFloatImag() {
391
87
    assert(isComplexFloat() && "Invalid accessor");
392
87
    return ((ComplexAPFloat*)(char*)Data.buffer)->Imag;
393
87
  }
394
85
  const APFloat &getComplexFloatImag() const {
395
85
    return const_cast<APValue*>(this)->getComplexFloatImag();
396
85
  }
397
398
  const LValueBase getLValueBase() const;
399
  CharUnits &getLValueOffset();
400
777k
  const CharUnits &getLValueOffset() const {
401
777k
    return const_cast<APValue*>(this)->getLValueOffset();
402
777k
  }
403
  bool isLValueOnePastTheEnd() const;
404
  bool hasLValuePath() const;
405
  ArrayRef<LValuePathEntry> getLValuePath() const;
406
  unsigned getLValueCallIndex() const;
407
  unsigned getLValueVersion() const;
408
  bool isNullPointer() const;
409
410
6.84k
  APValue &getVectorElt(unsigned I) {
411
6.84k
    assert(isVector() && "Invalid accessor");
412
6.84k
    assert(I < getVectorLength() && "Index out of range");
413
6.84k
    return ((Vec*)(char*)Data.buffer)->Elts[I];
414
6.84k
  }
415
6.34k
  const APValue &getVectorElt(unsigned I) const {
416
6.34k
    return const_cast<APValue*>(this)->getVectorElt(I);
417
6.34k
  }
418
2.23k
  unsigned getVectorLength() const {
419
2.23k
    assert(isVector() && "Invalid accessor");
420
2.23k
    return ((const Vec*)(const void *)Data.buffer)->NumElts;
421
2.23k
  }
422
423
263k
  APValue &getArrayInitializedElt(unsigned I) {
424
263k
    assert(isArray() && "Invalid accessor");
425
263k
    assert(I < getArrayInitializedElts() && "Index out of range");
426
263k
    return ((Arr*)(char*)Data.buffer)->Elts[I];
427
263k
  }
428
125k
  const APValue &getArrayInitializedElt(unsigned I) const {
429
125k
    return const_cast<APValue*>(this)->getArrayInitializedElt(I);
430
125k
  }
431
77.5k
  bool hasArrayFiller() const {
432
77.5k
    return getArrayInitializedElts() != getArraySize();
433
77.5k
  }
434
47.5k
  APValue &getArrayFiller() {
435
47.5k
    assert(isArray() && "Invalid accessor");
436
47.5k
    assert(hasArrayFiller() && "No array filler");
437
47.5k
    return ((Arr*)(char*)Data.buffer)->Elts[getArrayInitializedElts()];
438
47.5k
  }
439
8.18k
  const APValue &getArrayFiller() const {
440
8.18k
    return const_cast<APValue*>(this)->getArrayFiller();
441
8.18k
  }
442
177k
  unsigned getArrayInitializedElts() const {
443
177k
    assert(isArray() && "Invalid accessor");
444
177k
    return ((const Arr*)(const void *)Data.buffer)->NumElts;
445
177k
  }
446
91.7k
  unsigned getArraySize() const {
447
91.7k
    assert(isArray() && "Invalid accessor");
448
91.7k
    return ((const Arr*)(const void *)Data.buffer)->ArrSize;
449
91.7k
  }
450
451
462k
  unsigned getStructNumBases() const {
452
462k
    assert(isStruct() && "Invalid accessor");
453
462k
    return ((const StructData*)(const char*)Data.buffer)->NumBases;
454
462k
  }
455
143k
  unsigned getStructNumFields() const {
456
143k
    assert(isStruct() && "Invalid accessor");
457
143k
    return ((const StructData*)(const char*)Data.buffer)->NumFields;
458
143k
  }
459
4.47k
  APValue &getStructBase(unsigned i) {
460
4.47k
    assert(isStruct() && "Invalid accessor");
461
4.47k
    return ((StructData*)(char*)Data.buffer)->Elts[i];
462
4.47k
  }
463
319k
  APValue &getStructField(unsigned i) {
464
319k
    assert(isStruct() && "Invalid accessor");
465
319k
    return ((StructData*)(char*)Data.buffer)->Elts[getStructNumBases() + i];
466
319k
  }
467
839
  const APValue &getStructBase(unsigned i) const {
468
839
    return const_cast<APValue*>(this)->getStructBase(i);
469
839
  }
470
145k
  const APValue &getStructField(unsigned i) const {
471
145k
    return const_cast<APValue*>(this)->getStructField(i);
472
145k
  }
473
474
1.79k
  const FieldDecl *getUnionField() const {
475
1.79k
    assert(isUnion() && "Invalid accessor");
476
1.79k
    return ((const UnionData*)(const char*)Data.buffer)->Field;
477
1.79k
  }
478
1.84k
  APValue &getUnionValue() {
479
1.84k
    assert(isUnion() && "Invalid accessor");
480
1.84k
    return *((UnionData*)(char*)Data.buffer)->Value;
481
1.84k
  }
482
518
  const APValue &getUnionValue() const {
483
518
    return const_cast<APValue*>(this)->getUnionValue();
484
518
  }
485
486
  const ValueDecl *getMemberPointerDecl() const;
487
  bool isMemberPointerToDerivedMember() const;
488
  ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const;
489
490
18
  const AddrLabelExpr* getAddrLabelDiffLHS() const {
491
18
    assert(isAddrLabelDiff() && "Invalid accessor");
492
18
    return ((const AddrLabelDiffData*)(const char*)Data.buffer)->LHSExpr;
493
18
  }
494
18
  const AddrLabelExpr* getAddrLabelDiffRHS() const {
495
18
    assert(isAddrLabelDiff() && "Invalid accessor");
496
18
    return ((const AddrLabelDiffData*)(const char*)Data.buffer)->RHSExpr;
497
18
  }
498
499
29.7M
  void setInt(APSInt I) {
500
29.7M
    assert(isInt() && "Invalid accessor");
501
29.7M
    *(APSInt *)(char *)Data.buffer = std::move(I);
502
29.7M
  }
503
265k
  void setFloat(APFloat F) {
504
265k
    assert(isFloat() && "Invalid accessor");
505
265k
    *(APFloat *)(char *)Data.buffer = std::move(F);
506
265k
  }
507
0
  void setFixedPoint(APFixedPoint FX) {
508
0
    assert(isFixedPoint() && "Invalid accessor");
509
0
    *(APFixedPoint *)(char *)Data.buffer = std::move(FX);
510
0
  }
511
2.50k
  void setVector(const APValue *E, unsigned N) {
512
2.50k
    assert(isVector() && "Invalid accessor");
513
2.50k
    ((Vec*)(char*)Data.buffer)->Elts = new APValue[N];
514
2.50k
    ((Vec*)(char*)Data.buffer)->NumElts = N;
515
16.2k
    for (unsigned i = 0; i != N; 
++i13.7k
)
516
13.7k
      ((Vec*)(char*)Data.buffer)->Elts[i] = E[i];
517
2.50k
  }
518
74
  void setComplexInt(APSInt R, APSInt I) {
519
74
    assert(R.getBitWidth() == I.getBitWidth() &&
520
74
           "Invalid complex int (type mismatch).");
521
74
    assert(isComplexInt() && "Invalid accessor");
522
74
    ((ComplexAPSInt *)(char *)Data.buffer)->Real = std::move(R);
523
74
    ((ComplexAPSInt *)(char *)Data.buffer)->Imag = std::move(I);
524
74
  }
525
180
  void setComplexFloat(APFloat R, APFloat I) {
526
180
    assert(&R.getSemantics() == &I.getSemantics() &&
527
180
           "Invalid complex float (type mismatch).");
528
180
    assert(isComplexFloat() && "Invalid accessor");
529
180
    ((ComplexAPFloat *)(char *)Data.buffer)->Real = std::move(R);
530
180
    ((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I);
531
180
  }
532
  void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
533
                 bool IsNullPtr);
534
  void setLValue(LValueBase B, const CharUnits &O,
535
                 ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
536
                 bool IsNullPtr);
537
1.23k
  void setUnion(const FieldDecl *Field, const APValue &Value) {
538
1.23k
    assert(isUnion() && "Invalid accessor");
539
1.23k
    ((UnionData*)(char*)Data.buffer)->Field = Field;
540
1.23k
    *((UnionData*)(char*)Data.buffer)->Value = Value;
541
1.23k
  }
542
  void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
543
40
                        const AddrLabelExpr* RHSExpr) {
544
40
    ((AddrLabelDiffData*)(char*)Data.buffer)->LHSExpr = LHSExpr;
545
40
    ((AddrLabelDiffData*)(char*)Data.buffer)->RHSExpr = RHSExpr;
546
40
  }
547
548
  /// Assign by swapping from a copy of the RHS.
549
32.4M
  APValue &operator=(APValue RHS) {
550
32.4M
    swap(RHS);
551
32.4M
    return *this;
552
32.4M
  }
553
554
private:
555
  void DestroyDataAndMakeUninit();
556
29.7M
  void MakeInt() {
557
29.7M
    assert(isAbsent() && "Bad state change");
558
29.7M
    new ((void*)Data.buffer) APSInt(1);
559
29.7M
    Kind = Int;
560
29.7M
  }
561
265k
  void MakeFloat() {
562
265k
    assert(isAbsent() && "Bad state change");
563
265k
    new ((void*)(char*)Data.buffer) APFloat(0.0);
564
265k
    Kind = Float;
565
265k
  }
566
1.15k
  void MakeFixedPoint(APFixedPoint &&FX) {
567
1.15k
    assert(isAbsent() && "Bad state change");
568
1.15k
    new ((void *)(char *)Data.buffer) APFixedPoint(std::move(FX));
569
1.15k
    Kind = FixedPoint;
570
1.15k
  }
571
2.50k
  void MakeVector() {
572
2.50k
    assert(isAbsent() && "Bad state change");
573
2.50k
    new ((void*)(char*)Data.buffer) Vec();
574
2.50k
    Kind = Vector;
575
2.50k
  }
576
74
  void MakeComplexInt() {
577
74
    assert(isAbsent() && "Bad state change");
578
74
    new ((void*)(char*)Data.buffer) ComplexAPSInt();
579
74
    Kind = ComplexInt;
580
74
  }
581
180
  void MakeComplexFloat() {
582
180
    assert(isAbsent() && "Bad state change");
583
180
    new ((void*)(char*)Data.buffer) ComplexAPFloat();
584
180
    Kind = ComplexFloat;
585
180
  }
586
  void MakeLValue();
587
  void MakeArray(unsigned InitElts, unsigned Size);
588
105k
  void MakeStruct(unsigned B, unsigned M) {
589
105k
    assert(isAbsent() && "Bad state change");
590
105k
    new ((void*)(char*)Data.buffer) StructData(B, M);
591
105k
    Kind = Struct;
592
105k
  }
593
1.19k
  void MakeUnion() {
594
1.19k
    assert(isAbsent() && "Bad state change");
595
1.19k
    new ((void*)(char*)Data.buffer) UnionData();
596
1.19k
    Kind = Union;
597
1.19k
  }
598
  void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
599
                         ArrayRef<const CXXRecordDecl*> Path);
600
40
  void MakeAddrLabelDiff() {
601
40
    assert(isAbsent() && "Bad state change");
602
40
    new ((void*)(char*)Data.buffer) AddrLabelDiffData();
603
40
    Kind = AddrLabelDiff;
604
40
  }
605
};
606
607
} // end namespace clang.
608
609
namespace llvm {
610
template<> struct DenseMapInfo<clang::APValue::LValueBase> {
611
  static clang::APValue::LValueBase getEmptyKey();
612
  static clang::APValue::LValueBase getTombstoneKey();
613
  static unsigned getHashValue(const clang::APValue::LValueBase &Base);
614
  static bool isEqual(const clang::APValue::LValueBase &LHS,
615
                      const clang::APValue::LValueBase &RHS);
616
};
617
}
618
619
#endif