cgo: rename reserved field names like type

This commit renames reserved field names like `type` to `_type`, and in
turn renames those fields as well (recursively). This avoids name
clashes when a C struct contains a field named `type`, which is a
reserved keyword in Go.

For some details, see:
https://golang.org/cmd/cgo/#hdr-Go_references_to_C
Этот коммит содержится в:
Ayke van Laethem 2019-11-06 14:02:18 +01:00 коммит произвёл Ron Evans
родитель 0db403dc0c
коммит b41e58bcb4
4 изменённых файлов: 49 добавлений и 0 удалений

Просмотреть файл

@ -992,3 +992,29 @@ func (p *cgoPackage) walker(cursor *astutil.Cursor) bool {
}
return true
}
// renameFieldKeywords renames all reserved words in Go to some other field name
// with a "_" prefix. For example, it renames `type` to `_type`.
//
// See: https://golang.org/cmd/cgo/#hdr-Go_references_to_C
func renameFieldKeywords(fieldList *ast.FieldList) {
renameFieldName(fieldList, "type")
}
// renameFieldName renames a given field name to a name with a "_" prepended. It
// makes sure to do the same thing for any field sharing the same name.
func renameFieldName(fieldList *ast.FieldList, name string) {
var ident *ast.Ident
for _, f := range fieldList.List {
for _, n := range f.Names {
if n.Name == name {
ident = n
}
}
}
if ident == nil {
return
}
renameFieldName(fieldList, "_"+name)
ident.Name = "_" + ident.Name
}

Просмотреть файл

@ -605,6 +605,7 @@ func (p *cgoPackage) makeASTRecordType(cursor C.GoCXCursor, pos token.Pos) (*ast
}{fieldList, p, &inBitfield, &bitfieldNum, &bitfieldList})
defer storedRefs.Remove(ref)
C.tinygo_clang_visitChildren(cursor, C.CXCursorVisitor(C.tinygo_clang_struct_visitor), C.CXClientData(ref))
renameFieldKeywords(fieldList)
switch C.tinygo_clang_getCursorKind(cursor) {
case C.CXCursor_StructDecl:
return &ast.StructType{

16
cgo/testdata/types.go предоставленный
Просмотреть файл

@ -15,6 +15,18 @@ typedef struct point3d {
int z;
} point3d_t;
// Structs with reserved field names.
struct type1 {
// All these fields should be renamed.
int type;
int _type;
int __type;
};
struct type2 {
// This field should not be renamed.
int _type;
};
// Enums. These define constant numbers. All these constants must be given the
// correct number.
typedef enum option {
@ -66,6 +78,10 @@ var (
_ C.point3d_t
_ C.struct_point3d
// Structs with reserved field names.
_ C.struct_type1
_ C.struct_type2
// Enums (anonymous and named).
_ C.option_t
_ C.enum_option

6
cgo/testdata/types.out.go предоставленный
Просмотреть файл

@ -72,4 +72,10 @@ type C.struct_point3d struct {
y C.int
z C.int
}
type C.struct_type1 struct {
_type C.int
__type C.int
___type C.int
}
type C.struct_type2 struct{ _type C.int }
type C.enum_option C.int