1 1.1 joerg //===--- ByteCodeExprGen.cpp - Code generator for expressions ---*- C++ -*-===// 2 1.1 joerg // 3 1.1 joerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 1.1 joerg // See https://llvm.org/LICENSE.txt for license information. 5 1.1 joerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 1.1 joerg // 7 1.1 joerg //===----------------------------------------------------------------------===// 8 1.1 joerg 9 1.1 joerg #include "ByteCodeExprGen.h" 10 1.1 joerg #include "ByteCodeEmitter.h" 11 1.1 joerg #include "ByteCodeGenError.h" 12 1.1 joerg #include "Context.h" 13 1.1 joerg #include "Function.h" 14 1.1 joerg #include "PrimType.h" 15 1.1 joerg #include "Program.h" 16 1.1 joerg #include "State.h" 17 1.1 joerg 18 1.1 joerg using namespace clang; 19 1.1 joerg using namespace clang::interp; 20 1.1 joerg 21 1.1 joerg using APSInt = llvm::APSInt; 22 1.1 joerg template <typename T> using Expected = llvm::Expected<T>; 23 1.1 joerg template <typename T> using Optional = llvm::Optional<T>; 24 1.1 joerg 25 1.1 joerg namespace clang { 26 1.1 joerg namespace interp { 27 1.1 joerg 28 1.1 joerg /// Scope used to handle temporaries in toplevel variable declarations. 29 1.1 joerg template <class Emitter> class DeclScope final : public LocalScope<Emitter> { 30 1.1 joerg public: 31 1.1 joerg DeclScope(ByteCodeExprGen<Emitter> *Ctx, const VarDecl *VD) 32 1.1 joerg : LocalScope<Emitter>(Ctx), Scope(Ctx->P, VD) {} 33 1.1 joerg 34 1.1 joerg void addExtended(const Scope::Local &Local) override { 35 1.1 joerg return this->addLocal(Local); 36 1.1 joerg } 37 1.1 joerg 38 1.1 joerg private: 39 1.1 joerg Program::DeclScope Scope; 40 1.1 joerg }; 41 1.1 joerg 42 1.1 joerg /// Scope used to handle initialization methods. 43 1.1 joerg template <class Emitter> class OptionScope { 44 1.1 joerg public: 45 1.1 joerg using InitFnRef = typename ByteCodeExprGen<Emitter>::InitFnRef; 46 1.1 joerg using ChainedInitFnRef = std::function<bool(InitFnRef)>; 47 1.1 joerg 48 1.1 joerg /// Root constructor, compiling or discarding primitives. 49 1.1 joerg OptionScope(ByteCodeExprGen<Emitter> *Ctx, bool NewDiscardResult) 50 1.1 joerg : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult), 51 1.1 joerg OldInitFn(std::move(Ctx->InitFn)) { 52 1.1 joerg Ctx->DiscardResult = NewDiscardResult; 53 1.1 joerg Ctx->InitFn = llvm::Optional<InitFnRef>{}; 54 1.1 joerg } 55 1.1 joerg 56 1.1 joerg /// Root constructor, setting up compilation state. 57 1.1 joerg OptionScope(ByteCodeExprGen<Emitter> *Ctx, InitFnRef NewInitFn) 58 1.1 joerg : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult), 59 1.1 joerg OldInitFn(std::move(Ctx->InitFn)) { 60 1.1 joerg Ctx->DiscardResult = true; 61 1.1 joerg Ctx->InitFn = NewInitFn; 62 1.1 joerg } 63 1.1 joerg 64 1.1 joerg /// Extends the chain of initialisation pointers. 65 1.1 joerg OptionScope(ByteCodeExprGen<Emitter> *Ctx, ChainedInitFnRef NewInitFn) 66 1.1 joerg : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult), 67 1.1 joerg OldInitFn(std::move(Ctx->InitFn)) { 68 1.1 joerg assert(OldInitFn && "missing initializer"); 69 1.1 joerg Ctx->InitFn = [this, NewInitFn] { return NewInitFn(*OldInitFn); }; 70 1.1 joerg } 71 1.1 joerg 72 1.1 joerg ~OptionScope() { 73 1.1 joerg Ctx->DiscardResult = OldDiscardResult; 74 1.1 joerg Ctx->InitFn = std::move(OldInitFn); 75 1.1 joerg } 76 1.1 joerg 77 1.1 joerg private: 78 1.1 joerg /// Parent context. 79 1.1 joerg ByteCodeExprGen<Emitter> *Ctx; 80 1.1 joerg /// Old discard flag to restore. 81 1.1 joerg bool OldDiscardResult; 82 1.1 joerg /// Old pointer emitter to restore. 83 1.1 joerg llvm::Optional<InitFnRef> OldInitFn; 84 1.1 joerg }; 85 1.1 joerg 86 1.1 joerg } // namespace interp 87 1.1 joerg } // namespace clang 88 1.1 joerg 89 1.1 joerg template <class Emitter> 90 1.1 joerg bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) { 91 1.1 joerg auto *SubExpr = CE->getSubExpr(); 92 1.1 joerg switch (CE->getCastKind()) { 93 1.1 joerg 94 1.1 joerg case CK_LValueToRValue: { 95 1.1 joerg return dereference( 96 1.1 joerg CE->getSubExpr(), DerefKind::Read, 97 1.1 joerg [](PrimType) { 98 1.1 joerg // Value loaded - nothing to do here. 99 1.1 joerg return true; 100 1.1 joerg }, 101 1.1 joerg [this, CE](PrimType T) { 102 1.1 joerg // Pointer on stack - dereference it. 103 1.1 joerg if (!this->emitLoadPop(T, CE)) 104 1.1 joerg return false; 105 1.1 joerg return DiscardResult ? this->emitPop(T, CE) : true; 106 1.1 joerg }); 107 1.1 joerg } 108 1.1 joerg 109 1.1 joerg case CK_ArrayToPointerDecay: 110 1.1 joerg case CK_AtomicToNonAtomic: 111 1.1 joerg case CK_ConstructorConversion: 112 1.1 joerg case CK_FunctionToPointerDecay: 113 1.1 joerg case CK_NonAtomicToAtomic: 114 1.1 joerg case CK_NoOp: 115 1.1 joerg case CK_UserDefinedConversion: 116 1.1 joerg return this->Visit(SubExpr); 117 1.1 joerg 118 1.1 joerg case CK_ToVoid: 119 1.1 joerg return discard(SubExpr); 120 1.1 joerg 121 1.1 joerg default: { 122 1.1 joerg // TODO: implement other casts. 123 1.1 joerg return this->bail(CE); 124 1.1 joerg } 125 1.1 joerg } 126 1.1 joerg } 127 1.1 joerg 128 1.1 joerg template <class Emitter> 129 1.1 joerg bool ByteCodeExprGen<Emitter>::VisitIntegerLiteral(const IntegerLiteral *LE) { 130 1.1 joerg if (DiscardResult) 131 1.1 joerg return true; 132 1.1 joerg 133 1.1 joerg auto Val = LE->getValue(); 134 1.1 joerg QualType LitTy = LE->getType(); 135 1.1 joerg if (Optional<PrimType> T = classify(LitTy)) 136 1.1 joerg return emitConst(*T, getIntWidth(LitTy), LE->getValue(), LE); 137 1.1 joerg return this->bail(LE); 138 1.1 joerg } 139 1.1 joerg 140 1.1 joerg template <class Emitter> 141 1.1 joerg bool ByteCodeExprGen<Emitter>::VisitParenExpr(const ParenExpr *PE) { 142 1.1 joerg return this->Visit(PE->getSubExpr()); 143 1.1 joerg } 144 1.1 joerg 145 1.1 joerg template <class Emitter> 146 1.1 joerg bool ByteCodeExprGen<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) { 147 1.1 joerg const Expr *LHS = BO->getLHS(); 148 1.1 joerg const Expr *RHS = BO->getRHS(); 149 1.1 joerg 150 1.1 joerg // Deal with operations which have composite or void types. 151 1.1 joerg switch (BO->getOpcode()) { 152 1.1 joerg case BO_Comma: 153 1.1 joerg if (!discard(LHS)) 154 1.1 joerg return false; 155 1.1 joerg if (!this->Visit(RHS)) 156 1.1 joerg return false; 157 1.1 joerg return true; 158 1.1 joerg default: 159 1.1 joerg break; 160 1.1 joerg } 161 1.1 joerg 162 1.1 joerg // Typecheck the args. 163 1.1 joerg Optional<PrimType> LT = classify(LHS->getType()); 164 1.1 joerg Optional<PrimType> RT = classify(RHS->getType()); 165 1.1 joerg if (!LT || !RT) { 166 1.1 joerg return this->bail(BO); 167 1.1 joerg } 168 1.1 joerg 169 1.1 joerg if (Optional<PrimType> T = classify(BO->getType())) { 170 1.1 joerg if (!visit(LHS)) 171 1.1 joerg return false; 172 1.1 joerg if (!visit(RHS)) 173 1.1 joerg return false; 174 1.1 joerg 175 1.1 joerg auto Discard = [this, T, BO](bool Result) { 176 1.1 joerg if (!Result) 177 1.1 joerg return false; 178 1.1 joerg return DiscardResult ? this->emitPop(*T, BO) : true; 179 1.1 joerg }; 180 1.1 joerg 181 1.1 joerg switch (BO->getOpcode()) { 182 1.1 joerg case BO_EQ: 183 1.1 joerg return Discard(this->emitEQ(*LT, BO)); 184 1.1 joerg case BO_NE: 185 1.1 joerg return Discard(this->emitNE(*LT, BO)); 186 1.1 joerg case BO_LT: 187 1.1 joerg return Discard(this->emitLT(*LT, BO)); 188 1.1 joerg case BO_LE: 189 1.1 joerg return Discard(this->emitLE(*LT, BO)); 190 1.1 joerg case BO_GT: 191 1.1 joerg return Discard(this->emitGT(*LT, BO)); 192 1.1 joerg case BO_GE: 193 1.1 joerg return Discard(this->emitGE(*LT, BO)); 194 1.1 joerg case BO_Sub: 195 1.1 joerg return Discard(this->emitSub(*T, BO)); 196 1.1 joerg case BO_Add: 197 1.1 joerg return Discard(this->emitAdd(*T, BO)); 198 1.1 joerg case BO_Mul: 199 1.1 joerg return Discard(this->emitMul(*T, BO)); 200 1.1 joerg default: 201 1.1 joerg return this->bail(BO); 202 1.1 joerg } 203 1.1 joerg } 204 1.1 joerg 205 1.1 joerg return this->bail(BO); 206 1.1 joerg } 207 1.1 joerg 208 1.1 joerg template <class Emitter> 209 1.1 joerg bool ByteCodeExprGen<Emitter>::discard(const Expr *E) { 210 1.1 joerg OptionScope<Emitter> Scope(this, /*discardResult=*/true); 211 1.1 joerg return this->Visit(E); 212 1.1 joerg } 213 1.1 joerg 214 1.1 joerg template <class Emitter> 215 1.1 joerg bool ByteCodeExprGen<Emitter>::visit(const Expr *E) { 216 1.1 joerg OptionScope<Emitter> Scope(this, /*discardResult=*/false); 217 1.1 joerg return this->Visit(E); 218 1.1 joerg } 219 1.1 joerg 220 1.1 joerg template <class Emitter> 221 1.1 joerg bool ByteCodeExprGen<Emitter>::visitBool(const Expr *E) { 222 1.1 joerg if (Optional<PrimType> T = classify(E->getType())) { 223 1.1 joerg return visit(E); 224 1.1 joerg } else { 225 1.1 joerg return this->bail(E); 226 1.1 joerg } 227 1.1 joerg } 228 1.1 joerg 229 1.1 joerg template <class Emitter> 230 1.1 joerg bool ByteCodeExprGen<Emitter>::visitZeroInitializer(PrimType T, const Expr *E) { 231 1.1 joerg switch (T) { 232 1.1 joerg case PT_Bool: 233 1.1 joerg return this->emitZeroBool(E); 234 1.1 joerg case PT_Sint8: 235 1.1 joerg return this->emitZeroSint8(E); 236 1.1 joerg case PT_Uint8: 237 1.1 joerg return this->emitZeroUint8(E); 238 1.1 joerg case PT_Sint16: 239 1.1 joerg return this->emitZeroSint16(E); 240 1.1 joerg case PT_Uint16: 241 1.1 joerg return this->emitZeroUint16(E); 242 1.1 joerg case PT_Sint32: 243 1.1 joerg return this->emitZeroSint32(E); 244 1.1 joerg case PT_Uint32: 245 1.1 joerg return this->emitZeroUint32(E); 246 1.1 joerg case PT_Sint64: 247 1.1 joerg return this->emitZeroSint64(E); 248 1.1 joerg case PT_Uint64: 249 1.1 joerg return this->emitZeroUint64(E); 250 1.1 joerg case PT_Ptr: 251 1.1 joerg return this->emitNullPtr(E); 252 1.1 joerg } 253 1.1 joerg llvm_unreachable("unknown primitive type"); 254 1.1 joerg } 255 1.1 joerg 256 1.1 joerg template <class Emitter> 257 1.1 joerg bool ByteCodeExprGen<Emitter>::dereference( 258 1.1 joerg const Expr *LV, DerefKind AK, llvm::function_ref<bool(PrimType)> Direct, 259 1.1 joerg llvm::function_ref<bool(PrimType)> Indirect) { 260 1.1 joerg if (Optional<PrimType> T = classify(LV->getType())) { 261 1.1 joerg if (!LV->refersToBitField()) { 262 1.1 joerg // Only primitive, non bit-field types can be dereferenced directly. 263 1.1 joerg if (auto *DE = dyn_cast<DeclRefExpr>(LV)) { 264 1.1 joerg if (!DE->getDecl()->getType()->isReferenceType()) { 265 1.1 joerg if (auto *PD = dyn_cast<ParmVarDecl>(DE->getDecl())) 266 1.1 joerg return dereferenceParam(LV, *T, PD, AK, Direct, Indirect); 267 1.1 joerg if (auto *VD = dyn_cast<VarDecl>(DE->getDecl())) 268 1.1 joerg return dereferenceVar(LV, *T, VD, AK, Direct, Indirect); 269 1.1 joerg } 270 1.1 joerg } 271 1.1 joerg } 272 1.1 joerg 273 1.1 joerg if (!visit(LV)) 274 1.1 joerg return false; 275 1.1 joerg return Indirect(*T); 276 1.1 joerg } 277 1.1 joerg 278 1.1 joerg return false; 279 1.1 joerg } 280 1.1 joerg 281 1.1 joerg template <class Emitter> 282 1.1 joerg bool ByteCodeExprGen<Emitter>::dereferenceParam( 283 1.1 joerg const Expr *LV, PrimType T, const ParmVarDecl *PD, DerefKind AK, 284 1.1 joerg llvm::function_ref<bool(PrimType)> Direct, 285 1.1 joerg llvm::function_ref<bool(PrimType)> Indirect) { 286 1.1 joerg auto It = this->Params.find(PD); 287 1.1 joerg if (It != this->Params.end()) { 288 1.1 joerg unsigned Idx = It->second; 289 1.1 joerg switch (AK) { 290 1.1 joerg case DerefKind::Read: 291 1.1 joerg return DiscardResult ? true : this->emitGetParam(T, Idx, LV); 292 1.1 joerg 293 1.1 joerg case DerefKind::Write: 294 1.1 joerg if (!Direct(T)) 295 1.1 joerg return false; 296 1.1 joerg if (!this->emitSetParam(T, Idx, LV)) 297 1.1 joerg return false; 298 1.1 joerg return DiscardResult ? true : this->emitGetPtrParam(Idx, LV); 299 1.1 joerg 300 1.1 joerg case DerefKind::ReadWrite: 301 1.1 joerg if (!this->emitGetParam(T, Idx, LV)) 302 1.1 joerg return false; 303 1.1 joerg if (!Direct(T)) 304 1.1 joerg return false; 305 1.1 joerg if (!this->emitSetParam(T, Idx, LV)) 306 1.1 joerg return false; 307 1.1 joerg return DiscardResult ? true : this->emitGetPtrParam(Idx, LV); 308 1.1 joerg } 309 1.1 joerg return true; 310 1.1 joerg } 311 1.1 joerg 312 1.1 joerg // If the param is a pointer, we can dereference a dummy value. 313 1.1 joerg if (!DiscardResult && T == PT_Ptr && AK == DerefKind::Read) { 314 1.1 joerg if (auto Idx = P.getOrCreateDummy(PD)) 315 1.1 joerg return this->emitGetPtrGlobal(*Idx, PD); 316 1.1 joerg return false; 317 1.1 joerg } 318 1.1 joerg 319 1.1 joerg // Value cannot be produced - try to emit pointer and do stuff with it. 320 1.1 joerg return visit(LV) && Indirect(T); 321 1.1 joerg } 322 1.1 joerg 323 1.1 joerg template <class Emitter> 324 1.1 joerg bool ByteCodeExprGen<Emitter>::dereferenceVar( 325 1.1 joerg const Expr *LV, PrimType T, const VarDecl *VD, DerefKind AK, 326 1.1 joerg llvm::function_ref<bool(PrimType)> Direct, 327 1.1 joerg llvm::function_ref<bool(PrimType)> Indirect) { 328 1.1 joerg auto It = Locals.find(VD); 329 1.1 joerg if (It != Locals.end()) { 330 1.1 joerg const auto &L = It->second; 331 1.1 joerg switch (AK) { 332 1.1 joerg case DerefKind::Read: 333 1.1 joerg if (!this->emitGetLocal(T, L.Offset, LV)) 334 1.1 joerg return false; 335 1.1 joerg return DiscardResult ? this->emitPop(T, LV) : true; 336 1.1 joerg 337 1.1 joerg case DerefKind::Write: 338 1.1 joerg if (!Direct(T)) 339 1.1 joerg return false; 340 1.1 joerg if (!this->emitSetLocal(T, L.Offset, LV)) 341 1.1 joerg return false; 342 1.1 joerg return DiscardResult ? true : this->emitGetPtrLocal(L.Offset, LV); 343 1.1 joerg 344 1.1 joerg case DerefKind::ReadWrite: 345 1.1 joerg if (!this->emitGetLocal(T, L.Offset, LV)) 346 1.1 joerg return false; 347 1.1 joerg if (!Direct(T)) 348 1.1 joerg return false; 349 1.1 joerg if (!this->emitSetLocal(T, L.Offset, LV)) 350 1.1 joerg return false; 351 1.1 joerg return DiscardResult ? true : this->emitGetPtrLocal(L.Offset, LV); 352 1.1 joerg } 353 1.1 joerg } else if (auto Idx = getGlobalIdx(VD)) { 354 1.1 joerg switch (AK) { 355 1.1 joerg case DerefKind::Read: 356 1.1 joerg if (!this->emitGetGlobal(T, *Idx, LV)) 357 1.1 joerg return false; 358 1.1 joerg return DiscardResult ? this->emitPop(T, LV) : true; 359 1.1 joerg 360 1.1 joerg case DerefKind::Write: 361 1.1 joerg if (!Direct(T)) 362 1.1 joerg return false; 363 1.1 joerg if (!this->emitSetGlobal(T, *Idx, LV)) 364 1.1 joerg return false; 365 1.1 joerg return DiscardResult ? true : this->emitGetPtrGlobal(*Idx, LV); 366 1.1 joerg 367 1.1 joerg case DerefKind::ReadWrite: 368 1.1 joerg if (!this->emitGetGlobal(T, *Idx, LV)) 369 1.1 joerg return false; 370 1.1 joerg if (!Direct(T)) 371 1.1 joerg return false; 372 1.1 joerg if (!this->emitSetGlobal(T, *Idx, LV)) 373 1.1 joerg return false; 374 1.1 joerg return DiscardResult ? true : this->emitGetPtrGlobal(*Idx, LV); 375 1.1 joerg } 376 1.1 joerg } 377 1.1 joerg 378 1.1 joerg // If the declaration is a constant value, emit it here even 379 1.1 joerg // though the declaration was not evaluated in the current scope. 380 1.1 joerg // The access mode can only be read in this case. 381 1.1 joerg if (!DiscardResult && AK == DerefKind::Read) { 382 1.1 joerg if (VD->hasLocalStorage() && VD->hasInit() && !VD->isConstexpr()) { 383 1.1 joerg QualType VT = VD->getType(); 384 1.1 joerg if (VT.isConstQualified() && VT->isFundamentalType()) 385 1.1 joerg return this->Visit(VD->getInit()); 386 1.1 joerg } 387 1.1 joerg } 388 1.1 joerg 389 1.1 joerg // Value cannot be produced - try to emit pointer. 390 1.1 joerg return visit(LV) && Indirect(T); 391 1.1 joerg } 392 1.1 joerg 393 1.1 joerg template <class Emitter> 394 1.1 joerg bool ByteCodeExprGen<Emitter>::emitConst(PrimType T, unsigned NumBits, 395 1.1 joerg const APInt &Value, const Expr *E) { 396 1.1 joerg switch (T) { 397 1.1 joerg case PT_Sint8: 398 1.1 joerg return this->emitConstSint8(Value.getSExtValue(), E); 399 1.1 joerg case PT_Uint8: 400 1.1 joerg return this->emitConstUint8(Value.getZExtValue(), E); 401 1.1 joerg case PT_Sint16: 402 1.1 joerg return this->emitConstSint16(Value.getSExtValue(), E); 403 1.1 joerg case PT_Uint16: 404 1.1 joerg return this->emitConstUint16(Value.getZExtValue(), E); 405 1.1 joerg case PT_Sint32: 406 1.1 joerg return this->emitConstSint32(Value.getSExtValue(), E); 407 1.1 joerg case PT_Uint32: 408 1.1 joerg return this->emitConstUint32(Value.getZExtValue(), E); 409 1.1 joerg case PT_Sint64: 410 1.1 joerg return this->emitConstSint64(Value.getSExtValue(), E); 411 1.1 joerg case PT_Uint64: 412 1.1 joerg return this->emitConstUint64(Value.getZExtValue(), E); 413 1.1 joerg case PT_Bool: 414 1.1 joerg return this->emitConstBool(Value.getBoolValue(), E); 415 1.1 joerg case PT_Ptr: 416 1.1 joerg llvm_unreachable("Invalid integral type"); 417 1.1 joerg break; 418 1.1 joerg } 419 1.1 joerg llvm_unreachable("unknown primitive type"); 420 1.1 joerg } 421 1.1 joerg 422 1.1 joerg template <class Emitter> 423 1.1 joerg unsigned ByteCodeExprGen<Emitter>::allocateLocalPrimitive(DeclTy &&Src, 424 1.1 joerg PrimType Ty, 425 1.1 joerg bool IsConst, 426 1.1 joerg bool IsExtended) { 427 1.1 joerg Descriptor *D = P.createDescriptor(Src, Ty, IsConst, Src.is<const Expr *>()); 428 1.1 joerg Scope::Local Local = this->createLocal(D); 429 1.1 joerg if (auto *VD = dyn_cast_or_null<ValueDecl>(Src.dyn_cast<const Decl *>())) 430 1.1 joerg Locals.insert({VD, Local}); 431 1.1 joerg VarScope->add(Local, IsExtended); 432 1.1 joerg return Local.Offset; 433 1.1 joerg } 434 1.1 joerg 435 1.1 joerg template <class Emitter> 436 1.1 joerg llvm::Optional<unsigned> 437 1.1 joerg ByteCodeExprGen<Emitter>::allocateLocal(DeclTy &&Src, bool IsExtended) { 438 1.1 joerg QualType Ty; 439 1.1 joerg 440 1.1 joerg const ValueDecl *Key = nullptr; 441 1.1 joerg bool IsTemporary = false; 442 1.1 joerg if (auto *VD = dyn_cast_or_null<ValueDecl>(Src.dyn_cast<const Decl *>())) { 443 1.1 joerg Key = VD; 444 1.1 joerg Ty = VD->getType(); 445 1.1 joerg } 446 1.1 joerg if (auto *E = Src.dyn_cast<const Expr *>()) { 447 1.1 joerg IsTemporary = true; 448 1.1 joerg Ty = E->getType(); 449 1.1 joerg } 450 1.1 joerg 451 1.1 joerg Descriptor *D = P.createDescriptor(Src, Ty.getTypePtr(), 452 1.1 joerg Ty.isConstQualified(), IsTemporary); 453 1.1 joerg if (!D) 454 1.1 joerg return {}; 455 1.1 joerg 456 1.1 joerg Scope::Local Local = this->createLocal(D); 457 1.1 joerg if (Key) 458 1.1 joerg Locals.insert({Key, Local}); 459 1.1 joerg VarScope->add(Local, IsExtended); 460 1.1 joerg return Local.Offset; 461 1.1 joerg } 462 1.1 joerg 463 1.1 joerg template <class Emitter> 464 1.1 joerg bool ByteCodeExprGen<Emitter>::visitInitializer( 465 1.1 joerg const Expr *Init, InitFnRef InitFn) { 466 1.1 joerg OptionScope<Emitter> Scope(this, InitFn); 467 1.1 joerg return this->Visit(Init); 468 1.1 joerg } 469 1.1 joerg 470 1.1 joerg template <class Emitter> 471 1.1 joerg bool ByteCodeExprGen<Emitter>::getPtrVarDecl(const VarDecl *VD, const Expr *E) { 472 1.1 joerg // Generate a pointer to the local, loading refs. 473 1.1 joerg if (Optional<unsigned> Idx = getGlobalIdx(VD)) { 474 1.1 joerg if (VD->getType()->isReferenceType()) 475 1.1 joerg return this->emitGetGlobalPtr(*Idx, E); 476 1.1 joerg else 477 1.1 joerg return this->emitGetPtrGlobal(*Idx, E); 478 1.1 joerg } 479 1.1 joerg return this->bail(VD); 480 1.1 joerg } 481 1.1 joerg 482 1.1 joerg template <class Emitter> 483 1.1 joerg llvm::Optional<unsigned> 484 1.1 joerg ByteCodeExprGen<Emitter>::getGlobalIdx(const VarDecl *VD) { 485 1.1 joerg if (VD->isConstexpr()) { 486 1.1 joerg // Constexpr decl - it must have already been defined. 487 1.1 joerg return P.getGlobal(VD); 488 1.1 joerg } 489 1.1 joerg if (!VD->hasLocalStorage()) { 490 1.1 joerg // Not constexpr, but a global var - can have pointer taken. 491 1.1 joerg Program::DeclScope Scope(P, VD); 492 1.1 joerg return P.getOrCreateGlobal(VD); 493 1.1 joerg } 494 1.1 joerg return {}; 495 1.1 joerg } 496 1.1 joerg 497 1.1 joerg template <class Emitter> 498 1.1 joerg const RecordType *ByteCodeExprGen<Emitter>::getRecordTy(QualType Ty) { 499 1.1 joerg if (auto *PT = dyn_cast<PointerType>(Ty)) 500 1.1 joerg return PT->getPointeeType()->getAs<RecordType>(); 501 1.1 joerg else 502 1.1 joerg return Ty->getAs<RecordType>(); 503 1.1 joerg } 504 1.1 joerg 505 1.1 joerg template <class Emitter> 506 1.1 joerg Record *ByteCodeExprGen<Emitter>::getRecord(QualType Ty) { 507 1.1 joerg if (auto *RecordTy = getRecordTy(Ty)) { 508 1.1 joerg return getRecord(RecordTy->getDecl()); 509 1.1 joerg } 510 1.1 joerg return nullptr; 511 1.1 joerg } 512 1.1 joerg 513 1.1 joerg template <class Emitter> 514 1.1 joerg Record *ByteCodeExprGen<Emitter>::getRecord(const RecordDecl *RD) { 515 1.1 joerg return P.getOrCreateRecord(RD); 516 1.1 joerg } 517 1.1 joerg 518 1.1 joerg template <class Emitter> 519 1.1 joerg bool ByteCodeExprGen<Emitter>::visitExpr(const Expr *Exp) { 520 1.1 joerg ExprScope<Emitter> RootScope(this); 521 1.1 joerg if (!visit(Exp)) 522 1.1 joerg return false; 523 1.1 joerg 524 1.1 joerg if (Optional<PrimType> T = classify(Exp)) 525 1.1 joerg return this->emitRet(*T, Exp); 526 1.1 joerg else 527 1.1 joerg return this->emitRetValue(Exp); 528 1.1 joerg } 529 1.1 joerg 530 1.1 joerg template <class Emitter> 531 1.1 joerg bool ByteCodeExprGen<Emitter>::visitDecl(const VarDecl *VD) { 532 1.1 joerg const Expr *Init = VD->getInit(); 533 1.1 joerg 534 1.1 joerg if (Optional<unsigned> I = P.createGlobal(VD)) { 535 1.1 joerg if (Optional<PrimType> T = classify(VD->getType())) { 536 1.1 joerg { 537 1.1 joerg // Primitive declarations - compute the value and set it. 538 1.1 joerg DeclScope<Emitter> LocalScope(this, VD); 539 1.1 joerg if (!visit(Init)) 540 1.1 joerg return false; 541 1.1 joerg } 542 1.1 joerg 543 1.1 joerg // If the declaration is global, save the value for later use. 544 1.1 joerg if (!this->emitDup(*T, VD)) 545 1.1 joerg return false; 546 1.1 joerg if (!this->emitInitGlobal(*T, *I, VD)) 547 1.1 joerg return false; 548 1.1 joerg return this->emitRet(*T, VD); 549 1.1 joerg } else { 550 1.1 joerg { 551 1.1 joerg // Composite declarations - allocate storage and initialize it. 552 1.1 joerg DeclScope<Emitter> LocalScope(this, VD); 553 1.1 joerg if (!visitGlobalInitializer(Init, *I)) 554 1.1 joerg return false; 555 1.1 joerg } 556 1.1 joerg 557 1.1 joerg // Return a pointer to the global. 558 1.1 joerg if (!this->emitGetPtrGlobal(*I, VD)) 559 1.1 joerg return false; 560 1.1 joerg return this->emitRetValue(VD); 561 1.1 joerg } 562 1.1 joerg } 563 1.1 joerg 564 1.1 joerg return this->bail(VD); 565 1.1 joerg } 566 1.1 joerg 567 1.1 joerg template <class Emitter> 568 1.1 joerg void ByteCodeExprGen<Emitter>::emitCleanup() { 569 1.1 joerg for (VariableScope<Emitter> *C = VarScope; C; C = C->getParent()) 570 1.1 joerg C->emitDestruction(); 571 1.1 joerg } 572 1.1 joerg 573 1.1 joerg namespace clang { 574 1.1 joerg namespace interp { 575 1.1 joerg 576 1.1 joerg template class ByteCodeExprGen<ByteCodeEmitter>; 577 1.1 joerg template class ByteCodeExprGen<EvalEmitter>; 578 1.1 joerg 579 1.1 joerg } // namespace interp 580 1.1 joerg } // namespace clang 581