Coverage Report

Created: 2021-01-26 06:56

/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/LLVM.h"
17
#include "llvm/ADT/APFixedPoint.h"
18
#include "llvm/ADT/APFloat.h"
19
#include "llvm/ADT/APSInt.h"
20
#include "llvm/ADT/FoldingSet.h"
21
#include "llvm/ADT/PointerIntPair.h"
22
#include "llvm/ADT/PointerUnion.h"
23
#include "llvm/Support/AlignOf.h"
24
25
namespace clang {
26
namespace serialization {
27
template <typename T> class BasicReaderBase;
28
} // end namespace serialization
29
30
  class AddrLabelExpr;
31
  class ASTContext;
32
  class CharUnits;
33
  class CXXRecordDecl;
34
  class Decl;
35
  class DiagnosticBuilder;
36
  class Expr;
37
  class FieldDecl;
38
  struct PrintingPolicy;
39
  class Type;
40
  class ValueDecl;
41
  class QualType;
42
43
/// Symbolic representation of typeid(T) for some type T.
44
class TypeInfoLValue {
45
  const Type *T;
46
47
public:
48
5.84k
  TypeInfoLValue() : T() {}
49
  explicit TypeInfoLValue(const Type *T);
50
51
189
  const Type *getType() const { return T; }
52
4.47k
  explicit operator bool() const { return T; }
53
54
1.33k
  void *getOpaqueValue() { return const_cast<Type*>(T); }
55
189
  static TypeInfoLValue getFromOpaqueValue(void *Value) {
56
189
    TypeInfoLValue V;
57
189
    V.T = reinterpret_cast<const Type*>(Value);
58
189
    return V;
59
189
  }
60
61
  void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const;
62
};
63
64
/// Symbolic representation of a dynamic allocation.
65
class DynamicAllocLValue {
66
  unsigned Index;
67
68
public:
69
38.1k
  DynamicAllocLValue() : Index(0) {}
70
822
  explicit DynamicAllocLValue(unsigned Index) : Index(Index + 1) {}
71
19.2k
  unsigned getIndex() { return Index - 1; }
72
73
37.9k
  explicit operator bool() const { return Index != 0; }
74
75
822
  void *getOpaqueValue() {
76
822
    return reinterpret_cast<void *>(static_cast<uintptr_t>(Index)
77
822
                                    << NumLowBitsAvailable);
78
822
  }
79
2.86k
  static DynamicAllocLValue getFromOpaqueValue(void *Value) {
80
2.86k
    DynamicAllocLValue V;
81
2.86k
    V.Index = reinterpret_cast<uintptr_t>(Value) >> NumLowBitsAvailable;
82
2.86k
    return V;
83
2.86k
  }
84
85
822
  static unsigned getMaxIndex() {
86
822
    return (std::numeric_limits<unsigned>::max() >> NumLowBitsAvailable) - 1;
87
822
  }
88
89
  static constexpr int NumLowBitsAvailable = 3;
90
};
91
}
92
93
namespace llvm {
94
template<> struct PointerLikeTypeTraits<clang::TypeInfoLValue> {
95
1.33k
  static void *getAsVoidPointer(clang::TypeInfoLValue V) {
96
1.33k
    return V.getOpaqueValue();
97
1.33k
  }
98
189
  static clang::TypeInfoLValue getFromVoidPointer(void *P) {
99
189
    return clang::TypeInfoLValue::getFromOpaqueValue(P);
100
189
  }
101
  // Validated by static_assert in APValue.cpp; hardcoded to avoid needing
102
  // to include Type.h.
103
  static constexpr int NumLowBitsAvailable = 3;
104
};
105
106
template<> struct PointerLikeTypeTraits<clang::DynamicAllocLValue> {
107
822
  static void *getAsVoidPointer(clang::DynamicAllocLValue V) {
108
822
    return V.getOpaqueValue();
109
822
  }
110
2.86k
  static clang::DynamicAllocLValue getFromVoidPointer(void *P) {
111
2.86k
    return clang::DynamicAllocLValue::getFromOpaqueValue(P);
112
2.86k
  }
113
  static constexpr int NumLowBitsAvailable =
114
      clang::DynamicAllocLValue::NumLowBitsAvailable;
115
};
116
}
117
118
namespace clang {
119
/// APValue - This class implements a discriminated union of [uninitialized]
120
/// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset],
121
/// [Vector: N * APValue], [Array: N * APValue]
122
class APValue {
123
  typedef llvm::APFixedPoint APFixedPoint;
124
  typedef llvm::APSInt APSInt;
125
  typedef llvm::APFloat APFloat;
126
public:
127
  enum ValueKind {
128
    /// There is no such object (it's outside its lifetime).
129
    None,
130
    /// This object has an indeterminate value (C++ [basic.indet]).
131
    Indeterminate,
132
    Int,
133
    Float,
134
    FixedPoint,
135
    ComplexInt,
136
    ComplexFloat,
137
    LValue,
138
    Vector,
139
    Array,
140
    Struct,
141
    Union,
142
    MemberPointer,
143
    AddrLabelDiff
144
  };
145
146
  class LValueBase {
147
    typedef llvm::PointerUnion<const ValueDecl *, const Expr *, TypeInfoLValue,
148
                               DynamicAllocLValue>
149
        PtrTy;
150
151
  public:
152
19.8M
    LValueBase() : Local{} {}
153
    LValueBase(const ValueDecl *P, unsigned I = 0, unsigned V = 0);
154
    LValueBase(const Expr *P, unsigned I = 0, unsigned V = 0);
155
    static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type);
156
    static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo);
157
158
    void Profile(llvm::FoldingSetNodeID &ID) const;
159
160
    template <class T>
161
36.2M
    bool is() const { return Ptr.is<T>(); }
bool clang::APValue::LValueBase::is<clang::ValueDecl const*>() const
Line
Count
Source
161
10
    bool is() const { return Ptr.is<T>(); }
bool clang::APValue::LValueBase::is<clang::TypeInfoLValue>() const
Line
Count
Source
161
18.1M
    bool is() const { return Ptr.is<T>(); }
bool clang::APValue::LValueBase::is<clang::DynamicAllocLValue>() const
Line
Count
Source
161
18.1M
    bool is() const { return Ptr.is<T>(); }
162
163
    template <class T>
164
2.09M
    T get() const { return Ptr.get<T>(); }
clang::DynamicAllocLValue clang::APValue::LValueBase::get<clang::DynamicAllocLValue>() const
Line
Count
Source
164
9
    T get() const { return Ptr.get<T>(); }
clang::Expr const* clang::APValue::LValueBase::get<clang::Expr const*>() const
Line
Count
Source
164
2.09M
    T get() const { return Ptr.get<T>(); }
clang::ValueDecl const* clang::APValue::LValueBase::get<clang::ValueDecl const*>() const
Line
Count
Source
164
28
    T get() const { return Ptr.get<T>(); }
clang::TypeInfoLValue clang::APValue::LValueBase::get<clang::TypeInfoLValue>() const
Line
Count
Source
164
2
    T get() const { return Ptr.get<T>(); }
165
166
    template <class T>
167
34.9M
    T dyn_cast() const { return Ptr.dyn_cast<T>(); }
clang::ValueDecl const* clang::APValue::LValueBase::dyn_cast<clang::ValueDecl const*>() const
Line
Count
Source
167
27.7M
    T dyn_cast() const { return Ptr.dyn_cast<T>(); }
clang::DynamicAllocLValue clang::APValue::LValueBase::dyn_cast<clang::DynamicAllocLValue>() const
Line
Count
Source
167
38.1k
    T dyn_cast() const { return Ptr.dyn_cast<T>(); }
clang::Expr const* clang::APValue::LValueBase::dyn_cast<clang::Expr const*>() const
Line
Count
Source
167
7.16M
    T dyn_cast() const { return Ptr.dyn_cast<T>(); }
clang::TypeInfoLValue clang::APValue::LValueBase::dyn_cast<clang::TypeInfoLValue>() const
Line
Count
Source
167
4.47k
    T dyn_cast() const { return Ptr.dyn_cast<T>(); }
168
169
    void *getOpaqueValue() const;
170
171
    bool isNull() const;
172
173
    explicit operator bool() const;
174
175
    unsigned getCallIndex() const;
176
    unsigned getVersion() const;
177
    QualType getTypeInfoType() const;
178
    QualType getDynamicAllocType() const;
179
180
    QualType getType() const;
181
182
    friend bool operator==(const LValueBase &LHS, const LValueBase &RHS);
183
102
    friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS) {
184
102
      return !(LHS == RHS);
185
102
    }
186
    friend llvm::hash_code hash_value(const LValueBase &Base);
187
    friend struct llvm::DenseMapInfo<LValueBase>;
188
189
  private:
190
    PtrTy Ptr;
191
    struct LocalState {
192
      unsigned CallIndex, Version;
193
    };
194
    union {
195
      LocalState Local;
196
      /// The type std::type_info, if this is a TypeInfoLValue.
197
      void *TypeInfoType;
198
      /// The QualType, if this is a DynamicAllocLValue.
199
      void *DynamicAllocType;
200
    };
201
  };
202
203
  /// A FieldDecl or CXXRecordDecl, along with a flag indicating whether we
204
  /// mean a virtual or non-virtual base class subobject.
205
  typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
206
207
  /// A non-discriminated union of a base, field, or array index.
208
  class LValuePathEntry {
209
    static_assert(sizeof(uintptr_t) <= sizeof(uint64_t),
210
                  "pointer doesn't fit in 64 bits?");
211
    uint64_t Value;
212
213
  public:
214
178k
    LValuePathEntry() : Value() {}
215
    LValuePathEntry(BaseOrMemberType BaseOrMember);
216
177k
    static LValuePathEntry ArrayIndex(uint64_t Index) {
217
177k
      LValuePathEntry Result;
218
177k
      Result.Value = Index;
219
177k
      return Result;
220
177k
    }
221
222
42.4k
    BaseOrMemberType getAsBaseOrMember() const {
223
42.4k
      return BaseOrMemberType::getFromOpaqueValue(
224
42.4k
          reinterpret_cast<void *>(Value));
225
42.4k
    }
226
174k
    uint64_t getAsArrayIndex() const { return Value; }
227
228
    void Profile(llvm::FoldingSetNodeID &ID) const;
229
230
13.6k
    friend bool operator==(LValuePathEntry A, LValuePathEntry B) {
231
13.6k
      return A.Value == B.Value;
232
13.6k
    }
233
0
    friend bool operator!=(LValuePathEntry A, LValuePathEntry B) {
234
0
      return A.Value != B.Value;
235
0
    }
236
22.5k
    friend llvm::hash_code hash_value(LValuePathEntry A) {
237
22.5k
      return llvm::hash_value(A.Value);
238
22.5k
    }
239
  };
240
  class LValuePathSerializationHelper {
241
    const void *ElemTy;
242
243
  public:
244
    ArrayRef<LValuePathEntry> Path;
245
246
    LValuePathSerializationHelper(ArrayRef<LValuePathEntry>, QualType);
247
    QualType getType();
248
  };
249
  struct NoLValuePath {};
250
  struct UninitArray {};
251
  struct UninitStruct {};
252
253
  template <typename Impl> friend class clang::serialization::BasicReaderBase;
254
  friend class ASTImporter;
255
  friend class ASTNodeImporter;
256
257
private:
258
  ValueKind Kind;
259
260
  struct ComplexAPSInt {
261
    APSInt Real, Imag;
262
309
    ComplexAPSInt() : Real(1), Imag(1) {}
263
  };
264
  struct ComplexAPFloat {
265
    APFloat Real, Imag;
266
418
    ComplexAPFloat() : Real(0.0), Imag(0.0) {}
267
  };
268
  struct LV;
269
  struct Vec {
270
    APValue *Elts;
271
    unsigned NumElts;
272
8.37k
    Vec() : Elts(nullptr), NumElts(0) {}
273
7.87k
    ~Vec() { delete[] Elts; }
274
  };
275
  struct Arr {
276
    APValue *Elts;
277
    unsigned NumElts, ArrSize;
278
    Arr(unsigned NumElts, unsigned ArrSize);
279
    ~Arr();
280
  };
281
  struct StructData {
282
    APValue *Elts;
283
    unsigned NumBases;
284
    unsigned NumFields;
285
    StructData(unsigned NumBases, unsigned NumFields);
286
    ~StructData();
287
  };
288
  struct UnionData {
289
    const FieldDecl *Field;
290
    APValue *Value;
291
    UnionData();
292
    ~UnionData();
293
  };
294
  struct AddrLabelDiffData {
295
    const AddrLabelExpr* LHSExpr;
296
    const AddrLabelExpr* RHSExpr;
297
  };
298
  struct MemberPointerData;
299
300
  // We ensure elsewhere that Data is big enough for LV and MemberPointerData.
301
  typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt,
302
                                      ComplexAPFloat, Vec, Arr, StructData,
303
                                      UnionData, AddrLabelDiffData> DataType;
304
  static const size_t DataSize = sizeof(DataType);
305
306
  DataType Data;
307
308
public:
309
67.0M
  APValue() : Kind(None) {}
310
28.1M
  explicit APValue(APSInt I) : Kind(None) {
311
28.1M
    MakeInt(); setInt(std::move(I));
312
28.1M
  }
313
42.7k
  explicit APValue(APFloat F) : Kind(None) {
314
42.7k
    MakeFloat(); setFloat(std::move(F));
315
42.7k
  }
316
3.24k
  explicit APValue(APFixedPoint FX) : Kind(None) {
317
3.24k
    MakeFixedPoint(std::move(FX));
318
3.24k
  }
319
5.11k
  explicit APValue(const APValue *E, unsigned N) : Kind(None) {
320
5.11k
    MakeVector(); setVector(E, N);
321
5.11k
  }
322
138
  APValue(APSInt R, APSInt I) : Kind(None) {
323
138
    MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
324
138
  }
325
244
  APValue(APFloat R, APFloat I) : Kind(None) {
326
244
    MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
327
244
  }
328
  APValue(const APValue &RHS);
329
  APValue(APValue &&RHS);
330
  APValue(LValueBase B, const CharUnits &O, NoLValuePath N,
331
          bool IsNullPtr = false)
332
6.13k
      : Kind(None) {
333
6.13k
    MakeLValue(); setLValue(B, O, N, IsNullPtr);
334
6.13k
  }
335
  APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
336
          bool OnePastTheEnd, bool IsNullPtr = false)
337
1.19M
      : Kind(None) {
338
1.19M
    MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr);
339
1.19M
  }
340
14.1k
  APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(None) {
341
14.1k
    MakeArray(InitElts, Size);
342
14.1k
  }
343
56.8k
  APValue(UninitStruct, unsigned B, unsigned M) : Kind(None) {
344
56.8k
    MakeStruct(B, M);
345
56.8k
  }
346
  explicit APValue(const FieldDecl *D, const APValue &V = APValue())
347
2.12k
      : Kind(None) {
348
2.12k
    MakeUnion(); setUnion(D, V);
349
2.12k
  }
350
  APValue(const ValueDecl *Member, bool IsDerivedMember,
351
1.56k
          ArrayRef<const CXXRecordDecl*> Path) : Kind(None) {
352
1.56k
    MakeMemberPointer(Member, IsDerivedMember, Path);
353
1.56k
  }
354
  APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr)
355
44
      : Kind(None) {
356
44
    MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
357
44
  }
358
28.0k
  static APValue IndeterminateValue() {
359
28.0k
    APValue Result;
360
28.0k
    Result.Kind = Indeterminate;
361
28.0k
    return Result;
362
28.0k
  }
363
364
  APValue &operator=(const APValue &RHS);
365
  APValue &operator=(APValue &&RHS);
366
367
102M
  ~APValue() {
368
102M
    if (Kind != None && 
Kind != Indeterminate32.4M
)
369
32.4M
      DestroyDataAndMakeUninit();
370
102M
  }
371
372
  /// Returns whether the object performed allocations.
373
  ///
374
  /// If APValues are constructed via placement new, \c needsCleanup()
375
  /// indicates whether the destructor must be called in order to correctly
376
  /// free all allocated memory.
377
  bool needsCleanup() const;
378
379
  /// Swaps the contents of this and the given APValue.
380
  void swap(APValue &RHS);
381
382
  /// profile this value. There is no guarantee that values of different
383
  /// types will not produce the same profiled value, so the type should
