18 using namespace clang;
35 return this->addLocal(Local);
50 : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
51 OldInitFn(
std::move(Ctx->InitFn)) {
58 : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
59 OldInitFn(
std::move(Ctx->InitFn)) {
66 : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
67 OldInitFn(
std::move(Ctx->InitFn)) {
68 assert(OldInitFn &&
"missing initializer");
69 Ctx->
InitFn = [
this, NewInitFn] {
return NewInitFn(*OldInitFn); };
73 Ctx->DiscardResult = OldDiscardResult;
74 Ctx->InitFn = std::move(OldInitFn);
81 bool OldDiscardResult;
89 template <
class Emitter>
94 case CK_LValueToRValue: {
103 if (!this->emitLoadPop(T, CE))
105 return DiscardResult ? this->emitPop(T, CE) : true;
109 case CK_ArrayToPointerDecay:
110 case CK_AtomicToNonAtomic:
111 case CK_ConstructorConversion:
112 case CK_FunctionToPointerDecay:
113 case CK_NonAtomicToAtomic:
115 case CK_UserDefinedConversion:
116 return this->Visit(SubExpr);
119 return discard(SubExpr);
123 return this->bail(CE);
128 template <
class Emitter>
133 auto Val =
LE->getValue();
136 return emitConst(*T, getIntWidth(LitTy),
LE->getValue(),
LE);
137 return this->bail(
LE);
140 template <
class Emitter>
145 template <
class Emitter>
155 if (!this->Visit(RHS))
166 return this->bail(BO);
175 auto Discard = [
this, T, BO](
bool Result) {
178 return DiscardResult ? this->emitPop(*T, BO) :
true;
183 return Discard(this->emitEQ(*
LT, BO));
185 return Discard(this->emitNE(*
LT, BO));
187 return Discard(this->emitLT(*
LT, BO));
189 return Discard(this->emitLE(*
LT, BO));
191 return Discard(this->emitGT(*
LT, BO));
193 return Discard(this->emitGE(*
LT, BO));
195 return Discard(this->emitSub(*T, BO));
197 return Discard(this->emitAdd(*T, BO));
199 return Discard(this->emitMul(*T, BO));
201 return this->bail(BO);
205 return this->bail(BO);
208 template <
class Emitter>
211 return this->Visit(E);
214 template <
class Emitter>
217 return this->Visit(E);
220 template <
class Emitter>
225 return this->bail(E);
229 template <
class Emitter>
233 return this->emitZeroBool(E);
235 return this->emitZeroSint8(E);
237 return this->emitZeroUint8(E);
239 return this->emitZeroSint16(E);
241 return this->emitZeroUint16(E);
243 return this->emitZeroSint32(E);
245 return this->emitZeroUint32(E);
247 return this->emitZeroSint64(E);
249 return this->emitZeroUint64(E);
251 return this->emitNullPtr(E);
253 llvm_unreachable(
"unknown primitive type");
256 template <
class Emitter>
258 const Expr *LV, DerefKind AK, llvm::function_ref<
bool(
PrimType)> Direct,
259 llvm::function_ref<
bool(
PrimType)> Indirect) {
263 if (
auto *DE = dyn_cast<DeclRefExpr>(LV)) {
264 if (!DE->getDecl()->getType()->isReferenceType()) {
265 if (
auto *PD = dyn_cast<ParmVarDecl>(DE->getDecl()))
266 return dereferenceParam(LV, *T, PD, AK, Direct, Indirect);
267 if (
auto *VD = dyn_cast<VarDecl>(DE->getDecl()))
268 return dereferenceVar(LV, *T, VD, AK, Direct, Indirect);
281 template <
class Emitter>
284 llvm::function_ref<
bool(
PrimType)> Direct,
285 llvm::function_ref<
bool(
PrimType)> Indirect) {
286 auto It = this->Params.find(PD);
287 if (It != this->Params.end()) {
288 unsigned Idx = It->second;
290 case DerefKind::Read:
291 return DiscardResult ?
true : this->emitGetParam(T, Idx, LV);
296 if (!this->emitSetParam(T, Idx, LV))
298 return DiscardResult ?
true : this->emitGetPtrParam(Idx, LV);
300 case DerefKind::ReadWrite:
301 if (!this->emitGetParam(T, Idx, LV))
305 if (!this->emitSetParam(T, Idx, LV))
307 return DiscardResult ?
true : this->emitGetPtrParam(Idx, LV);
313 if (!DiscardResult && T ==
PT_Ptr && AK == DerefKind::Read) {
314 if (
auto Idx =
P.getOrCreateDummy(PD))
315 return this->emitGetPtrGlobal(*Idx, PD);
320 return visit(LV) && Indirect(T);
323 template <
class Emitter>
326 llvm::function_ref<
bool(
PrimType)> Direct,
327 llvm::function_ref<
bool(
PrimType)> Indirect) {
328 auto It = Locals.find(VD);
329 if (It != Locals.end()) {
330 const auto &L = It->second;
332 case DerefKind::Read:
333 if (!this->emitGetLocal(T, L.Offset, LV))
335 return DiscardResult ? this->emitPop(T, LV) :
true;
340 if (!this->emitSetLocal(T, L.Offset, LV))
342 return DiscardResult ?
true : this->emitGetPtrLocal(L.Offset, LV);
344 case DerefKind::ReadWrite:
345 if (!this->emitGetLocal(T, L.Offset, LV))
349 if (!this->emitSetLocal(T, L.Offset, LV))
351 return DiscardResult ?
true : this->emitGetPtrLocal(L.Offset, LV);
353 }
else if (
auto Idx = getGlobalIdx(VD)) {
355 case DerefKind::Read:
356 if (!this->emitGetGlobal(T, *Idx, LV))
358 return DiscardResult ? this->emitPop(T, LV) :
true;
363 if (!this->emitSetGlobal(T, *Idx, LV))
365 return DiscardResult ?
true : this->emitGetPtrGlobal(*Idx, LV);
367 case DerefKind::ReadWrite:
368 if (!this->emitGetGlobal(T, *Idx, LV))
372 if (!this->emitSetGlobal(T, *Idx, LV))
374 return DiscardResult ?
true : this->emitGetPtrGlobal(*Idx, LV);
381 if (!DiscardResult && AK == DerefKind::Read) {
385 return this->Visit(VD->
getInit());
390 return visit(LV) && Indirect(T);
393 template <
class Emitter>
398 return this->emitConstSint8(
Value.getSExtValue(), E);
400 return this->emitConstUint8(
Value.getZExtValue(), E);
402 return this->emitConstSint16(
Value.getSExtValue(), E);
404 return this->emitConstUint16(
Value.getZExtValue(), E);
406 return this->emitConstSint32(
Value.getSExtValue(), E);
408 return this->emitConstUint32(
Value.getZExtValue(), E);
410 return this->emitConstSint64(
Value.getSExtValue(), E);
412 return this->emitConstUint64(
Value.getZExtValue(), E);
414 return this->emitConstBool(
Value.getBoolValue(), E);
416 llvm_unreachable(
"Invalid integral type");
419 llvm_unreachable(
"unknown primitive type");
422 template <
class Emitter>
427 Descriptor *D =
P.createDescriptor(Src, Ty, IsConst, Src.is<
const Expr *>());
429 if (
auto *VD = dyn_cast_or_null<ValueDecl>(Src.dyn_cast<
const Decl *>()))
430 Locals.insert({VD, Local});
431 VarScope->add(Local, IsExtended);
435 template <
class Emitter>
441 bool IsTemporary =
false;
442 if (
auto *VD = dyn_cast_or_null<ValueDecl>(Src.dyn_cast<
const Decl *>())) {
446 if (
auto *E = Src.dyn_cast<
const Expr *>()) {
458 Locals.insert({Key, Local});
459 VarScope->add(Local, IsExtended);
463 template <
class Emitter>
467 return this->Visit(Init);
470 template <
class Emitter>
475 return this->emitGetGlobalPtr(*Idx, E);
477 return this->emitGetPtrGlobal(*Idx, E);
479 return this->bail(VD);
482 template <
class Emitter>
487 return P.getGlobal(VD);
492 return P.getOrCreateGlobal(VD);
497 template <
class Emitter>
499 if (
auto *PT = dyn_cast<PointerType>(Ty))
505 template <
class Emitter>
507 if (
auto *RecordTy = getRecordTy(Ty)) {
508 return getRecord(RecordTy->getDecl());
513 template <
class Emitter>
515 return P.getOrCreateRecord(RD);
518 template <
class Emitter>
525 return this->emitRet(*T, Exp);
527 return this->emitRetValue(Exp);
530 template <
class Emitter>
544 if (!this->emitDup(*T, VD))
546 if (!this->emitInitGlobal(*T, *I, VD))
548 return this->emitRet(*T, VD);
553 if (!visitGlobalInitializer(Init, *I))
558 if (!this->emitGetPtrGlobal(*I, VD))
560 return this->emitRetValue(VD);
564 return this->bail(VD);
567 template <
class Emitter>
570 C->emitDestruction();