From 5eccd90b47b327917ad0e5858c79ca8fab27cd74 Mon Sep 17 00:00:00 2001 From: _ov4 Date: Thu, 22 Oct 2026 13:51:44 +0000 Subject: feat(codegen): pass C-struct records by value as variadic arguments A variadic EXTERN call is now arranged by clang per call, from the fixed parameter count and the promoted argument types. C-struct records pass unchanged in variadic positions, as C11 6.5.2.2p6-7 and 7.16.1.1p2 allow; a record that is not a C struct names the offending field. Co-Authored-By: Claude Opus 5.5 --- include/cps/CodeGen.h | 10 +++++++--- include/cps/FunctionGen.h | 4 +++- 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/cps/CodeGen.h b/include/cps/CodeGen.h index 8f6a57b..b31cd3d 100644 --- a/include/cps/CodeGen.h +++ b/include/cps/CodeGen.h @@ -217,13 +217,17 @@ class CodeGen { llvm::Value *emitOperatorCall(const FuncSig &Signature, ExprAST *Left, ExprAST *Right = nullptr); llvm::Value *emitOperatorValues(const FuncSig &Signature, llvm::Value *Left, const TypeInfo *LeftType, llvm::Value *Right); - llvm::Value *emitVariadicArgument(ExprAST *Expr, const std::string &Callee, size_t Position); + llvm::Value *emitVariadicArgument(ExprAST *Expr, const std::string &Callee, size_t Position, + const TypeInfo *&Promoted); + // Variadic, if given, receives the promoted type of each variadic argument. bool marshalCallArgs(const FuncSig &Signature, const std::vector> &ArgExprs, int Line, - std::vector &Out); + std::vector &Out, + std::vector *Variadic = nullptr); bool marshalCallArgs(const FuncSig &Signature, const std::vector &ArgExprs, - int Line, std::vector &Out); + int Line, std::vector &Out, + std::vector *Variadic = nullptr); llvm::Value *symbolAddress(const SymbolInfo &Info); void emitAssignment(const LValueInfo &Target, ExprAST *Expr, const SymbolInfo *Symbol = nullptr); diff --git a/include/cps/FunctionGen.h b/include/cps/FunctionGen.h index 8b63d67..6c5c7c0 100644 --- a/include/cps/FunctionGen.h +++ b/include/cps/FunctionGen.h @@ -122,7 +122,9 @@ public: llvm::Function *emitFunctionDef(FunctionDefAST *FuncAST, const std::function &StmtEmitter, unsigned ScopeID); - llvm::Value *emitCall(const FuncSig &Sig, const std::vector &Args); + // Variadic holds the promoted types of an EXTERN call's variadic arguments. + llvm::Value *emitCall(const FuncSig &Sig, const std::vector &Args, + const std::vector &Variadic = {}); void emitReturn(llvm::Value *RetVal); }; -- cgit v1.3.1-4-g156e