384
  /// typically also be profiled if it's not implied by the context.
385
  void Profile(llvm::FoldingSetNodeID &ID) const;
386
387
15.1M
  ValueKind getKind() const { return Kind; }
388
389
39.0M
  bool isAbsent() const { return Kind == None; }
390
3.26M
  bool isIndeterminate() const { return Kind == Indeterminate; }
391
11.6M
  bool hasValue() const { return Kind != None && 
Kind != Indeterminate11.6M
; }
392
393
114M
  bool isInt() const { return Kind == Int; }
394
137k
  bool isFloat() const { return Kind == Float; }
395
4.95k
  bool isFixedPoint() const { return Kind == FixedPoint; }
396
1.59k
  bool isComplexInt() const { return Kind == ComplexInt; }
397
1.24k
  bool isComplexFloat() const { return Kind == ComplexFloat; }
398
29.5M
  bool isLValue() const { return Kind == LValue; }
399
44.6k
  bool isVector() const { return Kind == Vector; }
400
12.2M
  bool isArray() const { return Kind == Array; }
401
11.9M
  bool isStruct() const { return Kind == Struct; }
402
11.5M
  bool isUnion() const { return Kind == Union; }
403
11.4M
  bool isMemberPointer() const { return Kind == MemberPointer; }
404
1.62M
  bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
405
406
  void dump() const;
407
  void dump(raw_ostream &OS, const ASTContext &Context) const;
408
409
  void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const;
410
  void printPretty(raw_ostream &OS, const PrintingPolicy &Policy, QualType Ty,
411
                   const ASTContext *Ctx = nullptr) const;
412
413
  std::string getAsString(const ASTContext &Ctx, QualType Ty) const;
414
415
56.3M
  APSInt &getInt() {
416
56.3M
    assert(isInt() && "Invalid accessor");
417
56.3M
    return *(APSInt *)(char *)&Data;
418
56.3M
  }
419
22.2M
  const APSInt &getInt() const {
420
22.2M
    return const_cast<APValue*>(this)->getInt();
421
22.2M
  }
422
423
  /// Try to convert this value to an integral constant. This works if it's an
424
  /// integer, null pointer, or offset from a null pointer. Returns true on
425
  /// success.
426
  bool toIntegralConstant(APSInt &Result, QualType SrcTy,
427
                          const ASTContext &Ctx) const;
428
429
36.8k
  APFloat &getFloat() {
430
36.8k
    assert(isFloat() && "Invalid accessor");
431
36.8k
    return *(APFloat *)(char *)&Data;
432
36.8k
  }
433
32.2k
  const APFloat &getFloat() const {
434
32.2k
    return const_cast<APValue*>(this)->getFloat();
435
32.2k
  }
436
437
2.83k
  APFixedPoint &getFixedPoint() {
438
2.83k
    assert(isFixedPoint() && "Invalid accessor");
439
2.83k
    return *(APFixedPoint *)(char *)&Data;
440
2.83k
  }
441
700
  const APFixedPoint &getFixedPoint() const {
442
700
    return const_cast<APValue *>(this)->getFixedPoint();
443
700
  }
444
445
333
  APSInt &getComplexIntReal() {
446
333
    assert(isComplexInt() && "Invalid accessor");
447
333
    return ((ComplexAPSInt *)(char *)&Data)->Real;
448
333
  }
449
312
  const APSInt &getComplexIntReal() const {
450
312
    return const_cast<APValue*>(this)->getComplexIntReal();
451
312
  }
452
453
304
  APSInt &getComplexIntImag() {
454
304
    assert(isComplexInt() && "Invalid accessor");
455
304
    return ((ComplexAPSInt *)(char *)&Data)->Imag;
456
304
  }
457
283
  const APSInt &getComplexIntImag() const {
458
283
    return const_cast<APValue*>(this)->getComplexIntImag();
459
283
  }
460
461
397
  APFloat &getComplexFloatReal() {
462
397
    assert(isComplexFloat() && "Invalid accessor");
463
397
    return ((ComplexAPFloat *)(char *)&Data)->Real;
464
397
  }
465
395
  const APFloat &getComplexFloatReal() const {
466
395
    return const_cast<APValue*>(this)->getComplexFloatReal();
467
395
  }
