Handle multi anonymous struct with same USR (#559)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e996b1c..45b5993 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 7.2.11
+
+- Fix invalid struct/enum member references due to multiple anonymous struct/enum in a declaration.
+
# 7.2.10
- Generate parameter names in function pointer fields and typedefs.
diff --git a/lib/src/header_parser/utils.dart b/lib/src/header_parser/utils.dart
index a674618..f03df3f 100644
--- a/lib/src/header_parser/utils.dart
+++ b/lib/src/header_parser/utils.dart
@@ -60,7 +60,11 @@
extension CXCursorExt on clang_types.CXCursor {
String usr() {
- return clang.clang_getCursorUSR(this).toStringAndDispose();
+ var res = clang.clang_getCursorUSR(this).toStringAndDispose();
+ if (isAnonymousRecordDecl()) {
+ res += "@offset:${sourceFileOffset()}";
+ }
+ return res;
}
/// Returns the kind int from [clang_types.CXCursorKind].
@@ -124,6 +128,17 @@
return s;
}
+ int sourceFileOffset() {
+ final cxsource = clang.clang_getCursorLocation(this);
+ final cxOffset = calloc<UnsignedInt>();
+
+ // Puts the values in these pointers.
+ clang.clang_getFileLocation(cxsource, nullptr, nullptr, nullptr, cxOffset);
+ final offset = cxOffset.value;
+ calloc.free(cxOffset);
+ return offset;
+ }
+
/// Returns whether the file that the cursor is inside is a system header.
bool isInSystemHeader() {
final location = clang.clang_getCursorLocation(this);
diff --git a/pubspec.yaml b/pubspec.yaml
index 6c2e147..bebcaf5 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -3,7 +3,7 @@
# BSD-style license that can be found in the LICENSE file.
name: ffigen
-version: 7.2.10
+version: 7.2.11
description: Generator for FFI bindings, using LibClang to parse C header files.
repository: https://github.com/dart-lang/ffigen
diff --git a/test/header_parser_tests/expected_bindings/_expected_unions_bindings.dart b/test/header_parser_tests/expected_bindings/_expected_unions_bindings.dart
index 585ab9a..b35cd3d 100644
--- a/test/header_parser_tests/expected_bindings/_expected_unions_bindings.dart
+++ b/test/header_parser_tests/expected_bindings/_expected_unions_bindings.dart
@@ -63,3 +63,19 @@
class Union4 extends ffi.Opaque {}
class Union5 extends ffi.Opaque {}
+
+class Union6 extends ffi.Union {
+ external UnnamedUnion1 unnamed;
+
+ external UnnamedUnion2 unnamed1;
+}
+
+class UnnamedUnion1 extends ffi.Union {
+ @ffi.Float()
+ external double a;
+}
+
+class UnnamedUnion2 extends ffi.Union {
+ @ffi.Float()
+ external double b;
+}
diff --git a/test/header_parser_tests/unions.h b/test/header_parser_tests/unions.h
index 1bd9ae1..e7d86ff 100644
--- a/test/header_parser_tests/unions.h
+++ b/test/header_parser_tests/unions.h
@@ -32,6 +32,20 @@
union Union3 s; // Incomplete nested union.
};
+// Multiple anonymous declarations
+union Union6
+{
+ union
+ {
+ float a;
+ };
+
+ union
+ {
+ float b;
+ };
+};
+
void func1(union Union2 *s);
// Incomplete array parameter will be treated as a pointer.