//===- debug.go - debug info builder --------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This package builds LLVM debug info from go/* data structures.
//
//===----------------------------------------------------------------------===//

package debug

import (
	"debug/dwarf"
	"fmt"
	"go/token"
	"os"
	"strings"

	"llvm.org/llgo/third_party/go.tools/go/ssa"
	"llvm.org/llgo/third_party/go.tools/go/types"
	"llvm.org/llgo/third_party/go.tools/go/types/typeutil"

	"llvm.org/llvm/bindings/go/llvm"
)

const (
	// non-standard debug metadata tags
	tagAutoVariable dwarf.Tag = 0x100
	tagArgVariable  dwarf.Tag = 0x101
)

type PrefixMap struct {
	Source, Replacement string
}

// DIBuilder builds debug metadata for Go programs.
type DIBuilder struct {
	// builder is the current builder; there is one per CU.
	builder    *llvm.DIBuilder
	module     llvm.Module
	files      map[*token.File]llvm.Metadata
	cu, fn, lb llvm.Metadata
	fnFile     string
	sizes      types.Sizes
	fset       *token.FileSet
	prefixMaps []PrefixMap
	types      typeutil.Map
	voidType   llvm.Metadata
}

// NewDIBuilder creates a new debug information builder.
func NewDIBuilder(sizes types.Sizes, module llvm.Module, fset *token.FileSet, prefixMaps []PrefixMap) *DIBuilder {
	var d DIBuilder
	d.module = module
	d.files = make(map[*token.File]llvm.Metadata)
	d.sizes = sizes
	d.fset = fset
	d.prefixMaps = prefixMaps
	d.builder = llvm.NewDIBuilder(d.module)
	d.cu = d.createCompileUnit()
	return &d
}

// Destroy destroys the DIBuilder.
func (d *DIBuilder) Destroy() {
	d.builder.Destroy()
}

func (d *DIBuilder) scope() llvm.Metadata {
	if d.lb.C != nil {
		return d.lb
	}
	if d.fn.C != nil {
		return d.fn
	}
	return d.cu
}

func (d *DIBuilder) remapFilePath(path string) string {
	for _, pm := range d.prefixMaps {
		if strings.HasPrefix(path, pm.Source) {
			return pm.Replacement + path[len(pm.Source):]
		}
	}
	return path
}

func (d *DIBuilder) getFile(file *token.File) llvm.Metadata {
	if diFile := d.files[file]; diFile.C != nil {
		return diFile
	}
	diFile := d.builder.CreateFile(d.remapFilePath(file.Name()), "")
	d.files[file] = diFile
	return diFile
}

// createCompileUnit creates and returns debug metadata for the compile
// unit as a whole, using the first file in the file set as a representative
// (the choice of file is arbitrary).
func (d *DIBuilder) createCompileUnit() llvm.Metadata {
	var file *token.File
	d.fset.Iterate(func(f *token.File) bool {
		file = f
		return false
	})
	dir, err := os.Getwd()
	if err != nil {
		panic("could not get current directory: " + err.Error())
	}
	return d.builder.CreateCompileUnit(llvm.DICompileUnit{
		Language: llvm.DW_LANG_Go,
		File:     d.remapFilePath(file.Name()),
		Dir:      dir,
		Producer: "llgo",
	})
}

// PushFunction creates debug metadata for the specified function,
// and pushes it onto the scope stack.
func (d *DIBuilder) PushFunction(fnptr llvm.Value, sig *types.Signature, pos token.Pos) {
	var diFile llvm.Metadata
	var line int
	if file := d.fset.File(pos); file != nil {
		d.fnFile = file.Name()
		diFile = d.getFile(file)
		line = file.Line(pos)
	}
	d.fn = d.builder.CreateFunction(d.scope(), llvm.DIFunction{
		Name:         fnptr.Name(), // TODO(axw) unmangled name?
		LinkageName:  fnptr.Name(),
		File:         diFile,
		Line:         line,
		Type:         d.DIType(sig),
		IsDefinition: true,
		Function:     fnptr,
	})
}

// PopFunction pops the previously pushed function off the scope stack.
func (d *DIBuilder) PopFunction() {
	d.lb = llvm.Metadata{}
	d.fn = llvm.Metadata{}
	d.fnFile = ""
}

// Declare creates an llvm.dbg.declare call for the specified function
// parameter or local variable.
func (d *DIBuilder) Declare(b llvm.Builder, v ssa.Value, llv llvm.Value, paramIndex int) {
	tag := tagAutoVariable
	if paramIndex >= 0 {
		tag = tagArgVariable
	}
	var diFile llvm.Metadata
	var line int
	if file := d.fset.File(v.Pos()); file != nil {
		line = file.Line(v.Pos())
		diFile = d.getFile(file)
	}
	localVar := d.builder.CreateLocalVariable(d.scope(), llvm.DILocalVariable{
		Tag:   tag,
		Name:  llv.Name(),
		File:  diFile,
		Line:  line,
		ArgNo: paramIndex + 1,
		Type:  d.DIType(v.Type()),
	})
	expr := d.builder.CreateExpression(nil)
	d.builder.InsertDeclareAtEnd(llv, localVar, expr, b.GetInsertBlock())
}

// Value creates an llvm.dbg.value call for the specified register value.
func (d *DIBuilder) Value(b llvm.Builder, v ssa.Value, llv llvm.Value, paramIndex int) {
	// TODO(axw)
}

// SetLocation sets the current debug location.
func (d *DIBuilder) SetLocation(b llvm.Builder, pos token.Pos) {
	if !pos.IsValid() {
		return
	}
	position := d.fset.Position(pos)
	d.lb = llvm.Metadata{}
	if position.Filename != d.fnFile && position.Filename != "" {
		// This can happen rarely, e.g. in init functions.
		diFile := d.builder.CreateFile(d.remapFilePath(position.Filename), "")
		d.lb = d.builder.CreateLexicalBlockFile(d.scope(), diFile, 0)
	}
	b.SetCurrentDebugLocation(uint(position.Line), uint(position.Column), d.scope(), llvm.Metadata{})
}

// Finalize must be called after all compilation units are translated,
// generating the final debug metadata for the module.
func (d *DIBuilder) Finalize() {
	d.module.AddNamedMetadataOperand(
		"llvm.module.flags",
		llvm.GlobalContext().MDNode([]llvm.Metadata{
			llvm.ConstInt(llvm.Int32Type(), 2, false).ConstantAsMetadata(), // Warn on mismatch
			llvm.GlobalContext().MDString("Dwarf Version"),
			llvm.ConstInt(llvm.Int32Type(), 4, false).ConstantAsMetadata(),
		}),
	)
	d.module.AddNamedMetadataOperand(
		"llvm.module.flags",
		llvm.GlobalContext().MDNode([]llvm.Metadata{
			llvm.ConstInt(llvm.Int32Type(), 1, false).ConstantAsMetadata(), // Error on mismatch
			llvm.GlobalContext().MDString("Debug Info Version"),
			llvm.ConstInt(llvm.Int32Type(), 2, false).ConstantAsMetadata(),
		}),
	)
	d.builder.Finalize()
}

// DIType maps a Go type to DIType debug metadata value.
func (d *DIBuilder) DIType(t types.Type) llvm.Metadata {
	return d.typeDebugDescriptor(t, types.TypeString(nil, t))
}

func (d *DIBuilder) typeDebugDescriptor(t types.Type, name string) llvm.Metadata {
	// Signature needs to be handled specially, to preprocess
	// methods, moving the receiver to the parameter list.
	if t, ok := t.(*types.Signature); ok {
		return d.descriptorSignature(t, name)
	}
	if t == nil {
		if d.voidType.C == nil {
			d.voidType = d.builder.CreateBasicType(llvm.DIBasicType{Name: "void"})
		}
		return d.voidType
	}
	if dt, ok := d.types.At(t).(llvm.Metadata); ok {
		return dt
	}
	dt := d.descriptor(t, name)
	d.types.Set(t, dt)
	return dt
}