468
469
343
  APFloat &getComplexFloatImag() {
470
343
    assert(isComplexFloat() && "Invalid accessor");
471
343
    return ((ComplexAPFloat *)(char *)&Data)->Imag;
472
343
  }
473
341
  const APFloat &getComplexFloatImag() const {
474
341
    return const_cast<APValue*>(this)->getComplexFloatImag();
475
341
  }
476
477
  const LValueBase getLValueBase() const;
478
  CharUnits &getLValueOffset();
479
743k
  const CharUnits &getLValueOffset() const {
480
743k
    return const_cast<APValue*>(this)->getLValueOffset();
481
743k
  }
482
  bool isLValueOnePastTheEnd() const;
483
  bool hasLValuePath() const;
484
  ArrayRef<LValuePathEntry> getLValuePath() const;
485
  unsigned getLValueCallIndex() const;
486
  unsigned getLValueVersion() const;
487
  bool isNullPointer() const;
488
489
12.6k
  APValue &getVectorElt(unsigned I) {
490
12.6k
    assert(isVector() && "Invalid accessor");
491
12.6k
    assert(I < getVectorLength() && "Index out of range");
492
12.6k
    return ((Vec *)(char *)&Data)->Elts[I];
493
12.6k
  }
494
9.83k
  const APValue &getVectorElt(unsigned I) const {
495
9.83k
    return const_cast<APValue*>(this)->getVectorElt(I);
496
9.83k
  }
497
20.2k
  unsigned getVectorLength() const {
498
20.2k
    assert(isVector() && "Invalid accessor");
499
20.2k
    return ((const Vec *)(const void *)&Data)->NumElts;
500
20.2k
  }
501
502
240k
  APValue &getArrayInitializedElt(unsigned I) {
503
240k
    assert(isArray() && "Invalid accessor");
504
240k
    assert(I < getArrayInitializedElts() && "Index out of range");
505
240k
    return ((Arr *)(char *)&Data)->Elts[I];
506
240k
  }
507
93.5k
  const APValue &getArrayInitializedElt(unsigned I) const {
508
93.5k
    return const_cast<APValue*>(this)->getArrayInitializedElt(I);
509
93.5k
  }
510
36.8k
  bool hasArrayFiller() const {
511
36.8k
    return getArrayInitializedElts() != getArraySize();
512
36.8k
  }
513
18.9k
  APValue &getArrayFiller() {
514
18.9k
    assert(isArray() && "Invalid accessor");
515
18.9k
    assert(hasArrayFiller() && "No array filler");
516
18.9k
    return ((Arr *)(char *)&Data)->Elts[getArrayInitializedElts()];
517
18.9k
  }
518
3.37k
  const APValue &getArrayFiller() const {
519
3.37k
    return const_cast<APValue*>(this)->getArrayFiller();
520
3.37k
  }
521
323k
  unsigned getArrayInitializedElts() const {
522
323k
    assert(isArray() && "Invalid accessor");
523
323k
    return ((const Arr *)(const void *)&Data)->NumElts;
524
323k
  }
525
42.0k
  unsigned getArraySize() const {
526
42.0k
    assert(isArray() && "Invalid accessor");
527
42.0k
    return ((const Arr *)(const void *)&Data)->ArrSize;
528
42.0k
  }
529
530
142k
  unsigned getStructNumBases() const {
531
142k
    assert(isStruct() && "Invalid accessor");
532
142k
    return ((const StructData *)(const char *)&Data)->NumBases;
533
142k
  }
534
132k
  unsigned getStructNumFields() const {
535
132k
    assert(isStruct() && "Invalid accessor");
536
132k
    return ((const StructData *)(const char *)&Data)->NumFields;
537
132k
  }
538
9.84k
  APValue &getStructBase(unsigned i) {
539
9.84k
    assert(isStruct() && "Invalid accessor");
540
9.84k
    assert(i < getStructNumBases() && "base class index OOB");
541
9.84k
    return ((StructData *)(char *)&Data)->Elts[i];
542
9.84k
  }
543
122k
  APValue &getStructField(unsigned i) {
544
122k
    assert(isStruct() && "Invalid accessor");
545
122k
    assert(i < getStructNumFields() && "field index OOB");
546
122k
    return ((StructData *)(char *)&Data)->Elts[getStructNumBases() + i];
547
122k
  }
