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
|
||||
}
|
||||
|
||||
// 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
предоставленный
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
предоставленный
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
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче