aboutsummaryrefslogtreecommitdiffhomepage
path: root/cgo
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2022-10-30 21:12:57 +0100
committerRon Evans <[email protected]>2022-11-02 21:21:40 +0100
commitaaa860f1543add7d7b1e84db03773dad1dce2310 (patch)
tree90253d15a310a4a48fa1a29743f9a2d34249b660 /cgo
parentbce0516394f7446598d169867c31a708443dd2a4 (diff)
downloadtinygo-aaa860f1543add7d7b1e84db03773dad1dce2310.tar.gz
tinygo-aaa860f1543add7d7b1e84db03773dad1dce2310.zip
cgo: support anonymous enums included in multiple Go files
Anonymous enums (often used in typedefs) triggered a problem that was already solved for structs but wasn't yet solved for enums. So this patch generalizes the code to work for both structs and enums, and adds testing for both.
Diffstat (limited to 'cgo')
-rw-r--r--cgo/libclang.go39
1 files changed, 24 insertions, 15 deletions
diff --git a/cgo/libclang.go b/cgo/libclang.go
index 3c0d196df..27ac1b576 100644
--- a/cgo/libclang.go
+++ b/cgo/libclang.go
@@ -533,6 +533,26 @@ func tinygo_clang_globals_visitor(c, parent C.GoCXCursor, client_data C.CXClient
return C.CXChildVisit_Continue
}
+// Get the precise location in the source code. Used for uniquely identifying
+// source locations.
+func (f *cgoFile) getUniqueLocationID(pos token.Pos, cursor C.GoCXCursor) interface{} {
+ clangLocation := C.tinygo_clang_getCursorLocation(cursor)
+ var file C.CXFile
+ var line C.unsigned
+ var column C.unsigned
+ C.clang_getFileLocation(clangLocation, &file, &line, &column, nil)
+ location := token.Position{
+ Filename: getString(C.clang_getFileName(file)),
+ Line: int(line),
+ Column: int(column),
+ }
+ if location.Filename == "" || location.Line == 0 {
+ // Not sure when this would happen, but protect from it anyway.
+ f.addError(pos, "could not find file/line information")
+ }
+ return location
+}
+
// getCursorPosition returns a usable token.Pos from a libclang cursor.
func (p *cgoPackage) getCursorPosition(cursor C.GoCXCursor) token.Pos {
return p.getClangLocationPosition(C.tinygo_clang_getCursorLocation(cursor), C.tinygo_clang_Cursor_getTranslationUnit(cursor))
@@ -788,20 +808,7 @@ func (f *cgoFile) makeASTType(typ C.CXType, pos token.Pos) ast.Expr {
}
if name == "" {
// Anonymous record, probably inside a typedef.
- clangLocation := C.tinygo_clang_getCursorLocation(cursor)
- var file C.CXFile
- var line C.unsigned
- var column C.unsigned
- C.clang_getFileLocation(clangLocation, &file, &line, &column, nil)
- location := token.Position{
- Filename: getString(C.clang_getFileName(file)),
- Line: int(line),
- Column: int(column),
- }
- if location.Filename == "" || location.Line == 0 {
- // Not sure when this would happen, but protect from it anyway.
- f.addError(pos, "could not find file/line information")
- }
+ location := f.getUniqueLocationID(pos, cursor)
name = f.getUnnamedDeclName("_Ctype_"+cgoRecordPrefix+"__", location)
} else {
name = cgoRecordPrefix + name
@@ -814,7 +821,9 @@ func (f *cgoFile) makeASTType(typ C.CXType, pos token.Pos) ast.Expr {
cursor := C.tinygo_clang_getTypeDeclaration(typ)
name := getString(C.tinygo_clang_getCursorSpelling(cursor))
if name == "" {
- name = f.getUnnamedDeclName("_Ctype_enum___", cursor)
+ // Anonymous enum, probably inside a typedef.
+ location := f.getUniqueLocationID(pos, cursor)
+ name = f.getUnnamedDeclName("_Ctype_enum___", location)
} else {
name = "enum_" + name
}