548
3.61k
  const APValue &getStructBase(unsigned i) const {
549
3.61k
    return const_cast<APValue*>(this)->getStructBase(i);
550
3.61k
  }
551
34.3k
  const APValue &getStructField(unsigned i) const {
552
34.3k
    return const_cast<APValue*>(this)->getStructField(i);
553
34.3k
  }
554
555
4.96k
  const FieldDecl *getUnionField() const {
556
4.96k
    assert(isUnion() && "Invalid accessor");
557
4.96k
    return ((const UnionData *)(const char *)&Data)->Field;
558
4.96k
  }
559
4.08k
  APValue &getUnionValue() {
560
4.08k
    assert(isUnion() && "Invalid accessor");
561
4.08k
    return *((UnionData *)(char *)&Data)->Value;
562
4.08k
  }
563
1.93k
  const APValue &getUnionValue() const {
564
1.93k
    return const_cast<APValue*>(this)->getUnionValue();
565
1.93k
  }
566
567
  const ValueDecl *getMemberPointerDecl() const;
568
  bool isMemberPointerToDerivedMember() const;
569
  ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const;
570
571
26
  const AddrLabelExpr* getAddrLabelDiffLHS() const {
572
26
    assert(isAddrLabelDiff() && "Invalid accessor");
573
26
    return ((const AddrLabelDiffData *)(const char *)&Data)->LHSExpr;
574
26
  }
575
26
  const AddrLabelExpr* getAddrLabelDiffRHS() const {
576
26
    assert(isAddrLabelDiff() && "Invalid accessor");
577
26
    return ((const AddrLabelDiffData *)(const char *)&Data)->RHSExpr;
578
26
  }
579
580
34.0M
  void setInt(APSInt I) {
581
34.0M
    assert(isInt() && "Invalid accessor");
582
34.0M
    *(APSInt *)(char *)&Data = std::move(I);
583
34.0M
  }
584
55.9k
  void setFloat(APFloat F) {
585
55.9k
    assert(isFloat() && "Invalid accessor");
586
55.9k
    *(APFloat *)(char *)&Data = std::move(F);
587
55.9k
  }
588
0
  void setFixedPoint(APFixedPoint FX) {
589
0
    assert(isFixedPoint() && "Invalid accessor");
590
0
    *(APFixedPoint *)(char *)&Data = std::move(FX);
591
0
  }
592
8.37k
  void setVector(const APValue *E, unsigned N) {
593
8.37k
    MutableArrayRef<APValue> InternalElts = setVectorUninit(N);
594
58.3k
    for (unsigned i = 0; i != N; 
++i49.9k
)
595
49.9k
      InternalElts[i] = E[i];
596
8.37k
  }
597
309
  void setComplexInt(APSInt R, APSInt I) {
598
309
    assert(R.getBitWidth() == I.getBitWidth() &&
599
309
           "Invalid complex int (type mismatch).");
600
309
    assert(isComplexInt() && "Invalid accessor");
601
309
    ((ComplexAPSInt *)(char *)&Data)->Real = std::move(R);
602
309
    ((ComplexAPSInt *)(char *)&Data)->Imag = std::move(I);
603
309
  }
604
418
  void setComplexFloat(APFloat R, APFloat I) {
605
418
    assert(&R.getSemantics() == &I.getSemantics() &&
606
418
           "Invalid complex float (type mismatch).");
607
418
    assert(isComplexFloat() && "Invalid accessor");
608
418
    ((ComplexAPFloat *)(char *)&Data)->Real = std::move(R);
609
418
    ((ComplexAPFloat *)(char *)&Data)->Imag = std::move(I);
610
418
  }
611
  void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
612
                 bool IsNullPtr);
613
  void setLValue(LValueBase B, const CharUnits &O,
614
                 ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
615
                 bool IsNullPtr);
616
  void setUnion(const FieldDecl *Field, const APValue &Value);
617
  void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
618
63
                        const AddrLabelExpr* RHSExpr) {
619
63
    ((AddrLabelDiffData *)(char *)&Data)->LHSExpr = LHSExpr;
620
63
    ((AddrLabelDiffData *)(char *)&Data)->RHSExpr = RHSExpr;
621
63
  }
