LEFT | RIGHT |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package main | 5 package main |
6 | 6 |
7 import ( | 7 import ( |
8 "bytes" | 8 "bytes" |
9 "debug/elf" | 9 "debug/elf" |
10 "debug/macho" | 10 "debug/macho" |
(...skipping 14 matching lines...) Expand all Loading... |
25 func (p *Package) writeDefs() { | 25 func (p *Package) writeDefs() { |
26 fgo2 := creat(*objDir + "_cgo_gotypes.go") | 26 fgo2 := creat(*objDir + "_cgo_gotypes.go") |
27 fc := creat(*objDir + "_cgo_defun.c") | 27 fc := creat(*objDir + "_cgo_defun.c") |
28 fm := creat(*objDir + "_cgo_main.c") | 28 fm := creat(*objDir + "_cgo_main.c") |
29 | 29 |
30 var gccgoInit bytes.Buffer | 30 var gccgoInit bytes.Buffer |
31 | 31 |
32 fflg := creat(*objDir + "_cgo_flags") | 32 fflg := creat(*objDir + "_cgo_flags") |
33 for k, v := range p.CgoFlags { | 33 for k, v := range p.CgoFlags { |
34 fmt.Fprintf(fflg, "_CGO_%s=%s\n", k, strings.Join(v, " ")) | 34 fmt.Fprintf(fflg, "_CGO_%s=%s\n", k, strings.Join(v, " ")) |
35 » » if k == "LDFLAGS" { | 35 » » if k == "LDFLAGS" && !*gccgo { |
36 for _, arg := range v { | 36 for _, arg := range v { |
37 fmt.Fprintf(fc, "#pragma cgo_ldflag %q\n", arg) | 37 fmt.Fprintf(fc, "#pragma cgo_ldflag %q\n", arg) |
38 } | 38 } |
39 } | 39 } |
40 } | 40 } |
41 fflg.Close() | 41 fflg.Close() |
42 | 42 |
43 // Write C main file for using gcc to resolve imports. | 43 // Write C main file for using gcc to resolve imports. |
44 fmt.Fprintf(fm, "int main() { return 0; }\n") | 44 fmt.Fprintf(fm, "int main() { return 0; }\n") |
45 if *importRuntimeCgo { | 45 if *importRuntimeCgo { |
46 fmt.Fprintf(fm, "void crosscall2(void(*fn)(void*, int), void *a,
int c) { }\n") | 46 fmt.Fprintf(fm, "void crosscall2(void(*fn)(void*, int), void *a,
int c) { }\n") |
47 } else { | 47 } else { |
48 // If we're not importing runtime/cgo, we *are* runtime/cgo, | 48 // If we're not importing runtime/cgo, we *are* runtime/cgo, |
49 // which provides crosscall2. We just need a prototype. | 49 // which provides crosscall2. We just need a prototype. |
50 » » fmt.Fprintf(fm, "void crosscall2(void(*fn)(void*, int), void *a,
int c);") | 50 » » fmt.Fprintf(fm, "void crosscall2(void(*fn)(void*, int), void *a,
int c);\n") |
51 } | 51 } |
52 fmt.Fprintf(fm, "void _cgo_allocate(void *a, int c) { }\n") | 52 fmt.Fprintf(fm, "void _cgo_allocate(void *a, int c) { }\n") |
53 fmt.Fprintf(fm, "void _cgo_panic(void *a, int c) { }\n") | 53 fmt.Fprintf(fm, "void _cgo_panic(void *a, int c) { }\n") |
54 | 54 |
55 // Write second Go output: definitions of _C_xxx. | 55 // Write second Go output: definitions of _C_xxx. |
56 // In a separate file so that the import of "unsafe" does not | 56 // In a separate file so that the import of "unsafe" does not |
57 // pollute the original file. | 57 // pollute the original file. |
58 fmt.Fprintf(fgo2, "// Created by cgo - DO NOT EDIT\n\n") | 58 fmt.Fprintf(fgo2, "// Created by cgo - DO NOT EDIT\n\n") |
59 fmt.Fprintf(fgo2, "package %s\n\n", p.PackageName) | 59 fmt.Fprintf(fgo2, "package %s\n\n", p.PackageName) |
60 fmt.Fprintf(fgo2, "import \"unsafe\"\n\n") | 60 fmt.Fprintf(fgo2, "import \"unsafe\"\n\n") |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 for _, key := range nameKeys(p.Name) { | 98 for _, key := range nameKeys(p.Name) { |
99 n := p.Name[key] | 99 n := p.Name[key] |
100 if !n.IsVar() { | 100 if !n.IsVar() { |
101 continue | 101 continue |
102 } | 102 } |
103 | 103 |
104 if !cVars[n.C] { | 104 if !cVars[n.C] { |
105 fmt.Fprintf(fm, "extern char %s[];\n", n.C) | 105 fmt.Fprintf(fm, "extern char %s[];\n", n.C) |
106 fmt.Fprintf(fm, "void *_cgohack_%s = %s;\n\n", n.C, n.C) | 106 fmt.Fprintf(fm, "void *_cgohack_%s = %s;\n\n", n.C, n.C) |
107 | 107 |
108 » » » fmt.Fprintf(fc, "#pragma cgo_import_static %s\n", n.C) | 108 » » » if !*gccgo { |
| 109 » » » » fmt.Fprintf(fc, "#pragma cgo_import_static %s\n"
, n.C) |
| 110 » » » } |
| 111 |
109 fmt.Fprintf(fc, "extern byte *%s;\n", n.C) | 112 fmt.Fprintf(fc, "extern byte *%s;\n", n.C) |
110 | 113 |
111 cVars[n.C] = true | 114 cVars[n.C] = true |
112 } | 115 } |
113 var amp string | 116 var amp string |
114 var node ast.Node | 117 var node ast.Node |
115 if n.Kind == "var" { | 118 if n.Kind == "var" { |
116 amp = "&" | 119 amp = "&" |
117 node = &ast.StarExpr{X: n.Type.Go} | 120 node = &ast.StarExpr{X: n.Type.Go} |
118 } else if n.Kind == "fpvar" { | 121 } else if n.Kind == "fpvar" { |
119 node = n.Type.Go | 122 node = n.Type.Go |
120 } else { | 123 } else { |
121 » » » panic(fmt.Errorf("Invalid var kind %q", n.Kind)) | 124 » » » panic(fmt.Errorf("invalid var kind %q", n.Kind)) |
122 } | 125 } |
123 if *gccgo { | 126 if *gccgo { |
124 fmt.Fprintf(fc, `extern void *%s __asm__("%s.%s");`, n.M
angle, gccgoSymbolPrefix, n.Mangle) | 127 fmt.Fprintf(fc, `extern void *%s __asm__("%s.%s");`, n.M
angle, gccgoSymbolPrefix, n.Mangle) |
125 fmt.Fprintf(&gccgoInit, "\t%s = %s%s;\n", n.Mangle, amp,
n.C) | 128 fmt.Fprintf(&gccgoInit, "\t%s = %s%s;\n", n.Mangle, amp,
n.C) |
126 } else { | 129 } else { |
127 fmt.Fprintf(fc, "void *·%s = %s%s;\n", n.Mangle, amp, n.
C) | 130 fmt.Fprintf(fc, "void *·%s = %s%s;\n", n.Mangle, amp, n.
C) |
128 } | 131 } |
129 fmt.Fprintf(fc, "\n") | 132 fmt.Fprintf(fc, "\n") |
130 | 133 |
131 fmt.Fprintf(fgo2, "var %s ", n.Mangle) | 134 fmt.Fprintf(fgo2, "var %s ", n.Mangle) |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 } | 287 } |
285 fmt.Fprintf(&buf, "\t\t%s%s r;\n", qual, t.C) | 288 fmt.Fprintf(&buf, "\t\t%s%s r;\n", qual, t.C) |
286 off += t.Size | 289 off += t.Size |
287 } | 290 } |
288 if off%p.PtrSize != 0 { | 291 if off%p.PtrSize != 0 { |
289 pad := p.PtrSize - off%p.PtrSize | 292 pad := p.PtrSize - off%p.PtrSize |
290 fmt.Fprintf(&buf, "\t\tchar __pad%d[%d];\n", off, pad) | 293 fmt.Fprintf(&buf, "\t\tchar __pad%d[%d];\n", off, pad) |
291 off += pad | 294 off += pad |
292 } | 295 } |
293 if n.AddError { | 296 if n.AddError { |
294 » » fmt.Fprint(&buf, "\t\tvoid *e[2]; /* error */\n") | 297 » » fmt.Fprint(&buf, "\t\tint e[2*sizeof(void *)/sizeof(int)]; /* er
ror */\n") |
295 off += 2 * p.PtrSize | 298 off += 2 * p.PtrSize |
296 } | 299 } |
297 if off == 0 { | 300 if off == 0 { |
298 fmt.Fprintf(&buf, "\t\tchar unused;\n") // avoid empty struct | 301 fmt.Fprintf(&buf, "\t\tchar unused;\n") // avoid empty struct |
299 } | 302 } |
300 fmt.Fprintf(&buf, "\t}") | 303 fmt.Fprintf(&buf, "\t}") |
301 return buf.String(), off | 304 return buf.String(), off |
302 } | 305 } |
303 | 306 |
304 func (p *Package) writeDefsFunc(fc, fgo2 *os.File, n *Name) { | 307 func (p *Package) writeDefsFunc(fc, fgo2 *os.File, n *Name) { |
(...skipping 15 matching lines...) Expand all Loading... |
320 t.Results = &ast.FieldList{List: l} | 323 t.Results = &ast.FieldList{List: l} |
321 gtype = t | 324 gtype = t |
322 } | 325 } |
323 | 326 |
324 // Go func declaration. | 327 // Go func declaration. |
325 d := &ast.FuncDecl{ | 328 d := &ast.FuncDecl{ |
326 Name: ast.NewIdent(n.Mangle), | 329 Name: ast.NewIdent(n.Mangle), |
327 Type: gtype, | 330 Type: gtype, |
328 } | 331 } |
329 | 332 |
| 333 // Builtins defined in the C prolog. |
| 334 inProlog := name == "CString" || name == "GoString" || name == "GoString
N" || name == "GoBytes" |
| 335 |
330 if *gccgo { | 336 if *gccgo { |
331 // Gccgo style hooks. | 337 // Gccgo style hooks. |
332 fmt.Fprint(fgo2, "\n") | 338 fmt.Fprint(fgo2, "\n") |
333 cname := fmt.Sprintf("_cgo%s%s", cPrefix, n.Mangle) | 339 cname := fmt.Sprintf("_cgo%s%s", cPrefix, n.Mangle) |
334 paramnames := []string(nil) | 340 paramnames := []string(nil) |
335 for i, param := range d.Type.Params.List { | 341 for i, param := range d.Type.Params.List { |
336 paramName := fmt.Sprintf("p%d", i) | 342 paramName := fmt.Sprintf("p%d", i) |
337 param.Names = []*ast.Ident{ast.NewIdent(paramName)} | 343 param.Names = []*ast.Ident{ast.NewIdent(paramName)} |
338 paramnames = append(paramnames, paramName) | 344 paramnames = append(paramnames, paramName) |
339 } | 345 } |
340 | 346 |
341 conf.Fprint(fgo2, fset, d) | 347 conf.Fprint(fgo2, fset, d) |
342 fmt.Fprint(fgo2, " {\n") | 348 fmt.Fprint(fgo2, " {\n") |
343 » » fmt.Fprint(fgo2, "\tdefer syscall.CgocallDone()\n") | 349 » » if !inProlog { |
344 » » fmt.Fprint(fgo2, "\tsyscall.Cgocall()\n") | 350 » » » fmt.Fprint(fgo2, "\tdefer syscall.CgocallDone()\n") |
| 351 » » » fmt.Fprint(fgo2, "\tsyscall.Cgocall()\n") |
| 352 » » } |
345 if n.AddError { | 353 if n.AddError { |
346 fmt.Fprint(fgo2, "\tsyscall.SetErrno(0)\n") | 354 fmt.Fprint(fgo2, "\tsyscall.SetErrno(0)\n") |
347 } | 355 } |
348 fmt.Fprint(fgo2, "\t") | 356 fmt.Fprint(fgo2, "\t") |
349 if !void { | 357 if !void { |
350 fmt.Fprint(fgo2, "r := ") | 358 fmt.Fprint(fgo2, "r := ") |
351 } | 359 } |
352 fmt.Fprintf(fgo2, "%s(%s)\n", cname, strings.Join(paramnames, ",
")) | 360 fmt.Fprintf(fgo2, "%s(%s)\n", cname, strings.Join(paramnames, ",
")) |
353 | 361 |
354 if n.AddError { | 362 if n.AddError { |
(...skipping 10 matching lines...) Expand all Loading... |
365 fmt.Fprint(fgo2, "r, ") | 373 fmt.Fprint(fgo2, "r, ") |
366 } | 374 } |
367 fmt.Fprint(fgo2, "nil\n") | 375 fmt.Fprint(fgo2, "nil\n") |
368 } else if !void { | 376 } else if !void { |
369 fmt.Fprint(fgo2, "\treturn r\n") | 377 fmt.Fprint(fgo2, "\treturn r\n") |
370 } | 378 } |
371 | 379 |
372 fmt.Fprint(fgo2, "}\n") | 380 fmt.Fprint(fgo2, "}\n") |
373 | 381 |
374 // declare the C function. | 382 // declare the C function. |
375 » » fmt.Fprintf(fgo2, "//extern %s\n", n.C) | 383 » » if inProlog { |
| 384 » » » fmt.Fprintf(fgo2, "//extern %s\n", n.C) |
| 385 » » } else { |
| 386 » » » fmt.Fprintf(fgo2, "//extern _cgo%s%s\n", cPrefix, n.Mang
le) |
| 387 » » } |
376 d.Name = ast.NewIdent(cname) | 388 d.Name = ast.NewIdent(cname) |
377 if n.AddError { | 389 if n.AddError { |
378 l := d.Type.Results.List | 390 l := d.Type.Results.List |
379 d.Type.Results.List = l[:len(l)-1] | 391 d.Type.Results.List = l[:len(l)-1] |
380 } | 392 } |
381 conf.Fprint(fgo2, fset, d) | 393 conf.Fprint(fgo2, fset, d) |
382 fmt.Fprint(fgo2, "\n") | 394 fmt.Fprint(fgo2, "\n") |
383 | 395 |
384 return | 396 return |
385 } | 397 } |
386 conf.Fprint(fgo2, fset, d) | 398 conf.Fprint(fgo2, fset, d) |
387 fmt.Fprint(fgo2, "\n") | 399 fmt.Fprint(fgo2, "\n") |
388 | 400 |
389 » if name == "CString" || name == "GoString" || name == "GoStringN" || nam
e == "GoBytes" { | 401 » if inProlog { |
390 » » // The builtins are already defined in the C prolog. | |
391 return | 402 return |
392 } | 403 } |
393 | 404 |
394 var argSize int64 | 405 var argSize int64 |
395 _, argSize = p.structType(n) | 406 _, argSize = p.structType(n) |
396 | 407 |
397 // C wrapper calls into gcc, passing a pointer to the argument frame. | 408 // C wrapper calls into gcc, passing a pointer to the argument frame. |
398 fmt.Fprintf(fc, "#pragma cgo_import_static _cgo%s%s\n", cPrefix, n.Mangl
e) | 409 fmt.Fprintf(fc, "#pragma cgo_import_static _cgo%s%s\n", cPrefix, n.Mangl
e) |
399 fmt.Fprintf(fc, "void _cgo%s%s(void*);\n", cPrefix, n.Mangle) | 410 fmt.Fprintf(fc, "void _cgo%s%s(void*);\n", cPrefix, n.Mangle) |
400 fmt.Fprintf(fc, "\n") | 411 fmt.Fprintf(fc, "\n") |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
468 func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) { | 479 func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) { |
469 name := n.Mangle | 480 name := n.Mangle |
470 if name == "_Cfunc_CString" || name == "_Cfunc_GoString" || name == "_Cf
unc_GoStringN" || name == "_Cfunc_GoBytes" || p.Written[name] { | 481 if name == "_Cfunc_CString" || name == "_Cfunc_GoString" || name == "_Cf
unc_GoStringN" || name == "_Cfunc_GoBytes" || p.Written[name] { |
471 // The builtins are already defined in the C prolog, and we don'
t | 482 // The builtins are already defined in the C prolog, and we don'
t |
472 // want to duplicate function definitions we've already done. | 483 // want to duplicate function definitions we've already done. |
473 return | 484 return |
474 } | 485 } |
475 p.Written[name] = true | 486 p.Written[name] = true |
476 | 487 |
477 if *gccgo { | 488 if *gccgo { |
478 » » // we don't use wrappers with gccgo. | 489 » » p.writeGccgoOutputFunc(fgcc, n) |
479 return | 490 return |
480 } | 491 } |
481 | 492 |
482 ctype, _ := p.structType(n) | 493 ctype, _ := p.structType(n) |
483 | 494 |
484 // Gcc wrapper unpacks the C argument struct | 495 // Gcc wrapper unpacks the C argument struct |
485 // and calls the actual C function. | 496 // and calls the actual C function. |
486 fmt.Fprintf(fgcc, "void\n") | 497 fmt.Fprintf(fgcc, "void\n") |
487 fmt.Fprintf(fgcc, "_cgo%s%s(void *v)\n", cPrefix, n.Mangle) | 498 fmt.Fprintf(fgcc, "_cgo%s%s(void *v)\n", cPrefix, n.Mangle) |
488 fmt.Fprintf(fgcc, "{\n") | 499 fmt.Fprintf(fgcc, "{\n") |
489 if n.AddError { | 500 if n.AddError { |
490 fmt.Fprintf(fgcc, "\tint e;\n") // assuming 32 bit (see comment
above structType) | |
491 fmt.Fprintf(fgcc, "\terrno = 0;\n") | 501 fmt.Fprintf(fgcc, "\terrno = 0;\n") |
492 } | 502 } |
493 // We're trying to write a gcc struct that matches 6c/8c/5c's layout. | 503 // We're trying to write a gcc struct that matches 6c/8c/5c's layout. |
494 // Use packed attribute to force no padding in this struct in case | 504 // Use packed attribute to force no padding in this struct in case |
495 // gcc has different packing requirements. For example, | 505 // gcc has different packing requirements. For example, |
496 // on 386 Windows, gcc wants to 8-align int64s, but 8c does not. | 506 // on 386 Windows, gcc wants to 8-align int64s, but 8c does not. |
497 » fmt.Fprintf(fgcc, "\t%s __attribute__((__packed__)) *a = v;\n", ctype) | 507 » // Use __gcc_struct__ to work around http://gcc.gnu.org/PR52991 on x86, |
| 508 » // and http://golang.org/issue/5603. |
| 509 » extraAttr := "" |
| 510 » if !strings.Contains(p.gccBaseCmd()[0], "clang") && (goarch == "amd64" |
| goarch == "386") { |
| 511 » » extraAttr = ", __gcc_struct__" |
| 512 » } |
| 513 » fmt.Fprintf(fgcc, "\t%s __attribute__((__packed__%v)) *a = v;\n", ctype,
extraAttr) |
498 fmt.Fprintf(fgcc, "\t") | 514 fmt.Fprintf(fgcc, "\t") |
499 if t := n.FuncType.Result; t != nil { | 515 if t := n.FuncType.Result; t != nil { |
500 fmt.Fprintf(fgcc, "a->r = ") | 516 fmt.Fprintf(fgcc, "a->r = ") |
501 if c := t.C.String(); c[len(c)-1] == '*' { | 517 if c := t.C.String(); c[len(c)-1] == '*' { |
502 » » » fmt.Fprintf(fgcc, "(const %s) ", t.C) | 518 » » » fmt.Fprint(fgcc, "(__typeof__(a->r)) ") |
503 } | 519 } |
504 } | 520 } |
505 fmt.Fprintf(fgcc, "%s(", n.C) | 521 fmt.Fprintf(fgcc, "%s(", n.C) |
506 for i, t := range n.FuncType.Params { | 522 for i, t := range n.FuncType.Params { |
507 if i > 0 { | 523 if i > 0 { |
508 fmt.Fprintf(fgcc, ", ") | 524 fmt.Fprintf(fgcc, ", ") |
509 } | 525 } |
510 // We know the type params are correct, because | 526 // We know the type params are correct, because |
511 // the Go equivalents had good type params. | 527 // the Go equivalents had good type params. |
512 // However, our version of the type omits the magic | 528 // However, our version of the type omits the magic |
513 // words const and volatile, which can provoke | 529 // words const and volatile, which can provoke |
514 // C compiler warnings. Silence them by casting | 530 // C compiler warnings. Silence them by casting |
515 // all pointers to void*. (Eventually that will produce | 531 // all pointers to void*. (Eventually that will produce |
516 // other warnings.) | 532 // other warnings.) |
517 if c := t.C.String(); c[len(c)-1] == '*' { | 533 if c := t.C.String(); c[len(c)-1] == '*' { |
518 fmt.Fprintf(fgcc, "(void*)") | 534 fmt.Fprintf(fgcc, "(void*)") |
519 } | 535 } |
520 fmt.Fprintf(fgcc, "a->p%d", i) | 536 fmt.Fprintf(fgcc, "a->p%d", i) |
521 } | 537 } |
522 fmt.Fprintf(fgcc, ");\n") | 538 fmt.Fprintf(fgcc, ");\n") |
523 if n.AddError { | 539 if n.AddError { |
524 fmt.Fprintf(fgcc, "\t*(int*)(a->e) = errno;\n") | 540 fmt.Fprintf(fgcc, "\t*(int*)(a->e) = errno;\n") |
525 } | 541 } |
| 542 fmt.Fprintf(fgcc, "}\n") |
| 543 fmt.Fprintf(fgcc, "\n") |
| 544 } |
| 545 |
| 546 // Write out a wrapper for a function when using gccgo. This is a |
| 547 // simple wrapper that just calls the real function. We only need a |
| 548 // wrapper to support static functions in the prologue--without a |
| 549 // wrapper, we can't refer to the function, since the reference is in |
| 550 // a different file. |
| 551 func (p *Package) writeGccgoOutputFunc(fgcc *os.File, n *Name) { |
| 552 if t := n.FuncType.Result; t != nil { |
| 553 fmt.Fprintf(fgcc, "%s\n", t.C.String()) |
| 554 } else { |
| 555 fmt.Fprintf(fgcc, "void\n") |
| 556 } |
| 557 fmt.Fprintf(fgcc, "_cgo%s%s(", cPrefix, n.Mangle) |
| 558 for i, t := range n.FuncType.Params { |
| 559 if i > 0 { |
| 560 fmt.Fprintf(fgcc, ", ") |
| 561 } |
| 562 c := t.Typedef |
| 563 if c == "" { |
| 564 c = t.C.String() |
| 565 } |
| 566 fmt.Fprintf(fgcc, "%s p%d", c, i) |
| 567 } |
| 568 fmt.Fprintf(fgcc, ")\n") |
| 569 fmt.Fprintf(fgcc, "{\n") |
| 570 fmt.Fprintf(fgcc, "\t") |
| 571 if t := n.FuncType.Result; t != nil { |
| 572 fmt.Fprintf(fgcc, "return ") |
| 573 // Cast to void* to avoid warnings due to omitted qualifiers. |
| 574 if c := t.C.String(); c[len(c)-1] == '*' { |
| 575 fmt.Fprintf(fgcc, "(void*)") |
| 576 } |
| 577 } |
| 578 fmt.Fprintf(fgcc, "%s(", n.C) |
| 579 for i, t := range n.FuncType.Params { |
| 580 if i > 0 { |
| 581 fmt.Fprintf(fgcc, ", ") |
| 582 } |
| 583 // Cast to void* to avoid warnings due to omitted qualifiers. |
| 584 if c := t.C.String(); c[len(c)-1] == '*' { |
| 585 fmt.Fprintf(fgcc, "(void*)") |
| 586 } |
| 587 fmt.Fprintf(fgcc, "p%d", i) |
| 588 } |
| 589 fmt.Fprintf(fgcc, ");\n") |
526 fmt.Fprintf(fgcc, "}\n") | 590 fmt.Fprintf(fgcc, "}\n") |
527 fmt.Fprintf(fgcc, "\n") | 591 fmt.Fprintf(fgcc, "\n") |
528 } | 592 } |
529 | 593 |
530 // Write out the various stubs we need to support functions exported | 594 // Write out the various stubs we need to support functions exported |
531 // from Go so that they are callable from C. | 595 // from Go so that they are callable from C. |
532 func (p *Package) writeExports(fgo2, fc, fm *os.File) { | 596 func (p *Package) writeExports(fgo2, fc, fm *os.File) { |
533 fgcc := creat(*objDir + "_cgo_export.c") | 597 fgcc := creat(*objDir + "_cgo_export.c") |
534 fgcch := creat(*objDir + "_cgo_export.h") | 598 fgcch := creat(*objDir + "_cgo_export.h") |
535 | 599 |
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1151 typedef double GoFloat64; | 1215 typedef double GoFloat64; |
1152 typedef __complex float GoComplex64; | 1216 typedef __complex float GoComplex64; |
1153 typedef __complex double GoComplex128; | 1217 typedef __complex double GoComplex128; |
1154 | 1218 |
1155 typedef struct { char *p; GoInt n; } GoString; | 1219 typedef struct { char *p; GoInt n; } GoString; |
1156 typedef void *GoMap; | 1220 typedef void *GoMap; |
1157 typedef void *GoChan; | 1221 typedef void *GoChan; |
1158 typedef struct { void *t; void *v; } GoInterface; | 1222 typedef struct { void *t; void *v; } GoInterface; |
1159 typedef struct { void *data; GoInt len; GoInt cap; } GoSlice; | 1223 typedef struct { void *data; GoInt len; GoInt cap; } GoSlice; |
1160 ` | 1224 ` |
LEFT | RIGHT |