From 05f0952eccd4158f771ffec064cbbaa45fe1dbb9 Mon Sep 17 00:00:00 2001 From: Prerak Mann Date: Mon, 24 Jul 2023 17:55:11 +0530 Subject: [PATCH] Allow extern inline functions to be generated. (#594) --- CHANGELOG.md | 1 + .../clang_bindings/clang_bindings.dart | 31 +++++++++++++++++++ .../sub_parsers/functiondecl_parser.dart | 5 +-- .../_expected_functions_bindings.dart | 14 +++++++++ test/header_parser_tests/functions.h | 3 ++ tool/libclang_config.yaml | 1 + 6 files changed, 53 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b70ff75..b4bdf287 100644 --- a/CHANGELOG.md +++ b/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/lib/src/header_parser/clang_bindings/clang_bindings.dart b/lib/src/header_parser/clang_bindings/clang_bindings.dart index a2217b43..4c5fba22 100644 --- a/lib/src/header_parser/clang_bindings/clang_bindings.dart +++ b/lib/src/header_parser/clang_bindings/clang_bindings.dart @@ -948,6 +948,24 @@ class Clang { _clang_Cursor_isAnonymousRecordDeclPtr .asFunction(); + /// 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>( + 'clang_Cursor_getStorageClass'); + late final _clang_Cursor_getStorageClass = + _clang_Cursor_getStorageClassPtr.asFunction(); + /// Visit the children of a particular cursor. /// /// This function visits all the direct children of the given cursor, @@ -2564,6 +2582,19 @@ abstract class CXTypeLayoutError { 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/lib/src/header_parser/sub_parsers/functiondecl_parser.dart b/lib/src/header_parser/sub_parsers/functiondecl_parser.dart index 552a0d43..f9d1121d 100644 --- a/lib/src/header_parser/sub_parsers/functiondecl_parser.dart +++ b/lib/src/header_parser/sub_parsers/functiondecl_parser.dart @@ -36,8 +36,9 @@ List? parseFunctionDeclaration(clang_types.CXCursor cursor) { 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/test/header_parser_tests/expected_bindings/_expected_functions_bindings.dart b/test/header_parser_tests/expected_bindings/_expected_functions_bindings.dart index c4a01b39..7475b09d 100644 --- a/test/header_parser_tests/expected_bindings/_expected_functions_bindings.dart +++ b/test/header_parser_tests/expected_bindings/_expected_functions_bindings.dart @@ -103,6 +103,20 @@ class NativeLibrary { void Function(ffi.Pointer, ffi.Pointer>)>(); + void externInlineFunc( + int a, + ) { + return _externInlineFunc( + a, + ); + } + + late final _externInlineFuncPtr = + _lookup>( + 'externInlineFunc'); + late final _externInlineFunc = + _externInlineFuncPtr.asFunction(); + int diffChars( int a, int b, diff --git a/test/header_parser_tests/functions.h b/test/header_parser_tests/functions.h index 28b85463..9cf6a3b4 100644 --- a/test/header_parser_tests/functions.h +++ b/test/header_parser_tests/functions.h @@ -20,4 +20,7 @@ void func5(shortHand a, void(b)()); // 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/tool/libclang_config.yaml b/tool/libclang_config.yaml index f0f9b3be..b948e5ce 100644 --- a/tool/libclang_config.yaml +++ b/tool/libclang_config.yaml @@ -94,6 +94,7 @@ functions: - clang_getNumArgTypes - clang_getArgType - clang_isFunctionTypeVariadic + - clang_Cursor_getStorageClass - clang_getCursorResultType - clang_getEnumConstantDeclValue - clang_equalRanges