C.ulonglong (unsigned long long), C.float, C.double,
C.complexfloat (complex float), and C.complexdouble (complex double).
The C type void* is represented by Go's unsafe.Pointer.
+The C sized integer types (int8_t, uint8_t, …) are represented by their Go
+counterparts (int8, uint8, …).
The C types __int128_t and __uint128_t are represented by [16]byte.
A few special C types which would normally be represented by a pointer
They will be available in the C code as:
- extern int64 MyFunction(int arg1, int arg2, GoString arg3);
+ extern int64_t MyFunction(int arg1, int arg2, GoString arg3);
extern struct MyFunction2_return MyFunction2(int arg1, int arg2, GoString arg3);
found in the _cgo_export.h generated header, after any preambles
"internal/xcoff"
"math"
"os"
+ "regexp"
"strconv"
"strings"
"unicode"
ptrSize int64
intSize int64
+
+ exactWidthIntegerTypes map[string]*Type
}
var tagGen int
} else {
c.goVoidPtr = c.Ident("unsafe.Pointer")
}
+
+ c.exactWidthIntegerTypes = make(map[string]*Type)
+ for _, t := range []ast.Expr{
+ c.int8, c.int16, c.int32, c.int64,
+ c.uint8, c.uint16, c.uint32, c.uint64,
+ } {
+ name := t.(*ast.Ident).Name
+ u := new(Type)
+ *u = *goTypes[name]
+ if u.Align > ptrSize {
+ u.Align = ptrSize
+ }
+ u.Go = t
+ c.exactWidthIntegerTypes[name] = u
+ }
}
// base strips away qualifiers and typedefs to get the underlying type
t.Align = c.ptrSize
break
}
+ // Exact-width integer types. These are always compatible with
+ // the corresponding Go types since the C standard requires
+ // them to have no padding bit and use the two’s complement
+ // representation.
+ if exactWidthIntegerType.MatchString(dt.Name) {
+ sub := c.Type(dt.Type, pos)
+ u := c.exactWidthIntegerTypes[strings.TrimSuffix(dt.Name, "_t")]
+ if sub.Size != u.Size {
+ fatalf("%s: unexpected size: %d vs. %d – %s", lineno(pos), sub.Size, u.Size, dtype)
+ }
+ if sub.Align != u.Align {
+ fatalf("%s: unexpected alignment: %d vs. %d – %s", lineno(pos), sub.Align, u.Align, dtype)
+ }
+ t.Size = u.Size
+ t.Align = u.Align
+ t.Go = u.Go
+ break
+ }
name := c.Ident("_Ctype_" + dt.Name)
goIdent[name.Name] = name
sub := c.Type(dt.Type, pos)
return t
}
+var exactWidthIntegerType = regexp.MustCompile(`^u?int(8|16|32|64)_t$`)
+
// isStructUnionClass reports whether the type described by the Go syntax x
// is a struct, union, or class with a tag.
func isStructUnionClass(x ast.Expr) bool {
// Map predeclared Go types to Type.
var goTypes = map[string]*Type{
- "bool": {Size: 1, Align: 1, C: c("GoUint8")},
- "byte": {Size: 1, Align: 1, C: c("GoUint8")},
+ "bool": {Size: 1, Align: 1, C: c("uint8_t")},
+ "byte": {Size: 1, Align: 1, C: c("uint8_t")},
"int": {Size: 0, Align: 0, C: c("GoInt")},
"uint": {Size: 0, Align: 0, C: c("GoUint")},
- "rune": {Size: 4, Align: 4, C: c("GoInt32")},
- "int8": {Size: 1, Align: 1, C: c("GoInt8")},
- "uint8": {Size: 1, Align: 1, C: c("GoUint8")},
- "int16": {Size: 2, Align: 2, C: c("GoInt16")},
- "uint16": {Size: 2, Align: 2, C: c("GoUint16")},
- "int32": {Size: 4, Align: 4, C: c("GoInt32")},
- "uint32": {Size: 4, Align: 4, C: c("GoUint32")},
- "int64": {Size: 8, Align: 8, C: c("GoInt64")},
- "uint64": {Size: 8, Align: 8, C: c("GoUint64")},
+ "rune": {Size: 4, Align: 4, C: c("int32_t")},
+ "int8": {Size: 1, Align: 1, C: c("int8_t")},
+ "uint8": {Size: 1, Align: 1, C: c("uint8_t")},
+ "int16": {Size: 2, Align: 2, C: c("int16_t")},
+ "uint16": {Size: 2, Align: 2, C: c("uint16_t")},
+ "int32": {Size: 4, Align: 4, C: c("int32_t")},
+ "uint32": {Size: 4, Align: 4, C: c("uint32_t")},
+ "int64": {Size: 8, Align: 8, C: c("int64_t")},
+ "uint64": {Size: 8, Align: 8, C: c("uint64_t")},
"float32": {Size: 4, Align: 4, C: c("GoFloat32")},
"float64": {Size: 8, Align: 8, C: c("GoFloat64")},
"complex64": {Size: 8, Align: 4, C: c("GoComplex64")},
#ifndef GO_CGO_PROLOGUE_H
#define GO_CGO_PROLOGUE_H
-typedef signed char GoInt8;
-typedef unsigned char GoUint8;
-typedef short GoInt16;
-typedef unsigned short GoUint16;
-typedef int GoInt32;
-typedef unsigned int GoUint32;
-typedef long long GoInt64;
-typedef unsigned long long GoUint64;
-typedef GoIntGOINTBITS GoInt;
-typedef GoUintGOINTBITS GoUint;
+#include <stdint.h>
+
+typedef intGOINTBITS_t GoInt;
+typedef uintGOINTBITS_t GoUint;
typedef __SIZE_TYPE__ GoUintptr;
typedef float GoFloat32;
typedef double GoFloat64;