Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/clang/lib/AST/Interp/ByteCodeExprGen.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- ByteCodeExprGen.cpp - Code generator for expressions ---*- 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
#include "ByteCodeExprGen.h"
10
#include "ByteCodeEmitter.h"
11
#include "ByteCodeGenError.h"
12
#include "ByteCodeStmtGen.h"
13
#include "Context.h"
14
#include "Floating.h"
15
#include "Function.h"
16
#include "PrimType.h"
17
#include "Program.h"
18
19
using namespace clang;
20
using namespace clang::interp;
21
22
using APSInt = llvm::APSInt;
23
24
namespace clang {
25
namespace interp {
26
27
/// Scope used to handle temporaries in toplevel variable declarations.
28
template <class Emitter> class DeclScope final : public VariableScope<Emitter> {
29
public:
30
  DeclScope(ByteCodeExprGen<Emitter> *Ctx, const ValueDecl *VD)
31
      : VariableScope<Emitter>(Ctx), Scope(Ctx->P, VD),
32
0
        OldGlobalDecl(Ctx->GlobalDecl) {
33
0
    Ctx->GlobalDecl = Context::shouldBeGloballyIndexed(VD);
34
0
  }
Unexecuted instantiation: clang::interp::DeclScope<clang::interp::ByteCodeEmitter>::DeclScope(clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>*, clang::ValueDecl const*)
Unexecuted instantiation: clang::interp::DeclScope<clang::interp::EvalEmitter>::DeclScope(clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>*, clang::ValueDecl const*)
35
36
0
  void addExtended(const Scope::Local &Local) override {
37
0
    return this->addLocal(Local);
38
0
  }
Unexecuted instantiation: clang::interp::DeclScope<clang::interp::ByteCodeEmitter>::addExtended(clang::interp::Scope::Local const&)
Unexecuted instantiation: clang::interp::DeclScope<clang::interp::EvalEmitter>::addExtended(clang::interp::Scope::Local const&)
39
40
0
  ~DeclScope() { this->Ctx->GlobalDecl = OldGlobalDecl; }
Unexecuted instantiation: clang::interp::DeclScope<clang::interp::ByteCodeEmitter>::~DeclScope()
Unexecuted instantiation: clang::interp::DeclScope<clang::interp::EvalEmitter>::~DeclScope()
41
42
private:
43
  Program::DeclScope Scope;
44
  bool OldGlobalDecl;
45
};
46
47
/// Scope used to handle initialization methods.
48
template <class Emitter> class OptionScope final {
49
public:
50
  /// Root constructor, compiling or discarding primitives.
51
  OptionScope(ByteCodeExprGen<Emitter> *Ctx, bool NewDiscardResult,
52
              bool NewInitializing)
53
      : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
54
0
        OldInitializing(Ctx->Initializing) {
55
0
    Ctx->DiscardResult = NewDiscardResult;
56
0
    Ctx->Initializing = NewInitializing;
57
0
  }
Unexecuted instantiation: clang::interp::OptionScope<clang::interp::ByteCodeEmitter>::OptionScope(clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>*, bool, bool)
Unexecuted instantiation: clang::interp::OptionScope<clang::interp::EvalEmitter>::OptionScope(clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>*, bool, bool)
58
59
0
  ~OptionScope() {
60
0
    Ctx->DiscardResult = OldDiscardResult;
61
0
    Ctx->Initializing = OldInitializing;
62
0
  }
Unexecuted instantiation: clang::interp::OptionScope<clang::interp::ByteCodeEmitter>::~OptionScope()
Unexecuted instantiation: clang::interp::OptionScope<clang::interp::EvalEmitter>::~OptionScope()
63
64
private:
65
  /// Parent context.
66
  ByteCodeExprGen<Emitter> *Ctx;
67
  /// Old discard flag to restore.
68
  bool OldDiscardResult;
69
  bool OldInitializing;
70
};
71
72
} // namespace interp
73
} // namespace clang
74
75
template <class Emitter>
76
0
bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
77
0
  const Expr *SubExpr = CE->getSubExpr();
78
0
  switch (CE->getCastKind()) {
79
80
0
  case CK_LValueToRValue: {
81
0
    return dereference(
82
0
        SubExpr, DerefKind::Read,
83
0
        [](PrimType) {
84
          // Value loaded - nothing to do here.
85
0
          return true;
86
0
        },
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitCastExpr(clang::CastExpr const*)::{lambda(clang::interp::PrimType)#1}::operator()(clang::interp::PrimType) const
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitCastExpr(clang::CastExpr const*)::{lambda(clang::interp::PrimType)#1}::operator()(clang::interp::PrimType) const
87
0
        [this, CE](PrimType T) {
88
          // Pointer on stack - dereference it.
89
0
          if (!this->emitLoadPop(T, CE))
90
0
            return false;
91
0
          return DiscardResult ? this->emitPop(T, CE) : true;
92
0
        });
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitCastExpr(clang::CastExpr const*)::{lambda(clang::interp::PrimType)#2}::operator()(clang::interp::PrimType) const
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitCastExpr(clang::CastExpr const*)::{lambda(clang::interp::PrimType)#2}::operator()(clang::interp::PrimType) const
93
0
  }
94
95
0
  case CK_UncheckedDerivedToBase:
96
0
  case CK_DerivedToBase: {
97
0
    if (!this->visit(SubExpr))
98
0
      return false;
99
100
0
    unsigned DerivedOffset = collectBaseOffset(getRecordTy(CE->getType()),
101
0
                                               getRecordTy(SubExpr->getType()));
102
103
0
    return this->emitGetPtrBasePop(DerivedOffset, CE);
104
0
  }
105
106
0
  case CK_BaseToDerived: {
107
0
    if (!this->visit(SubExpr))
108
0
      return false;
109
110
0
    unsigned DerivedOffset = collectBaseOffset(getRecordTy(SubExpr->getType()),
111
0
                                               getRecordTy(CE->getType()));
112
113
0
    return this->emitGetPtrDerivedPop(DerivedOffset, CE);
114
0
  }
115
116
0
  case CK_FloatingCast: {
117
0
    if (DiscardResult)
118
0
      return this->discard(SubExpr);
119
0
    if (!this->visit(SubExpr))
120
0
      return false;
121
0
    const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->getType());
122
0
    return this->emitCastFP(TargetSemantics, getRoundingMode(CE), CE);
123
0
  }
124
125
0
  case CK_IntegralToFloating: {
126
0
    if (DiscardResult)
127
0
      return this->discard(SubExpr);
128
0
    std::optional<PrimType> FromT = classify(SubExpr->getType());
129
0
    if (!FromT)
130
0
      return false;
131
132
0
    if (!this->visit(SubExpr))
133
0
      return false;
134
135
0
    const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->getType());
136
0
    llvm::RoundingMode RM = getRoundingMode(CE);
137
0
    return this->emitCastIntegralFloating(*FromT, TargetSemantics, RM, CE);
138
0
  }
139
140
0
  case CK_FloatingToBoolean:
141
0
  case CK_FloatingToIntegral: {
142
0
    if (DiscardResult)
143
0
      return this->discard(SubExpr);
144
145
0
    std::optional<PrimType> ToT = classify(CE->getType());
146
147
0
    if (!ToT)
148
0
      return false;
149
150
0
    if (!this->visit(SubExpr))
151
0
      return false;
152
153
0
    if (ToT == PT_IntAP)
154
0
      return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(CE->getType()),
155
0
                                              CE);
156
0
    if (ToT == PT_IntAPS)
157
0
      return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(CE->getType()),
158
0
                                               CE);
159
160
0
    return this->emitCastFloatingIntegral(*ToT, CE);
161
0
  }
162
163
0
  case CK_NullToPointer:
164
0
    if (DiscardResult)
165
0
      return true;
166
0
    return this->emitNull(classifyPrim(CE->getType()), CE);
167
168
0
  case CK_PointerToIntegral: {
169
    // TODO: Discard handling.
170
0
    if (!this->visit(SubExpr))
171
0
      return false;
172
173
0
    PrimType T = classifyPrim(CE->getType());
174
0
    return this->emitCastPointerIntegral(T, CE);
175
0
  }
176
177
0
  case CK_ArrayToPointerDecay: {
178
0
    if (!this->visit(SubExpr))
179
0
      return false;
180
0
    if (!this->emitArrayDecay(CE))
181
0
      return false;
182
0
    if (DiscardResult)
183
0
      return this->emitPopPtr(CE);
184
0
    return true;
185
0
  }
186
187
0
  case CK_AtomicToNonAtomic:
188
0
  case CK_ConstructorConversion:
189
0
  case CK_FunctionToPointerDecay:
190
0
  case CK_NonAtomicToAtomic:
191
0
  case CK_NoOp:
192
0
  case CK_UserDefinedConversion:
193
0
  case CK_BitCast:
194
0
    return this->delegate(SubExpr);
195
196
0
  case CK_IntegralToBoolean:
197
0
  case CK_IntegralCast: {
198
0
    if (DiscardResult)
199
0
      return this->discard(SubExpr);
200
0
    std::optional<PrimType> FromT = classify(SubExpr->getType());
201
0
    std::optional<PrimType> ToT = classify(CE->getType());
202
203
0
    if (!FromT || !ToT)
204
0
      return false;
205
206
0
    if (!this->visit(SubExpr))
207
0
      return false;
208
209
0
    if (ToT == PT_IntAP)
210
0
      return this->emitCastAP(*FromT, Ctx.getBitWidth(CE->getType()), CE);
211
0
    if (ToT == PT_IntAPS)
212
0
      return this->emitCastAPS(*FromT, Ctx.getBitWidth(CE->getType()), CE);
213
214
0
    if (FromT == ToT)
215
0
      return true;
216
0
    return this->emitCast(*FromT, *ToT, CE);
217
0
  }
218
219
0
  case CK_PointerToBoolean: {
220
0
    PrimType PtrT = classifyPrim(SubExpr->getType());
221
222
    // Just emit p != nullptr for this.
223
0
    if (!this->visit(SubExpr))
224
0
      return false;
225
226
0
    if (!this->emitNull(PtrT, CE))
227
0
      return false;
228
229
0
    return this->emitNE(PtrT, CE);
230
0
  }
231
232
0
  case CK_IntegralComplexToBoolean:
233
0
  case CK_FloatingComplexToBoolean: {
234
0
    std::optional<PrimType> ElemT =
235
0
        classifyComplexElementType(SubExpr->getType());
236
0
    if (!ElemT)
237
0
      return false;
238
    // We emit the expression (__real(E) != 0 || __imag(E) != 0)
239
    // for us, that means (bool)E[0] || (bool)E[1]
240
0
    if (!this->visit(SubExpr))
241
0
      return false;
242
0
    if (!this->emitConstUint8(0, CE))
243
0
      return false;
244
0
    if (!this->emitArrayElemPtrUint8(CE))
245
0
      return false;
246
0
    if (!this->emitLoadPop(*ElemT, CE))
247
0
      return false;
248
0
    if (*ElemT == PT_Float) {
249
0
      if (!this->emitCastFloatingIntegral(PT_Bool, CE))
250
0
        return false;
251
0
    } else {
252
0
      if (!this->emitCast(*ElemT, PT_Bool, CE))
253
0
        return false;
254
0
    }
255
256
    // We now have the bool value of E[0] on the stack.
257
0
    LabelTy LabelTrue = this->getLabel();
258
0
    if (!this->jumpTrue(LabelTrue))
259
0
      return false;
260
261
0
    if (!this->emitConstUint8(1, CE))
262
0
      return false;
263
0
    if (!this->emitArrayElemPtrPopUint8(CE))
264
0
      return false;
265
0
    if (!this->emitLoadPop(*ElemT, CE))
266
0
      return false;
267
0
    if (*ElemT == PT_Float) {
268
0
      if (!this->emitCastFloatingIntegral(PT_Bool, CE))
269
0
        return false;
270
0
    } else {
271
0
      if (!this->emitCast(*ElemT, PT_Bool, CE))
272
0
        return false;
273
0
    }
274
    // Leave the boolean value of E[1] on the stack.
275
0
    LabelTy EndLabel = this->getLabel();
276
0
    this->jump(EndLabel);
277
278
0
    this->emitLabel(LabelTrue);
279
0
    if (!this->emitPopPtr(CE))
280
0
      return false;
281
0
    if (!this->emitConstBool(true, CE))
282
0
      return false;
283
284
0
    this->fallthrough(EndLabel);
285
0
    this->emitLabel(EndLabel);
286
287
0
    return true;
288
0
  }
289
290
0
  case CK_ToVoid:
291
0
    return discard(SubExpr);
292
293
0
  default:
294
0
    assert(false && "Cast not implemented");
295
0
  }
296
0
  llvm_unreachable("Unhandled clang::CastKind enum");
