30 if (
Func->isLambdaCallOperator()) {
33 const Record *R = P.getOrCreateRecord(ParentDecl);
35 llvm::DenseMap<const ValueDecl *, FieldDecl *> LC;
40 for (
const auto &Cap : LC) {
41 unsigned Offset = R->getField(Cap.second)->Offset;
43 Offset, Cap.second->getType()->isReferenceType()};
46 QualType CaptureType = R->getField(LTC)->Decl->getType();
54 for (
unsigned ParamIndex = 0, N =
Func->getNumWrittenParams();
55 ParamIndex != N; ++ParamIndex) {
59 this->
Params.insert({PD, {ParamIndex, Ctx.canClassify(PD->
getType())}});
62 Func->setDefined(
true);
65 bool IsEligibleForCompilation =
Func->isLambdaStaticInvoker() ||
67 FuncDecl->
hasAttr<MSConstexprAttr>();
70 if (!IsEligibleForCompilation || !
visitFunc(FuncDecl)) {
71 Func->setIsFullyCompiled(
true);
78 Scopes.emplace_back(std::move(DS));
82 Func->setCode(FuncDecl, NextLocalOffset, std::move(Code), std::move(SrcMap),
83 std::move(Scopes), FuncDecl->
hasBody(), IsValid);
84 Func->setIsFullyCompiled(
true);
88 NextLocalOffset +=
sizeof(
Block);
89 unsigned Location = NextLocalOffset;
95 const size_t Target = Code.size();
96 LabelOffsets.insert({Label,
Target});
98 if (
auto It = LabelRelocs.find(Label); It != LabelRelocs.end()) {
99 for (
unsigned Reloc : It->second) {
100 using namespace llvm::support;
103 void *Location = Code.data() + Reloc -
align(
sizeof(int32_t));
105 const int32_t Offset =
Target -
static_cast<int64_t
>(Reloc);
106 endian::write<int32_t, llvm::endianness::native>(Location, Offset);
108 LabelRelocs.erase(It);
112int32_t ByteCodeEmitter::getOffset(LabelTy Label) {
114 const int64_t Position =
119 if (
auto It = LabelOffsets.find(Label); It != LabelOffsets.end())
120 return It->second - Position;
123 LabelRelocs[Label].push_back(Position);
131 size_t ValPos = Code.size();
134 if constexpr (std::is_pointer_v<T>)
139 if (ValPos + Size > std::numeric_limits<unsigned>::max()) {
146 assert(
aligned(ValPos + Size));
147 Code.resize_for_overwrite(ValPos + Size);
149 if constexpr (std::is_pointer_v<T>)
152 new (Code.data() + ValPos)
T(Val);
160 size_t ValPos = Code.size();
161 size_t Size =
align(Val.bytesToSerialize());
163 if (ValPos + Size > std::numeric_limits<unsigned>::max()) {
170 assert(
aligned(ValPos + Size));
171 Code.resize_for_overwrite(ValPos + Size);
173 Val.serialize(Code.data() + ValPos);
200template <
typename... Tys>
209 if (SrcMap.empty() || SrcMap.back() != SI)
210 SrcMap.push(Code.size(), SI);
217 return emitJt(getOffset(Label), SI);
221 return emitJf(getOffset(Label), SI);
225 return emitJmp(getOffset(Label), SI);
236 if (!this->emitBCP(getOffset(EndLabel),
T, E))
238 if (!this->
visit(Arg))
248#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 ...
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.
static constexpr uint8_t InlineDescMD
bool jump(const LabelTy &Label, SourceInfo SI)
void emitLabel(LabelTy Label)
Define a label.
Local createLocal(const Descriptor *D)
Callback for local registration.
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)
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.
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.
Top level wrappers for InstallAPI frontend operations.
@ Success
Annotation was successful.
const FunctionProtoType * T
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
Describes a memory block created by an allocation site.
unsigned getAllocSize() const
Returns the allocated size, including metadata.
Information about a local's storage.