// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gc

import (
	"cmd/internal/dwarf"
	"cmd/internal/obj"
	"cmd/internal/src"
	"sort"
	"strings"
)

// To identify variables by original source position.
type varPos struct {
	DeclName string
	DeclFile string
	DeclLine uint
	DeclCol  uint
}

// This is the main entry point for collection of raw material to
// drive generation of DWARF "inlined subroutine" DIEs. See proposal
// 22080 for more details and background info.
func assembleInlines(fnsym *obj.LSym, fn *Node, dwVars []*dwarf.Var) dwarf.InlCalls {
	var inlcalls dwarf.InlCalls

	if Debug_gendwarfinl != 0 {
		Ctxt.Logf("assembling DWARF inlined routine info for %v\n", fnsym.Name)
	}

	// This maps inline index (from Ctxt.InlTree) to index in inlcalls.Calls
	imap := make(map[int]int)

	// Walk progs to build up the InlCalls data structure
	var prevpos src.XPos
	for p := fnsym.Func.Text; p != nil; p = p.Link {
		if p.Pos == prevpos {
			continue
		}
		ii := posInlIndex(p.Pos)
		if ii >= 0 {
			insertInlCall(&inlcalls, ii, imap)
		}
		prevpos = p.Pos
	}

	// This is used to partition DWARF vars by inline index. Vars not
	// produced by the inliner will wind up in the vmap[0] entry.
	vmap := make(map[int32][]*dwarf.Var)

	// Now walk the dwarf vars and partition them based on whether they
	// were produced by the inliner (dwv.InlIndex > 0) or were original
	// vars/params from the function (dwv.InlIndex == 0).
	for _, dwv := range dwVars {

		vmap[dwv.InlIndex] = append(vmap[dwv.InlIndex], dwv)

		// Zero index => var was not produced by an inline
		if dwv.InlIndex == 0 {
			continue
		}

		// Look up index in our map, then tack the var in question
		// onto the vars list for the correct inlined call.
		ii := int(dwv.InlIndex) - 1
		idx, ok := imap[ii]
		if !ok {
			// We can occasionally encounter a var produced by the
			// inliner for which there is no remaining prog; add a new
			// entry to the call list in this scenario.
			idx = insertInlCall(&inlcalls, ii, imap)
		}
		inlcalls.Calls[idx].InlVars =
			append(inlcalls.Calls[idx].InlVars, dwv)
	}

	// Post process the map above to assign child indices to vars.
	//
	// A given variable is treated differently depending on whether it
	// is part of the top-level function (ii == 0) or if it was
	// produced as a result of an inline (ii != 0).
	//
	// If a variable was not produced by an inline and its containing
	// function was not inlined, then we just assign an ordering of
	// based on variable name.
	//
	// If a variable was not produced by an inline and its containing
	// function was inlined, then we need to assign a child index
	// based on the order of vars in the abstract function (in
	// addition, those vars that don't appear in the abstract
	// function, such as "~r1", are flagged as such).
	//
	// If a variable was produced by an inline, then we locate it in
	// the pre-inlining decls for the target function and assign child
	// index accordingly.
	for ii, sl := range vmap {
		sort.Sort(byClassThenName(sl))
		var m map[varPos]int
		if ii == 0 {
			if !fnsym.WasInlined() {
				for j := 0; j < len(sl); j++ {
					sl[j].ChildIndex = int32(j)
				}
				continue
			}
			m = makePreinlineDclMap(fnsym)
		} else {
			ifnlsym := Ctxt.InlTree.InlinedFunction(int(ii - 1))
			m = makePreinlineDclMap(ifnlsym)
		}

		// Here we assign child indices to variables based on
		// pre-inlined decls, and set the "IsInAbstract" flag
		// appropriately. In addition: parameter and local variable
		// names are given "middle dot" version numbers as part of the
		// writing them out to export data (see issue 4326). If DWARF
		// inlined routine generation is turned on, we want to undo
		// this versioning, since DWARF variables in question will be
		// parented by the inlined routine and not the top-level
		// caller.
		synthCount := len(m)
		for j := 0; j < len(sl); j++ {
			canonName := unversion(sl[j].Name)
			vp := varPos{
				DeclName: canonName,
				DeclFile: sl[j].DeclFile,
				DeclLine: sl[j].DeclLine,
				DeclCol:  sl[j].DeclCol,
			}
			synthesized := strings.HasPrefix(sl[j].Name, "~r") || canonName == "_"
			if idx, found := m[vp]; found {
				sl[j].ChildIndex = int32(idx)
				sl[j].IsInAbstract = !synthesized
				sl[j].Name = canonName
			} else {
				// Variable can't be found in the pre-inline dcl list.
				// In the top-level case (ii=0) this can happen
				// because a composite variable was split into pieces,
				// and we're looking at a piece. We can also see
				// return temps (~r%d) that were created during
				// lowering, or unnamed params ("_").
				sl[j].ChildIndex = int32(synthCount)
				synthCount += 1
			}
		}
	}

	// Make a second pass through the progs to compute PC ranges for
	// the various inlined calls.
	curii := -1
	var crange *dwarf.Range
	var prevp *obj.Prog
	for p := fnsym.Func.Text; p != nil; prevp, p = p, p.Link {
		if prevp != nil && p.Pos == prevp.Pos {
			continue
		}
		ii := posInlIndex(p.Pos)
		if ii == curii {
			continue
		} else {
			// Close out the current range
			endRange(crange, prevp)

			// Begin new range
			crange = beginRange(inlcalls.Calls, p, ii, imap)
			curii = ii
		}
	}
	if prevp != nil {
		endRange(crange, prevp)
	}

	// Debugging
	if Debug_gendwarfinl != 0 {
		dumpInlCalls(inlcalls)
		dumpInlVars(dwVars)
	}

	return inlcalls
}

