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 "ByteCodeStmtGen.h" |
12 | #include "Context.h" |
13 | #include "Floating.h" |
14 | #include "Function.h" |
15 | #include "InterpShared.h" |
16 | #include "PrimType.h" |
17 | #include "Program.h" |
18 | #include "clang/AST/Attr.h" |
19 | |
20 | using namespace clang; |
21 | using namespace clang::interp; |
22 | |
23 | using APSInt = llvm::APSInt; |
24 | |
25 | namespace clang { |
26 | namespace interp { |
27 | |
28 | /// Scope used to handle temporaries in toplevel variable declarations. |
29 | template <class Emitter> class DeclScope final : public VariableScope<Emitter> { |
30 | public: |
31 | DeclScope(ByteCodeExprGen<Emitter> *Ctx, const ValueDecl *VD) |
32 | : VariableScope<Emitter>(Ctx), Scope(Ctx->P, VD), |
33 | OldGlobalDecl(Ctx->GlobalDecl) { |
34 | Ctx->GlobalDecl = Context::shouldBeGloballyIndexed(VD); |
35 | } |
36 | |
37 | void addExtended(const Scope::Local &Local) override { |
38 | return this->addLocal(Local); |
39 | } |
40 | |
41 | ~DeclScope() { this->Ctx->GlobalDecl = OldGlobalDecl; } |
42 | |
43 | private: |
44 | Program::DeclScope Scope; |
45 | bool OldGlobalDecl; |
46 | }; |
47 | |
48 | /// Scope used to handle initialization methods. |
49 | template <class Emitter> class OptionScope final { |
50 | public: |
51 | /// Root constructor, compiling or discarding primitives. |
52 | OptionScope(ByteCodeExprGen<Emitter> *Ctx, bool NewDiscardResult, |
53 | bool NewInitializing) |
54 | : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult), |
55 | OldInitializing(Ctx->Initializing) { |
56 | Ctx->DiscardResult = NewDiscardResult; |
57 | Ctx->Initializing = NewInitializing; |
58 | } |
59 | |
60 | ~OptionScope() { |
61 | Ctx->DiscardResult = OldDiscardResult; |
62 | Ctx->Initializing = OldInitializing; |
63 | } |
64 | |
65 | private: |
66 | /// Parent context. |
67 | ByteCodeExprGen<Emitter> *Ctx; |
68 | /// Old discard flag to restore. |
69 | bool OldDiscardResult; |
70 | bool OldInitializing; |
71 | }; |
72 | |
73 | } // namespace interp |
74 | } // namespace clang |
75 | |
76 | template <class Emitter> |
77 | bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) { |
78 | const Expr *SubExpr = CE->getSubExpr(); |
79 | switch (CE->getCastKind()) { |
80 | |
81 | case CK_LValueToRValue: { |
82 | if (DiscardResult) |
83 | return this->discard(SubExpr); |
84 | |
85 | std::optional<PrimType> SubExprT = classify(SubExpr->getType()); |
86 | // Prepare storage for the result. |
87 | if (!Initializing && !SubExprT) { |
88 | std::optional<unsigned> LocalIndex = |
89 | allocateLocal(Decl: SubExpr, /*IsExtended=*/false); |
90 | if (!LocalIndex) |
91 | return false; |
92 | if (!this->emitGetPtrLocal(*LocalIndex, CE)) |
93 | return false; |
94 | } |
95 | |
96 | if (!this->visit(SubExpr)) |
97 | return false; |
98 | |
99 | if (SubExprT) |
100 | return this->emitLoadPop(*SubExprT, CE); |
101 | |
102 | // If the subexpr type is not primitive, we need to perform a copy here. |
103 | // This happens for example in C when dereferencing a pointer of struct |
104 | // type. |
105 | return this->emitMemcpy(CE); |
106 | } |
107 | |
108 | case CK_UncheckedDerivedToBase: |
109 | case CK_DerivedToBase: { |
110 | if (!this->visit(SubExpr)) |
111 | return false; |
112 | |
113 | unsigned DerivedOffset = collectBaseOffset(BaseType: getRecordTy(Ty: CE->getType()), |
114 | DerivedType: getRecordTy(Ty: SubExpr->getType())); |
115 | |
116 | return this->emitGetPtrBasePop(DerivedOffset, CE); |
117 | } |
118 | |
119 | case CK_BaseToDerived: { |
120 | if (!this->visit(SubExpr)) |
121 | return false; |
122 | |
123 | unsigned DerivedOffset = collectBaseOffset(BaseType: getRecordTy(Ty: SubExpr->getType()), |
124 | DerivedType: getRecordTy(Ty: CE->getType())); |
125 | |
126 | return this->emitGetPtrDerivedPop(DerivedOffset, CE); |
127 | } |
128 | |
129 | case CK_FloatingCast: { |
130 | if (DiscardResult) |
131 | return this->discard(SubExpr); |
132 | if (!this->visit(SubExpr)) |
133 | return false; |
134 | const auto *TargetSemantics = &Ctx.getFloatSemantics(T: CE->getType()); |
135 | return this->emitCastFP(TargetSemantics, getRoundingMode(E: CE), CE); |
136 | } |
137 | |
138 | case CK_IntegralToFloating: { |
139 | if (DiscardResult) |
140 | return this->discard(SubExpr); |
141 | std::optional<PrimType> FromT = classify(SubExpr->getType()); |
142 | if (!FromT) |
143 | return false; |
144 | |
145 | if (!this->visit(SubExpr)) |
146 | return false; |
147 | |
148 | const auto *TargetSemantics = &Ctx.getFloatSemantics(T: CE->getType()); |
149 | llvm::RoundingMode RM = getRoundingMode(E: CE); |
150 | return this->emitCastIntegralFloating(*FromT, TargetSemantics, RM, CE); |
151 | } |
152 | |
153 | case CK_FloatingToBoolean: |
154 | case CK_FloatingToIntegral: { |
155 | if (DiscardResult) |
156 | return this->discard(SubExpr); |
157 | |
158 | std::optional<PrimType> ToT = classify(CE->getType()); |
159 | |
160 | if (!ToT) |
161 | return false; |
162 | |
163 | if (!this->visit(SubExpr)) |
164 | return false; |
165 | |
166 | if (ToT == PT_IntAP) |
167 | return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(T: CE->getType()), |
168 | CE); |
169 | if (ToT == PT_IntAPS) |
170 | return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(T: CE->getType()), |
171 | CE); |
172 | |
173 | return this->emitCastFloatingIntegral(*ToT, CE); |
174 | } |
175 | |
176 | case CK_NullToPointer: { |
177 | if (DiscardResult) |
178 | return true; |
179 | |
180 | const Descriptor *Desc = nullptr; |
181 | const QualType PointeeType = CE->getType()->getPointeeType(); |
182 | if (!PointeeType.isNull()) { |
183 | if (std::optional<PrimType> T = classify(PointeeType)) |
184 | Desc = P.createDescriptor(D: SubExpr, Type: *T); |
185 | } |
186 | return this->emitNull(classifyPrim(CE->getType()), Desc, CE); |
187 | } |
188 | |
189 | case CK_PointerToIntegral: { |
190 | if (DiscardResult) |
191 | return this->discard(SubExpr); |
192 | |
193 | if (!this->visit(SubExpr)) |
194 | return false; |
195 | |
196 | PrimType T = classifyPrim(CE->getType()); |
197 | if (T == PT_IntAP) |
198 | return this->emitCastPointerIntegralAP(Ctx.getBitWidth(T: CE->getType()), |
199 | CE); |
200 | if (T == PT_IntAPS) |
201 | return this->emitCastPointerIntegralAPS(Ctx.getBitWidth(T: CE->getType()), |
202 | CE); |
203 | return this->emitCastPointerIntegral(T, CE); |
204 | } |
205 | |
206 | case CK_ArrayToPointerDecay: { |
207 | if (!this->visit(SubExpr)) |
208 | return false; |
209 | if (!this->emitArrayDecay(CE)) |
210 | return false; |
211 | if (DiscardResult) |
212 | return this->emitPopPtr(CE); |
213 | return true; |
214 | } |
215 | |
216 | case CK_IntegralToPointer: { |
217 | QualType IntType = SubExpr->getType(); |
218 | assert(IntType->isIntegralOrEnumerationType()); |
219 | if (!this->visit(SubExpr)) |
220 | return false; |
221 | // FIXME: I think the discard is wrong since the int->ptr cast might cause a |
222 | // diagnostic. |
223 | PrimType T = classifyPrim(IntType); |
224 | if (DiscardResult) |
225 | return this->emitPop(T, CE); |
226 | |
227 | QualType PtrType = CE->getType(); |
228 | assert(PtrType->isPointerType()); |
229 | |
230 | const Descriptor *Desc; |
231 | if (std::optional<PrimType> T = classify(PtrType->getPointeeType())) |
232 | Desc = P.createDescriptor(D: SubExpr, Type: *T); |
233 | else if (PtrType->getPointeeType()->isVoidType()) |
234 | Desc = nullptr; |
235 | else |
236 | Desc = P.createDescriptor(CE, PtrType->getPointeeType().getTypePtr(), |
237 | Descriptor::InlineDescMD, true, false, |
238 | /*IsMutable=*/false, nullptr); |
239 | |
240 | if (!this->emitGetIntPtr(T, Desc, CE)) |
241 | return false; |
242 | |
243 | PrimType DestPtrT = classifyPrim(PtrType); |
244 | if (DestPtrT == PT_Ptr) |
245 | return true; |
246 | |
247 | // In case we're converting the integer to a non-Pointer. |
248 | return this->emitDecayPtr(PT_Ptr, DestPtrT, CE); |
249 | } |
250 | |
251 | case CK_AtomicToNonAtomic: |
252 | case CK_ConstructorConversion: |
253 | case CK_FunctionToPointerDecay: |
254 | case CK_NonAtomicToAtomic: |
255 | case CK_NoOp: |
256 | case CK_UserDefinedConversion: |
257 | return this->delegate(SubExpr); |
258 | |
259 | case CK_BitCast: { |
260 | // Reject bitcasts to atomic types. |
261 | if (CE->getType()->isAtomicType()) { |
262 | if (!this->discard(SubExpr)) |
263 | return false; |
264 | return this->emitInvalidCast(CastKind::Reinterpret, CE); |
265 | } |
266 | |
267 | if (DiscardResult) |
268 | return this->discard(SubExpr); |
269 | |
270 | std::optional<PrimType> FromT = classify(SubExpr->getType()); |
271 | std::optional<PrimType> ToT = classify(CE->getType()); |
272 | if (!FromT || !ToT) |
273 | return false; |
274 | |
275 | assert(isPtrType(*FromT)); |
276 | assert(isPtrType(*ToT)); |
277 | if (FromT == ToT) |
278 | return this->delegate(SubExpr); |
279 | |
280 | if (!this->visit(SubExpr)) |
281 | return false; |
282 | return this->emitDecayPtr(*FromT, *ToT, CE); |
283 | } |
284 | |
285 | case CK_IntegralToBoolean: |
286 | case CK_IntegralCast: { |
287 | if (DiscardResult) |
288 | return this->discard(SubExpr); |
289 | std::optional<PrimType> FromT = classify(SubExpr->getType()); |
290 | std::optional<PrimType> ToT = classify(CE->getType()); |
291 | |
292 | if (!FromT || !ToT) |
293 | return false; |
294 | |
295 | if (!this->visit(SubExpr)) |
296 | return false; |
297 | |
298 | if (ToT == PT_IntAP) |
299 | return this->emitCastAP(*FromT, Ctx.getBitWidth(T: CE->getType()), CE); |
300 | if (ToT == PT_IntAPS) |
301 | return this->emitCastAPS(*FromT, Ctx.getBitWidth(T: CE->getType()), CE); |
302 | |
303 | if (FromT == ToT) |
304 | return true; |
305 | return this->emitCast(*FromT, *ToT, CE); |
306 | } |
307 | |
308 | case CK_PointerToBoolean: { |
309 | PrimType PtrT = classifyPrim(SubExpr->getType()); |
310 | |
311 | // Just emit p != nullptr for this. |
312 | if (!this->visit(SubExpr)) |
313 | return false; |
314 | |
315 | if (!this->emitNull(PtrT, nullptr, CE)) |
316 | return false; |
317 | |
318 | return this->emitNE(PtrT, CE); |
319 | } |
320 | |
321 | case CK_IntegralComplexToBoolean: |
322 | case CK_FloatingComplexToBoolean: { |
323 | if (DiscardResult) |
324 | return this->discard(SubExpr); |
325 | if (!this->visit(SubExpr)) |
326 | return false; |
327 | return this->emitComplexBoolCast(SubExpr); |
328 | } |
329 | |
330 | case CK_IntegralComplexToReal: |
331 | case CK_FloatingComplexToReal: |
332 | return this->emitComplexReal(SubExpr); |
333 | |
334 | case CK_IntegralRealToComplex: |
335 | case CK_FloatingRealToComplex: { |
336 | // We're creating a complex value here, so we need to |
337 | // allocate storage for it. |
338 | if (!Initializing) { |
339 | std::optional<unsigned> LocalIndex = |
340 | allocateLocal(Decl: CE, /*IsExtended=*/true); |
341 | if (!LocalIndex) |
342 | return false; |
343 | if (!this->emitGetPtrLocal(*LocalIndex, CE)) |
344 | return false; |
345 | } |
346 | |
347 | // Init the complex value to {SubExpr, 0}. |
348 | if (!this->visitArrayElemInit(0, SubExpr)) |
349 | return false; |
350 | // Zero-init the second element. |
351 | PrimType T = classifyPrim(SubExpr->getType()); |
352 | if (!this->visitZeroInitializer(T, SubExpr->getType(), SubExpr)) |
353 | return false; |
354 | return this->emitInitElem(T, 1, SubExpr); |
355 | } |
356 | |
357 | case CK_IntegralComplexCast: |
358 | case CK_FloatingComplexCast: |
359 | case CK_IntegralComplexToFloatingComplex: |
360 | case CK_FloatingComplexToIntegralComplex: { |
361 | assert(CE->getType()->isAnyComplexType()); |
362 | assert(SubExpr->getType()->isAnyComplexType()); |
363 | if (DiscardResult) |
364 | return this->discard(SubExpr); |
365 | |
366 | if (!Initializing) { |
367 | std::optional<unsigned> LocalIndex = |
368 | allocateLocal(Decl: CE, /*IsExtended=*/true); |
369 | if (!LocalIndex) |
370 | return false; |
371 | if (!this->emitGetPtrLocal(*LocalIndex, CE)) |
372 | return false; |
373 | } |
374 | |
375 | // Location for the SubExpr. |
376 | // Since SubExpr is of complex type, visiting it results in a pointer |
377 | // anyway, so we just create a temporary pointer variable. |
378 | unsigned SubExprOffset = allocateLocalPrimitive( |
379 | Decl: SubExpr, Ty: PT_Ptr, /*IsConst=*/true, /*IsExtended=*/false); |
380 | if (!this->visit(SubExpr)) |
381 | return false; |
382 | if (!this->emitSetLocal(PT_Ptr, SubExprOffset, CE)) |
383 | return false; |
384 | |
385 | PrimType SourceElemT = classifyComplexElementType(T: SubExpr->getType()); |
386 | QualType DestElemType = |
387 | CE->getType()->getAs<ComplexType>()->getElementType(); |
388 | PrimType DestElemT = classifyPrim(DestElemType); |
389 | // Cast both elements individually. |
390 | for (unsigned I = 0; I != 2; ++I) { |
391 | if (!this->emitGetLocal(PT_Ptr, SubExprOffset, CE)) |
392 | return false; |
393 | if (!this->emitArrayElemPop(SourceElemT, I, CE)) |
394 | return false; |
395 | |
396 | // Do the cast. |
397 | if (!this->emitPrimCast(SourceElemT, DestElemT, DestElemType, CE)) |
398 | return false; |
399 | |
400 | // Save the value. |
401 | if (!this->emitInitElem(DestElemT, I, CE)) |
402 | return false; |
403 | } |
404 | return true; |
405 | } |
406 | |
407 | case CK_VectorSplat: { |
408 | assert(!classify(CE->getType())); |
409 | assert(classify(SubExpr->getType())); |
410 | assert(CE->getType()->isVectorType()); |
411 | |
412 | if (DiscardResult) |
413 | return this->discard(SubExpr); |
414 | |
415 | assert(Initializing); // FIXME: Not always correct. |
416 | const auto *VT = CE->getType()->getAs<VectorType>(); |
417 | PrimType ElemT = classifyPrim(SubExpr); |
418 | unsigned ElemOffset = allocateLocalPrimitive( |
419 | Decl: SubExpr, Ty: ElemT, /*IsConst=*/true, /*IsExtended=*/false); |
420 | |
421 | if (!this->visit(SubExpr)) |
422 | return false; |
423 | if (!this->emitSetLocal(ElemT, ElemOffset, CE)) |
424 | return false; |
425 | |
426 | for (unsigned I = 0; I != VT->getNumElements(); ++I) { |
427 | if (!this->emitGetLocal(ElemT, ElemOffset, CE)) |
428 | return false; |
429 | if (!this->emitInitElem(ElemT, I, CE)) |
430 | return false; |
431 | } |
432 | |
433 | return true; |
434 | } |
435 | |
436 | case CK_ToVoid: |
437 | return discard(E: SubExpr); |
438 | |
439 | default: |
440 | return this->emitInvalid(CE); |
441 | } |
442 | llvm_unreachable("Unhandled clang::CastKind enum" ); |
443 | } |
444 | |
445 | template <class Emitter> |
446 | bool ByteCodeExprGen<Emitter>::VisitIntegerLiteral(const IntegerLiteral *LE) { |
447 | if (DiscardResult) |
448 | return true; |
449 | |
450 | return this->emitConst(LE->getValue(), LE); |
451 | } |
452 | |
453 | template <class Emitter> |
454 | bool ByteCodeExprGen<Emitter>::VisitFloatingLiteral(const FloatingLiteral *E) { |
455 | if (DiscardResult) |
456 | return true; |
457 | |
458 | return this->emitConstFloat(E->getValue(), E); |
459 | } |
460 | |
461 | template <class Emitter> |
462 | bool ByteCodeExprGen<Emitter>::VisitImaginaryLiteral( |
463 | const ImaginaryLiteral *E) { |
464 | assert(E->getType()->isAnyComplexType()); |
465 | if (DiscardResult) |
466 | return true; |
467 | |
468 | if (!Initializing) { |
469 | std::optional<unsigned> LocalIndex = allocateLocal(Decl: E, /*IsExtended=*/false); |
470 | if (!LocalIndex) |
471 | return false; |
472 | if (!this->emitGetPtrLocal(*LocalIndex, E)) |
473 | return false; |
474 | } |
475 | |
476 | const Expr *SubExpr = E->getSubExpr(); |
477 | PrimType SubExprT = classifyPrim(SubExpr->getType()); |
478 | |
479 | if (!this->visitZeroInitializer(SubExprT, SubExpr->getType(), SubExpr)) |
480 | return false; |
481 | if (!this->emitInitElem(SubExprT, 0, SubExpr)) |
482 | return false; |
483 | return this->visitArrayElemInit(1, SubExpr); |
484 | } |
485 | |
486 | template <class Emitter> |
487 | bool ByteCodeExprGen<Emitter>::VisitParenExpr(const ParenExpr *E) { |
488 | return this->delegate(E->getSubExpr()); |
489 | } |
490 | |
491 | template <class Emitter> |
492 | bool ByteCodeExprGen<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) { |
493 | // Need short-circuiting for these. |
494 | if (BO->isLogicalOp()) |
495 | return this->VisitLogicalBinOp(BO); |
496 | |
497 | const Expr *LHS = BO->getLHS(); |
498 | const Expr *RHS = BO->getRHS(); |
499 | |
500 | // Handle comma operators. Just discard the LHS |
501 | // and delegate to RHS. |
502 | if (BO->isCommaOp()) { |
503 | if (!this->discard(LHS)) |
504 | return false; |
505 | if (RHS->getType()->isVoidType()) |
506 | return this->discard(RHS); |
507 | |
508 | return this->delegate(RHS); |
509 | } |
510 | |
511 | if (BO->getType()->isAnyComplexType()) |
512 | return this->VisitComplexBinOp(BO); |
513 | if ((LHS->getType()->isAnyComplexType() || |
514 | RHS->getType()->isAnyComplexType()) && |
515 | BO->isComparisonOp()) |
516 | return this->emitComplexComparison(LHS, RHS, BO); |
517 | |
518 | if (BO->isPtrMemOp()) |
519 | return this->visit(RHS); |
520 | |
521 | // Typecheck the args. |
522 | std::optional<PrimType> LT = classify(LHS->getType()); |
523 | std::optional<PrimType> RT = classify(RHS->getType()); |
524 | std::optional<PrimType> T = classify(BO->getType()); |
525 | |
526 | // Special case for C++'s three-way/spaceship operator <=>, which |
527 | // returns a std::{strong,weak,partial}_ordering (which is a class, so doesn't |
528 | // have a PrimType). |
529 | if (!T && BO->getOpcode() == BO_Cmp) { |
530 | if (DiscardResult) |
531 | return true; |
532 | const ComparisonCategoryInfo *CmpInfo = |
533 | Ctx.getASTContext().CompCategories.lookupInfoForType(Ty: BO->getType()); |
534 | assert(CmpInfo); |
535 | |
536 | // We need a temporary variable holding our return value. |
537 | if (!Initializing) { |
538 | std::optional<unsigned> ResultIndex = this->allocateLocal(BO, false); |
539 | if (!this->emitGetPtrLocal(*ResultIndex, BO)) |
540 | return false; |
541 | } |
542 | |
543 | if (!visit(E: LHS) || !visit(E: RHS)) |
544 | return false; |
545 | |
546 | return this->emitCMP3(*LT, CmpInfo, BO); |
547 | } |
548 | |
549 | if (!LT || !RT || !T) |
550 | return false; |
551 | |
552 | // Pointer arithmetic special case. |
553 | if (BO->getOpcode() == BO_Add || BO->getOpcode() == BO_Sub) { |
554 | if (isPtrType(T: *T) || (isPtrType(T: *LT) && isPtrType(T: *RT))) |
555 | return this->VisitPointerArithBinOp(BO); |
556 | } |
557 | |
558 | if (!visit(E: LHS) || !visit(E: RHS)) |
559 | return false; |
560 | |
561 | // For languages such as C, cast the result of one |
562 | // of our comparision opcodes to T (which is usually int). |
563 | auto MaybeCastToBool = [this, T, BO](bool Result) { |
564 | if (!Result) |
565 | return false; |
566 | if (DiscardResult) |
567 | return this->emitPop(*T, BO); |
568 | if (T != PT_Bool) |
569 | return this->emitCast(PT_Bool, *T, BO); |
570 | return true; |
571 | }; |
572 | |
573 | auto Discard = [this, T, BO](bool Result) { |
574 | if (!Result) |
575 | return false; |
576 | return DiscardResult ? this->emitPop(*T, BO) : true; |
577 | }; |
578 | |
579 | switch (BO->getOpcode()) { |
580 | case BO_EQ: |
581 | return MaybeCastToBool(this->emitEQ(*LT, BO)); |
582 | case BO_NE: |
583 | return MaybeCastToBool(this->emitNE(*LT, BO)); |
584 | case BO_LT: |
585 | return MaybeCastToBool(this->emitLT(*LT, BO)); |
586 | case BO_LE: |
587 | return MaybeCastToBool(this->emitLE(*LT, BO)); |
588 | case BO_GT: |
589 | return MaybeCastToBool(this->emitGT(*LT, BO)); |
590 | case BO_GE: |
591 | return MaybeCastToBool(this->emitGE(*LT, BO)); |
592 | case BO_Sub: |
593 | if (BO->getType()->isFloatingType()) |
594 | return Discard(this->emitSubf(getRoundingMode(E: BO), BO)); |
595 | return Discard(this->emitSub(*T, BO)); |
596 | case BO_Add: |
597 | if (BO->getType()->isFloatingType()) |
598 | return Discard(this->emitAddf(getRoundingMode(E: BO), BO)); |
599 | return Discard(this->emitAdd(*T, BO)); |
600 | case BO_Mul: |
601 | if (BO->getType()->isFloatingType()) |
602 | return Discard(this->emitMulf(getRoundingMode(E: BO), BO)); |
603 | return Discard(this->emitMul(*T, BO)); |
604 | case BO_Rem: |
605 | return Discard(this->emitRem(*T, BO)); |
606 | case BO_Div: |
607 | if (BO->getType()->isFloatingType()) |
608 | return Discard(this->emitDivf(getRoundingMode(E: BO), BO)); |
609 | return Discard(this->emitDiv(*T, BO)); |
610 | case BO_Assign: |
611 | if (DiscardResult) |
612 | return LHS->refersToBitField() ? this->emitStoreBitFieldPop(*T, BO) |
613 | : this->emitStorePop(*T, BO); |
614 | if (LHS->refersToBitField()) { |
615 | if (!this->emitStoreBitField(*T, BO)) |
616 | return false; |
617 | } else { |
618 | if (!this->emitStore(*T, BO)) |
619 | return false; |
620 | } |
621 | // Assignments aren't necessarily lvalues in C. |
622 | // Load from them in that case. |
623 | if (!BO->isLValue()) |
624 | return this->emitLoadPop(*T, BO); |
625 | return true; |
626 | case BO_And: |
627 | return Discard(this->emitBitAnd(*T, BO)); |
628 | case BO_Or: |
629 | return Discard(this->emitBitOr(*T, BO)); |
630 | case BO_Shl: |
631 | return Discard(this->emitShl(*LT, *RT, BO)); |
632 | case BO_Shr: |
633 | return Discard(this->emitShr(*LT, *RT, BO)); |
634 | case BO_Xor: |
635 | return Discard(this->emitBitXor(*T, BO)); |
636 | case BO_LOr: |
637 | case BO_LAnd: |
638 | llvm_unreachable("Already handled earlier" ); |
639 | default: |
640 | return false; |
641 | } |
642 | |
643 | llvm_unreachable("Unhandled binary op" ); |
644 | } |
645 | |
646 | /// Perform addition/subtraction of a pointer and an integer or |
647 | /// subtraction of two pointers. |
648 | template <class Emitter> |
649 | bool ByteCodeExprGen<Emitter>::VisitPointerArithBinOp(const BinaryOperator *E) { |
650 | BinaryOperatorKind Op = E->getOpcode(); |
651 | const Expr *LHS = E->getLHS(); |
652 | const Expr *RHS = E->getRHS(); |
653 | |
654 | if ((Op != BO_Add && Op != BO_Sub) || |
655 | (!LHS->getType()->isPointerType() && !RHS->getType()->isPointerType())) |
656 | return false; |
657 | |
658 | std::optional<PrimType> LT = classify(LHS); |
659 | std::optional<PrimType> RT = classify(RHS); |
660 | |
661 | if (!LT || !RT) |
662 | return false; |
663 | |
664 | if (LHS->getType()->isPointerType() && RHS->getType()->isPointerType()) { |
665 | if (Op != BO_Sub) |
666 | return false; |
667 | |
668 | assert(E->getType()->isIntegerType()); |
669 | if (!visit(E: RHS) || !visit(E: LHS)) |
670 | return false; |
671 | |
672 | return this->emitSubPtr(classifyPrim(E->getType()), E); |
673 | } |
674 | |
675 | PrimType OffsetType; |
676 | if (LHS->getType()->isIntegerType()) { |
677 | if (!visit(E: RHS) || !visit(E: LHS)) |
678 | return false; |
679 | OffsetType = *LT; |
680 | } else if (RHS->getType()->isIntegerType()) { |
681 | if (!visit(E: LHS) || !visit(E: RHS)) |
682 | return false; |
683 | OffsetType = *RT; |
684 | } else { |
685 | return false; |
686 | } |
687 | |
688 | if (Op == BO_Add) |
689 | return this->emitAddOffset(OffsetType, E); |
690 | else if (Op == BO_Sub) |
691 | return this->emitSubOffset(OffsetType, E); |
692 | |
693 | return false; |
694 | } |
695 | |
696 | template <class Emitter> |
697 | bool ByteCodeExprGen<Emitter>::VisitLogicalBinOp(const BinaryOperator *E) { |
698 | assert(E->isLogicalOp()); |
699 | BinaryOperatorKind Op = E->getOpcode(); |
700 | const Expr *LHS = E->getLHS(); |
701 | const Expr *RHS = E->getRHS(); |
702 | std::optional<PrimType> T = classify(E->getType()); |
703 | |
704 | if (Op == BO_LOr) { |
705 | // Logical OR. Visit LHS and only evaluate RHS if LHS was FALSE. |
706 | LabelTy LabelTrue = this->getLabel(); |
707 | LabelTy LabelEnd = this->getLabel(); |
708 | |
709 | if (!this->visitBool(LHS)) |
710 | return false; |
711 | if (!this->jumpTrue(LabelTrue)) |
712 | return false; |
713 | |
714 | if (!this->visitBool(RHS)) |
715 | return false; |
716 | if (!this->jump(LabelEnd)) |
717 | return false; |
718 | |
719 | this->emitLabel(LabelTrue); |
720 | this->emitConstBool(true, E); |
721 | this->fallthrough(LabelEnd); |
722 | this->emitLabel(LabelEnd); |
723 | |
724 | } else { |
725 | assert(Op == BO_LAnd); |
726 | // Logical AND. |
727 | // Visit LHS. Only visit RHS if LHS was TRUE. |
728 | LabelTy LabelFalse = this->getLabel(); |
729 | LabelTy LabelEnd = this->getLabel(); |
730 | |
731 | if (!this->visitBool(LHS)) |
732 | return false; |
733 | if (!this->jumpFalse(LabelFalse)) |
734 | return false; |
735 | |
736 | if (!this->visitBool(RHS)) |
737 | return false; |
738 | if (!this->jump(LabelEnd)) |
739 | return false; |
740 | |
741 | this->emitLabel(LabelFalse); |
742 | this->emitConstBool(false, E); |
743 | this->fallthrough(LabelEnd); |
744 | this->emitLabel(LabelEnd); |
745 | } |
746 | |
747 | if (DiscardResult) |
748 | return this->emitPopBool(E); |
749 | |
750 | // For C, cast back to integer type. |
751 | assert(T); |
752 | if (T != PT_Bool) |
753 | return this->emitCast(PT_Bool, *T, E); |
754 | return true; |
755 | } |
756 | |
757 | template <class Emitter> |
758 | bool ByteCodeExprGen<Emitter>::VisitComplexBinOp(const BinaryOperator *E) { |
759 | // Prepare storage for result. |
760 | if (!Initializing) { |
761 | std::optional<unsigned> LocalIndex = allocateLocal(Decl: E, /*IsExtended=*/false); |
762 | if (!LocalIndex) |
763 | return false; |
764 | if (!this->emitGetPtrLocal(*LocalIndex, E)) |
765 | return false; |
766 | } |
767 | |
768 | // Both LHS and RHS might _not_ be of complex type, but one of them |
769 | // needs to be. |
770 | const Expr *LHS = E->getLHS(); |
771 | const Expr *RHS = E->getRHS(); |
772 | |
773 | PrimType ResultElemT = this->classifyComplexElementType(E->getType()); |
774 | unsigned ResultOffset = ~0u; |
775 | if (!DiscardResult) |
776 | ResultOffset = this->allocateLocalPrimitive(E, PT_Ptr, true, false); |
777 | |
778 | // Save result pointer in ResultOffset |
779 | if (!this->DiscardResult) { |
780 | if (!this->emitDupPtr(E)) |
781 | return false; |
782 | if (!this->emitSetLocal(PT_Ptr, ResultOffset, E)) |
783 | return false; |
784 | } |
785 | QualType LHSType = LHS->getType(); |
786 | if (const auto *AT = LHSType->getAs<AtomicType>()) |
787 | LHSType = AT->getValueType(); |
788 | QualType RHSType = RHS->getType(); |
789 | if (const auto *AT = RHSType->getAs<AtomicType>()) |
790 | RHSType = AT->getValueType(); |
791 | |
792 | // Evaluate LHS and save value to LHSOffset. |
793 | bool LHSIsComplex; |
794 | unsigned LHSOffset; |
795 | if (LHSType->isAnyComplexType()) { |
796 | LHSIsComplex = true; |
797 | LHSOffset = this->allocateLocalPrimitive(LHS, PT_Ptr, true, false); |
798 | if (!this->visit(LHS)) |
799 | return false; |
800 | if (!this->emitSetLocal(PT_Ptr, LHSOffset, E)) |
801 | return false; |
802 | } else { |
803 | LHSIsComplex = false; |
804 | PrimType LHST = classifyPrim(LHSType); |
805 | LHSOffset = this->allocateLocalPrimitive(LHS, LHST, true, false); |
806 | if (!this->visit(LHS)) |
807 | return false; |
808 | if (!this->emitSetLocal(LHST, LHSOffset, E)) |
809 | return false; |
810 | } |
811 | |
812 | // Same with RHS. |
813 | bool RHSIsComplex; |
814 | unsigned RHSOffset; |
815 | if (RHSType->isAnyComplexType()) { |
816 | RHSIsComplex = true; |
817 | RHSOffset = this->allocateLocalPrimitive(RHS, PT_Ptr, true, false); |
818 | if (!this->visit(RHS)) |
819 | return false; |
820 | if (!this->emitSetLocal(PT_Ptr, RHSOffset, E)) |
821 | return false; |
822 | } else { |
823 | RHSIsComplex = false; |
824 | PrimType RHST = classifyPrim(RHSType); |
825 | RHSOffset = this->allocateLocalPrimitive(RHS, RHST, true, false); |
826 | if (!this->visit(RHS)) |
827 | return false; |
828 | if (!this->emitSetLocal(RHST, RHSOffset, E)) |
829 | return false; |
830 | } |
831 | |
832 | // For both LHS and RHS, either load the value from the complex pointer, or |
833 | // directly from the local variable. For index 1 (i.e. the imaginary part), |
834 | // just load 0 and do the operation anyway. |
835 | auto loadComplexValue = [this](bool IsComplex, unsigned ElemIndex, |
836 | unsigned Offset, const Expr *E) -> bool { |
837 | if (IsComplex) { |
838 | if (!this->emitGetLocal(PT_Ptr, Offset, E)) |
839 | return false; |
840 | return this->emitArrayElemPop(classifyComplexElementType(T: E->getType()), |
841 | ElemIndex, E); |
842 | } |
843 | if (ElemIndex == 0) |
844 | return this->emitGetLocal(classifyPrim(E->getType()), Offset, E); |
845 | return this->visitZeroInitializer(classifyPrim(E->getType()), E->getType(), |
846 | E); |
847 | }; |
848 | |
849 | // Now we can get pointers to the LHS and RHS from the offsets above. |
850 | BinaryOperatorKind Op = E->getOpcode(); |
851 | for (unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) { |
852 | // Result pointer for the store later. |
853 | if (!this->DiscardResult) { |
854 | if (!this->emitGetLocal(PT_Ptr, ResultOffset, E)) |
855 | return false; |
856 | } |
857 | |
858 | if (!loadComplexValue(LHSIsComplex, ElemIndex, LHSOffset, LHS)) |
859 | return false; |
860 | |
861 | if (!loadComplexValue(RHSIsComplex, ElemIndex, RHSOffset, RHS)) |
862 | return false; |
863 | |
864 | // The actual operation. |
865 | switch (Op) { |
866 | case BO_Add: |
867 | if (ResultElemT == PT_Float) { |
868 | if (!this->emitAddf(getRoundingMode(E), E)) |
869 | return false; |
870 | } else { |
871 | if (!this->emitAdd(ResultElemT, E)) |
872 | return false; |
873 | } |
874 | break; |
875 | case BO_Sub: |
876 | if (ResultElemT == PT_Float) { |
877 | if (!this->emitSubf(getRoundingMode(E), E)) |
878 | return false; |
879 | } else { |
880 | if (!this->emitSub(ResultElemT, E)) |
881 | return false; |
882 | } |
883 | break; |
884 | |
885 | default: |
886 | return false; |
887 | } |
888 | |
889 | if (!this->DiscardResult) { |
890 | // Initialize array element with the value we just computed. |
891 | if (!this->emitInitElemPop(ResultElemT, ElemIndex, E)) |
892 | return false; |
893 | } else { |
894 | if (!this->emitPop(ResultElemT, E)) |
895 | return false; |
896 | } |
897 | } |
898 | return true; |
899 | } |
900 | |
901 | template <class Emitter> |
902 | bool ByteCodeExprGen<Emitter>::VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) { |
903 | QualType QT = E->getType(); |
904 | |
905 | if (std::optional<PrimType> T = classify(QT)) |
906 | return this->visitZeroInitializer(*T, QT, E); |
907 | |
908 | if (QT->isRecordType()) |
909 | return false; |
910 | |
911 | if (QT->isIncompleteArrayType()) |
912 | return true; |
913 | |
914 | if (QT->isArrayType()) { |
915 | const ArrayType *AT = QT->getAsArrayTypeUnsafe(); |
916 | assert(AT); |
917 | const auto *CAT = cast<ConstantArrayType>(Val: AT); |
918 | size_t NumElems = CAT->getZExtSize(); |
919 | PrimType ElemT = classifyPrim(CAT->getElementType()); |
920 | |
921 | for (size_t I = 0; I != NumElems; ++I) { |
922 | if (!this->visitZeroInitializer(ElemT, CAT->getElementType(), E)) |
923 | return false; |
924 | if (!this->emitInitElem(ElemT, I, E)) |
925 | return false; |
926 | } |
927 | |
928 | return true; |
929 | } |
930 | |
931 | if (const auto *ComplexTy = E->getType()->getAs<ComplexType>()) { |
932 | assert(Initializing); |
933 | QualType ElemQT = ComplexTy->getElementType(); |
934 | PrimType ElemT = classifyPrim(ElemQT); |
935 | for (unsigned I = 0; I < 2; ++I) { |
936 | if (!this->visitZeroInitializer(ElemT, ElemQT, E)) |
937 | return false; |
938 | if (!this->emitInitElem(ElemT, I, E)) |
939 | return false; |
940 | } |
941 | return true; |
942 | } |
943 | |
944 | if (const auto *VecT = E->getType()->getAs<VectorType>()) { |
945 | unsigned NumVecElements = VecT->getNumElements(); |
946 | QualType ElemQT = VecT->getElementType(); |
947 | PrimType ElemT = classifyPrim(ElemQT); |
948 | |
949 | for (unsigned I = 0; I < NumVecElements; ++I) { |
950 | if (!this->visitZeroInitializer(ElemT, ElemQT, E)) |
951 | return false; |
952 | if (!this->emitInitElem(ElemT, I, E)) |
953 | return false; |
954 | } |
955 | return true; |
956 | } |
957 | |
958 | return false; |
959 | } |
960 | |
961 | template <class Emitter> |
962 | bool ByteCodeExprGen<Emitter>::VisitArraySubscriptExpr( |
963 | const ArraySubscriptExpr *E) { |
964 | const Expr *Base = E->getBase(); |
965 | const Expr *Index = E->getIdx(); |
966 | |
967 | if (DiscardResult) |
968 | return this->discard(Base) && this->discard(Index); |
969 | |
970 | // Take pointer of LHS, add offset from RHS. |
971 | // What's left on the stack after this is a pointer. |
972 | if (!this->visit(Base)) |
973 | return false; |
974 | |
975 | if (!this->visit(Index)) |
976 | return false; |
977 | |
978 | PrimType IndexT = classifyPrim(Index->getType()); |
979 | return this->emitArrayElemPtrPop(IndexT, E); |
980 | } |
981 | |
982 | template <class Emitter> |
983 | bool ByteCodeExprGen<Emitter>::visitInitList(ArrayRef<const Expr *> Inits, |
984 | const Expr *E) { |
985 | assert(E->getType()->isRecordType()); |
986 | const Record *R = getRecord(E->getType()); |
987 | |
988 | if (Inits.size() == 1 && E->getType() == Inits[0]->getType()) { |
989 | return this->visitInitializer(Inits[0]); |
990 | } |
991 | |
992 | unsigned InitIndex = 0; |
993 | for (const Expr *Init : Inits) { |
994 | // Skip unnamed bitfields. |
995 | while (InitIndex < R->getNumFields() && |
996 | R->getField(I: InitIndex)->Decl->isUnnamedBitField()) |
997 | ++InitIndex; |
998 | |
999 | if (!this->emitDupPtr(E)) |
1000 | return false; |
1001 | |
1002 | if (std::optional<PrimType> T = classify(Init)) { |
1003 | const Record::Field *FieldToInit = R->getField(I: InitIndex); |
1004 | if (!this->visit(Init)) |
1005 | return false; |
1006 | |
1007 | if (FieldToInit->isBitField()) { |
1008 | if (!this->emitInitBitField(*T, FieldToInit, E)) |
1009 | return false; |
1010 | } else { |
1011 | if (!this->emitInitField(*T, FieldToInit->Offset, E)) |
1012 | return false; |
1013 | } |
1014 | |
1015 | if (!this->emitPopPtr(E)) |
1016 | return false; |
1017 | ++InitIndex; |
1018 | } else { |
1019 | // Initializer for a direct base class. |
1020 | if (const Record::Base *B = R->getBase(T: Init->getType())) { |
1021 | if (!this->emitGetPtrBasePop(B->Offset, Init)) |
1022 | return false; |
1023 | |
1024 | if (!this->visitInitializer(Init)) |
1025 | return false; |
1026 | |
1027 | if (!this->emitFinishInitPop(E)) |
1028 | return false; |
1029 | // Base initializers don't increase InitIndex, since they don't count |
1030 | // into the Record's fields. |
1031 | } else { |
1032 | const Record::Field *FieldToInit = R->getField(I: InitIndex); |
1033 | // Non-primitive case. Get a pointer to the field-to-initialize |
1034 | // on the stack and recurse into visitInitializer(). |
1035 | if (!this->emitGetPtrField(FieldToInit->Offset, Init)) |
1036 | return false; |
1037 | |
1038 | if (!this->visitInitializer(Init)) |
1039 | return false; |
1040 | |
1041 | if (!this->emitPopPtr(E)) |
1042 | return false; |
1043 | ++InitIndex; |
1044 | } |
1045 | } |
1046 | } |
1047 | return true; |
1048 | } |
1049 | |
1050 | /// Pointer to the array(not the element!) must be on the stack when calling |
1051 | /// this. |
1052 | template <class Emitter> |
1053 | bool ByteCodeExprGen<Emitter>::visitArrayElemInit(unsigned ElemIndex, |
1054 | const Expr *Init) { |
1055 | if (std::optional<PrimType> T = classify(Init->getType())) { |
1056 | // Visit the primitive element like normal. |
1057 | if (!this->visit(Init)) |
1058 | return false; |
1059 | return this->emitInitElem(*T, ElemIndex, Init); |
1060 | } |
1061 | |
1062 | // Advance the pointer currently on the stack to the given |
1063 | // dimension. |
1064 | if (!this->emitConstUint32(ElemIndex, Init)) |
1065 | return false; |
1066 | if (!this->emitArrayElemPtrUint32(Init)) |
1067 | return false; |
1068 | if (!this->visitInitializer(Init)) |
1069 | return false; |
1070 | return this->emitFinishInitPop(Init); |
1071 | } |
1072 | |
1073 | template <class Emitter> |
1074 | bool ByteCodeExprGen<Emitter>::VisitInitListExpr(const InitListExpr *E) { |
1075 | // Handle discarding first. |
1076 | if (DiscardResult) { |
1077 | for (const Expr *Init : E->inits()) { |
1078 | if (!this->discard(Init)) |
1079 | return false; |
1080 | } |
1081 | return true; |
1082 | } |
1083 | |
1084 | // Primitive values. |
1085 | if (std::optional<PrimType> T = classify(E->getType())) { |
1086 | assert(!DiscardResult); |
1087 | if (E->getNumInits() == 0) |
1088 | return this->visitZeroInitializer(*T, E->getType(), E); |
1089 | assert(E->getNumInits() == 1); |
1090 | return this->delegate(E->inits()[0]); |
1091 | } |
1092 | |
1093 | QualType T = E->getType(); |
1094 | if (T->isRecordType()) |
1095 | return this->visitInitList(E->inits(), E); |
1096 | |
1097 | if (T->isArrayType()) { |
1098 | unsigned ElementIndex = 0; |
1099 | for (const Expr *Init : E->inits()) { |
1100 | if (!this->visitArrayElemInit(ElementIndex, Init)) |
1101 | return false; |
1102 | ++ElementIndex; |
1103 | } |
1104 | |
1105 | // Expand the filler expression. |
1106 | // FIXME: This should go away. |
1107 | if (const Expr *Filler = E->getArrayFiller()) { |
1108 | const ConstantArrayType *CAT = |
1109 | Ctx.getASTContext().getAsConstantArrayType(T: E->getType()); |
1110 | uint64_t NumElems = CAT->getZExtSize(); |
1111 | |
1112 | for (; ElementIndex != NumElems; ++ElementIndex) { |
1113 | if (!this->visitArrayElemInit(ElementIndex, Filler)) |
1114 | return false; |
1115 | } |
1116 | } |
1117 | |
1118 | return true; |
1119 | } |
1120 | |
1121 | if (const auto *ComplexTy = E->getType()->getAs<ComplexType>()) { |
1122 | unsigned NumInits = E->getNumInits(); |
1123 | |
1124 | if (NumInits == 1) |
1125 | return this->delegate(E->inits()[0]); |
1126 | |
1127 | QualType ElemQT = ComplexTy->getElementType(); |
1128 | PrimType ElemT = classifyPrim(ElemQT); |
1129 | if (NumInits == 0) { |
1130 | // Zero-initialize both elements. |
1131 | for (unsigned I = 0; I < 2; ++I) { |
1132 | if (!this->visitZeroInitializer(ElemT, ElemQT, E)) |
1133 | return false; |
1134 | if (!this->emitInitElem(ElemT, I, E)) |
1135 | return false; |
1136 | } |
1137 | } else if (NumInits == 2) { |
1138 | unsigned InitIndex = 0; |
1139 | for (const Expr *Init : E->inits()) { |
1140 | if (!this->visit(Init)) |
1141 | return false; |
1142 | |
1143 | if (!this->emitInitElem(ElemT, InitIndex, E)) |
1144 | return false; |
1145 | ++InitIndex; |
1146 | } |
1147 | } |
1148 | return true; |
1149 | } |
1150 | |
1151 | if (const auto *VecT = E->getType()->getAs<VectorType>()) { |
1152 | unsigned NumVecElements = VecT->getNumElements(); |
1153 | assert(NumVecElements >= E->getNumInits()); |
1154 | |
1155 | QualType ElemQT = VecT->getElementType(); |
1156 | PrimType ElemT = classifyPrim(ElemQT); |
1157 | |
1158 | // All initializer elements. |
1159 | unsigned InitIndex = 0; |
1160 | for (const Expr *Init : E->inits()) { |
1161 | if (!this->visit(Init)) |
1162 | return false; |
1163 | |
1164 | if (!this->emitInitElem(ElemT, InitIndex, E)) |
1165 | return false; |
1166 | ++InitIndex; |
1167 | } |
1168 | |
1169 | // Fill the rest with zeroes. |
1170 | for (; InitIndex != NumVecElements; ++InitIndex) { |
1171 | if (!this->visitZeroInitializer(ElemT, ElemQT, E)) |
1172 | return false; |
1173 | if (!this->emitInitElem(ElemT, InitIndex, E)) |
1174 | return false; |
1175 | } |
1176 | return true; |
1177 | } |
1178 | |
1179 | return false; |
1180 | } |
1181 | |
1182 | template <class Emitter> |
1183 | bool ByteCodeExprGen<Emitter>::VisitCXXParenListInitExpr( |
1184 | const CXXParenListInitExpr *E) { |
1185 | if (DiscardResult) { |
1186 | for (const Expr *Init : E->getInitExprs()) { |
1187 | if (!this->discard(Init)) |
1188 | return false; |
1189 | } |
1190 | return true; |
1191 | } |
1192 | |
1193 | assert(E->getType()->isRecordType()); |
1194 | return this->visitInitList(E->getInitExprs(), E); |
1195 | } |
1196 | |
1197 | template <class Emitter> |
1198 | bool ByteCodeExprGen<Emitter>::VisitSubstNonTypeTemplateParmExpr( |
1199 | const SubstNonTypeTemplateParmExpr *E) { |
1200 | return this->delegate(E->getReplacement()); |
1201 | } |
1202 | |
1203 | template <class Emitter> |
1204 | bool ByteCodeExprGen<Emitter>::VisitConstantExpr(const ConstantExpr *E) { |
1205 | std::optional<PrimType> T = classify(E->getType()); |
1206 | if (T && E->hasAPValueResult()) { |
1207 | // Try to emit the APValue directly, without visiting the subexpr. |
1208 | // This will only fail if we can't emit the APValue, so won't emit any |
1209 | // diagnostics or any double values. |
1210 | if (DiscardResult) |
1211 | return true; |
1212 | |
1213 | if (this->visitAPValue(E->getAPValueResult(), *T, E)) |
1214 | return true; |
1215 | } |
1216 | return this->delegate(E->getSubExpr()); |
1217 | } |
1218 | |
1219 | static CharUnits AlignOfType(QualType T, const ASTContext &ASTCtx, |
1220 | UnaryExprOrTypeTrait Kind) { |
1221 | bool AlignOfReturnsPreferred = |
1222 | ASTCtx.getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7; |
1223 | |
1224 | // C++ [expr.alignof]p3: |
1225 | // When alignof is applied to a reference type, the result is the |
1226 | // alignment of the referenced type. |
1227 | if (const auto *Ref = T->getAs<ReferenceType>()) |
1228 | T = Ref->getPointeeType(); |
1229 | |
1230 | if (T.getQualifiers().hasUnaligned()) |
1231 | return CharUnits::One(); |
1232 | |
1233 | // __alignof is defined to return the preferred alignment. |
1234 | // Before 8, clang returned the preferred alignment for alignof and |
1235 | // _Alignof as well. |
1236 | if (Kind == UETT_PreferredAlignOf || AlignOfReturnsPreferred) |
1237 | return ASTCtx.toCharUnitsFromBits(BitSize: ASTCtx.getPreferredTypeAlign(T)); |
1238 | |
1239 | return ASTCtx.getTypeAlignInChars(T); |
1240 | } |
1241 | |
1242 | template <class Emitter> |
1243 | bool ByteCodeExprGen<Emitter>::VisitUnaryExprOrTypeTraitExpr( |
1244 | const UnaryExprOrTypeTraitExpr *E) { |
1245 | UnaryExprOrTypeTrait Kind = E->getKind(); |
1246 | const ASTContext &ASTCtx = Ctx.getASTContext(); |
1247 | |
1248 | if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) { |
1249 | QualType ArgType = E->getTypeOfArgument(); |
1250 | |
1251 | // C++ [expr.sizeof]p2: "When applied to a reference or a reference type, |
1252 | // the result is the size of the referenced type." |
1253 | if (const auto *Ref = ArgType->getAs<ReferenceType>()) |
1254 | ArgType = Ref->getPointeeType(); |
1255 | |
1256 | CharUnits Size; |
1257 | if (ArgType->isVoidType() || ArgType->isFunctionType()) |
1258 | Size = CharUnits::One(); |
1259 | else { |
1260 | if (ArgType->isDependentType() || !ArgType->isConstantSizeType()) |
1261 | return false; |
1262 | |
1263 | if (Kind == UETT_SizeOf) |
1264 | Size = ASTCtx.getTypeSizeInChars(T: ArgType); |
1265 | else |
1266 | Size = ASTCtx.getTypeInfoDataSizeInChars(T: ArgType).Width; |
1267 | } |
1268 | |
1269 | if (DiscardResult) |
1270 | return true; |
1271 | |
1272 | return this->emitConst(Size.getQuantity(), E); |
1273 | } |
1274 | |
1275 | if (Kind == UETT_AlignOf || Kind == UETT_PreferredAlignOf) { |
1276 | CharUnits Size; |
1277 | |
1278 | if (E->isArgumentType()) { |
1279 | QualType ArgType = E->getTypeOfArgument(); |
1280 | |
1281 | Size = AlignOfType(T: ArgType, ASTCtx, Kind); |
1282 | } else { |
1283 | // Argument is an expression, not a type. |
1284 | const Expr *Arg = E->getArgumentExpr()->IgnoreParens(); |
1285 | |
1286 | // The kinds of expressions that we have special-case logic here for |
1287 | // should be kept up to date with the special checks for those |
1288 | // expressions in Sema. |
1289 | |
1290 | // alignof decl is always accepted, even if it doesn't make sense: we |
1291 | // default to 1 in those cases. |
1292 | if (const auto *DRE = dyn_cast<DeclRefExpr>(Val: Arg)) |
1293 | Size = ASTCtx.getDeclAlign(DRE->getDecl(), |
1294 | /*RefAsPointee*/ true); |
1295 | else if (const auto *ME = dyn_cast<MemberExpr>(Val: Arg)) |
1296 | Size = ASTCtx.getDeclAlign(ME->getMemberDecl(), |
1297 | /*RefAsPointee*/ true); |
1298 | else |
1299 | Size = AlignOfType(T: Arg->getType(), ASTCtx, Kind); |
1300 | } |
1301 | |
1302 | if (DiscardResult) |
1303 | return true; |
1304 | |
1305 | return this->emitConst(Size.getQuantity(), E); |
1306 | } |
1307 | |
1308 | if (Kind == UETT_VectorElements) { |
1309 | if (const auto *VT = E->getTypeOfArgument()->getAs<VectorType>()) |
1310 | return this->emitConst(VT->getNumElements(), E); |
1311 | |
1312 | // FIXME: Apparently we need to catch the fact that a sizeless vector type |
1313 | // has been passed and diagnose that (at run time). |
1314 | assert(E->getTypeOfArgument()->isSizelessVectorType()); |
1315 | } |
1316 | |
1317 | return false; |
1318 | } |
1319 | |
1320 | template <class Emitter> |
1321 | bool ByteCodeExprGen<Emitter>::VisitMemberExpr(const MemberExpr *E) { |
1322 | // 'Base.Member' |
1323 | const Expr *Base = E->getBase(); |
1324 | const ValueDecl *Member = E->getMemberDecl(); |
1325 | |
1326 | if (DiscardResult) |
1327 | return this->discard(Base); |
1328 | |
1329 | // MemberExprs are almost always lvalues, in which case we don't need to |
1330 | // do the load. But sometimes they aren't. |
1331 | const auto maybeLoadValue = [&]() -> bool { |
1332 | if (E->isGLValue()) |
1333 | return true; |
1334 | if (std::optional<PrimType> T = classify(E)) |
1335 | return this->emitLoadPop(*T, E); |
1336 | return false; |
1337 | }; |
1338 | |
1339 | if (const auto *VD = dyn_cast<VarDecl>(Val: Member)) { |
1340 | // I am almost confident in saying that a var decl must be static |
1341 | // and therefore registered as a global variable. But this will probably |
1342 | // turn out to be wrong some time in the future, as always. |
1343 | if (auto GlobalIndex = P.getGlobal(VD)) |
1344 | return this->emitGetPtrGlobal(*GlobalIndex, E) && maybeLoadValue(); |
1345 | return false; |
1346 | } |
1347 | |
1348 | if (Initializing) { |
1349 | if (!this->delegate(Base)) |
1350 | return false; |
1351 | } else { |
1352 | if (!this->visit(Base)) |
1353 | return false; |
1354 | } |
1355 | |
1356 | // Base above gives us a pointer on the stack. |
1357 | if (const auto *FD = dyn_cast<FieldDecl>(Val: Member)) { |
1358 | const RecordDecl *RD = FD->getParent(); |
1359 | const Record *R = getRecord(RD); |
1360 | if (!R) |
1361 | return false; |
1362 | const Record::Field *F = R->getField(FD); |
1363 | // Leave a pointer to the field on the stack. |
1364 | if (F->Decl->getType()->isReferenceType()) |
1365 | return this->emitGetFieldPop(PT_Ptr, F->Offset, E) && maybeLoadValue(); |
1366 | return this->emitGetPtrField(F->Offset, E) && maybeLoadValue(); |
1367 | } |
1368 | |
1369 | return false; |
1370 | } |
1371 | |
1372 | template <class Emitter> |
1373 | bool ByteCodeExprGen<Emitter>::VisitArrayInitIndexExpr( |
1374 | const ArrayInitIndexExpr *E) { |
1375 | // ArrayIndex might not be set if a ArrayInitIndexExpr is being evaluated |
1376 | // stand-alone, e.g. via EvaluateAsInt(). |
1377 | if (!ArrayIndex) |
1378 | return false; |
1379 | return this->emitConst(*ArrayIndex, E); |
1380 | } |
1381 | |
1382 | template <class Emitter> |
1383 | bool ByteCodeExprGen<Emitter>::VisitArrayInitLoopExpr( |
1384 | const ArrayInitLoopExpr *E) { |
1385 | assert(Initializing); |
1386 | assert(!DiscardResult); |
1387 | |
1388 | // We visit the common opaque expression here once so we have its value |
1389 | // cached. |
1390 | if (!this->discard(E->getCommonExpr())) |
1391 | return false; |
1392 | |
1393 | // TODO: This compiles to quite a lot of bytecode if the array is larger. |
1394 | // Investigate compiling this to a loop. |
1395 | const Expr *SubExpr = E->getSubExpr(); |
1396 | size_t Size = E->getArraySize().getZExtValue(); |
1397 | |
1398 | // So, every iteration, we execute an assignment here |
1399 | // where the LHS is on the stack (the target array) |
1400 | // and the RHS is our SubExpr. |
1401 | for (size_t I = 0; I != Size; ++I) { |
1402 | ArrayIndexScope<Emitter> IndexScope(this, I); |
1403 | BlockScope<Emitter> BS(this); |
1404 | |
1405 | if (!this->visitArrayElemInit(I, SubExpr)) |
1406 | return false; |
1407 | } |
1408 | return true; |
1409 | } |
1410 | |
1411 | template <class Emitter> |
1412 | bool ByteCodeExprGen<Emitter>::VisitOpaqueValueExpr(const OpaqueValueExpr *E) { |
1413 | const Expr *SourceExpr = E->getSourceExpr(); |
1414 | if (!SourceExpr) |
1415 | return false; |
1416 | |
1417 | if (Initializing) |
1418 | return this->visitInitializer(SourceExpr); |
1419 | |
1420 | PrimType SubExprT = classify(SourceExpr).value_or(PT_Ptr); |
1421 | if (auto It = OpaqueExprs.find(Val: E); It != OpaqueExprs.end()) |
1422 | return this->emitGetLocal(SubExprT, It->second, E); |
1423 | |
1424 | if (!this->visit(SourceExpr)) |
1425 | return false; |
1426 | |
1427 | // At this point we either have the evaluated source expression or a pointer |
1428 | // to an object on the stack. We want to create a local variable that stores |
1429 | // this value. |
1430 | unsigned LocalIndex = allocateLocalPrimitive(Decl: E, Ty: SubExprT, /*IsConst=*/true); |
1431 | if (!this->emitSetLocal(SubExprT, LocalIndex, E)) |
1432 | return false; |
1433 | |
1434 | // Here the local variable is created but the value is removed from the stack, |
1435 | // so we put it back if the caller needs it. |
1436 | if (!DiscardResult) { |
1437 | if (!this->emitGetLocal(SubExprT, LocalIndex, E)) |
1438 | return false; |
1439 | } |
1440 | |
1441 | // This is cleaned up when the local variable is destroyed. |
1442 | OpaqueExprs.insert(KV: {E, LocalIndex}); |
1443 | |
1444 | return true; |
1445 | } |
1446 | |
1447 | template <class Emitter> |
1448 | bool ByteCodeExprGen<Emitter>::VisitAbstractConditionalOperator( |
1449 | const AbstractConditionalOperator *E) { |
1450 | const Expr *Condition = E->getCond(); |
1451 | const Expr *TrueExpr = E->getTrueExpr(); |
1452 | const Expr *FalseExpr = E->getFalseExpr(); |
1453 | |
1454 | LabelTy LabelEnd = this->getLabel(); // Label after the operator. |
1455 | LabelTy LabelFalse = this->getLabel(); // Label for the false expr. |
1456 | |
1457 | if (!this->visitBool(Condition)) |
1458 | return false; |
1459 | |
1460 | if (!this->jumpFalse(LabelFalse)) |
1461 | return false; |
1462 | |
1463 | if (!this->delegate(TrueExpr)) |
1464 | return false; |
1465 | if (!this->jump(LabelEnd)) |
1466 | return false; |
1467 | |
1468 | this->emitLabel(LabelFalse); |
1469 | |
1470 | if (!this->delegate(FalseExpr)) |
1471 | return false; |
1472 | |
1473 | this->fallthrough(LabelEnd); |
1474 | this->emitLabel(LabelEnd); |
1475 | |
1476 | return true; |
1477 | } |
1478 | |
1479 | template <class Emitter> |
1480 | bool ByteCodeExprGen<Emitter>::VisitStringLiteral(const StringLiteral *E) { |
1481 | if (DiscardResult) |
1482 | return true; |
1483 | |
1484 | if (!Initializing) { |
1485 | unsigned StringIndex = P.createGlobalString(S: E); |
1486 | return this->emitGetPtrGlobal(StringIndex, E); |
1487 | } |
1488 | |
1489 | // We are initializing an array on the stack. |
1490 | const ConstantArrayType *CAT = |
1491 | Ctx.getASTContext().getAsConstantArrayType(T: E->getType()); |
1492 | assert(CAT && "a string literal that's not a constant array?" ); |
1493 | |
1494 | // If the initializer string is too long, a diagnostic has already been |
1495 | // emitted. Read only the array length from the string literal. |
1496 | unsigned ArraySize = CAT->getZExtSize(); |
1497 | unsigned N = std::min(a: ArraySize, b: E->getLength()); |
1498 | size_t CharWidth = E->getCharByteWidth(); |
1499 | |
1500 | for (unsigned I = 0; I != N; ++I) { |
1501 | uint32_t CodeUnit = E->getCodeUnit(i: I); |
1502 | |
1503 | if (CharWidth == 1) { |
1504 | this->emitConstSint8(CodeUnit, E); |
1505 | this->emitInitElemSint8(I, E); |
1506 | } else if (CharWidth == 2) { |
1507 | this->emitConstUint16(CodeUnit, E); |
1508 | this->emitInitElemUint16(I, E); |
1509 | } else if (CharWidth == 4) { |
1510 | this->emitConstUint32(CodeUnit, E); |
1511 | this->emitInitElemUint32(I, E); |
1512 | } else { |
1513 | llvm_unreachable("unsupported character width" ); |
1514 | } |
1515 | } |
1516 | |
1517 | // Fill up the rest of the char array with NUL bytes. |
1518 | for (unsigned I = N; I != ArraySize; ++I) { |
1519 | if (CharWidth == 1) { |
1520 | this->emitConstSint8(0, E); |
1521 | this->emitInitElemSint8(I, E); |
1522 | } else if (CharWidth == 2) { |
1523 | this->emitConstUint16(0, E); |
1524 | this->emitInitElemUint16(I, E); |
1525 | } else if (CharWidth == 4) { |
1526 | this->emitConstUint32(0, E); |
1527 | this->emitInitElemUint32(I, E); |
1528 | } else { |
1529 | llvm_unreachable("unsupported character width" ); |
1530 | } |
1531 | } |
1532 | |
1533 | return true; |
1534 | } |
1535 | |
1536 | template <class Emitter> |
1537 | bool ByteCodeExprGen<Emitter>::VisitCharacterLiteral( |
1538 | const CharacterLiteral *E) { |
1539 | if (DiscardResult) |
1540 | return true; |
1541 | return this->emitConst(E->getValue(), E); |
1542 | } |
1543 | |
1544 | template <class Emitter> |
1545 | bool ByteCodeExprGen<Emitter>::VisitFloatCompoundAssignOperator( |
1546 | const CompoundAssignOperator *E) { |
1547 | |
1548 | const Expr *LHS = E->getLHS(); |
1549 | const Expr *RHS = E->getRHS(); |
1550 | QualType LHSType = LHS->getType(); |
1551 | QualType LHSComputationType = E->getComputationLHSType(); |
1552 | QualType ResultType = E->getComputationResultType(); |
1553 | std::optional<PrimType> LT = classify(LHSComputationType); |
1554 | std::optional<PrimType> RT = classify(ResultType); |
1555 | |
1556 | assert(ResultType->isFloatingType()); |
1557 | |
1558 | if (!LT || !RT) |
1559 | return false; |
1560 | |
1561 | PrimType LHST = classifyPrim(LHSType); |
1562 | |
1563 | // C++17 onwards require that we evaluate the RHS first. |
1564 | // Compute RHS and save it in a temporary variable so we can |
1565 | // load it again later. |
1566 | if (!visit(E: RHS)) |
1567 | return false; |
1568 | |
1569 | unsigned TempOffset = this->allocateLocalPrimitive(E, *RT, /*IsConst=*/true); |
1570 | if (!this->emitSetLocal(*RT, TempOffset, E)) |
1571 | return false; |
1572 | |
1573 | // First, visit LHS. |
1574 | if (!visit(E: LHS)) |
1575 | return false; |
1576 | if (!this->emitLoad(LHST, E)) |
1577 | return false; |
1578 | |
1579 | // If necessary, convert LHS to its computation type. |
1580 | if (!this->emitPrimCast(LHST, classifyPrim(LHSComputationType), |
1581 | LHSComputationType, E)) |
1582 | return false; |
1583 | |
1584 | // Now load RHS. |
1585 | if (!this->emitGetLocal(*RT, TempOffset, E)) |
1586 | return false; |
1587 | |
1588 | llvm::RoundingMode RM = getRoundingMode(E); |
1589 | switch (E->getOpcode()) { |
1590 | case BO_AddAssign: |
1591 | if (!this->emitAddf(RM, E)) |
1592 | return false; |
1593 | break; |
1594 | case BO_SubAssign: |
1595 | if (!this->emitSubf(RM, E)) |
1596 | return false; |
1597 | break; |
1598 | case BO_MulAssign: |
1599 | if (!this->emitMulf(RM, E)) |
1600 | return false; |
1601 | break; |
1602 | case BO_DivAssign: |
1603 | if (!this->emitDivf(RM, E)) |
1604 | return false; |
1605 | break; |
1606 | default: |
1607 | return false; |
1608 | } |
1609 | |
1610 | if (!this->emitPrimCast(classifyPrim(ResultType), LHST, LHS->getType(), E)) |
1611 | return false; |
1612 | |
1613 | if (DiscardResult) |
1614 | return this->emitStorePop(LHST, E); |
1615 | return this->emitStore(LHST, E); |
1616 | } |
1617 | |
1618 | template <class Emitter> |
1619 | bool ByteCodeExprGen<Emitter>::VisitPointerCompoundAssignOperator( |
1620 | const CompoundAssignOperator *E) { |
1621 | BinaryOperatorKind Op = E->getOpcode(); |
1622 | const Expr *LHS = E->getLHS(); |
1623 | const Expr *RHS = E->getRHS(); |
1624 | std::optional<PrimType> LT = classify(LHS->getType()); |
1625 | std::optional<PrimType> RT = classify(RHS->getType()); |
1626 | |
1627 | if (Op != BO_AddAssign && Op != BO_SubAssign) |
1628 | return false; |
1629 | |
1630 | if (!LT || !RT) |
1631 | return false; |
1632 | |
1633 | if (!visit(E: LHS)) |
1634 | return false; |
1635 | |
1636 | if (!this->emitLoad(*LT, LHS)) |
1637 | return false; |
1638 | |
1639 | if (!visit(E: RHS)) |
1640 | return false; |
1641 | |
1642 | if (Op == BO_AddAssign) { |
1643 | if (!this->emitAddOffset(*RT, E)) |
1644 | return false; |
1645 | } else { |
1646 | if (!this->emitSubOffset(*RT, E)) |
1647 | return false; |
1648 | } |
1649 | |
1650 | if (DiscardResult) |
1651 | return this->emitStorePopPtr(E); |
1652 | return this->emitStorePtr(E); |
1653 | } |
1654 | |
1655 | template <class Emitter> |
1656 | bool ByteCodeExprGen<Emitter>::VisitCompoundAssignOperator( |
1657 | const CompoundAssignOperator *E) { |
1658 | |
1659 | const Expr *LHS = E->getLHS(); |
1660 | const Expr *RHS = E->getRHS(); |
1661 | std::optional<PrimType> LHSComputationT = |
1662 | classify(E->getComputationLHSType()); |
1663 | std::optional<PrimType> LT = classify(LHS->getType()); |
1664 | std::optional<PrimType> RT = classify(RHS->getType()); |
1665 | std::optional<PrimType> ResultT = classify(E->getType()); |
1666 | |
1667 | if (!LT || !RT || !ResultT || !LHSComputationT) |
1668 | return false; |
1669 | |
1670 | // Handle floating point operations separately here, since they |
1671 | // require special care. |
1672 | |
1673 | if (ResultT == PT_Float || RT == PT_Float) |
1674 | return VisitFloatCompoundAssignOperator(E); |
1675 | |
1676 | if (E->getType()->isPointerType()) |
1677 | return VisitPointerCompoundAssignOperator(E); |
1678 | |
1679 | assert(!E->getType()->isPointerType() && "Handled above" ); |
1680 | assert(!E->getType()->isFloatingType() && "Handled above" ); |
1681 | |
1682 | // C++17 onwards require that we evaluate the RHS first. |
1683 | // Compute RHS and save it in a temporary variable so we can |
1684 | // load it again later. |
1685 | // FIXME: Compound assignments are unsequenced in C, so we might |
1686 | // have to figure out how to reject them. |
1687 | if (!visit(E: RHS)) |
1688 | return false; |
1689 | |
1690 | unsigned TempOffset = this->allocateLocalPrimitive(E, *RT, /*IsConst=*/true); |
1691 | |
1692 | if (!this->emitSetLocal(*RT, TempOffset, E)) |
1693 | return false; |
1694 | |
1695 | // Get LHS pointer, load its value and cast it to the |
1696 | // computation type if necessary. |
1697 | if (!visit(E: LHS)) |
1698 | return false; |
1699 | if (!this->emitLoad(*LT, E)) |
1700 | return false; |
1701 | if (LT != LHSComputationT) { |
1702 | if (!this->emitCast(*LT, *LHSComputationT, E)) |
1703 | return false; |
1704 | } |
1705 | |
1706 | // Get the RHS value on the stack. |
1707 | if (!this->emitGetLocal(*RT, TempOffset, E)) |
1708 | return false; |
1709 | |
1710 | // Perform operation. |
1711 | switch (E->getOpcode()) { |
1712 | case BO_AddAssign: |
1713 | if (!this->emitAdd(*LHSComputationT, E)) |
1714 | return false; |
1715 | break; |
1716 | case BO_SubAssign: |
1717 | if (!this->emitSub(*LHSComputationT, E)) |
1718 | return false; |
1719 | break; |
1720 | case BO_MulAssign: |
1721 | if (!this->emitMul(*LHSComputationT, E)) |
1722 | return false; |
1723 | break; |
1724 | case BO_DivAssign: |
1725 | if (!this->emitDiv(*LHSComputationT, E)) |
1726 | return false; |
1727 | break; |
1728 | case BO_RemAssign: |
1729 | if (!this->emitRem(*LHSComputationT, E)) |
1730 | return false; |
1731 | break; |
1732 | case BO_ShlAssign: |
1733 | if (!this->emitShl(*LHSComputationT, *RT, E)) |
1734 | return false; |
1735 | break; |
1736 | case BO_ShrAssign: |
1737 | if (!this->emitShr(*LHSComputationT, *RT, E)) |
1738 | return false; |
1739 | break; |
1740 | case BO_AndAssign: |
1741 | if (!this->emitBitAnd(*LHSComputationT, E)) |
1742 | return false; |
1743 | break; |
1744 | case BO_XorAssign: |
1745 | if (!this->emitBitXor(*LHSComputationT, E)) |
1746 | return false; |
1747 | break; |
1748 | case BO_OrAssign: |
1749 | if (!this->emitBitOr(*LHSComputationT, E)) |
1750 | return false; |
1751 | break; |
1752 | default: |
1753 | llvm_unreachable("Unimplemented compound assign operator" ); |
1754 | } |
1755 | |
1756 | // And now cast from LHSComputationT to ResultT. |
1757 | if (ResultT != LHSComputationT) { |
1758 | if (!this->emitCast(*LHSComputationT, *ResultT, E)) |
1759 | return false; |
1760 | } |
1761 | |
1762 | // And store the result in LHS. |
1763 | if (DiscardResult) { |
1764 | if (LHS->refersToBitField()) |
1765 | return this->emitStoreBitFieldPop(*ResultT, E); |
1766 | return this->emitStorePop(*ResultT, E); |
1767 | } |
1768 | if (LHS->refersToBitField()) |
1769 | return this->emitStoreBitField(*ResultT, E); |
1770 | return this->emitStore(*ResultT, E); |
1771 | } |
1772 | |
1773 | template <class Emitter> |
1774 | bool ByteCodeExprGen<Emitter>::VisitExprWithCleanups( |
1775 | const ExprWithCleanups *E) { |
1776 | const Expr *SubExpr = E->getSubExpr(); |
1777 | |
1778 | assert(E->getNumObjects() == 0 && "TODO: Implement cleanups" ); |
1779 | |
1780 | return this->delegate(SubExpr); |
1781 | } |
1782 | |
1783 | template <class Emitter> |
1784 | bool ByteCodeExprGen<Emitter>::VisitMaterializeTemporaryExpr( |
1785 | const MaterializeTemporaryExpr *E) { |
1786 | const Expr *SubExpr = E->getSubExpr(); |
1787 | |
1788 | if (Initializing) { |
1789 | // We already have a value, just initialize that. |
1790 | return this->visitInitializer(SubExpr); |
1791 | } |
1792 | // If we don't end up using the materialized temporary anyway, don't |
1793 | // bother creating it. |
1794 | if (DiscardResult) |
1795 | return this->discard(SubExpr); |
1796 | |
1797 | // When we're initializing a global variable *or* the storage duration of |
1798 | // the temporary is explicitly static, create a global variable. |
1799 | std::optional<PrimType> SubExprT = classify(SubExpr); |
1800 | bool IsStatic = E->getStorageDuration() == SD_Static; |
1801 | if (GlobalDecl || IsStatic) { |
1802 | std::optional<unsigned> GlobalIndex = P.createGlobal(E); |
1803 | if (!GlobalIndex) |
1804 | return false; |
1805 | |
1806 | const LifetimeExtendedTemporaryDecl *TempDecl = |
1807 | E->getLifetimeExtendedTemporaryDecl(); |
1808 | if (IsStatic) |
1809 | assert(TempDecl); |
1810 | |
1811 | if (SubExprT) { |
1812 | if (!this->visit(SubExpr)) |
1813 | return false; |
1814 | if (IsStatic) { |
1815 | if (!this->emitInitGlobalTemp(*SubExprT, *GlobalIndex, TempDecl, E)) |
1816 | return false; |
1817 | } else { |
1818 | if (!this->emitInitGlobal(*SubExprT, *GlobalIndex, E)) |
1819 | return false; |
1820 | } |
1821 | return this->emitGetPtrGlobal(*GlobalIndex, E); |
1822 | } |
1823 | |
1824 | // Non-primitive values. |
1825 | if (!this->emitGetPtrGlobal(*GlobalIndex, E)) |
1826 | return false; |
1827 | if (!this->visitInitializer(SubExpr)) |
1828 | return false; |
1829 | if (IsStatic) |
1830 | return this->emitInitGlobalTempComp(TempDecl, E); |
1831 | return true; |
1832 | } |
1833 | |
1834 | // For everyhing else, use local variables. |
1835 | if (SubExprT) { |
1836 | unsigned LocalIndex = allocateLocalPrimitive( |
1837 | Decl: SubExpr, Ty: *SubExprT, /*IsConst=*/true, /*IsExtended=*/true); |
1838 | if (!this->visit(SubExpr)) |
1839 | return false; |
1840 | if (!this->emitSetLocal(*SubExprT, LocalIndex, E)) |
1841 | return false; |
1842 | return this->emitGetPtrLocal(LocalIndex, E); |
1843 | } else { |
1844 | const Expr *Inner = E->getSubExpr()->skipRValueSubobjectAdjustments(); |
1845 | |
1846 | if (std::optional<unsigned> LocalIndex = |
1847 | allocateLocal(Decl: Inner, /*IsExtended=*/true)) { |
1848 | if (!this->emitGetPtrLocal(*LocalIndex, E)) |
1849 | return false; |
1850 | return this->visitInitializer(SubExpr); |
1851 | } |
1852 | } |
1853 | return false; |
1854 | } |
1855 | |
1856 | template <class Emitter> |
1857 | bool ByteCodeExprGen<Emitter>::VisitCXXBindTemporaryExpr( |
1858 | const CXXBindTemporaryExpr *E) { |
1859 | return this->delegate(E->getSubExpr()); |
1860 | } |
1861 | |
1862 | template <class Emitter> |
1863 | bool ByteCodeExprGen<Emitter>::VisitCompoundLiteralExpr( |
1864 | const CompoundLiteralExpr *E) { |
1865 | const Expr *Init = E->getInitializer(); |
1866 | if (Initializing) { |
1867 | // We already have a value, just initialize that. |
1868 | return this->visitInitializer(Init) && this->emitFinishInit(E); |
1869 | } |
1870 | |
1871 | std::optional<PrimType> T = classify(E->getType()); |
1872 | if (E->isFileScope()) { |
1873 | // Avoid creating a variable if this is a primitive RValue anyway. |
1874 | if (T && !E->isLValue()) |
1875 | return this->delegate(Init); |
1876 | |
1877 | if (std::optional<unsigned> GlobalIndex = P.createGlobal(E)) { |
1878 | if (!this->emitGetPtrGlobal(*GlobalIndex, E)) |
1879 | return false; |
1880 | |
1881 | if (T) { |
1882 | if (!this->visit(Init)) |
1883 | return false; |
1884 | return this->emitInitGlobal(*T, *GlobalIndex, E); |
1885 | } |
1886 | |
1887 | return this->visitInitializer(Init) && this->emitFinishInit(E); |
1888 | } |
1889 | |
1890 | return false; |
1891 | } |
1892 | |
1893 | // Otherwise, use a local variable. |
1894 | if (T && !E->isLValue()) { |
1895 | // For primitive types, we just visit the initializer. |
1896 | return this->delegate(Init); |
1897 | } else { |
1898 | unsigned LocalIndex; |
1899 | |
1900 | if (T) |
1901 | LocalIndex = this->allocateLocalPrimitive(Init, *T, false, false); |
1902 | else if (std::optional<unsigned> MaybeIndex = this->allocateLocal(Init)) |
1903 | LocalIndex = *MaybeIndex; |
1904 | else |
1905 | return false; |
1906 | |
1907 | if (!this->emitGetPtrLocal(LocalIndex, E)) |
1908 | return false; |
1909 | |
1910 | if (T) { |
1911 | if (!this->visit(Init)) { |
1912 | return false; |
1913 | } |
1914 | return this->emitInit(*T, E); |
1915 | } else { |
1916 | if (!this->visitInitializer(Init) || !this->emitFinishInit(E)) |
1917 | return false; |
1918 | } |
1919 | |
1920 | if (DiscardResult) |
1921 | return this->emitPopPtr(E); |
1922 | return true; |
1923 | } |
1924 | |
1925 | return false; |
1926 | } |
1927 | |
1928 | template <class Emitter> |
1929 | bool ByteCodeExprGen<Emitter>::VisitTypeTraitExpr(const TypeTraitExpr *E) { |
1930 | if (DiscardResult) |
1931 | return true; |
1932 | if (E->getType()->isBooleanType()) |
1933 | return this->emitConstBool(E->getValue(), E); |
1934 | return this->emitConst(E->getValue(), E); |
1935 | } |
1936 | |
1937 | template <class Emitter> |
1938 | bool ByteCodeExprGen<Emitter>::VisitArrayTypeTraitExpr( |
1939 | const ArrayTypeTraitExpr *E) { |
1940 | if (DiscardResult) |
1941 | return true; |
1942 | return this->emitConst(E->getValue(), E); |
1943 | } |
1944 | |
1945 | template <class Emitter> |
1946 | bool ByteCodeExprGen<Emitter>::VisitLambdaExpr(const LambdaExpr *E) { |
1947 | if (DiscardResult) |
1948 | return true; |
1949 | |
1950 | assert(Initializing); |
1951 | const Record *R = P.getOrCreateRecord(E->getLambdaClass()); |
1952 | |
1953 | auto *CaptureInitIt = E->capture_init_begin(); |
1954 | // Initialize all fields (which represent lambda captures) of the |
1955 | // record with their initializers. |
1956 | for (const Record::Field &F : R->fields()) { |
1957 | const Expr *Init = *CaptureInitIt; |
1958 | ++CaptureInitIt; |
1959 | |
1960 | if (!Init) |
1961 | continue; |
1962 | |
1963 | if (std::optional<PrimType> T = classify(Init)) { |
1964 | if (!this->visit(Init)) |
1965 | return false; |
1966 | |
1967 | if (!this->emitSetField(*T, F.Offset, E)) |
1968 | return false; |
1969 | } else { |
1970 | if (!this->emitDupPtr(E)) |
1971 | return false; |
1972 | |
1973 | if (!this->emitGetPtrField(F.Offset, E)) |
1974 | return false; |
1975 | |
1976 | if (!this->visitInitializer(Init)) |
1977 | return false; |
1978 | |
1979 | if (!this->emitPopPtr(E)) |
1980 | return false; |
1981 | } |
1982 | } |
1983 | |
1984 | return true; |
1985 | } |
1986 | |
1987 | template <class Emitter> |
1988 | bool ByteCodeExprGen<Emitter>::VisitPredefinedExpr(const PredefinedExpr *E) { |
1989 | if (DiscardResult) |
1990 | return true; |
1991 | |
1992 | return this->delegate(E->getFunctionName()); |
1993 | } |
1994 | |
1995 | template <class Emitter> |
1996 | bool ByteCodeExprGen<Emitter>::VisitCXXThrowExpr(const CXXThrowExpr *E) { |
1997 | if (E->getSubExpr() && !this->discard(E->getSubExpr())) |
1998 | return false; |
1999 | |
2000 | return this->emitInvalid(E); |
2001 | } |
2002 | |
2003 | template <class Emitter> |
2004 | bool ByteCodeExprGen<Emitter>::VisitCXXReinterpretCastExpr( |
2005 | const CXXReinterpretCastExpr *E) { |
2006 | if (!this->discard(E->getSubExpr())) |
2007 | return false; |
2008 | |
2009 | return this->emitInvalidCast(CastKind::Reinterpret, E); |
2010 | } |
2011 | |
2012 | template <class Emitter> |
2013 | bool ByteCodeExprGen<Emitter>::VisitCXXNoexceptExpr(const CXXNoexceptExpr *E) { |
2014 | assert(E->getType()->isBooleanType()); |
2015 | |
2016 | if (DiscardResult) |
2017 | return true; |
2018 | return this->emitConstBool(E->getValue(), E); |
2019 | } |
2020 | |
2021 | template <class Emitter> |
2022 | bool ByteCodeExprGen<Emitter>::VisitCXXConstructExpr( |
2023 | const CXXConstructExpr *E) { |
2024 | QualType T = E->getType(); |
2025 | assert(!classify(T)); |
2026 | |
2027 | if (T->isRecordType()) { |
2028 | const CXXConstructorDecl *Ctor = E->getConstructor(); |
2029 | |
2030 | // Trivial zero initialization. |
2031 | if (E->requiresZeroInitialization() && Ctor->isTrivial()) { |
2032 | const Record *R = getRecord(E->getType()); |
2033 | return this->visitZeroRecordInitializer(R, E); |
2034 | } |
2035 | |
2036 | const Function *Func = getFunction(FD: Ctor); |
2037 | |
2038 | if (!Func) |
2039 | return false; |
2040 | |
2041 | assert(Func->hasThisPointer()); |
2042 | assert(!Func->hasRVO()); |
2043 | |
2044 | // If we're discarding a construct expression, we still need |
2045 | // to allocate a variable and call the constructor and destructor. |
2046 | if (DiscardResult) { |
2047 | assert(!Initializing); |
2048 | std::optional<unsigned> LocalIndex = |
2049 | allocateLocal(Decl: E, /*IsExtended=*/true); |
2050 | |
2051 | if (!LocalIndex) |
2052 | return false; |
2053 | |
2054 | if (!this->emitGetPtrLocal(*LocalIndex, E)) |
2055 | return false; |
2056 | } |
2057 | |
2058 | // The This pointer is already on the stack because this is an initializer, |
2059 | // but we need to dup() so the call() below has its own copy. |
2060 | if (!this->emitDupPtr(E)) |
2061 | return false; |
2062 | |
2063 | // Constructor arguments. |
2064 | for (const auto *Arg : E->arguments()) { |
2065 | if (!this->visit(Arg)) |
2066 | return false; |
2067 | } |
2068 | |
2069 | if (Func->isVariadic()) { |
2070 | uint32_t VarArgSize = 0; |
2071 | unsigned NumParams = Func->getNumWrittenParams(); |
2072 | for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I) { |
2073 | VarArgSize += |
2074 | align(primSize(classify(E->getArg(Arg: I)->getType()).value_or(PT_Ptr))); |
2075 | } |
2076 | if (!this->emitCallVar(Func, VarArgSize, E)) |
2077 | return false; |
2078 | } else { |
2079 | if (!this->emitCall(Func, 0, E)) |
2080 | return false; |
2081 | } |
2082 | |
2083 | // Immediately call the destructor if we have to. |
2084 | if (DiscardResult) { |
2085 | if (!this->emitRecordDestruction(getRecord(E->getType()))) |
2086 | return false; |
2087 | if (!this->emitPopPtr(E)) |
2088 | return false; |
2089 | } |
2090 | return true; |
2091 | } |
2092 | |
2093 | if (T->isArrayType()) { |
2094 | const ConstantArrayType *CAT = |
2095 | Ctx.getASTContext().getAsConstantArrayType(T: E->getType()); |
2096 | assert(CAT); |
2097 | size_t NumElems = CAT->getZExtSize(); |
2098 | const Function *Func = getFunction(FD: E->getConstructor()); |
2099 | if (!Func || !Func->isConstexpr()) |
2100 | return false; |
2101 | |
2102 | // FIXME(perf): We're calling the constructor once per array element here, |
2103 | // in the old intepreter we had a special-case for trivial constructors. |
2104 | for (size_t I = 0; I != NumElems; ++I) { |
2105 | if (!this->emitConstUint64(I, E)) |
2106 | return false; |
2107 | if (!this->emitArrayElemPtrUint64(E)) |
2108 | return false; |
2109 | |
2110 | // Constructor arguments. |
2111 | for (const auto *Arg : E->arguments()) { |
2112 | if (!this->visit(Arg)) |
2113 | return false; |
2114 | } |
2115 | |
2116 | if (!this->emitCall(Func, 0, E)) |
2117 | return false; |
2118 | } |
2119 | return true; |
2120 | } |
2121 | |
2122 | return false; |
2123 | } |
2124 | |
2125 | template <class Emitter> |
2126 | bool ByteCodeExprGen<Emitter>::VisitSourceLocExpr(const SourceLocExpr *E) { |
2127 | if (DiscardResult) |
2128 | return true; |
2129 | |
2130 | const APValue Val = |
2131 | E->EvaluateInContext(Ctx: Ctx.getASTContext(), DefaultExpr: SourceLocDefaultExpr); |
2132 | |
2133 | // Things like __builtin_LINE(). |
2134 | if (E->getType()->isIntegerType()) { |
2135 | assert(Val.isInt()); |
2136 | const APSInt &I = Val.getInt(); |
2137 | return this->emitConst(I, E); |
2138 | } |
2139 | // Otherwise, the APValue is an LValue, with only one element. |
2140 | // Theoretically, we don't need the APValue at all of course. |
2141 | assert(E->getType()->isPointerType()); |
2142 | assert(Val.isLValue()); |
2143 | const APValue::LValueBase &Base = Val.getLValueBase(); |
2144 | if (const Expr *LValueExpr = Base.dyn_cast<const Expr *>()) |
2145 | return this->visit(LValueExpr); |
2146 | |
2147 | // Otherwise, we have a decl (which is the case for |
2148 | // __builtin_source_location). |
2149 | assert(Base.is<const ValueDecl *>()); |
2150 | assert(Val.getLValuePath().size() == 0); |
2151 | const auto *BaseDecl = Base.dyn_cast<const ValueDecl *>(); |
2152 | assert(BaseDecl); |
2153 | |
2154 | auto *UGCD = cast<UnnamedGlobalConstantDecl>(Val: BaseDecl); |
2155 | |
2156 | std::optional<unsigned> GlobalIndex = P.getOrCreateGlobal(UGCD); |
2157 | if (!GlobalIndex) |
2158 | return false; |
2159 | |
2160 | if (!this->emitGetPtrGlobal(*GlobalIndex, E)) |
2161 | return false; |
2162 | |
2163 | const Record *R = getRecord(E->getType()); |
2164 | const APValue &V = UGCD->getValue(); |
2165 | for (unsigned I = 0, N = R->getNumFields(); I != N; ++I) { |
2166 | const Record::Field *F = R->getField(I); |
2167 | const APValue &FieldValue = V.getStructField(i: I); |
2168 | |
2169 | PrimType FieldT = classifyPrim(F->Decl->getType()); |
2170 | |
2171 | if (!this->visitAPValue(FieldValue, FieldT, E)) |
2172 | return false; |
2173 | if (!this->emitInitField(FieldT, F->Offset, E)) |
2174 | return false; |
2175 | } |
2176 | |
2177 | // Leave the pointer to the global on the stack. |
2178 | return true; |
2179 | } |
2180 | |
2181 | template <class Emitter> |
2182 | bool ByteCodeExprGen<Emitter>::VisitOffsetOfExpr(const OffsetOfExpr *E) { |
2183 | unsigned N = E->getNumComponents(); |
2184 | if (N == 0) |
2185 | return false; |
2186 | |
2187 | for (unsigned I = 0; I != N; ++I) { |
2188 | const OffsetOfNode &Node = E->getComponent(Idx: I); |
2189 | if (Node.getKind() == OffsetOfNode::Array) { |
2190 | const Expr *ArrayIndexExpr = E->getIndexExpr(Idx: Node.getArrayExprIndex()); |
2191 | PrimType IndexT = classifyPrim(ArrayIndexExpr->getType()); |
2192 | |
2193 | if (DiscardResult) { |
2194 | if (!this->discard(ArrayIndexExpr)) |
2195 | return false; |
2196 | continue; |
2197 | } |
2198 | |
2199 | if (!this->visit(ArrayIndexExpr)) |
2200 | return false; |
2201 | // Cast to Sint64. |
2202 | if (IndexT != PT_Sint64) { |
2203 | if (!this->emitCast(IndexT, PT_Sint64, E)) |
2204 | return false; |
2205 | } |
2206 | } |
2207 | } |
2208 | |
2209 | if (DiscardResult) |
2210 | return true; |
2211 | |
2212 | PrimType T = classifyPrim(E->getType()); |
2213 | return this->emitOffsetOf(T, E, E); |
2214 | } |
2215 | |
2216 | template <class Emitter> |
2217 | bool ByteCodeExprGen<Emitter>::VisitCXXScalarValueInitExpr( |
2218 | const CXXScalarValueInitExpr *E) { |
2219 | QualType Ty = E->getType(); |
2220 | |
2221 | if (DiscardResult || Ty->isVoidType()) |
2222 | return true; |
2223 | |
2224 | if (std::optional<PrimType> T = classify(Ty)) |
2225 | return this->visitZeroInitializer(*T, Ty, E); |
2226 | |
2227 | assert(Ty->isAnyComplexType()); |
2228 | if (!Initializing) { |
2229 | std::optional<unsigned> LocalIndex = allocateLocal(Decl: E, /*IsExtended=*/false); |
2230 | if (!LocalIndex) |
2231 | return false; |
2232 | if (!this->emitGetPtrLocal(*LocalIndex, E)) |
2233 | return false; |
2234 | } |
2235 | |
2236 | // Initialize both fields to 0. |
2237 | QualType ElemQT = Ty->getAs<ComplexType>()->getElementType(); |
2238 | PrimType ElemT = classifyPrim(ElemQT); |
2239 | |
2240 | for (unsigned I = 0; I != 2; ++I) { |
2241 | if (!this->visitZeroInitializer(ElemT, ElemQT, E)) |
2242 | return false; |
2243 | if (!this->emitInitElem(ElemT, I, E)) |
2244 | return false; |
2245 | } |
2246 | return true; |
2247 | } |
2248 | |
2249 | template <class Emitter> |
2250 | bool ByteCodeExprGen<Emitter>::VisitSizeOfPackExpr(const SizeOfPackExpr *E) { |
2251 | return this->emitConst(E->getPackLength(), E); |
2252 | } |
2253 | |
2254 | template <class Emitter> |
2255 | bool ByteCodeExprGen<Emitter>::VisitGenericSelectionExpr( |
2256 | const GenericSelectionExpr *E) { |
2257 | return this->delegate(E->getResultExpr()); |
2258 | } |
2259 | |
2260 | template <class Emitter> |
2261 | bool ByteCodeExprGen<Emitter>::VisitChooseExpr(const ChooseExpr *E) { |
2262 | return this->delegate(E->getChosenSubExpr()); |
2263 | } |
2264 | |
2265 | template <class Emitter> |
2266 | bool ByteCodeExprGen<Emitter>::VisitObjCBoolLiteralExpr( |
2267 | const ObjCBoolLiteralExpr *E) { |
2268 | if (DiscardResult) |
2269 | return true; |
2270 | |
2271 | return this->emitConst(E->getValue(), E); |
2272 | } |
2273 | |
2274 | template <class Emitter> |
2275 | bool ByteCodeExprGen<Emitter>::VisitCXXInheritedCtorInitExpr( |
2276 | const CXXInheritedCtorInitExpr *E) { |
2277 | const CXXConstructorDecl *Ctor = E->getConstructor(); |
2278 | assert(!Ctor->isTrivial() && |
2279 | "Trivial CXXInheritedCtorInitExpr, implement. (possible?)" ); |
2280 | const Function *F = this->getFunction(Ctor); |
2281 | assert(F); |
2282 | assert(!F->hasRVO()); |
2283 | assert(F->hasThisPointer()); |
2284 | |
2285 | if (!this->emitDupPtr(SourceInfo{})) |
2286 | return false; |
2287 | |
2288 | // Forward all arguments of the current function (which should be a |
2289 | // constructor itself) to the inherited ctor. |
2290 | // This is necessary because the calling code has pushed the pointer |
2291 | // of the correct base for us already, but the arguments need |
2292 | // to come after. |
2293 | unsigned Offset = align(Size: primSize(Type: PT_Ptr)); // instance pointer. |
2294 | for (const ParmVarDecl *PD : Ctor->parameters()) { |
2295 | PrimType PT = this->classify(PD->getType()).value_or(PT_Ptr); |
2296 | |
2297 | if (!this->emitGetParam(PT, Offset, E)) |
2298 | return false; |
2299 | Offset += align(primSize(PT)); |
2300 | } |
2301 | |
2302 | return this->emitCall(F, 0, E); |
2303 | } |
2304 | |
2305 | template <class Emitter> |
2306 | bool ByteCodeExprGen<Emitter>::VisitExpressionTraitExpr( |
2307 | const ExpressionTraitExpr *E) { |
2308 | assert(Ctx.getLangOpts().CPlusPlus); |
2309 | return this->emitConstBool(E->getValue(), E); |
2310 | } |
2311 | |
2312 | template <class Emitter> |
2313 | bool ByteCodeExprGen<Emitter>::VisitCXXUuidofExpr(const CXXUuidofExpr *E) { |
2314 | if (DiscardResult) |
2315 | return true; |
2316 | assert(!Initializing); |
2317 | |
2318 | std::optional<unsigned> GlobalIndex = P.getOrCreateGlobal(E->getGuidDecl()); |
2319 | if (!GlobalIndex) |
2320 | return false; |
2321 | if (!this->emitGetPtrGlobal(*GlobalIndex, E)) |
2322 | return false; |
2323 | |
2324 | const Record *R = this->getRecord(E->getType()); |
2325 | assert(R); |
2326 | |
2327 | const APValue &V = E->getGuidDecl()->getAsAPValue(); |
2328 | if (V.getKind() == APValue::None) |
2329 | return true; |
2330 | |
2331 | assert(V.isStruct()); |
2332 | assert(V.getStructNumBases() == 0); |
2333 | // FIXME: This could be useful in visitAPValue, too. |
2334 | for (unsigned I = 0, N = V.getStructNumFields(); I != N; ++I) { |
2335 | const APValue &F = V.getStructField(i: I); |
2336 | const Record::Field *RF = R->getField(I); |
2337 | |
2338 | if (F.isInt()) { |
2339 | PrimType T = classifyPrim(RF->Decl->getType()); |
2340 | if (!this->visitAPValue(F, T, E)) |
2341 | return false; |
2342 | if (!this->emitInitField(T, RF->Offset, E)) |
2343 | return false; |
2344 | } else if (F.isArray()) { |
2345 | assert(RF->Desc->isPrimitiveArray()); |
2346 | const auto *ArrType = RF->Decl->getType()->getAsArrayTypeUnsafe(); |
2347 | PrimType ElemT = classifyPrim(ArrType->getElementType()); |
2348 | assert(ArrType); |
2349 | |
2350 | if (!this->emitDupPtr(E)) |
2351 | return false; |
2352 | if (!this->emitGetPtrField(RF->Offset, E)) |
2353 | return false; |
2354 | |
2355 | for (unsigned A = 0, AN = F.getArraySize(); A != AN; ++A) { |
2356 | if (!this->visitAPValue(F.getArrayInitializedElt(I: A), ElemT, E)) |
2357 | return false; |
2358 | if (!this->emitInitElem(ElemT, A, E)) |
2359 | return false; |
2360 | } |
2361 | |
2362 | if (!this->emitPopPtr(E)) |
2363 | return false; |
2364 | } else { |
2365 | assert(false && "I don't think this should be possible" ); |
2366 | } |
2367 | } |
2368 | |
2369 | return this->emitFinishInit(E); |
2370 | } |
2371 | |
2372 | template <class Emitter> |
2373 | bool ByteCodeExprGen<Emitter>::VisitRequiresExpr(const RequiresExpr *E) { |
2374 | assert(classifyPrim(E->getType()) == PT_Bool); |
2375 | return this->emitConstBool(E->isSatisfied(), E); |
2376 | } |
2377 | |
2378 | template <class Emitter> |
2379 | bool ByteCodeExprGen<Emitter>::VisitConceptSpecializationExpr( |
2380 | const ConceptSpecializationExpr *E) { |
2381 | assert(classifyPrim(E->getType()) == PT_Bool); |
2382 | return this->emitConstBool(E->isSatisfied(), E); |
2383 | } |
2384 | |
2385 | template <class Emitter> |
2386 | bool ByteCodeExprGen<Emitter>::VisitCXXRewrittenBinaryOperator( |
2387 | const CXXRewrittenBinaryOperator *E) { |
2388 | return this->delegate(E->getSemanticForm()); |
2389 | } |
2390 | |
2391 | template <class Emitter> |
2392 | bool ByteCodeExprGen<Emitter>::VisitPseudoObjectExpr( |
2393 | const PseudoObjectExpr *E) { |
2394 | |
2395 | for (const Expr *SemE : E->semantics()) { |
2396 | if (auto *OVE = dyn_cast<OpaqueValueExpr>(Val: SemE)) { |
2397 | if (SemE == E->getResultExpr()) |
2398 | return false; |
2399 | |
2400 | if (OVE->isUnique()) |
2401 | continue; |
2402 | |
2403 | if (!this->discard(OVE)) |
2404 | return false; |
2405 | } else if (SemE == E->getResultExpr()) { |
2406 | if (!this->delegate(SemE)) |
2407 | return false; |
2408 | } else { |
2409 | if (!this->discard(SemE)) |
2410 | return false; |
2411 | } |
2412 | } |
2413 | return true; |
2414 | } |
2415 | |
2416 | template <class Emitter> |
2417 | bool ByteCodeExprGen<Emitter>::VisitPackIndexingExpr( |
2418 | const PackIndexingExpr *E) { |
2419 | return this->delegate(E->getSelectedExpr()); |
2420 | } |
2421 | |
2422 | template <class Emitter> bool ByteCodeExprGen<Emitter>::discard(const Expr *E) { |
2423 | if (E->containsErrors()) |
2424 | return false; |
2425 | |
2426 | OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/true, |
2427 | /*NewInitializing=*/false); |
2428 | return this->Visit(E); |
2429 | } |
2430 | |
2431 | template <class Emitter> |
2432 | bool ByteCodeExprGen<Emitter>::delegate(const Expr *E) { |
2433 | if (E->containsErrors()) |
2434 | return this->emitError(E); |
2435 | |
2436 | // We're basically doing: |
2437 | // OptionScope<Emitter> Scope(this, DicardResult, Initializing); |
2438 | // but that's unnecessary of course. |
2439 | return this->Visit(E); |
2440 | } |
2441 | |
2442 | template <class Emitter> bool ByteCodeExprGen<Emitter>::visit(const Expr *E) { |
2443 | if (E->containsErrors()) |
2444 | return this->emitError(E); |
2445 | |
2446 | if (E->getType()->isVoidType()) |
2447 | return this->discard(E); |
2448 | |
2449 | // Create local variable to hold the return value. |
2450 | if (!E->isGLValue() && !E->getType()->isAnyComplexType() && |
2451 | !classify(E->getType())) { |
2452 | std::optional<unsigned> LocalIndex = allocateLocal(Decl: E, /*IsExtended=*/true); |
2453 | if (!LocalIndex) |
2454 | return false; |
2455 | |
2456 | if (!this->emitGetPtrLocal(*LocalIndex, E)) |
2457 | return false; |
2458 | return this->visitInitializer(E); |
2459 | } |
2460 | |
2461 | // Otherwise,we have a primitive return value, produce the value directly |
2462 | // and push it on the stack. |
2463 | OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false, |
2464 | /*NewInitializing=*/false); |
2465 | return this->Visit(E); |
2466 | } |
2467 | |
2468 | template <class Emitter> |
2469 | bool ByteCodeExprGen<Emitter>::visitInitializer(const Expr *E) { |
2470 | assert(!classify(E->getType())); |
2471 | |
2472 | if (E->containsErrors()) |
2473 | return this->emitError(E); |
2474 | |
2475 | OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false, |
2476 | /*NewInitializing=*/true); |
2477 | return this->Visit(E); |
2478 | } |
2479 | |
2480 | template <class Emitter> |
2481 | bool ByteCodeExprGen<Emitter>::visitBool(const Expr *E) { |
2482 | std::optional<PrimType> T = classify(E->getType()); |
2483 | if (!T) { |
2484 | // Convert complex values to bool. |
2485 | if (E->getType()->isAnyComplexType()) { |
2486 | if (!this->visit(E)) |
2487 | return false; |
2488 | return this->emitComplexBoolCast(E); |
2489 | } |
2490 | return false; |
2491 | } |
2492 | |
2493 | if (!this->visit(E)) |
2494 | return false; |
2495 | |
2496 | if (T == PT_Bool) |
2497 | return true; |
2498 | |
2499 | // Convert pointers to bool. |
2500 | if (T == PT_Ptr || T == PT_FnPtr) { |
2501 | if (!this->emitNull(*T, nullptr, E)) |
2502 | return false; |
2503 | return this->emitNE(*T, E); |
2504 | } |
2505 | |
2506 | // Or Floats. |
2507 | if (T == PT_Float) |
2508 | return this->emitCastFloatingIntegralBool(E); |
2509 | |
2510 | // Or anything else we can. |
2511 | return this->emitCast(*T, PT_Bool, E); |
2512 | } |
2513 | |
2514 | template <class Emitter> |
2515 | bool ByteCodeExprGen<Emitter>::visitZeroInitializer(PrimType T, QualType QT, |
2516 | const Expr *E) { |
2517 | switch (T) { |
2518 | case PT_Bool: |
2519 | return this->emitZeroBool(E); |
2520 | case PT_Sint8: |
2521 | return this->emitZeroSint8(E); |
2522 | case PT_Uint8: |
2523 | return this->emitZeroUint8(E); |
2524 | case PT_Sint16: |
2525 | return this->emitZeroSint16(E); |
2526 | case PT_Uint16: |
2527 | return this->emitZeroUint16(E); |
2528 | case PT_Sint32: |
2529 | return this->emitZeroSint32(E); |
2530 | case PT_Uint32: |
2531 | return this->emitZeroUint32(E); |
2532 | case PT_Sint64: |
2533 | return this->emitZeroSint64(E); |
2534 | case PT_Uint64: |
2535 | return this->emitZeroUint64(E); |
2536 | case PT_IntAP: |
2537 | return this->emitZeroIntAP(Ctx.getBitWidth(T: QT), E); |
2538 | case PT_IntAPS: |
2539 | return this->emitZeroIntAPS(Ctx.getBitWidth(T: QT), E); |
2540 | case PT_Ptr: |
2541 | return this->emitNullPtr(nullptr, E); |
2542 | case PT_FnPtr: |
2543 | return this->emitNullFnPtr(nullptr, E); |
2544 | case PT_Float: { |
2545 | return this->emitConstFloat(APFloat::getZero(Sem: Ctx.getFloatSemantics(T: QT)), E); |
2546 | } |
2547 | } |
2548 | llvm_unreachable("unknown primitive type" ); |
2549 | } |
2550 | |
2551 | template <class Emitter> |
2552 | bool ByteCodeExprGen<Emitter>::visitZeroRecordInitializer(const Record *R, |
2553 | const Expr *E) { |
2554 | assert(E); |
2555 | assert(R); |
2556 | // Fields |
2557 | for (const Record::Field &Field : R->fields()) { |
2558 | const Descriptor *D = Field.Desc; |
2559 | if (D->isPrimitive()) { |
2560 | QualType QT = D->getType(); |
2561 | PrimType T = classifyPrim(D->getType()); |
2562 | if (!this->visitZeroInitializer(T, QT, E)) |
2563 | return false; |
2564 | if (!this->emitInitField(T, Field.Offset, E)) |
2565 | return false; |
2566 | continue; |
2567 | } |
2568 | |
2569 | // TODO: Add GetPtrFieldPop and get rid of this dup. |
2570 | if (!this->emitDupPtr(E)) |
2571 | return false; |
2572 | if (!this->emitGetPtrField(Field.Offset, E)) |
2573 | return false; |
2574 | |
2575 | if (D->isPrimitiveArray()) { |
2576 | QualType ET = D->getElemQualType(); |
2577 | PrimType T = classifyPrim(ET); |
2578 | for (uint32_t I = 0, N = D->getNumElems(); I != N; ++I) { |
2579 | if (!this->visitZeroInitializer(T, ET, E)) |
2580 | return false; |
2581 | if (!this->emitInitElem(T, I, E)) |
2582 | return false; |
2583 | } |
2584 | } else if (D->isCompositeArray()) { |
2585 | const Record *ElemRecord = D->ElemDesc->ElemRecord; |
2586 | assert(D->ElemDesc->ElemRecord); |
2587 | for (uint32_t I = 0, N = D->getNumElems(); I != N; ++I) { |
2588 | if (!this->emitConstUint32(I, E)) |
2589 | return false; |
2590 | if (!this->emitArrayElemPtr(PT_Uint32, E)) |
2591 | return false; |
2592 | if (!this->visitZeroRecordInitializer(ElemRecord, E)) |
2593 | return false; |
2594 | if (!this->emitPopPtr(E)) |
2595 | return false; |
2596 | } |
2597 | } else if (D->isRecord()) { |
2598 | if (!this->visitZeroRecordInitializer(D->ElemRecord, E)) |
2599 | return false; |
2600 | } else { |
2601 | assert(false); |
2602 | } |
2603 | |
2604 | if (!this->emitPopPtr(E)) |
2605 | return false; |
2606 | } |
2607 | |
2608 | for (const Record::Base &B : R->bases()) { |
2609 | if (!this->emitGetPtrBase(B.Offset, E)) |
2610 | return false; |
2611 | if (!this->visitZeroRecordInitializer(B.R, E)) |
2612 | return false; |
2613 | if (!this->emitFinishInitPop(E)) |
2614 | return false; |
2615 | } |
2616 | |
2617 | // FIXME: Virtual bases. |
2618 | |
2619 | return true; |
2620 | } |
2621 | |
2622 | template <class Emitter> |
2623 | template <typename T> |
2624 | bool ByteCodeExprGen<Emitter>::emitConst(T Value, PrimType Ty, const Expr *E) { |
2625 | switch (Ty) { |
2626 | case PT_Sint8: |
2627 | return this->emitConstSint8(Value, E); |
2628 | case PT_Uint8: |
2629 | return this->emitConstUint8(Value, E); |
2630 | case PT_Sint16: |
2631 | return this->emitConstSint16(Value, E); |
2632 | case PT_Uint16: |
2633 | return this->emitConstUint16(Value, E); |
2634 | case PT_Sint32: |
2635 | return this->emitConstSint32(Value, E); |
2636 | case PT_Uint32: |
2637 | return this->emitConstUint32(Value, E); |
2638 | case PT_Sint64: |
2639 | return this->emitConstSint64(Value, E); |
2640 | case PT_Uint64: |
2641 | return this->emitConstUint64(Value, E); |
2642 | case PT_Bool: |
2643 | return this->emitConstBool(Value, E); |
2644 | case PT_Ptr: |
2645 | case PT_FnPtr: |
2646 | case PT_Float: |
2647 | case PT_IntAP: |
2648 | case PT_IntAPS: |
2649 | llvm_unreachable("Invalid integral type" ); |
2650 | break; |
2651 | } |
2652 | llvm_unreachable("unknown primitive type" ); |
2653 | } |
2654 | |
2655 | template <class Emitter> |
2656 | template <typename T> |
2657 | bool ByteCodeExprGen<Emitter>::emitConst(T Value, const Expr *E) { |
2658 | return this->emitConst(Value, classifyPrim(E->getType()), E); |
2659 | } |
2660 | |
2661 | template <class Emitter> |
2662 | bool ByteCodeExprGen<Emitter>::emitConst(const APSInt &Value, PrimType Ty, |
2663 | const Expr *E) { |
2664 | if (Ty == PT_IntAPS) |
2665 | return this->emitConstIntAPS(Value, E); |
2666 | if (Ty == PT_IntAP) |
2667 | return this->emitConstIntAP(Value, E); |
2668 | |
2669 | if (Value.isSigned()) |
2670 | return this->emitConst(Value.getSExtValue(), Ty, E); |
2671 | return this->emitConst(Value.getZExtValue(), Ty, E); |
2672 | } |
2673 | |
2674 | template <class Emitter> |
2675 | bool ByteCodeExprGen<Emitter>::emitConst(const APSInt &Value, const Expr *E) { |
2676 | return this->emitConst(Value, classifyPrim(E->getType()), E); |
2677 | } |
2678 | |
2679 | template <class Emitter> |
2680 | unsigned ByteCodeExprGen<Emitter>::allocateLocalPrimitive(DeclTy &&Src, |
2681 | PrimType Ty, |
2682 | bool IsConst, |
2683 | bool IsExtended) { |
2684 | // Make sure we don't accidentally register the same decl twice. |
2685 | if (const auto *VD = |
2686 | dyn_cast_if_present<ValueDecl>(Val: Src.dyn_cast<const Decl *>())) { |
2687 | assert(!P.getGlobal(VD)); |
2688 | assert(!Locals.contains(VD)); |
2689 | (void)VD; |
2690 | } |
2691 | |
2692 | // FIXME: There are cases where Src.is<Expr*>() is wrong, e.g. |
2693 | // (int){12} in C. Consider using Expr::isTemporaryObject() instead |
2694 | // or isa<MaterializeTemporaryExpr>(). |
2695 | Descriptor *D = P.createDescriptor(D: Src, Type: Ty, MDSize: Descriptor::InlineDescMD, IsConst, |
2696 | IsTemporary: Src.is<const Expr *>()); |
2697 | Scope::Local Local = this->createLocal(D); |
2698 | if (auto *VD = dyn_cast_if_present<ValueDecl>(Val: Src.dyn_cast<const Decl *>())) |
2699 | Locals.insert(KV: {VD, Local}); |
2700 | VarScope->add(Local, IsExtended); |
2701 | return Local.Offset; |
2702 | } |
2703 | |
2704 | template <class Emitter> |
2705 | std::optional<unsigned> |
2706 | ByteCodeExprGen<Emitter>::allocateLocal(DeclTy &&Src, bool IsExtended) { |
2707 | // Make sure we don't accidentally register the same decl twice. |
2708 | if ([[maybe_unused]] const auto *VD = |
2709 | dyn_cast_if_present<ValueDecl>(Val: Src.dyn_cast<const Decl *>())) { |
2710 | assert(!P.getGlobal(VD)); |
2711 | assert(!Locals.contains(VD)); |
2712 | } |
2713 | |
2714 | QualType Ty; |
2715 | const ValueDecl *Key = nullptr; |
2716 | const Expr *Init = nullptr; |
2717 | bool IsTemporary = false; |
2718 | if (auto *VD = dyn_cast_if_present<ValueDecl>(Val: Src.dyn_cast<const Decl *>())) { |
2719 | Key = VD; |
2720 | Ty = VD->getType(); |
2721 | |
2722 | if (const auto *VarD = dyn_cast<VarDecl>(Val: VD)) |
2723 | Init = VarD->getInit(); |
2724 | } |
2725 | if (auto *E = Src.dyn_cast<const Expr *>()) { |
2726 | IsTemporary = true; |
2727 | Ty = E->getType(); |
2728 | } |
2729 | |
2730 | Descriptor *D = P.createDescriptor( |
2731 | D: Src, Ty: Ty.getTypePtr(), MDSize: Descriptor::InlineDescMD, IsConst: Ty.isConstQualified(), |
2732 | IsTemporary, /*IsMutable=*/false, Init); |
2733 | if (!D) |
2734 | return std::nullopt; |
2735 | |
2736 | Scope::Local Local = this->createLocal(D); |
2737 | if (Key) |
2738 | Locals.insert(KV: {Key, Local}); |
2739 | VarScope->add(Local, IsExtended); |
2740 | return Local.Offset; |
2741 | } |
2742 | |
2743 | template <class Emitter> |
2744 | const RecordType *ByteCodeExprGen<Emitter>::getRecordTy(QualType Ty) { |
2745 | if (const PointerType *PT = dyn_cast<PointerType>(Val&: Ty)) |
2746 | return PT->getPointeeType()->getAs<RecordType>(); |
2747 | return Ty->getAs<RecordType>(); |
2748 | } |
2749 | |
2750 | template <class Emitter> |
2751 | Record *ByteCodeExprGen<Emitter>::getRecord(QualType Ty) { |
2752 | if (const auto *RecordTy = getRecordTy(Ty)) |
2753 | return getRecord(RecordTy->getDecl()); |
2754 | return nullptr; |
2755 | } |
2756 | |
2757 | template <class Emitter> |
2758 | Record *ByteCodeExprGen<Emitter>::getRecord(const RecordDecl *RD) { |
2759 | return P.getOrCreateRecord(RD); |
2760 | } |
2761 | |
2762 | template <class Emitter> |
2763 | const Function *ByteCodeExprGen<Emitter>::getFunction(const FunctionDecl *FD) { |
2764 | return Ctx.getOrCreateFunction(FD); |
2765 | } |
2766 | |
2767 | template <class Emitter> |
2768 | bool ByteCodeExprGen<Emitter>::visitExpr(const Expr *E) { |
2769 | ExprScope<Emitter> RootScope(this); |
2770 | // Void expressions. |
2771 | if (E->getType()->isVoidType()) { |
2772 | if (!visit(E)) |
2773 | return false; |
2774 | return this->emitRetVoid(E); |
2775 | } |
2776 | |
2777 | // Expressions with a primitive return type. |
2778 | if (std::optional<PrimType> T = classify(E)) { |
2779 | if (!visit(E)) |
2780 | return false; |
2781 | return this->emitRet(*T, E); |
2782 | } |
2783 | |
2784 | // Expressions with a composite return type. |
2785 | // For us, that means everything we don't |
2786 | // have a PrimType for. |
2787 | if (std::optional<unsigned> LocalOffset = this->allocateLocal(E)) { |
2788 | if (!this->emitGetPtrLocal(*LocalOffset, E)) |
2789 | return false; |
2790 | |
2791 | if (!visitInitializer(E)) |
2792 | return false; |
2793 | |
2794 | if (!this->emitFinishInit(E)) |
2795 | return false; |
2796 | // We are destroying the locals AFTER the Ret op. |
2797 | // The Ret op needs to copy the (alive) values, but the |
2798 | // destructors may still turn the entire expression invalid. |
2799 | return this->emitRetValue(E) && RootScope.destroyLocals(); |
2800 | } |
2801 | |
2802 | return false; |
2803 | } |
2804 | |
2805 | /// Toplevel visitDecl(). |
2806 | /// We get here from evaluateAsInitializer(). |
2807 | /// We need to evaluate the initializer and return its value. |
2808 | template <class Emitter> |
2809 | bool ByteCodeExprGen<Emitter>::visitDecl(const VarDecl *VD) { |
2810 | assert(!VD->isInvalidDecl() && "Trying to constant evaluate an invalid decl" ); |
2811 | |
2812 | // Global variable we've already seen but that's uninitialized means |
2813 | // evaluating the initializer failed. Just return failure. |
2814 | if (std::optional<unsigned> Index = P.getGlobal(VD); |
2815 | Index && !P.getPtrGlobal(Idx: *Index).isInitialized()) |
2816 | return false; |
2817 | |
2818 | // Create and initialize the variable. |
2819 | if (!this->visitVarDecl(VD)) |
2820 | return false; |
2821 | |
2822 | std::optional<PrimType> VarT = classify(VD->getType()); |
2823 | // Get a pointer to the variable |
2824 | if (Context::shouldBeGloballyIndexed(VD)) { |
2825 | auto GlobalIndex = P.getGlobal(VD); |
2826 | assert(GlobalIndex); // visitVarDecl() didn't return false. |
2827 | if (VarT) { |
2828 | if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD)) |
2829 | return false; |
2830 | } else { |
2831 | if (!this->emitGetPtrGlobal(*GlobalIndex, VD)) |
2832 | return false; |
2833 | } |
2834 | } else { |
2835 | auto Local = Locals.find(VD); |
2836 | assert(Local != Locals.end()); // Same here. |
2837 | if (VarT) { |
2838 | if (!this->emitGetLocal(*VarT, Local->second.Offset, VD)) |
2839 | return false; |
2840 | } else { |
2841 | if (!this->emitGetPtrLocal(Local->second.Offset, VD)) |
2842 | return false; |
2843 | } |
2844 | } |
2845 | |
2846 | // Return the value |
2847 | if (VarT) |
2848 | return this->emitRet(*VarT, VD); |
2849 | |
2850 | // Return non-primitive values as pointers here. |
2851 | return this->emitRet(PT_Ptr, VD); |
2852 | } |
2853 | |
2854 | template <class Emitter> |
2855 | bool ByteCodeExprGen<Emitter>::visitVarDecl(const VarDecl *VD) { |
2856 | // We don't know what to do with these, so just return false. |
2857 | if (VD->getType().isNull()) |
2858 | return false; |
2859 | |
2860 | const Expr *Init = VD->getInit(); |
2861 | std::optional<PrimType> VarT = classify(VD->getType()); |
2862 | |
2863 | if (Context::shouldBeGloballyIndexed(VD)) { |
2864 | auto initGlobal = [&](unsigned GlobalIndex) -> bool { |
2865 | assert(Init); |
2866 | DeclScope<Emitter> LocalScope(this, VD); |
2867 | |
2868 | if (VarT) { |
2869 | if (!this->visit(Init)) |
2870 | return false; |
2871 | return this->emitInitGlobal(*VarT, GlobalIndex, VD); |
2872 | } |
2873 | return this->visitGlobalInitializer(Init, GlobalIndex); |
2874 | }; |
2875 | |
2876 | // We've already seen and initialized this global. |
2877 | if (std::optional<unsigned> GlobalIndex = P.getGlobal(VD)) { |
2878 | if (P.getPtrGlobal(Idx: *GlobalIndex).isInitialized()) |
2879 | return true; |
2880 | |
2881 | // The previous attempt at initialization might've been unsuccessful, |
2882 | // so let's try this one. |
2883 | return Init && initGlobal(*GlobalIndex); |
2884 | } |
2885 | |
2886 | std::optional<unsigned> GlobalIndex = P.createGlobal(VD, Init); |
2887 | |
2888 | if (!GlobalIndex) |
2889 | return false; |
2890 | |
2891 | return !Init || initGlobal(*GlobalIndex); |
2892 | } else { |
2893 | VariableScope<Emitter> LocalScope(this); |
2894 | if (VarT) { |
2895 | unsigned Offset = this->allocateLocalPrimitive( |
2896 | VD, *VarT, VD->getType().isConstQualified()); |
2897 | if (Init) { |
2898 | // Compile the initializer in its own scope. |
2899 | ExprScope<Emitter> Scope(this); |
2900 | if (!this->visit(Init)) |
2901 | return false; |
2902 | |
2903 | return this->emitSetLocal(*VarT, Offset, VD); |
2904 | } |
2905 | } else { |
2906 | if (std::optional<unsigned> Offset = this->allocateLocal(VD)) |
2907 | return !Init || this->visitLocalInitializer(Init, *Offset); |
2908 | return false; |
2909 | } |
2910 | return true; |
2911 | } |
2912 | |
2913 | return false; |
2914 | } |
2915 | |
2916 | template <class Emitter> |
2917 | bool ByteCodeExprGen<Emitter>::visitAPValue(const APValue &Val, |
2918 | PrimType ValType, const Expr *E) { |
2919 | assert(!DiscardResult); |
2920 | if (Val.isInt()) |
2921 | return this->emitConst(Val.getInt(), ValType, E); |
2922 | |
2923 | if (Val.isLValue()) { |
2924 | APValue::LValueBase Base = Val.getLValueBase(); |
2925 | if (const Expr *BaseExpr = Base.dyn_cast<const Expr *>()) |
2926 | return this->visit(BaseExpr); |
2927 | } |
2928 | |
2929 | return false; |
2930 | } |
2931 | |
2932 | template <class Emitter> |
2933 | bool ByteCodeExprGen<Emitter>::VisitBuiltinCallExpr(const CallExpr *E) { |
2934 | const Function *Func = getFunction(FD: E->getDirectCallee()); |
2935 | if (!Func) |
2936 | return false; |
2937 | |
2938 | QualType ReturnType = E->getType(); |
2939 | std::optional<PrimType> ReturnT = classify(E); |
2940 | |
2941 | // Non-primitive return type. Prepare storage. |
2942 | if (!Initializing && !ReturnT && !ReturnType->isVoidType()) { |
2943 | std::optional<unsigned> LocalIndex = allocateLocal(Src: E, /*IsExtended=*/false); |
2944 | if (!LocalIndex) |
2945 | return false; |
2946 | if (!this->emitGetPtrLocal(*LocalIndex, E)) |
2947 | return false; |
2948 | } |
2949 | |
2950 | if (!Func->isUnevaluatedBuiltin()) { |
2951 | // Put arguments on the stack. |
2952 | for (const auto *Arg : E->arguments()) { |
2953 | if (!this->visit(Arg)) |
2954 | return false; |
2955 | } |
2956 | } |
2957 | |
2958 | if (!this->emitCallBI(Func, E, E)) |
2959 | return false; |
2960 | |
2961 | if (DiscardResult && !ReturnType->isVoidType()) { |
2962 | assert(ReturnT); |
2963 | return this->emitPop(*ReturnT, E); |
2964 | } |
2965 | |
2966 | return true; |
2967 | } |
2968 | |
2969 | template <class Emitter> |
2970 | bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) { |
2971 | if (E->getBuiltinCallee()) |
2972 | return VisitBuiltinCallExpr(E); |
2973 | |
2974 | QualType ReturnType = E->getCallReturnType(Ctx: Ctx.getASTContext()); |
2975 | std::optional<PrimType> T = classify(ReturnType); |
2976 | bool HasRVO = !ReturnType->isVoidType() && !T; |
2977 | const FunctionDecl *FuncDecl = E->getDirectCallee(); |
2978 | |
2979 | if (HasRVO) { |
2980 | if (DiscardResult) { |
2981 | // If we need to discard the return value but the function returns its |
2982 | // value via an RVO pointer, we need to create one such pointer just |
2983 | // for this call. |
2984 | if (std::optional<unsigned> LocalIndex = allocateLocal(Src: E)) { |
2985 | if (!this->emitGetPtrLocal(*LocalIndex, E)) |
2986 | return false; |
2987 | } |
2988 | } else { |
2989 | // We need the result. Prepare a pointer to return or |
2990 | // dup the current one. |
2991 | if (!Initializing) { |
2992 | if (std::optional<unsigned> LocalIndex = allocateLocal(Src: E)) { |
2993 | if (!this->emitGetPtrLocal(*LocalIndex, E)) |
2994 | return false; |
2995 | } |
2996 | } |
2997 | if (!this->emitDupPtr(E)) |
2998 | return false; |
2999 | } |
3000 | } |
3001 | |
3002 | auto Args = llvm::ArrayRef(E->getArgs(), E->getNumArgs()); |
3003 | // Calling a static operator will still |
3004 | // pass the instance, but we don't need it. |
3005 | // Discard it here. |
3006 | if (isa<CXXOperatorCallExpr>(Val: E)) { |
3007 | if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(Val: FuncDecl); |
3008 | MD && MD->isStatic()) { |
3009 | if (!this->discard(E->getArg(Arg: 0))) |
3010 | return false; |
3011 | Args = Args.drop_front(); |
3012 | } |
3013 | } |
3014 | |
3015 | // Add the (optional, implicit) This pointer. |
3016 | if (const auto *MC = dyn_cast<CXXMemberCallExpr>(Val: E)) { |
3017 | if (!this->visit(MC->getImplicitObjectArgument())) |
3018 | return false; |
3019 | } |
3020 | |
3021 | llvm::BitVector NonNullArgs = collectNonNullArgs(F: FuncDecl, Args); |
3022 | // Put arguments on the stack. |
3023 | unsigned ArgIndex = 0; |
3024 | for (const auto *Arg : Args) { |
3025 | if (!this->visit(Arg)) |
3026 | return false; |
3027 | |
3028 | // If we know the callee already, check the known parametrs for nullability. |
3029 | if (FuncDecl && NonNullArgs[ArgIndex]) { |
3030 | PrimType ArgT = classify(Arg).value_or(PT_Ptr); |
3031 | if (ArgT == PT_Ptr || ArgT == PT_FnPtr) { |
3032 | if (!this->emitCheckNonNullArg(ArgT, Arg)) |
3033 | return false; |
3034 | } |
3035 | } |
3036 | ++ArgIndex; |
3037 | } |
3038 | |
3039 | if (FuncDecl) { |
3040 | const Function *Func = getFunction(FD: FuncDecl); |
3041 | if (!Func) |
3042 | return false; |
3043 | assert(HasRVO == Func->hasRVO()); |
3044 | |
3045 | bool HasQualifier = false; |
3046 | if (const auto *ME = dyn_cast<MemberExpr>(Val: E->getCallee())) |
3047 | HasQualifier = ME->hasQualifier(); |
3048 | |
3049 | bool IsVirtual = false; |
3050 | if (const auto *MD = dyn_cast<CXXMethodDecl>(Val: FuncDecl)) |
3051 | IsVirtual = MD->isVirtual(); |
3052 | |
3053 | // In any case call the function. The return value will end up on the stack |
3054 | // and if the function has RVO, we already have the pointer on the stack to |
3055 | // write the result into. |
3056 | if (IsVirtual && !HasQualifier) { |
3057 | uint32_t VarArgSize = 0; |
3058 | unsigned NumParams = Func->getNumWrittenParams(); |
3059 | for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I) |
3060 | VarArgSize += align(primSize(classify(E->getArg(Arg: I)).value_or(PT_Ptr))); |
3061 | |
3062 | if (!this->emitCallVirt(Func, VarArgSize, E)) |
3063 | return false; |
3064 | } else if (Func->isVariadic()) { |
3065 | uint32_t VarArgSize = 0; |
3066 | unsigned NumParams = |
3067 | Func->getNumWrittenParams() + isa<CXXOperatorCallExpr>(Val: E); |
3068 | for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I) |
3069 | VarArgSize += align(primSize(classify(E->getArg(Arg: I)).value_or(PT_Ptr))); |
3070 | if (!this->emitCallVar(Func, VarArgSize, E)) |
3071 | return false; |
3072 | } else { |
3073 | if (!this->emitCall(Func, 0, E)) |
3074 | return false; |
3075 | } |
3076 | } else { |
3077 | // Indirect call. Visit the callee, which will leave a FunctionPointer on |
3078 | // the stack. Cleanup of the returned value if necessary will be done after |
3079 | // the function call completed. |
3080 | |
3081 | // Sum the size of all args from the call expr. |
3082 | uint32_t ArgSize = 0; |
3083 | for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) |
3084 | ArgSize += align(primSize(classify(E->getArg(Arg: I)).value_or(PT_Ptr))); |
3085 | |
3086 | if (!this->visit(E->getCallee())) |
3087 | return false; |
3088 | |
3089 | if (!this->emitCallPtr(ArgSize, E, E)) |
3090 | return false; |
3091 | } |
3092 | |
3093 | // Cleanup for discarded return values. |
3094 | if (DiscardResult && !ReturnType->isVoidType() && T) |
3095 | return this->emitPop(*T, E); |
3096 | |
3097 | return true; |
3098 | } |
3099 | |
3100 | template <class Emitter> |
3101 | bool ByteCodeExprGen<Emitter>::VisitCXXDefaultInitExpr( |
3102 | const CXXDefaultInitExpr *E) { |
3103 | SourceLocScope<Emitter> SLS(this, E); |
3104 | return this->delegate(E->getExpr()); |
3105 | } |
3106 | |
3107 | template <class Emitter> |
3108 | bool ByteCodeExprGen<Emitter>::VisitCXXDefaultArgExpr( |
3109 | const CXXDefaultArgExpr *E) { |
3110 | SourceLocScope<Emitter> SLS(this, E); |
3111 | |
3112 | const Expr *SubExpr = E->getExpr(); |
3113 | if (std::optional<PrimType> T = classify(E->getExpr())) |
3114 | return this->visit(SubExpr); |
3115 | |
3116 | assert(Initializing); |
3117 | return this->visitInitializer(SubExpr); |
3118 | } |
3119 | |
3120 | template <class Emitter> |
3121 | bool ByteCodeExprGen<Emitter>::VisitCXXBoolLiteralExpr( |
3122 | const CXXBoolLiteralExpr *E) { |
3123 | if (DiscardResult) |
3124 | return true; |
3125 | |
3126 | return this->emitConstBool(E->getValue(), E); |
3127 | } |
3128 | |
3129 | template <class Emitter> |
3130 | bool ByteCodeExprGen<Emitter>::VisitCXXNullPtrLiteralExpr( |
3131 | const CXXNullPtrLiteralExpr *E) { |
3132 | if (DiscardResult) |
3133 | return true; |
3134 | |
3135 | return this->emitNullPtr(nullptr, E); |
3136 | } |
3137 | |
3138 | template <class Emitter> |
3139 | bool ByteCodeExprGen<Emitter>::VisitGNUNullExpr(const GNUNullExpr *E) { |
3140 | if (DiscardResult) |
3141 | return true; |
3142 | |
3143 | assert(E->getType()->isIntegerType()); |
3144 | |
3145 | PrimType T = classifyPrim(E->getType()); |
3146 | return this->emitZero(T, E); |
3147 | } |
3148 | |
3149 | template <class Emitter> |
3150 | bool ByteCodeExprGen<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) { |
3151 | if (DiscardResult) |
3152 | return true; |
3153 | |
3154 | if (this->LambdaThisCapture.Offset > 0) { |
3155 | if (this->LambdaThisCapture.IsPtr) |
3156 | return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset, E); |
3157 | return this->emitGetPtrThisField(this->LambdaThisCapture.Offset, E); |
3158 | } |
3159 | |
3160 | return this->emitThis(E); |
3161 | } |
3162 | |
3163 | template <class Emitter> |
3164 | bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) { |
3165 | const Expr *SubExpr = E->getSubExpr(); |
3166 | if (SubExpr->getType()->isAnyComplexType()) |
3167 | return this->VisitComplexUnaryOperator(E); |
3168 | std::optional<PrimType> T = classify(SubExpr->getType()); |
3169 | |
3170 | switch (E->getOpcode()) { |
3171 | case UO_PostInc: { // x++ |
3172 | if (!this->visit(SubExpr)) |
3173 | return false; |
3174 | |
3175 | if (T == PT_Ptr || T == PT_FnPtr) { |
3176 | if (!this->emitIncPtr(E)) |
3177 | return false; |
3178 | |
3179 | return DiscardResult ? this->emitPopPtr(E) : true; |
3180 | } |
3181 | |
3182 | if (T == PT_Float) { |
3183 | return DiscardResult ? this->emitIncfPop(getRoundingMode(E), E) |
3184 | : this->emitIncf(getRoundingMode(E), E); |
3185 | } |
3186 | |
3187 | return DiscardResult ? this->emitIncPop(*T, E) : this->emitInc(*T, E); |
3188 | } |
3189 | case UO_PostDec: { // x-- |
3190 | if (!this->visit(SubExpr)) |
3191 | return false; |
3192 | |
3193 | if (T == PT_Ptr || T == PT_FnPtr) { |
3194 | if (!this->emitDecPtr(E)) |
3195 | return false; |
3196 | |
3197 | return DiscardResult ? this->emitPopPtr(E) : true; |
3198 | } |
3199 | |
3200 | if (T == PT_Float) { |
3201 | return DiscardResult ? this->emitDecfPop(getRoundingMode(E), E) |
3202 | : this->emitDecf(getRoundingMode(E), E); |
3203 | } |
3204 | |
3205 | return DiscardResult ? this->emitDecPop(*T, E) : this->emitDec(*T, E); |
3206 | } |
3207 | case UO_PreInc: { // ++x |
3208 | if (!this->visit(SubExpr)) |
3209 | return false; |
3210 | |
3211 | if (T == PT_Ptr || T == PT_FnPtr) { |
3212 | if (!this->emitLoadPtr(E)) |
3213 | return false; |
3214 | if (!this->emitConstUint8(1, E)) |
3215 | return false; |
3216 | if (!this->emitAddOffsetUint8(E)) |
3217 | return false; |
3218 | return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E); |
3219 | } |
3220 | |
3221 | // Post-inc and pre-inc are the same if the value is to be discarded. |
3222 | if (DiscardResult) { |
3223 | if (T == PT_Float) |
3224 | return this->emitIncfPop(getRoundingMode(E), E); |
3225 | return this->emitIncPop(*T, E); |
3226 | } |
3227 | |
3228 | if (T == PT_Float) { |
3229 | const auto &TargetSemantics = Ctx.getFloatSemantics(T: E->getType()); |
3230 | if (!this->emitLoadFloat(E)) |
3231 | return false; |
3232 | if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E)) |
3233 | return false; |
3234 | if (!this->emitAddf(getRoundingMode(E), E)) |
3235 | return false; |
3236 | if (!this->emitStoreFloat(E)) |
3237 | return false; |
3238 | } else { |
3239 | assert(isIntegralType(*T)); |
3240 | if (!this->emitLoad(*T, E)) |
3241 | return false; |
3242 | if (!this->emitConst(1, E)) |
3243 | return false; |
3244 | if (!this->emitAdd(*T, E)) |
3245 | return false; |
3246 | if (!this->emitStore(*T, E)) |
3247 | return false; |
3248 | } |
3249 | return E->isGLValue() || this->emitLoadPop(*T, E); |
3250 | } |
3251 | case UO_PreDec: { // --x |
3252 | if (!this->visit(SubExpr)) |
3253 | return false; |
3254 | |
3255 | if (T == PT_Ptr || T == PT_FnPtr) { |
3256 | if (!this->emitLoadPtr(E)) |
3257 | return false; |
3258 | if (!this->emitConstUint8(1, E)) |
3259 | return false; |
3260 | if (!this->emitSubOffsetUint8(E)) |
3261 | return false; |
3262 | return DiscardResult ? this->emitStorePopPtr(E) : this->emitStorePtr(E); |
3263 | } |
3264 | |
3265 | // Post-dec and pre-dec are the same if the value is to be discarded. |
3266 | if (DiscardResult) { |
3267 | if (T == PT_Float) |
3268 | return this->emitDecfPop(getRoundingMode(E), E); |
3269 | return this->emitDecPop(*T, E); |
3270 | } |
3271 | |
3272 | if (T == PT_Float) { |
3273 | const auto &TargetSemantics = Ctx.getFloatSemantics(T: E->getType()); |
3274 | if (!this->emitLoadFloat(E)) |
3275 | return false; |
3276 | if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E)) |
3277 | return false; |
3278 | if (!this->emitSubf(getRoundingMode(E), E)) |
3279 | return false; |
3280 | if (!this->emitStoreFloat(E)) |
3281 | return false; |
3282 | } else { |
3283 | assert(isIntegralType(*T)); |
3284 | if (!this->emitLoad(*T, E)) |
3285 | return false; |
3286 | if (!this->emitConst(1, E)) |
3287 | return false; |
3288 | if (!this->emitSub(*T, E)) |
3289 | return false; |
3290 | if (!this->emitStore(*T, E)) |
3291 | return false; |
3292 | } |
3293 | return E->isGLValue() || this->emitLoadPop(*T, E); |
3294 | } |
3295 | case UO_LNot: // !x |
3296 | if (DiscardResult) |
3297 | return this->discard(SubExpr); |
3298 | |
3299 | if (!this->visitBool(SubExpr)) |
3300 | return false; |
3301 | |
3302 | if (!this->emitInvBool(E)) |
3303 | return false; |
3304 | |
3305 | if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool) |
3306 | return this->emitCast(PT_Bool, ET, E); |
3307 | return true; |
3308 | case UO_Minus: // -x |
3309 | if (!this->visit(SubExpr)) |
3310 | return false; |
3311 | return DiscardResult ? this->emitPop(*T, E) : this->emitNeg(*T, E); |
3312 | case UO_Plus: // +x |
3313 | if (!this->visit(SubExpr)) // noop |
3314 | return false; |
3315 | return DiscardResult ? this->emitPop(*T, E) : true; |
3316 | case UO_AddrOf: // &x |
3317 | // We should already have a pointer when we get here. |
3318 | return this->delegate(SubExpr); |
3319 | case UO_Deref: // *x |
3320 | if (DiscardResult) |
3321 | return this->discard(SubExpr); |
3322 | return this->visit(SubExpr); |
3323 | case UO_Not: // ~x |
3324 | if (!this->visit(SubExpr)) |
3325 | return false; |
3326 | return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E); |
3327 | case UO_Real: // __real x |
3328 | assert(T); |
3329 | return this->delegate(SubExpr); |
3330 | case UO_Imag: { // __imag x |
3331 | assert(T); |
3332 | if (!this->discard(SubExpr)) |
3333 | return false; |
3334 | return this->visitZeroInitializer(*T, SubExpr->getType(), SubExpr); |
3335 | } |
3336 | case UO_Extension: |
3337 | return this->delegate(SubExpr); |
3338 | case UO_Coawait: |
3339 | assert(false && "Unhandled opcode" ); |
3340 | } |
3341 | |
3342 | return false; |
3343 | } |
3344 | |
3345 | template <class Emitter> |
3346 | bool ByteCodeExprGen<Emitter>::VisitComplexUnaryOperator( |
3347 | const UnaryOperator *E) { |
3348 | const Expr *SubExpr = E->getSubExpr(); |
3349 | assert(SubExpr->getType()->isAnyComplexType()); |
3350 | |
3351 | if (DiscardResult) |
3352 | return this->discard(SubExpr); |
3353 | |
3354 | std::optional<PrimType> ResT = classify(E); |
3355 | auto prepareResult = [=]() -> bool { |
3356 | if (!ResT && !Initializing) { |
3357 | std::optional<unsigned> LocalIndex = |
3358 | allocateLocal(Src: SubExpr, /*IsExtended=*/false); |
3359 | if (!LocalIndex) |
3360 | return false; |
3361 | return this->emitGetPtrLocal(*LocalIndex, E); |
3362 | } |
3363 | |
3364 | return true; |
3365 | }; |
3366 | |
3367 | // The offset of the temporary, if we created one. |
3368 | unsigned SubExprOffset = ~0u; |
3369 | auto createTemp = [=, &SubExprOffset]() -> bool { |
3370 | SubExprOffset = this->allocateLocalPrimitive(SubExpr, PT_Ptr, true, false); |
3371 | if (!this->visit(SubExpr)) |
3372 | return false; |
3373 | return this->emitSetLocal(PT_Ptr, SubExprOffset, E); |
3374 | }; |
3375 | |
3376 | PrimType ElemT = classifyComplexElementType(T: SubExpr->getType()); |
3377 | auto getElem = [=](unsigned Offset, unsigned Index) -> bool { |
3378 | if (!this->emitGetLocal(PT_Ptr, Offset, E)) |
3379 | return false; |
3380 | return this->emitArrayElemPop(ElemT, Index, E); |
3381 | }; |
3382 | |
3383 | switch (E->getOpcode()) { |
3384 | case UO_Minus: |
3385 | if (!prepareResult()) |
3386 | return false; |
3387 | if (!createTemp()) |
3388 | return false; |
3389 | for (unsigned I = 0; I != 2; ++I) { |
3390 | if (!getElem(SubExprOffset, I)) |
3391 | return false; |
3392 | if (!this->emitNeg(ElemT, E)) |
3393 | return false; |
3394 | if (!this->emitInitElem(ElemT, I, E)) |
3395 | return false; |
3396 | } |
3397 | break; |
3398 | |
3399 | case UO_Plus: // +x |
3400 | case UO_AddrOf: // &x |
3401 | case UO_Deref: // *x |
3402 | return this->delegate(SubExpr); |
3403 | |
3404 | case UO_LNot: |
3405 | if (!this->visit(SubExpr)) |
3406 | return false; |
3407 | if (!this->emitComplexBoolCast(SubExpr)) |
3408 | return false; |
3409 | if (!this->emitInvBool(E)) |
3410 | return false; |
3411 | if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool) |
3412 | return this->emitCast(PT_Bool, ET, E); |
3413 | return true; |
3414 | |
3415 | case UO_Real: |
3416 | return this->emitComplexReal(SubExpr); |
3417 | |
3418 | case UO_Imag: |
3419 | if (!this->visit(SubExpr)) |
3420 | return false; |
3421 | |
3422 | if (SubExpr->isLValue()) { |
3423 | if (!this->emitConstUint8(1, E)) |
3424 | return false; |
3425 | return this->emitArrayElemPtrPopUint8(E); |
3426 | } |
3427 | |
3428 | // Since our _Complex implementation does not map to a primitive type, |
3429 | // we sometimes have to do the lvalue-to-rvalue conversion here manually. |
3430 | return this->emitArrayElemPop(classifyPrim(E->getType()), 1, E); |
3431 | |
3432 | default: |
3433 | return this->emitInvalid(E); |
3434 | } |
3435 | |
3436 | return true; |
3437 | } |
3438 | |
3439 | template <class Emitter> |
3440 | bool ByteCodeExprGen<Emitter>::VisitDeclRefExpr(const DeclRefExpr *E) { |
3441 | if (DiscardResult) |
3442 | return true; |
3443 | |
3444 | const auto *D = E->getDecl(); |
3445 | |
3446 | if (const auto *ECD = dyn_cast<EnumConstantDecl>(Val: D)) { |
3447 | return this->emitConst(ECD->getInitVal(), E); |
3448 | } else if (const auto *BD = dyn_cast<BindingDecl>(Val: D)) { |
3449 | return this->visit(BD->getBinding()); |
3450 | } else if (const auto *FuncDecl = dyn_cast<FunctionDecl>(Val: D)) { |
3451 | const Function *F = getFunction(FD: FuncDecl); |
3452 | return F && this->emitGetFnPtr(F, E); |
3453 | } else if (isa<TemplateParamObjectDecl>(Val: D)) { |
3454 | if (std::optional<unsigned> Index = P.getOrCreateGlobal(VD: D)) |
3455 | return this->emitGetPtrGlobal(*Index, E); |
3456 | return false; |
3457 | } |
3458 | |
3459 | // References are implemented via pointers, so when we see a DeclRefExpr |
3460 | // pointing to a reference, we need to get its value directly (i.e. the |
3461 | // pointer to the actual value) instead of a pointer to the pointer to the |
3462 | // value. |
3463 | bool IsReference = D->getType()->isReferenceType(); |
3464 | |
3465 | // Check for local/global variables and parameters. |
3466 | if (auto It = Locals.find(Val: D); It != Locals.end()) { |
3467 | const unsigned Offset = It->second.Offset; |
3468 | if (IsReference) |
3469 | return this->emitGetLocal(PT_Ptr, Offset, E); |
3470 | return this->emitGetPtrLocal(Offset, E); |
3471 | } else if (auto GlobalIndex = P.getGlobal(VD: D)) { |
3472 | if (IsReference) |
3473 | return this->emitGetGlobalPtr(*GlobalIndex, E); |
3474 | |
3475 | return this->emitGetPtrGlobal(*GlobalIndex, E); |
3476 | } else if (const auto *PVD = dyn_cast<ParmVarDecl>(Val: D)) { |
3477 | if (auto It = this->Params.find(PVD); It != this->Params.end()) { |
3478 | if (IsReference || !It->second.IsPtr) |
3479 | return this->emitGetParamPtr(It->second.Offset, E); |
3480 | |
3481 | return this->emitGetPtrParam(It->second.Offset, E); |
3482 | } |
3483 | } |
3484 | |
3485 | // Handle lambda captures. |
3486 | if (auto It = this->LambdaCaptures.find(D); |
3487 | It != this->LambdaCaptures.end()) { |
3488 | auto [Offset, IsPtr] = It->second; |
3489 | |
3490 | if (IsPtr) |
3491 | return this->emitGetThisFieldPtr(Offset, E); |
3492 | return this->emitGetPtrThisField(Offset, E); |
3493 | } |
3494 | |
3495 | // Try to lazily visit (or emit dummy pointers for) declarations |
3496 | // we haven't seen yet. |
3497 | if (Ctx.getLangOpts().CPlusPlus) { |
3498 | if (const auto *VD = dyn_cast<VarDecl>(Val: D)) { |
3499 | // Visit local const variables like normal. |
3500 | if ((VD->isLocalVarDecl() || VD->isStaticDataMember()) && |
3501 | VD->getType().isConstQualified()) { |
3502 | if (!this->visitVarDecl(VD)) |
3503 | return false; |
3504 | // Retry. |
3505 | return this->VisitDeclRefExpr(E); |
3506 | } |
3507 | } |
3508 | } else { |
3509 | if (const auto *VD = dyn_cast<VarDecl>(Val: D); |
3510 | VD && VD->getAnyInitializer() && VD->getType().isConstQualified()) { |
3511 | if (!this->visitVarDecl(VD)) |
3512 | return false; |
3513 | // Retry. |
3514 | return this->VisitDeclRefExpr(E); |
3515 | } |
3516 | } |
3517 | |
3518 | if (std::optional<unsigned> I = P.getOrCreateDummy(VD: D)) |
3519 | return this->emitGetPtrGlobal(*I, E); |
3520 | |
3521 | return this->emitInvalidDeclRef(E, E); |
3522 | } |
3523 | |
3524 | template <class Emitter> |
3525 | void ByteCodeExprGen<Emitter>::emitCleanup() { |
3526 | for (VariableScope<Emitter> *C = VarScope; C; C = C->getParent()) |
3527 | C->emitDestruction(); |
3528 | } |
3529 | |
3530 | template <class Emitter> |
3531 | unsigned |
3532 | ByteCodeExprGen<Emitter>::collectBaseOffset(const RecordType *BaseType, |
3533 | const RecordType *DerivedType) { |
3534 | assert(BaseType); |
3535 | assert(DerivedType); |
3536 | const auto *FinalDecl = cast<CXXRecordDecl>(Val: BaseType->getDecl()); |
3537 | const RecordDecl *CurDecl = DerivedType->getDecl(); |
3538 | const Record *CurRecord = getRecord(CurDecl); |
3539 | assert(CurDecl && FinalDecl); |
3540 | |
3541 | unsigned OffsetSum = 0; |
3542 | for (;;) { |
3543 | assert(CurRecord->getNumBases() > 0); |
3544 | // One level up |
3545 | for (const Record::Base &B : CurRecord->bases()) { |
3546 | const auto *BaseDecl = cast<CXXRecordDecl>(Val: B.Decl); |
3547 | |
3548 | if (BaseDecl == FinalDecl || BaseDecl->isDerivedFrom(Base: FinalDecl)) { |
3549 | OffsetSum += B.Offset; |
3550 | CurRecord = B.R; |
3551 | CurDecl = BaseDecl; |
3552 | break; |
3553 | } |
3554 | } |
3555 | if (CurDecl == FinalDecl) |
3556 | break; |
3557 | } |
3558 | |
3559 | assert(OffsetSum > 0); |
3560 | return OffsetSum; |
3561 | } |
3562 | |
3563 | /// Emit casts from a PrimType to another PrimType. |
3564 | template <class Emitter> |
3565 | bool ByteCodeExprGen<Emitter>::emitPrimCast(PrimType FromT, PrimType ToT, |
3566 | QualType ToQT, const Expr *E) { |
3567 | |
3568 | if (FromT == PT_Float) { |
3569 | // Floating to floating. |
3570 | if (ToT == PT_Float) { |
3571 | const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(T: ToQT); |
3572 | return this->emitCastFP(ToSem, getRoundingMode(E), E); |
3573 | } |
3574 | |
3575 | // Float to integral. |
3576 | if (isIntegralType(T: ToT) || ToT == PT_Bool) |
3577 | return this->emitCastFloatingIntegral(ToT, E); |
3578 | } |
3579 | |
3580 | if (isIntegralType(T: FromT) || FromT == PT_Bool) { |
3581 | // Integral to integral. |
3582 | if (isIntegralType(T: ToT) || ToT == PT_Bool) |
3583 | return FromT != ToT ? this->emitCast(FromT, ToT, E) : true; |
3584 | |
3585 | if (ToT == PT_Float) { |
3586 | // Integral to floating. |
3587 | const llvm::fltSemantics *ToSem = &Ctx.getFloatSemantics(T: ToQT); |
3588 | return this->emitCastIntegralFloating(FromT, ToSem, getRoundingMode(E), |
3589 | E); |
3590 | } |
3591 | } |
3592 | |
3593 | return false; |
3594 | } |
3595 | |
3596 | /// Emits __real(SubExpr) |
3597 | template <class Emitter> |
3598 | bool ByteCodeExprGen<Emitter>::emitComplexReal(const Expr *SubExpr) { |
3599 | assert(SubExpr->getType()->isAnyComplexType()); |
3600 | |
3601 | if (DiscardResult) |
3602 | return this->discard(SubExpr); |
3603 | |
3604 | if (!this->visit(SubExpr)) |
3605 | return false; |
3606 | if (SubExpr->isLValue()) { |
3607 | if (!this->emitConstUint8(0, SubExpr)) |
3608 | return false; |
3609 | return this->emitArrayElemPtrPopUint8(SubExpr); |
3610 | } |
3611 | |
3612 | // Rvalue, load the actual element. |
3613 | return this->emitArrayElemPop(classifyComplexElementType(T: SubExpr->getType()), |
3614 | 0, SubExpr); |
3615 | } |
3616 | |
3617 | template <class Emitter> |
3618 | bool ByteCodeExprGen<Emitter>::emitComplexBoolCast(const Expr *E) { |
3619 | assert(!DiscardResult); |
3620 | PrimType ElemT = classifyComplexElementType(T: E->getType()); |
3621 | // We emit the expression (__real(E) != 0 || __imag(E) != 0) |
3622 | // for us, that means (bool)E[0] || (bool)E[1] |
3623 | if (!this->emitArrayElem(ElemT, 0, E)) |
3624 | return false; |
3625 | if (ElemT == PT_Float) { |
3626 | if (!this->emitCastFloatingIntegral(PT_Bool, E)) |
3627 | return false; |
3628 | } else { |
3629 | if (!this->emitCast(ElemT, PT_Bool, E)) |
3630 | return false; |
3631 | } |
3632 | |
3633 | // We now have the bool value of E[0] on the stack. |
3634 | LabelTy LabelTrue = this->getLabel(); |
3635 | if (!this->jumpTrue(LabelTrue)) |
3636 | return false; |
3637 | |
3638 | if (!this->emitArrayElemPop(ElemT, 1, E)) |
3639 | return false; |
3640 | if (ElemT == PT_Float) { |
3641 | if (!this->emitCastFloatingIntegral(PT_Bool, E)) |
3642 | return false; |
3643 | } else { |
3644 | if (!this->emitCast(ElemT, PT_Bool, E)) |
3645 | return false; |
3646 | } |
3647 | // Leave the boolean value of E[1] on the stack. |
3648 | LabelTy EndLabel = this->getLabel(); |
3649 | this->jump(EndLabel); |
3650 | |
3651 | this->emitLabel(LabelTrue); |
3652 | if (!this->emitPopPtr(E)) |
3653 | return false; |
3654 | if (!this->emitConstBool(true, E)) |
3655 | return false; |
3656 | |
3657 | this->fallthrough(EndLabel); |
3658 | this->emitLabel(EndLabel); |
3659 | |
3660 | return true; |
3661 | } |
3662 | |
3663 | template <class Emitter> |
3664 | bool ByteCodeExprGen<Emitter>::emitComplexComparison(const Expr *LHS, |
3665 | const Expr *RHS, |
3666 | const BinaryOperator *E) { |
3667 | assert(E->isComparisonOp()); |
3668 | assert(!Initializing); |
3669 | assert(!DiscardResult); |
3670 | |
3671 | PrimType ElemT; |
3672 | bool LHSIsComplex; |
3673 | unsigned LHSOffset; |
3674 | if (LHS->getType()->isAnyComplexType()) { |
3675 | LHSIsComplex = true; |
3676 | ElemT = classifyComplexElementType(T: LHS->getType()); |
3677 | LHSOffset = allocateLocalPrimitive(Src: LHS, Ty: PT_Ptr, /*IsConst=*/true, |
3678 | /*IsExtended=*/false); |
3679 | if (!this->visit(LHS)) |
3680 | return false; |
3681 | if (!this->emitSetLocal(PT_Ptr, LHSOffset, E)) |
3682 | return false; |
3683 | } else { |
3684 | LHSIsComplex = false; |
3685 | PrimType LHST = classifyPrim(LHS->getType()); |
3686 | LHSOffset = this->allocateLocalPrimitive(LHS, LHST, true, false); |
3687 | if (!this->visit(LHS)) |
3688 | return false; |
3689 | if (!this->emitSetLocal(LHST, LHSOffset, E)) |
3690 | return false; |
3691 | } |
3692 | |
3693 | bool RHSIsComplex; |
3694 | unsigned RHSOffset; |
3695 | if (RHS->getType()->isAnyComplexType()) { |
3696 | RHSIsComplex = true; |
3697 | ElemT = classifyComplexElementType(T: RHS->getType()); |
3698 | RHSOffset = allocateLocalPrimitive(Src: RHS, Ty: PT_Ptr, /*IsConst=*/true, |
3699 | /*IsExtended=*/false); |
3700 | if (!this->visit(RHS)) |
3701 | return false; |
3702 | if (!this->emitSetLocal(PT_Ptr, RHSOffset, E)) |
3703 | return false; |
3704 | } else { |
3705 | RHSIsComplex = false; |
3706 | PrimType RHST = classifyPrim(RHS->getType()); |
3707 | RHSOffset = this->allocateLocalPrimitive(RHS, RHST, true, false); |
3708 | if (!this->visit(RHS)) |
3709 | return false; |
3710 | if (!this->emitSetLocal(RHST, RHSOffset, E)) |
3711 | return false; |
3712 | } |
3713 | |
3714 | auto getElem = [&](unsigned LocalOffset, unsigned Index, |
3715 | bool IsComplex) -> bool { |
3716 | if (IsComplex) { |
3717 | if (!this->emitGetLocal(PT_Ptr, LocalOffset, E)) |
3718 | return false; |
3719 | return this->emitArrayElemPop(ElemT, Index, E); |
3720 | } |
3721 | return this->emitGetLocal(ElemT, LocalOffset, E); |
3722 | }; |
3723 | |
3724 | for (unsigned I = 0; I != 2; ++I) { |
3725 | // Get both values. |
3726 | if (!getElem(LHSOffset, I, LHSIsComplex)) |
3727 | return false; |
3728 | if (!getElem(RHSOffset, I, RHSIsComplex)) |
3729 | return false; |
3730 | // And compare them. |
3731 | if (!this->emitEQ(ElemT, E)) |
3732 | return false; |
3733 | |
3734 | if (!this->emitCastBoolUint8(E)) |
3735 | return false; |
3736 | } |
3737 | |
3738 | // We now have two bool values on the stack. Compare those. |
3739 | if (!this->emitAddUint8(E)) |
3740 | return false; |
3741 | if (!this->emitConstUint8(2, E)) |
3742 | return false; |
3743 | |
3744 | if (E->getOpcode() == BO_EQ) { |
3745 | if (!this->emitEQUint8(E)) |
3746 | return false; |
3747 | } else if (E->getOpcode() == BO_NE) { |
3748 | if (!this->emitNEUint8(E)) |
3749 | return false; |
3750 | } else |
3751 | return false; |
3752 | |
3753 | // In C, this returns an int. |
3754 | if (PrimType ResT = classifyPrim(E->getType()); ResT != PT_Bool) |
3755 | return this->emitCast(PT_Bool, ResT, E); |
3756 | return true; |
3757 | } |
3758 | |
3759 | /// When calling this, we have a pointer of the local-to-destroy |
3760 | /// on the stack. |
3761 | /// Emit destruction of record types (or arrays of record types). |
3762 | template <class Emitter> |
3763 | bool ByteCodeExprGen<Emitter>::emitRecordDestruction(const Record *R) { |
3764 | assert(R); |
3765 | // First, destroy all fields. |
3766 | for (const Record::Field &Field : llvm::reverse(C: R->fields())) { |
3767 | const Descriptor *D = Field.Desc; |
3768 | if (!D->isPrimitive() && !D->isPrimitiveArray()) { |
3769 | if (!this->emitDupPtr(SourceInfo{})) |
3770 | return false; |
3771 | if (!this->emitGetPtrField(Field.Offset, SourceInfo{})) |
3772 | return false; |
3773 | if (!this->emitDestruction(D)) |
3774 | return false; |
3775 | if (!this->emitPopPtr(SourceInfo{})) |
3776 | return false; |
3777 | } |
3778 | } |
3779 | |
3780 | // FIXME: Unions need to be handled differently here. We don't want to |
3781 | // call the destructor of its members. |
3782 | |
3783 | // Now emit the destructor and recurse into base classes. |
3784 | if (const CXXDestructorDecl *Dtor = R->getDestructor(); |
3785 | Dtor && !Dtor->isTrivial()) { |
3786 | const Function *DtorFunc = getFunction(FD: Dtor); |
3787 | if (!DtorFunc) |
3788 | return false; |
3789 | assert(DtorFunc->hasThisPointer()); |
3790 | assert(DtorFunc->getNumParams() == 1); |
3791 | if (!this->emitDupPtr(SourceInfo{})) |
3792 | return false; |
3793 | if (!this->emitCall(DtorFunc, 0, SourceInfo{})) |
3794 | return false; |
3795 | } |
3796 | |
3797 | for (const Record::Base &Base : llvm::reverse(C: R->bases())) { |
3798 | if (!this->emitGetPtrBase(Base.Offset, SourceInfo{})) |
3799 | return false; |
3800 | if (!this->emitRecordDestruction(Base.R)) |
3801 | return false; |
3802 | if (!this->emitPopPtr(SourceInfo{})) |
3803 | return false; |
3804 | } |
3805 | |
3806 | // FIXME: Virtual bases. |
3807 | return true; |
3808 | } |
3809 | /// When calling this, we have a pointer of the local-to-destroy |
3810 | /// on the stack. |
3811 | /// Emit destruction of record types (or arrays of record types). |
3812 | template <class Emitter> |
3813 | bool ByteCodeExprGen<Emitter>::emitDestruction(const Descriptor *Desc) { |
3814 | assert(Desc); |
3815 | assert(!Desc->isPrimitive()); |
3816 | assert(!Desc->isPrimitiveArray()); |
3817 | |
3818 | // Arrays. |
3819 | if (Desc->isArray()) { |
3820 | const Descriptor *ElemDesc = Desc->ElemDesc; |
3821 | assert(ElemDesc); |
3822 | |
3823 | // Don't need to do anything for these. |
3824 | if (ElemDesc->isPrimitiveArray()) |
3825 | return true; |
3826 | |
3827 | // If this is an array of record types, check if we need |
3828 | // to call the element destructors at all. If not, try |
3829 | // to save the work. |
3830 | if (const Record *ElemRecord = ElemDesc->ElemRecord) { |
3831 | if (const CXXDestructorDecl *Dtor = ElemRecord->getDestructor(); |
3832 | !Dtor || Dtor->isTrivial()) |
3833 | return true; |
3834 | } |
3835 | |
3836 | for (ssize_t I = Desc->getNumElems() - 1; I >= 0; --I) { |
3837 | if (!this->emitConstUint64(I, SourceInfo{})) |
3838 | return false; |
3839 | if (!this->emitArrayElemPtrUint64(SourceInfo{})) |
3840 | return false; |
3841 | if (!this->emitDestruction(ElemDesc)) |
3842 | return false; |
3843 | if (!this->emitPopPtr(SourceInfo{})) |
3844 | return false; |
3845 | } |
3846 | return true; |
3847 | } |
3848 | |
3849 | assert(Desc->ElemRecord); |
3850 | return this->emitRecordDestruction(Desc->ElemRecord); |
3851 | } |
3852 | |
3853 | namespace clang { |
3854 | namespace interp { |
3855 | |
3856 | template class ByteCodeExprGen<ByteCodeEmitter>; |
3857 | template class ByteCodeExprGen<EvalEmitter>; |
3858 | |
3859 | } // namespace interp |
3860 | } // namespace clang |
3861 | |