37 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl);
42 llvm::DenseMap<const ValueDecl *, FieldDecl *> LC;
45 MD->
getParent()->getCaptureFields(LC, LTC);
50 Offset, Cap.second->getType()->isReferenceType()};
60 unsigned ParamIndex = 0;
61 unsigned Drop =
Func->hasRVO() +
62 (
Func->hasThisPointer() && !
Func->isThisPointerExplicit());
70 Func->setDefined(
true);
73 bool IsEligibleForCompilation =
Func->isLambdaStaticInvoker() ||
75 FuncDecl->
hasAttr<MSConstexprAttr>();
78 if (!IsEligibleForCompilation || !
visitFunc(FuncDecl)) {
79 Func->setIsFullyCompiled(
true);
86 Scopes.emplace_back(std::move(DS));
90 Func->setCode(NextLocalOffset, std::move(Code), std::move(SrcMap),
91 std::move(Scopes), FuncDecl->
hasBody());
92 Func->setIsFullyCompiled(
true);
96 NextLocalOffset +=
sizeof(
Block);
97 unsigned Location = NextLocalOffset;
98 NextLocalOffset +=
align(
D->getAllocSize());
103 const size_t Target = Code.size();
106 if (
auto It = LabelRelocs.find(
Label); It != LabelRelocs.end()) {
107 for (
unsigned Reloc : It->second) {
108 using namespace llvm::support;
111 void *Location = Code.data() + Reloc -
align(
sizeof(int32_t));
113 const int32_t Offset =
Target -
static_cast<int64_t
>(Reloc);
114 endian::write<int32_t, llvm::endianness::native>(Location, Offset);
116 LabelRelocs.erase(It);
120int32_t ByteCodeEmitter::getOffset(LabelTy
Label) {
122 const int64_t Position =
127 if (
auto It = LabelOffsets.find(
Label); It != LabelOffsets.end())
128 return It->second - Position;
131 LabelRelocs[
Label].push_back(Position);
140 size_t ValPos = Code.size();
143 if constexpr (std::is_pointer_v<T>)
144 Size =
align(
sizeof(uint32_t));
148 if (ValPos + Size > std::numeric_limits<unsigned>::max()) {
155 assert(
aligned(ValPos + Size));
156 Code.resize_for_overwrite(ValPos + Size);
158 if constexpr (!std::is_pointer_v<T>) {
159 new (Code.data() + ValPos)
T(Val);
161 uint32_t ID =
P.getOrCreateNativePointer(Val);
162 new (Code.data() + ValPos) uint32_t(ID);
171 size_t ValPos = Code.size();
172 size_t Size =
align(Val.bytesToSerialize());
174 if (ValPos + Size > std::numeric_limits<unsigned>::max()) {
181 assert(
aligned(ValPos + Size));
182 Code.resize_for_overwrite(ValPos + Size);
184 Val.serialize(Code.data() + ValPos);
211template <
typename... Tys>
212bool ByteCodeEmitter::emitOp(
Opcode Op,
const Tys &...Args,
222 SrcMap.emplace_back(Code.size(), SI);
246 const Expr *Arg =
E->getArg(0);
248 if (!this->emitBCP(getOffset(EndLabel),
T,
E))
250 if (!this->
visit(Arg))
260#include "Opcodes.inc"
This file provides some common utility functions for processing Lambda related AST Constructs.
static void emitSerialized(llvm::SmallVectorImpl< std::byte > &Code, const T &Val, bool &Success)
Emits a serializable value.
static void emit(Program &P, llvm::SmallVectorImpl< std::byte > &Code, const T &Val, bool &Success)
Helper to write bytecode and bail out if 32-bit offsets become invalid.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
llvm::MachO::Target Target
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
This represents one expression.
Represents a member of a struct/union/class.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
Represents a function declaration or definition.
ArrayRef< ParmVarDecl * > parameters() const
param_iterator param_begin()
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
bool isDefined(const FunctionDecl *&Definition, bool CheckForPendingFriendDefinition=false) const
Returns true if the function has a definition that does not need to be instantiated.
Represents a parameter to a function.
A (possibly-)qualified type.
bool isPointerOrReferenceType() const
A memory block, either on the stack or in the heap.
bool jump(const LabelTy &Label)
void emitLabel(LabelTy Label)
Define a label.
ParamOffset LambdaThisCapture
Offset of the This parameter in a lambda record.
llvm::DenseMap< const ParmVarDecl *, ParamOffset > Params
Parameter indices.
llvm::DenseMap< const ValueDecl *, ParamOffset > LambdaCaptures
Lambda captures.
bool speculate(const CallExpr *E, const LabelTy &EndLabel)
Speculative execution.
void compileFunc(const FunctionDecl *FuncDecl, Function *Func=nullptr)
Compiles the function into the module.
bool fallthrough(const LabelTy &Label)
Local createLocal(Descriptor *D)
Callback for local registration.
virtual bool visitFunc(const FunctionDecl *E)=0
Methods implemented by the compiler.
bool jumpTrue(const LabelTy &Label)
Emits jumps.
std::optional< SourceInfo > LocOverride
bool jumpFalse(const LabelTy &Label)
virtual bool visit(const Expr *E)=0
llvm::SmallVector< SmallVector< Local, 8 >, 2 > Descriptors
Local descriptors.
OptPrimType classify(QualType T) const
Classifies a type.
Wrapper around fixed point types.
If a Floating is constructed from Memory, it DOES NOT OWN THAT MEMORY.
If an IntegralAP is constructed from Memory, it DOES NOT OWN THAT MEMORY.
PrimType value_or(PrimType PT) const
The program contains and links the bytecode for all functions.
Record * getOrCreateRecord(const RecordDecl *RD)
Returns a record or creates one if it does not exist.
Structure/Class descriptor.
const Field * getField(const FieldDecl *FD) const
Returns a field.
Describes the statement/declaration an opcode was generated from.
constexpr bool aligned(uintptr_t Value)
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
PrimType
Enumeration of the primitive types of the VM.
The JSON file list parser is used to communicate input to InstallAPI.
@ Success
Annotation was successful.
bool isLambdaCallOperator(const CXXMethodDecl *MD)
const FunctionProtoType * T
Describes a memory block created by an allocation site.
Information about a local's storage.