diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-04-14 21:41:27 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-06-22 18:20:56 +0000 |
commit | bdd1243df58e60e85101c09001d9812a789b6bc4 (patch) | |
tree | a1ce621c7301dd47ba2ddc3b8eaa63b441389481 /contrib/llvm-project/clang/lib/AST/Interp/Context.cpp | |
parent | 781624ca2d054430052c828ba8d2c2eaf2d733e7 (diff) | |
parent | e3b557809604d036af6e00c60f012c2025b59a5e (diff) |
Diffstat (limited to 'contrib/llvm-project/clang/lib/AST/Interp/Context.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/AST/Interp/Context.cpp | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/contrib/llvm-project/clang/lib/AST/Interp/Context.cpp b/contrib/llvm-project/clang/lib/AST/Interp/Context.cpp index 3bfcdfcd4c58..16471242f328 100644 --- a/contrib/llvm-project/clang/lib/AST/Interp/Context.cpp +++ b/contrib/llvm-project/clang/lib/AST/Interp/Context.cpp @@ -27,39 +27,52 @@ Context::Context(ASTContext &Ctx) : Ctx(Ctx), P(new Program(*this)) {} Context::~Context() {} bool Context::isPotentialConstantExpr(State &Parent, const FunctionDecl *FD) { + assert(Stk.empty()); Function *Func = P->getFunction(FD); - if (!Func) { + if (!Func || !Func->hasBody()) { if (auto R = ByteCodeStmtGen<ByteCodeEmitter>(*this, *P).compileFunc(FD)) { Func = *R; } else { handleAllErrors(R.takeError(), [&Parent](ByteCodeGenError &Err) { - Parent.FFDiag(Err.getLoc(), diag::err_experimental_clang_interp_failed); + Parent.FFDiag(Err.getRange().getBegin(), + diag::err_experimental_clang_interp_failed) + << Err.getRange(); }); return false; } } - if (!Func->isConstexpr()) - return false; - - APValue Dummy; - return Run(Parent, Func, Dummy); + return Func->isConstexpr(); } bool Context::evaluateAsRValue(State &Parent, const Expr *E, APValue &Result) { + assert(Stk.empty()); ByteCodeExprGen<EvalEmitter> C(*this, *P, Parent, Stk, Result); - return Check(Parent, C.interpretExpr(E)); + if (Check(Parent, C.interpretExpr(E))) { + assert(Stk.empty()); + return true; + } + + Stk.clear(); + return false; } bool Context::evaluateAsInitializer(State &Parent, const VarDecl *VD, APValue &Result) { + assert(Stk.empty()); ByteCodeExprGen<EvalEmitter> C(*this, *P, Parent, Stk, Result); - return Check(Parent, C.interpretDecl(VD)); + if (Check(Parent, C.interpretDecl(VD))) { + assert(Stk.empty()); + return true; + } + + Stk.clear(); + return false; } const LangOptions &Context::getLangOpts() const { return Ctx.getLangOpts(); } -llvm::Optional<PrimType> Context::classify(QualType T) { +std::optional<PrimType> Context::classify(QualType T) const { if (T->isReferenceType() || T->isPointerType()) { return PT_Ptr; } @@ -112,7 +125,7 @@ unsigned Context::getCharBit() const { bool Context::Run(State &Parent, Function *Func, APValue &Result) { InterpState State(Parent, *P, Stk, *this); - State.Current = new InterpFrame(State, Func, nullptr, {}, {}); + State.Current = new InterpFrame(State, Func, /*Caller=*/nullptr, {}); if (Interpret(State, Result)) return true; Stk.clear(); @@ -123,7 +136,9 @@ bool Context::Check(State &Parent, llvm::Expected<bool> &&Flag) { if (Flag) return *Flag; handleAllErrors(Flag.takeError(), [&Parent](ByteCodeGenError &Err) { - Parent.FFDiag(Err.getLoc(), diag::err_experimental_clang_interp_failed); + Parent.FFDiag(Err.getRange().getBegin(), + diag::err_experimental_clang_interp_failed) + << Err.getRange(); }); return false; } |