Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions Sources/LLVM/Call.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#if !NO_SWIFTPM
import cllvm
#endif

/// Represents a simple function call.
public struct Call: IRValue {
let llvm: LLVMValueRef

/// Retrieves the underlying LLVM value object.
public func asLLVM() -> LLVMValueRef {
return self.llvm
}

/// Retrieves the number of argument operands passed by this call.
public var argumentCount: Int {
return Int(LLVMGetNumArgOperands(self.llvm))
}

/// Accesses the calling convention for this function call.
public var callingConvention: CallingConvention {
get { return CallingConvention(rawValue: LLVMGetInstructionCallConv(self.llvm))! }
set { LLVMSetInstructionCallConv(self.llvm, newValue.rawValue) }
}

/// Returns whether this function call is a tail call. That is, if the callee
/// may reuse the stack memory of the caller.
///
/// This attribute requires support from the target architecture.
public var isTailCall: Bool {
get { return LLVMIsTailCall(self.llvm) != 0 }
set { LLVMSetTailCall(self.llvm, newValue.llvm) }
}

/// Retrieves the alignment of the parameter at the given index.
///
/// This property is currently set-only due to limitations of the LLVM C API.
///
/// - parameter i: The index of the parameter to retrieve.
/// - parameter alignment: The alignment to apply to the parameter.
public func setParameterAlignment(at i : Int, to alignment: Int) {
LLVMSetInstrParamAlignment(self.llvm, UInt32(i), UInt32(alignment))
}
}

/// Represents a function call that may transfer control to an exception handler.
public struct Invoke: IRValue {
let llvm: LLVMValueRef

/// Retrieves the underlying LLVM value object.
public func asLLVM() -> LLVMValueRef {
return self.llvm
}

/// Accesses the destination block the flow of control will transfer to if an
/// exception does not occur.
public var normalDestination: BasicBlock {
get { return BasicBlock(llvm: LLVMGetNormalDest(self.llvm)) }
set { LLVMSetNormalDest(self.llvm, newValue.asLLVM()) }
}

/// Accesses the destination block that exception unwinding will jump to.
public var unwindDestination: BasicBlock {
get { return BasicBlock(llvm: LLVMGetUnwindDest(self.llvm)) }
set { LLVMSetUnwindDest(self.llvm, newValue.asLLVM()) }
}
}
8 changes: 4 additions & 4 deletions Sources/LLVM/IRBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -965,10 +965,10 @@ public class IRBuilder {
/// - parameter name: The name for the newly inserted instruction.
///
/// - returns: A value representing the result of returning from the callee.
public func buildCall(_ fn: IRValue, args: [IRValue], name: String = "") -> IRValue {
public func buildCall(_ fn: IRValue, args: [IRValue], name: String = "") -> Call {
var args = args.map { $0.asLLVM() as Optional }
return args.withUnsafeMutableBufferPointer { buf in
return LLVMBuildCall(llvm, fn.asLLVM(), buf.baseAddress!, UInt32(buf.count), name)
return Call(llvm: LLVMBuildCall(llvm, fn.asLLVM(), buf.baseAddress!, UInt32(buf.count), name))
}
}

Expand All @@ -994,12 +994,12 @@ public class IRBuilder {
/// - returns: A value representing the result of returning from the callee
/// under normal circumstances. Under exceptional circumstances, the value
/// represents the value of any `resume` instruction in the `catch` block.
public func buildInvoke(_ fn: IRValue, args: [IRValue], next: BasicBlock, catch: BasicBlock, name: String = "") -> IRValue {
public func buildInvoke(_ fn: IRValue, args: [IRValue], next: BasicBlock, catch: BasicBlock, name: String = "") -> Invoke {
precondition(`catch`.firstInstruction!.opCode == .landingPad, "First instruction of catch block must be a landing pad")

var args = args.map { $0.asLLVM() as Optional }
return args.withUnsafeMutableBufferPointer { buf in
return LLVMBuildInvoke(llvm, fn.asLLVM(), buf.baseAddress!, UInt32(buf.count), next.llvm, `catch`.llvm, name)
return Invoke(llvm: LLVMBuildInvoke(llvm, fn.asLLVM(), buf.baseAddress!, UInt32(buf.count), next.llvm, `catch`.llvm, name))
}
}

Expand Down