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