//===- gllgo.go - gccgo-like driver for llgo ------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This is llgo's driver. It has a gccgo-like interface in order to easily
// interoperate with the "go" command and the libgo build system.
//
//===----------------------------------------------------------------------===//

package main

/*
#include "config.h"
*/
import "C"

import (
	"errors"
	"fmt"
	"go/scanner"
	"go/token"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"llvm.org/llgo/debug"
	"llvm.org/llgo/driver"
	"llvm.org/llgo/irgen"
	"llvm.org/llvm/bindings/go/llvm"
)

const LibDirSuffix = C.LLVM_LIBDIR_SUFFIX

func report(err error) {
	if list, ok := err.(scanner.ErrorList); ok {
		for _, e := range list {
			fmt.Fprintf(os.Stderr, "%s\n", e)
		}
	} else if err != nil {
		fmt.Fprintf(os.Stderr, "gllgo: error: %s\n", err)
	}
}

func llvmVersion() string {
	return strings.Replace(llvm.Version, "svn", "", 1)
}

func displayVersion() {
	fmt.Printf("llgo version %s (%s)\n\n", llvmVersion(), irgen.GoVersion())
	os.Exit(0)
}

func initCompiler(opts *driverOptions) (*irgen.Compiler, error) {
	importPaths := make([]string, len(opts.importPaths)+len(opts.libPaths))
	copy(importPaths, opts.importPaths)
	copy(importPaths[len(opts.importPaths):], opts.libPaths)
	if opts.prefix != "" {
		importPaths = append(importPaths, filepath.Join(opts.prefix, "lib"+LibDirSuffix, "go", "llgo-"+llvmVersion()))
	}
	copts := irgen.CompilerOptions{
		TargetTriple:       opts.triple,
		GenerateDebug:      opts.generateDebug,
		DebugPrefixMaps:    opts.debugPrefixMaps,
		DumpSSA:            opts.dumpSSA,
		GccgoPath:          opts.gccgoPath,
		GccgoABI:           opts.gccgoPath != "",
		ImportPaths:        importPaths,
		SanitizerAttribute: opts.sanitizer.getAttribute(),
	}
	if opts.dumpTrace {
		copts.Logger = log.New(os.Stderr, "", 0)
	}
	return irgen.NewCompiler(copts)
}

type actionKind int

const (
	actionAssemble = actionKind(iota)
	actionCompile
	actionLink
	actionPrint
)

type action struct {
	kind   actionKind
	inputs []string
}

type sanitizerOptions struct {
	blacklist string
	crtPrefix string

	address, thread, memory, dataflow bool
}

func (san *sanitizerOptions) resourcePath() string {
	return filepath.Join(san.crtPrefix, "lib"+LibDirSuffix, "clang", llvmVersion())
}

func (san *sanitizerOptions) isPIEDefault() bool {
	return san.thread || san.memory || san.dataflow
}

func (san *sanitizerOptions) addPasses(mpm, fpm llvm.PassManager) {
	switch {
	case san.address:
		mpm.AddAddressSanitizerModulePass()
		fpm.AddAddressSanitizerFunctionPass()
	case san.thread:
		mpm.AddThreadSanitizerPass()
	case san.memory:
		mpm.AddMemorySanitizerPass()
	case san.dataflow:
		blacklist := san.blacklist
		if blacklist == "" {
			blacklist = filepath.Join(san.resourcePath(), "dfsan_abilist.txt")
		}
		mpm.AddDataFlowSanitizerPass([]string{blacklist})
	}
}

func (san *sanitizerOptions) libPath(triple, sanitizerName string) string {
	s := strings.Split(triple, "-")
	return filepath.Join(san.resourcePath(), "lib", s[2], "libclang_rt."+sanitizerName+"-"+s[0]+".a")
}

func (san *sanitizerOptions) addLibsForSanitizer(flags []string, triple, sanitizerName string) []string {
	return append(flags, san.libPath(triple, sanitizerName),
		"-Wl,--no-as-needed", "-lpthread", "-lrt", "-lm", "-ldl")
}