622
623
private:
624
  void DestroyDataAndMakeUninit();
625
34.0M
  void MakeInt() {
626
34.0M
    assert(isAbsent() && "Bad state change");
627
34.0M
    new ((void *)&Data) APSInt(1);
628
34.0M
    Kind = Int;
629
34.0M
  }
630
55.9k
  void MakeFloat() {
631
55.9k
    assert(isAbsent() && "Bad state change");
632
55.9k
    new ((void *)(char *)&Data) APFloat(0.0);
633
55.9k
    Kind = Float;
634
55.9k
  }
635
3.25k
  void MakeFixedPoint(APFixedPoint &&FX) {
636
3.25k
    assert(isAbsent() && "Bad state change");
637
3.25k
    new ((void *)(char *)&Data) APFixedPoint(std::move(FX));
638
3.25k
    Kind = FixedPoint;
639
3.25k
  }
640
8.37k
  void MakeVector() {
641
8.37k
    assert(isAbsent() && "Bad state change");
642
8.37k
    new ((void *)(char *)&Data) Vec();
643
8.37k
    Kind = Vector;
644
8.37k
  }
645
309
  void MakeComplexInt() {
646
309
    assert(isAbsent() && "Bad state change");
647
309
    new ((void *)(char *)&Data) ComplexAPSInt();
648
309
    Kind = ComplexInt;
649
309
  }
650
418
  void MakeComplexFloat() {
651
418
    assert(isAbsent() && "Bad state change");
652
418
    new ((void *)(char *)&Data) ComplexAPFloat();
653
418
    Kind = ComplexFloat;
654
418
  }
655
  void MakeLValue();
656
  void MakeArray(unsigned InitElts, unsigned Size);
657
61.2k
  void MakeStruct(unsigned B, unsigned M) {
658
61.2k
    assert(isAbsent() && "Bad state change");
659
61.2k
    new ((void *)(char *)&Data) StructData(B, M);
660
61.2k
    Kind = Struct;
661
61.2k
  }
662
2.66k
  void MakeUnion() {
663
2.66k
    assert(isAbsent() && "Bad state change");
664
2.66k
    new ((void *)(char *)&Data) UnionData();
665
2.66k
    Kind = Union;
666
2.66k
  }
667
  void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
668
                         ArrayRef<const CXXRecordDecl*> Path);
669
63
  void MakeAddrLabelDiff() {
670
63
    assert(isAbsent() && "Bad state change");
671
63
    new ((void *)(char *)&Data) AddrLabelDiffData();
672
63
    Kind = AddrLabelDiff;
673
63
  }
674
675
private:
676
  /// The following functions are used as part of initialization, during
677
  /// deserialization and importing. Reserve the space so that it can be
678
  /// filled in by those steps.
679
8.37k
  MutableArrayRef<APValue> setVectorUninit(unsigned N) {
680
8.37k
    assert(isVector() && "Invalid accessor");
681
8.37k
    Vec *V = ((Vec *)(char *)&Data);
682
8.37k
    V->Elts = new APValue[N];
683
8.37k
    V->NumElts = N;
684
8.37k
    return {V->Elts, V->NumElts};
685
8.37k
  }
686
  MutableArrayRef<LValuePathEntry>
687
  setLValueUninit(LValueBase B, const CharUnits &O, unsigned Size,
688
                  bool OnePastTheEnd, bool IsNullPtr);
689
  MutableArrayRef<const CXXRecordDecl *>
690
  setMemberPointerUninit(const ValueDecl *Member, bool IsDerivedMember,
691
                         unsigned Size);
692
};
693
694
} // end namespace clang.
695
696
namespace llvm {
697
template<> struct DenseMapInfo<clang::APValue::LValueBase> {
698
  static clang::APValue::LValueBase getEmptyKey();
699
  static clang::APValue::LValueBase getTombstoneKey();
700
  static unsigned getHashValue(const clang::APValue::LValueBase &Base);
701
  static bool isEqual(const clang::APValue::LValueBase &LHS,
702
                      const clang::APValue::LValueBase &RHS);
703
};
704
}
705
706
#endif