compiler: improve debug info to cover initialization
Этот коммит содержится в:
родитель
f2768bee17
коммит
5d2ffa79e5
1 изменённых файлов: 50 добавлений и 35 удалений
|
@ -362,9 +362,15 @@ func (c *Compiler) Compile(mainPath string) error {
|
||||||
|
|
||||||
// After all packages are imported, add a synthetic initializer function
|
// After all packages are imported, add a synthetic initializer function
|
||||||
// that calls the initializer of each package.
|
// that calls the initializer of each package.
|
||||||
initFn := c.mod.NamedFunction("runtime.initAll")
|
initFn := c.ir.GetFunction(c.ir.Program.ImportedPackage("runtime").Members["initAll"].(*ssa.Function))
|
||||||
initFn.SetLinkage(llvm.InternalLinkage)
|
initFn.LLVMFn.SetLinkage(llvm.InternalLinkage)
|
||||||
block := c.ctx.AddBasicBlock(initFn, "entry")
|
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)
|
c.builder.SetInsertPointAtEnd(block)
|
||||||
for _, fn := range c.initFuncs {
|
for _, fn := range c.initFuncs {
|
||||||
c.builder.CreateCall(fn, nil, "")
|
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 {
|
if c.Debug && f.Syntax() != nil && len(f.Blocks) != 0 {
|
||||||
// Create debug info file if needed.
|
// Create debug info file if needed.
|
||||||
pos := c.ir.Program.Fset.Position(f.Syntax().Pos())
|
difunc, err := c.attachDebugInfo(f)
|
||||||
if _, ok := c.difiles[pos.Filename]; !ok {
|
if err != nil {
|
||||||
dir, file := filepath.Split(pos.Filename)
|
return nil, err
|
||||||
c.difiles[pos.Filename] = c.dibuilder.CreateFile(file, dir[:len(dir)-1])
|
|
||||||
}
|
}
|
||||||
|
frame.difunc = difunc
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return frame, nil
|
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.
|
// Create a new global hashmap bucket, for map initialization.
|
||||||
func (c *Compiler) initMapNewBucket(prefix string, mapType *types.Map) (llvm.Value, uint64, uint64, error) {
|
func (c *Compiler) initMapNewBucket(prefix string, mapType *types.Map) (llvm.Value, uint64, uint64, error) {
|
||||||
llvmKeyType, err := c.getLLVMType(mapType.Key().Underlying())
|
llvmKeyType, err := c.getLLVMType(mapType.Key().Underlying())
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче