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
Этот коммит содержится в:
родитель
0db403dc0c
коммит
b41e58bcb4
4 изменённых файлов: 49 добавлений и 0 удалений
26
cgo/cgo.go
26
cgo/cgo.go
|
@ -992,3 +992,29 @@ func (p *cgoPackage) walker(cursor *astutil.Cursor) bool {
|
||||||
}
|
}
|
||||||
return true
|
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})
|
}{fieldList, p, &inBitfield, &bitfieldNum, &bitfieldList})
|
||||||
defer storedRefs.Remove(ref)
|
defer storedRefs.Remove(ref)
|
||||||
C.tinygo_clang_visitChildren(cursor, C.CXCursorVisitor(C.tinygo_clang_struct_visitor), C.CXClientData(ref))
|
C.tinygo_clang_visitChildren(cursor, C.CXCursorVisitor(C.tinygo_clang_struct_visitor), C.CXClientData(ref))
|
||||||
|
renameFieldKeywords(fieldList)
|
||||||
switch C.tinygo_clang_getCursorKind(cursor) {
|
switch C.tinygo_clang_getCursorKind(cursor) {
|
||||||
case C.CXCursor_StructDecl:
|
case C.CXCursor_StructDecl:
|
||||||
return &ast.StructType{
|
return &ast.StructType{
|
||||||
|
|
16
cgo/testdata/types.go
предоставленный
16
cgo/testdata/types.go
предоставленный
|
@ -15,6 +15,18 @@ typedef struct point3d {
|
||||||
int z;
|
int z;
|
||||||
} point3d_t;
|
} 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
|
// Enums. These define constant numbers. All these constants must be given the
|
||||||
// correct number.
|
// correct number.
|
||||||
typedef enum option {
|
typedef enum option {
|
||||||
|
@ -66,6 +78,10 @@ var (
|
||||||
_ C.point3d_t
|
_ C.point3d_t
|
||||||
_ C.struct_point3d
|
_ C.struct_point3d
|
||||||
|
|
||||||
|
// Structs with reserved field names.
|
||||||
|
_ C.struct_type1
|
||||||
|
_ C.struct_type2
|
||||||
|
|
||||||
// Enums (anonymous and named).
|
// Enums (anonymous and named).
|
||||||
_ C.option_t
|
_ C.option_t
|
||||||
_ C.enum_option
|
_ C.enum_option
|
||||||
|
|
6
cgo/testdata/types.out.go
предоставленный
6
cgo/testdata/types.out.go
предоставленный
|
@ -72,4 +72,10 @@ type C.struct_point3d struct {
|
||||||
y C.int
|
y C.int
|
||||||
z 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
|
type C.enum_option C.int
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче