Browse Source

compiler: improve debug info to cover initialization

pull/36/head
Ayke van Laethem 6 years ago
parent
commit
5d2ffa79e5
No known key found for this signature in database GPG Key ID: E97FF5335DFDFDED
  1. 85
      compiler/compiler.go

85
compiler/compiler.go

@ -362,9 +362,15 @@ func (c *Compiler) Compile(mainPath string) error {
// After all packages are imported, add a synthetic initializer function
// that calls the initializer of each package.
initFn := c.mod.NamedFunction("runtime.initAll")
initFn.SetLinkage(llvm.InternalLinkage)
block := c.ctx.AddBasicBlock(initFn, "entry")
initFn := c.ir.GetFunction(c.ir.Program.ImportedPackage("runtime").Members["initAll"].(*ssa.Function))
initFn.LLVMFn.SetLinkage(llvm.InternalLinkage)
difunc, err := c.attachDebugInfo(initFn)
if err != nil {
return err
}
pos := c.ir.Program.Fset.Position(initFn.Pos())
c.builder.SetCurrentDebugLocation(uint(pos.Line), uint(pos.Column), difunc, llvm.Metadata{})
block := c.ctx.AddBasicBlock(initFn.LLVMFn, "entry")
c.builder.SetInsertPointAtEnd(block)
for _, fn := range c.initFuncs {
c.builder.CreateCall(fn, nil, "")
@ -811,44 +817,53 @@ func (c *Compiler) parseFuncDecl(f *ir.Function) (*Frame, error) {
if c.Debug && f.Syntax() != nil && len(f.Blocks) != 0 {
// Create debug info file if needed.
pos := c.ir.Program.Fset.Position(f.Syntax().Pos())
if _, ok := c.difiles[pos.Filename]; !ok {
dir, file := filepath.Split(pos.Filename)
c.difiles[pos.Filename] = c.dibuilder.CreateFile(file, dir[:len(dir)-1])
}
// Debug info for this function.
diparams := make([]llvm.Metadata, 0, len(f.Params))
for _, param := range f.Params {
ditype, err := c.getDIType(param.Type())
if err != nil {
return nil, err
}
diparams = append(diparams, ditype)
difunc, err := c.attachDebugInfo(f)
if err != nil {
return nil, err
}
diFuncType := c.dibuilder.CreateSubroutineType(llvm.DISubroutineType{
File: c.difiles[pos.Filename],
Parameters: diparams,
Flags: 0, // ?
})
frame.difunc = c.dibuilder.CreateFunction(c.difiles[pos.Filename], llvm.DIFunction{
Name: f.RelString(nil),
LinkageName: f.LinkName(),
File: c.difiles[pos.Filename],
Line: pos.Line,
Type: diFuncType,
LocalToUnit: true,
IsDefinition: true,
ScopeLine: 0,
Flags: llvm.FlagPrototyped,
Optimized: true,
})
frame.fn.LLVMFn.SetSubprogram(frame.difunc)
frame.difunc = difunc
}
return frame, nil
}
func (c *Compiler) attachDebugInfo(f *ir.Function) (llvm.Metadata, error) {
pos := c.ir.Program.Fset.Position(f.Syntax().Pos())
if _, ok := c.difiles[pos.Filename]; !ok {
dir, file := filepath.Split(pos.Filename)
c.difiles[pos.Filename] = c.dibuilder.CreateFile(file, dir[:len(dir)-1])
}
// Debug info for this function.
diparams := make([]llvm.Metadata, 0, len(f.Params))
for _, param := range f.Params {
ditype, err := c.getDIType(param.Type())
if err != nil {
return llvm.Metadata{}, err
}
diparams = append(diparams, ditype)
}
diFuncType := c.dibuilder.CreateSubroutineType(llvm.DISubroutineType{
File: c.difiles[pos.Filename],
Parameters: diparams,
Flags: 0, // ?
})
difunc := c.dibuilder.CreateFunction(c.difiles[pos.Filename], llvm.DIFunction{
Name: f.RelString(nil),
LinkageName: f.LinkName(),
File: c.difiles[pos.Filename],
Line: pos.Line,
Type: diFuncType,
LocalToUnit: true,
IsDefinition: true,
ScopeLine: 0,
Flags: llvm.FlagPrototyped,
Optimized: true,
})
f.LLVMFn.SetSubprogram(difunc)
return difunc, nil
}
// Create a new global hashmap bucket, for map initialization.
func (c *Compiler) initMapNewBucket(prefix string, mapType *types.Map) (llvm.Value, uint64, uint64, error) {
llvmKeyType, err := c.getLLVMType(mapType.Key().Underlying())

Loading…
Cancel
Save