1 1.1 joerg //===--- Context.cpp - Context for the constexpr VM -------------*- 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 "Context.h" 10 1.1 joerg #include "ByteCodeEmitter.h" 11 1.1 joerg #include "ByteCodeExprGen.h" 12 1.1 joerg #include "ByteCodeStmtGen.h" 13 1.1 joerg #include "EvalEmitter.h" 14 1.1 joerg #include "Interp.h" 15 1.1 joerg #include "InterpFrame.h" 16 1.1 joerg #include "InterpStack.h" 17 1.1 joerg #include "PrimType.h" 18 1.1 joerg #include "Program.h" 19 1.1 joerg #include "clang/AST/Expr.h" 20 1.1.1.2 joerg #include "clang/Basic/TargetInfo.h" 21 1.1 joerg 22 1.1 joerg using namespace clang; 23 1.1 joerg using namespace clang::interp; 24 1.1 joerg 25 1.1.1.2 joerg Context::Context(ASTContext &Ctx) : Ctx(Ctx), P(new Program(*this)) {} 26 1.1 joerg 27 1.1 joerg Context::~Context() {} 28 1.1 joerg 29 1.1.1.2 joerg bool Context::isPotentialConstantExpr(State &Parent, const FunctionDecl *FD) { 30 1.1 joerg Function *Func = P->getFunction(FD); 31 1.1 joerg if (!Func) { 32 1.1 joerg if (auto R = ByteCodeStmtGen<ByteCodeEmitter>(*this, *P).compileFunc(FD)) { 33 1.1 joerg Func = *R; 34 1.1.1.2 joerg } else { 35 1.1 joerg handleAllErrors(R.takeError(), [&Parent](ByteCodeGenError &Err) { 36 1.1 joerg Parent.FFDiag(Err.getLoc(), diag::err_experimental_clang_interp_failed); 37 1.1 joerg }); 38 1.1.1.2 joerg return false; 39 1.1 joerg } 40 1.1 joerg } 41 1.1 joerg 42 1.1 joerg if (!Func->isConstexpr()) 43 1.1.1.2 joerg return false; 44 1.1 joerg 45 1.1 joerg APValue Dummy; 46 1.1 joerg return Run(Parent, Func, Dummy); 47 1.1 joerg } 48 1.1 joerg 49 1.1.1.2 joerg bool Context::evaluateAsRValue(State &Parent, const Expr *E, APValue &Result) { 50 1.1 joerg ByteCodeExprGen<EvalEmitter> C(*this, *P, Parent, Stk, Result); 51 1.1 joerg return Check(Parent, C.interpretExpr(E)); 52 1.1 joerg } 53 1.1 joerg 54 1.1.1.2 joerg bool Context::evaluateAsInitializer(State &Parent, const VarDecl *VD, 55 1.1.1.2 joerg APValue &Result) { 56 1.1 joerg ByteCodeExprGen<EvalEmitter> C(*this, *P, Parent, Stk, Result); 57 1.1 joerg return Check(Parent, C.interpretDecl(VD)); 58 1.1 joerg } 59 1.1 joerg 60 1.1 joerg const LangOptions &Context::getLangOpts() const { return Ctx.getLangOpts(); } 61 1.1 joerg 62 1.1 joerg llvm::Optional<PrimType> Context::classify(QualType T) { 63 1.1 joerg if (T->isReferenceType() || T->isPointerType()) { 64 1.1 joerg return PT_Ptr; 65 1.1 joerg } 66 1.1 joerg 67 1.1 joerg if (T->isBooleanType()) 68 1.1 joerg return PT_Bool; 69 1.1 joerg 70 1.1 joerg if (T->isSignedIntegerOrEnumerationType()) { 71 1.1 joerg switch (Ctx.getIntWidth(T)) { 72 1.1 joerg case 64: 73 1.1 joerg return PT_Sint64; 74 1.1 joerg case 32: 75 1.1 joerg return PT_Sint32; 76 1.1 joerg case 16: 77 1.1 joerg return PT_Sint16; 78 1.1 joerg case 8: 79 1.1 joerg return PT_Sint8; 80 1.1 joerg default: 81 1.1 joerg return {}; 82 1.1 joerg } 83 1.1 joerg } 84 1.1 joerg 85 1.1 joerg if (T->isUnsignedIntegerOrEnumerationType()) { 86 1.1 joerg switch (Ctx.getIntWidth(T)) { 87 1.1 joerg case 64: 88 1.1 joerg return PT_Uint64; 89 1.1 joerg case 32: 90 1.1 joerg return PT_Uint32; 91 1.1 joerg case 16: 92 1.1 joerg return PT_Uint16; 93 1.1 joerg case 8: 94 1.1 joerg return PT_Uint8; 95 1.1 joerg default: 96 1.1 joerg return {}; 97 1.1 joerg } 98 1.1 joerg } 99 1.1 joerg 100 1.1 joerg if (T->isNullPtrType()) 101 1.1 joerg return PT_Ptr; 102 1.1 joerg 103 1.1 joerg if (auto *AT = dyn_cast<AtomicType>(T)) 104 1.1 joerg return classify(AT->getValueType()); 105 1.1 joerg 106 1.1 joerg return {}; 107 1.1 joerg } 108 1.1 joerg 109 1.1 joerg unsigned Context::getCharBit() const { 110 1.1 joerg return Ctx.getTargetInfo().getCharWidth(); 111 1.1 joerg } 112 1.1 joerg 113 1.1.1.2 joerg bool Context::Run(State &Parent, Function *Func, APValue &Result) { 114 1.1.1.2 joerg InterpState State(Parent, *P, Stk, *this); 115 1.1.1.2 joerg State.Current = new InterpFrame(State, Func, nullptr, {}, {}); 116 1.1.1.2 joerg if (Interpret(State, Result)) 117 1.1.1.2 joerg return true; 118 1.1.1.2 joerg Stk.clear(); 119 1.1.1.2 joerg return false; 120 1.1.1.2 joerg } 121 1.1.1.2 joerg 122 1.1.1.2 joerg bool Context::Check(State &Parent, llvm::Expected<bool> &&Flag) { 123 1.1.1.2 joerg if (Flag) 124 1.1.1.2 joerg return *Flag; 125 1.1.1.2 joerg handleAllErrors(Flag.takeError(), [&Parent](ByteCodeGenError &Err) { 126 1.1.1.2 joerg Parent.FFDiag(Err.getLoc(), diag::err_experimental_clang_interp_failed); 127 1.1.1.2 joerg }); 128 1.1.1.2 joerg return false; 129 1.1 joerg } 130