xref: /freebsd-src/contrib/llvm-project/clang/lib/AST/Interp/Context.h (revision a7dea1671b87c07d2d266f836bfa8b58efc7c134)
1*a7dea167SDimitry Andric //===--- Context.h - Context for the constexpr VM ---------------*- C++ -*-===//
2*a7dea167SDimitry Andric //
3*a7dea167SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*a7dea167SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*a7dea167SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*a7dea167SDimitry Andric //
7*a7dea167SDimitry Andric //===----------------------------------------------------------------------===//
8*a7dea167SDimitry Andric //
9*a7dea167SDimitry Andric // Defines the constexpr execution context.
10*a7dea167SDimitry Andric //
11*a7dea167SDimitry Andric // The execution context manages cached bytecode and the global context.
12*a7dea167SDimitry Andric // It invokes the compiler and interpreter, propagating errors.
13*a7dea167SDimitry Andric //
14*a7dea167SDimitry Andric //===----------------------------------------------------------------------===//
15*a7dea167SDimitry Andric 
16*a7dea167SDimitry Andric #ifndef LLVM_CLANG_AST_INTERP_CONTEXT_H
17*a7dea167SDimitry Andric #define LLVM_CLANG_AST_INTERP_CONTEXT_H
18*a7dea167SDimitry Andric 
19*a7dea167SDimitry Andric #include "Context.h"
20*a7dea167SDimitry Andric #include "InterpStack.h"
21*a7dea167SDimitry Andric #include "clang/AST/APValue.h"
22*a7dea167SDimitry Andric #include "llvm/ADT/PointerIntPair.h"
23*a7dea167SDimitry Andric 
24*a7dea167SDimitry Andric namespace clang {
25*a7dea167SDimitry Andric class ASTContext;
26*a7dea167SDimitry Andric class LangOptions;
27*a7dea167SDimitry Andric class Stmt;
28*a7dea167SDimitry Andric class FunctionDecl;
29*a7dea167SDimitry Andric class VarDecl;
30*a7dea167SDimitry Andric 
31*a7dea167SDimitry Andric namespace interp {
32*a7dea167SDimitry Andric class Function;
33*a7dea167SDimitry Andric class Program;
34*a7dea167SDimitry Andric class State;
35*a7dea167SDimitry Andric enum PrimType : unsigned;
36*a7dea167SDimitry Andric 
37*a7dea167SDimitry Andric /// Wrapper around interpreter termination results.
38*a7dea167SDimitry Andric enum class InterpResult {
39*a7dea167SDimitry Andric   /// Interpreter successfully computed a value.
40*a7dea167SDimitry Andric   Success,
41*a7dea167SDimitry Andric   /// Interpreter encountered an error and quit.
42*a7dea167SDimitry Andric   Fail,
43*a7dea167SDimitry Andric   /// Interpreter encountered an unimplemented feature, AST fallback.
44*a7dea167SDimitry Andric   Bail,
45*a7dea167SDimitry Andric };
46*a7dea167SDimitry Andric 
47*a7dea167SDimitry Andric /// Holds all information required to evaluate constexpr code in a module.
48*a7dea167SDimitry Andric class Context {
49*a7dea167SDimitry Andric public:
50*a7dea167SDimitry Andric   /// Initialises the constexpr VM.
51*a7dea167SDimitry Andric   Context(ASTContext &Ctx);
52*a7dea167SDimitry Andric 
53*a7dea167SDimitry Andric   /// Cleans up the constexpr VM.
54*a7dea167SDimitry Andric   ~Context();
55*a7dea167SDimitry Andric 
56*a7dea167SDimitry Andric   /// Checks if a function is a potential constant expression.
57*a7dea167SDimitry Andric   InterpResult isPotentialConstantExpr(State &Parent,
58*a7dea167SDimitry Andric                                        const FunctionDecl *FnDecl);
59*a7dea167SDimitry Andric 
60*a7dea167SDimitry Andric   /// Evaluates a toplevel expression as an rvalue.
61*a7dea167SDimitry Andric   InterpResult evaluateAsRValue(State &Parent, const Expr *E, APValue &Result);
62*a7dea167SDimitry Andric 
63*a7dea167SDimitry Andric   /// Evaluates a toplevel initializer.
64*a7dea167SDimitry Andric   InterpResult evaluateAsInitializer(State &Parent, const VarDecl *VD,
65*a7dea167SDimitry Andric                                      APValue &Result);
66*a7dea167SDimitry Andric 
67*a7dea167SDimitry Andric   /// Returns the AST context.
68*a7dea167SDimitry Andric   ASTContext &getASTContext() const { return Ctx; }
69*a7dea167SDimitry Andric   /// Returns the language options.
70*a7dea167SDimitry Andric   const LangOptions &getLangOpts() const;
71*a7dea167SDimitry Andric   /// Returns the interpreter stack.
72*a7dea167SDimitry Andric   InterpStack &getStack() { return Stk; }
73*a7dea167SDimitry Andric   /// Returns CHAR_BIT.
74*a7dea167SDimitry Andric   unsigned getCharBit() const;
75*a7dea167SDimitry Andric 
76*a7dea167SDimitry Andric   /// Classifies an expression.
77*a7dea167SDimitry Andric   llvm::Optional<PrimType> classify(QualType T);
78*a7dea167SDimitry Andric 
79*a7dea167SDimitry Andric private:
80*a7dea167SDimitry Andric   /// Runs a function.
81*a7dea167SDimitry Andric   InterpResult Run(State &Parent, Function *Func, APValue &Result);
82*a7dea167SDimitry Andric 
83*a7dea167SDimitry Andric   /// Checks a result fromt the interpreter.
84*a7dea167SDimitry Andric   InterpResult Check(State &Parent, llvm::Expected<bool> &&R);
85*a7dea167SDimitry Andric 
86*a7dea167SDimitry Andric private:
87*a7dea167SDimitry Andric   /// Current compilation context.
88*a7dea167SDimitry Andric   ASTContext &Ctx;
89*a7dea167SDimitry Andric   /// Flag to indicate if the use of the interpreter is mandatory.
90*a7dea167SDimitry Andric   bool ForceInterp;
91*a7dea167SDimitry Andric   /// Interpreter stack, shared across invocations.
92*a7dea167SDimitry Andric   InterpStack Stk;
93*a7dea167SDimitry Andric   /// Constexpr program.
94*a7dea167SDimitry Andric   std::unique_ptr<Program> P;
95*a7dea167SDimitry Andric };
96*a7dea167SDimitry Andric 
97*a7dea167SDimitry Andric } // namespace interp
98*a7dea167SDimitry Andric } // namespace clang
99*a7dea167SDimitry Andric 
100*a7dea167SDimitry Andric #endif
101