[ffigen] Allow extern inline functions to be generated. (#594)
diff --git a/pkgs/ffigen/CHANGELOG.md b/pkgs/ffigen/CHANGELOG.md index 1b70ff7..b4bdf28 100644 --- a/pkgs/ffigen/CHANGELOG.md +++ b/pkgs/ffigen/CHANGELOG.md
@@ -1,6 +1,7 @@ # 9.0.1 - Fix doc comment missing on struct/union array fields. +- Allow extern inline functions to be generated. # 9.0.0
diff --git a/pkgs/ffigen/lib/src/header_parser/clang_bindings/clang_bindings.dart b/pkgs/ffigen/lib/src/header_parser/clang_bindings/clang_bindings.dart index a2217b4..4c5fba2 100644 --- a/pkgs/ffigen/lib/src/header_parser/clang_bindings/clang_bindings.dart +++ b/pkgs/ffigen/lib/src/header_parser/clang_bindings/clang_bindings.dart
@@ -948,6 +948,24 @@ _clang_Cursor_isAnonymousRecordDeclPtr .asFunction<int Function(CXCursor)>(); + /// Returns the storage class for a function or variable declaration. + /// + /// If the passed in Cursor is not a function or variable declaration, + /// CX_SC_Invalid is returned else the storage class. + int clang_Cursor_getStorageClass( + CXCursor arg0, + ) { + return _clang_Cursor_getStorageClass( + arg0, + ); + } + + late final _clang_Cursor_getStorageClassPtr = + _lookup<ffi.NativeFunction<ffi.Int32 Function(CXCursor)>>( + 'clang_Cursor_getStorageClass'); + late final _clang_Cursor_getStorageClass = + _clang_Cursor_getStorageClassPtr.asFunction<int Function(CXCursor)>(); + /// Visit the children of a particular cursor. /// /// This function visits all the direct children of the given cursor, @@ -2564,6 +2582,19 @@ static const int CXTypeLayoutError_Undeduced = -6; } +/// Represents the storage classes as declared in the source. CX_SC_Invalid +/// was added for the case that the passed cursor in not a declaration. +abstract class CX_StorageClass { + static const int CX_SC_Invalid = 0; + static const int CX_SC_None = 1; + static const int CX_SC_Extern = 2; + static const int CX_SC_Static = 3; + static const int CX_SC_PrivateExtern = 4; + static const int CX_SC_OpenCLWorkGroupLocal = 5; + static const int CX_SC_Auto = 6; + static const int CX_SC_Register = 7; +} + /// Describes how the traversal of the children of a particular /// cursor should proceed after visiting a particular child cursor. ///
diff --git a/pkgs/ffigen/lib/src/header_parser/sub_parsers/functiondecl_parser.dart b/pkgs/ffigen/lib/src/header_parser/sub_parsers/functiondecl_parser.dart index 552a0d4..f9d1121 100644 --- a/pkgs/ffigen/lib/src/header_parser/sub_parsers/functiondecl_parser.dart +++ b/pkgs/ffigen/lib/src/header_parser/sub_parsers/functiondecl_parser.dart
@@ -36,8 +36,9 @@ final rt = _getFunctionReturnType(cursor); final parameters = _getParameters(cursor, funcName); - - if (clang.clang_Cursor_isFunctionInlined(cursor) != 0) { + if (clang.clang_Cursor_isFunctionInlined(cursor) != 0 && + clang.clang_Cursor_getStorageClass(cursor) != + clang_types.CX_StorageClass.CX_SC_Extern) { _logger.fine('---- Removed Function, reason: inline function: ' '${cursor.completeStringRepr()}'); _logger.warning(
diff --git a/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_functions_bindings.dart b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_functions_bindings.dart index c4a01b3..7475b09 100644 --- a/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_functions_bindings.dart +++ b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_functions_bindings.dart
@@ -103,6 +103,20 @@ void Function(ffi.Pointer<shortHand>, ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(); + void externInlineFunc( + int a, + ) { + return _externInlineFunc( + a, + ); + } + + late final _externInlineFuncPtr = + _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Int)>>( + 'externInlineFunc'); + late final _externInlineFunc = + _externInlineFuncPtr.asFunction<void Function(int)>(); + int diffChars( int a, int b,
diff --git a/pkgs/ffigen/test/header_parser_tests/functions.h b/pkgs/ffigen/test/header_parser_tests/functions.h index 28b8546..9cf6a3b 100644 --- a/pkgs/ffigen/test/header_parser_tests/functions.h +++ b/pkgs/ffigen/test/header_parser_tests/functions.h
@@ -20,4 +20,7 @@ // Should be skipped as inline functions are not supported. static inline void inlineFunc(); +// Not skipped since it is extern. +extern inline void externInlineFunc(int a); + char diffChars(unsigned char a, signed char b);
diff --git a/pkgs/ffigen/tool/libclang_config.yaml b/pkgs/ffigen/tool/libclang_config.yaml index f0f9b3b..b948e5c 100644 --- a/pkgs/ffigen/tool/libclang_config.yaml +++ b/pkgs/ffigen/tool/libclang_config.yaml
@@ -94,6 +94,7 @@ - clang_getNumArgTypes - clang_getArgType - clang_isFunctionTypeVariadic + - clang_Cursor_getStorageClass - clang_getCursorResultType - clang_getEnumConstantDeclValue - clang_equalRanges