From 0928bc13137a7a44af1daaa4dfe50788fd89cbfd Mon Sep 17 00:00:00 2001 From: Robert Widmann Date: Wed, 29 Mar 2017 18:21:22 -0400 Subject: [PATCH] Model terminator instructions --- Sources/LLVM/BasicBlock.swift | 7 +++++++ Sources/LLVM/Instruction.swift | 27 +++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/Sources/LLVM/BasicBlock.swift b/Sources/LLVM/BasicBlock.swift index 63ee2121..a00b87ed 100644 --- a/Sources/LLVM/BasicBlock.swift +++ b/Sources/LLVM/BasicBlock.swift @@ -40,6 +40,13 @@ public struct BasicBlock: IRValue { return Instruction(llvm: val) } + /// Returns the terminator instruction if this basic block is well formed or + /// `nil` if it is not well formed. + public var terminator: TerminatorInstruction? { + guard let term = LLVMGetBasicBlockTerminator(llvm) else { return nil } + return TerminatorInstruction(llvm: term) + } + /// Returns the parent function of this basic block, if it exists. public var parent: Function? { guard let functionRef = LLVMGetBasicBlockParent(llvm) else { return nil } diff --git a/Sources/LLVM/Instruction.swift b/Sources/LLVM/Instruction.swift index 0d6c7bc1..4dbf10ad 100644 --- a/Sources/LLVM/Instruction.swift +++ b/Sources/LLVM/Instruction.swift @@ -51,3 +51,30 @@ public struct Instruction: IRValue { } } } + +/// A `TerminatorInstruction` represents an instruction that terminates a +/// basic block. +public struct TerminatorInstruction { + internal let llvm: LLVMValueRef + + /// Creates a `TerminatorInstruction` from an `LLVMValueRef` object. + public init(llvm: LLVMValueRef) { + self.llvm = llvm + } + + /// Retrieves the number of successors of this terminator instruction. + public var successorCount: Int { + return Int(LLVMGetNumSuccessors(llvm)) + } + + /// Returns the successor block at the specified index, if it exists. + public func getSuccessor(at idx: Int) -> BasicBlock? { + guard let succ = LLVMGetSuccessor(llvm, UInt32(idx)) else { return nil } + return BasicBlock(llvm: succ) + } + + /// Updates the successor block at the specified index. + public func setSuccessor(at idx: Int, to bb: BasicBlock) { + LLVMSetSuccessor(llvm, UInt32(idx), bb.asLLVM()) + } +}