sun::codegen::abi::ExternCEmitter
class · Source (opens in a new tab)
class sun::codegen::abi::ExternCEmitterBinds C-call emission to the current code-generation context and module.
Public Functions
ExternCEmitter
public · function · Source (opens in a new tab)
sun::codegen::abi::ExternCEmitter::ExternCEmitter(sun::codegen::CodegenContext &ctx, llvm::Module *module)Binds C-call emission to the current code-generation context and module.
Related: sun::codegen::CodegenContext
declare
public · function · Source (opens in a new tab)
llvm::Function * sun::codegen::abi::ExternCEmitter::declare(const sun::ast::PrototypeAST &proto, llvm::Type *returnType, llvm::ArrayRef< llvm::Type * > paramTypes)Declare a C function, applying the C ABI to its signature.
Idempotent: the block pre-pass declares externs up front so they can be called before their declaration appears, and function codegen reaches the same declaration again. Re-creating would give LLVM a uniqued name (abs.1) that no longer matches the C symbol.
Related: sun::ast::PrototypeAST
declareGlobal
public · function · Source (opens in a new tab)
llvm::GlobalVariable * sun::codegen::abi::ExternCEmitter::declareGlobal(const sun::ast::VariableCreationAST &variable, llvm::Type *valueType)Declare storage owned by a native C global.
Compatible repeated declarations return the same LLVM global.
Related: sun::ast::VariableCreationAST
emitCall
public · function · Source (opens in a new tab)
llvm::Value * sun::codegen::abi::ExternCEmitter::emitCall(llvm::Function *func, llvm::ArrayRef< PreparedArg > args, CallEmitter emitCallInsn)Marshal args per the C ABI and emit the call.
Returns the Sun-level result: an address for struct returns, the value otherwise.
Related: PreparedArg, CallEmitter
needsMarshalling
public · function · Source (opens in a new tab)
bool sun::codegen::abi::ExternCEmitter::needsMarshalling(const llvm::Function *func) constWhether calls to func must go through emitCall: true when its signature needed ABI rewriting, so its LLVM parameters no longer line up one-to-one with the Sun arguments.
promoteVararg
public · function · Source (opens in a new tab)
llvm::Value * sun::codegen::abi::ExternCEmitter::promoteVararg(llvm::Value *value, const TypePtr &sunType) constC's default argument promotions for a value in a ... tail: float widens to double, anything narrower than int widens to int, and a static_ptr fat pointer narrows to its data pointer.
Callees read these back with va_arg at the promoted width, so skipping them hands printf and friends the wrong bytes.
Related: TypePtr
Public Type Aliases
CallEmitter
public · typedef · Source (opens in a new tab)
using sun::codegen::abi::ExternCEmitter::CallEmitter = llvm::function_ref<llvm::Value*(
llvm::FunctionType*, llvm::Value*, llvm::ArrayRef<llvm::Value*>)>How the actual call instruction should be emitted.
Supplied by the caller so this class does not need to know about try blocks or invokes.
Private Functions
addressOf
private · function · Source (opens in a new tab)
llvm::Value * sun::codegen::abi::ExternCEmitter::addressOf(llvm::Value *value, llvm::Type *aggregateType) constAn address for value, spilling to a stack slot if it is a loaded struct, so its bytes can be reread in the shapes the ABI wants.
applyAttributes
private · function · Source (opens in a new tab)
void sun::codegen::abi::ExternCEmitter::applyAttributes(llvm::Function *func, const SignatureLowering &lowering) constAttach the byval/sret attributes a lowered signature requires.
Without them LLVM does not know the pointers refer to aggregates passed by value.
Related: SignatureLowering
entryAlloca
private · function · Source (opens in a new tab)
llvm::AllocaInst * sun::codegen::abi::ExternCEmitter::entryAlloca(llvm::Type *type, const char *name) constCreates temporary storage in the function entry block.
loadPiece
private · function · Source (opens in a new tab)
llvm::Value * sun::codegen::abi::ExternCEmitter::loadPiece(llvm::Value *aggregateAddr, llvm::Type *pieceType, uint64_t offset, uint64_t aggregateSize) constLoad one coerced register piece from the aggregate at aggregateAddr.
Bounces through a padded slot when the piece's type overhangs the aggregate's end (AAPCS64 reads a 12-byte struct as [2 x i64]).
loweringFor
private · function · Source (opens in a new tab)
const SignatureLowering * sun::codegen::abi::ExternCEmitter::loweringFor(const llvm::Function *func) constLooks up the C calling-convention rules recorded for a function.
Related: SignatureLowering
storePiece
private · function · Source (opens in a new tab)
void sun::codegen::abi::ExternCEmitter::storePiece(llvm::Value *piece, llvm::Value *aggregateAddr, uint64_t offset, uint64_t aggregateSize) constMirror of loadPiece for writing a returned piece back over the aggregate without touching memory past its end.
Private Fields
ctx_
private · variable · Source (opens in a new tab)
sun::codegen::CodegenContext& sun::codegen::abi::ExternCEmitter::ctx_No documentation comment.
Related: sun::codegen::CodegenContext
lowerings_
private · variable · Source (opens in a new tab)
std::map<std::string, SignatureLowering> sun::codegen::abi::ExternCEmitter::lowerings_Sun-side extern name -> C symbol.
Name resolution rewrites call sites through the Sun name, so this is where it becomes the real symbol. C symbol -> how its signature was lowered. Call sites need the same plan the declaration was built from; recomputing it independently would risk the two disagreeing.
Related: SignatureLowering
module_
private · variable · Source (opens in a new tab)
llvm::Module* sun::codegen::abi::ExternCEmitter::module_No documentation comment.