35 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl);
38 const Record *R = P.getOrCreateRecord(MD->getParent());
40 llvm::DenseMap<const ValueDecl *, FieldDecl *> LC;
43 MD->
getParent()->getCaptureFields(LC, LTC);
48 Offset, Cap.second->getType()->isReferenceType()};
59 unsigned ParamIndex = 0;
60 unsigned Drop =
Func->hasRVO() +
61 (
Func->hasThisPointer() && !
Func->isThisPointerExplicit());
71 Func->setDefined(
true);
74 bool IsEligibleForCompilation =
Func->isLambdaStaticInvoker() ||
76 FuncDecl->
hasAttr<MSConstexprAttr>();
79 if (!IsEligibleForCompilation || !
visitFunc(FuncDecl)) {
80 Func->setIsFullyCompiled(
true);
87 Scopes.emplace_back(std::move(DS));
91 Func->setCode(FuncDecl, NextLocalOffset, std::move(Code), std::move(SrcMap),
92 std::move(Scopes), FuncDecl->
hasBody(), IsValid);
93 Func->setIsFullyCompiled(
true);
97 NextLocalOffset +=
sizeof(
Block);
98 unsigned Location = NextLocalOffset;
100 return {Location, D};
104 const size_t Target = Code.size();
105 LabelOffsets.insert({Label,
Target});
107 if (
auto It = LabelRelocs.find(Label); It != LabelRelocs.end()) {
108 for (
unsigned Reloc : It->second) {
109 using namespace llvm::support;
112 void *Location = Code.data() + Reloc -
align(
sizeof(int32_t));
114 const int32_t Offset =
Target -
static_cast<int64_t
>(Reloc);
115 endian::write<int32_t, llvm::endianness::native>(Location, Offset);
117 LabelRelocs.erase(It);
121int32_t ByteCodeEmitter::getOffset(LabelTy Label) {
123 const int64_t Position =
128 if (
auto It = LabelOffsets.find(Label); It != LabelOffsets.end())
129 return It->second - Position;
132 LabelRelocs[Label].push_back(Position);
141 size_t ValPos = Code.size();
144 if constexpr (std::is_pointer_v<T>)
145 Size =
align(
sizeof(uint32_t));
149 if (ValPos + Size > std::numeric_limits<unsigned>::max()) {
156 assert(
aligned(ValPos + Size));
157 Code.resize_for_overwrite(ValPos + Size);
159 if constexpr (!std::is_pointer_v<T>) {
160 new (Code.data() + ValPos)
T(Val);
163 new (Code.data() + ValPos) uint32_t(ID);
172 size_t ValPos = Code.size();
173 size_t Size =
align(Val.bytesToSerialize());
175 if (ValPos + Size > std::numeric_limits<unsigned>::max()) {
182 assert(
aligned(ValPos + Size));
183 Code.resize_for_overwrite(ValPos + Size);
185 Val.serialize(Code.data() + ValPos);
212template <
typename... Tys>
222 SrcMap.emplace_back(Code.size(), SI);
229 return emitJt(getOffset(Label),
SourceInfo{});
233 return emitJf(getOffset(Label),
SourceInfo{});
237 return emitJmp(getOffset(Label),
SourceInfo{});
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....
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.
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.
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
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.
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.
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.
const Field * getField(unsigned I) const
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.
unsigned getAllocSize() const
Returns the allocated size, including metadata.
Information about a local's storage.