func (san *sanitizerOptions) addLibs(triple string, flags []string) []string {
	switch {
	case san.address:
		flags = san.addLibsForSanitizer(flags, triple, "asan")
	case san.thread:
		flags = san.addLibsForSanitizer(flags, triple, "tsan")
	case san.memory:
		flags = san.addLibsForSanitizer(flags, triple, "msan")
	case san.dataflow:
		flags = san.addLibsForSanitizer(flags, triple, "dfsan")
	}

	return flags
}

func (san *sanitizerOptions) getAttribute() llvm.Attribute {
	switch {
	case san.address:
		return llvm.SanitizeAddressAttribute
	case san.thread:
		return llvm.SanitizeThreadAttribute
	case san.memory:
		return llvm.SanitizeMemoryAttribute
	default:
		return 0
	}
}

type driverOptions struct {
	actions []action
	output  string

	bprefix         string
	debugPrefixMaps []debug.PrefixMap
	dumpSSA         bool
	dumpTrace       bool
	emitIR          bool
	gccgoPath       string
	generateDebug   bool
	importPaths     []string
	libPaths        []string
	llvmArgs        []string
	lto             bool
	optLevel        int
	pic             bool
	pieLink         bool
	pkgpath         string
	plugins         []string
	prefix          string
	sanitizer       sanitizerOptions
	sizeLevel       int
	staticLibgcc    bool
	staticLibgo     bool
	staticLink      bool
	triple          string
}

func getInstPrefix() (string, error) {
	path, err := exec.LookPath(os.Args[0])
	if err != nil {
		return "", err
	}

	path, err = filepath.EvalSymlinks(path)
	if err != nil {
		return "", err
	}

	prefix := filepath.Join(path, "..", "..")
	return prefix, nil
}

