Skip to content

Commit c4867c8

Browse files
aykevldeadprogram
authored andcommitted
cgo: define idents referenced only from macros
1 parent 8068419 commit c4867c8

File tree

6 files changed

+28
-7
lines changed

6 files changed

+28
-7
lines changed

cgo/cgo.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -1148,7 +1148,7 @@ func (f *cgoFile) getASTDeclName(name string, found clangCursor, iscall bool) st
11481148
if alias := cgoAliases["C."+name]; alias != "" {
11491149
return alias
11501150
}
1151-
node := f.getASTDeclNode(name, found, iscall)
1151+
node := f.getASTDeclNode(name, found)
11521152
if node, ok := node.(*ast.FuncDecl); ok {
11531153
if !iscall {
11541154
return node.Name.Name + "$funcaddr"
@@ -1160,7 +1160,7 @@ func (f *cgoFile) getASTDeclName(name string, found clangCursor, iscall bool) st
11601160

11611161
// getASTDeclNode will declare the given C AST node (if not already defined) and
11621162
// returns it.
1163-
func (f *cgoFile) getASTDeclNode(name string, found clangCursor, iscall bool) ast.Node {
1163+
func (f *cgoFile) getASTDeclNode(name string, found clangCursor) ast.Node {
11641164
if node, ok := f.defined[name]; ok {
11651165
// Declaration was found in the current file, so return it immediately.
11661166
return node

cgo/const.go

+19-3
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ func init() {
5454
}
5555

5656
// parseConst parses the given string as a C constant.
57-
func parseConst(pos token.Pos, fset *token.FileSet, value string) (ast.Expr, *scanner.Error) {
58-
t := newTokenizer(pos, fset, value)
57+
func parseConst(pos token.Pos, fset *token.FileSet, value string, f *cgoFile) (ast.Expr, *scanner.Error) {
58+
t := newTokenizer(pos, fset, value, f)
5959
expr, err := parseConstExpr(t, precedenceLowest)
6060
t.Next()
6161
if t.curToken != token.EOF {
@@ -96,6 +96,20 @@ func parseConstExpr(t *tokenizer, precedence int) (ast.Expr, *scanner.Error) {
9696
}
9797

9898
func parseIdent(t *tokenizer) (ast.Expr, *scanner.Error) {
99+
// Normally the name is something defined in the file (like another macro)
100+
// which we get the declaration from using getASTDeclName.
101+
// This ensures that names that are only referenced inside a macro are still
102+
// getting defined.
103+
if t.f != nil {
104+
if cursor, ok := t.f.names[t.curValue]; ok {
105+
return &ast.Ident{
106+
NamePos: t.curPos,
107+
Name: t.f.getASTDeclName(t.curValue, cursor, false),
108+
}, nil
109+
}
110+
}
111+
112+
// t.f is nil during testing. This is a fallback.
99113
return &ast.Ident{
100114
NamePos: t.curPos,
101115
Name: "C." + t.curValue,
@@ -164,6 +178,7 @@ func unexpectedToken(t *tokenizer, expected token.Token) *scanner.Error {
164178

165179
// tokenizer reads C source code and converts it to Go tokens.
166180
type tokenizer struct {
181+
f *cgoFile
167182
curPos, peekPos token.Pos
168183
fset *token.FileSet
169184
curToken, peekToken token.Token
@@ -173,8 +188,9 @@ type tokenizer struct {
173188

174189
// newTokenizer initializes a new tokenizer, positioned at the first token in
175190
// the string.
176-
func newTokenizer(start token.Pos, fset *token.FileSet, buf string) *tokenizer {
191+
func newTokenizer(start token.Pos, fset *token.FileSet, buf string, f *cgoFile) *tokenizer {
177192
t := &tokenizer{
193+
f: f,
178194
peekPos: start,
179195
fset: fset,
180196
buf: buf,

cgo/const_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func TestParseConst(t *testing.T) {
5959
} {
6060
fset := token.NewFileSet()
6161
startPos := fset.AddFile("", -1, 1000).Pos(0)
62-
expr, err := parseConst(startPos, fset, tc.C)
62+
expr, err := parseConst(startPos, fset, tc.C, nil)
6363
s := "<invalid>"
6464
if err != nil {
6565
if !strings.HasPrefix(tc.Go, "error: ") {

cgo/libclang.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
408408
if pos != token.NoPos {
409409
tokenPos = pos + token.Pos(len(name))
410410
}
411-
expr, scannerError := parseConst(tokenPos, f.fset, value)
411+
expr, scannerError := parseConst(tokenPos, f.fset, value, f)
412412
if scannerError != nil {
413413
f.errors = append(f.errors, *scannerError)
414414
return nil, nil

cgo/testdata/const.go

+3
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@ package main
33
/*
44
#define foo 3
55
#define bar foo
6+
#define unreferenced 4
7+
#define referenced unreferenced
68
*/
79
import "C"
810

911
const (
1012
Foo = C.foo
1113
Bar = C.bar
14+
Baz = C.referenced
1215
)

cgo/testdata/const.out.go

+2
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,5 @@ type (
4747

4848
const C.foo = 3
4949
const C.bar = C.foo
50+
const C.unreferenced = 4
51+
const C.referenced = C.unreferenced

0 commit comments

Comments
 (0)