Fixes for typedefs (#75)
closes #71.
* Fixed missing typedef used in function's return type.
* Named function typedefs are now reused.
* Added tests for typedef generation.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b773ee0..705ba58 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+# 0.2.1
+- Fixed missing/duplicate typedef generation.
+
# 0.2.0
- Updated header config. Header `entry-points` and `include-directives` are now specified under `headers` key. Glob syntax is allowed.
- Updated declaration `include`/`exclude` config. These are now specified as a list.
diff --git a/example/libclang-example/generated_bindings.dart b/example/libclang-example/generated_bindings.dart
index 6148331..34a5cd2 100644
--- a/example/libclang-example/generated_bindings.dart
+++ b/example/libclang-example/generated_bindings.dart
@@ -1889,7 +1889,7 @@
/// is inspecting the inclusions in the PCH file itself).
void clang_getInclusions(
ffi.Pointer<CXTranslationUnitImpl> tu,
- ffi.Pointer<ffi.NativeFunction<CXInclusionVisitor_1>> visitor,
+ ffi.Pointer<ffi.NativeFunction<CXInclusionVisitor>> visitor,
ffi.Pointer<ffi.Void> client_data,
) {
_clang_getInclusions ??= _dylib.lookupFunction<_c_clang_getInclusions,
@@ -3266,15 +3266,15 @@
class IndexerCallbacks extends ffi.Struct {
/// Called periodically to check whether indexing should be aborted.
/// Should return 0 to continue, and non-zero to abort.
- ffi.Pointer<ffi.NativeFunction<_typedefC_3>> abortQuery;
+ ffi.Pointer<ffi.NativeFunction<_typedefC_2>> abortQuery;
/// Called at the end of indexing; passes the complete diagnostic set.
- ffi.Pointer<ffi.NativeFunction<_typedefC_4>> diagnostic;
+ ffi.Pointer<ffi.NativeFunction<_typedefC_3>> diagnostic;
- ffi.Pointer<ffi.NativeFunction<_typedefC_5>> enteredMainFile;
+ ffi.Pointer<ffi.NativeFunction<_typedefC_4>> enteredMainFile;
/// Called when a file gets \#included/\#imported.
- ffi.Pointer<ffi.NativeFunction<_typedefC_6>> ppIncludedFile;
+ ffi.Pointer<ffi.NativeFunction<_typedefC_5>> ppIncludedFile;
/// Called when a AST file (PCH or module) gets imported.
///
@@ -3282,15 +3282,15 @@
/// the entities in an AST file). The recommended action is that, if the AST
/// file is not already indexed, to initiate a new indexing job specific to
/// the AST file.
- ffi.Pointer<ffi.NativeFunction<_typedefC_7>> importedASTFile;
+ ffi.Pointer<ffi.NativeFunction<_typedefC_6>> importedASTFile;
/// Called at the beginning of indexing a translation unit.
- ffi.Pointer<ffi.NativeFunction<_typedefC_8>> startedTranslationUnit;
+ ffi.Pointer<ffi.NativeFunction<_typedefC_7>> startedTranslationUnit;
- ffi.Pointer<ffi.NativeFunction<_typedefC_9>> indexDeclaration;
+ ffi.Pointer<ffi.NativeFunction<_typedefC_8>> indexDeclaration;
/// Called to index a reference of an entity.
- ffi.Pointer<ffi.NativeFunction<_typedefC_10>> indexEntityReference;
+ ffi.Pointer<ffi.NativeFunction<_typedefC_9>> indexEntityReference;
}
const int CINDEX_VERSION_MAJOR = 0;
@@ -4147,7 +4147,7 @@
int isEnabled,
);
-typedef CXInclusionVisitor_1 = ffi.Void Function(
+typedef CXInclusionVisitor = ffi.Void Function(
ffi.Pointer<ffi.Void>,
ffi.Pointer<CXSourceLocation>,
ffi.Uint32,
@@ -4156,13 +4156,13 @@
typedef _c_clang_getInclusions = ffi.Void Function(
ffi.Pointer<CXTranslationUnitImpl> tu,
- ffi.Pointer<ffi.NativeFunction<CXInclusionVisitor_1>> visitor,
+ ffi.Pointer<ffi.NativeFunction<CXInclusionVisitor>> visitor,
ffi.Pointer<ffi.Void> client_data,
);
typedef _dart_clang_getInclusions = void Function(
ffi.Pointer<CXTranslationUnitImpl> tu,
- ffi.Pointer<ffi.NativeFunction<CXInclusionVisitor_1>> visitor,
+ ffi.Pointer<ffi.NativeFunction<CXInclusionVisitor>> visitor,
ffi.Pointer<ffi.Void> client_data,
);
@@ -4486,12 +4486,18 @@
ffi.Pointer<CXTranslationUnitImpl> arg5,
);
-typedef _typedefC_3 = ffi.Int32 Function(
+typedef _typedefC_2 = ffi.Int32 Function(
ffi.Pointer<ffi.Void>,
ffi.Pointer<ffi.Void>,
);
-typedef _typedefC_4 = ffi.Void Function(
+typedef _typedefC_3 = ffi.Void Function(
+ ffi.Pointer<ffi.Void>,
+ ffi.Pointer<ffi.Void>,
+ ffi.Pointer<ffi.Void>,
+);
+
+typedef _typedefC_4 = ffi.Pointer<ffi.Void> Function(
ffi.Pointer<ffi.Void>,
ffi.Pointer<ffi.Void>,
ffi.Pointer<ffi.Void>,
@@ -4499,31 +4505,25 @@
typedef _typedefC_5 = ffi.Pointer<ffi.Void> Function(
ffi.Pointer<ffi.Void>,
- ffi.Pointer<ffi.Void>,
- ffi.Pointer<ffi.Void>,
+ ffi.Pointer<CXIdxIncludedFileInfo>,
);
typedef _typedefC_6 = ffi.Pointer<ffi.Void> Function(
ffi.Pointer<ffi.Void>,
- ffi.Pointer<CXIdxIncludedFileInfo>,
+ ffi.Pointer<CXIdxImportedASTFileInfo>,
);
typedef _typedefC_7 = ffi.Pointer<ffi.Void> Function(
ffi.Pointer<ffi.Void>,
- ffi.Pointer<CXIdxImportedASTFileInfo>,
-);
-
-typedef _typedefC_8 = ffi.Pointer<ffi.Void> Function(
- ffi.Pointer<ffi.Void>,
ffi.Pointer<ffi.Void>,
);
-typedef _typedefC_9 = ffi.Void Function(
+typedef _typedefC_8 = ffi.Void Function(
ffi.Pointer<ffi.Void>,
ffi.Pointer<CXIdxDeclInfo>,
);
-typedef _typedefC_10 = ffi.Void Function(
+typedef _typedefC_9 = ffi.Void Function(
ffi.Pointer<ffi.Void>,
ffi.Pointer<CXIdxEntityRefInfo>,
);
diff --git a/lib/src/code_generator/func.dart b/lib/src/code_generator/func.dart
index 0e24fb1..551dae9 100644
--- a/lib/src/code_generator/func.dart
+++ b/lib/src/code_generator/func.dart
@@ -58,16 +58,16 @@
if (_typedefDependencies == null) {
_typedefDependencies = <Typedef>[];
- /// Ensure name conflicts are resolved for [cType] and [dartType] typedefs.
- cType.name = _uniqueTypedefName(cType.name, w);
- dartType.name = _uniqueTypedefName(dartType.name, w);
+ // Add typedef's required by return type.
+ final returnTypeBase = returnType.getBaseType();
+ if (returnTypeBase.broadType == BroadType.NativeFunction) {
+ _typedefDependencies.add(returnTypeBase.nativeFunc);
+ }
// Add typedef's required by parameters.
for (final p in parameters) {
final base = p.type.getBaseType();
if (base.broadType == BroadType.NativeFunction) {
- // Resolve name conflicts in typedef's required by parameters before using.
- base.nativeFunc.name = _uniqueTypedefName(base.nativeFunc.name, w);
_typedefDependencies.add(base.nativeFunc);
}
}
@@ -79,21 +79,6 @@
return _typedefDependencies;
}
- /// Checks if typedef name is unique in both top level and wrapper level.
- /// And only marks it as used at top-level.
- String _uniqueTypedefName(String name, Writer w) {
- final base = name;
- var uniqueName = name;
- var suffix = 0;
- while (w.topLevelUniqueNamer.isUsed(uniqueName) ||
- w.wrapperLevelUniqueNamer.isUsed(uniqueName)) {
- suffix++;
- uniqueName = base + suffix.toString();
- }
- w.topLevelUniqueNamer.markUsed(uniqueName);
- return uniqueName;
- }
-
Typedef _cType, _dartType;
Typedef get cType => _cType ??= Typedef(
name: '_c_$name',
@@ -151,6 +136,6 @@
String name;
final Type type;
- Parameter({String originalName, this.name, @required this.type})
+ Parameter({String originalName, this.name = '', @required this.type})
: originalName = originalName ?? name;
}
diff --git a/lib/src/code_generator/struc.dart b/lib/src/code_generator/struc.dart
index 24e6727..f241fd7 100644
--- a/lib/src/code_generator/struc.dart
+++ b/lib/src/code_generator/struc.dart
@@ -66,8 +66,6 @@
for (final m in members) {
final base = m.type.getBaseType();
if (base.broadType == BroadType.NativeFunction) {
- base.nativeFunc.name =
- w.topLevelUniqueNamer.makeUnique(base.nativeFunc.name);
_typedefDependencies.add(base.nativeFunc);
}
}
diff --git a/lib/src/code_generator/writer.dart b/lib/src/code_generator/writer.dart
index 06ea9d7..e09b9ed 100644
--- a/lib/src/code_generator/writer.dart
+++ b/lib/src/code_generator/writer.dart
@@ -115,16 +115,20 @@
s.write("import 'dart:ffi' as $ffiLibraryPrefix;\n");
s.write('\n');
- final dependencies = <Typedef>[];
+ // Will contain duplicates, must be processed.
+ final rawDependencies = <Typedef>[];
/// Get typedef dependencies, these will be written at the end.
for (final b in lookUpBindings) {
- dependencies.addAll(b.getTypedefDependencies(this));
+ rawDependencies.addAll(b.getTypedefDependencies(this));
}
for (final b in noLookUpBindings) {
- dependencies.addAll(b.getTypedefDependencies(this));
+ rawDependencies.addAll(b.getTypedefDependencies(this));
}
+ // Dependencies, processed to remove duplicates and resolve name conflicts.
+ final dependencies = processDependencies(rawDependencies);
+
/// Write [lookUpBindings].
if (lookUpBindings.isNotEmpty) {
// Write doc comment for wrapper class.
@@ -160,4 +164,29 @@
return s.toString();
}
+
+ /// Removes duplicates and resolves all name conflicts.
+ Set<Typedef> processDependencies(List<Typedef> dependencies) {
+ final processedDependencies = dependencies.toSet();
+
+ for (final d in processedDependencies) {
+ d.name = _makeUniqueTypedefName(d.name);
+ }
+ return processedDependencies;
+ }
+
+ /// Returns a typedef name that is unique in both top level and wrapper level,
+ /// ans only marks it as used at top-level.
+ String _makeUniqueTypedefName(String name) {
+ final base = name;
+ var uniqueName = name;
+ var suffix = 0;
+ while (topLevelUniqueNamer.isUsed(uniqueName) ||
+ wrapperLevelUniqueNamer.isUsed(uniqueName)) {
+ suffix++;
+ uniqueName = base + suffix.toString();
+ }
+ topLevelUniqueNamer.markUsed(uniqueName);
+ return uniqueName;
+ }
}
diff --git a/lib/src/header_parser/type_extractor/extractor.dart b/lib/src/header_parser/type_extractor/extractor.dart
index c76c8ea..d73e029 100644
--- a/lib/src/header_parser/type_extractor/extractor.dart
+++ b/lib/src/header_parser/type_extractor/extractor.dart
@@ -56,8 +56,11 @@
return Type.nativeType(
enumNativeType,
);
- case clang_types.CXTypeKind
- .CXType_FunctionProto: // Primarily used for function pointers.
+ case clang_types.CXTypeKind.CXType_FunctionProto:
+ // Primarily used for function pointers.
+ return _extractFromFunctionProto(cxtype, parentName);
+ case clang_types.CXTypeKind.CXType_FunctionNoProto:
+ // Primarily used for function types with zero arguments.
return _extractFromFunctionProto(cxtype, parentName);
case clang_types.CXTypeKind
.CXType_ConstantArray: // Primarily used for constant array in struct members.
@@ -132,12 +135,9 @@
Pointer<clang_types.CXType> cxtype, String parentName) {
var name = parentName;
- // Set a name for typedefc incase it was null or empty.
- if (name == null || name == '') {
- name = incrementalNamer.name('_typedefC');
- } else {
- name = incrementalNamer.name(name);
- }
+ // An empty name means the function prototype was declared in-place, instead
+ // of using a typedef.
+ name = name ?? '';
final _parameters = <Parameter>[];
final totalArgs = clang.clang_getNumArgTypes_wrap(cxtype);
for (var i = 0; i < totalArgs; i++) {
@@ -154,13 +154,23 @@
Parameter(name: '', type: pt),
);
}
- final typedefC = Typedef(
- name: name,
- typedefType: TypedefType.C,
- parameters: _parameters,
- returnType:
- clang.clang_getResultType_wrap(cxtype).toCodeGenTypeAndDispose(),
- );
+
+ Typedef typedefC;
+ if (bindingsIndex.isSeenFunctionTypedef(name)) {
+ typedefC = bindingsIndex.getSeenFunctionTypedef(name);
+ } else {
+ typedefC = Typedef(
+ name: name.isNotEmpty ? name : incrementalNamer.name('_typedefC'),
+ typedefType: TypedefType.C,
+ parameters: _parameters,
+ returnType:
+ clang.clang_getResultType_wrap(cxtype).toCodeGenTypeAndDispose(),
+ );
+ // Add to seen, if name isn't empty.
+ if (name.isNotEmpty) {
+ bindingsIndex.addFunctionTypedefToSeen(name, typedefC);
+ }
+ }
return Type.nativeFunc(typedefC);
}
diff --git a/lib/src/header_parser/utils.dart b/lib/src/header_parser/utils.dart
index 6d8e159..54fcc8b 100644
--- a/lib/src/header_parser/utils.dart
+++ b/lib/src/header_parser/utils.dart
@@ -330,6 +330,8 @@
final Map<String, Func> _functions = {};
final Map<String, EnumClass> _enumClass = {};
final Map<String, String> _macros = {};
+ // Stores only named typedefC used in NativeFunc.
+ final Map<String, Typedef> _functionTypedefs = {};
bool isSeenStruct(String originalName) {
return _structs.containsKey(originalName);
@@ -378,4 +380,16 @@
String getSeenMacro(String originalName) {
return _macros[originalName];
}
+
+ bool isSeenFunctionTypedef(String originalName) {
+ return _functionTypedefs.containsKey(originalName);
+ }
+
+ void addFunctionTypedefToSeen(String originalName, Typedef t) {
+ _functionTypedefs[originalName] = t;
+ }
+
+ Typedef getSeenFunctionTypedef(String originalName) {
+ return _functionTypedefs[originalName];
+ }
}
diff --git a/pubspec.yaml b/pubspec.yaml
index 5659a9d..aca4a49 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: 0.2.0
+version: 0.2.1
homepage: https://github.com/dart-lang/ffigen
description: Experimental generator for FFI bindings, using LibClang to parse C/C++ header files.
diff --git a/test/header_parser_tests/typedef.h b/test/header_parser_tests/typedef.h
new file mode 100644
index 0000000..f9aa357
--- /dev/null
+++ b/test/header_parser_tests/typedef.h
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+typedef void (*NamedFunctionProto)();
+
+struct Struct1
+{
+ NamedFunctionProto named;
+ void (*unnamed)();
+};
+
+extern NamedFunctionProto func1(NamedFunctionProto named, void (*unnamed)(int));
diff --git a/test/header_parser_tests/typedef_test.dart b/test/header_parser_tests/typedef_test.dart
new file mode 100644
index 0000000..8480acd
--- /dev/null
+++ b/test/header_parser_tests/typedef_test.dart
@@ -0,0 +1,86 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser.dart' as parser;
+import 'package:ffigen/src/config_provider.dart';
+import 'package:logging/logging.dart';
+import 'package:test/test.dart';
+import 'package:yaml/yaml.dart' as yaml;
+import 'package:ffigen/src/strings.dart' as strings;
+
+import '../test_utils.dart';
+
+Library actual, expected;
+
+void main() {
+ group('typedef_test', () {
+ setUpAll(() {
+ logWarnings(Level.SEVERE);
+ expected = expectedLibrary();
+ actual = parser.parse(
+ Config.fromYaml(yaml.loadYaml('''
+${strings.name}: 'Bindings'
+${strings.output}: 'unused'
+
+${strings.headers}:
+ ${strings.entryPoints}:
+ - 'test/header_parser_tests/typedef.h'
+ ''') as yaml.YamlMap),
+ );
+ });
+
+ test('Library output', () {
+ expect(actual.generate(), expected.generate());
+ });
+ });
+}
+
+Library expectedLibrary() {
+ final namedTypedef = Typedef(
+ name: 'NamedFunctionProto',
+ typedefType: TypedefType.C,
+ returnType: Type.nativeType(SupportedNativeType.Void),
+ );
+ return Library(
+ name: 'Bindings',
+ bindings: [
+ Struc(name: 'Struct1', members: [
+ Member(
+ name: 'named',
+ type: Type.pointer(Type.nativeFunc(namedTypedef)),
+ ),
+ Member(
+ name: 'unnamed',
+ type: Type.pointer(Type.nativeFunc(Typedef(
+ name: '_typedefC_1',
+ typedefType: TypedefType.C,
+ returnType: Type.nativeType(SupportedNativeType.Void),
+ ))),
+ ),
+ ]),
+ Func(
+ name: 'func1',
+ parameters: [
+ Parameter(
+ name: 'named',
+ type: Type.pointer(Type.nativeFunc(namedTypedef)),
+ ),
+ Parameter(
+ name: 'unnamed',
+ type: Type.pointer(Type.nativeFunc(Typedef(
+ name: '_typedefC_2',
+ typedefType: TypedefType.C,
+ parameters: [
+ Parameter(type: Type.nativeType(SupportedNativeType.Int32)),
+ ],
+ returnType: Type.nativeType(SupportedNativeType.Void),
+ ))),
+ ),
+ ],
+ returnType: Type.pointer(Type.nativeFunc(namedTypedef)),
+ ),
+ ],
+ );
+}
diff --git a/test/large_integration_tests/_expected_libclang_bindings.dart b/test/large_integration_tests/_expected_libclang_bindings.dart
index f857457..1cbd2a2 100644
--- a/test/large_integration_tests/_expected_libclang_bindings.dart
+++ b/test/large_integration_tests/_expected_libclang_bindings.dart
@@ -1628,7 +1628,7 @@
/// inspecting the inclusions in the PCH file itself).
void clang_getInclusions(
ffi.Pointer<CXTranslationUnitImpl> tu,
- ffi.Pointer<ffi.NativeFunction<CXInclusionVisitor_1>> visitor,
+ ffi.Pointer<ffi.NativeFunction<CXInclusionVisitor>> visitor,
ffi.Pointer<ffi.Void> client_data,
) {
_clang_getInclusions ??= _dylib.lookupFunction<_c_clang_getInclusions,
@@ -4370,26 +4370,26 @@
class IndexerCallbacks extends ffi.Struct {
/// Called periodically to check whether indexing should be aborted. Should
/// return 0 to continue, and non-zero to abort.
- ffi.Pointer<ffi.NativeFunction<_typedefC_3>> abortQuery;
+ ffi.Pointer<ffi.NativeFunction<_typedefC_2>> abortQuery;
/// Called at the end of indexing; passes the complete diagnostic set.
- ffi.Pointer<ffi.NativeFunction<_typedefC_4>> diagnostic;
+ ffi.Pointer<ffi.NativeFunction<_typedefC_3>> diagnostic;
- ffi.Pointer<ffi.NativeFunction<_typedefC_5>> enteredMainFile;
+ ffi.Pointer<ffi.NativeFunction<_typedefC_4>> enteredMainFile;
/// Called when a file gets #included/#imported.
- ffi.Pointer<ffi.NativeFunction<_typedefC_6>> ppIncludedFile;
+ ffi.Pointer<ffi.NativeFunction<_typedefC_5>> ppIncludedFile;
/// Called when a AST file (PCH or module) gets imported.
- ffi.Pointer<ffi.NativeFunction<_typedefC_7>> importedASTFile;
+ ffi.Pointer<ffi.NativeFunction<_typedefC_6>> importedASTFile;
/// Called at the beginning of indexing a translation unit.
- ffi.Pointer<ffi.NativeFunction<_typedefC_8>> startedTranslationUnit;
+ ffi.Pointer<ffi.NativeFunction<_typedefC_7>> startedTranslationUnit;
- ffi.Pointer<ffi.NativeFunction<_typedefC_9>> indexDeclaration;
+ ffi.Pointer<ffi.NativeFunction<_typedefC_8>> indexDeclaration;
/// Called to index a reference of an entity.
- ffi.Pointer<ffi.NativeFunction<_typedefC_10>> indexEntityReference;
+ ffi.Pointer<ffi.NativeFunction<_typedefC_9>> indexEntityReference;
}
abstract class CXIndexOptFlags {
@@ -5391,7 +5391,7 @@
int isEnabled,
);
-typedef CXInclusionVisitor_1 = ffi.Void Function(
+typedef CXInclusionVisitor = ffi.Void Function(
ffi.Pointer<ffi.Void>,
ffi.Pointer<CXSourceLocation>,
ffi.Uint32,
@@ -5400,13 +5400,13 @@
typedef _c_clang_getInclusions = ffi.Void Function(
ffi.Pointer<CXTranslationUnitImpl> tu,
- ffi.Pointer<ffi.NativeFunction<CXInclusionVisitor_1>> visitor,
+ ffi.Pointer<ffi.NativeFunction<CXInclusionVisitor>> visitor,
ffi.Pointer<ffi.Void> client_data,
);
typedef _dart_clang_getInclusions = void Function(
ffi.Pointer<CXTranslationUnitImpl> tu,
- ffi.Pointer<ffi.NativeFunction<CXInclusionVisitor_1>> visitor,
+ ffi.Pointer<ffi.NativeFunction<CXInclusionVisitor>> visitor,
ffi.Pointer<ffi.Void> client_data,
);
@@ -5730,12 +5730,18 @@
ffi.Pointer<CXTranslationUnitImpl> arg5,
);
-typedef _typedefC_3 = ffi.Int32 Function(
+typedef _typedefC_2 = ffi.Int32 Function(
ffi.Pointer<ffi.Void>,
ffi.Pointer<ffi.Void>,
);
-typedef _typedefC_4 = ffi.Void Function(
+typedef _typedefC_3 = ffi.Void Function(
+ ffi.Pointer<ffi.Void>,
+ ffi.Pointer<ffi.Void>,
+ ffi.Pointer<ffi.Void>,
+);
+
+typedef _typedefC_4 = ffi.Pointer<ffi.Void> Function(
ffi.Pointer<ffi.Void>,
ffi.Pointer<ffi.Void>,
ffi.Pointer<ffi.Void>,
@@ -5743,31 +5749,25 @@
typedef _typedefC_5 = ffi.Pointer<ffi.Void> Function(
ffi.Pointer<ffi.Void>,
- ffi.Pointer<ffi.Void>,
- ffi.Pointer<ffi.Void>,
+ ffi.Pointer<CXIdxIncludedFileInfo>,
);
typedef _typedefC_6 = ffi.Pointer<ffi.Void> Function(
ffi.Pointer<ffi.Void>,
- ffi.Pointer<CXIdxIncludedFileInfo>,
+ ffi.Pointer<CXIdxImportedASTFileInfo>,
);
typedef _typedefC_7 = ffi.Pointer<ffi.Void> Function(
ffi.Pointer<ffi.Void>,
- ffi.Pointer<CXIdxImportedASTFileInfo>,
-);
-
-typedef _typedefC_8 = ffi.Pointer<ffi.Void> Function(
- ffi.Pointer<ffi.Void>,
ffi.Pointer<ffi.Void>,
);
-typedef _typedefC_9 = ffi.Void Function(
+typedef _typedefC_8 = ffi.Void Function(
ffi.Pointer<ffi.Void>,
ffi.Pointer<CXIdxDeclInfo>,
);
-typedef _typedefC_10 = ffi.Void Function(
+typedef _typedefC_9 = ffi.Void Function(
ffi.Pointer<ffi.Void>,
ffi.Pointer<CXIdxEntityRefInfo>,
);