func parseArguments(args []string) (opts driverOptions, err error) {
	var goInputs, otherInputs []string
	hasOtherNonFlagInputs := false
	noPrefix := false
	actionKind := actionLink
	opts.triple = llvm.DefaultTargetTriple()

	for len(args) > 0 {
		consumedArgs := 1

		switch {
		case !strings.HasPrefix(args[0], "-"):
			if strings.HasSuffix(args[0], ".go") {
				goInputs = append(goInputs, args[0])
			} else {
				hasOtherNonFlagInputs = true
				otherInputs = append(otherInputs, args[0])
			}

		case strings.HasPrefix(args[0], "-Wl,"), strings.HasPrefix(args[0], "-l"), strings.HasPrefix(args[0], "--sysroot="):
			// TODO(pcc): Handle these correctly.
			otherInputs = append(otherInputs, args[0])

		case args[0] == "-B":
			if len(args) == 1 {
				return opts, errors.New("missing argument after '-B'")
			}
			opts.bprefix = args[1]
			consumedArgs = 2

		case args[0] == "-D":
			if len(args) == 1 {
				return opts, errors.New("missing argument after '-D'")
			}
			otherInputs = append(otherInputs, args[0], args[1])
			consumedArgs = 2

		case strings.HasPrefix(args[0], "-D"):
			otherInputs = append(otherInputs, args[0])

		case args[0] == "-I":
			if len(args) == 1 {
				return opts, errors.New("missing argument after '-I'")
			}
			opts.importPaths = append(opts.importPaths, args[1])
			consumedArgs = 2

		case strings.HasPrefix(args[0], "-I"):
			opts.importPaths = append(opts.importPaths, args[0][2:])

		case args[0] == "-isystem":
			if len(args) == 1 {
				return opts, errors.New("missing argument after '-isystem'")
			}
			otherInputs = append(otherInputs, args[0], args[1])
			consumedArgs = 2

		case args[0] == "-L":
			if len(args) == 1 {
				return opts, errors.New("missing argument after '-L'")
			}
			opts.libPaths = append(opts.libPaths, args[1])
			consumedArgs = 2

		case strings.HasPrefix(args[0], "-L"):
			opts.libPaths = append(opts.libPaths, args[0][2:])

		case args[0] == "-O0":
			opts.optLevel = 0

		case args[0] == "-O1", args[0] == "-O":
			opts.optLevel = 1

		case args[0] == "-O2":
			opts.optLevel = 2

		case args[0] == "-Os":
			opts.optLevel = 2
			opts.sizeLevel = 1

		case args[0] == "-O3":
			opts.optLevel = 3

		case args[0] == "-S":
			actionKind = actionAssemble

		case args[0] == "-c":
			actionKind = actionCompile

		case strings.HasPrefix(args[0], "-fcompilerrt-prefix="):
			opts.sanitizer.crtPrefix = args[0][20:]

		case strings.HasPrefix(args[0], "-fdebug-prefix-map="):
			split := strings.SplitN(args[0][19:], "=", 2)
			if len(split) < 2 {
				return opts, fmt.Errorf("argument '%s' must be of form '-fdebug-prefix-map=SOURCE=REPLACEMENT'", args[0])
			}
			opts.debugPrefixMaps = append(opts.debugPrefixMaps, debug.PrefixMap{split[0], split[1]})

		case args[0] == "-fdump-ssa":
			opts.dumpSSA = true

		case args[0] == "-fdump-trace":
			opts.dumpTrace = true

		case strings.HasPrefix(args[0], "-fgccgo-path="):
			opts.gccgoPath = args[0][13:]

		case strings.HasPrefix(args[0], "-fgo-pkgpath="):
			opts.pkgpath = args[0][13:]

		case strings.HasPrefix(args[0], "-fgo-relative-import-path="):
			// TODO(pcc): Handle this.

		case strings.HasPrefix(args[0], "-fstack-protector"):
			// TODO(axw) set ssp function attributes. This can be useful
			// even for Go, if it interfaces with code written in a non-
			// memory safe language (e.g. via cgo).

		case strings.HasPrefix(args[0], "-W"):
			// Go doesn't do warnings. Ignore.

		case args[0] == "-fload-plugin":
			if len(args) == 1 {
				return opts, errors.New("missing argument after '-fload-plugin'")
			}
			opts.plugins = append(opts.plugins, args[1])
			consumedArgs = 2

		case args[0] == "-fno-toplevel-reorder":
			// This is a GCC-specific code generation option. Ignore.

		case args[0] == "-emit-llvm":
			opts.emitIR = true

		case args[0] == "-flto":
			opts.lto = true

		case args[0] == "-fPIC":
			opts.pic = true

		case strings.HasPrefix(args[0], "-fsanitize-blacklist="):
			opts.sanitizer.blacklist = args[0][21:]

		// TODO(pcc): Enforce mutual exclusion between sanitizers.

		case args[0] == "-fsanitize=address":
			opts.sanitizer.address = true

		case args[0] == "-fsanitize=thread":
			opts.sanitizer.thread = true

		case args[0] == "-fsanitize=memory":
			opts.sanitizer.memory = true

		case args[0] == "-fsanitize=dataflow":
			opts.sanitizer.dataflow = true

		case args[0] == "-g":
			opts.generateDebug = true

		case args[0] == "-mllvm":
			if len(args) == 1 {
				return opts, errors.New("missing argument after '-mllvm'")
			}
			opts.llvmArgs = append(opts.llvmArgs, args[1])
			consumedArgs = 2

		case strings.HasPrefix(args[0], "-m"), args[0] == "-funsafe-math-optimizations", args[0] == "-ffp-contract=off":
			// TODO(pcc): Handle code generation options.

		case args[0] == "-no-prefix":
			noPrefix = true

		case args[0] == "-o":
			if len(args) == 1 {
				return opts, errors.New("missing argument after '-o'")
			}
			opts.output = args[1]
			consumedArgs = 2

		case args[0] == "-pie":
			opts.pieLink = true

		case args[0] == "-dumpversion",
			args[0] == "-print-libgcc-file-name",
			args[0] == "-print-multi-os-directory",
			args[0] == "--version":
			actionKind = actionPrint
			opts.output = args[0]

		case args[0] == "-static":
			opts.staticLink = true

		case args[0] == "-static-libgcc":
			opts.staticLibgcc = true

		case args[0] == "-static-libgo":
			opts.staticLibgo = true

		default:
			return opts, fmt.Errorf("unrecognized command line option '%s'", args[0])
		}

		args = args[consumedArgs:]
	}

	if actionKind != actionPrint && len(goInputs) == 0 && !hasOtherNonFlagInputs {
		return opts, errors.New("no input files")
	}

	if !noPrefix {
		opts.prefix, err = getInstPrefix()
		if err != nil {
			return opts, err
		}
	}

	if opts.sanitizer.crtPrefix == "" {
		opts.sanitizer.crtPrefix = opts.prefix
	}

	if opts.sanitizer.isPIEDefault() {
		// This should really only be turning on -fPIE, but this isn't
		// easy to do from Go, and -fPIC is a superset of it anyway.
		opts.pic = true
		opts.pieLink = true
	}

	switch actionKind {
	case actionLink:
		if len(goInputs) != 0 {
			opts.actions = []action{action{actionCompile, goInputs}}
		}
		opts.actions = append(opts.actions, action{actionLink, otherInputs})

	case actionCompile, actionAssemble:
		if len(goInputs) != 0 {
			opts.actions = []action{action{actionKind, goInputs}}
		}

	case actionPrint:
		opts.actions = []action{action{actionKind, nil}}
	}

	if opts.output == "" && len(opts.actions) != 0 {
		switch actionKind {
		case actionCompile, actionAssemble:
			base := filepath.Base(goInputs[0])
			base = base[0 : len(base)-3]
			if actionKind == actionCompile {
				opts.output = base + ".o"
			} else {
				opts.output = base + ".s"
			}

		case actionLink:
			opts.output = "a.out"
		}
	}

	return opts, nil
}

