createFunction builds the LLVM IR implementation for this function. The function must not yet be defined, otherwise this function will create a diagnostic.
()
| 1348 | // function must not yet be defined, otherwise this function will create a |
| 1349 | // diagnostic. |
| 1350 | func (b *builder) createFunction() { |
| 1351 | b.createFunctionStart(false) |
| 1352 | |
| 1353 | // Fill blocks with instructions. |
| 1354 | for _, block := range b.fn.DomPreorder() { |
| 1355 | if b.DumpSSA { |
| 1356 | fmt.Printf("%d: %s:\n", block.Index, block.Comment) |
| 1357 | } |
| 1358 | b.currentBlock = block |
| 1359 | b.currentBlockInfo = &b.blockInfo[block.Index] |
| 1360 | b.SetInsertPointAtEnd(b.currentBlockInfo.entry) |
| 1361 | for _, instr := range block.Instrs { |
| 1362 | if instr, ok := instr.(*ssa.DebugRef); ok { |
| 1363 | if !b.Debug { |
| 1364 | continue |
| 1365 | } |
| 1366 | object := instr.Object() |
| 1367 | variable, ok := object.(*types.Var) |
| 1368 | if !ok { |
| 1369 | // Not a local variable. |
| 1370 | continue |
| 1371 | } |
| 1372 | if instr.IsAddr { |
| 1373 | // TODO, this may happen for *ssa.Alloc and *ssa.FieldAddr |
| 1374 | // for example. |
| 1375 | continue |
| 1376 | } |
| 1377 | dbgVar := b.getLocalVariable(variable) |
| 1378 | pos := b.program.Fset.Position(instr.Pos()) |
| 1379 | b.dibuilder.InsertValueAtEnd(b.getValue(instr.X, getPos(instr)), dbgVar, b.dibuilder.CreateExpression(nil), llvm.DebugLoc{ |
| 1380 | Line: uint(pos.Line), |
| 1381 | Col: uint(pos.Column), |
| 1382 | Scope: b.difunc, |
| 1383 | }, b.GetInsertBlock()) |
| 1384 | continue |
| 1385 | } |
| 1386 | if b.DumpSSA { |
| 1387 | if val, ok := instr.(ssa.Value); ok && val.Name() != "" { |
| 1388 | fmt.Printf("\t%s = %s\n", val.Name(), val.String()) |
| 1389 | } else { |
| 1390 | fmt.Printf("\t%s\n", instr.String()) |
| 1391 | } |
| 1392 | } |
| 1393 | b.createInstruction(instr) |
| 1394 | } |
| 1395 | if b.fn.Name() == "init" && len(block.Instrs) == 0 { |
| 1396 | b.CreateRetVoid() |
| 1397 | } |
| 1398 | } |
| 1399 | |
| 1400 | // The rundefers instruction needs to be created after all defer |
| 1401 | // instructions have been created. Otherwise it won't handle all defer |
| 1402 | // cases. |
| 1403 | for i, bb := range b.runDefersBlock { |
| 1404 | b.SetInsertPointAtEnd(bb) |
| 1405 | b.createRunDefers() |
| 1406 | b.CreateBr(b.afterDefersBlock[i]) |
| 1407 | } |
no test coverage detected