// parseBasicBlock converts the provided LLVM IR basic block into a basic block // in which the instructions have been translated to Go AST statement nodes but // the terminator instruction is an unmodified LLVM IR value. func parseBasicBlock(llBB llvm.BasicBlock) (bb *basicBlock, err error) { name, err := getBBName(llBB.AsValue()) if err != nil { return nil, err } bb = &basicBlock{name: name, phis: make(map[string][]*definition)} for inst := llBB.FirstInstruction(); !inst.IsNil(); inst = llvm.NextInstruction(inst) { // Handle terminator instruction. if inst == llBB.LastInstruction() { err = bb.addTerm(inst) if err != nil { return nil, errutil.Err(err) } return bb, nil } // Handle PHI instructions. if inst.InstructionOpcode() == llvm.PHI { ident, def, err := parsePHIInst(inst) if err != nil { return nil, errutil.Err(err) } bb.phis[ident] = def continue } // Handle non-terminator instructions. stmt, err := parseInst(inst) if err != nil { return nil, err } bb.stmts = append(bb.stmts, stmt) } return nil, errutil.Newf("invalid basic block %q; contains no instructions", name) }