MCPcopy Index your code
hub / github.com/tinygo-org/tinygo / walker

Method walker

cgo/cgo.go:1388–1461  ·  view source on GitHub ↗

walker replaces all "C". expressions to literal "C. " expressions. Such expressions are impossible to write in Go (a dot cannot be used in the middle of a name) so in practice all C identifiers live in a separate namespace (no _Cgo_ hacks like in gc).

(cursor *astutil.Cursor, names map[string]clangCursor)

Source from the content-addressed store, hash-verified

1386// used in the middle of a name) so in practice all C identifiers live in a
1387// separate namespace (no _Cgo_ hacks like in gc).
1388func (f *cgoFile) walker(cursor *astutil.Cursor, names map[string]clangCursor) bool {
1389 switch node := cursor.Node().(type) {
1390 case *ast.AssignStmt:
1391 // An assign statement could be something like this:
1392 //
1393 // val, errno := C.some_func()
1394 //
1395 // Check whether it looks like that, and if so, read the errno value and
1396 // return it as the second return value. The call will be transformed
1397 // into something like this:
1398 //
1399 // val, errno := C.some_func(), C.__get_errno()
1400 if len(node.Lhs) != 2 || len(node.Rhs) != 1 {
1401 return true
1402 }
1403 rhs, ok := node.Rhs[0].(*ast.CallExpr)
1404 if !ok {
1405 return true
1406 }
1407 fun, ok := rhs.Fun.(*ast.SelectorExpr)
1408 if !ok {
1409 return true
1410 }
1411 x, ok := fun.X.(*ast.Ident)
1412 if !ok {
1413 return true
1414 }
1415 if found, ok := names[fun.Sel.Name]; ok && x.Name == "C" {
1416 // Replace "C"."some_func" into "C.somefunc".
1417 rhs.Fun = &ast.Ident{
1418 NamePos: x.NamePos,
1419 Name: f.getASTDeclName(fun.Sel.Name, found, true),
1420 }
1421 // Add the errno value as the second value in the statement.
1422 node.Rhs = append(node.Rhs, &ast.CallExpr{
1423 Fun: &ast.Ident{
1424 NamePos: node.Lhs[1].End(),
1425 Name: "_Cgo___get_errno",
1426 },
1427 })
1428 }
1429 case *ast.CallExpr:
1430 fun, ok := node.Fun.(*ast.SelectorExpr)
1431 if !ok {
1432 return true
1433 }
1434 x, ok := fun.X.(*ast.Ident)
1435 if !ok {
1436 return true
1437 }
1438 if found, ok := names[fun.Sel.Name]; ok && x.Name == "C" {
1439 node.Fun = &ast.Ident{
1440 NamePos: x.NamePos,
1441 Name: f.getASTDeclName(fun.Sel.Name, found, true),
1442 }
1443 }
1444 case *ast.SelectorExpr:
1445 x, ok := node.X.(*ast.Ident)

Callers 1

ProcessFunction · 0.80

Calls 2

getASTDeclNameMethod · 0.95
EndMethod · 0.65

Tested by

no test coverage detected