irgen, driver: modify Compiler.Compile to take a FileSet and Files

This change allows clients to generate IR using "files" received from locations
other than the file system. The regular file parser is moved to a new library,
"driver", which is intended to eventually contain much of the logic from
the existing driver.

Differential Revision: http://reviews.llvm.org/D6794

llvm-svn: 225026
GitOrigin-RevId: 9350942b20bf1e6e2b182159f5837ba209485972
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 51d20c2..b4ec074 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -11,6 +11,7 @@
   build/context.go
   cmd/gllgo/gllgo.go
   debug/debug.go
+  driver/parser.go
   irgen/annotations.go
   irgen/attribute.go
   irgen/builtins.go
@@ -23,7 +24,6 @@
   irgen/indirect.go
   irgen/interfaces.go
   irgen/maps.go
-  irgen/parser.go
   irgen/predicates.go
   irgen/println.go
   irgen/runtime.go
diff --git a/cmd/gllgo/gllgo.go b/cmd/gllgo/gllgo.go
index db25ccf..e58686e 100644
--- a/cmd/gllgo/gllgo.go
+++ b/cmd/gllgo/gllgo.go
@@ -23,6 +23,7 @@
 	"errors"
 	"fmt"
 	"go/scanner"
+	"go/token"
 	"io/ioutil"
 	"log"
 	"os"
@@ -31,6 +32,7 @@
 	"strings"
 
 	"llvm.org/llgo/debug"
+	"llvm.org/llgo/driver"
 	"llvm.org/llgo/irgen"
 	"llvm.org/llvm/bindings/go/llvm"
 )
@@ -580,7 +582,13 @@
 			return err
 		}
 
-		module, err := compiler.Compile(inputs, opts.pkgpath)
+		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
 		}
diff --git a/irgen/parser.go b/driver/parser.go
similarity index 87%
rename from irgen/parser.go
rename to driver/parser.go
index 143134b..07600f4 100644
--- a/irgen/parser.go
+++ b/driver/parser.go
@@ -12,7 +12,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-package irgen
+package driver
 
 import (
 	"fmt"
@@ -23,11 +23,12 @@
 )
 
 func parseFile(fset *token.FileSet, filename string) (*ast.File, error) {
+	// Retain comments; this is important for annotation processing.
 	mode := parser.DeclarationErrors | parser.ParseComments
 	return parser.ParseFile(fset, filename, nil, mode)
 }
 
-func parseFiles(fset *token.FileSet, filenames []string) ([]*ast.File, error) {
+func ParseFiles(fset *token.FileSet, filenames []string) ([]*ast.File, error) {
 	files := make([]*ast.File, len(filenames))
 	for i, filename := range filenames {
 		file, err := parseFile(fset, filename)
diff --git a/irgen/compiler.go b/irgen/compiler.go
index f7d1655..de496ff 100644
--- a/irgen/compiler.go
+++ b/irgen/compiler.go
@@ -16,6 +16,7 @@
 import (
 	"bytes"
 	"fmt"
+	"go/ast"
 	"go/token"
 	"log"
 	"sort"
@@ -102,7 +103,7 @@
 	return compiler, nil
 }
 
-func (c *Compiler) Compile(filenames []string, importpath string) (m *Module, err error) {
+func (c *Compiler) Compile(fset *token.FileSet, astFiles []*ast.File, importpath string) (m *Module, err error) {
 	target := llvm.NewTargetData(c.dataLayout)
 	compiler := &compiler{
 		CompilerOptions: c.opts,
@@ -111,7 +112,7 @@
 		pnacl:           c.pnacl,
 		llvmtypes:       NewLLVMTypeMap(llvm.GlobalContext(), target),
 	}
-	return compiler.compile(filenames, importpath)
+	return compiler.compile(fset, astFiles, importpath)
 }
 
 type compiler struct {
@@ -149,7 +150,7 @@
 	}
 }
 
-func (compiler *compiler) compile(filenames []string, importpath string) (m *Module, err error) {
+func (compiler *compiler) compile(fset *token.FileSet, astFiles []*ast.File, importpath string) (m *Module, err error) {
 	buildctx, err := llgobuild.ContextFromTriple(compiler.TargetTriple)
 	if err != nil {
 		return nil, err
@@ -170,19 +171,13 @@
 	}
 
 	impcfg := &loader.Config{
-		Fset: token.NewFileSet(),
+		Fset: fset,
 		TypeChecker: types.Config{
 			Import: importer,
 			Sizes:  compiler.llvmtypes,
 		},
 		Build: &buildctx.Context,
 	}
-	// Must use parseFiles, so we retain comments;
-	// this is important for annotation processing.
-	astFiles, err := parseFiles(impcfg.Fset, filenames)
-	if err != nil {
-		return nil, err
-	}
 	// If no import path is specified, then set the import
 	// path to be the same as the package's name.
 	if importpath == "" {