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)
| 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). |
| 1388 | func (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) |
no test coverage detected