Coverage Report

Created: 2020-02-25 14:32

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