func runPasses(opts *driverOptions, tm llvm.TargetMachine, m llvm.Module) {
	fpm := llvm.NewFunctionPassManagerForModule(m)
	defer fpm.Dispose()

	mpm := llvm.NewPassManager()
	defer mpm.Dispose()

	pmb := llvm.NewPassManagerBuilder()
	defer pmb.Dispose()

	pmb.SetOptLevel(opts.optLevel)
	pmb.SetSizeLevel(opts.sizeLevel)

	tm.AddAnalysisPasses(mpm)
	tm.AddAnalysisPasses(fpm)

	mpm.AddVerifierPass()
	fpm.AddVerifierPass()

	pmb.Populate(mpm)
	pmb.PopulateFunc(fpm)

	if opts.optLevel == 0 {
		// Remove references (via the descriptor) to dead functions,
		// for compatibility with other compilers.
		mpm.AddGlobalDCEPass()
	}

	opts.sanitizer.addPasses(mpm, fpm)

	fpm.InitializeFunc()
	for fn := m.FirstFunction(); !fn.IsNil(); fn = llvm.NextFunction(fn) {
		fpm.RunFunc(fn)
	}
	fpm.FinalizeFunc()

	mpm.Run(m)
}

func getMetadataSectionInlineAsm(name string) string {
	// ELF: creates a non-allocated excluded section.
	return ".section \"" + name + "\", \"e\"\n"
}

func getDataInlineAsm(data []byte) string {
	edata := make([]byte, 0, len(data)*4+10)

	edata = append(edata, ".ascii \""...)
	for i := range data {
		switch data[i] {
		case '\000':
			edata = append(edata, "\\000"...)
			continue
		case '\n':
			edata = append(edata, "\\n"...)
			continue
		case '"', '\\':
			edata = append(edata, '\\')
		}
		edata = append(edata, data[i])
	}
	edata = append(edata, "\"\n"...)
	return string(edata)
}

