1 //===--- Context.cpp - Context for the constexpr VM -------------*- 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 "Context.h" 10 #include "ByteCodeEmitter.h" 11 #include "ByteCodeExprGen.h" 12 #include "ByteCodeGenError.h" 13 #include "ByteCodeStmtGen.h" 14 #include "EvalEmitter.h" 15 #include "Interp.h" 16 #include "InterpFrame.h" 17 #include "InterpStack.h" 18 #include "PrimType.h" 19 #include "Program.h" 20 #include "clang/AST/Expr.h" 21 #include "clang/Basic/TargetInfo.h" 22 23 using namespace clang; 24 using namespace clang::interp; 25 26 Context::Context(ASTContext &Ctx) : Ctx(Ctx), P(new Program(*this)) {} 27 28 Context::~Context() {} 29 30 bool Context::isPotentialConstantExpr(State &Parent, const FunctionDecl *FD) { 31 assert(Stk.empty()); 32 Function *Func = P->getFunction(FD); 33 if (!Func || !Func->hasBody()) 34 Func = ByteCodeStmtGen<ByteCodeEmitter>(*this, *P).compileFunc(FD); 35 36 APValue DummyResult; 37 if (!Run(Parent, Func, DummyResult)) { 38 return false; 39 } 40 41 return Func->isConstexpr(); 42 } 43 44 bool Context::evaluateAsRValue(State &Parent, const Expr *E, APValue &Result) { 45 assert(Stk.empty()); 46 ByteCodeExprGen<EvalEmitter> C(*this, *P, Parent, Stk, Result); 47 48 auto Res = C.interpretExpr(E); 49 50 if (Res.isInvalid()) { 51 Stk.clear(); 52 return false; 53 } 54 55 assert(Stk.empty()); 56 #ifndef NDEBUG 57 // Make sure we don't rely on some value being still alive in 58 // InterpStack memory. 59 Stk.clear(); 60 #endif 61 62 // Implicit lvalue-to-rvalue conversion. 63 if (E->isGLValue()) { 64 std::optional<APValue> RValueResult = Res.toRValue(); 65 if (!RValueResult) { 66 return false; 67 } 68 Result = *RValueResult; 69 } else { 70 Result = Res.toAPValue(); 71 } 72 73 return true; 74 } 75 76 bool Context::evaluate(State &Parent, const Expr *E, APValue &Result) { 77 assert(Stk.empty()); 78 ByteCodeExprGen<EvalEmitter> C(*this, *P, Parent, Stk, Result); 79 80 auto Res = C.interpretExpr(E); 81 if (Res.isInvalid()) { 82 Stk.clear(); 83 return false; 84 } 85 86 assert(Stk.empty()); 87 #ifndef NDEBUG 88 // Make sure we don't rely on some value being still alive in 89 // InterpStack memory. 90 Stk.clear(); 91 #endif 92 Result = Res.toAPValue(); 93 return true; 94 } 95 96 bool Context::evaluateAsInitializer(State &Parent, const VarDecl *VD, 97 APValue &Result) { 98 assert(Stk.empty()); 99 ByteCodeExprGen<EvalEmitter> C(*this, *P, Parent, Stk, Result); 100 101 auto Res = C.interpretDecl(VD); 102 if (Res.isInvalid()) { 103 Stk.clear(); 104 return false; 105 } 106 107 assert(Stk.empty()); 108 #ifndef NDEBUG 109 // Make sure we don't rely on some value being still alive in 110 // InterpStack memory. 111 Stk.clear(); 112 #endif 113 114 // Ensure global variables are fully initialized. 115 if (shouldBeGloballyIndexed(VD) && !Res.isInvalid() && 116 (VD->getType()->isRecordType() || VD->getType()->isArrayType())) { 117 assert(Res.isLValue()); 118 119 if (!Res.checkFullyInitialized(C.getState())) 120 return false; 121 122 // lvalue-to-rvalue conversion. 123 std::optional<APValue> RValueResult = Res.toRValue(); 124 if (!RValueResult) 125 return false; 126 Result = *RValueResult; 127 128 } else 129 Result = Res.toAPValue(); 130 return true; 131 } 132 133 const LangOptions &Context::getLangOpts() const { return Ctx.getLangOpts(); } 134 135 std::optional<PrimType> Context::classify(QualType T) const { 136 if (T->isBooleanType()) 137 return PT_Bool; 138 139 if (T->isAnyComplexType()) 140 return std::nullopt; 141 142 if (T->isSignedIntegerOrEnumerationType()) { 143 switch (Ctx.getIntWidth(T)) { 144 case 64: 145 return PT_Sint64; 146 case 32: 147 return PT_Sint32; 148 case 16: 149 return PT_Sint16; 150 case 8: 151 return PT_Sint8; 152 default: 153 return PT_IntAPS; 154 } 155 } 156 157 if (T->isUnsignedIntegerOrEnumerationType()) { 158 switch (Ctx.getIntWidth(T)) { 159 case 64: 160 return PT_Uint64; 161 case 32: 162 return PT_Uint32; 163 case 16: 164 return PT_Uint16; 165 case 8: 166 return PT_Uint8; 167 default: 168 return PT_IntAP; 169 } 170 } 171 172 if (T->isNullPtrType()) 173 return PT_Ptr; 174 175 if (T->isFloatingType()) 176 return PT_Float; 177 178 if (T->isFunctionPointerType() || T->isFunctionReferenceType() || 179 T->isFunctionType() || T->isSpecificBuiltinType(BuiltinType::BoundMember)) 180 return PT_FnPtr; 181 182 if (T->isReferenceType() || T->isPointerType()) 183 return PT_Ptr; 184 185 if (const auto *AT = dyn_cast<AtomicType>(T)) 186 return classify(AT->getValueType()); 187 188 if (const auto *DT = dyn_cast<DecltypeType>(T)) 189 return classify(DT->getUnderlyingType()); 190 191 if (const auto *DT = dyn_cast<MemberPointerType>(T)) 192 return classify(DT->getPointeeType()); 193 194 return std::nullopt; 195 } 196 197 unsigned Context::getCharBit() const { 198 return Ctx.getTargetInfo().getCharWidth(); 199 } 200 201 /// Simple wrapper around getFloatTypeSemantics() to make code a 202 /// little shorter. 203 const llvm::fltSemantics &Context::getFloatSemantics(QualType T) const { 204 return Ctx.getFloatTypeSemantics(T); 205 } 206 207 bool Context::Run(State &Parent, const Function *Func, APValue &Result) { 208 209 { 210 InterpState State(Parent, *P, Stk, *this); 211 State.Current = new InterpFrame(State, Func, /*Caller=*/nullptr, {}); 212 if (Interpret(State, Result)) { 213 assert(Stk.empty()); 214 return true; 215 } 216 217 // State gets destroyed here, so the Stk.clear() below doesn't accidentally 218 // remove values the State's destructor might access. 219 } 220 221 Stk.clear(); 222 return false; 223 } 224 225 bool Context::Check(State &Parent, llvm::Expected<bool> &&Flag) { 226 if (Flag) 227 return *Flag; 228 handleAllErrors(Flag.takeError(), [&Parent](ByteCodeGenError &Err) { 229 Parent.FFDiag(Err.getRange().getBegin(), 230 diag::err_experimental_clang_interp_failed) 231 << Err.getRange(); 232 }); 233 return false; 234 } 235 236 // TODO: Virtual bases? 237 const CXXMethodDecl * 238 Context::getOverridingFunction(const CXXRecordDecl *DynamicDecl, 239 const CXXRecordDecl *StaticDecl, 240 const CXXMethodDecl *InitialFunction) const { 241 242 const CXXRecordDecl *CurRecord = DynamicDecl; 243 const CXXMethodDecl *FoundFunction = InitialFunction; 244 for (;;) { 245 const CXXMethodDecl *Overrider = 246 FoundFunction->getCorrespondingMethodDeclaredInClass(CurRecord, false); 247 if (Overrider) 248 return Overrider; 249 250 // Common case of only one base class. 251 if (CurRecord->getNumBases() == 1) { 252 CurRecord = CurRecord->bases_begin()->getType()->getAsCXXRecordDecl(); 253 continue; 254 } 255 256 // Otherwise, go to the base class that will lead to the StaticDecl. 257 for (const CXXBaseSpecifier &Spec : CurRecord->bases()) { 258 const CXXRecordDecl *Base = Spec.getType()->getAsCXXRecordDecl(); 259 if (Base == StaticDecl || Base->isDerivedFrom(StaticDecl)) { 260 CurRecord = Base; 261 break; 262 } 263 } 264 } 265 266 llvm_unreachable( 267 "Couldn't find an overriding function in the class hierarchy?"); 268 return nullptr; 269 } 270 271 const Function *Context::getOrCreateFunction(const FunctionDecl *FD) { 272 assert(FD); 273 const Function *Func = P->getFunction(FD); 274 bool IsBeingCompiled = Func && Func->isDefined() && !Func->isFullyCompiled(); 275 bool WasNotDefined = Func && !Func->isConstexpr() && !Func->isDefined(); 276 277 if (IsBeingCompiled) 278 return Func; 279 280 if (!Func || WasNotDefined) { 281 if (auto F = ByteCodeStmtGen<ByteCodeEmitter>(*this, *P).compileFunc(FD)) 282 Func = F; 283 } 284 285 return Func; 286 } 287