[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
//===--- ByteCodeExprGen.h - Code generator for expressions -----*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// Defines the constexpr bytecode compiler.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef LLVM_CLANG_AST_INTERP_BYTECODEEXPRGEN_H
|
|
|
|
#define LLVM_CLANG_AST_INTERP_BYTECODEEXPRGEN_H
|
|
|
|
|
|
|
|
#include "ByteCodeEmitter.h"
|
|
|
|
#include "EvalEmitter.h"
|
|
|
|
#include "Pointer.h"
|
|
|
|
#include "PrimType.h"
|
|
|
|
#include "Record.h"
|
|
|
|
#include "clang/AST/Decl.h"
|
|
|
|
#include "clang/AST/Expr.h"
|
|
|
|
#include "clang/AST/StmtVisitor.h"
|
2020-02-27 14:16:47 -08:00
|
|
|
#include "clang/Basic/TargetInfo.h"
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
class QualType;
|
|
|
|
|
|
|
|
namespace interp {
|
|
|
|
|
|
|
|
template <class Emitter> class LocalScope;
|
2023-03-06 19:05:54 +01:00
|
|
|
template <class Emitter> class DestructorScope;
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
template <class Emitter> class VariableScope;
|
|
|
|
template <class Emitter> class DeclScope;
|
|
|
|
template <class Emitter> class OptionScope;
|
2022-09-21 16:05:30 +02:00
|
|
|
template <class Emitter> class ArrayIndexScope;
|
2023-07-18 17:11:30 +02:00
|
|
|
template <class Emitter> class SourceLocScope;
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
|
|
|
|
/// Compilation context for expressions.
|
|
|
|
template <class Emitter>
|
|
|
|
class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
|
|
|
|
public Emitter {
|
|
|
|
protected:
|
|
|
|
// Aliases for types defined in the emitter.
|
|
|
|
using LabelTy = typename Emitter::LabelTy;
|
|
|
|
using AddrTy = typename Emitter::AddrTy;
|
|
|
|
|
|
|
|
/// Current compilation context.
|
|
|
|
Context &Ctx;
|
|
|
|
/// Program to link to.
|
|
|
|
Program &P;
|
|
|
|
|
|
|
|
public:
|
|
|
|
/// Initializes the compiler and the backend emitter.
|
|
|
|
template <typename... Tys>
|
|
|
|
ByteCodeExprGen(Context &Ctx, Program &P, Tys &&... Args)
|
|
|
|
: Emitter(Ctx, P, Args...), Ctx(Ctx), P(P) {}
|
|
|
|
|
2022-08-31 16:09:40 +02:00
|
|
|
// Expression visitors - result returned on interp stack.
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
bool VisitCastExpr(const CastExpr *E);
|
|
|
|
bool VisitIntegerLiteral(const IntegerLiteral *E);
|
2023-01-25 14:51:16 +01:00
|
|
|
bool VisitFloatingLiteral(const FloatingLiteral *E);
|
2024-02-01 07:13:10 +01:00
|
|
|
bool VisitImaginaryLiteral(const ImaginaryLiteral *E);
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
bool VisitParenExpr(const ParenExpr *E);
|
|
|
|
bool VisitBinaryOperator(const BinaryOperator *E);
|
2022-12-31 20:04:41 +01:00
|
|
|
bool VisitLogicalBinOp(const BinaryOperator *E);
|
2022-10-13 10:09:36 +02:00
|
|
|
bool VisitPointerArithBinOp(const BinaryOperator *E);
|
2023-05-16 14:54:56 +02:00
|
|
|
bool VisitComplexBinOp(const BinaryOperator *E);
|
2022-08-19 13:45:11 +02:00
|
|
|
bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E);
|
|
|
|
bool VisitCallExpr(const CallExpr *E);
|
2022-11-05 13:08:40 +01:00
|
|
|
bool VisitBuiltinCallExpr(const CallExpr *E);
|
2022-09-16 19:11:58 +02:00
|
|
|
bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E);
|
2022-08-05 13:57:39 +02:00
|
|
|
bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E);
|
|
|
|
bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E);
|
2023-07-18 09:22:48 +02:00
|
|
|
bool VisitGNUNullExpr(const GNUNullExpr *E);
|
2022-09-18 20:40:27 +02:00
|
|
|
bool VisitCXXThisExpr(const CXXThisExpr *E);
|
2022-08-09 08:08:48 +02:00
|
|
|
bool VisitUnaryOperator(const UnaryOperator *E);
|
2022-08-18 10:15:20 +02:00
|
|
|
bool VisitDeclRefExpr(const DeclRefExpr *E);
|
2022-08-27 08:21:59 +02:00
|
|
|
bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E);
|
2022-08-27 17:37:26 +02:00
|
|
|
bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E);
|
2022-08-31 16:09:40 +02:00
|
|
|
bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E);
|
|
|
|
bool VisitInitListExpr(const InitListExpr *E);
|
2023-07-23 09:36:18 +02:00
|
|
|
bool VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
|
2022-08-31 16:09:40 +02:00
|
|
|
bool VisitConstantExpr(const ConstantExpr *E);
|
2022-09-14 16:53:55 +02:00
|
|
|
bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
|
2022-09-16 19:11:58 +02:00
|
|
|
bool VisitMemberExpr(const MemberExpr *E);
|
2022-09-21 16:05:30 +02:00
|
|
|
bool VisitArrayInitIndexExpr(const ArrayInitIndexExpr *E);
|
[clang][Interp] Rework initializers
Before this patch, we had visitRecordInitializer() and
visitArrayInitializer(), which were different from the regular visit()
in that they expected a pointer on the top of the stack, which they
initialized. For example, visitArrayInitializer handled InitListExprs by
looping over the members and initializing the elements of that pointer.
However, this had a few corner cases and problems. For example, in
visitLambdaExpr() (a lambda is always of record type), it was not clear
whether we should always create a new local variable to save the lambda
to, or not. This is why https://reviews.llvm.org/D153616 changed
things around.
This patch changes the visiting functions to:
- visit(): Always leaves a new value on the stack. If the expression
can be mapped to a primitive type, it's just visited and the value is
put on the stack. If it's of composite type, this function will
create a local variable for the expression value and call
visitInitializer(). The pointer to the local variable will stay on
the stack.
- visitInitializer(): Visits the given expression, assuming there is a
pointer on top of the stack that will be initialized by it.
- discard(): Visit the expression for side-effects, but don't leave a
value on the stack.
It also adds an additional Initializing flag to differentiate between the initializing and non-initializing case.
Differential Revision: https://reviews.llvm.org/D156027
2023-07-19 15:59:58 +02:00
|
|
|
bool VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E);
|
2022-09-21 16:05:30 +02:00
|
|
|
bool VisitOpaqueValueExpr(const OpaqueValueExpr *E);
|
2022-09-28 06:51:17 +02:00
|
|
|
bool VisitAbstractConditionalOperator(const AbstractConditionalOperator *E);
|
2022-10-28 13:49:30 +02:00
|
|
|
bool VisitStringLiteral(const StringLiteral *E);
|
|
|
|
bool VisitCharacterLiteral(const CharacterLiteral *E);
|
2022-10-22 15:32:27 +02:00
|
|
|
bool VisitCompoundAssignOperator(const CompoundAssignOperator *E);
|
2022-12-20 10:19:56 +01:00
|
|
|
bool VisitFloatCompoundAssignOperator(const CompoundAssignOperator *E);
|
2023-01-03 10:04:27 +01:00
|
|
|
bool VisitPointerCompoundAssignOperator(const CompoundAssignOperator *E);
|
2022-10-15 14:40:23 +02:00
|
|
|
bool VisitExprWithCleanups(const ExprWithCleanups *E);
|
|
|
|
bool VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E);
|
2023-04-05 09:11:32 +02:00
|
|
|
bool VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *E);
|
2022-12-26 09:18:56 +01:00
|
|
|
bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
|
2023-01-24 12:11:45 +01:00
|
|
|
bool VisitTypeTraitExpr(const TypeTraitExpr *E);
|
2023-03-14 11:08:16 +01:00
|
|
|
bool VisitLambdaExpr(const LambdaExpr *E);
|
2023-04-19 08:49:21 +02:00
|
|
|
bool VisitPredefinedExpr(const PredefinedExpr *E);
|
2023-05-11 16:01:54 +02:00
|
|
|
bool VisitCXXThrowExpr(const CXXThrowExpr *E);
|
2023-06-19 16:24:52 +02:00
|
|
|
bool VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E);
|
2023-07-19 09:20:47 +02:00
|
|
|
bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E);
|
[clang][Interp] Rework initializers
Before this patch, we had visitRecordInitializer() and
visitArrayInitializer(), which were different from the regular visit()
in that they expected a pointer on the top of the stack, which they
initialized. For example, visitArrayInitializer handled InitListExprs by
looping over the members and initializing the elements of that pointer.
However, this had a few corner cases and problems. For example, in
visitLambdaExpr() (a lambda is always of record type), it was not clear
whether we should always create a new local variable to save the lambda
to, or not. This is why https://reviews.llvm.org/D153616 changed
things around.
This patch changes the visiting functions to:
- visit(): Always leaves a new value on the stack. If the expression
can be mapped to a primitive type, it's just visited and the value is
put on the stack. If it's of composite type, this function will
create a local variable for the expression value and call
visitInitializer(). The pointer to the local variable will stay on
the stack.
- visitInitializer(): Visits the given expression, assuming there is a
pointer on top of the stack that will be initialized by it.
- discard(): Visit the expression for side-effects, but don't leave a
value on the stack.
It also adds an additional Initializing flag to differentiate between the initializing and non-initializing case.
Differential Revision: https://reviews.llvm.org/D156027
2023-07-19 15:59:58 +02:00
|
|
|
bool VisitCXXConstructExpr(const CXXConstructExpr *E);
|
2023-07-18 17:11:30 +02:00
|
|
|
bool VisitSourceLocExpr(const SourceLocExpr *E);
|
2023-07-27 08:30:59 +02:00
|
|
|
bool VisitOffsetOfExpr(const OffsetOfExpr *E);
|
2023-10-10 12:45:09 +02:00
|
|
|
bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
|
2023-11-12 05:34:16 +01:00
|
|
|
bool VisitSizeOfPackExpr(const SizeOfPackExpr *E);
|
2024-01-31 15:51:48 +01:00
|
|
|
bool VisitGenericSelectionExpr(const GenericSelectionExpr *E);
|
2024-02-01 09:11:27 +01:00
|
|
|
bool VisitChooseExpr(const ChooseExpr *E);
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
bool visitExpr(const Expr *E) override;
|
|
|
|
bool visitDecl(const VarDecl *VD) override;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
/// Emits scope cleanup instructions.
|
|
|
|
void emitCleanup();
|
|
|
|
|
|
|
|
/// Returns a record type from a record or pointer type.
|
|
|
|
const RecordType *getRecordTy(QualType Ty);
|
|
|
|
|
|
|
|
/// Returns a record from a record or pointer type.
|
|
|
|
Record *getRecord(QualType Ty);
|
|
|
|
Record *getRecord(const RecordDecl *RD);
|
|
|
|
|
2022-09-18 20:40:27 +02:00
|
|
|
// Returns a function for the given FunctionDecl.
|
|
|
|
// If the function does not exist yet, it is compiled.
|
|
|
|
const Function *getFunction(const FunctionDecl *FD);
|
|
|
|
|
2022-12-05 17:30:24 +01:00
|
|
|
std::optional<PrimType> classify(const Expr *E) const {
|
2024-01-31 15:57:23 +01:00
|
|
|
return Ctx.classify(E);
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
}
|
2022-12-05 17:30:24 +01:00
|
|
|
std::optional<PrimType> classify(QualType Ty) const {
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
return Ctx.classify(Ty);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Classifies a known primitive type
|
|
|
|
PrimType classifyPrim(QualType Ty) const {
|
|
|
|
if (auto T = classify(Ty)) {
|
|
|
|
return *T;
|
|
|
|
}
|
|
|
|
llvm_unreachable("not a primitive type");
|
|
|
|
}
|
[clang][Interp] Rework initializers
Before this patch, we had visitRecordInitializer() and
visitArrayInitializer(), which were different from the regular visit()
in that they expected a pointer on the top of the stack, which they
initialized. For example, visitArrayInitializer handled InitListExprs by
looping over the members and initializing the elements of that pointer.
However, this had a few corner cases and problems. For example, in
visitLambdaExpr() (a lambda is always of record type), it was not clear
whether we should always create a new local variable to save the lambda
to, or not. This is why https://reviews.llvm.org/D153616 changed
things around.
This patch changes the visiting functions to:
- visit(): Always leaves a new value on the stack. If the expression
can be mapped to a primitive type, it's just visited and the value is
put on the stack. If it's of composite type, this function will
create a local variable for the expression value and call
visitInitializer(). The pointer to the local variable will stay on
the stack.
- visitInitializer(): Visits the given expression, assuming there is a
pointer on top of the stack that will be initialized by it.
- discard(): Visit the expression for side-effects, but don't leave a
value on the stack.
It also adds an additional Initializing flag to differentiate between the initializing and non-initializing case.
Differential Revision: https://reviews.llvm.org/D156027
2023-07-19 15:59:58 +02:00
|
|
|
/// Evaluates an expression and places the result on the stack. If the
|
|
|
|
/// expression is of composite type, a local variable will be created
|
|
|
|
/// and a pointer to said variable will be placed on the stack.
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
bool visit(const Expr *E);
|
[clang][Interp] Rework initializers
Before this patch, we had visitRecordInitializer() and
visitArrayInitializer(), which were different from the regular visit()
in that they expected a pointer on the top of the stack, which they
initialized. For example, visitArrayInitializer handled InitListExprs by
looping over the members and initializing the elements of that pointer.
However, this had a few corner cases and problems. For example, in
visitLambdaExpr() (a lambda is always of record type), it was not clear
whether we should always create a new local variable to save the lambda
to, or not. This is why https://reviews.llvm.org/D153616 changed
things around.
This patch changes the visiting functions to:
- visit(): Always leaves a new value on the stack. If the expression
can be mapped to a primitive type, it's just visited and the value is
put on the stack. If it's of composite type, this function will
create a local variable for the expression value and call
visitInitializer(). The pointer to the local variable will stay on
the stack.
- visitInitializer(): Visits the given expression, assuming there is a
pointer on top of the stack that will be initialized by it.
- discard(): Visit the expression for side-effects, but don't leave a
value on the stack.
It also adds an additional Initializing flag to differentiate between the initializing and non-initializing case.
Differential Revision: https://reviews.llvm.org/D156027
2023-07-19 15:59:58 +02:00
|
|
|
/// Compiles an initializer. This is like visit() but it will never
|
|
|
|
/// create a variable and instead rely on a variable already having
|
|
|
|
/// been created. visitInitializer() then relies on a pointer to this
|
|
|
|
/// variable being on top of the stack.
|
2022-08-31 16:09:40 +02:00
|
|
|
bool visitInitializer(const Expr *E);
|
[clang][Interp] Rework initializers
Before this patch, we had visitRecordInitializer() and
visitArrayInitializer(), which were different from the regular visit()
in that they expected a pointer on the top of the stack, which they
initialized. For example, visitArrayInitializer handled InitListExprs by
looping over the members and initializing the elements of that pointer.
However, this had a few corner cases and problems. For example, in
visitLambdaExpr() (a lambda is always of record type), it was not clear
whether we should always create a new local variable to save the lambda
to, or not. This is why https://reviews.llvm.org/D153616 changed
things around.
This patch changes the visiting functions to:
- visit(): Always leaves a new value on the stack. If the expression
can be mapped to a primitive type, it's just visited and the value is
put on the stack. If it's of composite type, this function will
create a local variable for the expression value and call
visitInitializer(). The pointer to the local variable will stay on
the stack.
- visitInitializer(): Visits the given expression, assuming there is a
pointer on top of the stack that will be initialized by it.
- discard(): Visit the expression for side-effects, but don't leave a
value on the stack.
It also adds an additional Initializing flag to differentiate between the initializing and non-initializing case.
Differential Revision: https://reviews.llvm.org/D156027
2023-07-19 15:59:58 +02:00
|
|
|
/// Evaluates an expression for side effects and discards the result.
|
|
|
|
bool discard(const Expr *E);
|
|
|
|
/// Just pass evaluation on to \p E. This leaves all the parsing flags
|
|
|
|
/// intact.
|
|
|
|
bool delegate(const Expr *E);
|
|
|
|
|
2023-01-20 15:07:25 +01:00
|
|
|
/// Creates and initializes a variable from the given decl.
|
|
|
|
bool visitVarDecl(const VarDecl *VD);
|
2023-07-18 17:11:30 +02:00
|
|
|
/// Visit an APValue.
|
|
|
|
bool visitAPValue(const APValue &Val, PrimType ValType, const Expr *E);
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
|
|
|
|
/// Visits an expression and converts it to a boolean.
|
|
|
|
bool visitBool(const Expr *E);
|
|
|
|
|
|
|
|
/// Visits an initializer for a local.
|
|
|
|
bool visitLocalInitializer(const Expr *Init, unsigned I) {
|
2022-08-31 16:09:40 +02:00
|
|
|
if (!this->emitGetPtrLocal(I, Init))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (!visitInitializer(Init))
|
|
|
|
return false;
|
|
|
|
|
2024-01-31 08:03:37 +01:00
|
|
|
if (!this->emitInitPtr(Init))
|
|
|
|
return false;
|
|
|
|
|
2022-08-31 16:09:40 +02:00
|
|
|
return this->emitPopPtr(Init);
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Visits an initializer for a global.
|
|
|
|
bool visitGlobalInitializer(const Expr *Init, unsigned I) {
|
2022-08-31 16:09:40 +02:00
|
|
|
if (!this->emitGetPtrGlobal(I, Init))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (!visitInitializer(Init))
|
|
|
|
return false;
|
|
|
|
|
2024-01-31 08:03:37 +01:00
|
|
|
if (!this->emitInitPtr(Init))
|
|
|
|
return false;
|
|
|
|
|
2022-08-31 16:09:40 +02:00
|
|
|
return this->emitPopPtr(Init);
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Visits a delegated initializer.
|
|
|
|
bool visitThisInitializer(const Expr *I) {
|
2022-08-31 16:09:40 +02:00
|
|
|
if (!this->emitThis(I))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (!visitInitializer(I))
|
|
|
|
return false;
|
|
|
|
|
2024-01-31 08:03:37 +01:00
|
|
|
return this->emitInitPtrPop(I);
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
}
|
|
|
|
|
2023-07-23 09:36:18 +02:00
|
|
|
bool visitInitList(ArrayRef<const Expr *> Inits, const Expr *E);
|
2023-11-20 12:01:50 +01:00
|
|
|
bool visitArrayElemInit(unsigned ElemIndex, const Expr *Init);
|
2023-07-23 09:36:18 +02:00
|
|
|
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
/// Creates a local primitive value.
|
2023-05-04 12:57:37 +02:00
|
|
|
unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsConst,
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
bool IsExtended = false);
|
|
|
|
|
|
|
|
/// Allocates a space storing a local given its type.
|
2022-12-05 17:30:24 +01:00
|
|
|
std::optional<unsigned> allocateLocal(DeclTy &&Decl, bool IsExtended = false);
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
friend class VariableScope<Emitter>;
|
|
|
|
friend class LocalScope<Emitter>;
|
2023-03-06 19:05:54 +01:00
|
|
|
friend class DestructorScope<Emitter>;
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
friend class DeclScope<Emitter>;
|
|
|
|
friend class OptionScope<Emitter>;
|
2022-09-21 16:05:30 +02:00
|
|
|
friend class ArrayIndexScope<Emitter>;
|
2023-07-18 17:11:30 +02:00
|
|
|
friend class SourceLocScope<Emitter>;
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
|
|
|
|
/// Emits a zero initializer.
|
2023-10-14 17:42:27 +02:00
|
|
|
bool visitZeroInitializer(PrimType T, QualType QT, const Expr *E);
|
2023-06-30 09:56:58 +02:00
|
|
|
bool visitZeroRecordInitializer(const Record *R, const Expr *E);
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
|
|
|
|
enum class DerefKind {
|
|
|
|
/// Value is read and pushed to stack.
|
|
|
|
Read,
|
|
|
|
/// Direct method generates a value which is written. Returns pointer.
|
|
|
|
Write,
|
|
|
|
/// Direct method receives the value, pushes mutated value. Returns pointer.
|
|
|
|
ReadWrite,
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Method to directly load a value. If the value can be fetched directly,
|
|
|
|
/// the direct handler is called. Otherwise, a pointer is left on the stack
|
|
|
|
/// and the indirect handler is expected to operate on that.
|
|
|
|
bool dereference(const Expr *LV, DerefKind AK,
|
|
|
|
llvm::function_ref<bool(PrimType)> Direct,
|
|
|
|
llvm::function_ref<bool(PrimType)> Indirect);
|
|
|
|
bool dereferenceParam(const Expr *LV, PrimType T, const ParmVarDecl *PD,
|
|
|
|
DerefKind AK,
|
|
|
|
llvm::function_ref<bool(PrimType)> Direct,
|
|
|
|
llvm::function_ref<bool(PrimType)> Indirect);
|
|
|
|
bool dereferenceVar(const Expr *LV, PrimType T, const VarDecl *PD,
|
|
|
|
DerefKind AK, llvm::function_ref<bool(PrimType)> Direct,
|
|
|
|
llvm::function_ref<bool(PrimType)> Indirect);
|
|
|
|
|
2022-10-30 10:05:42 +01:00
|
|
|
/// Emits an APSInt constant.
|
2023-07-18 17:11:30 +02:00
|
|
|
bool emitConst(const llvm::APSInt &Value, PrimType Ty, const Expr *E);
|
2023-02-16 09:01:52 +01:00
|
|
|
bool emitConst(const llvm::APSInt &Value, const Expr *E);
|
|
|
|
bool emitConst(const llvm::APInt &Value, const Expr *E) {
|
|
|
|
return emitConst(static_cast<llvm::APSInt>(Value), E);
|
2022-10-30 10:05:42 +01:00
|
|
|
}
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
|
|
|
|
/// Emits an integer constant.
|
2023-07-18 17:11:30 +02:00
|
|
|
template <typename T> bool emitConst(T Value, PrimType Ty, const Expr *E);
|
2022-10-30 10:05:42 +01:00
|
|
|
template <typename T> bool emitConst(T Value, const Expr *E);
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
|
2023-01-25 14:51:16 +01:00
|
|
|
llvm::RoundingMode getRoundingMode(const Expr *E) const {
|
|
|
|
FPOptions FPO = E->getFPFeaturesInEffect(Ctx.getLangOpts());
|
|
|
|
|
|
|
|
if (FPO.getRoundingMode() == llvm::RoundingMode::Dynamic)
|
|
|
|
return llvm::RoundingMode::NearestTiesToEven;
|
|
|
|
|
|
|
|
return FPO.getRoundingMode();
|
|
|
|
}
|
|
|
|
|
2023-08-10 12:01:08 +02:00
|
|
|
bool emitPrimCast(PrimType FromT, PrimType ToT, QualType ToQT, const Expr *E);
|
2024-01-24 12:47:51 +01:00
|
|
|
PrimType classifyComplexElementType(QualType T) const {
|
2023-04-15 14:20:35 +02:00
|
|
|
assert(T->isAnyComplexType());
|
|
|
|
|
|
|
|
QualType ElemType = T->getAs<ComplexType>()->getElementType();
|
|
|
|
|
2024-01-24 12:47:51 +01:00
|
|
|
return *this->classify(ElemType);
|
2023-04-15 14:20:35 +02:00
|
|
|
}
|
|
|
|
|
2024-01-18 13:55:04 +01:00
|
|
|
bool emitComplexReal(const Expr *SubExpr);
|
|
|
|
|
2023-03-06 19:05:54 +01:00
|
|
|
bool emitRecordDestruction(const Descriptor *Desc);
|
2023-04-24 16:45:16 +02:00
|
|
|
unsigned collectBaseOffset(const RecordType *BaseType,
|
|
|
|
const RecordType *DerivedType);
|
2023-03-06 19:05:54 +01:00
|
|
|
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
protected:
|
|
|
|
/// Variable to storage mapping.
|
|
|
|
llvm::DenseMap<const ValueDecl *, Scope::Local> Locals;
|
|
|
|
|
|
|
|
/// OpaqueValueExpr to location mapping.
|
|
|
|
llvm::DenseMap<const OpaqueValueExpr *, unsigned> OpaqueExprs;
|
|
|
|
|
|
|
|
/// Current scope.
|
|
|
|
VariableScope<Emitter> *VarScope = nullptr;
|
|
|
|
|
2022-09-21 16:05:30 +02:00
|
|
|
/// Current argument index. Needed to emit ArrayInitIndexExpr.
|
2022-12-05 17:30:24 +01:00
|
|
|
std::optional<uint64_t> ArrayIndex;
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
|
2023-07-18 17:11:30 +02:00
|
|
|
/// DefaultInit- or DefaultArgExpr, needed for SourceLocExpr.
|
|
|
|
const Expr *SourceLocDefaultExpr = nullptr;
|
|
|
|
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
/// Flag indicating if return value is to be discarded.
|
|
|
|
bool DiscardResult = false;
|
[clang][Interp] Rework initializers
Before this patch, we had visitRecordInitializer() and
visitArrayInitializer(), which were different from the regular visit()
in that they expected a pointer on the top of the stack, which they
initialized. For example, visitArrayInitializer handled InitListExprs by
looping over the members and initializing the elements of that pointer.
However, this had a few corner cases and problems. For example, in
visitLambdaExpr() (a lambda is always of record type), it was not clear
whether we should always create a new local variable to save the lambda
to, or not. This is why https://reviews.llvm.org/D153616 changed
things around.
This patch changes the visiting functions to:
- visit(): Always leaves a new value on the stack. If the expression
can be mapped to a primitive type, it's just visited and the value is
put on the stack. If it's of composite type, this function will
create a local variable for the expression value and call
visitInitializer(). The pointer to the local variable will stay on
the stack.
- visitInitializer(): Visits the given expression, assuming there is a
pointer on top of the stack that will be initialized by it.
- discard(): Visit the expression for side-effects, but don't leave a
value on the stack.
It also adds an additional Initializing flag to differentiate between the initializing and non-initializing case.
Differential Revision: https://reviews.llvm.org/D156027
2023-07-19 15:59:58 +02:00
|
|
|
|
|
|
|
/// Flag inidicating if we're initializing an already created
|
|
|
|
/// variable. This is set in visitInitializer().
|
|
|
|
bool Initializing = false;
|
2023-07-27 17:57:26 +02:00
|
|
|
|
|
|
|
/// Flag indicating if we're initializing a global variable.
|
|
|
|
bool GlobalDecl = false;
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
extern template class ByteCodeExprGen<ByteCodeEmitter>;
|
|
|
|
extern template class ByteCodeExprGen<EvalEmitter>;
|
|
|
|
|
|
|
|
/// Scope chain managing the variable lifetimes.
|
|
|
|
template <class Emitter> class VariableScope {
|
|
|
|
public:
|
2023-01-20 15:07:25 +01:00
|
|
|
VariableScope(ByteCodeExprGen<Emitter> *Ctx)
|
|
|
|
: Ctx(Ctx), Parent(Ctx->VarScope) {
|
|
|
|
Ctx->VarScope = this;
|
|
|
|
}
|
|
|
|
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
virtual ~VariableScope() { Ctx->VarScope = this->Parent; }
|
|
|
|
|
|
|
|
void add(const Scope::Local &Local, bool IsExtended) {
|
|
|
|
if (IsExtended)
|
|
|
|
this->addExtended(Local);
|
|
|
|
else
|
|
|
|
this->addLocal(Local);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void addLocal(const Scope::Local &Local) {
|
|
|
|
if (this->Parent)
|
|
|
|
this->Parent->addLocal(Local);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void addExtended(const Scope::Local &Local) {
|
|
|
|
if (this->Parent)
|
|
|
|
this->Parent->addExtended(Local);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void emitDestruction() {}
|
2023-03-06 19:05:54 +01:00
|
|
|
virtual void emitDestructors() {}
|
2023-01-30 09:09:22 +01:00
|
|
|
VariableScope *getParent() const { return Parent; }
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
/// ByteCodeExprGen instance.
|
|
|
|
ByteCodeExprGen<Emitter> *Ctx;
|
|
|
|
/// Link to the parent scope.
|
|
|
|
VariableScope *Parent;
|
|
|
|
};
|
|
|
|
|
2023-03-06 19:05:54 +01:00
|
|
|
/// Generic scope for local variables.
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
template <class Emitter> class LocalScope : public VariableScope<Emitter> {
|
|
|
|
public:
|
|
|
|
LocalScope(ByteCodeExprGen<Emitter> *Ctx) : VariableScope<Emitter>(Ctx) {}
|
|
|
|
|
2023-03-06 19:05:54 +01:00
|
|
|
/// Emit a Destroy op for this scope.
|
|
|
|
~LocalScope() override {
|
|
|
|
if (!Idx)
|
|
|
|
return;
|
|
|
|
this->Ctx->emitDestroy(*Idx, SourceInfo{});
|
2024-01-26 17:19:11 +01:00
|
|
|
removeStoredOpaqueValues();
|
2023-03-06 19:05:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Overriden to support explicit destruction.
|
|
|
|
void emitDestruction() override {
|
|
|
|
if (!Idx)
|
|
|
|
return;
|
|
|
|
this->emitDestructors();
|
|
|
|
this->Ctx->emitDestroy(*Idx, SourceInfo{});
|
2024-01-26 17:19:11 +01:00
|
|
|
removeStoredOpaqueValues();
|
2023-03-06 19:05:54 +01:00
|
|
|
this->Idx = std::nullopt;
|
|
|
|
}
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
|
|
|
|
void addLocal(const Scope::Local &Local) override {
|
2022-06-20 10:51:34 -07:00
|
|
|
if (!Idx) {
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
Idx = this->Ctx->Descriptors.size();
|
|
|
|
this->Ctx->Descriptors.emplace_back();
|
|
|
|
}
|
|
|
|
|
|
|
|
this->Ctx->Descriptors[*Idx].emplace_back(Local);
|
|
|
|
}
|
|
|
|
|
2023-03-06 19:05:54 +01:00
|
|
|
void emitDestructors() override {
|
2022-06-20 10:51:34 -07:00
|
|
|
if (!Idx)
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
return;
|
2023-03-06 19:05:54 +01:00
|
|
|
// Emit destructor calls for local variables of record
|
|
|
|
// type with a destructor.
|
|
|
|
for (Scope::Local &Local : this->Ctx->Descriptors[*Idx]) {
|
|
|
|
if (!Local.Desc->isPrimitive() && !Local.Desc->isPrimitiveArray()) {
|
|
|
|
this->Ctx->emitGetPtrLocal(Local.Offset, SourceInfo{});
|
|
|
|
this->Ctx->emitRecordDestruction(Local.Desc);
|
2024-01-26 17:19:11 +01:00
|
|
|
removeIfStoredOpaqueValue(Local);
|
2023-03-06 19:05:54 +01:00
|
|
|
}
|
|
|
|
}
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
}
|
|
|
|
|
2024-01-26 17:19:11 +01:00
|
|
|
void removeStoredOpaqueValues() {
|
|
|
|
if (!Idx)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (const Scope::Local &Local : this->Ctx->Descriptors[*Idx]) {
|
|
|
|
removeIfStoredOpaqueValue(Local);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void removeIfStoredOpaqueValue(const Scope::Local &Local) {
|
|
|
|
if (const auto *OVE =
|
|
|
|
llvm::dyn_cast_if_present<OpaqueValueExpr>(Local.Desc->asExpr())) {
|
|
|
|
if (auto It = this->Ctx->OpaqueExprs.find(OVE);
|
|
|
|
It != this->Ctx->OpaqueExprs.end())
|
|
|
|
this->Ctx->OpaqueExprs.erase(It);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
/// Index of the scope in the chain.
|
2022-12-05 17:30:24 +01:00
|
|
|
std::optional<unsigned> Idx;
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
};
|
|
|
|
|
2023-03-06 19:05:54 +01:00
|
|
|
/// Emits the destructors of the variables of \param OtherScope
|
|
|
|
/// when this scope is destroyed. Does not create a Scope in the bytecode at
|
|
|
|
/// all, this is just a RAII object to emit destructors.
|
|
|
|
template <class Emitter> class DestructorScope final {
|
|
|
|
public:
|
|
|
|
DestructorScope(LocalScope<Emitter> &OtherScope) : OtherScope(OtherScope) {}
|
|
|
|
|
|
|
|
~DestructorScope() { OtherScope.emitDestructors(); }
|
|
|
|
|
|
|
|
private:
|
|
|
|
LocalScope<Emitter> &OtherScope;
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Like a regular LocalScope, except that the destructors of all local
|
|
|
|
/// variables are automatically emitted when the AutoScope is destroyed.
|
|
|
|
template <class Emitter> class AutoScope : public LocalScope<Emitter> {
|
|
|
|
public:
|
|
|
|
AutoScope(ByteCodeExprGen<Emitter> *Ctx)
|
|
|
|
: LocalScope<Emitter>(Ctx), DS(*this) {}
|
|
|
|
|
|
|
|
private:
|
|
|
|
DestructorScope<Emitter> DS;
|
|
|
|
};
|
|
|
|
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
/// Scope for storage declared in a compound statement.
|
2023-03-06 19:05:54 +01:00
|
|
|
template <class Emitter> class BlockScope final : public AutoScope<Emitter> {
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
public:
|
2023-03-06 19:05:54 +01:00
|
|
|
BlockScope(ByteCodeExprGen<Emitter> *Ctx) : AutoScope<Emitter>(Ctx) {}
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
|
|
|
|
void addExtended(const Scope::Local &Local) override {
|
2022-12-26 09:18:56 +01:00
|
|
|
// If we to this point, just add the variable as a normal local
|
|
|
|
// variable. It will be destroyed at the end of the block just
|
|
|
|
// like all others.
|
|
|
|
this->addLocal(Local);
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Expression scope which tracks potentially lifetime extended
|
|
|
|
/// temporaries which are hoisted to the parent scope on exit.
|
2023-03-06 19:05:54 +01:00
|
|
|
template <class Emitter> class ExprScope final : public AutoScope<Emitter> {
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
public:
|
2023-03-06 19:05:54 +01:00
|
|
|
ExprScope(ByteCodeExprGen<Emitter> *Ctx) : AutoScope<Emitter>(Ctx) {}
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
|
|
|
|
void addExtended(const Scope::Local &Local) override {
|
2022-12-26 09:18:56 +01:00
|
|
|
if (this->Parent)
|
|
|
|
this->Parent->addLocal(Local);
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-09-21 16:05:30 +02:00
|
|
|
template <class Emitter> class ArrayIndexScope final {
|
|
|
|
public:
|
|
|
|
ArrayIndexScope(ByteCodeExprGen<Emitter> *Ctx, uint64_t Index) : Ctx(Ctx) {
|
|
|
|
OldArrayIndex = Ctx->ArrayIndex;
|
|
|
|
Ctx->ArrayIndex = Index;
|
|
|
|
}
|
|
|
|
|
|
|
|
~ArrayIndexScope() { Ctx->ArrayIndex = OldArrayIndex; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
ByteCodeExprGen<Emitter> *Ctx;
|
2022-12-05 17:30:24 +01:00
|
|
|
std::optional<uint64_t> OldArrayIndex;
|
2022-09-21 16:05:30 +02:00
|
|
|
};
|
|
|
|
|
2023-07-18 17:11:30 +02:00
|
|
|
template <class Emitter> class SourceLocScope final {
|
|
|
|
public:
|
|
|
|
SourceLocScope(ByteCodeExprGen<Emitter> *Ctx, const Expr *DefaultExpr)
|
|
|
|
: Ctx(Ctx) {
|
|
|
|
assert(DefaultExpr);
|
|
|
|
// We only switch if the current SourceLocDefaultExpr is null.
|
|
|
|
if (!Ctx->SourceLocDefaultExpr) {
|
|
|
|
Enabled = true;
|
|
|
|
Ctx->SourceLocDefaultExpr = DefaultExpr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
~SourceLocScope() {
|
|
|
|
if (Enabled)
|
|
|
|
Ctx->SourceLocDefaultExpr = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
ByteCodeExprGen<Emitter> *Ctx;
|
|
|
|
bool Enabled = false;
|
|
|
|
};
|
|
|
|
|
[Clang Interpreter] Initial patch for the constexpr interpreter
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
2019-09-13 09:46:16 +00:00
|
|
|
} // namespace interp
|
|
|
|
} // namespace clang
|
|
|
|
|
|
|
|
#endif
|