// Secondary hook for DWARF inlined subroutine generation. This is called
// late in the compilation when it is determined that we need an
// abstract function DIE for an inlined routine imported from a
// previously compiled package.
func genAbstractFunc(fn *obj.LSym) {
	ifn := Ctxt.DwFixups.GetPrecursorFunc(fn)
	if ifn == nil {
		Ctxt.Diag("failed to locate precursor fn for %v", fn)
		return
	}
	if Debug_gendwarfinl != 0 {
		Ctxt.Logf("DwarfAbstractFunc(%v)\n", fn.Name)
	}
	Ctxt.DwarfAbstractFunc(ifn, fn, myimportpath)
}

// Undo any versioning performed when a name was written
// out as part of export data.
func unversion(name string) string {
	if i := strings.Index(name, "·"); i > 0 {
		name = name[:i]
	}
	return name
}

// Given a function that was inlined as part of the compilation, dig
// up the pre-inlining DCL list for the function and create a map that
// supports lookup of pre-inline dcl index, based on variable
// position/name.
func makePreinlineDclMap(fnsym *obj.LSym) map[varPos]int {
	dcl := preInliningDcls(fnsym)
	m := make(map[varPos]int)
	for i := 0; i < len(dcl); i++ {
		n := dcl[i]
		pos := Ctxt.InnermostPos(n.Pos)
		vp := varPos{
			DeclName: unversion(n.Sym.Name),
			DeclFile: pos.Base().SymFilename(),
			DeclLine: pos.Line(),
			DeclCol:  pos.Col(),
		}
		if _, found := m[vp]; found {
			Fatalf("child dcl collision on symbol %s within %v\n", n.Sym.Name, fnsym.Name)
		}
		m[vp] = i
	}
	return m
}

func insertInlCall(dwcalls *dwarf.InlCalls, inlIdx int, imap map[int]int) int {
	callIdx, found := imap[inlIdx]
	if found {
		return callIdx
	}

	// Haven't seen this inline yet. Visit parent of inline if there
	// is one. We do this first so that parents appear before their
	// children in the resulting table.
	parCallIdx := -1
	parInlIdx := Ctxt.InlTree.Parent(inlIdx)
	if parInlIdx >= 0 {
		parCallIdx = insertInlCall(dwcalls, parInlIdx, imap)
	}

	// Create new entry for this inline
	inlinedFn := Ctxt.InlTree.InlinedFunction(int(inlIdx))
	callXPos := Ctxt.InlTree.CallPos(int(inlIdx))
	absFnSym := Ctxt.DwFixups.AbsFuncDwarfSym(inlinedFn)
	pb := Ctxt.PosTable.Pos(callXPos).Base()
	callFileSym := Ctxt.Lookup(pb.SymFilename())
	ic := dwarf.InlCall{
		InlIndex:  inlIdx,
		CallFile:  callFileSym,
		CallLine:  uint32(callXPos.Line()),
		AbsFunSym: absFnSym,
		Root:      parCallIdx == -1,
	}
	dwcalls.Calls = append(dwcalls.Calls, ic)
	callIdx = len(dwcalls.Calls) - 1
	imap[inlIdx] = callIdx

	if parCallIdx != -1 {
		// Add this inline to parent's child list
		dwcalls.Calls[parCallIdx].Children = append(dwcalls.Calls[parCallIdx].Children, callIdx)
	}

	return callIdx
}

// Given a src.XPos, return its associated inlining index if it
// corresponds to something created as a result of an inline, or -1 if
// there is no inline info. Note that the index returned will refer to
// the deepest call in the inlined stack, e.g. if you have "A calls B
// calls C calls D" and all three callees are inlined (B, C, and D),
// the index for a node from the inlined body of D will refer to the
// call to D from C. Whew.
func posInlIndex(xpos src.XPos) int {
	pos := Ctxt.PosTable.Pos(xpos)
	if b := pos.Base(); b != nil {
		ii := b.InliningIndex()
		if ii >= 0 {
			return ii
		}
	}
	return -1
}

func endRange(crange *dwarf.Range, p *obj.Prog) {
	if crange == nil {
		return
	}
	crange.End = p.Pc
}

func beginRange(calls []dwarf.InlCall, p *obj.Prog, ii int, imap map[int]int) *dwarf.Range {
	if ii == -1 {
		return nil
	}
	callIdx, found := imap[ii]
	if !found {
		Fatalf("internal error: can't find inlIndex %d in imap for prog at %d\n", ii, p.Pc)
	}
	call := &calls[callIdx]

	// Set up range and append to correct inlined call
	call.Ranges = append(call.Ranges, dwarf.Range{Start: p.Pc, End: -1})
	return &call.Ranges[len(call.Ranges)-1]
}

func cmpDwarfVar(a, b *dwarf.Var) bool {
	// named before artificial
	aart := 0
	if strings.HasPrefix(a.Name, "~r") {
		aart = 1
	}
	bart := 0
	if strings.HasPrefix(b.Name, "~r") {
		bart = 1
	}
	if aart != bart {
		return aart < bart
	}

	// otherwise sort by name
	return a.Name < b.Name
}

// byClassThenName implements sort.Interface for []*dwarf.Var using cmpDwarfVar.
type byClassThenName []*dwarf.Var

func (s byClassThenName) Len() int           { return len(s) }
func (s byClassThenName) Less(i, j int) bool { return cmpDwarfVar(s[i], s[j]) }
func (s byClassThenName) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }

func dumpInlCall(inlcalls dwarf.InlCalls, idx, ilevel int) {
	for i := 0; i < ilevel; i += 1 {
		Ctxt.Logf("  ")
	}
	ic := inlcalls.Calls[idx]
	callee := Ctxt.InlTree.InlinedFunction(ic.InlIndex)
	Ctxt.Logf("  %d: II:%d (%s) V: (", idx, ic.InlIndex, callee.Name)
	for _, f := range ic.InlVars {
		Ctxt.Logf(" %v", f.Name)
	}
	Ctxt.Logf(" ) C: (")
	for _, k := range ic.Children {
		Ctxt.Logf(" %v", k)
	}
	Ctxt.Logf(" ) R:")
	for _, r := range ic.Ranges {
		Ctxt.Logf(" [%d,%d)", r.Start, r.End)
	}
	Ctxt.Logf("\n")
	for _, k := range ic.Children {
		dumpInlCall(inlcalls, k, ilevel+1)
	}

}

func dumpInlCalls(inlcalls dwarf.InlCalls) {
	n := len(inlcalls.Calls)
	for k := 0; k < n; k += 1 {
		if inlcalls.Calls[k].Root {
			dumpInlCall(inlcalls, k, 0)
		}
	}
}

func dumpInlVars(dwvars []*dwarf.Var) {
	for i, dwv := range dwvars {
		typ := "local"
		if dwv.Abbrev == dwarf.DW_ABRV_PARAM_LOCLIST || dwv.Abbrev == dwarf.DW_ABRV_PARAM {
			typ = "param"
		}
		ia := 0
		if dwv.IsInAbstract {
			ia = 1
		}
		Ctxt.Logf("V%d: %s CI:%d II:%d IA:%d %s\n", i, dwv.Name, dwv.ChildIndex, dwv.InlIndex-1, ia, typ)
	}
}
