1a7dea167SDimitry Andric //===--- Context.cpp - Context for the constexpr VM -------------*- C++ -*-===// 2a7dea167SDimitry Andric // 3a7dea167SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4a7dea167SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5a7dea167SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6a7dea167SDimitry Andric // 7a7dea167SDimitry Andric //===----------------------------------------------------------------------===// 8a7dea167SDimitry Andric 9a7dea167SDimitry Andric #include "Context.h" 10a7dea167SDimitry Andric #include "ByteCodeEmitter.h" 11a7dea167SDimitry Andric #include "ByteCodeExprGen.h" 125f757f3fSDimitry Andric #include "ByteCodeGenError.h" 13a7dea167SDimitry Andric #include "ByteCodeStmtGen.h" 14a7dea167SDimitry Andric #include "EvalEmitter.h" 15a7dea167SDimitry Andric #include "Interp.h" 16a7dea167SDimitry Andric #include "InterpFrame.h" 17a7dea167SDimitry Andric #include "InterpStack.h" 18a7dea167SDimitry Andric #include "PrimType.h" 19a7dea167SDimitry Andric #include "Program.h" 20a7dea167SDimitry Andric #include "clang/AST/Expr.h" 215ffd83dbSDimitry Andric #include "clang/Basic/TargetInfo.h" 22a7dea167SDimitry Andric 23a7dea167SDimitry Andric using namespace clang; 24a7dea167SDimitry Andric using namespace clang::interp; 25a7dea167SDimitry Andric 26480093f4SDimitry Andric Context::Context(ASTContext &Ctx) : Ctx(Ctx), P(new Program(*this)) {} 27a7dea167SDimitry Andric 28a7dea167SDimitry Andric Context::~Context() {} 29a7dea167SDimitry Andric 30480093f4SDimitry Andric bool Context::isPotentialConstantExpr(State &Parent, const FunctionDecl *FD) { 31bdd1243dSDimitry Andric assert(Stk.empty()); 32a7dea167SDimitry Andric Function *Func = P->getFunction(FD); 33*7a6dacacSDimitry Andric if (!Func || !Func->hasBody()) 34*7a6dacacSDimitry Andric Func = ByteCodeStmtGen<ByteCodeEmitter>(*this, *P).compileFunc(FD); 35a7dea167SDimitry Andric 3606c3fb27SDimitry Andric APValue DummyResult; 3706c3fb27SDimitry Andric if (!Run(Parent, Func, DummyResult)) { 3806c3fb27SDimitry Andric return false; 3906c3fb27SDimitry Andric } 4006c3fb27SDimitry Andric 41bdd1243dSDimitry Andric return Func->isConstexpr(); 42a7dea167SDimitry Andric } 43a7dea167SDimitry Andric 44480093f4SDimitry Andric bool Context::evaluateAsRValue(State &Parent, const Expr *E, APValue &Result) { 45bdd1243dSDimitry Andric assert(Stk.empty()); 46a7dea167SDimitry Andric ByteCodeExprGen<EvalEmitter> C(*this, *P, Parent, Stk, Result); 47*7a6dacacSDimitry Andric 48*7a6dacacSDimitry Andric auto Res = C.interpretExpr(E); 49*7a6dacacSDimitry Andric 50*7a6dacacSDimitry Andric if (Res.isInvalid()) { 51*7a6dacacSDimitry Andric Stk.clear(); 52*7a6dacacSDimitry Andric return false; 53*7a6dacacSDimitry Andric } 54*7a6dacacSDimitry Andric 55bdd1243dSDimitry Andric assert(Stk.empty()); 5606c3fb27SDimitry Andric #ifndef NDEBUG 5706c3fb27SDimitry Andric // Make sure we don't rely on some value being still alive in 5806c3fb27SDimitry Andric // InterpStack memory. 5906c3fb27SDimitry Andric Stk.clear(); 6006c3fb27SDimitry Andric #endif 61*7a6dacacSDimitry Andric 62*7a6dacacSDimitry Andric // Implicit lvalue-to-rvalue conversion. 63*7a6dacacSDimitry Andric if (E->isGLValue()) { 64*7a6dacacSDimitry Andric std::optional<APValue> RValueResult = Res.toRValue(); 65*7a6dacacSDimitry Andric if (!RValueResult) { 66*7a6dacacSDimitry Andric return false; 67*7a6dacacSDimitry Andric } 68*7a6dacacSDimitry Andric Result = *RValueResult; 69*7a6dacacSDimitry Andric } else { 70*7a6dacacSDimitry Andric Result = Res.toAPValue(); 71*7a6dacacSDimitry Andric } 72*7a6dacacSDimitry Andric 73bdd1243dSDimitry Andric return true; 74bdd1243dSDimitry Andric } 75bdd1243dSDimitry Andric 76*7a6dacacSDimitry Andric bool Context::evaluate(State &Parent, const Expr *E, APValue &Result) { 77*7a6dacacSDimitry Andric assert(Stk.empty()); 78*7a6dacacSDimitry Andric ByteCodeExprGen<EvalEmitter> C(*this, *P, Parent, Stk, Result); 79*7a6dacacSDimitry Andric 80*7a6dacacSDimitry Andric auto Res = C.interpretExpr(E); 81*7a6dacacSDimitry Andric if (Res.isInvalid()) { 82bdd1243dSDimitry Andric Stk.clear(); 83bdd1243dSDimitry Andric return false; 84a7dea167SDimitry Andric } 85a7dea167SDimitry Andric 86*7a6dacacSDimitry Andric assert(Stk.empty()); 87*7a6dacacSDimitry Andric #ifndef NDEBUG 88*7a6dacacSDimitry Andric // Make sure we don't rely on some value being still alive in 89*7a6dacacSDimitry Andric // InterpStack memory. 90*7a6dacacSDimitry Andric Stk.clear(); 91*7a6dacacSDimitry Andric #endif 92*7a6dacacSDimitry Andric Result = Res.toAPValue(); 93*7a6dacacSDimitry Andric return true; 94*7a6dacacSDimitry Andric } 95*7a6dacacSDimitry Andric 96480093f4SDimitry Andric bool Context::evaluateAsInitializer(State &Parent, const VarDecl *VD, 97a7dea167SDimitry Andric APValue &Result) { 98bdd1243dSDimitry Andric assert(Stk.empty()); 99a7dea167SDimitry Andric ByteCodeExprGen<EvalEmitter> C(*this, *P, Parent, Stk, Result); 100*7a6dacacSDimitry Andric 101*7a6dacacSDimitry Andric auto Res = C.interpretDecl(VD); 102*7a6dacacSDimitry Andric if (Res.isInvalid()) { 103*7a6dacacSDimitry Andric Stk.clear(); 104*7a6dacacSDimitry Andric return false; 105*7a6dacacSDimitry Andric } 106*7a6dacacSDimitry Andric 107bdd1243dSDimitry Andric assert(Stk.empty()); 10806c3fb27SDimitry Andric #ifndef NDEBUG 10906c3fb27SDimitry Andric // Make sure we don't rely on some value being still alive in 11006c3fb27SDimitry Andric // InterpStack memory. 11106c3fb27SDimitry Andric Stk.clear(); 11206c3fb27SDimitry Andric #endif 113bdd1243dSDimitry Andric 114*7a6dacacSDimitry Andric // Ensure global variables are fully initialized. 115*7a6dacacSDimitry Andric if (shouldBeGloballyIndexed(VD) && !Res.isInvalid() && 116*7a6dacacSDimitry Andric (VD->getType()->isRecordType() || VD->getType()->isArrayType())) { 117*7a6dacacSDimitry Andric assert(Res.isLValue()); 118*7a6dacacSDimitry Andric 119*7a6dacacSDimitry Andric if (!Res.checkFullyInitialized(C.getState())) 120bdd1243dSDimitry Andric return false; 121*7a6dacacSDimitry Andric 122*7a6dacacSDimitry Andric // lvalue-to-rvalue conversion. 123*7a6dacacSDimitry Andric std::optional<APValue> RValueResult = Res.toRValue(); 124*7a6dacacSDimitry Andric if (!RValueResult) 125*7a6dacacSDimitry Andric return false; 126*7a6dacacSDimitry Andric Result = *RValueResult; 127*7a6dacacSDimitry Andric 128*7a6dacacSDimitry Andric } else 129*7a6dacacSDimitry Andric Result = Res.toAPValue(); 130*7a6dacacSDimitry Andric return true; 131a7dea167SDimitry Andric } 132a7dea167SDimitry Andric 133a7dea167SDimitry Andric const LangOptions &Context::getLangOpts() const { return Ctx.getLangOpts(); } 134a7dea167SDimitry Andric 135bdd1243dSDimitry Andric std::optional<PrimType> Context::classify(QualType T) const { 136a7dea167SDimitry Andric if (T->isBooleanType()) 137a7dea167SDimitry Andric return PT_Bool; 138a7dea167SDimitry Andric 1395f757f3fSDimitry Andric if (T->isAnyComplexType()) 1405f757f3fSDimitry Andric return std::nullopt; 1415f757f3fSDimitry Andric 142a7dea167SDimitry Andric if (T->isSignedIntegerOrEnumerationType()) { 143a7dea167SDimitry Andric switch (Ctx.getIntWidth(T)) { 144a7dea167SDimitry Andric case 64: 145a7dea167SDimitry Andric return PT_Sint64; 146a7dea167SDimitry Andric case 32: 147a7dea167SDimitry Andric return PT_Sint32; 148a7dea167SDimitry Andric case 16: 149a7dea167SDimitry Andric return PT_Sint16; 150a7dea167SDimitry Andric case 8: 151a7dea167SDimitry Andric return PT_Sint8; 152a7dea167SDimitry Andric default: 1535f757f3fSDimitry Andric return PT_IntAPS; 154a7dea167SDimitry Andric } 155a7dea167SDimitry Andric } 156a7dea167SDimitry Andric 157a7dea167SDimitry Andric if (T->isUnsignedIntegerOrEnumerationType()) { 158a7dea167SDimitry Andric switch (Ctx.getIntWidth(T)) { 159a7dea167SDimitry Andric case 64: 160a7dea167SDimitry Andric return PT_Uint64; 161a7dea167SDimitry Andric case 32: 162a7dea167SDimitry Andric return PT_Uint32; 163a7dea167SDimitry Andric case 16: 164a7dea167SDimitry Andric return PT_Uint16; 165a7dea167SDimitry Andric case 8: 166a7dea167SDimitry Andric return PT_Uint8; 167a7dea167SDimitry Andric default: 1685f757f3fSDimitry Andric return PT_IntAP; 169a7dea167SDimitry Andric } 170a7dea167SDimitry Andric } 171a7dea167SDimitry Andric 172a7dea167SDimitry Andric if (T->isNullPtrType()) 173a7dea167SDimitry Andric return PT_Ptr; 174a7dea167SDimitry Andric 17506c3fb27SDimitry Andric if (T->isFloatingType()) 17606c3fb27SDimitry Andric return PT_Float; 17706c3fb27SDimitry Andric 1785f757f3fSDimitry Andric if (T->isFunctionPointerType() || T->isFunctionReferenceType() || 1795f757f3fSDimitry Andric T->isFunctionType() || T->isSpecificBuiltinType(BuiltinType::BoundMember)) 1805f757f3fSDimitry Andric return PT_FnPtr; 1815f757f3fSDimitry Andric 1825f757f3fSDimitry Andric if (T->isReferenceType() || T->isPointerType()) 1835f757f3fSDimitry Andric return PT_Ptr; 1845f757f3fSDimitry Andric 1855f757f3fSDimitry Andric if (const auto *AT = dyn_cast<AtomicType>(T)) 186a7dea167SDimitry Andric return classify(AT->getValueType()); 187a7dea167SDimitry Andric 1885f757f3fSDimitry Andric if (const auto *DT = dyn_cast<DecltypeType>(T)) 1895f757f3fSDimitry Andric return classify(DT->getUnderlyingType()); 1905f757f3fSDimitry Andric 1915f757f3fSDimitry Andric if (const auto *DT = dyn_cast<MemberPointerType>(T)) 1925f757f3fSDimitry Andric return classify(DT->getPointeeType()); 1935f757f3fSDimitry Andric 1945f757f3fSDimitry Andric return std::nullopt; 195a7dea167SDimitry Andric } 196a7dea167SDimitry Andric 197a7dea167SDimitry Andric unsigned Context::getCharBit() const { 198a7dea167SDimitry Andric return Ctx.getTargetInfo().getCharWidth(); 199a7dea167SDimitry Andric } 200a7dea167SDimitry Andric 20106c3fb27SDimitry Andric /// Simple wrapper around getFloatTypeSemantics() to make code a 20206c3fb27SDimitry Andric /// little shorter. 20306c3fb27SDimitry Andric const llvm::fltSemantics &Context::getFloatSemantics(QualType T) const { 20406c3fb27SDimitry Andric return Ctx.getFloatTypeSemantics(T); 20506c3fb27SDimitry Andric } 20606c3fb27SDimitry Andric 20706c3fb27SDimitry Andric bool Context::Run(State &Parent, const Function *Func, APValue &Result) { 2085f757f3fSDimitry Andric 2095f757f3fSDimitry Andric { 210a7dea167SDimitry Andric InterpState State(Parent, *P, Stk, *this); 211bdd1243dSDimitry Andric State.Current = new InterpFrame(State, Func, /*Caller=*/nullptr, {}); 2125f757f3fSDimitry Andric if (Interpret(State, Result)) { 2135f757f3fSDimitry Andric assert(Stk.empty()); 214480093f4SDimitry Andric return true; 2155f757f3fSDimitry Andric } 2165f757f3fSDimitry Andric 2175f757f3fSDimitry Andric // State gets destroyed here, so the Stk.clear() below doesn't accidentally 2185f757f3fSDimitry Andric // remove values the State's destructor might access. 2195f757f3fSDimitry Andric } 2205f757f3fSDimitry Andric 221a7dea167SDimitry Andric Stk.clear(); 222480093f4SDimitry Andric return false; 223a7dea167SDimitry Andric } 224a7dea167SDimitry Andric 225480093f4SDimitry Andric bool Context::Check(State &Parent, llvm::Expected<bool> &&Flag) { 226480093f4SDimitry Andric if (Flag) 227480093f4SDimitry Andric return *Flag; 228480093f4SDimitry Andric handleAllErrors(Flag.takeError(), [&Parent](ByteCodeGenError &Err) { 229bdd1243dSDimitry Andric Parent.FFDiag(Err.getRange().getBegin(), 230bdd1243dSDimitry Andric diag::err_experimental_clang_interp_failed) 231bdd1243dSDimitry Andric << Err.getRange(); 232a7dea167SDimitry Andric }); 233480093f4SDimitry Andric return false; 234a7dea167SDimitry Andric } 23506c3fb27SDimitry Andric 23606c3fb27SDimitry Andric // TODO: Virtual bases? 23706c3fb27SDimitry Andric const CXXMethodDecl * 23806c3fb27SDimitry Andric Context::getOverridingFunction(const CXXRecordDecl *DynamicDecl, 23906c3fb27SDimitry Andric const CXXRecordDecl *StaticDecl, 24006c3fb27SDimitry Andric const CXXMethodDecl *InitialFunction) const { 24106c3fb27SDimitry Andric 24206c3fb27SDimitry Andric const CXXRecordDecl *CurRecord = DynamicDecl; 24306c3fb27SDimitry Andric const CXXMethodDecl *FoundFunction = InitialFunction; 24406c3fb27SDimitry Andric for (;;) { 24506c3fb27SDimitry Andric const CXXMethodDecl *Overrider = 24606c3fb27SDimitry Andric FoundFunction->getCorrespondingMethodDeclaredInClass(CurRecord, false); 24706c3fb27SDimitry Andric if (Overrider) 24806c3fb27SDimitry Andric return Overrider; 24906c3fb27SDimitry Andric 25006c3fb27SDimitry Andric // Common case of only one base class. 25106c3fb27SDimitry Andric if (CurRecord->getNumBases() == 1) { 25206c3fb27SDimitry Andric CurRecord = CurRecord->bases_begin()->getType()->getAsCXXRecordDecl(); 25306c3fb27SDimitry Andric continue; 25406c3fb27SDimitry Andric } 25506c3fb27SDimitry Andric 25606c3fb27SDimitry Andric // Otherwise, go to the base class that will lead to the StaticDecl. 25706c3fb27SDimitry Andric for (const CXXBaseSpecifier &Spec : CurRecord->bases()) { 25806c3fb27SDimitry Andric const CXXRecordDecl *Base = Spec.getType()->getAsCXXRecordDecl(); 25906c3fb27SDimitry Andric if (Base == StaticDecl || Base->isDerivedFrom(StaticDecl)) { 26006c3fb27SDimitry Andric CurRecord = Base; 26106c3fb27SDimitry Andric break; 26206c3fb27SDimitry Andric } 26306c3fb27SDimitry Andric } 26406c3fb27SDimitry Andric } 26506c3fb27SDimitry Andric 26606c3fb27SDimitry Andric llvm_unreachable( 26706c3fb27SDimitry Andric "Couldn't find an overriding function in the class hierarchy?"); 26806c3fb27SDimitry Andric return nullptr; 26906c3fb27SDimitry Andric } 2705f757f3fSDimitry Andric 2715f757f3fSDimitry Andric const Function *Context::getOrCreateFunction(const FunctionDecl *FD) { 2725f757f3fSDimitry Andric assert(FD); 2735f757f3fSDimitry Andric const Function *Func = P->getFunction(FD); 2745f757f3fSDimitry Andric bool IsBeingCompiled = Func && Func->isDefined() && !Func->isFullyCompiled(); 2755f757f3fSDimitry Andric bool WasNotDefined = Func && !Func->isConstexpr() && !Func->isDefined(); 2765f757f3fSDimitry Andric 2775f757f3fSDimitry Andric if (IsBeingCompiled) 2785f757f3fSDimitry Andric return Func; 2795f757f3fSDimitry Andric 2805f757f3fSDimitry Andric if (!Func || WasNotDefined) { 281*7a6dacacSDimitry Andric if (auto F = ByteCodeStmtGen<ByteCodeEmitter>(*this, *P).compileFunc(FD)) 282*7a6dacacSDimitry Andric Func = F; 2835f757f3fSDimitry Andric } 2845f757f3fSDimitry Andric 2855f757f3fSDimitry Andric return Func; 2865f757f3fSDimitry Andric } 287