sun::codegen::abi::ExternCEmitter

sun::codegen::abi::ExternCEmitter

class · Source (opens in a new tab)

class sun::codegen::abi::ExternCEmitter

Binds 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) const

Whether 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) const

C'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) const

An 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) const

Attach 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) const

Creates 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) const

Load 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) const

Looks 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) const

Mirror 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.