29 llvm::DenseMap<unsigned, Function::ParamDescriptor> ParamDescriptors;
38 ParamTypes.push_back(
PT_Ptr);
46 bool HasThisPointer =
false;
47 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl)) {
48 if (MD->isImplicitObjectMemberFunction()) {
49 HasThisPointer =
true;
50 ParamTypes.push_back(
PT_Ptr);
58 llvm::DenseMap<const ValueDecl *, FieldDecl *> LC;
61 MD->
getParent()->getCaptureFields(LC, LTC);
66 Offset, Cap.second->getType()->isReferenceType()};
76 std::optional<PrimType> T = Ctx.
classify(PD->getType());
83 ParamTypes.push_back(PT);
89 bool IsUnevaluatedBuiltin =
false;
95 std::move(ParamDescriptors), std::move(ParamOffsets),
96 HasThisPointer, HasRVO, IsUnevaluatedBuiltin);
103 Func->setDefined(
false);
107 Func->setDefined(
true);
110 bool IsEligibleForCompilation =
false;
111 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
112 IsEligibleForCompilation = MD->isLambdaStaticInvoker();
113 if (!IsEligibleForCompilation)
114 IsEligibleForCompilation = FuncDecl->
isConstexpr();
117 if (!IsEligibleForCompilation || !
visitFunc(FuncDecl)) {
120 return llvm::make_error<ByteCodeGenError>(*BailLocation);
122 Func->setIsFullyCompiled(
true);
129 Scopes.emplace_back(std::move(DS));
133 Func->setCode(NextLocalOffset, std::move(Code), std::move(SrcMap),
134 std::move(Scopes), FuncDecl->
hasBody());
135 Func->setIsFullyCompiled(
true);
140 NextLocalOffset +=
sizeof(
Block);
141 unsigned Location = NextLocalOffset;
143 return {Location, D};
147 const size_t Target = Code.size();
150 if (
auto It = LabelRelocs.find(
Label);
151 It != LabelRelocs.end()) {
152 for (
unsigned Reloc : It->second) {
153 using namespace llvm::support;
156 void *Location = Code.data() + Reloc -
align(
sizeof(int32_t));
158 const int32_t Offset =
Target -
static_cast<int64_t
>(Reloc);
159 endian::write<int32_t, llvm::endianness::native>(Location, Offset);
161 LabelRelocs.erase(It);
165int32_t ByteCodeEmitter::getOffset(LabelTy
Label) {
167 const int64_t Position =
172 if (
auto It = LabelOffsets.find(
Label);
173 It != LabelOffsets.end())
174 return It->second - Position;
177 LabelRelocs[
Label].push_back(Position);
190static void emit(
Program &
P, std::vector<std::byte> &Code,
const T &Val,
194 if constexpr (std::is_pointer_v<T>)
195 Size =
sizeof(uint32_t);
199 if (Code.size() + Size > std::numeric_limits<unsigned>::max()) {
205 size_t ValPos =
align(Code.size());
207 assert(
aligned(ValPos + Size));
208 Code.resize(ValPos + Size);
210 if constexpr (!std::is_pointer_v<T>) {
211 new (Code.data() + ValPos) T(Val);
213 uint32_t ID =
P.getOrCreateNativePointer(Val);
214 new (Code.data() + ValPos) uint32_t(ID);
223 if (Code.size() + Size > std::numeric_limits<unsigned>::max()) {
229 size_t ValPos =
align(Code.size());
231 assert(
aligned(ValPos + Size));
232 Code.resize(ValPos + Size);
237template <
typename... Tys>
238bool ByteCodeEmitter::emitOp(
Opcode Op,
const Tys &... Args,
const SourceInfo &SI) {
243 emit(P, Code, Op, Success);
245 SrcMap.emplace_back(Code.size(), SI);
249 (void)std::initializer_list<int>{(
emit(P, Code, Args, Success), 0)...};
276#include "Opcodes.inc"
This file provides some common utility functions for processing Lambda related AST Constructs.
Defines enum values for all the target-independent builtin functions.
static void emit(Program &P, std::vector< 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....
Builtin::Context & BuiltinInfo
bool isUnevaluated(unsigned ID) const
Returns true if this builtin does not perform the side-effects of its arguments.
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.
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
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.
Encodes a location in the source.
A memory block, either on the stack or in the heap.
bool jump(const LabelTy &Label)
void emitLabel(LabelTy Label)
Define a label.
llvm::DenseMap< const ParmVarDecl *, ParamOffset > Params
Parameter indices.
unsigned LambdaThisCapture
Offset of the This parameter in a lambda record.
llvm::DenseMap< const ValueDecl *, ParamOffset > LambdaCaptures
Lambda captures.
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.
bool bail(const Stmt *S)
Bails out if a given node cannot be compiled.
llvm::Expected< Function * > compileFunc(const FunctionDecl *FuncDecl)
Compiles the function into the module.
bool jumpFalse(const LabelTy &Label)
llvm::SmallVector< SmallVector< Local, 8 >, 2 > Descriptors
Local descriptors.
ASTContext & getASTContext() const
Returns the AST context.
std::optional< PrimType > classify(QualType T) const
Classifies an expression.
void serialize(std::byte *Buff) const
size_t bytesToSerialize() const
The program contains and links the bytecode for all functions.
Function * getFunction(const FunctionDecl *F)
Returns a function.
Descriptor * createDescriptor(const DeclTy &D, PrimType Type, Descriptor::MetadataSize MDSize=std::nullopt, bool IsConst=false, bool IsTemporary=false, bool IsMutable=false)
Creates a descriptor for a primitive type.
Function * createFunction(const FunctionDecl *Def, Ts &&... Args)
Creates a new function from a code range.
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.
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
bool isLambdaCallOperator(const CXXMethodDecl *MD)
Describes a memory block created by an allocation site.
unsigned getAllocSize() const
Returns the allocated size, including metadata.
Information about a local's storage.