Switch builds a switch statement.
(cases []SwitchCase, defaultCase func())
| 265 | |
| 266 | // Switch builds a switch statement. |
| 267 | func (b *Builder) Switch(cases []SwitchCase, defaultCase func()) { |
| 268 | tests := make([]llvm.BasicBlock, len(cases)) |
| 269 | blocks := make([]llvm.BasicBlock, len(cases)) |
| 270 | for i := range cases { |
| 271 | tests[i] = b.m.ctx.AddBasicBlock(b.function.llvm, fmt.Sprintf("switch_case_%d_test", i)) |
| 272 | blocks[i] = b.m.ctx.AddBasicBlock(b.function.llvm, fmt.Sprintf("switch_case_%d_block", i)) |
| 273 | } |
| 274 | |
| 275 | var defaultBlock llvm.BasicBlock |
| 276 | if defaultCase != nil { |
| 277 | defaultBlock = b.m.ctx.AddBasicBlock(b.function.llvm, "switch_case_default") |
| 278 | tests = append(tests, defaultBlock) |
| 279 | } |
| 280 | |
| 281 | exit := b.m.ctx.AddBasicBlock(b.function.llvm, "end_switch") |
| 282 | |
| 283 | b.llvm.CreateBr(tests[0]) |
| 284 | |
| 285 | for i, c := range cases { |
| 286 | i, c := i, c |
| 287 | b.block(tests[i], llvm.BasicBlock{}, func() { |
| 288 | conds := c.Conditions() |
| 289 | match := conds[0] |
| 290 | for _, c := range conds[1:] { |
| 291 | match = b.Or(match, c) |
| 292 | } |
| 293 | next := exit |
| 294 | if i+1 < len(tests) { |
| 295 | next = tests[i+1] |
| 296 | } |
| 297 | b.llvm.CreateCondBr(match.llvm, blocks[i], next) |
| 298 | }) |
| 299 | b.block(blocks[i], exit, c.Block) |
| 300 | } |
| 301 | |
| 302 | if defaultCase != nil { |
| 303 | b.block(defaultBlock, exit, defaultCase) |
| 304 | } |
| 305 | |
| 306 | b.setInsertPointAtEnd(exit) |
| 307 | } |
| 308 | |
| 309 | // Return returns execution of the function with the given value |
| 310 | func (b *Builder) Return(val *Value) { |
nothing calls this directly
no test coverage detected