35 if (
Func->isLambdaCallOperator()) {
38 const Record *R = P.getOrCreateRecord(ParentDecl);
40 llvm::DenseMap<const ValueDecl *, FieldDecl *> LC;
46 unsigned Offset = R->getField(Cap.second)->Offset;
48 Offset, Cap.second->getType()->isReferenceType()};
51 QualType CaptureType = R->getField(LTC)->Decl->getType();
59 for (
unsigned ParamIndex = 0, N =
Func->getNumWrittenParams();
60 ParamIndex != N; ++ParamIndex) {
64 this->
Params.insert({PD, {ParamIndex, Ctx.canClassify(PD->
getType())}});
67 Func->setDefined(
true);
70 bool IsEligibleForCompilation =
Func->isLambdaStaticInvoker() ||
72 FuncDecl->
hasAttr<MSConstexprAttr>();
75 if (!IsEligibleForCompilation || !
visitFunc(FuncDecl)) {
76 Func->setIsFullyCompiled(
true);
83 Scopes.emplace_back(std::move(DS));
87 Func->setCode(FuncDecl, NextLocalOffset, std::move(Code), std::move(SrcMap),
88 std::move(Scopes), FuncDecl->
hasBody(), IsValid);
89 Func->setIsFullyCompiled(
true);
93 NextLocalOffset +=
sizeof(
Block);
94 unsigned Location = NextLocalOffset;
100 const size_t Target = Code.size();
101 LabelOffsets.insert({Label,
Target});
103 if (
auto It = LabelRelocs.find(Label); It != LabelRelocs.end()) {
104 for (
unsigned Reloc : It->second) {
105 using namespace llvm::support;
108 void *Location = Code.data() + Reloc -
align(
sizeof(int32_t));
110 const int32_t Offset =
Target -
static_cast<int64_t
>(Reloc);
111 endian::write<int32_t, llvm::endianness::native>(Location, Offset);
113 LabelRelocs.erase(It);
117int32_t ByteCodeEmitter::getOffset(LabelTy Label) {
119 const int64_t Position =
124 if (
auto It = LabelOffsets.find(Label); It != LabelOffsets.end())
125 return It->second - Position;
128 LabelRelocs[Label].push_back(Position);
137 size_t ValPos = Code.size();
140 if constexpr (std::is_pointer_v<T>)
141 Size =
align(
sizeof(uint32_t));
143 Size =
align(
sizeof(T));
145 if (ValPos + Size > std::numeric_limits<unsigned>::max()) {
152 assert(
aligned(ValPos + Size));
153 Code.resize_for_overwrite(ValPos + Size);
155 if constexpr (!std::is_pointer_v<T>) {
156 new (Code.data() + ValPos) T(Val);
159 new (Code.data() + ValPos) uint32_t(ID);
168 size_t ValPos = Code.size();
169 size_t Size =
align(Val.bytesToSerialize());
171 if (ValPos + Size > std::numeric_limits<unsigned>::max()) {
178 assert(
aligned(ValPos + Size));
179 Code.resize_for_overwrite(ValPos + Size);
181 Val.serialize(Code.data() + ValPos);
208template <
typename... Tys>
218 SrcMap.emplace_back(Code.size(), SI);
225 return emitJt(getOffset(Label), SI);
229 return emitJf(getOffset(Label), SI);
233 return emitJmp(getOffset(Label), SI);
244 if (!this->emitBCP(getOffset(EndLabel), T, E))
246 if (!this->
visit(Arg))
256#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....
Represents a C++ struct/union/class.
void getCaptureFields(llvm::DenseMap< const ValueDecl *, FieldDecl * > &Captures, FieldDecl *&ThisCapture) const
For a closure type, retrieve the mapping from captured variables and this to the non-static data memb...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
bool isInvalidDecl() const
This represents one expression.
Represents a member of a struct/union/class.
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
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.
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, SourceInfo SI)
void emitLabel(LabelTy Label)
Define a label.
ParamOffset LambdaThisCapture
Offset of the This parameter in a lambda record.
llvm::DenseMap< const ValueDecl *, ParamOffset > LambdaCaptures
Lambda captures.
bool jumpTrue(const LabelTy &Label, SourceInfo SI)
Emits jumps.
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.
bool jumpFalse(const LabelTy &Label, SourceInfo SI)
virtual bool visitFunc(const FunctionDecl *E)=0
Methods implemented by the compiler.
std::optional< SourceInfo > LocOverride
llvm::DenseMap< const ParmVarDecl *, FuncParam > Params
Parameter indices.
virtual bool visit(const Expr *E)=0
llvm::SmallVector< SmallVector< Local, 8 >, 2 > Descriptors
Local descriptors.
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.
The program contains and links the bytecode for all functions.
unsigned getOrCreateNativePointer(const void *Ptr)
Marshals a native pointer to an ID for embedding in bytecode.
Structure/Class descriptor.
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.
Describes a memory block created by an allocation site.
unsigned getAllocSize() const
Returns the allocated size, including metadata.
Information about a local's storage.