func (d *DIBuilder) descriptor(t types.Type, name string) llvm.Metadata {
	switch t := t.(type) {
	case *types.Basic:
		return d.descriptorBasic(t, name)
	case *types.Pointer:
		return d.descriptorPointer(t)
	case *types.Struct:
		return d.descriptorStruct(t, name)
	case *types.Named:
		return d.descriptorNamed(t)
	case *types.Array:
		return d.descriptorArray(t, name)
	case *types.Slice:
		return d.descriptorSlice(t, name)
	case *types.Map:
		return d.descriptorMap(t, name)
	case *types.Chan:
		return d.descriptorChan(t, name)
	case *types.Interface:
		return d.descriptorInterface(t, name)
	default:
		panic(fmt.Sprintf("unhandled type: %T", t))
	}
}

func (d *DIBuilder) descriptorBasic(t *types.Basic, name string) llvm.Metadata {
	switch t.Kind() {
	case types.String:
		return d.typeDebugDescriptor(types.NewStruct([]*types.Var{
			types.NewVar(0, nil, "ptr", types.NewPointer(types.Typ[types.Uint8])),
			types.NewVar(0, nil, "len", types.Typ[types.Int]),
		}, nil), name)
	case types.UnsafePointer:
		return d.builder.CreateBasicType(llvm.DIBasicType{
			Name:        name,
			SizeInBits:  uint64(d.sizes.Sizeof(t) * 8),
			AlignInBits: uint64(d.sizes.Alignof(t) * 8),
			Encoding:    llvm.DW_ATE_unsigned,
		})
	default:
		bt := llvm.DIBasicType{
			Name:        t.String(),
			SizeInBits:  uint64(d.sizes.Sizeof(t) * 8),
			AlignInBits: uint64(d.sizes.Alignof(t) * 8),
		}
		switch bi := t.Info(); {
		case bi&types.IsBoolean != 0:
			bt.Encoding = llvm.DW_ATE_boolean
		case bi&types.IsUnsigned != 0:
			bt.Encoding = llvm.DW_ATE_unsigned
		case bi&types.IsInteger != 0:
			bt.Encoding = llvm.DW_ATE_signed
		case bi&types.IsFloat != 0:
			bt.Encoding = llvm.DW_ATE_float
		case bi&types.IsComplex != 0:
			bt.Encoding = llvm.DW_ATE_imaginary_float
		case bi&types.IsUnsigned != 0:
			bt.Encoding = llvm.DW_ATE_unsigned
		default:
			panic(fmt.Sprintf("unhandled: %#v", t))
		}
		return d.builder.CreateBasicType(bt)
	}
}

func (d *DIBuilder) descriptorPointer(t *types.Pointer) llvm.Metadata {
	return d.builder.CreatePointerType(llvm.DIPointerType{
		Pointee:     d.DIType(t.Elem()),
		SizeInBits:  uint64(d.sizes.Sizeof(t) * 8),
		AlignInBits: uint64(d.sizes.Alignof(t) * 8),
	})
}

func (d *DIBuilder) descriptorStruct(t *types.Struct, name string) llvm.Metadata {
	fields := make([]*types.Var, t.NumFields())
	for i := range fields {
		fields[i] = t.Field(i)
	}
	offsets := d.sizes.Offsetsof(fields)
	members := make([]llvm.Metadata, len(fields))
	for i, f := range fields {
		// TODO(axw) file/line where member is defined.
		t := f.Type()
		members[i] = d.builder.CreateMemberType(d.cu, llvm.DIMemberType{
			Name:         f.Name(),
			Type:         d.DIType(t),
			SizeInBits:   uint64(d.sizes.Sizeof(t) * 8),
			AlignInBits:  uint64(d.sizes.Alignof(t) * 8),
			OffsetInBits: uint64(offsets[i] * 8),
		})
	}
	// TODO(axw) file/line where struct is defined.
	return d.builder.CreateStructType(d.cu, llvm.DIStructType{
		Name:        name,
		SizeInBits:  uint64(d.sizes.Sizeof(t) * 8),
		AlignInBits: uint64(d.sizes.Alignof(t) * 8),
		Elements:    members,
	})
}

func (d *DIBuilder) descriptorNamed(t *types.Named) llvm.Metadata {
	// Create a placeholder for the named type, to terminate cycles.
	placeholder := llvm.GlobalContext().TemporaryMDNode(nil)
	d.types.Set(t, placeholder)
	var diFile llvm.Metadata
	var line int
	if file := d.fset.File(t.Obj().Pos()); file != nil {
		line = file.Line(t.Obj().Pos())
		diFile = d.getFile(file)
	}
	typedef := d.builder.CreateTypedef(llvm.DITypedef{
		Type: d.DIType(t.Underlying()),
		Name: t.Obj().Name(),
		File: diFile,
		Line: line,
	})
	placeholder.ReplaceAllUsesWith(typedef)
	return typedef
}