// Get the lib path to the standard libraries for the given driver options.
// This is normally 'lib' but can vary for cross compilation, LTO, sanitizers
// etc.
func getLibDir(opts *driverOptions) string {
	lib := "lib" + LibDirSuffix
	switch {
	case opts.lto:
		return filepath.Join(lib, "llvm-lto.0")
	case opts.sanitizer.address:
		return filepath.Join(lib, "llvm-asan.0")
	case opts.sanitizer.thread:
		return filepath.Join(lib, "llvm-tsan.0")
	case opts.sanitizer.memory:
		return filepath.Join(lib, "llvm-msan.0")
	case opts.sanitizer.dataflow:
		return filepath.Join(lib, "llvm-dfsan.0")
	default:
		return lib
	}
}

func performAction(opts *driverOptions, kind actionKind, inputs []string, output string) error {
	switch kind {
	case actionPrint:
		switch opts.output {
		case "-dumpversion":
			fmt.Println("llgo-" + llvmVersion())
			return nil
		case "-print-libgcc-file-name":
			cmd := exec.Command(opts.bprefix+"gcc", "-print-libgcc-file-name")
			out, err := cmd.CombinedOutput()
			os.Stdout.Write(out)
			return err
		case "-print-multi-os-directory":
			fmt.Println(filepath.Join("..", getLibDir(opts)))
			return nil
		case "--version":
			displayVersion()
			return nil
		default:
			panic("unexpected print command")
		}

	case actionCompile, actionAssemble:
		compiler, err := initCompiler(opts)
		if err != nil {
			return err
		}

		fset := token.NewFileSet()
		files, err := driver.ParseFiles(fset, inputs)
		if err != nil {
			return err
		}

		module, err := compiler.Compile(fset, files, opts.pkgpath)
		if err != nil {
			return err
		}

		defer module.Dispose()

		target, err := llvm.GetTargetFromTriple(opts.triple)
		if err != nil {
			return err
		}

		optLevel := [...]llvm.CodeGenOptLevel{
			llvm.CodeGenLevelNone,
			llvm.CodeGenLevelLess,
			llvm.CodeGenLevelDefault,
			llvm.CodeGenLevelAggressive,
		}[opts.optLevel]

		relocMode := llvm.RelocStatic
		if opts.pic {
			relocMode = llvm.RelocPIC
		}

		tm := target.CreateTargetMachine(opts.triple, "", "", optLevel,
			relocMode, llvm.CodeModelDefault)
		defer tm.Dispose()

		runPasses(opts, tm, module.Module)

		var file *os.File
		if output == "-" {
			file = os.Stdout
		} else {
			file, err = os.Create(output)
			if err != nil {
				return err
			}
			defer file.Close()
		}

		switch {
		case !opts.lto && !opts.emitIR:
			if module.ExportData != nil {
				asm := getMetadataSectionInlineAsm(".go_export")
				asm += getDataInlineAsm(module.ExportData)
				module.Module.SetInlineAsm(asm)
			}

			fileType := llvm.AssemblyFile
			if kind == actionCompile {
				fileType = llvm.ObjectFile
			}
			mb, err := tm.EmitToMemoryBuffer(module.Module, fileType)
			if err != nil {
				return err
			}
			defer mb.Dispose()

			bytes := mb.Bytes()
			_, err = file.Write(bytes)
			return err

		case opts.lto:
			bcmb := llvm.WriteBitcodeToMemoryBuffer(module.Module)
			defer bcmb.Dispose()

			// This is a bit of a hack. We just want an object file
			// containing some metadata sections. This might be simpler
			// if we had bindings for the MC library, but for now we create
			// a fresh module containing only inline asm that creates the
			// sections.
			outmodule := llvm.NewModule("")
			defer outmodule.Dispose()
			asm := getMetadataSectionInlineAsm(".llvmbc")
			asm += getDataInlineAsm(bcmb.Bytes())
			if module.ExportData != nil {
				asm += getMetadataSectionInlineAsm(".go_export")
				asm += getDataInlineAsm(module.ExportData)
			}
			outmodule.SetInlineAsm(asm)

			fileType := llvm.AssemblyFile
			if kind == actionCompile {
				fileType = llvm.ObjectFile
			}
			mb, err := tm.EmitToMemoryBuffer(outmodule, fileType)
			if err != nil {
				return err
			}
			defer mb.Dispose()

			bytes := mb.Bytes()
			_, err = file.Write(bytes)
			return err

		case kind == actionCompile:
			err := llvm.WriteBitcodeToFile(module.Module, file)
			return err

		case kind == actionAssemble:
			_, err := file.WriteString(module.Module.String())
			return err

		default:
			panic("unexpected action kind")
		}

	case actionLink:
		// TODO(pcc): Teach this to do LTO.
		args := []string{"-o", output}
		if opts.pic {
			args = append(args, "-fPIC")
		}
		if opts.pieLink {
			args = append(args, "-pie")
		}
		if opts.staticLink {
			args = append(args, "-static")
		}
		if opts.staticLibgcc {
			args = append(args, "-static-libgcc")
		}
		for _, p := range opts.libPaths {
			args = append(args, "-L", p)
		}
		for _, p := range opts.importPaths {
			args = append(args, "-I", p)
		}
		args = append(args, inputs...)
		var linkerPath string
		if opts.gccgoPath == "" {
			// TODO(pcc): See if we can avoid calling gcc here.
			// We currently rely on it to find crt*.o and compile
			// any C source files passed as arguments.
			linkerPath = opts.bprefix + "gcc"

			if opts.prefix != "" {
				libdir := filepath.Join(opts.prefix, getLibDir(opts))
				args = append(args, "-L", libdir)
				if !opts.staticLibgo {
					args = append(args, "-Wl,-rpath,"+libdir)
				}
			}

			args = append(args, "-lgobegin-llgo")
			if opts.staticLibgo {
				args = append(args, "-Wl,-Bstatic", "-lgo-llgo", "-Wl,-Bdynamic", "-lpthread", "-lm")
			} else {
				args = append(args, "-lgo-llgo", "-lm")
			}
		} else {
			linkerPath = opts.gccgoPath
			if opts.staticLibgo {
				args = append(args, "-static-libgo")
			}
		}

		args = opts.sanitizer.addLibs(opts.triple, args)

		cmd := exec.Command(linkerPath, args...)
		out, err := cmd.CombinedOutput()
		if err != nil {
			os.Stderr.Write(out)
		}
		return err

	default:
		panic("unexpected action kind")
	}
}