297
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitCastExpr(clang::CastExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitCastExpr(clang::CastExpr const*)
298
299
template <class Emitter>
300
0
bool ByteCodeExprGen<Emitter>::VisitIntegerLiteral(const IntegerLiteral *LE) {
301
0
  if (DiscardResult)
302
0
    return true;
303
304
0
  return this->emitConst(LE->getValue(), LE);
305
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitIntegerLiteral(clang::IntegerLiteral const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitIntegerLiteral(clang::IntegerLiteral const*)
306
307
template <class Emitter>
308
0
bool ByteCodeExprGen<Emitter>::VisitFloatingLiteral(const FloatingLiteral *E) {
309
0
  if (DiscardResult)
310
0
    return true;
311
312
0
  return this->emitConstFloat(E->getValue(), E);
313
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitFloatingLiteral(clang::FloatingLiteral const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitFloatingLiteral(clang::FloatingLiteral const*)
314
315
template <class Emitter>
316
0
bool ByteCodeExprGen<Emitter>::VisitParenExpr(const ParenExpr *E) {
317
0
  return this->delegate(E->getSubExpr());
318
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitParenExpr(clang::ParenExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitParenExpr(clang::ParenExpr const*)
319
320
template <class Emitter>
321
0
bool ByteCodeExprGen<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) {
322
  // Need short-circuiting for these.
323
0
  if (BO->isLogicalOp())
324
0
    return this->VisitLogicalBinOp(BO);
325
326
0
  if (BO->getType()->isAnyComplexType())
327
0
    return this->VisitComplexBinOp(BO);
328
329
0
  const Expr *LHS = BO->getLHS();
330
0
  const Expr *RHS = BO->getRHS();
331
332
0
  if (BO->isPtrMemOp())
333
0
    return this->visit(RHS);
334
335
  // Typecheck the args.
336
0
  std::optional<PrimType> LT = classify(LHS->getType());
337
0
  std::optional<PrimType> RT = classify(RHS->getType());
338
0
  std::optional<PrimType> T = classify(BO->getType());
339
340
  // Deal with operations which have composite or void types.
341
0
  if (BO->isCommaOp()) {
342
0
    if (!this->discard(LHS))
343
0
      return false;
344
0
    if (RHS->getType()->isVoidType())
345
0
      return this->discard(RHS);
346
347
0
    return this->delegate(RHS);
348
0
  }
349
350
  // Special case for C++'s three-way/spaceship operator <=>, which
351
  // returns a std::{strong,weak,partial}_ordering (which is a class, so doesn't
352
  // have a PrimType).
353
0
  if (!T) {
354
0
    if (DiscardResult)
355
0
      return true;
356
0
    const ComparisonCategoryInfo *CmpInfo =
357
0
        Ctx.getASTContext().CompCategories.lookupInfoForType(BO->getType());
358
0
    assert(CmpInfo);
359
360
    // We need a temporary variable holding our return value.
361
0
    if (!Initializing) {
362
0
      std::optional<unsigned> ResultIndex = this->allocateLocal(BO, false);
363
0
      if (!this->emitGetPtrLocal(*ResultIndex, BO))
364
0
        return false;
365
0
    }
366
367
0
    if (!visit(LHS) || !visit(RHS))
368
0
      return false;
369
370
0
    return this->emitCMP3(*LT, CmpInfo, BO);
371
0
  }
372
373
0
  if (!LT || !RT || !T)
374
0
    return this->bail(BO);
375
376
  // Pointer arithmetic special case.
377
0
  if (BO->getOpcode() == BO_Add || BO->getOpcode() == BO_Sub) {
378
0
    if (T == PT_Ptr || (LT == PT_Ptr && RT == PT_Ptr))
379
0
      return this->VisitPointerArithBinOp(BO);
380
0
  }
381
382
0
  if (!visit(LHS) || !visit(RHS))
383
0
    return false;
384
385
  // For languages such as C, cast the result of one
386
  // of our comparision opcodes to T (which is usually int).
387
0
  auto MaybeCastToBool = [this, T, BO](bool Result) {
388
0
    if (!Result)
389
0
      return false;
390
0
    if (DiscardResult)
391
0
      return this->emitPop(*T, BO);
392
0
    if (T != PT_Bool)
393
0
      return this->emitCast(PT_Bool, *T, BO);
394
0
    return true;
395
0
  };
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitBinaryOperator(clang::BinaryOperator const*)::{lambda(bool)#1}::operator()(bool) const
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitBinaryOperator(clang::BinaryOperator const*)::{lambda(bool)#1}::operator()(bool) const
396
397
0
  auto Discard = [this, T, BO](bool Result) {
398
0
    if (!Result)
399
0
      return false;
400
0
    return DiscardResult ? this->emitPop(*T, BO) : true;
401
0
  };
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitBinaryOperator(clang::BinaryOperator const*)::{lambda(bool)#2}::operator()(bool) const
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitBinaryOperator(clang::BinaryOperator const*)::{lambda(bool)#2}::operator()(bool) const
402
403
0
  switch (BO->getOpcode()) {
404
0
  case BO_EQ:
405
0
    return MaybeCastToBool(this->emitEQ(*LT, BO));
406
0
  case BO_NE:
407
0
    return MaybeCastToBool(this->emitNE(*LT, BO));
408
0
  case BO_LT:
409
0
    return MaybeCastToBool(this->emitLT(*LT, BO));
410
0
  case BO_LE:
411
0
    return MaybeCastToBool(this->emitLE(*LT, BO));
412
0
  case BO_GT:
413
0
    return MaybeCastToBool(this->emitGT(*LT, BO));
414
0
  case BO_GE:
415
0
    return MaybeCastToBool(this->emitGE(*LT, BO));
416
0
  case BO_Sub:
417
0
    if (BO->getType()->isFloatingType())
418
0
      return Discard(this->emitSubf(getRoundingMode(BO), BO));
419
0
    return Discard(this->emitSub(*T, BO));
420
0
  case BO_Add:
421
0
    if (BO->getType()->isFloatingType())
422
0
      return Discard(this->emitAddf(getRoundingMode(BO), BO));
423
0
    return Discard(this->emitAdd(*T, BO));
424
0
  case BO_Mul:
425
0
    if (BO->getType()->isFloatingType())
426
0
      return Discard(this->emitMulf(getRoundingMode(BO), BO));
427
0
    return Discard(this->emitMul(*T, BO));
428
0
  case BO_Rem:
429
0
    return Discard(this->emitRem(*T, BO));
430
0
  case BO_Div:
431
0
    if (BO->getType()->isFloatingType())
432
0
      return Discard(this->emitDivf(getRoundingMode(BO), BO));
433
0
    return Discard(this->emitDiv(*T, BO));
434
0
  case BO_Assign:
435
0
    if (DiscardResult)
436
0
      return LHS->refersToBitField() ? this->emitStoreBitFieldPop(*T, BO)
437
0
                                     : this->emitStorePop(*T, BO);
438
0
    return LHS->refersToBitField() ? this->emitStoreBitField(*T, BO)
439
0
                                   : this->emitStore(*T, BO);
440
0
  case BO_And:
441
0
    return Discard(this->emitBitAnd(*T, BO));
442
0
  case BO_Or:
443
0
    return Discard(this->emitBitOr(*T, BO));
444
0
  case BO_Shl:
445
0
    return Discard(this->emitShl(*LT, *RT, BO));
446
0
  case BO_Shr:
447
0
    return Discard(this->emitShr(*LT, *RT, BO));
448
0
  case BO_Xor:
449
0
    return Discard(this->emitBitXor(*T, BO));
450
0
  case BO_LOr:
451
0
  case BO_LAnd:
452
0
    llvm_unreachable("Already handled earlier");
453
0
  default:
454
0
    return this->bail(BO);
455
0
  }
456
457
0
  llvm_unreachable("Unhandled binary op");
458
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitBinaryOperator(clang::BinaryOperator const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitBinaryOperator(clang::BinaryOperator const*)
459
460
/// Perform addition/subtraction of a pointer and an integer or
461
/// subtraction of two pointers.
462
template <class Emitter>
463
0
bool ByteCodeExprGen<Emitter>::VisitPointerArithBinOp(const BinaryOperator *E) {
464
0
  BinaryOperatorKind Op = E->getOpcode();
465
0
  const Expr *LHS = E->getLHS();
466
0
  const Expr *RHS = E->getRHS();
467
468
0
  if ((Op != BO_Add && Op != BO_Sub) ||
469
0
      (!LHS->getType()->isPointerType() && !RHS->getType()->isPointerType()))
470
0
    return false;
471
472
0
  std::optional<PrimType> LT = classify(LHS);
473
0
  std::optional<PrimType> RT = classify(RHS);
474
475
0
  if (!LT || !RT)
476
0
    return false;
477
478
0
  if (LHS->getType()->isPointerType() && RHS->getType()->isPointerType()) {
479
0
    if (Op != BO_Sub)
480
0
      return false;
481
482
0
    assert(E->getType()->isIntegerType());
483
0
    if (!visit(RHS) || !visit(LHS))
484
0
      return false;
485
486
0
    return this->emitSubPtr(classifyPrim(E->getType()), E);
487
0
  }
488
489
0
  PrimType OffsetType;
490
0
  if (LHS->getType()->isIntegerType()) {
491
0
    if (!visit(RHS) || !visit(LHS))
492
0
      return false;
493
0
    OffsetType = *LT;
494
0
  } else if (RHS->getType()->isIntegerType()) {
495
0
    if (!visit(LHS) || !visit(RHS))
496
0
      return false;
497
0
    OffsetType = *RT;
498
0
  } else {
499
0
    return false;
500
0
  }
501
502
0
  if (Op == BO_Add)
503
0
    return this->emitAddOffset(OffsetType, E);
504
0
  else if (Op == BO_Sub)
505
0
    return this->emitSubOffset(OffsetType, E);
506
507
0
  return this->bail(E);
508
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitPointerArithBinOp(clang::BinaryOperator const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitPointerArithBinOp(clang::BinaryOperator const*)
509
510
template <class Emitter>
511
0
bool ByteCodeExprGen<Emitter>::VisitLogicalBinOp(const BinaryOperator *E) {
512
0
  assert(E->isLogicalOp());
513
0
  BinaryOperatorKind Op = E->getOpcode();
514
0
  const Expr *LHS = E->getLHS();
515
0
  const Expr *RHS = E->getRHS();
516
0
  std::optional<PrimType> T = classify(E->getType());
517
518
0
  if (Op == BO_LOr) {
519
    // Logical OR. Visit LHS and only evaluate RHS if LHS was FALSE.
520
0
    LabelTy LabelTrue = this->getLabel();
521
0
    LabelTy LabelEnd = this->getLabel();
522
523
0
    if (!this->visitBool(LHS))
524
0
      return false;
525
0
    if (!this->jumpTrue(LabelTrue))
526
0
      return false;
527
528
0
    if (!this->visitBool(RHS))
529
0
      return false;
530
0
    if (!this->jump(LabelEnd))
531
0
      return false;
532
533
0
    this->emitLabel(LabelTrue);
534
0
    this->emitConstBool(true, E);
535
0
    this->fallthrough(LabelEnd);
536
0
    this->emitLabel(LabelEnd);
537
538
0
  } else {
539
0
    assert(Op == BO_LAnd);
540
    // Logical AND.
541
    // Visit LHS. Only visit RHS if LHS was TRUE.
542
0
    LabelTy LabelFalse = this->getLabel();
543
0
    LabelTy LabelEnd = this->getLabel();
544
545
0
    if (!this->visitBool(LHS))
546
0
      return false;
547
0
    if (!this->jumpFalse(LabelFalse))
548
0
      return false;
549
550
0
    if (!this->visitBool(RHS))
551
0
      return false;
552
0
    if (!this->jump(LabelEnd))
553
0
      return false;
554
555
0
    this->emitLabel(LabelFalse);
556
0
    this->emitConstBool(false, E);
557
0
    this->fallthrough(LabelEnd);
558
0
    this->emitLabel(LabelEnd);
559
0
  }
560
561
0
  if (DiscardResult)
562
0
    return this->emitPopBool(E);
563
564
  // For C, cast back to integer type.
565
0
  assert(T);
566
0
  if (T != PT_Bool)
567
0
    return this->emitCast(PT_Bool, *T, E);
568
0
  return true;
569
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitLogicalBinOp(clang::BinaryOperator const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitLogicalBinOp(clang::BinaryOperator const*)
570
571
template <class Emitter>
572
0
bool ByteCodeExprGen<Emitter>::VisitComplexBinOp(const BinaryOperator *E) {
573
0
  assert(Initializing);
574
575
0
  const Expr *LHS = E->getLHS();
576
0
  const Expr *RHS = E->getRHS();
577
0
  PrimType LHSElemT = *this->classifyComplexElementType(LHS->getType());
578
0
  PrimType RHSElemT = *this->classifyComplexElementType(RHS->getType());
579
580
0
  unsigned LHSOffset = this->allocateLocalPrimitive(LHS, PT_Ptr, true, false);
581
0
  unsigned RHSOffset = this->allocateLocalPrimitive(RHS, PT_Ptr, true, false);
582
0
  unsigned ResultOffset = ~0u;
583
0
  if (!this->DiscardResult)
584
0
    ResultOffset = this->allocateLocalPrimitive(E, PT_Ptr, true, false);
585
586
0
  assert(LHSElemT == RHSElemT);
587
588
  // Save result pointer in ResultOffset
589
0
  if (!this->DiscardResult) {
590
0
    if (!this->emitDupPtr(E))
591
0
      return false;
592
0
    if (!this->emitSetLocal(PT_Ptr, ResultOffset, E))
593
0
      return false;
594
0
  }
595
596
  // Evaluate LHS and save value to LHSOffset.
597
0
  if (!this->visit(LHS))
598
0
    return false;
599
0
  if (!this->emitSetLocal(PT_Ptr, LHSOffset, E))
600
0
    return false;
601
602
  // Same with RHS.
603
0
  if (!this->visit(RHS))
604
0
    return false;
605
0
  if (!this->emitSetLocal(PT_Ptr, RHSOffset, E))
606
0
    return false;
607
608
  // Now we can get pointers to the LHS and RHS from the offsets above.
609
0
  BinaryOperatorKind Op = E->getOpcode();
610
0
  for (unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
611
    // Result pointer for the store later.
612
0
    if (!this->DiscardResult) {
613
0
      if (!this->emitGetLocal(PT_Ptr, ResultOffset, E))
614
0
        return false;
615
0
    }
616
617
0
    if (!this->emitGetLocal(PT_Ptr, LHSOffset, E))
618
0
      return false;
619
0
    if (!this->emitConstUint8(ElemIndex, E))
620
0
      return false;
621
0
    if (!this->emitArrayElemPtrPopUint8(E))
622
0
      return false;
623
0
    if (!this->emitLoadPop(LHSElemT, E))
624
0
      return false;
625
626
0
    if (!this->emitGetLocal(PT_Ptr, RHSOffset, E))
627
0
      return false;
628
0
    if (!this->emitConstUint8(ElemIndex, E))
629
0
      return false;
630
0
    if (!this->emitArrayElemPtrPopUint8(E))
631
0
      return false;
632
0
    if (!this->emitLoadPop(RHSElemT, E))
633
0
      return false;
634
635
    // The actual operation.
636
0
    switch (Op) {
637
0
    case BO_Add:
638
0
      if (LHSElemT == PT_Float) {
639
0
        if (!this->emitAddf(getRoundingMode(E), E))
640
0
          return false;
641
0
      } else {
642
0
        if (!this->emitAdd(LHSElemT, E))
643
0
          return false;
644
0
      }
645
0
      break;
646
0
    case BO_Sub:
647
0
      if (LHSElemT == PT_Float) {
648
0
        if (!this->emitSubf(getRoundingMode(E), E))
649
0
          return false;
650
0
      } else {
651
0
        if (!this->emitSub(LHSElemT, E))
652
0
          return false;
653
0
      }
654
0
      break;
655
656
0
    default:
657
0
      return false;
658
0
    }
659
660
0
    if (!this->DiscardResult) {
661
      // Initialize array element with the value we just computed.
662
0
      if (!this->emitInitElemPop(LHSElemT, ElemIndex, E))
663
0
        return false;
664
0
    } else {
665
0
      if (!this->emitPop(LHSElemT, E))
666
0
        return false;
667
0
    }
668
0
  }
669
0
  return true;
670
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitComplexBinOp(clang::BinaryOperator const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitComplexBinOp(clang::BinaryOperator const*)
671
672
template <class Emitter>
673
0
bool ByteCodeExprGen<Emitter>::VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
674
0
  QualType QT = E->getType();
675
676
0
  if (std::optional<PrimType> T = classify(QT))
677
0
    return this->visitZeroInitializer(*T, QT, E);
678
679
0
  if (QT->isRecordType())
680
0
    return false;
681
682
0
  if (QT->isIncompleteArrayType())
683
0
    return true;
684
685
0
  if (QT->isArrayType()) {
686
0
    const ArrayType *AT = QT->getAsArrayTypeUnsafe();
687
0
    assert(AT);
688
0
    const auto *CAT = cast<ConstantArrayType>(AT);
689
0
    size_t NumElems = CAT->getSize().getZExtValue();
690
0
    PrimType ElemT = classifyPrim(CAT->getElementType());
691
692
0
    for (size_t I = 0; I != NumElems; ++I) {
693
0
      if (!this->visitZeroInitializer(ElemT, CAT->getElementType(), E))
694
0
        return false;
695
0
      if (!this->emitInitElem(ElemT, I, E))
696
0
        return false;
697
0
    }
698
699
0
    return true;
700
0
  }
701
702
0
  return false;
703
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitImplicitValueInitExpr(clang::ImplicitValueInitExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitImplicitValueInitExpr(clang::ImplicitValueInitExpr const*)
704
705
template <class Emitter>
706
bool ByteCodeExprGen<Emitter>::VisitArraySubscriptExpr(
707
0
    const ArraySubscriptExpr *E) {
708
0
  const Expr *Base = E->getBase();
709
0
  const Expr *Index = E->getIdx();
710
711
0
  if (DiscardResult)
712
0
    return this->discard(Base) && this->discard(Index);
713
714
  // Take pointer of LHS, add offset from RHS.
715
  // What's left on the stack after this is a pointer.
716
0
  if (!this->visit(Base))
717
0
    return false;
718
719
0
  if (!this->visit(Index))
720
0
    return false;
721
722
0
  PrimType IndexT = classifyPrim(Index->getType());
723
0
  return this->emitArrayElemPtrPop(IndexT, E);
724
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitArraySubscriptExpr(clang::ArraySubscriptExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitArraySubscriptExpr(clang::ArraySubscriptExpr const*)
725
726
template <class Emitter>
727
bool ByteCodeExprGen<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
728
0
                                             const Expr *E) {
729
0
  assert(E->getType()->isRecordType());
730
0
  const Record *R = getRecord(E->getType());
731
732
0
  unsigned InitIndex = 0;
733
0
  for (const Expr *Init : Inits) {
734
0
    if (!this->emitDupPtr(E))
735
0
      return false;
736
737
0
    if (std::optional<PrimType> T = classify(Init)) {
738
0
      const Record::Field *FieldToInit = R->getField(InitIndex);
739
0
      if (!this->visit(Init))
740
0
        return false;
741
742
0
      if (FieldToInit->isBitField()) {
743
0
        if (!this->emitInitBitField(*T, FieldToInit, E))
744
0
          return false;
745
0
      } else {
746
0
        if (!this->emitInitField(*T, FieldToInit->Offset, E))
747
0
          return false;
748
0
      }
749
750
0
      if (!this->emitPopPtr(E))
751
0
        return false;
752
0
      ++InitIndex;
753
0
    } else {
754
      // Initializer for a direct base class.
755
0
      if (const Record::Base *B = R->getBase(Init->getType())) {
756
0
        if (!this->emitGetPtrBasePop(B->Offset, Init))
757
0
          return false;
758
759
0
        if (!this->visitInitializer(Init))
760
0
          return false;
761
762
0
        if (!this->emitInitPtrPop(E))
763
0
          return false;
764
        // Base initializers don't increase InitIndex, since they don't count
765
        // into the Record's fields.
766
0
      } else {
767
0
        const Record::Field *FieldToInit = R->getField(InitIndex);
768
        // Non-primitive case. Get a pointer to the field-to-initialize
769
        // on the stack and recurse into visitInitializer().
770
0
        if (!this->emitGetPtrField(FieldToInit->Offset, Init))
771
0
          return false;
772
773
0
        if (!this->visitInitializer(Init))
774
0
          return false;
775
776
0
        if (!this->emitPopPtr(E))
777
0
          return false;
778
0
        ++InitIndex;
779
0
      }
780
0
    }
781
0
  }
782
0
  return true;
783
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::visitInitList(llvm::ArrayRef<clang::Expr const*>, clang::Expr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::visitInitList(llvm::ArrayRef<clang::Expr const*>, clang::Expr const*)
784
785
/// Pointer to the array(not the element!) must be on the stack when calling
786
/// this.
787
template <class Emitter>
788
bool ByteCodeExprGen<Emitter>::visitArrayElemInit(unsigned ElemIndex,
789
0
                                                  const Expr *Init) {
790
0
  if (std::optional<PrimType> T = classify(Init->getType())) {
791
    // Visit the primitive element like normal.
792
0
    if (!this->visit(Init))
793
0
      return false;
794
0
    return this->emitInitElem(*T, ElemIndex, Init);
795
0
  }
796
797
  // Advance the pointer currently on the stack to the given
798
  // dimension.
799
0
  if (!this->emitConstUint32(ElemIndex, Init))
800
0
    return false;
801
0
  if (!this->emitArrayElemPtrUint32(Init))
802
0
    return false;
803
0
  if (!this->visitInitializer(Init))
804
0
    return false;
805
0
  return this->emitPopPtr(Init);
806
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::visitArrayElemInit(unsigned int, clang::Expr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::visitArrayElemInit(unsigned int, clang::Expr const*)
807
808
template <class Emitter>
809
0
bool ByteCodeExprGen<Emitter>::VisitInitListExpr(const InitListExpr *E) {
810
  // Handle discarding first.
811
0
  if (DiscardResult) {
812
0
    for (const Expr *Init : E->inits()) {
813
0
      if (!this->discard(Init))
814
0
        return false;
815
0
    }
816
0
    return true;
817
0
  }
818
819
  // Primitive values.
820
0
  if (std::optional<PrimType> T = classify(E->getType())) {
821
0
    assert(!DiscardResult);
822
0
    if (E->getNumInits() == 0)
823
0
      return this->visitZeroInitializer(*T, E->getType(), E);
824
0
    assert(E->getNumInits() == 1);
825
0
    return this->delegate(E->inits()[0]);
826
0
  }
827
828
0
  QualType T = E->getType();
829
0
  if (T->isRecordType())
830
0
    return this->visitInitList(E->inits(), E);
831
832
0
  if (T->isArrayType()) {
833
    // FIXME: Array fillers.
834
0
    unsigned ElementIndex = 0;
835
0
    for (const Expr *Init : E->inits()) {
836
0
      if (!this->visitArrayElemInit(ElementIndex, Init))
837
0
        return false;
838
0
      ++ElementIndex;
839
0
    }
840
0
    return true;
841
0
  }
842
843
0
  if (T->isAnyComplexType()) {
844
0
    unsigned NumInits = E->getNumInits();
845
0
    QualType ElemQT = E->getType()->getAs<ComplexType>()->getElementType();
846
0
    PrimType ElemT = classifyPrim(ElemQT);
847
0
    if (NumInits == 0) {
848
      // Zero-initialize both elements.
849
0
      for (unsigned I = 0; I < 2; ++I) {
850
0
        if (!this->visitZeroInitializer(ElemT, ElemQT, E))
851
0
          return false;
852
0
        if (!this->emitInitElem(ElemT, I, E))
853
0
          return false;
854
0
      }
855
0
    } else if (NumInits == 2) {
856
0
      unsigned InitIndex = 0;
857
0
      for (const Expr *Init : E->inits()) {
858
0
        if (!this->visit(Init))
859
0
          return false;
860
861
0
        if (!this->emitInitElem(ElemT, InitIndex, E))
862
0
          return false;
863
0
        ++InitIndex;
864
0
      }
865
0
    }
866
0
    return true;
867
0
  }
868
869
0
  return false;
870
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitInitListExpr(clang::InitListExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitInitListExpr(clang::InitListExpr const*)
871
872
template <class Emitter>
873
bool ByteCodeExprGen<Emitter>::VisitCXXParenListInitExpr(
874
0
    const CXXParenListInitExpr *E) {
875
0
  if (DiscardResult) {
876
0
    for (const Expr *Init : E->getInitExprs()) {
877
0
      if (!this->discard(Init))
878
0
        return false;
879
0
    }
880
0
    return true;
881
0
  }
882
883
0
  assert(E->getType()->isRecordType());
884
0
  return this->visitInitList(E->getInitExprs(), E);
885
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitCXXParenListInitExpr(clang::CXXParenListInitExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitCXXParenListInitExpr(clang::CXXParenListInitExpr const*)
886
887
template <class Emitter>
888
bool ByteCodeExprGen<Emitter>::VisitSubstNonTypeTemplateParmExpr(
889
0
    const SubstNonTypeTemplateParmExpr *E) {
890
0
  return this->delegate(E->getReplacement());
891
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitSubstNonTypeTemplateParmExpr(clang::SubstNonTypeTemplateParmExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitSubstNonTypeTemplateParmExpr(clang::SubstNonTypeTemplateParmExpr const*)
892
893
template <class Emitter>
894
0
bool ByteCodeExprGen<Emitter>::VisitConstantExpr(const ConstantExpr *E) {
895
  // Try to emit the APValue directly, without visiting the subexpr.
896
  // This will only fail if we can't emit the APValue, so won't emit any
897
  // diagnostics or any double values.
898
0
  std::optional<PrimType> T = classify(E->getType());
899
0
  if (T && E->hasAPValueResult() &&
900
0
      this->visitAPValue(E->getAPValueResult(), *T, E))
901
0
    return true;
902
903
0
  return this->delegate(E->getSubExpr());
904
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitConstantExpr(clang::ConstantExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitConstantExpr(clang::ConstantExpr const*)
905
906
static CharUnits AlignOfType(QualType T, const ASTContext &ASTCtx,
907
0
                             UnaryExprOrTypeTrait Kind) {
908
0
  bool AlignOfReturnsPreferred =
909
0
      ASTCtx.getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
910
911
  // C++ [expr.alignof]p3:
912
  //     When alignof is applied to a reference type, the result is the
913
  //     alignment of the referenced type.
914
0
  if (const auto *Ref = T->getAs<ReferenceType>())
915
0
    T = Ref->getPointeeType();
916
917
  // __alignof is defined to return the preferred alignment.
918
  // Before 8, clang returned the preferred alignment for alignof and
919
  // _Alignof as well.
920
0
  if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
921
0
    return ASTCtx.toCharUnitsFromBits(ASTCtx.getPreferredTypeAlign(T));
922
923
0
  return ASTCtx.getTypeAlignInChars(T);
924
0
}
925
926
template <class Emitter>
927
bool ByteCodeExprGen<Emitter>::VisitUnaryExprOrTypeTraitExpr(
928
0
    const UnaryExprOrTypeTraitExpr *E) {
929
0
  UnaryExprOrTypeTrait Kind = E->getKind();
930
0
  ASTContext &ASTCtx = Ctx.getASTContext();
931
932
0
  if (Kind == UETT_SizeOf) {
933
0
    QualType ArgType = E->getTypeOfArgument();
934
0
    CharUnits Size;
935
0
    if (ArgType->isVoidType() || ArgType->isFunctionType())
936
0
      Size = CharUnits::One();
937
0
    else {
938
0
      if (ArgType->isDependentType() || !ArgType->isConstantSizeType())
939
0
        return false;
940
941
0
      Size = ASTCtx.getTypeSizeInChars(ArgType);
942
0
    }
943
944
0
    if (DiscardResult)
945
0
      return true;
946
947
0
    return this->emitConst(Size.getQuantity(), E);
948
0
  }
949
950
0
  if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) {
951
0
    CharUnits Size;
952
953
0
    if (E->isArgumentType()) {
954
0
      QualType ArgType = E->getTypeOfArgument();
955
956
0
      Size = AlignOfType(ArgType, ASTCtx, Kind);
957
0
    } else {
958
      // Argument is an expression, not a type.
959
0
      const Expr *Arg = E->getArgumentExpr()->IgnoreParens();
960
961
      // The kinds of expressions that we have special-case logic here for
962
      // should be kept up to date with the special checks for those
963
      // expressions in Sema.
964
965
      // alignof decl is always accepted, even if it doesn't make sense: we
966
      // default to 1 in those cases.
967
0
      if (const auto *DRE = dyn_cast<DeclRefExpr>(Arg))
968
0
        Size = ASTCtx.getDeclAlign(DRE->getDecl(),
969
0
                                   /*RefAsPointee*/ true);
970
0
      else if (const auto *ME = dyn_cast<MemberExpr>(Arg))
971
0
        Size = ASTCtx.getDeclAlign(ME->getMemberDecl(),
972
0
                                   /*RefAsPointee*/ true);
973
0
      else
974
0
        Size = AlignOfType(Arg->getType(), ASTCtx, Kind);
975
0
    }
976
977
0
    if (DiscardResult)
978
0
      return true;
979
980
0
    return this->emitConst(Size.getQuantity(), E);
981
0
  }
982
983
0
  return false;
984
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitUnaryExprOrTypeTraitExpr(clang::UnaryExprOrTypeTraitExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitUnaryExprOrTypeTraitExpr(clang::UnaryExprOrTypeTraitExpr const*)
985
986
template <class Emitter>
987
0
bool ByteCodeExprGen<Emitter>::VisitMemberExpr(const MemberExpr *E) {
988
  // 'Base.Member'
989
0
  const Expr *Base = E->getBase();
990
991
0
  if (DiscardResult)
992
0
    return this->discard(Base);
993
994
0
  if (!this->visit(Base))
995
0
    return false;
996
997
  // Base above gives us a pointer on the stack.
998
  // TODO: Implement non-FieldDecl members.
999
0
  const ValueDecl *Member = E->getMemberDecl();
1000
0
  if (const auto *FD = dyn_cast<FieldDecl>(Member)) {
1001
0
    const RecordDecl *RD = FD->getParent();
1002
0
    const Record *R = getRecord(RD);
1003
0
    const Record::Field *F = R->getField(FD);
1004
    // Leave a pointer to the field on the stack.
1005
0
    if (F->Decl->getType()->isReferenceType())
1006
0
      return this->emitGetFieldPop(PT_Ptr, F->Offset, E);
1007
0
    return this->emitGetPtrField(F->Offset, E);
1008
0
  }
1009
1010
0
  return false;
1011
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitMemberExpr(clang::MemberExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitMemberExpr(clang::MemberExpr const*)
1012
1013
template <class Emitter>
1014
bool ByteCodeExprGen<Emitter>::VisitArrayInitIndexExpr(
1015
0
    const ArrayInitIndexExpr *E) {
1016
  // ArrayIndex might not be set if a ArrayInitIndexExpr is being evaluated
1017
  // stand-alone, e.g. via EvaluateAsInt().
1018
0
  if (!ArrayIndex)
1019
0
    return false;
1020
0
  return this->emitConst(*ArrayIndex, E);
1021
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitArrayInitIndexExpr(clang::ArrayInitIndexExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitArrayInitIndexExpr(clang::ArrayInitIndexExpr const*)
1022
1023
template <class Emitter>
1024
bool ByteCodeExprGen<Emitter>::VisitArrayInitLoopExpr(
1025
0
    const ArrayInitLoopExpr *E) {
1026
0
  assert(Initializing);
1027
0
  assert(!DiscardResult);
1028
  // TODO: This compiles to quite a lot of bytecode if the array is larger.
1029
  //   Investigate compiling this to a loop.
1030
1031
0
  const Expr *SubExpr = E->getSubExpr();
1032
0
  const Expr *CommonExpr = E->getCommonExpr();
1033
0
  size_t Size = E->getArraySize().getZExtValue();
1034
1035
  // If the common expression is an opaque expression, we visit it
1036
  // here once so we have its value cached.
1037
  // FIXME: This might be necessary (or useful) for all expressions.
1038
0
  if (isa<OpaqueValueExpr>(CommonExpr)) {
1039
0
    if (!this->discard(CommonExpr))
1040
0
      return false;
1041
0
  }
1042
1043
  // So, every iteration, we execute an assignment here
1044
  // where the LHS is on the stack (the target array)
1045
  // and the RHS is our SubExpr.
1046
0
  for (size_t I = 0; I != Size; ++I) {
1047
0
    ArrayIndexScope<Emitter> IndexScope(this, I);
1048
0
    BlockScope<Emitter> BS(this);
1049
1050
0
    if (!this->visitArrayElemInit(I, SubExpr))
1051
0
      return false;
1052
0
  }
1053
0
  return true;
1054
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitArrayInitLoopExpr(clang::ArrayInitLoopExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitArrayInitLoopExpr(clang::ArrayInitLoopExpr const*)
1055
1056
template <class Emitter>
1057
0
bool ByteCodeExprGen<Emitter>::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
1058
0
  if (Initializing)
1059
0
    return this->visitInitializer(E->getSourceExpr());
1060
1061
0
  PrimType SubExprT = classify(E->getSourceExpr()).value_or(PT_Ptr);
1062
0
  if (auto It = OpaqueExprs.find(E); It != OpaqueExprs.end())
1063
0
    return this->emitGetLocal(SubExprT, It->second, E);
1064
1065
0
  if (!this->visit(E->getSourceExpr()))
1066
0
    return false;
1067
1068
  // At this point we either have the evaluated source expression or a pointer
1069
  // to an object on the stack. We want to create a local variable that stores
1070
  // this value.
1071
0
  std::optional<unsigned> LocalIndex =
1072
0
      allocateLocalPrimitive(E, SubExprT, /*IsConst=*/true);
1073
0
  if (!LocalIndex)
1074
0
    return false;
1075
0
  if (!this->emitSetLocal(SubExprT, *LocalIndex, E))
1076
0
    return false;
1077
1078
  // Here the local variable is created but the value is removed from the stack,
1079
  // so we put it back, because the caller might need it.
1080
0
  if (!DiscardResult) {
1081
0
    if (!this->emitGetLocal(SubExprT, *LocalIndex, E))
1082
0
      return false;
1083
0
  }
1084
1085
  // FIXME: Ideally the cached value should be cleaned up later.
1086
0
  OpaqueExprs.insert({E, *LocalIndex});
1087
1088
0
  return true;
1089
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitOpaqueValueExpr(clang::OpaqueValueExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitOpaqueValueExpr(clang::OpaqueValueExpr const*)
1090
1091
template <class Emitter>
1092
bool ByteCodeExprGen<Emitter>::VisitAbstractConditionalOperator(
1093
0
    const AbstractConditionalOperator *E) {
1094
0
  const Expr *Condition = E->getCond();
1095
0
  const Expr *TrueExpr = E->getTrueExpr();
1096
0
  const Expr *FalseExpr = E->getFalseExpr();
1097
1098
0
  LabelTy LabelEnd = this->getLabel();   // Label after the operator.
1099
0
  LabelTy LabelFalse = this->getLabel(); // Label for the false expr.
1100
1101
0
  if (!this->visitBool(Condition))
1102
0
    return false;
1103
1104
0
  if (!this->jumpFalse(LabelFalse))
1105
0
    return false;
1106
1107
0
  if (!this->delegate(TrueExpr))
1108
0
    return false;
1109
0
  if (!this->jump(LabelEnd))
1110
0
    return false;
1111
1112
0
  this->emitLabel(LabelFalse);
1113
1114
0
  if (!this->delegate(FalseExpr))
1115
0
    return false;
1116
1117
0
  this->fallthrough(LabelEnd);
1118
0
  this->emitLabel(LabelEnd);
1119
1120
0
  return true;
1121
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitAbstractConditionalOperator(clang::AbstractConditionalOperator const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitAbstractConditionalOperator(clang::AbstractConditionalOperator const*)
1122
1123
template <class Emitter>
1124
0
bool ByteCodeExprGen<Emitter>::VisitStringLiteral(const StringLiteral *E) {
1125
0
  if (DiscardResult)
1126
0
    return true;
1127
1128
0
  if (!Initializing) {
1129
0
    unsigned StringIndex = P.createGlobalString(E);
1130
0
    return this->emitGetPtrGlobal(StringIndex, E);
1131
0
  }
1132
1133
  // We are initializing an array on the stack.
1134
0
  const ConstantArrayType *CAT =
1135
0
      Ctx.getASTContext().getAsConstantArrayType(E->getType());
1136
0
  assert(CAT && "a string literal that's not a constant array?");
1137
1138
  // If the initializer string is too long, a diagnostic has already been
1139
  // emitted. Read only the array length from the string literal.
1140
0
  unsigned ArraySize = CAT->getSize().getZExtValue();
1141
0
  unsigned N = std::min(ArraySize, E->getLength());
1142
0
  size_t CharWidth = E->getCharByteWidth();
1143
1144
0
  for (unsigned I = 0; I != N; ++I) {
1145
0
    uint32_t CodeUnit = E->getCodeUnit(I);
1146
1147
0
    if (CharWidth == 1) {
1148
0
      this->emitConstSint8(CodeUnit, E);
1149
0
      this->emitInitElemSint8(I, E);
1150
0
    } else if (CharWidth == 2) {
1151
0
      this->emitConstUint16(CodeUnit, E);
1152
0
      this->emitInitElemUint16(I, E);
1153
0
    } else if (CharWidth == 4) {
1154
0
      this->emitConstUint32(CodeUnit, E);
1155
0
      this->emitInitElemUint32(I, E);
1156
0
    } else {
1157
0
      llvm_unreachable("unsupported character width");
1158
0
    }
1159
0
  }
1160
1161
  // Fill up the rest of the char array with NUL bytes.
1162
0
  for (unsigned I = N; I != ArraySize; ++I) {
1163
0
    if (CharWidth == 1) {
1164
0
      this->emitConstSint8(0, E);
1165
0
      this->emitInitElemSint8(I, E);
1166
0
    } else if (CharWidth == 2) {
1167
0
      this->emitConstUint16(0, E);
1168
0
      this->emitInitElemUint16(I, E);
1169
0
    } else if (CharWidth == 4) {
1170
0
      this->emitConstUint32(0, E);
1171
0
      this->emitInitElemUint32(I, E);
1172
0
    } else {
1173
0
      llvm_unreachable("unsupported character width");
1174
0
    }
1175
0
  }
1176
1177
0
  return true;
1178
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitStringLiteral(clang::StringLiteral const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitStringLiteral(clang::StringLiteral const*)
1179
1180
template <class Emitter>
1181
bool ByteCodeExprGen<Emitter>::VisitCharacterLiteral(
1182
0
    const CharacterLiteral *E) {
1183
0
  if (DiscardResult)
1184
0
    return true;
1185
0
  return this->emitConst(E->getValue(), E);
1186
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitCharacterLiteral(clang::CharacterLiteral const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitCharacterLiteral(clang::CharacterLiteral const*)
1187
1188
template <class Emitter>
1189
bool ByteCodeExprGen<Emitter>::VisitFloatCompoundAssignOperator(
1190
0
    const CompoundAssignOperator *E) {
1191
1192
0
  const Expr *LHS = E->getLHS();
1193
0
  const Expr *RHS = E->getRHS();
1194
0
  QualType LHSType = LHS->getType();
1195
0
  QualType LHSComputationType = E->getComputationLHSType();
1196
0
  QualType ResultType = E->getComputationResultType();
1197
0
  std::optional<PrimType> LT = classify(LHSComputationType);
1198
0
  std::optional<PrimType> RT = classify(ResultType);
1199
1200
0
  assert(ResultType->isFloatingType());
1201
1202
0
  if (!LT || !RT)
1203
0
    return false;
1204
1205
0
  PrimType LHST = classifyPrim(LHSType);
1206
1207
  // C++17 onwards require that we evaluate the RHS first.
1208
  // Compute RHS and save it in a temporary variable so we can
1209
  // load it again later.
1210
0
  if (!visit(RHS))
1211
0
    return false;
1212
1213
0
  unsigned TempOffset = this->allocateLocalPrimitive(E, *RT, /*IsConst=*/true);
1214
0
  if (!this->emitSetLocal(*RT, TempOffset, E))
1215
0
    return false;
1216
1217
  // First, visit LHS.
1218
0
  if (!visit(LHS))
1219
0
    return false;
1220
0
  if (!this->emitLoad(LHST, E))
1221
0
    return false;
1222
1223
  // If necessary, convert LHS to its computation type.
1224
0
  if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType),
1225
0
                          LHSComputationType, E))
1226
0
    return false;
1227
1228
  // Now load RHS.
1229
0
  if (!this->emitGetLocal(*RT, TempOffset, E))
1230
0
    return false;
1231
1232
0
  llvm::RoundingMode RM = getRoundingMode(E);
1233
0
  switch (E->getOpcode()) {
1234
0
  case BO_AddAssign:
1235
0
    if (!this->emitAddf(RM, E))
1236
0
      return false;
1237
0
    break;
1238
0
  case BO_SubAssign:
1239
0
    if (!this->emitSubf(RM, E))
1240
0
      return false;
1241
0
    break;
1242
0
  case BO_MulAssign:
1243
0
    if (!this->emitMulf(RM, E))
1244
0
      return false;
1245
0
    break;
1246
0
  case BO_DivAssign:
1247
0
    if (!this->emitDivf(RM, E))
1248
0
      return false;
1249
0
    break;
1250
0
  default:
1251
0
    return false;
1252
0
  }
1253
1254
0
  if (!this->emitPrimCast(classifyPrim(ResultType), LHST, LHS->getType(), E))
1255
0
    return false;
1256
1257
0
  if (DiscardResult)
1258
0
    return this->emitStorePop(LHST, E);
1259
0
  return this->emitStore(LHST, E);
1260
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitFloatCompoundAssignOperator(clang::CompoundAssignOperator const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitFloatCompoundAssignOperator(clang::CompoundAssignOperator const*)
1261
1262
template <class Emitter>
1263
bool ByteCodeExprGen<Emitter>::VisitPointerCompoundAssignOperator(
1264
0
    const CompoundAssignOperator *E) {
1265
0
  BinaryOperatorKind Op = E->getOpcode();
1266
0
  const Expr *LHS = E->getLHS();
1267
0
  const Expr *RHS = E->getRHS();
1268
0
  std::optional<PrimType> LT = classify(LHS->getType());
1269
0
  std::optional<PrimType> RT = classify(RHS->getType());
1270
1271
0
  if (Op != BO_AddAssign && Op != BO_SubAssign)
1272
0
    return false;
1273
1274
0
  if (!LT || !RT)
1275
0
    return false;
1276
0
  assert(*LT == PT_Ptr);
1277
1278
0
  if (!visit(LHS))
1279
0
    return false;
1280
1281
0
  if (!this->emitLoadPtr(LHS))
1282
0
    return false;
1283
1284
0
  if (!visit(RHS))
1285
0
    return false;
1286
1287
0
  if (Op == BO_AddAssign)
1288
0
    this->emitAddOffset(*RT, E);
1289
0
  else
1290
0
    this->emitSubOffset(*RT, E);
1291
1292
0
  if (DiscardResult)
1293
0
    return this->emitStorePopPtr(E);
1294
0
  return this->emitStorePtr(E);
1295
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitPointerCompoundAssignOperator(clang::CompoundAssignOperator const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitPointerCompoundAssignOperator(clang::CompoundAssignOperator const*)
1296
1297
template <class Emitter>
1298
bool ByteCodeExprGen<Emitter>::VisitCompoundAssignOperator(
1299
0
    const CompoundAssignOperator *E) {
1300
1301
0
  const Expr *LHS = E->getLHS();
1302
0
  const Expr *RHS = E->getRHS();
1303
0
  std::optional<PrimType> LHSComputationT =
1304
0
      classify(E->getComputationLHSType());
1305
0
  std::optional<PrimType> LT = classify(LHS->getType());
1306
0
  std::optional<PrimType> RT = classify(E->getComputationResultType());
1307
0
  std::optional<PrimType> ResultT = classify(E->getType());
1308
1309
0
  if (!LT || !RT || !ResultT || !LHSComputationT)
1310
0
    return false;
1311
1312
  // Handle floating point operations separately here, since they
1313
  // require special care.
1314
1315
0
  if (ResultT == PT_Float || RT == PT_Float)
1316
0
    return VisitFloatCompoundAssignOperator(E);
1317
1318
0
  if (E->getType()->isPointerType())
1319
0
    return VisitPointerCompoundAssignOperator(E);
1320
1321
0
  assert(!E->getType()->isPointerType() && "Handled above");
1322
0
  assert(!E->getType()->isFloatingType() && "Handled above");
1323
1324
  // C++17 onwards require that we evaluate the RHS first.
1325
  // Compute RHS and save it in a temporary variable so we can
1326
  // load it again later.
1327
  // FIXME: Compound assignments are unsequenced in C, so we might
1328
  //   have to figure out how to reject them.
1329
0
  if (!visit(RHS))
1330
0
    return false;
1331
1332
0
  unsigned TempOffset = this->allocateLocalPrimitive(E, *RT, /*IsConst=*/true);
1333
1334
0
  if (!this->emitSetLocal(*RT, TempOffset, E))
1335
0
    return false;
1336
1337
  // Get LHS pointer, load its value and cast it to the
1338
  // computation type if necessary.
1339
0
  if (!visit(LHS))
1340
0
    return false;
1341
0
  if (!this->emitLoad(*LT, E))
1342
0
    return false;
1343
0
  if (*LT != *LHSComputationT) {
1344
0
    if (!this->emitCast(*LT, *LHSComputationT, E))
1345
0
      return false;
1346
0
  }
1347
1348
  // Get the RHS value on the stack.
1349
0
  if (!this->emitGetLocal(*RT, TempOffset, E))
1350
0
    return false;
1351
1352
  // Perform operation.
1353
0
  switch (E->getOpcode()) {
1354
0
  case BO_AddAssign:
1355
0
    if (!this->emitAdd(*LHSComputationT, E))
1356
0
      return false;
1357
0
    break;
1358
0
  case BO_SubAssign:
1359
0
    if (!this->emitSub(*LHSComputationT, E))
1360
0
      return false;
1361
0
    break;
1362
0
  case BO_MulAssign:
1363
0
    if (!this->emitMul(*LHSComputationT, E))
1364
0
      return false;
1365
0
    break;
1366
0
  case BO_DivAssign:
1367
0
    if (!this->emitDiv(*LHSComputationT, E))
1368
0
      return false;
1369
0
    break;
1370
0
  case BO_RemAssign:
1371
0
    if (!this->emitRem(*LHSComputationT, E))
1372
0
      return false;
1373
0
    break;
1374
0
  case BO_ShlAssign:
1375
0
    if (!this->emitShl(*LHSComputationT, *RT, E))
1376
0
      return false;
1377
0
    break;
1378
0
  case BO_ShrAssign:
1379
0
    if (!this->emitShr(*LHSComputationT, *RT, E))
1380
0
      return false;
1381
0
    break;
1382
0
  case BO_AndAssign:
1383
0
    if (!this->emitBitAnd(*LHSComputationT, E))
1384
0
      return false;
1385
0
    break;
1386
0
  case BO_XorAssign:
1387
0
    if (!this->emitBitXor(*LHSComputationT, E))
1388
0
      return false;
1389
0
    break;
1390
0
  case BO_OrAssign:
1391
0
    if (!this->emitBitOr(*LHSComputationT, E))
1392
0
      return false;
1393
0
    break;
1394
0
  default:
1395
0
    llvm_unreachable("Unimplemented compound assign operator");
1396
0
  }
1397
1398
  // And now cast from LHSComputationT to ResultT.
1399
0
  if (*ResultT != *LHSComputationT) {
1400
0
    if (!this->emitCast(*LHSComputationT, *ResultT, E))
1401
0
      return false;
1402
0
  }
1403
1404
  // And store the result in LHS.
1405
0
  if (DiscardResult) {
1406
0
    if (LHS->refersToBitField())
1407
0
      return this->emitStoreBitFieldPop(*ResultT, E);
1408
0
    return this->emitStorePop(*ResultT, E);
1409
0
  }
1410
0
  if (LHS->refersToBitField())
1411
0
    return this->emitStoreBitField(*ResultT, E);
1412
0
  return this->emitStore(*ResultT, E);
1413
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitCompoundAssignOperator(clang::CompoundAssignOperator const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitCompoundAssignOperator(clang::CompoundAssignOperator const*)
1414
1415
template <class Emitter>
1416
bool ByteCodeExprGen<Emitter>::VisitExprWithCleanups(
1417
0
    const ExprWithCleanups *E) {
1418
0
  const Expr *SubExpr = E->getSubExpr();
1419
1420
0
  assert(E->getNumObjects() == 0 && "TODO: Implement cleanups");
1421
1422
0
  return this->delegate(SubExpr);
1423
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitExprWithCleanups(clang::ExprWithCleanups const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitExprWithCleanups(clang::ExprWithCleanups const*)
1424
1425
template <class Emitter>
1426
bool ByteCodeExprGen<Emitter>::VisitMaterializeTemporaryExpr(
1427
0
    const MaterializeTemporaryExpr *E) {
1428
0
  const Expr *SubExpr = E->getSubExpr();
1429
1430
0
  if (Initializing) {
1431
    // We already have a value, just initialize that.
1432
0
    return this->visitInitializer(SubExpr);
1433
0
  }
1434
  // If we don't end up using the materialized temporary anyway, don't
1435
  // bother creating it.
1436
0
  if (DiscardResult)
1437
0
    return this->discard(SubExpr);
1438
1439
  // When we're initializing a global variable *or* the storage duration of
1440
  // the temporary is explicitly static, create a global variable.
1441
0
  std::optional<PrimType> SubExprT = classify(SubExpr);
1442
0
  bool IsStatic = E->getStorageDuration() == SD_Static;
1443
0
  if (GlobalDecl || IsStatic) {
1444
0
    std::optional<unsigned> GlobalIndex = P.createGlobal(E);
1445
0
    if (!GlobalIndex)
1446
0
      return false;
1447
1448
0
    const LifetimeExtendedTemporaryDecl *TempDecl =
1449
0
        E->getLifetimeExtendedTemporaryDecl();
1450
0
    if (IsStatic)
1451
0
      assert(TempDecl);
1452
1453
0
    if (SubExprT) {
1454
0
      if (!this->visit(SubExpr))
1455
0
        return false;
1456
0
      if (IsStatic) {
1457
0
        if (!this->emitInitGlobalTemp(*SubExprT, *GlobalIndex, TempDecl, E))
1458
0
          return false;
1459
0
      } else {
1460
0
        if (!this->emitInitGlobal(*SubExprT, *GlobalIndex, E))
1461
0
          return false;
1462
0
      }
1463
0
      return this->emitGetPtrGlobal(*GlobalIndex, E);
1464
0
    }
1465
1466
    // Non-primitive values.
1467
0
    if (!this->emitGetPtrGlobal(*GlobalIndex, E))
1468
0
      return false;
1469
0
    if (!this->visitInitializer(SubExpr))
1470
0
      return false;
1471
0
    if (IsStatic)
1472
0
      return this->emitInitGlobalTempComp(TempDecl, E);
1473
0
    return true;
1474
0
  }
1475
1476
  // For everyhing else, use local variables.
1477
0
  if (SubExprT) {
1478
0
    if (std::optional<unsigned> LocalIndex = allocateLocalPrimitive(
1479
0
            SubExpr, *SubExprT, /*IsConst=*/true, /*IsExtended=*/true)) {
1480
0
      if (!this->visit(SubExpr))
1481
0
        return false;
1482
0
      this->emitSetLocal(*SubExprT, *LocalIndex, E);
1483
0
      return this->emitGetPtrLocal(*LocalIndex, E);
1484
0
    }
1485
0
  } else {
1486
0
    if (std::optional<unsigned> LocalIndex =
1487
0
            allocateLocal(SubExpr, /*IsExtended=*/true)) {
1488
0
      if (!this->emitGetPtrLocal(*LocalIndex, E))
1489
0
        return false;
1490
0
      return this->visitInitializer(SubExpr);
1491
0
    }
1492
0
  }
1493
0
  return false;
1494
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitMaterializeTemporaryExpr(clang::MaterializeTemporaryExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitMaterializeTemporaryExpr(clang::MaterializeTemporaryExpr const*)
1495
1496
template <class Emitter>
1497
bool ByteCodeExprGen<Emitter>::VisitCXXBindTemporaryExpr(
1498
0
    const CXXBindTemporaryExpr *E) {
1499
0
  return this->delegate(E->getSubExpr());
1500
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitCXXBindTemporaryExpr(clang::CXXBindTemporaryExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitCXXBindTemporaryExpr(clang::CXXBindTemporaryExpr const*)
1501
1502
template <class Emitter>
1503
bool ByteCodeExprGen<Emitter>::VisitCompoundLiteralExpr(
1504
0
    const CompoundLiteralExpr *E) {
1505
0
  const Expr *Init = E->getInitializer();
1506
0
  if (Initializing) {
1507
    // We already have a value, just initialize that.
1508
0
    return this->visitInitializer(Init);
1509
0
  }
1510
1511
0
  std::optional<PrimType> T = classify(E->getType());
1512
0
  if (E->isFileScope()) {
1513
0
    if (std::optional<unsigned> GlobalIndex = P.createGlobal(E)) {
1514
0
      if (classify(E->getType()))
1515
0
        return this->visit(Init);
1516
0
      if (!this->emitGetPtrGlobal(*GlobalIndex, E))
1517
0
        return false;
1518
0
      return this->visitInitializer(Init);
1519
0
    }
1520
0
  }
1521
1522
  // Otherwise, use a local variable.
1523
0
  if (T) {
1524
    // For primitive types, we just visit the initializer.
1525
0
    return this->delegate(Init);
1526
0
  } else {
1527
0
    if (std::optional<unsigned> LocalIndex = allocateLocal(Init)) {
1528
0
      if (!this->emitGetPtrLocal(*LocalIndex, E))
1529
0
        return false;
1530
0
      if (!this->visitInitializer(Init))
1531
0
        return false;
1532
0
      if (DiscardResult)
1533
0
        return this->emitPopPtr(E);
1534
0
      return true;
1535
0
    }
1536
0
  }
1537
1538
0
  return false;
1539
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitCompoundLiteralExpr(clang::CompoundLiteralExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitCompoundLiteralExpr(clang::CompoundLiteralExpr const*)
1540
1541
template <class Emitter>
1542
0
bool ByteCodeExprGen<Emitter>::VisitTypeTraitExpr(const TypeTraitExpr *E) {
1543
0
  if (DiscardResult)
1544
0
    return true;
1545
0
  return this->emitConstBool(E->getValue(), E);
1546
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitTypeTraitExpr(clang::TypeTraitExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitTypeTraitExpr(clang::TypeTraitExpr const*)
1547
1548
template <class Emitter>
1549
0
bool ByteCodeExprGen<Emitter>::VisitLambdaExpr(const LambdaExpr *E) {
1550
0
  assert(Initializing);
1551
0
  const Record *R = P.getOrCreateRecord(E->getLambdaClass());
1552
1553
0
  auto *CaptureInitIt = E->capture_init_begin();
1554
  // Initialize all fields (which represent lambda captures) of the
1555
  // record with their initializers.
1556
0
  for (const Record::Field &F : R->fields()) {
1557
0
    const Expr *Init = *CaptureInitIt;
1558
0
    ++CaptureInitIt;
1559
1560
0
    if (std::optional<PrimType> T = classify(Init)) {
1561
0
      if (!this->visit(Init))
1562
0
        return false;
1563
1564
0
      if (!this->emitSetField(*T, F.Offset, E))
1565
0
        return false;
1566
0
    } else {
1567
0
      if (!this->emitDupPtr(E))
1568
0
        return false;
1569
1570
0
      if (!this->emitGetPtrField(F.Offset, E))
1571
0
        return false;
1572
1573
0
      if (!this->visitInitializer(Init))
1574
0
        return false;
1575
1576
0
      if (!this->emitPopPtr(E))
1577
0
        return false;
1578
0
    }
1579
0
  }
1580
1581
0
  return true;
1582
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitLambdaExpr(clang::LambdaExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitLambdaExpr(clang::LambdaExpr const*)
1583
1584
template <class Emitter>
1585
0
bool ByteCodeExprGen<Emitter>::VisitPredefinedExpr(const PredefinedExpr *E) {
1586
0
  if (DiscardResult)
1587
0
    return true;
1588
1589
0
  assert(!Initializing);
1590
0
  return this->visit(E->getFunctionName());
1591
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitPredefinedExpr(clang::PredefinedExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitPredefinedExpr(clang::PredefinedExpr const*)
1592
1593
template <class Emitter>
1594
0
bool ByteCodeExprGen<Emitter>::VisitCXXThrowExpr(const CXXThrowExpr *E) {
1595
0
  if (E->getSubExpr() && !this->discard(E->getSubExpr()))
1596
0
    return false;
1597
1598
0
  return this->emitInvalid(E);
1599
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitCXXThrowExpr(clang::CXXThrowExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitCXXThrowExpr(clang::CXXThrowExpr const*)
1600
1601
template <class Emitter>
1602
bool ByteCodeExprGen<Emitter>::VisitCXXReinterpretCastExpr(
1603
0
    const CXXReinterpretCastExpr *E) {
1604
0
  if (!this->discard(E->getSubExpr()))
1605
0
    return false;
1606
1607
0
  return this->emitInvalidCast(CastKind::Reinterpret, E);
1608
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitCXXReinterpretCastExpr(clang::CXXReinterpretCastExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitCXXReinterpretCastExpr(clang::CXXReinterpretCastExpr const*)
1609
1610
template <class Emitter>
1611
0
bool ByteCodeExprGen<Emitter>::VisitCXXNoexceptExpr(const CXXNoexceptExpr *E) {
1612
0
  assert(E->getType()->isBooleanType());
1613
1614
0
  if (DiscardResult)
1615
0
    return true;
1616
0
  return this->emitConstBool(E->getValue(), E);
1617
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitCXXNoexceptExpr(clang::CXXNoexceptExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitCXXNoexceptExpr(clang::CXXNoexceptExpr const*)
1618
1619
template <class Emitter>
1620
bool ByteCodeExprGen<Emitter>::VisitCXXConstructExpr(
1621
0
    const CXXConstructExpr *E) {
1622
0
  QualType T = E->getType();
1623
0
  assert(!classify(T));
1624
1625
0
  if (T->isRecordType()) {
1626
0
    const CXXConstructorDecl *Ctor = E->getConstructor();
1627
1628
    // Trivial zero initialization.
1629
0
    if (E->requiresZeroInitialization() && Ctor->isTrivial()) {
1630
0
      const Record *R = getRecord(E->getType());
1631
0
      return this->visitZeroRecordInitializer(R, E);
1632
0
    }
1633
1634
0
    const Function *Func = getFunction(Ctor);
1635
1636
0
    if (!Func)
1637
0
      return false;
1638
1639
0
    assert(Func->hasThisPointer());
1640
0
    assert(!Func->hasRVO());
1641
1642
    // If we're discarding a construct expression, we still need
1643
    // to allocate a variable and call the constructor and destructor.
1644
0
    if (DiscardResult) {
1645
0
      assert(!Initializing);
1646
0
      std::optional<unsigned> LocalIndex =
1647
0
          allocateLocal(E, /*IsExtended=*/true);
1648
1649
0
      if (!LocalIndex)
1650
0
        return false;
1651
1652
0
      if (!this->emitGetPtrLocal(*LocalIndex, E))
1653
0
        return false;
1654
0
    }
1655
1656
    //  The This pointer is already on the stack because this is an initializer,
1657
    //  but we need to dup() so the call() below has its own copy.
1658
0
    if (!this->emitDupPtr(E))
1659
0
      return false;
1660
1661
    // Constructor arguments.
1662
0
    for (const auto *Arg : E->arguments()) {
1663
0
      if (!this->visit(Arg))
1664
0
        return false;
1665
0
    }
1666
1667
0
    if (!this->emitCall(Func, E))
1668
0
      return false;
1669
1670
    // Immediately call the destructor if we have to.
1671
0
    if (DiscardResult) {
1672
0
      if (!this->emitPopPtr(E))
1673
0
        return false;
1674
0
    }
1675
0
    return true;
1676
0
  }
1677
1678
0
  if (T->isArrayType()) {
1679
0
    const ConstantArrayType *CAT =
1680
0
        Ctx.getASTContext().getAsConstantArrayType(E->getType());
1681
0
    assert(CAT);
1682
0
    size_t NumElems = CAT->getSize().getZExtValue();
1683
0
    const Function *Func = getFunction(E->getConstructor());
1684
0
    if (!Func || !Func->isConstexpr())
1685
0
      return false;
1686
1687
    // FIXME(perf): We're calling the constructor once per array element here,
1688
    //   in the old intepreter we had a special-case for trivial constructors.
1689
0
    for (size_t I = 0; I != NumElems; ++I) {
1690
0
      if (!this->emitConstUint64(I, E))
1691
0
        return false;
1692
0
      if (!this->emitArrayElemPtrUint64(E))
1693
0
        return false;
1694
1695
      // Constructor arguments.
1696
0
      for (const auto *Arg : E->arguments()) {
1697
0
        if (!this->visit(Arg))
1698
0
          return false;
1699
0
      }
1700
1701
0
      if (!this->emitCall(Func, E))
1702
0
        return false;
1703
0
    }
1704
0
    return true;
1705
0
  }
1706
1707
0
  return false;
1708
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitCXXConstructExpr(clang::CXXConstructExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitCXXConstructExpr(clang::CXXConstructExpr const*)
1709
1710
template <class Emitter>
1711
0
bool ByteCodeExprGen<Emitter>::VisitSourceLocExpr(const SourceLocExpr *E) {
1712
0
  if (DiscardResult)
1713
0
    return true;
1714
1715
0
  const APValue Val =
1716
0
      E->EvaluateInContext(Ctx.getASTContext(), SourceLocDefaultExpr);
1717
1718
  // Things like __builtin_LINE().
1719
0
  if (E->getType()->isIntegerType()) {
1720
0
    assert(Val.isInt());
1721
0
    const APSInt &I = Val.getInt();
1722
0
    return this->emitConst(I, E);
1723
0
  }
1724
  // Otherwise, the APValue is an LValue, with only one element.
1725
  // Theoretically, we don't need the APValue at all of course.
1726
0
  assert(E->getType()->isPointerType());
1727
0
  assert(Val.isLValue());
1728
0
  const APValue::LValueBase &Base = Val.getLValueBase();
1729
0
  if (const Expr *LValueExpr = Base.dyn_cast<const Expr *>())
1730
0
    return this->visit(LValueExpr);
1731
1732
  // Otherwise, we have a decl (which is the case for
1733
  // __builtin_source_location).
1734
0
  assert(Base.is<const ValueDecl *>());
1735
0
  assert(Val.getLValuePath().size() == 0);
1736
0
  const auto *BaseDecl = Base.dyn_cast<const ValueDecl *>();
1737
0
  assert(BaseDecl);
1738
1739
0
  auto *UGCD = cast<UnnamedGlobalConstantDecl>(BaseDecl);
1740
1741
0
  std::optional<unsigned> GlobalIndex = P.getOrCreateGlobal(UGCD);
1742
0
  if (!GlobalIndex)
1743
0
    return false;
1744
1745
0
  if (!this->emitGetPtrGlobal(*GlobalIndex, E))
1746
0
    return false;
1747
1748
0
  const Record *R = getRecord(E->getType());
1749
0
  const APValue &V = UGCD->getValue();
1750
0
  for (unsigned I = 0, N = R->getNumFields(); I != N; ++I) {
1751
0
    const Record::Field *F = R->getField(I);
1752
0
    const APValue &FieldValue = V.getStructField(I);
1753
1754
0
    PrimType FieldT = classifyPrim(F->Decl->getType());
1755
1756
0
    if (!this->visitAPValue(FieldValue, FieldT, E))
1757
0
      return false;
1758
0
    if (!this->emitInitField(FieldT, F->Offset, E))
1759
0
      return false;
1760
0
  }
1761
1762
  // Leave the pointer to the global on the stack.
1763
0
  return true;
1764
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitSourceLocExpr(clang::SourceLocExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitSourceLocExpr(clang::SourceLocExpr const*)
1765
1766
template <class Emitter>
1767
0
bool ByteCodeExprGen<Emitter>::VisitOffsetOfExpr(const OffsetOfExpr *E) {
1768
0
  unsigned N = E->getNumComponents();
1769
0
  if (N == 0)
1770
0
    return false;
1771
1772
0
  for (unsigned I = 0; I != N; ++I) {
1773
0
    const OffsetOfNode &Node = E->getComponent(I);
1774
0
    if (Node.getKind() == OffsetOfNode::Array) {
1775
0
      const Expr *ArrayIndexExpr = E->getIndexExpr(Node.getArrayExprIndex());
1776
0
      PrimType IndexT = classifyPrim(ArrayIndexExpr->getType());
1777
1778
0
      if (DiscardResult) {
1779
0
        if (!this->discard(ArrayIndexExpr))
1780
0
          return false;
1781
0
        continue;
1782
0
      }
1783
1784
0
      if (!this->visit(ArrayIndexExpr))
1785
0
        return false;
1786
      // Cast to Sint64.
1787
0
      if (IndexT != PT_Sint64) {
1788
0
        if (!this->emitCast(IndexT, PT_Sint64, E))
1789
0
          return false;
1790
0
      }
1791
0
    }
1792
0
  }
1793
1794
0
  if (DiscardResult)
1795
0
    return true;
1796
1797
0
  PrimType T = classifyPrim(E->getType());
1798
0
  return this->emitOffsetOf(T, E, E);
1799
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitOffsetOfExpr(clang::OffsetOfExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitOffsetOfExpr(clang::OffsetOfExpr const*)
1800
1801
template <class Emitter>
1802
bool ByteCodeExprGen<Emitter>::VisitCXXScalarValueInitExpr(
1803
0
    const CXXScalarValueInitExpr *E) {
1804
0
  QualType Ty = E->getType();
1805
1806
0
  if (Ty->isVoidType())
1807
0
    return true;
1808
1809
0
  return this->visitZeroInitializer(classifyPrim(Ty), Ty, E);
1810
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitCXXScalarValueInitExpr(clang::CXXScalarValueInitExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitCXXScalarValueInitExpr(clang::CXXScalarValueInitExpr const*)
1811
1812
template <class Emitter>
1813
0
bool ByteCodeExprGen<Emitter>::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
1814
0
  return this->emitConst(E->getPackLength(), E);
1815
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitSizeOfPackExpr(clang::SizeOfPackExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitSizeOfPackExpr(clang::SizeOfPackExpr const*)
1816
1817
0
template <class Emitter> bool ByteCodeExprGen<Emitter>::discard(const Expr *E) {
1818
0
  if (E->containsErrors())
1819
0
    return false;
1820
1821
0
  OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/true,
1822
0
                             /*NewInitializing=*/false);
1823
0
  return this->Visit(E);
1824
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::discard(clang::Expr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::discard(clang::Expr const*)
1825
1826
template <class Emitter>
1827
0
bool ByteCodeExprGen<Emitter>::delegate(const Expr *E) {
1828
0
  if (E->containsErrors())
1829
0
    return false;
1830
1831
  // We're basically doing:
1832
  // OptionScope<Emitter> Scope(this, DicardResult, Initializing);
1833
  // but that's unnecessary of course.
1834
0
  return this->Visit(E);
1835
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::delegate(clang::Expr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::delegate(clang::Expr const*)
1836
1837
0
template <class Emitter> bool ByteCodeExprGen<Emitter>::visit(const Expr *E) {
1838
0
  if (E->containsErrors())
1839
0
    return false;
1840
1841
0
  if (E->getType()->isVoidType())
1842
0
    return this->discard(E);
1843
1844
  // Create local variable to hold the return value.
1845
0
  if (!E->isGLValue() && !E->getType()->isAnyComplexType() &&
1846
0
      !classify(E->getType())) {
1847
0
    std::optional<unsigned> LocalIndex = allocateLocal(E, /*IsExtended=*/true);
1848
0
    if (!LocalIndex)
1849
0
      return false;
1850
1851
0
    if (!this->emitGetPtrLocal(*LocalIndex, E))
1852
0
      return false;
1853
0
    return this->visitInitializer(E);
1854
0
  }
1855
1856
  //  Otherwise,we have a primitive return value, produce the value directly
1857
  //  and push it on the stack.
1858
0
  OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
1859
0
                             /*NewInitializing=*/false);
1860
0
  return this->Visit(E);
1861
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::visit(clang::Expr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::visit(clang::Expr const*)
1862
1863
template <class Emitter>
1864
0
bool ByteCodeExprGen<Emitter>::visitInitializer(const Expr *E) {
1865
0
  assert(!classify(E->getType()));
1866
1867
0
  if (E->containsErrors())
1868
0
    return false;
1869
1870
0
  OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false,
1871
0
                             /*NewInitializing=*/true);
1872
0
  return this->Visit(E);
1873
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::visitInitializer(clang::Expr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::visitInitializer(clang::Expr const*)
1874
1875
template <class Emitter>
1876
0
bool ByteCodeExprGen<Emitter>::visitBool(const Expr *E) {
1877
0
  std::optional<PrimType> T = classify(E->getType());
1878
0
  if (!T)
1879
0
    return false;
1880
1881
0
  if (!this->visit(E))
1882
0
    return false;
1883
1884
0
  if (T == PT_Bool)
1885
0
    return true;
1886
1887
  // Convert pointers to bool.
1888
0
  if (T == PT_Ptr || T == PT_FnPtr) {
1889
0
    if (!this->emitNull(*T, E))
1890
0
      return false;
1891
0
    return this->emitNE(*T, E);
1892
0
  }
1893
1894
  // Or Floats.
1895
0
  if (T == PT_Float)
1896
0
    return this->emitCastFloatingIntegralBool(E);
1897
1898
  // Or anything else we can.
1899
0
  return this->emitCast(*T, PT_Bool, E);
1900
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::visitBool(clang::Expr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::visitBool(clang::Expr const*)
1901
1902
template <class Emitter>
1903
bool ByteCodeExprGen<Emitter>::visitZeroInitializer(PrimType T, QualType QT,
1904
0
                                                    const Expr *E) {
1905
0
  switch (T) {
1906
0
  case PT_Bool:
1907
0
    return this->emitZeroBool(E);
1908
0
  case PT_Sint8:
1909
0
    return this->emitZeroSint8(E);
1910
0
  case PT_Uint8:
1911
0
    return this->emitZeroUint8(E);
1912
0
  case PT_Sint16:
1913
0
    return this->emitZeroSint16(E);
1914
0
  case PT_Uint16:
1915
0
    return this->emitZeroUint16(E);
1916
0
  case PT_Sint32:
1917
0
    return this->emitZeroSint32(E);
1918
0
  case PT_Uint32:
1919
0
    return this->emitZeroUint32(E);
1920
0
  case PT_Sint64:
1921
0
    return this->emitZeroSint64(E);
1922
0
  case PT_Uint64:
1923
0
    return this->emitZeroUint64(E);
1924
0
  case PT_IntAP:
1925
0
    return this->emitZeroIntAP(Ctx.getBitWidth(QT), E);
1926
0
  case PT_IntAPS:
1927
0
    return this->emitZeroIntAPS(Ctx.getBitWidth(QT), E);
1928
0
  case PT_Ptr:
1929
0
    return this->emitNullPtr(E);
1930
0
  case PT_FnPtr:
1931
0
    return this->emitNullFnPtr(E);
1932
0
  case PT_Float: {
1933
0
    return this->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)), E);
1934
0
  }
1935
0
  }
1936
0
  llvm_unreachable("unknown primitive type");
1937
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::visitZeroInitializer(clang::interp::PrimType, clang::QualType, clang::Expr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::visitZeroInitializer(clang::interp::PrimType, clang::QualType, clang::Expr const*)
1938
1939
template <class Emitter>
1940
bool ByteCodeExprGen<Emitter>::visitZeroRecordInitializer(const Record *R,
1941
0
                                                          const Expr *E) {
1942
0
  assert(E);
1943
0
  assert(R);
1944
  // Fields
1945
0
  for (const Record::Field &Field : R->fields()) {
1946
0
    const Descriptor *D = Field.Desc;
1947
0
    if (D->isPrimitive()) {
1948
0
      QualType QT = D->getType();
1949
0
      PrimType T = classifyPrim(D->getType());
1950
0
      if (!this->visitZeroInitializer(T, QT, E))
1951
0
        return false;
1952
0
      if (!this->emitInitField(T, Field.Offset, E))
1953
0
        return false;
1954
0
      continue;
1955
0
    }
1956
1957
    // TODO: Add GetPtrFieldPop and get rid of this dup.
1958
0
    if (!this->emitDupPtr(E))
1959
0
      return false;
1960
0
    if (!this->emitGetPtrField(Field.Offset, E))
1961
0
      return false;
1962
1963
0
    if (D->isPrimitiveArray()) {
1964
0
      QualType ET = D->getElemQualType();
1965
0
      PrimType T = classifyPrim(ET);
1966
0
      for (uint32_t I = 0, N = D->getNumElems(); I != N; ++I) {
1967
0
        if (!this->visitZeroInitializer(T, ET, E))
1968
0
          return false;
1969
0
        if (!this->emitInitElem(T, I, E))
1970
0
          return false;
1971
0
      }
1972
0
    } else if (D->isCompositeArray()) {
1973
0
      const Record *ElemRecord = D->ElemDesc->ElemRecord;
1974
0
      assert(D->ElemDesc->ElemRecord);
1975
0
      for (uint32_t I = 0, N = D->getNumElems(); I != N; ++I) {
1976
0
        if (!this->emitConstUint32(I, E))
1977
0
          return false;
1978
0
        if (!this->emitArrayElemPtr(PT_Uint32, E))
1979
0
          return false;
1980
0
        if (!this->visitZeroRecordInitializer(ElemRecord, E))
1981
0
          return false;
1982
0
        if (!this->emitPopPtr(E))
1983
0
          return false;
1984
0
      }
1985
0
    } else if (D->isRecord()) {
1986
0
      if (!this->visitZeroRecordInitializer(D->ElemRecord, E))
1987
0
        return false;
1988
0
    } else {
1989
0
      assert(false);
1990
0
    }
1991
1992
0
    if (!this->emitPopPtr(E))
1993
0
      return false;
1994
0
  }
1995
1996
0
  for (const Record::Base &B : R->bases()) {
1997
0
    if (!this->emitGetPtrBase(B.Offset, E))
1998
0
      return false;
1999
0
    if (!this->visitZeroRecordInitializer(B.R, E))
2000
0
      return false;
2001
0
    if (!this->emitInitPtrPop(E))
2002
0
      return false;
2003
0
  }
2004
2005
  // FIXME: Virtual bases.
2006
2007
0
  return true;
2008
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::visitZeroRecordInitializer(clang::interp::Record const*, clang::Expr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::visitZeroRecordInitializer(clang::interp::Record const*, clang::Expr const*)
2009
2010
template <class Emitter>
2011
bool ByteCodeExprGen<Emitter>::dereference(
2012
    const Expr *LV, DerefKind AK, llvm::function_ref<bool(PrimType)> Direct,
2013
0
    llvm::function_ref<bool(PrimType)> Indirect) {
2014
0
  if (std::optional<PrimType> T = classify(LV->getType())) {
2015
0
    if (!LV->refersToBitField()) {
2016
      // Only primitive, non bit-field types can be dereferenced directly.
2017
0
      if (const auto *DE = dyn_cast<DeclRefExpr>(LV)) {
2018
0
        if (!DE->getDecl()->getType()->isReferenceType()) {
2019
0
          if (const auto *PD = dyn_cast<ParmVarDecl>(DE->getDecl()))
2020
0
            return dereferenceParam(LV, *T, PD, AK, Direct, Indirect);
2021
0
          if (const auto *VD = dyn_cast<VarDecl>(DE->getDecl()))
2022
0
            return dereferenceVar(LV, *T, VD, AK, Direct, Indirect);
2023
0
        }
2024
0
      }
2025
0
    }
2026
2027
0
    if (!visit(LV))
2028
0
      return false;
2029
0
    return Indirect(*T);
2030
0
  }
2031
2032
0
  if (LV->getType()->isAnyComplexType())
2033
0
    return visit(LV);
2034
2035
0
  return false;
2036
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::dereference(clang::Expr const*, clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::DerefKind, llvm::function_ref<bool (clang::interp::PrimType)>, llvm::function_ref<bool (clang::interp::PrimType)>)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::dereference(clang::Expr const*, clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::DerefKind, llvm::function_ref<bool (clang::interp::PrimType)>, llvm::function_ref<bool (clang::interp::PrimType)>)
2037
2038
template <class Emitter>
2039
bool ByteCodeExprGen<Emitter>::dereferenceParam(
2040
    const Expr *LV, PrimType T, const ParmVarDecl *PD, DerefKind AK,
2041
    llvm::function_ref<bool(PrimType)> Direct,
2042
0
    llvm::function_ref<bool(PrimType)> Indirect) {
2043
0
  auto It = this->Params.find(PD);
2044
0
  if (It != this->Params.end()) {
2045
0
    unsigned Idx = It->second.Offset;
2046
0
    switch (AK) {
2047
0
    case DerefKind::Read:
2048
0
      return DiscardResult ? true : this->emitGetParam(T, Idx, LV);
2049
2050
0
    case DerefKind::Write:
2051
0
      if (!Direct(T))
2052
0
        return false;
2053
0
      if (!this->emitSetParam(T, Idx, LV))
2054
0
        return false;
2055
0
      return DiscardResult ? true : this->emitGetPtrParam(Idx, LV);
2056
2057
0
    case DerefKind::ReadWrite:
2058
0
      if (!this->emitGetParam(T, Idx, LV))
2059
0
        return false;
2060
0
      if (!Direct(T))
2061
0
        return false;
2062
0
      if (!this->emitSetParam(T, Idx, LV))
2063
0
        return false;
2064
0
      return DiscardResult ? true : this->emitGetPtrParam(Idx, LV);
2065
0
    }
2066
0
    return true;
2067
0
  }
2068
2069
  // If the param is a pointer, we can dereference a dummy value.
2070
0
  if (!DiscardResult && T == PT_Ptr && AK == DerefKind::Read) {
2071
0
    if (auto Idx = P.getOrCreateDummy(PD))
2072
0
      return this->emitGetPtrGlobal(*Idx, PD);
2073
0
    return false;
2074
0
  }
2075
2076
  // Value cannot be produced - try to emit pointer and do stuff with it.
2077
0
  return visit(LV) && Indirect(T);
2078
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::dereferenceParam(clang::Expr const*, clang::interp::PrimType, clang::ParmVarDecl const*, clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::DerefKind, llvm::function_ref<bool (clang::interp::PrimType)>, llvm::function_ref<bool (clang::interp::PrimType)>)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::dereferenceParam(clang::Expr const*, clang::interp::PrimType, clang::ParmVarDecl const*, clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::DerefKind, llvm::function_ref<bool (clang::interp::PrimType)>, llvm::function_ref<bool (clang::interp::PrimType)>)
2079
2080
template <class Emitter>
2081
bool ByteCodeExprGen<Emitter>::dereferenceVar(
2082
    const Expr *LV, PrimType T, const VarDecl *VD, DerefKind AK,
2083
    llvm::function_ref<bool(PrimType)> Direct,
2084
0
    llvm::function_ref<bool(PrimType)> Indirect) {
2085
0
  auto It = Locals.find(VD);
2086
0
  if (It != Locals.end()) {
2087
0
    const auto &L = It->second;
2088
0
    switch (AK) {
2089
0
    case DerefKind::Read:
2090
0
      if (!this->emitGetLocal(T, L.Offset, LV))
2091
0
        return false;
2092
0
      return DiscardResult ? this->emitPop(T, LV) : true;
2093
2094
0
    case DerefKind::Write:
2095
0
      if (!Direct(T))
2096
0
        return false;
2097
0
      if (!this->emitSetLocal(T, L.Offset, LV))
2098
0
        return false;
2099
0
      return DiscardResult ? true : this->emitGetPtrLocal(L.Offset, LV);
2100
2101
0
    case DerefKind::ReadWrite:
2102
0
      if (!this->emitGetLocal(T, L.Offset, LV))
2103
0
        return false;
2104
0
      if (!Direct(T))
2105
0
        return false;
2106
0
      if (!this->emitSetLocal(T, L.Offset, LV))
2107
0
        return false;
2108
0
      return DiscardResult ? true : this->emitGetPtrLocal(L.Offset, LV);
2109
0
    }
2110
0
  } else if (auto Idx = P.getGlobal(VD)) {
2111
0
    switch (AK) {
2112
0
    case DerefKind::Read:
2113
0
      if (!this->emitGetGlobal(T, *Idx, LV))
2114
0
        return false;
2115
0
      return DiscardResult ? this->emitPop(T, LV) : true;
2116
2117
0
    case DerefKind::Write:
2118
0
      if (!Direct(T))
2119
0
        return false;
2120
0
      if (!this->emitSetGlobal(T, *Idx, LV))
2121
0
        return false;
2122
0
      return DiscardResult ? true : this->emitGetPtrGlobal(*Idx, LV);
2123
2124
0
    case DerefKind::ReadWrite:
2125
0
      if (!this->emitGetGlobal(T, *Idx, LV))
2126
0
        return false;
2127
0
      if (!Direct(T))
2128
0
        return false;
2129
0
      if (!this->emitSetGlobal(T, *Idx, LV))
2130
0
        return false;
2131
0
      return DiscardResult ? true : this->emitGetPtrGlobal(*Idx, LV);
2132
0
    }
2133
0
  }
2134
2135
  // If the declaration is a constant value, emit it here even
2136
  // though the declaration was not evaluated in the current scope.
2137
  // The access mode can only be read in this case.
2138
0
  if (!DiscardResult && AK == DerefKind::Read) {
2139
0
    if (VD->hasLocalStorage() && VD->hasInit() && !VD->isConstexpr()) {
2140
0
      QualType VT = VD->getType();
2141
0
      if (VT.isConstQualified() && VT->isFundamentalType())
2142
0
        return this->visit(VD->getInit());
2143
0
    }
2144
0
  }
2145
2146
  // Value cannot be produced - try to emit pointer.
2147
0
  return visit(LV) && Indirect(T);
2148
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::dereferenceVar(clang::Expr const*, clang::interp::PrimType, clang::VarDecl const*, clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::DerefKind, llvm::function_ref<bool (clang::interp::PrimType)>, llvm::function_ref<bool (clang::interp::PrimType)>)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::dereferenceVar(clang::Expr const*, clang::interp::PrimType, clang::VarDecl const*, clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::DerefKind, llvm::function_ref<bool (clang::interp::PrimType)>, llvm::function_ref<bool (clang::interp::PrimType)>)
2149
2150
template <class Emitter>
2151
template <typename T>
2152
0
bool ByteCodeExprGen<Emitter>::emitConst(T Value, PrimType Ty, const Expr *E) {
2153
0
  switch (Ty) {
2154
0
  case PT_Sint8:
2155
0
    return this->emitConstSint8(Value, E);
2156
0
  case PT_Uint8:
2157
0
    return this->emitConstUint8(Value, E);
2158
0
  case PT_Sint16:
2159
0
    return this->emitConstSint16(Value, E);
2160
0
  case PT_Uint16:
2161
0
    return this->emitConstUint16(Value, E);
2162
0
  case PT_Sint32:
2163
0
    return this->emitConstSint32(Value, E);
2164
0
  case PT_Uint32:
2165
0
    return this->emitConstUint32(Value, E);
2166
0
  case PT_Sint64:
2167
0
    return this->emitConstSint64(Value, E);
2168
0
  case PT_Uint64:
2169
0
    return this->emitConstUint64(Value, E);
2170
0
  case PT_IntAP:
2171
0
  case PT_IntAPS:
2172
0
    assert(false);
2173
0
    return false;
2174
0
  case PT_Bool:
2175
0
    return this->emitConstBool(Value, E);
2176
0
  case PT_Ptr:
2177
0
  case PT_FnPtr:
2178
0
  case PT_Float:
2179
0
    llvm_unreachable("Invalid integral type");
2180
0
    break;
2181
0
  }
2182
0
  llvm_unreachable("unknown primitive type");
2183
0
}
Unexecuted instantiation: bool clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::emitConst<int>(int, clang::interp::PrimType, clang::Expr const*)
Unexecuted instantiation: bool clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::emitConst<unsigned int>(unsigned int, clang::interp::PrimType, clang::Expr const*)
Unexecuted instantiation: bool clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::emitConst<long>(long, clang::interp::PrimType, clang::Expr const*)
Unexecuted instantiation: bool clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::emitConst<unsigned long>(unsigned long, clang::interp::PrimType, clang::Expr const*)
Unexecuted instantiation: bool clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::emitConst<int>(int, clang::interp::PrimType, clang::Expr const*)
Unexecuted instantiation: bool clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::emitConst<unsigned int>(unsigned int, clang::interp::PrimType, clang::Expr const*)
Unexecuted instantiation: bool clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::emitConst<long>(long, clang::interp::PrimType, clang::Expr const*)
Unexecuted instantiation: bool clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::emitConst<unsigned long>(unsigned long, clang::interp::PrimType, clang::Expr const*)
2184
2185
template <class Emitter>
2186
template <typename T>
2187
0
bool ByteCodeExprGen<Emitter>::emitConst(T Value, const Expr *E) {
2188
0
  return this->emitConst(Value, classifyPrim(E->getType()), E);
2189
0
}
Unexecuted instantiation: bool clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::emitConst<int>(int, clang::Expr const*)
Unexecuted instantiation: bool clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::emitConst<long>(long, clang::Expr const*)
Unexecuted instantiation: bool clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::emitConst<unsigned long>(unsigned long, clang::Expr const*)
Unexecuted instantiation: bool clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::emitConst<unsigned int>(unsigned int, clang::Expr const*)
Unexecuted instantiation: bool clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::emitConst<int>(int, clang::Expr const*)
Unexecuted instantiation: bool clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::emitConst<long>(long, clang::Expr const*)
Unexecuted instantiation: bool clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::emitConst<unsigned long>(unsigned long, clang::Expr const*)
Unexecuted instantiation: bool clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::emitConst<unsigned int>(unsigned int, clang::Expr const*)
2190
2191
template <class Emitter>
2192
bool ByteCodeExprGen<Emitter>::emitConst(const APSInt &Value, PrimType Ty,
2193
0
                                         const Expr *E) {
2194
0
  if (Value.isSigned())
2195
0
    return this->emitConst(Value.getSExtValue(), Ty, E);
2196
0
  return this->emitConst(Value.getZExtValue(), Ty, E);
2197
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::emitConst(llvm::APSInt const&, clang::interp::PrimType, clang::Expr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::emitConst(llvm::APSInt const&, clang::interp::PrimType, clang::Expr const*)
2198
2199
template <class Emitter>
2200
0
bool ByteCodeExprGen<Emitter>::emitConst(const APSInt &Value, const Expr *E) {
2201
0
  return this->emitConst(Value, classifyPrim(E->getType()), E);
2202
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::emitConst(llvm::APSInt const&, clang::Expr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::emitConst(llvm::APSInt const&, clang::Expr const*)
2203
2204
template <class Emitter>
2205
unsigned ByteCodeExprGen<Emitter>::allocateLocalPrimitive(DeclTy &&Src,
2206
                                                          PrimType Ty,
2207
                                                          bool IsConst,
2208
0
                                                          bool IsExtended) {
2209
  // Make sure we don't accidentally register the same decl twice.
2210
0
  if (const auto *VD =
2211
0
          dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
2212
0
    assert(!P.getGlobal(VD));
2213
0
    assert(!Locals.contains(VD));
2214
0
  }
2215
2216
  // FIXME: There are cases where Src.is<Expr*>() is wrong, e.g.
2217
  //   (int){12} in C. Consider using Expr::isTemporaryObject() instead
2218
  //   or isa<MaterializeTemporaryExpr>().
2219
0
  Descriptor *D = P.createDescriptor(Src, Ty, Descriptor::InlineDescMD, IsConst,
2220
0
                                     Src.is<const Expr *>());
2221
0
  Scope::Local Local = this->createLocal(D);
2222
0
  if (auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>()))
2223
0
    Locals.insert({VD, Local});
2224
0
  VarScope->add(Local, IsExtended);
2225
0
  return Local.Offset;
2226
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::allocateLocalPrimitive(llvm::PointerUnion<clang::Decl const*, clang::Expr const*>&&, clang::interp::PrimType, bool, bool)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::allocateLocalPrimitive(llvm::PointerUnion<clang::Decl const*, clang::Expr const*>&&, clang::interp::PrimType, bool, bool)
2227
2228
template <class Emitter>
2229
std::optional<unsigned>
2230
0
ByteCodeExprGen<Emitter>::allocateLocal(DeclTy &&Src, bool IsExtended) {
2231
  // Make sure we don't accidentally register the same decl twice.
2232
0
  if ([[maybe_unused]]  const auto *VD =
2233
0
          dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
2234
0
    assert(!P.getGlobal(VD));
2235
0
    assert(!Locals.contains(VD));
2236
0
  }
2237
2238
0
  QualType Ty;
2239
0
  const ValueDecl *Key = nullptr;
2240
0
  const Expr *Init = nullptr;
2241
0
  bool IsTemporary = false;
2242
0
  if (auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
2243
0
    Key = VD;
2244
0
    Ty = VD->getType();
2245
2246
0
    if (const auto *VarD = dyn_cast<VarDecl>(VD))
2247
0
      Init = VarD->getInit();
2248
0
  }
2249
0
  if (auto *E = Src.dyn_cast<const Expr *>()) {
2250
0
    IsTemporary = true;
2251
0
    Ty = E->getType();
2252
0
  }
2253
2254
0
  Descriptor *D = P.createDescriptor(
2255
0
      Src, Ty.getTypePtr(), Descriptor::InlineDescMD, Ty.isConstQualified(),
2256
0
      IsTemporary, /*IsMutable=*/false, Init);
2257
0
  if (!D)
2258
0
    return {};
2259
2260
0
  Scope::Local Local = this->createLocal(D);
2261
0
  if (Key)
2262
0
    Locals.insert({Key, Local});
2263
0
  VarScope->add(Local, IsExtended);
2264
0
  return Local.Offset;
2265
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::allocateLocal(llvm::PointerUnion<clang::Decl const*, clang::Expr const*>&&, bool)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::allocateLocal(llvm::PointerUnion<clang::Decl const*, clang::Expr const*>&&, bool)
2266
2267
template <class Emitter>
2268
0
const RecordType *ByteCodeExprGen<Emitter>::getRecordTy(QualType Ty) {
2269
0
  if (const PointerType *PT = dyn_cast<PointerType>(Ty))
2270
0
    return PT->getPointeeType()->getAs<RecordType>();
2271
0
  return Ty->getAs<RecordType>();
2272
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::getRecordTy(clang::QualType)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::getRecordTy(clang::QualType)
2273
2274
template <class Emitter>
2275
0
Record *ByteCodeExprGen<Emitter>::getRecord(QualType Ty) {
2276
0
  if (const auto *RecordTy = getRecordTy(Ty))
2277
0
    return getRecord(RecordTy->getDecl());
2278
0
  return nullptr;
2279
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::getRecord(clang::QualType)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::getRecord(clang::QualType)
2280
2281
template <class Emitter>
2282
0
Record *ByteCodeExprGen<Emitter>::getRecord(const RecordDecl *RD) {
2283
0
  return P.getOrCreateRecord(RD);
2284
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::getRecord(clang::RecordDecl const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::getRecord(clang::RecordDecl const*)
2285
2286
template <class Emitter>
2287
0
const Function *ByteCodeExprGen<Emitter>::getFunction(const FunctionDecl *FD) {
2288
0
  return Ctx.getOrCreateFunction(FD);
2289
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::getFunction(clang::FunctionDecl const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::getFunction(clang::FunctionDecl const*)
2290
2291
template <class Emitter>
2292
0
bool ByteCodeExprGen<Emitter>::visitExpr(const Expr *E) {
2293
0
  ExprScope<Emitter> RootScope(this);
2294
  // Void expressions.
2295
0
  if (E->getType()->isVoidType()) {
2296
0
    if (!visit(E))
2297
0
      return false;
2298
0
    return this->emitRetVoid(E);
2299
0
  }
2300
2301
  // Expressions with a primitive return type.
2302
0
  if (std::optional<PrimType> T = classify(E)) {
2303
0
    if (!visit(E))
2304
0
      return false;
2305
0
    return this->emitRet(*T, E);
2306
0
  }
2307
2308
  // Expressions with a composite return type.
2309
  // For us, that means everything we don't
2310
  // have a PrimType for.
2311
0
  if (std::optional<unsigned> LocalOffset = this->allocateLocal(E)) {
2312
0
    if (!this->visitLocalInitializer(E, *LocalOffset))
2313
0
      return false;
2314
2315
0
    if (!this->emitGetPtrLocal(*LocalOffset, E))
2316
0
      return false;
2317
0
    return this->emitRetValue(E);
2318
0
  }
2319
2320
0
  return false;
2321
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::visitExpr(clang::Expr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::visitExpr(clang::Expr const*)
2322
2323
/// Toplevel visitDecl().
2324
/// We get here from evaluateAsInitializer().
2325
/// We need to evaluate the initializer and return its value.
2326
template <class Emitter>
2327
0
bool ByteCodeExprGen<Emitter>::visitDecl(const VarDecl *VD) {
2328
0
  assert(!VD->isInvalidDecl() && "Trying to constant evaluate an invalid decl");
2329
2330
  // Create and initialize the variable.
2331
0
  if (!this->visitVarDecl(VD))
2332
0
    return false;
2333
2334
0
  std::optional<PrimType> VarT = classify(VD->getType());
2335
  // Get a pointer to the variable
2336
0
  if (Context::shouldBeGloballyIndexed(VD)) {
2337
0
    auto GlobalIndex = P.getGlobal(VD);
2338
0
    assert(GlobalIndex); // visitVarDecl() didn't return false.
2339
0
    if (VarT) {
2340
0
      if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
2341
0
        return false;
2342
0
    } else {
2343
0
      if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
2344
0
        return false;
2345
0
    }
2346
0
  } else {
2347
0
    auto Local = Locals.find(VD);
2348
0
    assert(Local != Locals.end()); // Same here.
2349
0
    if (VarT) {
2350
0
      if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
2351
0
        return false;
2352
0
    } else {
2353
0
      if (!this->emitGetPtrLocal(Local->second.Offset, VD))
2354
0
        return false;
2355
0
    }
2356
0
  }
2357
2358
  // Return the value
2359
0
  if (VarT)
2360
0
    return this->emitRet(*VarT, VD);
2361
0
  return this->emitRetValue(VD);
2362
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::visitDecl(clang::VarDecl const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::visitDecl(clang::VarDecl const*)
2363
2364
template <class Emitter>
2365
0
bool ByteCodeExprGen<Emitter>::visitVarDecl(const VarDecl *VD) {
2366
  // We don't know what to do with these, so just return false.
2367
0
  if (VD->getType().isNull())
2368
0
    return false;
2369
2370
0
  const Expr *Init = VD->getInit();
2371
0
  std::optional<PrimType> VarT = classify(VD->getType());
2372
2373
0
  if (Context::shouldBeGloballyIndexed(VD)) {
2374
    // We've already seen and initialized this global.
2375
0
    if (P.getGlobal(VD))
2376
0
      return true;
2377
2378
0
    std::optional<unsigned> GlobalIndex = P.createGlobal(VD, Init);
2379
2380
0
    if (!GlobalIndex)
2381
0
      return this->bail(VD);
2382
2383
0
    assert(Init);
2384
0
    {
2385
0
      DeclScope<Emitter> LocalScope(this, VD);
2386
2387
0
      if (VarT) {
2388
0
        if (!this->visit(Init))
2389
0
          return false;
2390
0
        return this->emitInitGlobal(*VarT, *GlobalIndex, VD);
2391
0
      }
2392
0
      return this->visitGlobalInitializer(Init, *GlobalIndex);
2393
0
    }
2394
0
  } else {
2395
0
    VariableScope<Emitter> LocalScope(this);
2396
0
    if (VarT) {
2397
0
      unsigned Offset = this->allocateLocalPrimitive(
2398
0
          VD, *VarT, VD->getType().isConstQualified());
2399
0
      if (Init) {
2400
        // Compile the initializer in its own scope.
2401
0
        ExprScope<Emitter> Scope(this);
2402
0
        if (!this->visit(Init))
2403
0
          return false;
2404
2405
0
        return this->emitSetLocal(*VarT, Offset, VD);
2406
0
      }
2407
0
    } else {
2408
0
      if (std::optional<unsigned> Offset = this->allocateLocal(VD)) {
2409
0
        if (Init)
2410
0
          return this->visitLocalInitializer(Init, *Offset);
2411
0
      }
2412
0
    }
2413
0
    return true;
2414
0
  }
2415
2416
0
  return false;
2417
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::visitVarDecl(clang::VarDecl const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::visitVarDecl(clang::VarDecl const*)
2418
2419
template <class Emitter>
2420
bool ByteCodeExprGen<Emitter>::visitAPValue(const APValue &Val,
2421
0
                                            PrimType ValType, const Expr *E) {
2422
0
  assert(!DiscardResult);
2423
0
  if (Val.isInt())
2424
0
    return this->emitConst(Val.getInt(), ValType, E);
2425
2426
0
  if (Val.isLValue()) {
2427
0
    APValue::LValueBase Base = Val.getLValueBase();
2428
0
    if (const Expr *BaseExpr = Base.dyn_cast<const Expr *>())
2429
0
      return this->visit(BaseExpr);
2430
0
  }
2431
2432
0
  return false;
2433
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::visitAPValue(clang::APValue const&, clang::interp::PrimType, clang::Expr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::visitAPValue(clang::APValue const&, clang::interp::PrimType, clang::Expr const*)
2434
2435
template <class Emitter>
2436
0
bool ByteCodeExprGen<Emitter>::VisitBuiltinCallExpr(const CallExpr *E) {
2437
0
  const Function *Func = getFunction(E->getDirectCallee());
2438
0
  if (!Func)
2439
0
    return false;
2440
2441
0
  if (!Func->isUnevaluatedBuiltin()) {
2442
    // Put arguments on the stack.
2443
0
    for (const auto *Arg : E->arguments()) {
2444
0
      if (!this->visit(Arg))
2445
0
        return false;
2446
0
    }
2447
0
  }
2448
2449
0
  if (!this->emitCallBI(Func, E, E))
2450
0
    return false;
2451
2452
0
  QualType ReturnType = E->getCallReturnType(Ctx.getASTContext());
2453
0
  if (DiscardResult && !ReturnType->isVoidType()) {
2454
0
    PrimType T = classifyPrim(ReturnType);
2455
0
    return this->emitPop(T, E);
2456
0
  }
2457
2458
0
  return true;
2459
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitBuiltinCallExpr(clang::CallExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitBuiltinCallExpr(clang::CallExpr const*)
2460
2461
template <class Emitter>
2462
0
bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) {
2463
0
  if (E->getBuiltinCallee())
2464
0
    return VisitBuiltinCallExpr(E);
2465
2466
0
  QualType ReturnType = E->getCallReturnType(Ctx.getASTContext());
2467
0
  std::optional<PrimType> T = classify(ReturnType);
2468
0
  bool HasRVO = !ReturnType->isVoidType() && !T;
2469
2470
0
  if (HasRVO) {
2471
0
    if (DiscardResult) {
2472
      // If we need to discard the return value but the function returns its
2473
      // value via an RVO pointer, we need to create one such pointer just
2474
      // for this call.
2475
0
      if (std::optional<unsigned> LocalIndex = allocateLocal(E)) {
2476
0
        if (!this->emitGetPtrLocal(*LocalIndex, E))
2477
0
          return false;
2478
0
      }
2479
0
    } else {
2480
0
      assert(Initializing);
2481
0
      if (!this->emitDupPtr(E))
2482
0
        return false;
2483
0
    }
2484
0
  }
2485
2486
  // Add the (optional, implicit) This pointer.
2487
0
  if (const auto *MC = dyn_cast<CXXMemberCallExpr>(E)) {
2488
0
    if (!this->visit(MC->getImplicitObjectArgument()))
2489
0
      return false;
2490
0
  }
2491
2492
  // Put arguments on the stack.
2493
0
  for (const auto *Arg : E->arguments()) {
2494
0
    if (!this->visit(Arg))
2495
0
      return false;
2496
0
  }
2497
2498
0
  if (const FunctionDecl *FuncDecl = E->getDirectCallee()) {
2499
0
    const Function *Func = getFunction(FuncDecl);
2500
0
    if (!Func)
2501
0
      return false;
2502
    // If the function is being compiled right now, this is a recursive call.
2503
    // In that case, the function can't be valid yet, even though it will be
2504
    // later.
2505
    // If the function is already fully compiled but not constexpr, it was
2506
    // found to be faulty earlier on, so bail out.
2507
0
    if (Func->isFullyCompiled() && !Func->isConstexpr())
2508
0
      return false;
2509
2510
0
    assert(HasRVO == Func->hasRVO());
2511
2512
0
    bool HasQualifier = false;
2513
0
    if (const auto *ME = dyn_cast<MemberExpr>(E->getCallee()))
2514
0
      HasQualifier = ME->hasQualifier();
2515
2516
0
    bool IsVirtual = false;
2517
0
    if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
2518
0
      IsVirtual = MD->isVirtual();
2519
2520
    // In any case call the function. The return value will end up on the stack
2521
    // and if the function has RVO, we already have the pointer on the stack to
2522
    // write the result into.
2523
0
    if (IsVirtual && !HasQualifier) {
2524
0
      if (!this->emitCallVirt(Func, E))
2525
0
        return false;
2526
0
    } else {
2527
0
      if (!this->emitCall(Func, E))
2528
0
        return false;
2529
0
    }
2530
0
  } else {
2531
    // Indirect call. Visit the callee, which will leave a FunctionPointer on
2532
    // the stack. Cleanup of the returned value if necessary will be done after
2533
    // the function call completed.
2534
0
    if (!this->visit(E->getCallee()))
2535
0
      return false;
2536
2537
0
    if (!this->emitCallPtr(E))
2538
0
      return false;
2539
0
  }
2540
2541
  // Cleanup for discarded return values.
2542
0
  if (DiscardResult && !ReturnType->isVoidType() && T)
2543
0
    return this->emitPop(*T, E);
2544
2545
0
  return true;
2546
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitCallExpr(clang::CallExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitCallExpr(clang::CallExpr const*)
2547
2548
template <class Emitter>
2549
bool ByteCodeExprGen<Emitter>::VisitCXXDefaultInitExpr(
2550
0
    const CXXDefaultInitExpr *E) {
2551
0
  SourceLocScope<Emitter> SLS(this, E);
2552
0
  if (Initializing)
2553
0
    return this->visitInitializer(E->getExpr());
2554
2555
0
  assert(classify(E->getType()));
2556
0
  return this->visit(E->getExpr());
2557
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitCXXDefaultInitExpr(clang::CXXDefaultInitExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitCXXDefaultInitExpr(clang::CXXDefaultInitExpr const*)
2558
2559
template <class Emitter>
2560
bool ByteCodeExprGen<Emitter>::VisitCXXDefaultArgExpr(
2561
0
    const CXXDefaultArgExpr *E) {
2562
0
  SourceLocScope<Emitter> SLS(this, E);
2563
2564
0
  const Expr *SubExpr = E->getExpr();
2565
0
  if (std::optional<PrimType> T = classify(E->getExpr()))
2566
0
    return this->visit(SubExpr);
2567
2568
0
  assert(Initializing);
2569
0
  return this->visitInitializer(SubExpr);
2570
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitCXXDefaultArgExpr(clang::CXXDefaultArgExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitCXXDefaultArgExpr(clang::CXXDefaultArgExpr const*)
2571
2572
template <class Emitter>
2573
bool ByteCodeExprGen<Emitter>::VisitCXXBoolLiteralExpr(
2574
0
    const CXXBoolLiteralExpr *E) {
2575
0
  if (DiscardResult)
2576
0
    return true;
2577
2578
0
  return this->emitConstBool(E->getValue(), E);
2579
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitCXXBoolLiteralExpr(clang::CXXBoolLiteralExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitCXXBoolLiteralExpr(clang::CXXBoolLiteralExpr const*)
2580
2581
template <class Emitter>
2582
bool ByteCodeExprGen<Emitter>::VisitCXXNullPtrLiteralExpr(
2583
0
    const CXXNullPtrLiteralExpr *E) {
2584
0
  if (DiscardResult)
2585
0
    return true;
2586
2587
0
  return this->emitNullPtr(E);
2588
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitCXXNullPtrLiteralExpr(clang::CXXNullPtrLiteralExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitCXXNullPtrLiteralExpr(clang::CXXNullPtrLiteralExpr const*)
2589
2590
template <class Emitter>
2591
0
bool ByteCodeExprGen<Emitter>::VisitGNUNullExpr(const GNUNullExpr *E) {
2592
0
  if (DiscardResult)
2593
0
    return true;
2594
2595
0
  assert(E->getType()->isIntegerType());
2596
2597
0
  PrimType T = classifyPrim(E->getType());
2598
0
  return this->emitZero(T, E);
2599
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitGNUNullExpr(clang::GNUNullExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitGNUNullExpr(clang::GNUNullExpr const*)
2600
2601
template <class Emitter>
2602
0
bool ByteCodeExprGen<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) {
2603
0
  if (DiscardResult)
2604
0
    return true;
2605
2606
0
  if (this->LambdaThisCapture > 0)
2607
0
    return this->emitGetThisFieldPtr(this->LambdaThisCapture, E);
2608
2609
0
  return this->emitThis(E);
2610
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitCXXThisExpr(clang::CXXThisExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitCXXThisExpr(clang::CXXThisExpr const*)
2611
2612
template <class Emitter>
2613
0
bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
2614
0
  const Expr *SubExpr = E->getSubExpr();
2615
0
  std::optional<PrimType> T = classify(SubExpr->getType());
2616
2617
0
  switch (E->getOpcode()) {
2618
0
  case UO_PostInc: { // x++
2619
0
    if (!this->visit(SubExpr))
2620
0
      return false;
2621
2622
0
    if (T == PT_Ptr) {
2623
0
      if (!this->emitIncPtr(E))
2624
0
        return false;
2625
2626
0
      return DiscardResult ? this->emitPopPtr(E) : true;
2627
0
    }
2628
2629
0
    if (T == PT_Float) {
2630
0
      return DiscardResult ? this->emitIncfPop(getRoundingMode(E), E)
2631
0
                           : this->emitIncf(getRoundingMode(E), E);
2632
0
    }
2633
2634
0
    return DiscardResult ? this->emitIncPop(*T, E) : this->emitInc(*T, E);
2635
0
  }
2636
0
  case UO_PostDec: { // x--
2637
0
    if (!this->visit(SubExpr))
2638
0
      return false;
2639
2640
0
    if (T == PT_Ptr) {
2641
0
      if (!this->emitDecPtr(E))
2642
0
        return false;
2643
2644
0
      return DiscardResult ? this->emitPopPtr(E) : true;
2645
0
    }
2646
2647
0
    if (T == PT_Float) {
2648
0
      return DiscardResult ? this->emitDecfPop(getRoundingMode(E), E)
2649
0
                           : this->emitDecf(getRoundingMode(E), E);
2650
0
    }
2651
2652
0
    return DiscardResult ? this->emitDecPop(*T, E) : this->emitDec(*T, E);
2653
0
  }
2654
0
  case UO_PreInc: { // ++x
2655
0
    if (!this->visit(SubExpr))
2656
0
      return false;
2657
2658
0
    if (T == PT_Ptr) {
2659
0
      if (!this->emitLoadPtr(E))
2660
0
        return false;
2661
0
      if (!this->emitConstUint8(1, E))
2662
0
        return false;
2663
0
      if (!this->emitAddOffsetUint8(E))
2664
0
        return false;
2665
0
      return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
2666
0
    }
2667
2668
    // Post-inc and pre-inc are the same if the value is to be discarded.
2669
0
    if (DiscardResult) {
2670
0
      if (T == PT_Float)
2671
0
        return this->emitIncfPop(getRoundingMode(E), E);
2672
0
      return this->emitIncPop(*T, E);
2673
0
    }
2674
2675
0
    if (T == PT_Float) {
2676
0
      const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType());
2677
0
      if (!this->emitLoadFloat(E))
2678
0
        return false;
2679
0
      if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E))
2680
0
        return false;
2681
0
      if (!this->emitAddf(getRoundingMode(E), E))
2682
0
        return false;
2683
0
      return this->emitStoreFloat(E);
2684
0
    }
2685
0
    if (!this->emitLoad(*T, E))
2686
0
      return false;
2687
0
    if (!this->emitConst(1, E))
2688
0
      return false;
2689
0
    if (!this->emitAdd(*T, E))
2690
0
      return false;
2691
0
    return this->emitStore(*T, E);
2692
0
  }
2693
0
  case UO_PreDec: { // --x
2694
0
    if (!this->visit(SubExpr))
2695
0
      return false;
2696
2697
0
    if (T == PT_Ptr) {
2698
0
      if (!this->emitLoadPtr(E))
2699
0
        return false;
2700
0
      if (!this->emitConstUint8(1, E))
2701
0
        return false;
2702
0
      if (!this->emitSubOffsetUint8(E))
2703
0
        return false;
2704
0
      return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E);
2705
0
    }
2706
2707
    // Post-dec and pre-dec are the same if the value is to be discarded.
2708
0
    if (DiscardResult) {
2709
0
      if (T == PT_Float)
2710
0
        return this->emitDecfPop(getRoundingMode(E), E);
2711
0
      return this->emitDecPop(*T, E);
2712
0
    }
2713
2714
0
    if (T == PT_Float) {
2715
0
      const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType());
2716
0
      if (!this->emitLoadFloat(E))
2717
0
        return false;
2718
0
      if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E))
2719
0
        return false;
2720
0
      if (!this->emitSubf(getRoundingMode(E), E))
2721
0
        return false;
2722
0
      return this->emitStoreFloat(E);
2723
0
    }
2724
0
    if (!this->emitLoad(*T, E))
2725
0
      return false;
2726
0
    if (!this->emitConst(1, E))
2727
0
      return false;
2728
0
    if (!this->emitSub(*T, E))
2729
0
      return false;
2730
0
    return this->emitStore(*T, E);
2731
0
  }
2732
0
  case UO_LNot: // !x
2733
0
    if (DiscardResult)
2734
0
      return this->discard(SubExpr);
2735
2736
0
    if (!this->visitBool(SubExpr))
2737
0
      return false;
2738
2739
0
    if (!this->emitInvBool(E))
2740
0
      return false;
2741
2742
0
    if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool)
2743
0
      return this->emitCast(PT_Bool, ET, E);
2744
0
    return true;
2745
0
  case UO_Minus: // -x
2746
0
    if (!this->visit(SubExpr))
2747
0
      return false;
2748
0
    return DiscardResult ? this->emitPop(*T, E) : this->emitNeg(*T, E);
2749
0
  case UO_Plus:  // +x
2750
0
    if (!this->visit(SubExpr)) // noop
2751
0
      return false;
2752
0
    return DiscardResult ? this->emitPop(*T, E) : true;
2753
0
  case UO_AddrOf: // &x
2754
    // We should already have a pointer when we get here.
2755
0
    return this->delegate(SubExpr);
2756
0
  case UO_Deref:  // *x
2757
0
    return dereference(
2758
0
        SubExpr, DerefKind::Read,
2759
0
        [](PrimType) {
2760
0
          llvm_unreachable("Dereferencing requires a pointer");
2761
0
          return false;
2762
0
        },
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitUnaryOperator(clang::UnaryOperator const*)::{lambda(clang::interp::PrimType)#1}::operator()(clang::interp::PrimType) const
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitUnaryOperator(clang::UnaryOperator const*)::{lambda(clang::interp::PrimType)#1}::operator()(clang::interp::PrimType) const
2763
0
        [this, E](PrimType T) {
2764
0
          return DiscardResult ? this->emitPop(T, E) : true;
2765
0
        });
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitUnaryOperator(clang::UnaryOperator const*)::{lambda(clang::interp::PrimType)#2}::operator()(clang::interp::PrimType) const
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitUnaryOperator(clang::UnaryOperator const*)::{lambda(clang::interp::PrimType)#2}::operator()(clang::interp::PrimType) const
2766
0
  case UO_Not:    // ~x
2767
0
    if (!this->visit(SubExpr))
2768
0
      return false;
2769
0
    return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E);
2770
0
  case UO_Real: { // __real x
2771
0
    if (T)
2772
0
      return this->delegate(SubExpr);
2773
0
    if (!this->visit(SubExpr))
2774
0
      return false;
2775
0
    if (!this->emitConstUint8(0, E))
2776
0
      return false;
2777
0
    if (!this->emitArrayElemPtrPopUint8(E))
2778
0
      return false;
2779
2780
    // Since our _Complex implementation does not map to a primitive type,
2781
    // we sometimes have to do the lvalue-to-rvalue conversion here manually.
2782
0
    if (!SubExpr->isLValue())
2783
0
      return this->emitLoadPop(classifyPrim(E->getType()), E);
2784
0
    return true;
2785
0
  }
2786
0
  case UO_Imag: { // __imag x
2787
0
    if (T) {
2788
0
      if (!this->discard(SubExpr))
2789
0
        return false;
2790
0
      return this->visitZeroInitializer(*T, SubExpr->getType(), SubExpr);
2791
0
    }
2792
0
    if (!this->visit(SubExpr))
2793
0
      return false;
2794
0
    if (!this->emitConstUint8(1, E))
2795
0
      return false;
2796
0
    if (!this->emitArrayElemPtrPopUint8(E))
2797
0
      return false;
2798
2799
    // Since our _Complex implementation does not map to a primitive type,
2800
    // we sometimes have to do the lvalue-to-rvalue conversion here manually.
2801
0
    if (!SubExpr->isLValue())
2802
0
      return this->emitLoadPop(classifyPrim(E->getType()), E);
2803
0
    return true;
2804
0
  }
2805
0
  case UO_Extension:
2806
0
    return this->delegate(SubExpr);
2807
0
  case UO_Coawait:
2808
0
    assert(false && "Unhandled opcode");
2809
0
  }
2810
2811
0
  return false;
2812
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitUnaryOperator(clang::UnaryOperator const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitUnaryOperator(clang::UnaryOperator const*)
2813
2814
template <class Emitter>
2815
0
bool ByteCodeExprGen<Emitter>::VisitDeclRefExpr(const DeclRefExpr *E) {
2816
0
  if (DiscardResult)
2817
0
    return true;
2818
2819
0
  const auto *D = E->getDecl();
2820
2821
0
  if (const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
2822
0
    return this->emitConst(ECD->getInitVal(), E);
2823
0
  } else if (const auto *BD = dyn_cast<BindingDecl>(D)) {
2824
0
    return this->visit(BD->getBinding());
2825
0
  } else if (const auto *FuncDecl = dyn_cast<FunctionDecl>(D)) {
2826
0
    const Function *F = getFunction(FuncDecl);
2827
0
    return F && this->emitGetFnPtr(F, E);
2828
0
  }
2829
2830
  // References are implemented via pointers, so when we see a DeclRefExpr
2831
  // pointing to a reference, we need to get its value directly (i.e. the
2832
  // pointer to the actual value) instead of a pointer to the pointer to the
2833
  // value.
2834
0
  bool IsReference = D->getType()->isReferenceType();
2835
2836
  // Check for local/global variables and parameters.
2837
0
  if (auto It = Locals.find(D); It != Locals.end()) {
2838
0
    const unsigned Offset = It->second.Offset;
2839
2840
0
    if (IsReference)
2841
0
      return this->emitGetLocal(PT_Ptr, Offset, E);
2842
0
    return this->emitGetPtrLocal(Offset, E);
2843
0
  } else if (auto GlobalIndex = P.getGlobal(D)) {
2844
0
    if (IsReference)
2845
0
      return this->emitGetGlobalPtr(*GlobalIndex, E);
2846
2847
0
    return this->emitGetPtrGlobal(*GlobalIndex, E);
2848
0
  } else if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
2849
0
    if (auto It = this->Params.find(PVD); It != this->Params.end()) {
2850
0
      if (IsReference || !It->second.IsPtr)
2851
0
        return this->emitGetParamPtr(It->second.Offset, E);
2852
2853
0
      return this->emitGetPtrParam(It->second.Offset, E);
2854
0
    }
2855
0
  }
2856
2857
  // Handle lambda captures.
2858
0
  if (auto It = this->LambdaCaptures.find(D);
2859
0
      It != this->LambdaCaptures.end()) {
2860
0
    auto [Offset, IsPtr] = It->second;
2861
2862
0
    if (IsPtr)
2863
0
      return this->emitGetThisFieldPtr(Offset, E);
2864
0
    return this->emitGetPtrThisField(Offset, E);
2865
0
  }
2866
2867
  // Lazily visit global declarations we haven't seen yet.
2868
  // This happens in C.
2869
0
  if (!Ctx.getLangOpts().CPlusPlus) {
2870
0
    if (const auto *VD = dyn_cast<VarDecl>(D);
2871
0
        VD && VD->hasGlobalStorage() && VD->getAnyInitializer() &&
2872
0
        VD->getType().isConstQualified()) {
2873
0
      if (!this->visitVarDecl(VD))
2874
0
        return false;
2875
      // Retry.
2876
0
      return this->VisitDeclRefExpr(E);
2877
0
    }
2878
2879
0
    if (std::optional<unsigned> I = P.getOrCreateDummy(D))
2880
0
      return this->emitGetPtrGlobal(*I, E);
2881
0
  }
2882
2883
0
  return this->emitInvalidDeclRef(E, E);
2884
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitDeclRefExpr(clang::DeclRefExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitDeclRefExpr(clang::DeclRefExpr const*)
2885
2886
template <class Emitter>
2887
0
void ByteCodeExprGen<Emitter>::emitCleanup() {
2888
0
  for (VariableScope<Emitter> *C = VarScope; C; C = C->getParent())
2889
0
    C->emitDestruction();
2890
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::emitCleanup()
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::emitCleanup()
2891
2892
template <class Emitter>
2893
unsigned
2894
ByteCodeExprGen<Emitter>::collectBaseOffset(const RecordType *BaseType,
2895
0
                                            const RecordType *DerivedType) {
2896
0
  const auto *FinalDecl = cast<CXXRecordDecl>(BaseType->getDecl());
2897
0
  const RecordDecl *CurDecl = DerivedType->getDecl();
2898
0
  const Record *CurRecord = getRecord(CurDecl);
2899
0
  assert(CurDecl && FinalDecl);
2900
2901
0
  unsigned OffsetSum = 0;
2902
0
  for (;;) {
2903
0
    assert(CurRecord->getNumBases() > 0);
2904
    // One level up
2905
0
    for (const Record::Base &B : CurRecord->bases()) {
2906
0
      const auto *BaseDecl = cast<CXXRecordDecl>(B.Decl);
2907
2908
0
      if (BaseDecl == FinalDecl || BaseDecl->isDerivedFrom(FinalDecl)) {
2909
0
        OffsetSum += B.Offset;
2910
0
        CurRecord = B.R;
2911
0
        CurDecl = BaseDecl;
2912
0
        break;
2913
0
      }
2914
0
    }
2915
0
    if (CurDecl == FinalDecl)
2916
0
      break;
2917
0
  }
2918
2919
0
  assert(OffsetSum > 0);
2920
0
  return OffsetSum;
2921
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::collectBaseOffset(clang::RecordType const*, clang::RecordType const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::collectBaseOffset(clang::RecordType const*, clang::RecordType const*)
2922
2923
/// Emit casts from a PrimType to another PrimType.
2924
template <class Emitter>
2925
bool ByteCodeExprGen<Emitter>::emitPrimCast(PrimType FromT, PrimType ToT,
2926
0
                                            QualType ToQT, const Expr *E) {
2927
2928
0
  if (FromT == PT_Float) {
2929
    // Floating to floating.
2930
0
    if (ToT == PT_Float) {
2931
0
      const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
2932
0
      return this->emitCastFP(ToSem, getRoundingMode(E), E);
2933
0
    }
2934
2935
    // Float to integral.
2936
0
    if (isIntegralType(ToT) || ToT == PT_Bool)
2937
0
      return this->emitCastFloatingIntegral(ToT, E);
2938
0
  }
2939
2940
0
  if (isIntegralType(FromT) || FromT == PT_Bool) {
2941
    // Integral to integral.
2942
0
    if (isIntegralType(ToT) || ToT == PT_Bool)
2943
0
      return FromT != ToT ? this->emitCast(FromT, ToT, E) : true;
2944
2945
0
    if (ToT == PT_Float) {
2946
      // Integral to floating.
2947
0
      const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(ToQT);
2948
0
      return this->emitCastIntegralFloating(FromT, ToSem, getRoundingMode(E),
2949
0
                                            E);
2950
0
    }
2951
0
  }
2952
2953
0
  return false;
2954
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::emitPrimCast(clang::interp::PrimType, clang::interp::PrimType, clang::QualType, clang::Expr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::emitPrimCast(clang::interp::PrimType, clang::interp::PrimType, clang::QualType, clang::Expr const*)
2955
2956
/// When calling this, we have a pointer of the local-to-destroy
2957
/// on the stack.
2958
/// Emit destruction of record types (or arrays of record types).
2959
template <class Emitter>
2960
0
bool ByteCodeExprGen<Emitter>::emitRecordDestruction(const Descriptor *Desc) {
2961
0
  assert(Desc);
2962
0
  assert(!Desc->isPrimitive());
2963
0
  assert(!Desc->isPrimitiveArray());
2964
2965
  // Arrays.
2966
0
  if (Desc->isArray()) {
2967
0
    const Descriptor *ElemDesc = Desc->ElemDesc;
2968
0
    assert(ElemDesc);
2969
2970
    // Don't need to do anything for these.
2971
0
    if (ElemDesc->isPrimitiveArray())
2972
0
      return this->emitPopPtr(SourceInfo{});
2973
2974
    // If this is an array of record types, check if we need
2975
    // to call the element destructors at all. If not, try
2976
    // to save the work.
2977
0
    if (const Record *ElemRecord = ElemDesc->ElemRecord) {
2978
0
      if (const CXXDestructorDecl *Dtor = ElemRecord->getDestructor();
2979
0
          !Dtor || Dtor->isTrivial())
2980
0
        return this->emitPopPtr(SourceInfo{});
2981
0
    }
2982
2983
0
    for (ssize_t I = Desc->getNumElems() - 1; I >= 0; --I) {
2984
0
      if (!this->emitConstUint64(I, SourceInfo{}))
2985
0
        return false;
2986
0
      if (!this->emitArrayElemPtrUint64(SourceInfo{}))
2987
0
        return false;
2988
0
      if (!this->emitRecordDestruction(ElemDesc))
2989
0
        return false;
2990
0
    }
2991
0
    return this->emitPopPtr(SourceInfo{});
2992
0
  }
2993
2994
0
  const Record *R = Desc->ElemRecord;
2995
0
  assert(R);
2996
  // First, destroy all fields.
2997
0
  for (const Record::Field &Field : llvm::reverse(R->fields())) {
2998
0
    const Descriptor *D = Field.Desc;
2999
0
    if (!D->isPrimitive() && !D->isPrimitiveArray()) {
3000
0
      if (!this->emitDupPtr(SourceInfo{}))
3001
0
        return false;
3002
0
      if (!this->emitGetPtrField(Field.Offset, SourceInfo{}))
3003
0
        return false;
3004
0
      if (!this->emitRecordDestruction(D))
3005
0
        return false;
3006
0
    }
3007
0
  }
3008
3009
  // FIXME: Unions need to be handled differently here. We don't want to
3010
  //   call the destructor of its members.
3011
3012
  // Now emit the destructor and recurse into base classes.
3013
0
  if (const CXXDestructorDecl *Dtor = R->getDestructor();
3014
0
      Dtor && !Dtor->isTrivial()) {
3015
0
    if (const Function *DtorFunc = getFunction(Dtor)) {
3016
0
      assert(DtorFunc->hasThisPointer());
3017
0
      assert(DtorFunc->getNumParams() == 1);
3018
0
      if (!this->emitDupPtr(SourceInfo{}))
3019
0
        return false;
3020
0
      if (!this->emitCall(DtorFunc, SourceInfo{}))
3021
0
        return false;
3022
0
    }
3023
0
  }
3024
3025
0
  for (const Record::Base &Base : llvm::reverse(R->bases())) {
3026
0
    if (!this->emitGetPtrBase(Base.Offset, SourceInfo{}))
3027
0
      return false;
3028
0
    if (!this->emitRecordDestruction(Base.Desc))
3029
0
      return false;
3030
0
  }
3031
  // FIXME: Virtual bases.
3032
3033
  // Remove the instance pointer.
3034
0
  return this->emitPopPtr(SourceInfo{});
3035
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::emitRecordDestruction(clang::interp::Descriptor const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::emitRecordDestruction(clang::interp::Descriptor const*)
3036
3037
namespace clang {
3038
namespace interp {
3039
3040
template class ByteCodeExprGen<ByteCodeEmitter>;
3041
template class ByteCodeExprGen<EvalEmitter>;
3042
3043
} // namespace interp
3044
} // namespace clang