// Copyright 2009 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. // Cgo; see gmp.go for an overview. // TODO(rsc): // Emit correct line number annotations. // Make 6g understand the annotations. package main import ( "fmt"; "go/ast"; "os"; ) func usage() { fmt.Fprint(os.Stderr, "usage: cgo [compiler options] file.go\n"); } var ptrSizeMap = map[string]int64{ "386": 4, "amd64": 8, "arm": 4, } var expandName = map[string]string{ "schar": "signed char", "uchar": "unsigned char", "ushort": "unsigned short", "uint": "unsigned int", "ulong": "unsigned long", "longlong": "long long", "ulonglong": "unsigned long long", } func main() { args := os.Args; if len(args) < 2 { usage(); os.Exit(2); } gccOptions := args[1 : len(args)-1]; input := args[len(args)-1]; arch := os.Getenv("GOARCH"); if arch == "" { fatal("$GOARCH is not set"); } ptrSize, ok := ptrSizeMap[arch]; if !ok { fatal("unknown architecture %s", arch); } p := openProg(input); for _, cref := range p.Crefs { // Convert C.ulong to C.unsigned long, etc. if expand, ok := expandName[cref.Name]; ok { cref.Name = expand; } } p.PtrSize = ptrSize; p.Preamble = p.Preamble + "\n" + builtinProlog; p.GccOptions = gccOptions; p.loadDebugInfo(); p.Vardef = make(map[string]*Type); p.Funcdef = make(map[string]*FuncType); for _, cref := range p.Crefs { switch cref.Context { case "call": if !cref.TypeName { // Is an actual function call. *cref.Expr = &ast.Ident{Value: "_C_" + cref.Name}; p.Funcdef[cref.Name] = cref.FuncType; break; } *cref.Expr = cref.Type.Go; case "expr": if cref.TypeName { error((*cref.Expr).Pos(), "type C.%s used as expression", cref.Name); } // Reference to C variable. // We declare a pointer and arrange to have it filled in. *cref.Expr = &ast.StarExpr{X: &ast.Ident{Value: "_C_" + cref.Name}}; p.Vardef[cref.Name] = cref.Type; case "type": if !cref.TypeName { error((*cref.Expr).Pos(), "expression C.%s used as type", cref.Name); } *cref.Expr = cref.Type.Go; } } if nerrors > 0 { os.Exit(2); } p.PackagePath = p.Package; p.writeOutput(input); }