func performActions(opts *driverOptions) error {
	var extraInput string

	for _, plugin := range opts.plugins {
		err := llvm.LoadLibraryPermanently(plugin)
		if err != nil {
			return err
		}
	}

	llvm.ParseCommandLineOptions(append([]string{"llgo"}, opts.llvmArgs...), "llgo (LLVM option parsing)\n")

	for i, action := range opts.actions {
		var output string
		if i == len(opts.actions)-1 {
			output = opts.output
		} else {
			tmpfile, err := ioutil.TempFile("", "llgo")
			if err != nil {
				return err
			}
			output = tmpfile.Name() + ".o"
			tmpfile.Close()
			err = os.Remove(tmpfile.Name())
			if err != nil {
				return err
			}
			defer os.Remove(output)
		}

		inputs := action.inputs
		if extraInput != "" {
			inputs = append([]string{extraInput}, inputs...)
		}

		err := performAction(opts, action.kind, inputs, output)
		if err != nil {
			return err
		}

		extraInput = output
	}

	return nil
}

func main() {
	llvm.InitializeAllTargets()
	llvm.InitializeAllTargetMCs()
	llvm.InitializeAllTargetInfos()
	llvm.InitializeAllAsmParsers()
	llvm.InitializeAllAsmPrinters()

	opts, err := parseArguments(os.Args[1:])
	if err != nil {
		report(err)
		os.Exit(1)
	}

	err = performActions(&opts)
	if err != nil {
		report(err)
		os.Exit(1)
	}
}