func (d *DIBuilder) descriptorArray(t *types.Array, name string) llvm.Metadata {
	return d.builder.CreateArrayType(llvm.DIArrayType{
		SizeInBits:  uint64(d.sizes.Sizeof(t) * 8),
		AlignInBits: uint64(d.sizes.Alignof(t) * 8),
		ElementType: d.DIType(t.Elem()),
		Subscripts:  []llvm.DISubrange{{Count: t.Len()}},
	})
}

func (d *DIBuilder) descriptorSlice(t *types.Slice, name string) llvm.Metadata {
	sliceStruct := types.NewStruct([]*types.Var{
		types.NewVar(0, nil, "ptr", types.NewPointer(t.Elem())),
		types.NewVar(0, nil, "len", types.Typ[types.Int]),
		types.NewVar(0, nil, "cap", types.Typ[types.Int]),
	}, nil)
	return d.typeDebugDescriptor(sliceStruct, name)
}

func (d *DIBuilder) descriptorMap(t *types.Map, name string) llvm.Metadata {
	// FIXME: This should be DW_TAG_pointer_type to __go_map.
	return d.descriptorBasic(types.Typ[types.Uintptr], name)
}

func (d *DIBuilder) descriptorChan(t *types.Chan, name string) llvm.Metadata {
	// FIXME: This should be DW_TAG_pointer_type to __go_channel.
	return d.descriptorBasic(types.Typ[types.Uintptr], name)
}

func (d *DIBuilder) descriptorInterface(t *types.Interface, name string) llvm.Metadata {
	ifaceStruct := types.NewStruct([]*types.Var{
		types.NewVar(0, nil, "type", types.NewPointer(types.Typ[types.Uint8])),
		types.NewVar(0, nil, "data", types.NewPointer(types.Typ[types.Uint8])),
	}, nil)
	return d.typeDebugDescriptor(ifaceStruct, name)
}

func (d *DIBuilder) descriptorSignature(t *types.Signature, name string) llvm.Metadata {
	// If there's a receiver change the receiver to an
	// additional (first) parameter, and take the value of
	// the resulting signature instead.
	if recv := t.Recv(); recv != nil {
		params := t.Params()
		paramvars := make([]*types.Var, int(params.Len()+1))
		paramvars[0] = recv
		for i := 0; i < int(params.Len()); i++ {
			paramvars[i+1] = params.At(i)
		}
		params = types.NewTuple(paramvars...)
		t := types.NewSignature(nil, nil, params, t.Results(), t.Variadic())
		return d.typeDebugDescriptor(t, name)
	}
	if dt, ok := d.types.At(t).(llvm.Metadata); ok {
		return dt
	}

	var returnType llvm.Metadata
	results := t.Results()
	switch n := results.Len(); n {
	case 0:
		returnType = d.DIType(nil) // void
	case 1:
		returnType = d.DIType(results.At(0).Type())
	default:
		fields := make([]*types.Var, results.Len())
		for i := range fields {
			f := results.At(i)
			// Structs may not have multiple fields
			// with the same name, excepting "_".
			if f.Name() == "" {
				f = types.NewVar(f.Pos(), f.Pkg(), "_", f.Type())
			}
			fields[i] = f
		}
		returnType = d.typeDebugDescriptor(types.NewStruct(fields, nil), "")
	}

	var paramTypes []llvm.Metadata
	params := t.Params()
	if params != nil && params.Len() > 0 {
		paramTypes = make([]llvm.Metadata, params.Len()+1)
		paramTypes[0] = returnType
		for i := range paramTypes[1:] {
			paramTypes[i+1] = d.DIType(params.At(i).Type())
		}
	} else {
		paramTypes = []llvm.Metadata{returnType}
	}

	// TODO(axw) get position of type definition for File field
	return d.builder.CreateSubroutineType(llvm.DISubroutineType{
		Parameters: paramTypes,
	})
}
