clang  16.0.0git
Context.cpp
Go to the documentation of this file.
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 "ByteCodeStmtGen.h"
13 #include "EvalEmitter.h"
14 #include "Interp.h"
15 #include "InterpFrame.h"
16 #include "InterpStack.h"
17 #include "PrimType.h"
18 #include "Program.h"
19 #include "clang/AST/Expr.h"
20 #include "clang/Basic/TargetInfo.h"
21 
22 using namespace clang;
23 using namespace clang::interp;
24 
25 Context::Context(ASTContext &Ctx) : Ctx(Ctx), P(new Program(*this)) {}
26 
28 
30  assert(Stk.empty());
31  Function *Func = P->getFunction(FD);
32  if (!Func || !Func->hasBody()) {
33  if (auto R = ByteCodeStmtGen<ByteCodeEmitter>(*this, *P).compileFunc(FD)) {
34  Func = *R;
35  } else {
36  handleAllErrors(R.takeError(), [&Parent](ByteCodeGenError &Err) {
37  Parent.FFDiag(Err.getRange().getBegin(),
38  diag::err_experimental_clang_interp_failed)
39  << Err.getRange();
40  });
41  return false;
42  }
43  }
44 
45  return Func->isConstexpr();
46 }
47 
48 bool Context::evaluateAsRValue(State &Parent, const Expr *E, APValue &Result) {
49  assert(Stk.empty());
50  ByteCodeExprGen<EvalEmitter> C(*this, *P, Parent, Stk, Result);
51  if (Check(Parent, C.interpretExpr(E))) {
52  assert(Stk.empty());
53  return true;
54  }
55 
56  Stk.clear();
57  return false;
58 }
59 
61  APValue &Result) {
62  assert(Stk.empty());
63  ByteCodeExprGen<EvalEmitter> C(*this, *P, Parent, Stk, Result);
64  if (Check(Parent, C.interpretDecl(VD))) {
65  assert(Stk.empty());
66  return true;
67  }
68 
69  Stk.clear();
70  return false;
71 }
72 
73 const LangOptions &Context::getLangOpts() const { return Ctx.getLangOpts(); }
74 
75 std::optional<PrimType> Context::classify(QualType T) const {
76  if (T->isReferenceType() || T->isPointerType()) {
77  return PT_Ptr;
78  }
79 
80  if (T->isBooleanType())
81  return PT_Bool;
82 
84  switch (Ctx.getIntWidth(T)) {
85  case 64:
86  return PT_Sint64;
87  case 32:
88  return PT_Sint32;
89  case 16:
90  return PT_Sint16;
91  case 8:
92  return PT_Sint8;
93  default:
94  return {};
95  }
96  }
97 
99  switch (Ctx.getIntWidth(T)) {
100  case 64:
101  return PT_Uint64;
102  case 32:
103  return PT_Uint32;
104  case 16:
105  return PT_Uint16;
106  case 8:
107  return PT_Uint8;
108  default:
109  return {};
110  }
111  }
112 
113  if (T->isNullPtrType())
114  return PT_Ptr;
115 
116  if (auto *AT = dyn_cast<AtomicType>(T))
117  return classify(AT->getValueType());
118 
119  return {};
120 }
121 
122 unsigned Context::getCharBit() const {
123  return Ctx.getTargetInfo().getCharWidth();
124 }
125 
126 bool Context::Run(State &Parent, Function *Func, APValue &Result) {
127  InterpState State(Parent, *P, Stk, *this);
128  State.Current = new InterpFrame(State, Func, nullptr, {}, {});
129  if (Interpret(State, Result))
130  return true;
131  Stk.clear();
132  return false;
133 }
134 
135 bool Context::Check(State &Parent, llvm::Expected<bool> &&Flag) {
136  if (Flag)
137  return *Flag;
138  handleAllErrors(Flag.takeError(), [&Parent](ByteCodeGenError &Err) {
139  Parent.FFDiag(Err.getRange().getBegin(),
140  diag::err_experimental_clang_interp_failed)
141  << Err.getRange();
142  });
143  return false;
144 }
clang::interp::InterpState
Interpreter context.
Definition: InterpState.h:34
clang::ASTContext::getIntWidth
unsigned getIntWidth(QualType T) const
Definition: ASTContext.cpp:10902
TargetInfo.h
clang::interp::Context::getCharBit
unsigned getCharBit() const
Returns CHAR_BIT.
Definition: Context.cpp:122
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:737
AttributeLangSupport::C
@ C
Definition: SemaDeclAttr.cpp:56
clang::interp::ByteCodeStmtGen
Compilation context for statements.
Definition: ByteCodeStmtGen.h:35
clang::interp::ByteCodeExprGen
Compilation context for expressions.
Definition: ByteCodeExprGen.h:40
clang::interp::PT_Uint16
@ PT_Uint16
Definition: PrimType.h:32
clang::TargetInfo::getCharWidth
unsigned getCharWidth() const
Definition: TargetInfo.h:466
clang::interp::Function::isConstexpr
bool isConstexpr() const
Checks if the function is valid to call in constexpr.
Definition: Function.h:125
llvm::Expected
Definition: LLVM.h:41
clang::interp::PT_Sint16
@ PT_Sint16
Definition: PrimType.h:31
ByteCodeStmtGen.h
clang::interp::InterpFrame
Frame storing local variables.
Definition: InterpFrame.h:29
clang::Type::isReferenceType
bool isReferenceType() const
Definition: Type.h:6895
clang::interp::Context::getLangOpts
const LangOptions & getLangOpts() const
Returns the language options.
Definition: Context.cpp:73
clang::interp
Definition: ASTContext.h:128
clang::Type::isSignedIntegerOrEnumerationType
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
Definition: Type.cpp:2040
clang::interp::ByteCodeGenError
Error thrown by the compiler.
Definition: ByteCodeGenError.h:21
clang::interp::InterpStack::clear
void clear()
Clears the stack without calling any destructors.
Definition: InterpStack.cpp:20
clang::interp::Context::evaluateAsRValue
bool evaluateAsRValue(State &Parent, const Expr *E, APValue &Result)
Evaluates a toplevel expression as an rvalue.
Definition: Context.cpp:48
clang::Type::isNullPtrType
bool isNullPtrType() const
Definition: Type.h:7205
clang::interp::State
Interface for the VM to interact with the AST walker's context.
Definition: State.h:55
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
clang::interp::PT_Bool
@ PT_Bool
Definition: PrimType.h:37
clang::interp::Context::Context
Context(ASTContext &Ctx)
Initialises the constexpr VM.
Definition: Context.cpp:25
clang::interp::PT_Uint32
@ PT_Uint32
Definition: PrimType.h:34
Expr.h
clang::VarDecl
Represents a variable declaration or definition.
Definition: Decl.h:906
clang::interp::Function::hasBody
bool hasBody() const
Definition: Function.h:139
PrimType.h
InterpStack.h
clang::Type::isUnsignedIntegerOrEnumerationType
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
Definition: Type.cpp:2090
clang::interp::Context::evaluateAsInitializer
bool evaluateAsInitializer(State &Parent, const VarDecl *VD, APValue &Result)
Evaluates a toplevel initializer.
Definition: Context.cpp:60
clang::interp::Interpret
bool Interpret(InterpState &S, APValue &Result)
Interpreter entry point.
Definition: Interp.cpp:404
clang::interp::InterpStack::empty
bool empty() const
Definition: InterpStack.h:79
P
StringRef P
Definition: ASTMatchersInternal.cpp:564
clang::Type::isPointerType
bool isPointerType() const
Definition: Type.h:6883
Interp.h
State
LineState State
Definition: UnwrappedLineFormatter.cpp:1147
clang::interp::PT_Uint8
@ PT_Uint8
Definition: PrimType.h:30
clang::ASTContext::getTargetInfo
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:746
clang::LangOptions
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:81
clang::Type::isBooleanType
bool isBooleanType() const
Definition: Type.h:7296
clang::interp::PT_Sint32
@ PT_Sint32
Definition: PrimType.h:33
clang::interp::PT_Sint8
@ PT_Sint8
Definition: PrimType.h:29
clang
Definition: CalledOnceCheck.h:17
clang::interp::Function
Bytecode function.
Definition: Function.h:74
clang::interp::Context::~Context
~Context()
Cleans up the constexpr VM.
Definition: Context.cpp:27
InterpFrame.h
EvalEmitter.h
clang::interp::Context::isPotentialConstantExpr
bool isPotentialConstantExpr(State &Parent, const FunctionDecl *FnDecl)
Checks if a function is a potential constant expression.
Definition: Context.cpp:29
clang::interp::PT_Uint64
@ PT_Uint64
Definition: PrimType.h:36
ByteCodeEmitter.h
clang::interp::PT_Sint64
@ PT_Sint64
Definition: PrimType.h:35
Program.h
Parent
NodeId Parent
Definition: ASTDiff.cpp:190
clang::interp::PT_Ptr
@ PT_Ptr
Definition: PrimType.h:38
clang::APValue
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition: APValue.h:122
clang::interp::Program
The program contains and links the bytecode for all functions.
Definition: Program.h:40
clang::Expr
This represents one expression.
Definition: Expr.h:109
clang::interp::Context::classify
std::optional< PrimType > classify(QualType T) const
Classifies an expression.
Definition: Context.cpp:75
clang::FunctionDecl
Represents a function declaration or definition.
Definition: Decl.h:1904
clang::ASTContext::getLangOpts
const LangOptions & getLangOpts() const
Definition: ASTContext.h:764
Context.h
ByteCodeExprGen.h