compiler: Refactor Compiler.Parse: extract parsePackage
Этот коммит содержится в:
родитель
2d19bb11ba
коммит
9a988dd1d1
1 изменённых файлов: 95 добавлений и 86 удалений
181
tgo.go
181
tgo.go
|
@ -209,92 +209,7 @@ func (c *Compiler) Parse(mainPath string, buildTags []string) error {
|
|||
}
|
||||
|
||||
for _, pkg := range packageList {
|
||||
fmt.Println("package:", pkg.Pkg.Path())
|
||||
|
||||
// Make sure we're walking through all members in a constant order every
|
||||
// run.
|
||||
memberNames := make([]string, 0)
|
||||
for name := range pkg.Members {
|
||||
if strings.HasPrefix(name, "_Cgo_") || strings.HasPrefix(name, "_cgo") {
|
||||
// _Cgo_ptr, _Cgo_use, _cgoCheckResult, _cgo_runtime_cgocall
|
||||
continue // CGo-internal functions
|
||||
}
|
||||
if strings.HasPrefix(name, "__cgofn__cgo_") {
|
||||
continue // CGo function pointer in global scope
|
||||
}
|
||||
memberNames = append(memberNames, name)
|
||||
}
|
||||
sort.Strings(memberNames)
|
||||
|
||||
frames := make(map[*ssa.Function]*Frame)
|
||||
|
||||
// First, build all function declarations.
|
||||
for _, name := range memberNames {
|
||||
member := pkg.Members[name]
|
||||
|
||||
switch member := member.(type) {
|
||||
case *ssa.Function:
|
||||
frame, err := c.parseFuncDecl(member)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
frames[member] = frame
|
||||
case *ssa.NamedConst:
|
||||
// Ignore package-level untyped constants. The SSA form doesn't
|
||||
// need them.
|
||||
case *ssa.Global:
|
||||
typ, err := c.getLLVMType(member.Type())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
global := llvm.AddGlobal(c.mod, typ, pkgPrefix(member.Pkg) + "." + member.Name())
|
||||
if ast.IsExported(member.Name()) {
|
||||
global.SetLinkage(llvm.PrivateLinkage)
|
||||
}
|
||||
case *ssa.Type:
|
||||
ms := program.MethodSets.MethodSet(member.Type())
|
||||
for i := 0; i < ms.Len(); i++ {
|
||||
fn := program.MethodValue(ms.At(i))
|
||||
frame, err := c.parseFuncDecl(fn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
frames[fn] = frame
|
||||
}
|
||||
default:
|
||||
return errors.New("todo: member: " + fmt.Sprintf("%#v", member))
|
||||
}
|
||||
}
|
||||
|
||||
// Now, add definitions to those declarations.
|
||||
for _, name := range memberNames {
|
||||
member := pkg.Members[name]
|
||||
fmt.Println("member:", member.Token(), member)
|
||||
|
||||
switch member := member.(type) {
|
||||
case *ssa.Function:
|
||||
if strings.HasPrefix(name, "_Cfunc_") {
|
||||
// CGo function. Don't implement it's body.
|
||||
continue
|
||||
}
|
||||
if member.Blocks == nil {
|
||||
continue // external function
|
||||
}
|
||||
err := c.parseFunc(frames[member], member)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case *ssa.Type:
|
||||
ms := program.MethodSets.MethodSet(member.Type())
|
||||
for i := 0; i < ms.Len(); i++ {
|
||||
fn := program.MethodValue(ms.At(i))
|
||||
err := c.parseFunc(frames[fn], fn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
c.parsePackage(program, pkg)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -382,6 +297,100 @@ func (c *Compiler) getFunctionName(fn *ssa.Function) string {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *Compiler) parsePackage(program *ssa.Program, pkg *ssa.Package) error {
|
||||
fmt.Println("package:", pkg.Pkg.Path())
|
||||
|
||||
// Make sure we're walking through all members in a constant order every
|
||||
// run.
|
||||
memberNames := make([]string, 0)
|
||||
for name := range pkg.Members {
|
||||
if strings.HasPrefix(name, "_Cgo_") || strings.HasPrefix(name, "_cgo") {
|
||||
// _Cgo_ptr, _Cgo_use, _cgoCheckResult, _cgo_runtime_cgocall
|
||||
continue // CGo-internal functions
|
||||
}
|
||||
if strings.HasPrefix(name, "__cgofn__cgo_") {
|
||||
continue // CGo function pointer in global scope
|
||||
}
|
||||
memberNames = append(memberNames, name)
|
||||
}
|
||||
sort.Strings(memberNames)
|
||||
|
||||
frames := make(map[*ssa.Function]*Frame)
|
||||
|
||||
// First, build all function declarations.
|
||||
for _, name := range memberNames {
|
||||
member := pkg.Members[name]
|
||||
|
||||
switch member := member.(type) {
|
||||
case *ssa.Function:
|
||||
frame, err := c.parseFuncDecl(member)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
frames[member] = frame
|
||||
if member.Synthetic == "package initializer" {
|
||||
c.initFuncs = append(c.initFuncs, frame.llvmFn)
|
||||
}
|
||||
case *ssa.NamedConst:
|
||||
// Ignore package-level untyped constants. The SSA form doesn't need
|
||||
// them.
|
||||
case *ssa.Global:
|
||||
typ, err := c.getLLVMType(member.Type())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
global := llvm.AddGlobal(c.mod, typ, pkgPrefix(member.Pkg) + "." + member.Name())
|
||||
if ast.IsExported(member.Name()) {
|
||||
global.SetLinkage(llvm.PrivateLinkage)
|
||||
}
|
||||
case *ssa.Type:
|
||||
ms := program.MethodSets.MethodSet(member.Type())
|
||||
for i := 0; i < ms.Len(); i++ {
|
||||
fn := program.MethodValue(ms.At(i))
|
||||
frame, err := c.parseFuncDecl(fn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
frames[fn] = frame
|
||||
}
|
||||
default:
|
||||
return errors.New("todo: member: " + fmt.Sprintf("%#v", member))
|
||||
}
|
||||
}
|
||||
|
||||
// Now, add definitions to those declarations.
|
||||
for _, name := range memberNames {
|
||||
member := pkg.Members[name]
|
||||
fmt.Println("member:", member.Token(), member)
|
||||
|
||||
switch member := member.(type) {
|
||||
case *ssa.Function:
|
||||
if strings.HasPrefix(name, "_Cfunc_") {
|
||||
// CGo function. Don't implement it's body.
|
||||
continue
|
||||
}
|
||||
if member.Blocks == nil {
|
||||
continue // external function
|
||||
}
|
||||
err := c.parseFunc(frames[member], member)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case *ssa.Type:
|
||||
ms := program.MethodSets.MethodSet(member.Type())
|
||||
for i := 0; i < ms.Len(); i++ {
|
||||
fn := program.MethodValue(ms.At(i))
|
||||
err := c.parseFunc(frames[fn], fn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Compiler) parseFuncDecl(f *ssa.Function) (*Frame, error) {
|
||||
f.WriteTo(os.Stdout)
|
||||
name := c.getFunctionName(f)
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче