diff --git a/.github/workflows/test-package.yml b/.github/workflows/test-package.yml index f9fc2b88..d3ed8c62 100644 --- a/.github/workflows/test-package.yml +++ b/.github/workflows/test-package.yml @@ -49,8 +49,6 @@ jobs: run: dart pub get - name: Install libclang-10-dev run: sudo apt-get install libclang-10-dev - - name: Setup ffigen - run: dart --no-sound-null-safety run ffigen:setup - name: Build test dylib run: cd test/native_test && dart build_test_dylib.dart && cd ../.. - name: Run VM tests diff --git a/CHANGELOG.md b/CHANGELOG.md index 67ad9482..865e28b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 2.0.0-dev.2 +- Removed setup phase for ffigen. Added new optional config key `llvm-lib` +to specify path to `llvm/lib` folder. + # 2.0.0-dev.1 - Added support for passing and returning struct by value in functions. diff --git a/README.md b/README.md index 2cd23d2d..15e659ad 100644 --- a/README.md +++ b/README.md @@ -40,13 +40,13 @@ typedef _dart_sum = int Function(int a, int b); ``` ## Using this package - Add `ffigen` under `dev_dependencies` in your `pubspec.yaml`. -- Setup for use (see [Setup](#Setup)). +- Install LLVM (see [Installing LLVM](#installing-llvm)). - Configurations must be provided in `pubspec.yaml` or in a custom YAML file (see [configurations](#configurations)). - Run the tool- `dart run ffigen`. Jump to [FAQ](#faq). -## Setup +## Installing LLVM `package:ffigen` uses LLVM. Install LLVM (9+) in the following way. #### ubuntu/linux @@ -87,6 +87,16 @@ The following configuration options are available- ```yaml output: 'generated_bindings.dart' +``` + + + + llvm-lib + Path to llvm/lib folder. Required if ffigen is unable to find this at default locations. + + +```yaml +llvm-lib: '/usr/local/opt/llvm/lib' ``` @@ -383,13 +393,12 @@ class ArrayHelper_CXFileUniqueID_data_level0 { 2. Run `pub run ffigen`. ## Running Tests -1. Run setup to build the LLVM wrapper - `pub run ffigen:setup`. -2. Dynamic library for some tests also need to be built before running the examples. +1. Dynamic library for some tests need to be built before running the examples. 1. `cd test/native_test`. 2. Run `dart build_test_dylib.dart`. Run tests from the root of the package with `pub run test`. - +> Note: If llvm is not installed in one of the default locations, tests may fail. ## FAQ ### Can ffigen be used for removing underscores or renaming declarations? Ffigen supports **regexp based renaming**, the regexp must be a diff --git a/bin/ffigen.dart b/bin/ffigen.dart index 82abac5b..4405d19b 100644 --- a/bin/ffigen.dart +++ b/bin/ffigen.dart @@ -11,8 +11,6 @@ import 'package:ffigen/ffigen.dart'; import 'package:logging/logging.dart'; import 'package:yaml/yaml.dart' as yaml; -import 'setup.dart'; - final _logger = Logger('ffigen.ffigen'); final _ansi = Ansi(Ansi.terminalSupportsAnsi); @@ -31,16 +29,6 @@ void main(List args) { // Setup logging level and printing. setupLogger(argResult); - /// Prompt user if dylib doesn't exist and cannot be auto created to run - /// `pub run ffigen:setup -Ipath/to/llvm/include -Lpath/to/llvm/lib`. - if (!checkDylibExist() && !autoCreateDylib()) { - _logger.severe('Unable to create dynamic library automatically.'); - _logger.severe('If LLVM (9+) is installed, try running:'); - _logger.severe( - ' pub run ffigen:setup -Ipath/to/llvm/include -Lpath/to/llvm/lib'); - exit(1); - } - // Create a config object. Config config; try { diff --git a/bin/setup.dart b/bin/setup.dart deleted file mode 100644 index edc79e21..00000000 --- a/bin/setup.dart +++ /dev/null @@ -1,275 +0,0 @@ -// 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. - -/// ======================================================================= -/// =============== Build script to generate dyamic library =============== -/// ======================================================================= -/// This Script effectively calls the following (but user can provide -/// command line args which will replace the defaults shown below)- -/// -/// Linux: -/// ``` -/// clang -I/usr/lib/llvm-9/include/ -I/usr/lib/llvm-10/include/ -lclang -shared -fpic path/to/wrapper.c -o path/to/libwrapped_clang.so -/// ``` -/// MacOS: -/// ``` -/// clang -I/usr/local/opt/llvm/include/ -L/usr/local/opt/llvm/lib/ -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/ -v -lclang -shared -fpic path/to/wrapper.c -o path/to/libwrapped_clang.dylib -/// ``` -/// Windows: -/// ``` -/// clang -IC:\Progra~1\LLVM\include -LC:\Progra~1\LLVM\lib -llibclang -shared path/to/wrapper.c -o path/to/wrapped_clang.dll -Wl,/DEF:path/to/wrapper.def -/// ``` -/// ======================================================================= -/// ======================================================================= -/// ======================================================================= - -import 'dart:io'; -import 'package:args/args.dart'; -import 'package:ffigen/src/find_resource.dart'; -import 'package:ffigen/src/strings.dart' as strings; -import 'package:path/path.dart' as path; - -/// Default platform options. -final _linuxOpts = _Options( - sharedFlag: '-shared', - inputHeader: _getWrapperPath('wrapper.c'), - fPIC: '-fpic', - ldLibFlag: '-lclang', - headerIncludes: [ - '-I/usr/lib/llvm-9/include/', - '-I/usr/lib/llvm-10/include/', - ], -); -final _windowsOpts = _Options( - sharedFlag: '-shared', - inputHeader: _getWrapperPath('wrapper.c'), - moduleDefPath: '-Wl,/DEF:${_getWrapperPath("wrapper.def")}', - ldLibFlag: '-llibclang', - headerIncludes: [ - r'-IC:\Progra~1\LLVM\include', - ], - libIncludes: [ - r'-LC:\Progra~1\LLVM\lib', - ], -); -final _macOSOpts = _Options( - sharedFlag: '-shared', - inputHeader: _getWrapperPath('wrapper.c'), - fPIC: '-fpic', - ldLibFlag: '-lclang', - headerIncludes: [ - '-I/usr/local/opt/llvm/include/', - '-I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/', - ], - libIncludes: [ - '-L/usr/local/opt/llvm/lib/', - ], -); - -/// If main is called directly we always re-create the dynamic library. -void main(List arguments) { - // Parses the cmd args. This will print usage and exit if --help was passed. - final argResults = _getArgResults(arguments); - - print('Building Dynamic Library for libclang wrapper...'); - final options = _getPlatformOptions(); - _deleteOldDylib(); - - // Updates header/lib includes in platform options. - _changeIncludesUsingCmdArgs(argResults, options); - - // Run clang compiler to generate the dynamic library. - final processResult = _runClangProcess(options); - _printDetails(processResult, options); -} - -/// Returns true if auto creating dylib was successful. -/// -/// This will fail if llvm is not in default directories or if .dart_tool -/// doesn't exist. -bool autoCreateDylib() { - _deleteOldDylib(); - final options = _getPlatformOptions(); - final processResult = _runClangProcess(options); - if ((processResult.stderr as String).isNotEmpty) { - print(processResult.stderr); - } - return checkDylibExist(); -} - -bool checkDylibExist() { - return File(path.join( - _getDotDartToolPath(), - strings.ffigenFolderName, - strings.dylibFileName, - )).existsSync(); -} - -/// Removes old dynamic libraries(if any) by deleting .dart_tool/ffigen. -/// -/// Throws error if '.dart_tool' is not found. -void _deleteOldDylib() { - // Find .dart_tool. - final dtpath = _getDotDartToolPath(); - // Find .dart_tool/ffigen and delete recursively if it exists. - final ffigenDir = Directory(path.join(dtpath, strings.ffigenFolderName)); - if (ffigenDir.existsSync()) ffigenDir.deleteSync(recursive: true); -} - -/// Creates necesarry parent folders and return full path to dylib. -String _dylibPath() { - // Find .dart_tool. - final dtpath = _getDotDartToolPath(); - // Create .dart_tool/ffigen if it doesn't exists. - final ffigenDir = Directory(path.join(dtpath, strings.ffigenFolderName)); - if (!ffigenDir.existsSync()) ffigenDir.createSync(); - - // Return dylib path - return path.join(ffigenDir.absolute.path, strings.dylibFileName); -} - -/// Returns full path of the wrapper files. -/// -/// Throws error if not found. -String _getWrapperPath(String wrapperName) { - final file = File.fromUri(findWrapper(wrapperName)!); - if (file.existsSync()) { - return file.absolute.path; - } else { - throw Exception('Unable to find $wrapperName file.'); - } -} - -/// Gets full path to .dart_tool. -/// -/// Throws Exception if not found. -String _getDotDartToolPath() { - final dtpath = findDotDartTool()?.toFilePath(); - if (dtpath == null) { - throw Exception('.dart_tool not found.'); - } - return dtpath; -} - -/// Calls the clang compiler. -ProcessResult _runClangProcess(_Options options) { - final result = Process.runSync( - 'clang', - [ - ...options.headerIncludes, - ...options.libIncludes, - options.ldLibFlag, - options.sharedFlag, - options.fPIC, - options.inputHeader, - '-o', - _dylibPath(), - options.moduleDefPath, - '-Wno-nullability-completeness', - ], - ); - return result; -} - -/// Prints success message (or process error if any). -void _printDetails(ProcessResult result, _Options options) { - print(result.stdout); - if ((result.stderr as String).isNotEmpty) { - print(result.stderr); - } else { - print('Created dynamic library.'); - } -} - -ArgResults _getArgResults(List args) { - final parser = ArgParser(allowTrailingOptions: true); - parser.addSeparator('Generates LLVM Wrapper used by this package:'); - parser.addMultiOption('include-header', - abbr: 'I', help: 'Path to header include directories'); - parser.addMultiOption('include-lib', - abbr: 'L', help: 'Path to library include directories'); - parser.addFlag( - 'help', - abbr: 'h', - help: 'prints this usage', - negatable: false, - ); - - ArgResults results; - try { - results = parser.parse(args); - - if (results.wasParsed('help')) { - print(parser.usage); - exit(0); - } - } catch (e) { - print(e); - print(parser.usage); - exit(1); - } - - return results; -} - -/// Use cmd args(if any) to change header/lib include paths. -void _changeIncludesUsingCmdArgs(ArgResults argResult, _Options options) { - if (argResult.wasParsed('include-header')) { - options.headerIncludes = (argResult['include-header'] as List) - .map((header) => '-I$header') - .toList(); - } - if (argResult.wasParsed('include-lib')) { - options.libIncludes = (argResult['include-lib'] as List) - .map((lib) => '-L$lib') - .toList(); - } -} - -/// Get options based on current platform. -_Options _getPlatformOptions() { - if (Platform.isMacOS) { - return _macOSOpts; - } else if (Platform.isWindows) { - return _windowsOpts; - } else if (Platform.isLinux) { - return _linuxOpts; - } else { - throw Exception('Unknown Platform.'); - } -} - -/// Hold options which would be passed to clang. -class _Options { - /// Tells compiler to generate a shared library. - final String sharedFlag; - - /// Flag for generating Position Independant Code (Not used on windows). - final String fPIC; - - /// Input file. - final String inputHeader; - - /// Path to `.def` file containing symbols to export, windows use only. - final String moduleDefPath; - - /// Path to header files. - List headerIncludes; - - /// Path to dynamic/static libraries - List libIncludes; - - /// Linker flag for linking to libclang. - final String ldLibFlag; - - _Options({ - required this.sharedFlag, - required this.inputHeader, - required this.ldLibFlag, - this.headerIncludes = const [], - this.libIncludes = const [], - this.fPIC = '', - this.moduleDefPath = '', - }); -} diff --git a/example/libclang-example/pubspec.yaml b/example/libclang-example/pubspec.yaml index c1bfc6c1..e81c3269 100644 --- a/example/libclang-example/pubspec.yaml +++ b/example/libclang-example/pubspec.yaml @@ -15,6 +15,9 @@ ffigen: output: 'generated_bindings.dart' sort: true + # This is required if LLVM can't be found in default locations by ffigen. + # llvm-lib: '/usr/local/opt/llvm/lib' + # Bash style Glob matching is also supported. # TODO(11): Globs dont work on windows if they begin with '.' or '..'. headers: diff --git a/lib/src/README.md b/lib/src/README.md index 900c9f7f..cdfc01a7 100644 --- a/lib/src/README.md +++ b/lib/src/README.md @@ -2,12 +2,9 @@ ## Table of Contents - 1. [Overview](#overview) 2. [LibClang](#LibClang) - 1. [The Wrapper library](#The-Wrapper-library) - 2. [Generation and Usage](#Generation-and-Usage) - 3. [Bindings](#Bindings) + 1. [Bindings](#Bindings) 3. [Scripts](#scripts) 1. [ffigen.dart](#ffigen.dart) - 2. [setup.dart](#setup.dart) 4. [Components](#components) 1. [Config Provider](#Config-Provider) 2. [Header Parser](#Header-Parser) @@ -15,21 +12,7 @@ # Overview `package:ffigen` simplifies the process of generating `dart:ffi` bindings from C header files. It is simple to use, with the input being a small YAML config file. It requires LLVM (9+) to work. This document tries to give a complete overview of every component without going into too many details about every single class/file. # LibClang -`package:ffigen` binds to LibClang using `dart:ffi` for parsing C header files. A wrapper library must be generated to use it, as `dart:ffi` currently [doesn't support structs by value](https://github.com/dart-lang/ffigen/issues/3). -## The Wrapper library -> Note: The wrapper is only needed because `dart:ffi` currently doesn't support Structs by value. - -The `wrapper.c` file consists of functions that wrap LibClang functions. Most of them simply convert structs by value to pointers. Except - -- `clang_visitChildren_wrap` - The bindings for this function internally uses a **list** of **stack** for maintaining the supplied visitor functions. This is required because this function takes a function pointer which itself passes a struct by value. All this effort makes `clang_visitChildren_wrap` behave exactly like `clang_visitChildren`. -## Generation and Usage -The files needed for generating the wrapper are in `lib/src/clang_library`. -> The `wrapper.def` file is only needed on windows because the symbols are otherwise hidden. - -The libclang wrapper can be _manually_ generated using `pub run ffigen:setup`. See [setup.dart](#setup.dart) for details. - -The generated file is placed in the project's `.dart_tool/ffigen` folder, the file name also specifies the ffigen version (E.g - `_v0_2_4_libclang_wrapper.dylib`), this helps ensure the correct wrapper is being used for its corresponding version. - -This dynamic library is then used by [Header Parser](#header-parser) for parsing C files. +`package:ffigen` binds to LibClang using `dart:ffi` for parsing C header files. ## Bindings The config file for generating bindings is `tool/libclang_config.yaml`. The bindings are generated to `lib/src/header_parser/clang_bindings/clang_bindings.dart`. These are used by [Header Parser](#header-parser) for calling libclang functions. # Scripts @@ -38,19 +21,11 @@ This is the main entry point for the user- `pub run ffigen`. - Command-line options: - `--verbose`: Sets log level. - `--config`: Specifies a config file. -- `ffigen.dart` will first check if a dynamic library already exists and is up to date. If not, it tries to auto-create it. If that fails, user must excplicitly call [setup.dart](#setup.dart). - The internal modules are called by `ffigen.dart` in the following way: +- `ffigen.dart` will try to find dynamic library in default locations. If that fails, the user must excplicitly specify location in ffigen's config under the key `llvm-lib`. - It first creates a `Config` object from an input Yaml file. This is used by other modules. - The `parse` method is then invoked to generate a `Library` object. - Finally, the code is generated from the `Library` object to the specified file. -## setup.dart -Used to generate the wrapper dynamic library. Users will need to explicitly call this if `pub run ffigen` is unable to auto-create the dynamic library. -> `clang` must be on user's path for `setup.dart` to work. - -- Command-line options: - - `-I`: Specifies header includes. - - `-L`: Specifies library includes. -- `setup.dart` generates the dynamic library to the project's `.dart_tool/ffigen` folder using `clang`. # Components ## Config Provider The Config Provider holds all the configurations required by other modules. diff --git a/lib/src/clang_library/wrapper.c b/lib/src/clang_library/wrapper.c deleted file mode 100644 index 96f64bae..00000000 --- a/lib/src/clang_library/wrapper.c +++ /dev/null @@ -1,370 +0,0 @@ -// 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. - -#include -#include -#include - -// utility. -#define aloc(T) ((T *)malloc(sizeof(T))) -CXCursor *ptrToCXCursor(CXCursor t) -{ - CXCursor *c = aloc(CXCursor); - *c = t; - return c; -} -CXString *ptrToCXString(CXString t) -{ - CXString *c = aloc(CXString); - *c = t; - return c; -} -CXType *ptrToCXType(CXType t) -{ - CXType *c = aloc(CXType); - *c = t; - return c; -} -CXSourceLocation *ptrToCXSourceLocation(CXSourceLocation t) -{ - CXSourceLocation *c = aloc(CXSourceLocation); - *c = t; - return c; -} -CXSourceRange *ptrToCXSourceRange(CXSourceRange t) -{ - CXSourceRange *c = aloc(CXSourceRange); - *c = t; - return c; -} -// START ===== Functions for testing libclang behavior in C. -enum CXChildVisitResult visitor_for_test_in_c(CXCursor cursor, CXCursor parent, CXClientData clientData) -{ - printf("Cursor- kind: %s, name: %s\n", clang_getCString(clang_getCursorKindSpelling(clang_getCursorKind(cursor))), clang_getCString(clang_getCursorSpelling(cursor))); - return CXChildVisit_Continue; -} -int test_in_c() -{ - printf("==========================run==========================\n"); - CXIndex Index = clang_createIndex(0, 0); - CXTranslationUnit TU = clang_parseTranslationUnit(Index, - "./test.h", 0, 0, NULL, 0, CXTranslationUnit_None); - - if (TU == NULL) - { - printf("Error creating TU\n"); - return 0; - } - - CXCursor root = clang_getTranslationUnitCursor(TU); - - unsigned a = clang_visitChildren(root, visitor_for_test_in_c, NULL); - - clang_disposeTranslationUnit(TU); - clang_disposeIndex(Index); - printf("\n==========================end==========================\n"); - return 0; -} -// END ===== Functions for testing libclang behavior in C ============================ - -// START ===== WRAPPER FUNCTIONS ===================== - -const char *clang_getCString_wrap(CXString *string) -{ - const char *a = clang_getCString(*string); - - return a; -} - -void clang_disposeString_wrap(CXString *string) -{ - clang_disposeString(*string); - free(string); - return; -} - -enum CXCursorKind clang_getCursorKind_wrap(CXCursor *cursor) -{ - return clang_getCursorKind(*cursor); -} - -CXString *clang_getCursorKindSpelling_wrap(enum CXCursorKind kind) -{ - return ptrToCXString(clang_getCursorKindSpelling(kind)); -} - -CXType *clang_getCursorType_wrap(CXCursor *cursor) -{ - return ptrToCXType(clang_getCursorType(*cursor)); -} - -CXString *clang_getTypeSpelling_wrap(CXType *type) -{ - return ptrToCXString(clang_getTypeSpelling(*type)); -} - -CXString *clang_getTypeKindSpelling_wrap(enum CXTypeKind typeKind) -{ - return ptrToCXString(clang_getTypeKindSpelling(typeKind)); -} - -CXType *clang_getResultType_wrap(CXType *functionType) -{ - return ptrToCXType(clang_getResultType(*functionType)); -} - -CXType *clang_getPointeeType_wrap(CXType *pointerType) -{ - return ptrToCXType(clang_getPointeeType(*pointerType)); -} - -CXType *clang_getCanonicalType_wrap(CXType *typerefType) -{ - return ptrToCXType(clang_getCanonicalType(*typerefType)); -} - -CXType *clang_Type_getNamedType_wrap(CXType *elaboratedType) -{ - return ptrToCXType(clang_Type_getNamedType(*elaboratedType)); -} - -CXCursor *clang_getTypeDeclaration_wrap(CXType *cxtype) -{ - return ptrToCXCursor(clang_getTypeDeclaration(*cxtype)); -} - -CXType *clang_getTypedefDeclUnderlyingType_wrap(CXCursor *cxcursor) -{ - return ptrToCXType(clang_getTypedefDeclUnderlyingType(*cxcursor)); -} - -/** The name of parameter, struct, typedef. */ -CXString *clang_getCursorSpelling_wrap(CXCursor *cursor) -{ - return ptrToCXString(clang_getCursorSpelling(*cursor)); -} - -CXCursor *clang_getTranslationUnitCursor_wrap(CXTranslationUnit tu) -{ - return ptrToCXCursor(clang_getTranslationUnitCursor(tu)); -} - -CXString *clang_formatDiagnostic_wrap(CXDiagnostic diag, int opts) -{ - return ptrToCXString(clang_formatDiagnostic(diag, opts)); -} - -// Alternative typedef for [CXCursorVisitor] using pointer for passing cursor and parent -// instead of passing by value -typedef enum CXChildVisitResult (*ModifiedCXCursorVisitor)(CXCursor *cursor, - CXCursor *parent, - CXClientData client_data); - -struct _stackForVisitChildren -{ - ModifiedCXCursorVisitor modifiedVisitor; - struct _stackForVisitChildren *link; -} * _visitorTemp; - -// Holds list of Isolate-Processor pairs, each having their own stack -// to hold the vistorFunctions. -struct _listForIsolateProcessPair -{ - long long uid; - struct _listForIsolateProcessPair *next; - struct _stackForVisitChildren *_visitorTop; -} ipHead, *ipTemp; -// `ipHead` is used only as head marker and will not contain any information. - -// Finds/Creates an Isolate-Processor pair from/in the linkedlist. -struct _listForIsolateProcessPair *_findIP(long long uid) -{ - struct _listForIsolateProcessPair *temp = ipHead.next; - while (temp != NULL) - { - if (temp->uid == uid) - { - return temp; - } - temp = temp->next; - } - // If we reach here this means no IP pair was found and we should create one - // and add it to the head of our list. - temp = aloc(struct _listForIsolateProcessPair); - temp->next = ipHead.next; - temp->uid = uid; - temp->_visitorTop = NULL; - ipHead.next = temp; - return temp; -} -void _push(ModifiedCXCursorVisitor modifiedVisitor, long long uid) -{ - struct _listForIsolateProcessPair *current = _findIP(uid); - if (current->_visitorTop == NULL) - { - current->_visitorTop = aloc(struct _stackForVisitChildren); - current->_visitorTop->link = NULL; - current->_visitorTop->modifiedVisitor = modifiedVisitor; - } - else - { - _visitorTemp = aloc(struct _stackForVisitChildren); - _visitorTemp->link = current->_visitorTop; - _visitorTemp->modifiedVisitor = modifiedVisitor; - current->_visitorTop = _visitorTemp; - } -} -void _pop(long long uid) -{ - struct _listForIsolateProcessPair *current = _findIP(uid); - _visitorTemp = current->_visitorTop; - - if (_visitorTemp == NULL) - { - printf("\n Error, Wrapper.C : Trying to pop from empty stack"); - return; - } - else - _visitorTemp = current->_visitorTop->link; - free(current->_visitorTop); - current->_visitorTop = _visitorTemp; -} -ModifiedCXCursorVisitor _top(long long uid) -{ - return _findIP(uid)->_visitorTop->modifiedVisitor; -} - -// Do not write binding for this function. -// used by [clang_visitChildren_wrap]. -enum CXChildVisitResult -_visitorwrap(CXCursor cursor, CXCursor parent, CXClientData clientData) -{ - // Use clientData (which is a unique ID) to get reference to the stack which - // this particular process-isolate pair uses. - long long uid = *((long long *)clientData); - enum CXChildVisitResult e = (_top(uid)(ptrToCXCursor(cursor), ptrToCXCursor(parent), clientData)); - return e; -} - -/** Visitor is a function pointer with parameters having pointers to cxcursor -* instead of cxcursor by default. */ -unsigned clang_visitChildren_wrap(CXCursor *parent, ModifiedCXCursorVisitor _modifiedVisitor, long long uid) -{ - long long *clientData = aloc(long long); - *clientData = uid; - _push(_modifiedVisitor, uid); - unsigned a = clang_visitChildren(*parent, _visitorwrap, clientData); - _pop(uid); - return a; -} - -int clang_Cursor_getNumArguments_wrap(CXCursor *cursor) -{ - return clang_Cursor_getNumArguments(*cursor); -} - -CXCursor *clang_Cursor_getArgument_wrap(CXCursor *cursor, unsigned i) -{ - return ptrToCXCursor(clang_Cursor_getArgument(*cursor, i)); -} - -int clang_getNumArgTypes_wrap(CXType *cxtype) -{ - return clang_getNumArgTypes(*cxtype); -} - -CXType *clang_getArgType_wrap(CXType *cxtype, unsigned i) -{ - return ptrToCXType(clang_getArgType(*cxtype, i)); -} - -long long clang_getEnumConstantDeclValue_wrap(CXCursor *cursor) -{ - return clang_getEnumConstantDeclValue(*cursor); -} - -/** Returns non-zero if the ranges are the same, zero if they differ. */ -unsigned clang_equalRanges_wrap(CXSourceRange *c1, CXSourceRange *c2) -{ - return clang_equalRanges(*c1, *c2); -} - -/** Returns the comment range. */ -CXSourceRange *clang_Cursor_getCommentRange_wrap(CXCursor *cursor) -{ - return ptrToCXSourceRange(clang_Cursor_getCommentRange(*cursor)); -} - -/** Returns the raw comment. */ -CXString *clang_Cursor_getRawCommentText_wrap(CXCursor *cursor) -{ - return ptrToCXString(clang_Cursor_getRawCommentText(*cursor)); -} - -/** Returns the first paragraph of doxygen doc comment. */ -CXString *clang_Cursor_getBriefCommentText_wrap(CXCursor *cursor) -{ - return ptrToCXString(clang_Cursor_getBriefCommentText(*cursor)); -} - -CXSourceLocation *clang_getCursorLocation_wrap(CXCursor *cursor) -{ - return ptrToCXSourceLocation(clang_getCursorLocation(*cursor)); -} - -void clang_getFileLocation_wrap(CXSourceLocation *location, CXFile *file, unsigned *line, unsigned *column, unsigned *offset) -{ - return clang_getFileLocation(*location, file, line, column, offset); -} - -CXString *clang_getFileName_wrap(CXFile SFile) -{ - return ptrToCXString(clang_getFileName(SFile)); -} - -unsigned long long clang_getNumElements_wrap(CXType *cxtype) -{ - return clang_getNumElements(*cxtype); -} - -CXType *clang_getArrayElementType_wrap(CXType *cxtype) -{ - return ptrToCXType(clang_getArrayElementType(*cxtype)); -} - -unsigned clang_Cursor_isMacroFunctionLike_wrap(CXCursor *cursor) -{ - return clang_Cursor_isMacroFunctionLike(*cursor); -} - -unsigned clang_Cursor_isMacroBuiltin_wrap(CXCursor *cursor) -{ - return clang_Cursor_isMacroBuiltin(*cursor); -} - -CXEvalResult clang_Cursor_Evaluate_wrap(CXCursor *cursor) -{ - return clang_Cursor_Evaluate(*cursor); -} - -unsigned clang_Cursor_isAnonymous_wrap(CXCursor *cursor) -{ - return clang_Cursor_isAnonymous(*cursor); -} - -unsigned clang_Cursor_isAnonymousRecordDecl_wrap(CXCursor *cursor) -{ - return clang_Cursor_isAnonymousRecordDecl(*cursor); -} - -CXString *clang_getCursorUSR_wrap(CXCursor *cursor) -{ - return ptrToCXString(clang_getCursorUSR(*cursor)); -} - -int clang_getFieldDeclBitWidth_wrap(CXCursor *cursor){ - return clang_getFieldDeclBitWidth(*cursor); -} - -// END ===== WRAPPER FUNCTIONS ===================== diff --git a/lib/src/clang_library/wrapper.def b/lib/src/clang_library/wrapper.def deleted file mode 100644 index 8a984b02..00000000 --- a/lib/src/clang_library/wrapper.def +++ /dev/null @@ -1,362 +0,0 @@ -; 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. - -EXPORTS -clang_getCString -clang_disposeString -clang_disposeStringSet -clang_createIndex -clang_disposeIndex -clang_CXIndex_setGlobalOptions -clang_CXIndex_getGlobalOptions -clang_CXIndex_setInvocationEmissionPathOption -clang_getFileName -clang_getFileTime -clang_getFileUniqueID -clang_isFileMultipleIncludeGuarded -clang_getFile -clang_getFileContents -clang_File_isEqual -clang_File_tryGetRealPathName -clang_getNullLocation -clang_equalLocations -clang_getLocation -clang_getLocationForOffset -clang_Location_isInSystemHeader -clang_Location_isFromMainFile -clang_getNullRange -clang_getRange -clang_equalRanges -clang_Range_isNull -clang_getExpansionLocation -clang_getPresumedLocation -clang_getInstantiationLocation -clang_getSpellingLocation -clang_getFileLocation -clang_getRangeStart -clang_getRangeEnd -clang_getSkippedRanges -clang_getAllSkippedRanges -clang_disposeSourceRangeList -clang_getNumDiagnosticsInSet -clang_getDiagnosticInSet -clang_loadDiagnostics -clang_disposeDiagnosticSet -clang_getChildDiagnostics -clang_getNumDiagnostics -clang_getDiagnostic -clang_getDiagnosticSetFromTU -clang_disposeDiagnostic -clang_formatDiagnostic -clang_defaultDiagnosticDisplayOptions -clang_getDiagnosticSeverity -clang_getDiagnosticLocation -clang_getDiagnosticSpelling -clang_getDiagnosticOption -clang_getDiagnosticCategory -clang_getDiagnosticCategoryName -clang_getDiagnosticCategoryText -clang_getDiagnosticNumRanges -clang_getDiagnosticRange -clang_getDiagnosticNumFixIts -clang_getDiagnosticFixIt -clang_getTranslationUnitSpelling -clang_createTranslationUnitFromSourceFile -clang_createTranslationUnit -clang_createTranslationUnit2 -clang_defaultEditingTranslationUnitOptions -clang_parseTranslationUnit -clang_parseTranslationUnit2 -clang_parseTranslationUnit2FullArgv -clang_defaultSaveOptions -clang_saveTranslationUnit -clang_suspendTranslationUnit -clang_disposeTranslationUnit -clang_defaultReparseOptions -clang_reparseTranslationUnit -clang_getTUResourceUsageName -clang_getCXTUResourceUsage -clang_disposeCXTUResourceUsage -clang_getTranslationUnitTargetInfo -clang_TargetInfo_dispose -clang_TargetInfo_getTriple -clang_TargetInfo_getPointerWidth -clang_getNullCursor -clang_getTranslationUnitCursor -clang_equalCursors -clang_Cursor_isNull -clang_hashCursor -clang_getCursorKind -clang_isDeclaration -clang_isInvalidDeclaration -clang_isReference -clang_isExpression -clang_isStatement -clang_isAttribute -clang_Cursor_hasAttrs -clang_isInvalid -clang_isTranslationUnit -clang_isPreprocessing -clang_isUnexposed -clang_getCursorLinkage -clang_getCursorVisibility -clang_getCursorAvailability -clang_getCursorPlatformAvailability -clang_disposeCXPlatformAvailability -clang_getCursorLanguage -clang_getCursorTLSKind -clang_Cursor_getTranslationUnit -clang_createCXCursorSet -clang_disposeCXCursorSet -clang_CXCursorSet_contains -clang_CXCursorSet_insert -clang_getCursorSemanticParent -clang_getCursorLexicalParent -clang_getOverriddenCursors -clang_disposeOverriddenCursors -clang_getIncludedFile -clang_getCursor -clang_getCursorLocation -clang_getCursorExtent -clang_getCursorType -clang_getTypeSpelling -clang_getTypedefDeclUnderlyingType -clang_getEnumDeclIntegerType -clang_getEnumConstantDeclValue -clang_getEnumConstantDeclUnsignedValue -clang_getFieldDeclBitWidth -clang_Cursor_getNumArguments -clang_Cursor_getArgument -clang_Cursor_getNumTemplateArguments -clang_Cursor_getTemplateArgumentKind -clang_Cursor_getTemplateArgumentType -clang_Cursor_getTemplateArgumentValue -clang_Cursor_getTemplateArgumentUnsignedValue -clang_equalTypes -clang_getCanonicalType -clang_isConstQualifiedType -clang_Cursor_isMacroFunctionLike -clang_Cursor_isMacroBuiltin -clang_Cursor_isFunctionInlined -clang_isVolatileQualifiedType -clang_isRestrictQualifiedType -clang_getAddressSpace -clang_getTypedefName -clang_getPointeeType -clang_getTypeDeclaration -clang_getDeclObjCTypeEncoding -clang_Type_getObjCEncoding -clang_getTypeKindSpelling -clang_getFunctionTypeCallingConv -clang_getResultType -clang_getExceptionSpecificationType -clang_getNumArgTypes -clang_getArgType -clang_Type_getObjCObjectBaseType -clang_Type_getNumObjCProtocolRefs -clang_Type_getObjCProtocolDecl -clang_Type_getNumObjCTypeArgs -clang_Type_getObjCTypeArg -clang_isFunctionTypeVariadic -clang_getCursorResultType -clang_getCursorExceptionSpecificationType -clang_isPODType -clang_getElementType -clang_getNumElements -clang_getArrayElementType -clang_getArraySize -clang_Type_getNamedType -clang_Type_isTransparentTagTypedef -clang_Type_getNullability -clang_Type_getAlignOf -clang_Type_getClassType -clang_Type_getSizeOf -clang_Type_getOffsetOf -clang_Type_getModifiedType -clang_Cursor_getOffsetOfField -clang_Cursor_isAnonymous -clang_Cursor_isAnonymousRecordDecl -clang_Cursor_isInlineNamespace -clang_Type_getNumTemplateArguments -clang_Type_getTemplateArgumentAsType -clang_Type_getCXXRefQualifier -clang_Cursor_isBitField -clang_isVirtualBase -clang_getCXXAccessSpecifier -clang_Cursor_getStorageClass -clang_getNumOverloadedDecls -clang_getOverloadedDecl -clang_getIBOutletCollectionType -clang_visitChildren -clang_getCursorUSR -clang_constructUSR_ObjCClass -clang_constructUSR_ObjCCategory -clang_constructUSR_ObjCProtocol -clang_constructUSR_ObjCIvar -clang_constructUSR_ObjCMethod -clang_constructUSR_ObjCProperty -clang_getCursorSpelling -clang_Cursor_getSpellingNameRange -clang_PrintingPolicy_getProperty -clang_PrintingPolicy_setProperty -clang_getCursorPrintingPolicy -clang_PrintingPolicy_dispose -clang_getCursorPrettyPrinted -clang_getCursorDisplayName -clang_getCursorReferenced -clang_getCursorDefinition -clang_isCursorDefinition -clang_getCanonicalCursor -clang_Cursor_getObjCSelectorIndex -clang_Cursor_isDynamicCall -clang_Cursor_getReceiverType -clang_Cursor_getObjCPropertyAttributes -clang_Cursor_getObjCPropertyGetterName -clang_Cursor_getObjCPropertySetterName -clang_Cursor_getObjCDeclQualifiers -clang_Cursor_isObjCOptional -clang_Cursor_isVariadic -clang_Cursor_isExternalSymbol -clang_Cursor_getCommentRange -clang_Cursor_getRawCommentText -clang_Cursor_getBriefCommentText -clang_Cursor_getMangling -clang_Cursor_getCXXManglings -clang_Cursor_getObjCManglings -clang_Cursor_getModule -clang_getModuleForFile -clang_Module_getASTFile -clang_Module_getParent -clang_Module_getName -clang_Module_getFullName -clang_Module_isSystem -clang_Module_getNumTopLevelHeaders -clang_Module_getTopLevelHeader -clang_CXXConstructor_isConvertingConstructor -clang_CXXConstructor_isCopyConstructor -clang_CXXConstructor_isDefaultConstructor -clang_CXXConstructor_isMoveConstructor -clang_CXXField_isMutable -clang_CXXMethod_isDefaulted -clang_CXXMethod_isPureVirtual -clang_CXXMethod_isStatic -clang_CXXMethod_isVirtual -clang_CXXRecord_isAbstract -clang_EnumDecl_isScoped -clang_CXXMethod_isConst -clang_getTemplateCursorKind -clang_getSpecializedCursorTemplate -clang_getCursorReferenceNameRange -clang_getToken -clang_getTokenKind -clang_getTokenSpelling -clang_getTokenLocation -clang_getTokenExtent -clang_tokenize -clang_annotateTokens -clang_disposeTokens -clang_getCursorKindSpelling -clang_getDefinitionSpellingAndExtent -clang_enableStackTraces -clang_executeOnThread -clang_getCompletionChunkKind -clang_getCompletionChunkText -clang_getCompletionChunkCompletionString -clang_getNumCompletionChunks -clang_getCompletionPriority -clang_getCompletionAvailability -clang_getCompletionNumAnnotations -clang_getCompletionAnnotation -clang_getCompletionParent -clang_getCompletionBriefComment -clang_getCursorCompletionString -clang_getCompletionNumFixIts -clang_getCompletionFixIt -clang_defaultCodeCompleteOptions -clang_codeCompleteAt -clang_sortCodeCompletionResults -clang_disposeCodeCompleteResults -clang_codeCompleteGetNumDiagnostics -clang_codeCompleteGetDiagnostic -clang_codeCompleteGetContexts -clang_codeCompleteGetContainerKind -clang_codeCompleteGetContainerUSR -clang_codeCompleteGetObjCSelector -clang_getClangVersion -clang_toggleCrashRecovery -clang_getInclusions -clang_Cursor_Evaluate -clang_EvalResult_getKind -clang_EvalResult_getAsInt -clang_EvalResult_getAsLongLong -clang_EvalResult_isUnsignedInt -clang_EvalResult_getAsUnsigned -clang_EvalResult_getAsDouble -clang_EvalResult_getAsStr -clang_EvalResult_dispose -clang_getRemappings -clang_getRemappingsFromFileList -clang_remap_getNumFiles -clang_remap_getFilenames -clang_remap_dispose -clang_findReferencesInFile -clang_findIncludesInFile -clang_index_isEntityObjCContainerKind -clang_index_getObjCContainerDeclInfo -clang_index_getObjCInterfaceDeclInfo -clang_index_getObjCCategoryDeclInfo -clang_index_getObjCProtocolRefListInfo -clang_index_getObjCPropertyDeclInfo -clang_index_getIBOutletCollectionAttrInfo -clang_index_getCXXClassDeclInfo -clang_index_getClientContainer -clang_index_setClientContainer -clang_index_getClientEntity -clang_index_setClientEntity -clang_IndexAction_create -clang_IndexAction_dispose -clang_indexSourceFile -clang_indexSourceFileFullArgv -clang_indexTranslationUnit -clang_indexLoc_getFileLocation -clang_indexLoc_getCXSourceLocation -clang_Type_visitFields -clang_getCString_wrap -clang_disposeString_wrap -clang_getCursorKind_wrap -clang_getCursorKindSpelling_wrap -clang_getCursorType_wrap -clang_getTypeSpelling_wrap -clang_getTypeKindSpelling_wrap -clang_getResultType_wrap -clang_getPointeeType_wrap -clang_getCanonicalType_wrap -clang_Type_getNamedType_wrap -clang_getTypeDeclaration_wrap -clang_getTypedefDeclUnderlyingType_wrap -clang_getCursorSpelling_wrap -clang_getTranslationUnitCursor_wrap -clang_formatDiagnostic_wrap -clang_visitChildren_wrap -clang_Cursor_getNumArguments_wrap -clang_Cursor_getArgument_wrap -clang_getNumArgTypes_wrap -clang_getArgType_wrap -clang_getEnumConstantDeclValue_wrap -clang_equalRanges_wrap -clang_Cursor_getCommentRange_wrap -clang_Cursor_getRawCommentText_wrap -clang_Cursor_getBriefCommentText_wrap -clang_getCursorLocation_wrap -clang_getFileLocation_wrap -clang_getFileName_wrap -clang_getNumElements_wrap -clang_getArrayElementType_wrap -clang_Cursor_isMacroFunctionLike_wrap -clang_Cursor_isMacroBuiltin_wrap -clang_Cursor_Evaluate_wrap -clang_Cursor_isAnonymous_wrap -clang_Cursor_isAnonymousRecordDecl_wrap -clang_getCursorUSR_wrap -clang_getFieldDeclBitWidth_wrap diff --git a/lib/src/config_provider/config.dart b/lib/src/config_provider/config.dart index 0649de57..96ca643d 100644 --- a/lib/src/config_provider/config.dart +++ b/lib/src/config_provider/config.dart @@ -20,6 +20,10 @@ final _logger = Logger('ffigen.config_provider.config'); /// /// Handles validation, extraction of confiurations from yaml file. class Config { + /// Location for llvm/lib folder. + String get libclangDylib => _libclangDylib; + late String _libclangDylib; + /// output file name. String get output => _output; late String _output; @@ -156,6 +160,13 @@ class Config { /// Key: Name, Value: [Specification] Map _getSpecs() { return { + strings.llvmLib: Specification( + requirement: Requirement.no, + validator: llvmLibValidator, + extractor: llvmLibExtractor, + defaultValue: () => findDylibAtDefaultLocations(), + extractedResult: (dynamic result) => _libclangDylib = result as String, + ), strings.output: Specification( requirement: Requirement.yes, validator: outputValidator, diff --git a/lib/src/config_provider/spec_utils.dart b/lib/src/config_provider/spec_utils.dart index 2df79391..839333ae 100644 --- a/lib/src/config_provider/spec_utils.dart +++ b/lib/src/config_provider/spec_utils.dart @@ -197,6 +197,64 @@ String getDylibPath(String dylibParentFoler) { return dylibPath; } +/// Returns location of dynamic library by searching default locations. Logs +/// error and exits if not found. +String findDylibAtDefaultLocations() { + String? k; + if (Platform.isLinux) { + for (final l in strings.linuxDylibLocations) { + k = findLibclangDylib(l); + if (k != null) return k; + } + } else if (Platform.isWindows) { + for (final l in strings.windowsDylibLocations) { + k = findLibclangDylib(l); + if (k != null) return k; + } + } else if (Platform.isMacOS) { + for (final l in strings.macOsDylibLocations) { + k = findLibclangDylib(l); + if (k != null) return k; + } + } else { + throw Exception('Unsupported Platform.'); + } + + _logger.severe("Couldn't find dynamic library in default locations."); + _logger.severe( + "Please supply the path/to/llvm/lib in ffigen's config under the key 'llvm-lib'."); + throw Exception("Couldn't find dynamic library in default locations."); +} + +String? findLibclangDylib(String parentFolder) { + final location = p.join(parentFolder, strings.dylibFileName); + if (File(location).existsSync()) { + return location; + } else { + return null; + } +} + +String llvmLibExtractor(dynamic value) { + // Extract libclang's dylib from this. + final p = findLibclangDylib(value as String); + if (p == null) { + _logger.severe("Couldn't find ${strings.dylibFileName} at $value."); + exit(1); + } else { + return p; + } +} + +bool llvmLibValidator(String name, dynamic value) { + if (!checkType([name], value) || + !Directory(value as String).existsSync()) { + _logger.severe('Expected $name to be a valid folder Path.'); + return false; + } + return true; +} + String outputExtractor(dynamic value) => _replaceSeparators(value as String); bool outputValidator(String name, dynamic value) => diff --git a/lib/src/find_resource.dart b/lib/src/find_resource.dart deleted file mode 100644 index c16d47ff..00000000 --- a/lib/src/find_resource.dart +++ /dev/null @@ -1,96 +0,0 @@ -// 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 'dart:convert' show jsonDecode; -import 'dart:io' show File, Directory; - -import 'package:logging/logging.dart'; -import 'package:yaml/yaml.dart'; - -final _logger = Logger('ffigen.find_resource'); - -/// Find the `.dart_tool/` folder, returns `null` if unable to find it. -Uri? findDotDartTool() { - // HACK: Because 'dart:isolate' is unavailable in Flutter we have no means - // by which we can find the location of the package_config.json file. - // Which we need, because the binary library created by: - // flutter pub run ffigen:setup - // is located relative to this path. As a workaround we use - // `Platform.script` and traverse level-up until we find a - // `.dart_tool/package_config.json` file. - // Find script directory - var root = Directory.current.uri; - // Traverse up until we see a `.dart_tool/package_config.json` file. - do { - if (File.fromUri(root.resolve('.dart_tool/package_config.json')) - .existsSync()) { - return root.resolve('.dart_tool/'); - } - } while (root != (root = root.resolve('..'))); - return null; -} - -/// Get [Uri] for [posixPath] inside ffigen's rootUri. -Uri? _findInPackageRoot(String posixPath) { - var root = Directory.current.uri; - // Traverse up until we see a `.dart_tool/package_config.json` file. - do { - final file = File.fromUri(root.resolve('.dart_tool/package_config.json')); - if (file.existsSync()) { - /// Read the package_config.json file to extract path of wrapper. - try { - final packageMap = - jsonDecode(file.readAsStringSync()) as Map; - if (packageMap['configVersion'] == 2) { - var ffigenRootUriString = ((packageMap['packages'] as List) - .cast>() - .firstWhere( - (element) => element['name'] == 'ffigen')['rootUri'] - as String); - ffigenRootUriString = ffigenRootUriString.endsWith('/') - ? ffigenRootUriString - : ffigenRootUriString + '/'; - - /// [ffigenRootUri] can be relative to .dart_tool if its from - /// filesystem so we need to resolve it from .dart_tool first. - return file.parent.uri - .resolve(ffigenRootUriString) - .resolve(posixPath); - } - } catch (e, s) { - print(s); - throw Exception('Cannot resolve package:ffigen\'s rootUri.'); - } - } - } while (root != (root = root.resolve('..'))); - return null; -} - -Uri? findWrapper(String wrapperName) { - return _findInPackageRoot('lib/src/clang_library/$wrapperName'); -} - -Uri? _findFfigenPubspecYaml() { - return _findInPackageRoot('pubspec.yaml'); -} - -String? _ffigenVersion; - -/// Gets ffigen version from ffigen's pubspec.yaml -String? get ffigenVersion { - if (_ffigenVersion == null) { - try { - final yaml = - loadYaml(File.fromUri(_findFfigenPubspecYaml()!).readAsStringSync()) - as YamlMap; - final rawVersion = yaml['version'] as String; - // Sanitize name to be used as a file name. - _ffigenVersion = - 'v_${rawVersion.replaceAll('.', '_').replaceAll('+', '_')}'; - } catch (e) { - _logger.severe('Unable to extract ffigen version.'); - } - } - return _ffigenVersion; -} diff --git a/lib/src/header_parser/clang_bindings/clang_bindings.dart b/lib/src/header_parser/clang_bindings/clang_bindings.dart index 213f7719..7e7ab7c8 100644 --- a/lib/src/header_parser/clang_bindings/clang_bindings.dart +++ b/lib/src/header_parser/clang_bindings/clang_bindings.dart @@ -16,6 +16,32 @@ class Clang { /// The symbols are looked up in [dynamicLibrary]. Clang(ffi.DynamicLibrary dynamicLibrary) : _dylib = dynamicLibrary; + /// Retrieve the character data associated with the given string. + ffi.Pointer clang_getCString( + CXString string, + ) { + return (_clang_getCString ??= + _dylib.lookupFunction<_c_clang_getCString, _dart_clang_getCString>( + 'clang_getCString'))( + string, + ); + } + + _dart_clang_getCString? _clang_getCString; + + /// Free the given string. + void clang_disposeString( + CXString string, + ) { + return (_clang_disposeString ??= _dylib.lookupFunction< + _c_clang_disposeString, + _dart_clang_disposeString>('clang_disposeString'))( + string, + ); + } + + _dart_clang_disposeString? _clang_disposeString; + /// Provides a shared context for creating translation units. /// /// It provides two options: @@ -84,6 +110,77 @@ class Clang { _dart_clang_disposeIndex? _clang_disposeIndex; + /// Retrieve the complete file and path name of the given file. + CXString clang_getFileName( + ffi.Pointer SFile, + ) { + return (_clang_getFileName ??= + _dylib.lookupFunction<_c_clang_getFileName, _dart_clang_getFileName>( + 'clang_getFileName'))( + SFile, + ); + } + + _dart_clang_getFileName? _clang_getFileName; + + /// Determine whether two ranges are equivalent. + /// + /// \returns non-zero if the ranges are the same, zero if they differ. + int clang_equalRanges( + CXSourceRange range1, + CXSourceRange range2, + ) { + return (_clang_equalRanges ??= + _dylib.lookupFunction<_c_clang_equalRanges, _dart_clang_equalRanges>( + 'clang_equalRanges'))( + range1, + range2, + ); + } + + _dart_clang_equalRanges? _clang_equalRanges; + + /// Retrieve the file, line, column, and offset represented by + /// the given source location. + /// + /// If the location refers into a macro expansion, return where the macro was + /// expanded or where the macro argument was written, if the location points at + /// a macro argument. + /// + /// \param location the location within a source file that will be decomposed + /// into its parts. + /// + /// \param file [out] if non-NULL, will be set to the file to which the given + /// source location points. + /// + /// \param line [out] if non-NULL, will be set to the line to which the given + /// source location points. + /// + /// \param column [out] if non-NULL, will be set to the column to which the given + /// source location points. + /// + /// \param offset [out] if non-NULL, will be set to the offset into the + /// buffer to which the given source location points. + void clang_getFileLocation( + CXSourceLocation location, + ffi.Pointer> file, + ffi.Pointer line, + ffi.Pointer column, + ffi.Pointer offset, + ) { + return (_clang_getFileLocation ??= _dylib.lookupFunction< + _c_clang_getFileLocation, + _dart_clang_getFileLocation>('clang_getFileLocation'))( + location, + file, + line, + column, + offset, + ); + } + + _dart_clang_getFileLocation? _clang_getFileLocation; + /// Determine the number of diagnostics produced for the given /// translation unit. int clang_getNumDiagnostics( @@ -132,6 +229,33 @@ class Clang { _dart_clang_disposeDiagnostic? _clang_disposeDiagnostic; + /// Format the given diagnostic in a manner that is suitable for display. + /// + /// This routine will format the given diagnostic to a string, rendering + /// the diagnostic according to the various options given. The + /// \c clang_defaultDiagnosticDisplayOptions() function returns the set of + /// options that most closely mimics the behavior of the clang compiler. + /// + /// \param Diagnostic The diagnostic to print. + /// + /// \param Options A set of options that control the diagnostic display, + /// created by combining \c CXDiagnosticDisplayOptions values. + /// + /// \returns A new string containing for formatted diagnostic. + CXString clang_formatDiagnostic( + ffi.Pointer Diagnostic, + int Options, + ) { + return (_clang_formatDiagnostic ??= _dylib.lookupFunction< + _c_clang_formatDiagnostic, + _dart_clang_formatDiagnostic>('clang_formatDiagnostic'))( + Diagnostic, + Options, + ); + } + + _dart_clang_formatDiagnostic? _clang_formatDiagnostic; + /// Same as \c clang_parseTranslationUnit2, but returns /// the \c CXTranslationUnit instead of an error code. In case of an error this /// routine returns a \c NULL \c CXTranslationUnit, without further detailed @@ -173,595 +297,614 @@ class Clang { _dart_clang_disposeTranslationUnit? _clang_disposeTranslationUnit; - /// Returns the kind of the evaluated result. - int clang_EvalResult_getKind( - ffi.Pointer E, - ) { - return (_clang_EvalResult_getKind ??= _dylib.lookupFunction< - _c_clang_EvalResult_getKind, - _dart_clang_EvalResult_getKind>('clang_EvalResult_getKind'))( - E, - ); - } - - _dart_clang_EvalResult_getKind? _clang_EvalResult_getKind; - - /// Returns the evaluation result as integer if the - /// kind is Int. - int clang_EvalResult_getAsInt( - ffi.Pointer E, - ) { - return (_clang_EvalResult_getAsInt ??= _dylib.lookupFunction< - _c_clang_EvalResult_getAsInt, - _dart_clang_EvalResult_getAsInt>('clang_EvalResult_getAsInt'))( - E, - ); - } - - _dart_clang_EvalResult_getAsInt? _clang_EvalResult_getAsInt; - - /// Returns the evaluation result as a long long integer if the - /// kind is Int. This prevents overflows that may happen if the result is - /// returned with clang_EvalResult_getAsInt. - int clang_EvalResult_getAsLongLong( - ffi.Pointer E, - ) { - return (_clang_EvalResult_getAsLongLong ??= _dylib.lookupFunction< - _c_clang_EvalResult_getAsLongLong, - _dart_clang_EvalResult_getAsLongLong>( - 'clang_EvalResult_getAsLongLong'))( - E, - ); - } - - _dart_clang_EvalResult_getAsLongLong? _clang_EvalResult_getAsLongLong; - - /// Returns the evaluation result as double if the - /// kind is double. - double clang_EvalResult_getAsDouble( - ffi.Pointer E, - ) { - return (_clang_EvalResult_getAsDouble ??= _dylib.lookupFunction< - _c_clang_EvalResult_getAsDouble, - _dart_clang_EvalResult_getAsDouble>('clang_EvalResult_getAsDouble'))( - E, - ); - } - - _dart_clang_EvalResult_getAsDouble? _clang_EvalResult_getAsDouble; - - /// Returns the evaluation result as a constant string if the - /// kind is other than Int or float. User must not free this pointer, - /// instead call clang_EvalResult_dispose on the CXEvalResult returned - /// by clang_Cursor_Evaluate. - ffi.Pointer clang_EvalResult_getAsStr( - ffi.Pointer E, - ) { - return (_clang_EvalResult_getAsStr ??= _dylib.lookupFunction< - _c_clang_EvalResult_getAsStr, - _dart_clang_EvalResult_getAsStr>('clang_EvalResult_getAsStr'))( - E, - ); - } - - _dart_clang_EvalResult_getAsStr? _clang_EvalResult_getAsStr; - - /// Disposes the created Eval memory. - void clang_EvalResult_dispose( - ffi.Pointer E, - ) { - return (_clang_EvalResult_dispose ??= _dylib.lookupFunction< - _c_clang_EvalResult_dispose, - _dart_clang_EvalResult_dispose>('clang_EvalResult_dispose'))( - E, - ); - } - - _dart_clang_EvalResult_dispose? _clang_EvalResult_dispose; - - ffi.Pointer clang_getCString_wrap( - ffi.Pointer string, + /// Retrieve the cursor that represents the given translation unit. + /// + /// The translation unit cursor can be used to start traversing the + /// various declarations within the given translation unit. + CXCursor clang_getTranslationUnitCursor( + ffi.Pointer arg0, ) { - return (_clang_getCString_wrap ??= _dylib.lookupFunction< - _c_clang_getCString_wrap, - _dart_clang_getCString_wrap>('clang_getCString_wrap'))( - string, + return (_clang_getTranslationUnitCursor ??= _dylib.lookupFunction< + _c_clang_getTranslationUnitCursor, + _dart_clang_getTranslationUnitCursor>( + 'clang_getTranslationUnitCursor'))( + arg0, ); } - _dart_clang_getCString_wrap? _clang_getCString_wrap; + _dart_clang_getTranslationUnitCursor? _clang_getTranslationUnitCursor; - void clang_disposeString_wrap( - ffi.Pointer string, + /// Retrieve the kind of the given cursor. + int clang_getCursorKind( + CXCursor arg0, ) { - return (_clang_disposeString_wrap ??= _dylib.lookupFunction< - _c_clang_disposeString_wrap, - _dart_clang_disposeString_wrap>('clang_disposeString_wrap'))( - string, + return (_clang_getCursorKind ??= _dylib.lookupFunction< + _c_clang_getCursorKind, + _dart_clang_getCursorKind>('clang_getCursorKind'))( + arg0, ); } - _dart_clang_disposeString_wrap? _clang_disposeString_wrap; + _dart_clang_getCursorKind? _clang_getCursorKind; - int clang_getCursorKind_wrap( - ffi.Pointer cursor, + /// Retrieve the physical location of the source constructor referenced + /// by the given cursor. + /// + /// The location of a declaration is typically the location of the name of that + /// declaration, where the name of that declaration would occur if it is + /// unnamed, or some keyword that introduces that particular declaration. + /// The location of a reference is where that reference occurs within the + /// source code. + CXSourceLocation clang_getCursorLocation( + CXCursor arg0, ) { - return (_clang_getCursorKind_wrap ??= _dylib.lookupFunction< - _c_clang_getCursorKind_wrap, - _dart_clang_getCursorKind_wrap>('clang_getCursorKind_wrap'))( - cursor, + return (_clang_getCursorLocation ??= _dylib.lookupFunction< + _c_clang_getCursorLocation, + _dart_clang_getCursorLocation>('clang_getCursorLocation'))( + arg0, ); } - _dart_clang_getCursorKind_wrap? _clang_getCursorKind_wrap; + _dart_clang_getCursorLocation? _clang_getCursorLocation; - ffi.Pointer clang_getCursorKindSpelling_wrap( - int kind, + /// Retrieve the type of a CXCursor (if any). + CXType clang_getCursorType( + CXCursor C, ) { - return (_clang_getCursorKindSpelling_wrap ??= _dylib.lookupFunction< - _c_clang_getCursorKindSpelling_wrap, - _dart_clang_getCursorKindSpelling_wrap>( - 'clang_getCursorKindSpelling_wrap'))( - kind, + return (_clang_getCursorType ??= _dylib.lookupFunction< + _c_clang_getCursorType, + _dart_clang_getCursorType>('clang_getCursorType'))( + C, ); } - _dart_clang_getCursorKindSpelling_wrap? _clang_getCursorKindSpelling_wrap; + _dart_clang_getCursorType? _clang_getCursorType; - ffi.Pointer clang_getCursorType_wrap( - ffi.Pointer cursor, + /// Pretty-print the underlying type using the rules of the + /// language of the translation unit from which it came. + /// + /// If the type is invalid, an empty string is returned. + CXString clang_getTypeSpelling( + CXType CT, ) { - return (_clang_getCursorType_wrap ??= _dylib.lookupFunction< - _c_clang_getCursorType_wrap, - _dart_clang_getCursorType_wrap>('clang_getCursorType_wrap'))( - cursor, + return (_clang_getTypeSpelling ??= _dylib.lookupFunction< + _c_clang_getTypeSpelling, + _dart_clang_getTypeSpelling>('clang_getTypeSpelling'))( + CT, ); } - _dart_clang_getCursorType_wrap? _clang_getCursorType_wrap; + _dart_clang_getTypeSpelling? _clang_getTypeSpelling; - ffi.Pointer clang_getTypeSpelling_wrap( - ffi.Pointer type, + /// Retrieve the underlying type of a typedef declaration. + /// + /// If the cursor does not reference a typedef declaration, an invalid type is + /// returned. + CXType clang_getTypedefDeclUnderlyingType( + CXCursor C, ) { - return (_clang_getTypeSpelling_wrap ??= _dylib.lookupFunction< - _c_clang_getTypeSpelling_wrap, - _dart_clang_getTypeSpelling_wrap>('clang_getTypeSpelling_wrap'))( - type, + return (_clang_getTypedefDeclUnderlyingType ??= _dylib.lookupFunction< + _c_clang_getTypedefDeclUnderlyingType, + _dart_clang_getTypedefDeclUnderlyingType>( + 'clang_getTypedefDeclUnderlyingType'))( + C, ); } - _dart_clang_getTypeSpelling_wrap? _clang_getTypeSpelling_wrap; + _dart_clang_getTypedefDeclUnderlyingType? _clang_getTypedefDeclUnderlyingType; - ffi.Pointer clang_getTypeKindSpelling_wrap( - int typeKind, + /// Retrieve the integer value of an enum constant declaration as a signed + /// long long. + /// + /// If the cursor does not reference an enum constant declaration, LLONG_MIN is returned. + /// Since this is also potentially a valid constant value, the kind of the cursor + /// must be verified before calling this function. + int clang_getEnumConstantDeclValue( + CXCursor C, ) { - return (_clang_getTypeKindSpelling_wrap ??= _dylib.lookupFunction< - _c_clang_getTypeKindSpelling_wrap, - _dart_clang_getTypeKindSpelling_wrap>( - 'clang_getTypeKindSpelling_wrap'))( - typeKind, + return (_clang_getEnumConstantDeclValue ??= _dylib.lookupFunction< + _c_clang_getEnumConstantDeclValue, + _dart_clang_getEnumConstantDeclValue>( + 'clang_getEnumConstantDeclValue'))( + C, ); } - _dart_clang_getTypeKindSpelling_wrap? _clang_getTypeKindSpelling_wrap; + _dart_clang_getEnumConstantDeclValue? _clang_getEnumConstantDeclValue; - ffi.Pointer clang_getResultType_wrap( - ffi.Pointer functionType, + /// Retrieve the bit width of a bit field declaration as an integer. + /// + /// If a cursor that is not a bit field declaration is passed in, -1 is returned. + int clang_getFieldDeclBitWidth( + CXCursor C, ) { - return (_clang_getResultType_wrap ??= _dylib.lookupFunction< - _c_clang_getResultType_wrap, - _dart_clang_getResultType_wrap>('clang_getResultType_wrap'))( - functionType, + return (_clang_getFieldDeclBitWidth ??= _dylib.lookupFunction< + _c_clang_getFieldDeclBitWidth, + _dart_clang_getFieldDeclBitWidth>('clang_getFieldDeclBitWidth'))( + C, ); } - _dart_clang_getResultType_wrap? _clang_getResultType_wrap; + _dart_clang_getFieldDeclBitWidth? _clang_getFieldDeclBitWidth; - ffi.Pointer clang_getPointeeType_wrap( - ffi.Pointer pointerType, + /// Retrieve the number of non-variadic arguments associated with a given + /// cursor. + /// + /// The number of arguments can be determined for calls as well as for + /// declarations of functions or methods. For other cursors -1 is returned. + int clang_Cursor_getNumArguments( + CXCursor C, ) { - return (_clang_getPointeeType_wrap ??= _dylib.lookupFunction< - _c_clang_getPointeeType_wrap, - _dart_clang_getPointeeType_wrap>('clang_getPointeeType_wrap'))( - pointerType, + return (_clang_Cursor_getNumArguments ??= _dylib.lookupFunction< + _c_clang_Cursor_getNumArguments, + _dart_clang_Cursor_getNumArguments>('clang_Cursor_getNumArguments'))( + C, ); } - _dart_clang_getPointeeType_wrap? _clang_getPointeeType_wrap; + _dart_clang_Cursor_getNumArguments? _clang_Cursor_getNumArguments; - ffi.Pointer clang_getCanonicalType_wrap( - ffi.Pointer typerefType, + /// Retrieve the argument cursor of a function or method. + /// + /// The argument cursor can be determined for calls as well as for declarations + /// of functions or methods. For other cursors and for invalid indices, an + /// invalid cursor is returned. + CXCursor clang_Cursor_getArgument( + CXCursor C, + int i, ) { - return (_clang_getCanonicalType_wrap ??= _dylib.lookupFunction< - _c_clang_getCanonicalType_wrap, - _dart_clang_getCanonicalType_wrap>('clang_getCanonicalType_wrap'))( - typerefType, + return (_clang_Cursor_getArgument ??= _dylib.lookupFunction< + _c_clang_Cursor_getArgument, + _dart_clang_Cursor_getArgument>('clang_Cursor_getArgument'))( + C, + i, ); } - _dart_clang_getCanonicalType_wrap? _clang_getCanonicalType_wrap; + _dart_clang_Cursor_getArgument? _clang_Cursor_getArgument; - ffi.Pointer clang_Type_getNamedType_wrap( - ffi.Pointer elaboratedType, + /// Return the canonical type for a CXType. + /// + /// Clang's type system explicitly models typedefs and all the ways + /// a specific type can be represented. The canonical type is the underlying + /// type with all the "sugar" removed. For example, if 'T' is a typedef + /// for 'int', the canonical type for 'T' would be 'int'. + CXType clang_getCanonicalType( + CXType T, ) { - return (_clang_Type_getNamedType_wrap ??= _dylib.lookupFunction< - _c_clang_Type_getNamedType_wrap, - _dart_clang_Type_getNamedType_wrap>('clang_Type_getNamedType_wrap'))( - elaboratedType, + return (_clang_getCanonicalType ??= _dylib.lookupFunction< + _c_clang_getCanonicalType, + _dart_clang_getCanonicalType>('clang_getCanonicalType'))( + T, ); } - _dart_clang_Type_getNamedType_wrap? _clang_Type_getNamedType_wrap; + _dart_clang_getCanonicalType? _clang_getCanonicalType; - ffi.Pointer clang_getTypeDeclaration_wrap( - ffi.Pointer cxtype, + /// Determine whether a CXCursor that is a macro, is + /// function like. + int clang_Cursor_isMacroFunctionLike( + CXCursor C, ) { - return (_clang_getTypeDeclaration_wrap ??= _dylib.lookupFunction< - _c_clang_getTypeDeclaration_wrap, - _dart_clang_getTypeDeclaration_wrap>('clang_getTypeDeclaration_wrap'))( - cxtype, + return (_clang_Cursor_isMacroFunctionLike ??= _dylib.lookupFunction< + _c_clang_Cursor_isMacroFunctionLike, + _dart_clang_Cursor_isMacroFunctionLike>( + 'clang_Cursor_isMacroFunctionLike'))( + C, ); } - _dart_clang_getTypeDeclaration_wrap? _clang_getTypeDeclaration_wrap; + _dart_clang_Cursor_isMacroFunctionLike? _clang_Cursor_isMacroFunctionLike; - ffi.Pointer clang_getTypedefDeclUnderlyingType_wrap( - ffi.Pointer cxcursor, + /// Determine whether a CXCursor that is a macro, is a + /// builtin one. + int clang_Cursor_isMacroBuiltin( + CXCursor C, ) { - return (_clang_getTypedefDeclUnderlyingType_wrap ??= _dylib.lookupFunction< - _c_clang_getTypedefDeclUnderlyingType_wrap, - _dart_clang_getTypedefDeclUnderlyingType_wrap>( - 'clang_getTypedefDeclUnderlyingType_wrap'))( - cxcursor, + return (_clang_Cursor_isMacroBuiltin ??= _dylib.lookupFunction< + _c_clang_Cursor_isMacroBuiltin, + _dart_clang_Cursor_isMacroBuiltin>('clang_Cursor_isMacroBuiltin'))( + C, ); } - _dart_clang_getTypedefDeclUnderlyingType_wrap? - _clang_getTypedefDeclUnderlyingType_wrap; + _dart_clang_Cursor_isMacroBuiltin? _clang_Cursor_isMacroBuiltin; - /// The name of parameter, struct, typedef. - ffi.Pointer clang_getCursorSpelling_wrap( - ffi.Pointer cursor, + /// For pointer types, returns the type of the pointee. + CXType clang_getPointeeType( + CXType T, ) { - return (_clang_getCursorSpelling_wrap ??= _dylib.lookupFunction< - _c_clang_getCursorSpelling_wrap, - _dart_clang_getCursorSpelling_wrap>('clang_getCursorSpelling_wrap'))( - cursor, + return (_clang_getPointeeType ??= _dylib.lookupFunction< + _c_clang_getPointeeType, + _dart_clang_getPointeeType>('clang_getPointeeType'))( + T, ); } - _dart_clang_getCursorSpelling_wrap? _clang_getCursorSpelling_wrap; + _dart_clang_getPointeeType? _clang_getPointeeType; - ffi.Pointer clang_getTranslationUnitCursor_wrap( - ffi.Pointer tu, + /// Return the cursor for the declaration of the given type. + CXCursor clang_getTypeDeclaration( + CXType T, ) { - return (_clang_getTranslationUnitCursor_wrap ??= _dylib.lookupFunction< - _c_clang_getTranslationUnitCursor_wrap, - _dart_clang_getTranslationUnitCursor_wrap>( - 'clang_getTranslationUnitCursor_wrap'))( - tu, + return (_clang_getTypeDeclaration ??= _dylib.lookupFunction< + _c_clang_getTypeDeclaration, + _dart_clang_getTypeDeclaration>('clang_getTypeDeclaration'))( + T, ); } - _dart_clang_getTranslationUnitCursor_wrap? - _clang_getTranslationUnitCursor_wrap; + _dart_clang_getTypeDeclaration? _clang_getTypeDeclaration; - ffi.Pointer clang_formatDiagnostic_wrap( - ffi.Pointer diag, - int opts, + /// Retrieve the spelling of a given CXTypeKind. + CXString clang_getTypeKindSpelling( + int K, ) { - return (_clang_formatDiagnostic_wrap ??= _dylib.lookupFunction< - _c_clang_formatDiagnostic_wrap, - _dart_clang_formatDiagnostic_wrap>('clang_formatDiagnostic_wrap'))( - diag, - opts, + return (_clang_getTypeKindSpelling ??= _dylib.lookupFunction< + _c_clang_getTypeKindSpelling, + _dart_clang_getTypeKindSpelling>('clang_getTypeKindSpelling'))( + K, ); } - _dart_clang_formatDiagnostic_wrap? _clang_formatDiagnostic_wrap; + _dart_clang_getTypeKindSpelling? _clang_getTypeKindSpelling; - /// Visitor is a function pointer with parameters having pointers to cxcursor - /// instead of cxcursor by default. - int clang_visitChildren_wrap( - ffi.Pointer parent, - ffi.Pointer> _modifiedVisitor, - int uid, + /// Retrieve the return type associated with a function type. + /// + /// If a non-function type is passed in, an invalid type is returned. + CXType clang_getResultType( + CXType T, ) { - return (_clang_visitChildren_wrap ??= _dylib.lookupFunction< - _c_clang_visitChildren_wrap, - _dart_clang_visitChildren_wrap>('clang_visitChildren_wrap'))( - parent, - _modifiedVisitor, - uid, + return (_clang_getResultType ??= _dylib.lookupFunction< + _c_clang_getResultType, + _dart_clang_getResultType>('clang_getResultType'))( + T, ); } - _dart_clang_visitChildren_wrap? _clang_visitChildren_wrap; + _dart_clang_getResultType? _clang_getResultType; - int clang_Cursor_getNumArguments_wrap( - ffi.Pointer cursor, + /// Retrieve the number of non-variadic parameters associated with a + /// function type. + /// + /// If a non-function type is passed in, -1 is returned. + int clang_getNumArgTypes( + CXType T, ) { - return (_clang_Cursor_getNumArguments_wrap ??= _dylib.lookupFunction< - _c_clang_Cursor_getNumArguments_wrap, - _dart_clang_Cursor_getNumArguments_wrap>( - 'clang_Cursor_getNumArguments_wrap'))( - cursor, + return (_clang_getNumArgTypes ??= _dylib.lookupFunction< + _c_clang_getNumArgTypes, + _dart_clang_getNumArgTypes>('clang_getNumArgTypes'))( + T, ); } - _dart_clang_Cursor_getNumArguments_wrap? _clang_Cursor_getNumArguments_wrap; + _dart_clang_getNumArgTypes? _clang_getNumArgTypes; - ffi.Pointer clang_Cursor_getArgument_wrap( - ffi.Pointer cursor, + /// Retrieve the type of a parameter of a function type. + /// + /// If a non-function type is passed in or the function does not have enough + /// parameters, an invalid type is returned. + CXType clang_getArgType( + CXType T, int i, ) { - return (_clang_Cursor_getArgument_wrap ??= _dylib.lookupFunction< - _c_clang_Cursor_getArgument_wrap, - _dart_clang_Cursor_getArgument_wrap>('clang_Cursor_getArgument_wrap'))( - cursor, + return (_clang_getArgType ??= + _dylib.lookupFunction<_c_clang_getArgType, _dart_clang_getArgType>( + 'clang_getArgType'))( + T, i, ); } - _dart_clang_Cursor_getArgument_wrap? _clang_Cursor_getArgument_wrap; + _dart_clang_getArgType? _clang_getArgType; - int clang_getNumArgTypes_wrap( - ffi.Pointer cxtype, + /// Return the number of elements of an array or vector type. + /// + /// If a type is passed in that is not an array or vector type, + /// -1 is returned. + int clang_getNumElements( + CXType T, ) { - return (_clang_getNumArgTypes_wrap ??= _dylib.lookupFunction< - _c_clang_getNumArgTypes_wrap, - _dart_clang_getNumArgTypes_wrap>('clang_getNumArgTypes_wrap'))( - cxtype, + return (_clang_getNumElements ??= _dylib.lookupFunction< + _c_clang_getNumElements, + _dart_clang_getNumElements>('clang_getNumElements'))( + T, ); } - _dart_clang_getNumArgTypes_wrap? _clang_getNumArgTypes_wrap; + _dart_clang_getNumElements? _clang_getNumElements; - ffi.Pointer clang_getArgType_wrap( - ffi.Pointer cxtype, - int i, + /// Return the element type of an array type. + /// + /// If a non-array type is passed in, an invalid type is returned. + CXType clang_getArrayElementType( + CXType T, ) { - return (_clang_getArgType_wrap ??= _dylib.lookupFunction< - _c_clang_getArgType_wrap, - _dart_clang_getArgType_wrap>('clang_getArgType_wrap'))( - cxtype, - i, + return (_clang_getArrayElementType ??= _dylib.lookupFunction< + _c_clang_getArrayElementType, + _dart_clang_getArrayElementType>('clang_getArrayElementType'))( + T, ); } - _dart_clang_getArgType_wrap? _clang_getArgType_wrap; + _dart_clang_getArrayElementType? _clang_getArrayElementType; - int clang_getEnumConstantDeclValue_wrap( - ffi.Pointer cursor, + /// Retrieve the type named by the qualified-id. + /// + /// If a non-elaborated type is passed in, an invalid type is returned. + CXType clang_Type_getNamedType( + CXType T, ) { - return (_clang_getEnumConstantDeclValue_wrap ??= _dylib.lookupFunction< - _c_clang_getEnumConstantDeclValue_wrap, - _dart_clang_getEnumConstantDeclValue_wrap>( - 'clang_getEnumConstantDeclValue_wrap'))( - cursor, + return (_clang_Type_getNamedType ??= _dylib.lookupFunction< + _c_clang_Type_getNamedType, + _dart_clang_Type_getNamedType>('clang_Type_getNamedType'))( + T, ); } - _dart_clang_getEnumConstantDeclValue_wrap? - _clang_getEnumConstantDeclValue_wrap; + _dart_clang_Type_getNamedType? _clang_Type_getNamedType; - /// Returns non-zero if the ranges are the same, zero if they differ. - int clang_equalRanges_wrap( - ffi.Pointer c1, - ffi.Pointer c2, + /// Determine whether the given cursor represents an anonymous + /// tag or namespace + int clang_Cursor_isAnonymous( + CXCursor C, ) { - return (_clang_equalRanges_wrap ??= _dylib.lookupFunction< - _c_clang_equalRanges_wrap, - _dart_clang_equalRanges_wrap>('clang_equalRanges_wrap'))( - c1, - c2, + return (_clang_Cursor_isAnonymous ??= _dylib.lookupFunction< + _c_clang_Cursor_isAnonymous, + _dart_clang_Cursor_isAnonymous>('clang_Cursor_isAnonymous'))( + C, ); } - _dart_clang_equalRanges_wrap? _clang_equalRanges_wrap; + _dart_clang_Cursor_isAnonymous? _clang_Cursor_isAnonymous; - /// Returns the comment range. - ffi.Pointer clang_Cursor_getCommentRange_wrap( - ffi.Pointer cursor, + /// Determine whether the given cursor represents an anonymous record + /// declaration. + int clang_Cursor_isAnonymousRecordDecl( + CXCursor C, ) { - return (_clang_Cursor_getCommentRange_wrap ??= _dylib.lookupFunction< - _c_clang_Cursor_getCommentRange_wrap, - _dart_clang_Cursor_getCommentRange_wrap>( - 'clang_Cursor_getCommentRange_wrap'))( - cursor, + return (_clang_Cursor_isAnonymousRecordDecl ??= _dylib.lookupFunction< + _c_clang_Cursor_isAnonymousRecordDecl, + _dart_clang_Cursor_isAnonymousRecordDecl>( + 'clang_Cursor_isAnonymousRecordDecl'))( + C, ); } - _dart_clang_Cursor_getCommentRange_wrap? _clang_Cursor_getCommentRange_wrap; + _dart_clang_Cursor_isAnonymousRecordDecl? _clang_Cursor_isAnonymousRecordDecl; - /// Returns the raw comment. - ffi.Pointer clang_Cursor_getRawCommentText_wrap( - ffi.Pointer cursor, + /// Visit the children of a particular cursor. + /// + /// This function visits all the direct children of the given cursor, + /// invoking the given \p visitor function with the cursors of each + /// visited child. The traversal may be recursive, if the visitor returns + /// \c CXChildVisit_Recurse. The traversal may also be ended prematurely, if + /// the visitor returns \c CXChildVisit_Break. + /// + /// \param parent the cursor whose child may be visited. All kinds of + /// cursors can be visited, including invalid cursors (which, by + /// definition, have no children). + /// + /// \param visitor the visitor function that will be invoked for each + /// child of \p parent. + /// + /// \param client_data pointer data supplied by the client, which will + /// be passed to the visitor each time it is invoked. + /// + /// \returns a non-zero value if the traversal was terminated + /// prematurely by the visitor returning \c CXChildVisit_Break. + int clang_visitChildren( + CXCursor parent, + ffi.Pointer> visitor, + ffi.Pointer client_data, ) { - return (_clang_Cursor_getRawCommentText_wrap ??= _dylib.lookupFunction< - _c_clang_Cursor_getRawCommentText_wrap, - _dart_clang_Cursor_getRawCommentText_wrap>( - 'clang_Cursor_getRawCommentText_wrap'))( - cursor, + return (_clang_visitChildren ??= _dylib.lookupFunction< + _c_clang_visitChildren, + _dart_clang_visitChildren>('clang_visitChildren'))( + parent, + visitor, + client_data, ); } - _dart_clang_Cursor_getRawCommentText_wrap? - _clang_Cursor_getRawCommentText_wrap; + _dart_clang_visitChildren? _clang_visitChildren; - /// Returns the first paragraph of doxygen doc comment. - ffi.Pointer clang_Cursor_getBriefCommentText_wrap( - ffi.Pointer cursor, + /// Retrieve a Unified Symbol Resolution (USR) for the entity referenced + /// by the given cursor. + /// + /// A Unified Symbol Resolution (USR) is a string that identifies a particular + /// entity (function, class, variable, etc.) within a program. USRs can be + /// compared across translation units to determine, e.g., when references in + /// one translation refer to an entity defined in another translation unit. + CXString clang_getCursorUSR( + CXCursor arg0, ) { - return (_clang_Cursor_getBriefCommentText_wrap ??= _dylib.lookupFunction< - _c_clang_Cursor_getBriefCommentText_wrap, - _dart_clang_Cursor_getBriefCommentText_wrap>( - 'clang_Cursor_getBriefCommentText_wrap'))( - cursor, + return (_clang_getCursorUSR ??= + _dylib.lookupFunction<_c_clang_getCursorUSR, _dart_clang_getCursorUSR>( + 'clang_getCursorUSR'))( + arg0, ); } - _dart_clang_Cursor_getBriefCommentText_wrap? - _clang_Cursor_getBriefCommentText_wrap; + _dart_clang_getCursorUSR? _clang_getCursorUSR; - ffi.Pointer clang_getCursorLocation_wrap( - ffi.Pointer cursor, + /// Retrieve a name for the entity referenced by this cursor. + CXString clang_getCursorSpelling( + CXCursor arg0, ) { - return (_clang_getCursorLocation_wrap ??= _dylib.lookupFunction< - _c_clang_getCursorLocation_wrap, - _dart_clang_getCursorLocation_wrap>('clang_getCursorLocation_wrap'))( - cursor, + return (_clang_getCursorSpelling ??= _dylib.lookupFunction< + _c_clang_getCursorSpelling, + _dart_clang_getCursorSpelling>('clang_getCursorSpelling'))( + arg0, ); } - _dart_clang_getCursorLocation_wrap? _clang_getCursorLocation_wrap; + _dart_clang_getCursorSpelling? _clang_getCursorSpelling; - void clang_getFileLocation_wrap( - ffi.Pointer location, - ffi.Pointer> file, - ffi.Pointer line, - ffi.Pointer column, - ffi.Pointer offset, + /// Given a cursor that represents a declaration, return the associated + /// comment's source range. The range may include multiple consecutive comments + /// with whitespace in between. + CXSourceRange clang_Cursor_getCommentRange( + CXCursor C, ) { - return (_clang_getFileLocation_wrap ??= _dylib.lookupFunction< - _c_clang_getFileLocation_wrap, - _dart_clang_getFileLocation_wrap>('clang_getFileLocation_wrap'))( - location, - file, - line, - column, - offset, + return (_clang_Cursor_getCommentRange ??= _dylib.lookupFunction< + _c_clang_Cursor_getCommentRange, + _dart_clang_Cursor_getCommentRange>('clang_Cursor_getCommentRange'))( + C, ); } - _dart_clang_getFileLocation_wrap? _clang_getFileLocation_wrap; + _dart_clang_Cursor_getCommentRange? _clang_Cursor_getCommentRange; - ffi.Pointer clang_getFileName_wrap( - ffi.Pointer SFile, + /// Given a cursor that represents a declaration, return the associated + /// comment text, including comment markers. + CXString clang_Cursor_getRawCommentText( + CXCursor C, ) { - return (_clang_getFileName_wrap ??= _dylib.lookupFunction< - _c_clang_getFileName_wrap, - _dart_clang_getFileName_wrap>('clang_getFileName_wrap'))( - SFile, + return (_clang_Cursor_getRawCommentText ??= _dylib.lookupFunction< + _c_clang_Cursor_getRawCommentText, + _dart_clang_Cursor_getRawCommentText>( + 'clang_Cursor_getRawCommentText'))( + C, ); } - _dart_clang_getFileName_wrap? _clang_getFileName_wrap; + _dart_clang_Cursor_getRawCommentText? _clang_Cursor_getRawCommentText; - int clang_getNumElements_wrap( - ffi.Pointer cxtype, + /// Given a cursor that represents a documentable entity (e.g., + /// declaration), return the associated \paragraph; otherwise return the + /// first paragraph. + CXString clang_Cursor_getBriefCommentText( + CXCursor C, ) { - return (_clang_getNumElements_wrap ??= _dylib.lookupFunction< - _c_clang_getNumElements_wrap, - _dart_clang_getNumElements_wrap>('clang_getNumElements_wrap'))( - cxtype, + return (_clang_Cursor_getBriefCommentText ??= _dylib.lookupFunction< + _c_clang_Cursor_getBriefCommentText, + _dart_clang_Cursor_getBriefCommentText>( + 'clang_Cursor_getBriefCommentText'))( + C, ); } - _dart_clang_getNumElements_wrap? _clang_getNumElements_wrap; + _dart_clang_Cursor_getBriefCommentText? _clang_Cursor_getBriefCommentText; - ffi.Pointer clang_getArrayElementType_wrap( - ffi.Pointer cxtype, + /// \defgroup CINDEX_DEBUG Debugging facilities + /// + /// These routines are used for testing and debugging, only, and should not + /// be relied upon. + /// + /// @{ + CXString clang_getCursorKindSpelling( + int Kind, ) { - return (_clang_getArrayElementType_wrap ??= _dylib.lookupFunction< - _c_clang_getArrayElementType_wrap, - _dart_clang_getArrayElementType_wrap>( - 'clang_getArrayElementType_wrap'))( - cxtype, + return (_clang_getCursorKindSpelling ??= _dylib.lookupFunction< + _c_clang_getCursorKindSpelling, + _dart_clang_getCursorKindSpelling>('clang_getCursorKindSpelling'))( + Kind, ); } - _dart_clang_getArrayElementType_wrap? _clang_getArrayElementType_wrap; + _dart_clang_getCursorKindSpelling? _clang_getCursorKindSpelling; - int clang_Cursor_isMacroFunctionLike_wrap( - ffi.Pointer cursor, + /// If cursor is a statement declaration tries to evaluate the + /// statement and if its variable, tries to evaluate its initializer, + /// into its corresponding type. + ffi.Pointer clang_Cursor_Evaluate( + CXCursor C, ) { - return (_clang_Cursor_isMacroFunctionLike_wrap ??= _dylib.lookupFunction< - _c_clang_Cursor_isMacroFunctionLike_wrap, - _dart_clang_Cursor_isMacroFunctionLike_wrap>( - 'clang_Cursor_isMacroFunctionLike_wrap'))( - cursor, + return (_clang_Cursor_Evaluate ??= _dylib.lookupFunction< + _c_clang_Cursor_Evaluate, + _dart_clang_Cursor_Evaluate>('clang_Cursor_Evaluate'))( + C, ); } - _dart_clang_Cursor_isMacroFunctionLike_wrap? - _clang_Cursor_isMacroFunctionLike_wrap; + _dart_clang_Cursor_Evaluate? _clang_Cursor_Evaluate; - int clang_Cursor_isMacroBuiltin_wrap( - ffi.Pointer cursor, + /// Returns the kind of the evaluated result. + int clang_EvalResult_getKind( + ffi.Pointer E, ) { - return (_clang_Cursor_isMacroBuiltin_wrap ??= _dylib.lookupFunction< - _c_clang_Cursor_isMacroBuiltin_wrap, - _dart_clang_Cursor_isMacroBuiltin_wrap>( - 'clang_Cursor_isMacroBuiltin_wrap'))( - cursor, + return (_clang_EvalResult_getKind ??= _dylib.lookupFunction< + _c_clang_EvalResult_getKind, + _dart_clang_EvalResult_getKind>('clang_EvalResult_getKind'))( + E, ); } - _dart_clang_Cursor_isMacroBuiltin_wrap? _clang_Cursor_isMacroBuiltin_wrap; + _dart_clang_EvalResult_getKind? _clang_EvalResult_getKind; - ffi.Pointer clang_Cursor_Evaluate_wrap( - ffi.Pointer cursor, + /// Returns the evaluation result as integer if the + /// kind is Int. + int clang_EvalResult_getAsInt( + ffi.Pointer E, ) { - return (_clang_Cursor_Evaluate_wrap ??= _dylib.lookupFunction< - _c_clang_Cursor_Evaluate_wrap, - _dart_clang_Cursor_Evaluate_wrap>('clang_Cursor_Evaluate_wrap'))( - cursor, + return (_clang_EvalResult_getAsInt ??= _dylib.lookupFunction< + _c_clang_EvalResult_getAsInt, + _dart_clang_EvalResult_getAsInt>('clang_EvalResult_getAsInt'))( + E, ); } - _dart_clang_Cursor_Evaluate_wrap? _clang_Cursor_Evaluate_wrap; + _dart_clang_EvalResult_getAsInt? _clang_EvalResult_getAsInt; - int clang_Cursor_isAnonymous_wrap( - ffi.Pointer cursor, + /// Returns the evaluation result as a long long integer if the + /// kind is Int. This prevents overflows that may happen if the result is + /// returned with clang_EvalResult_getAsInt. + int clang_EvalResult_getAsLongLong( + ffi.Pointer E, ) { - return (_clang_Cursor_isAnonymous_wrap ??= _dylib.lookupFunction< - _c_clang_Cursor_isAnonymous_wrap, - _dart_clang_Cursor_isAnonymous_wrap>('clang_Cursor_isAnonymous_wrap'))( - cursor, + return (_clang_EvalResult_getAsLongLong ??= _dylib.lookupFunction< + _c_clang_EvalResult_getAsLongLong, + _dart_clang_EvalResult_getAsLongLong>( + 'clang_EvalResult_getAsLongLong'))( + E, ); } - _dart_clang_Cursor_isAnonymous_wrap? _clang_Cursor_isAnonymous_wrap; + _dart_clang_EvalResult_getAsLongLong? _clang_EvalResult_getAsLongLong; - int clang_Cursor_isAnonymousRecordDecl_wrap( - ffi.Pointer cursor, + /// Returns the evaluation result as double if the + /// kind is double. + double clang_EvalResult_getAsDouble( + ffi.Pointer E, ) { - return (_clang_Cursor_isAnonymousRecordDecl_wrap ??= _dylib.lookupFunction< - _c_clang_Cursor_isAnonymousRecordDecl_wrap, - _dart_clang_Cursor_isAnonymousRecordDecl_wrap>( - 'clang_Cursor_isAnonymousRecordDecl_wrap'))( - cursor, + return (_clang_EvalResult_getAsDouble ??= _dylib.lookupFunction< + _c_clang_EvalResult_getAsDouble, + _dart_clang_EvalResult_getAsDouble>('clang_EvalResult_getAsDouble'))( + E, ); } - _dart_clang_Cursor_isAnonymousRecordDecl_wrap? - _clang_Cursor_isAnonymousRecordDecl_wrap; + _dart_clang_EvalResult_getAsDouble? _clang_EvalResult_getAsDouble; - ffi.Pointer clang_getCursorUSR_wrap( - ffi.Pointer cursor, + /// Returns the evaluation result as a constant string if the + /// kind is other than Int or float. User must not free this pointer, + /// instead call clang_EvalResult_dispose on the CXEvalResult returned + /// by clang_Cursor_Evaluate. + ffi.Pointer clang_EvalResult_getAsStr( + ffi.Pointer E, ) { - return (_clang_getCursorUSR_wrap ??= _dylib.lookupFunction< - _c_clang_getCursorUSR_wrap, - _dart_clang_getCursorUSR_wrap>('clang_getCursorUSR_wrap'))( - cursor, + return (_clang_EvalResult_getAsStr ??= _dylib.lookupFunction< + _c_clang_EvalResult_getAsStr, + _dart_clang_EvalResult_getAsStr>('clang_EvalResult_getAsStr'))( + E, ); } - _dart_clang_getCursorUSR_wrap? _clang_getCursorUSR_wrap; + _dart_clang_EvalResult_getAsStr? _clang_EvalResult_getAsStr; - int clang_getFieldDeclBitWidth_wrap( - ffi.Pointer cursor, + /// Disposes the created Eval memory. + void clang_EvalResult_dispose( + ffi.Pointer E, ) { - return (_clang_getFieldDeclBitWidth_wrap ??= _dylib.lookupFunction< - _c_clang_getFieldDeclBitWidth_wrap, - _dart_clang_getFieldDeclBitWidth_wrap>( - 'clang_getFieldDeclBitWidth_wrap'))( - cursor, + return (_clang_EvalResult_dispose ??= _dylib.lookupFunction< + _c_clang_EvalResult_dispose, + _dart_clang_EvalResult_dispose>('clang_EvalResult_dispose'))( + E, ); } - _dart_clang_getFieldDeclBitWidth_wrap? _clang_getFieldDeclBitWidth_wrap; + _dart_clang_EvalResult_dispose? _clang_EvalResult_dispose; } /// A character string. @@ -1429,49 +1572,46 @@ abstract class CXCursorKind { /// \endcode static const int CXCursor_CXXFunctionalCastExpr = 128; - /// OpenCL's addrspace_cast<> expression. - static const int CXCursor_CXXAddrspaceCastExpr = 129; - /// A C++ typeid expression (C++ [expr.typeid]). - static const int CXCursor_CXXTypeidExpr = 130; + static const int CXCursor_CXXTypeidExpr = 129; /// [C++ 2.13.5] C++ Boolean Literal. - static const int CXCursor_CXXBoolLiteralExpr = 131; + static const int CXCursor_CXXBoolLiteralExpr = 130; /// [C++0x 2.14.7] C++ Pointer Literal. - static const int CXCursor_CXXNullPtrLiteralExpr = 132; + static const int CXCursor_CXXNullPtrLiteralExpr = 131; /// Represents the "this" expression in C++ - static const int CXCursor_CXXThisExpr = 133; + static const int CXCursor_CXXThisExpr = 132; /// [C++ 15] C++ Throw Expression. /// /// This handles 'throw' and 'throw' assignment-expression. When /// assignment-expression isn't present, Op will be null. - static const int CXCursor_CXXThrowExpr = 134; + static const int CXCursor_CXXThrowExpr = 133; /// A new expression for memory allocation and constructor calls, e.g: /// "new CXXNewExpr(foo)". - static const int CXCursor_CXXNewExpr = 135; + static const int CXCursor_CXXNewExpr = 134; /// A delete expression for memory deallocation and destructor calls, /// e.g. "delete[] pArray". - static const int CXCursor_CXXDeleteExpr = 136; + static const int CXCursor_CXXDeleteExpr = 135; /// A unary expression. (noexcept, sizeof, or other traits) - static const int CXCursor_UnaryExpr = 137; + static const int CXCursor_UnaryExpr = 136; /// An Objective-C string literal i.e. @"foo". - static const int CXCursor_ObjCStringLiteral = 138; + static const int CXCursor_ObjCStringLiteral = 137; /// An Objective-C \@encode expression. - static const int CXCursor_ObjCEncodeExpr = 139; + static const int CXCursor_ObjCEncodeExpr = 138; /// An Objective-C \@selector expression. - static const int CXCursor_ObjCSelectorExpr = 140; + static const int CXCursor_ObjCSelectorExpr = 139; /// An Objective-C \@protocol expression. - static const int CXCursor_ObjCProtocolExpr = 141; + static const int CXCursor_ObjCProtocolExpr = 140; /// An Objective-C "bridged" cast expression, which casts between /// Objective-C pointers and C pointers, transferring ownership in the process. @@ -1479,7 +1619,7 @@ abstract class CXCursorKind { /// \code /// NSString *str = (__bridge_transfer NSString *)CFCreateString(); /// \endcode - static const int CXCursor_ObjCBridgedCastExpr = 142; + static const int CXCursor_ObjCBridgedCastExpr = 141; /// Represents a C++0x pack expansion that produces a sequence of /// expressions. @@ -1493,7 +1633,7 @@ abstract class CXCursorKind { /// f(static_cast(args)...); /// } /// \endcode - static const int CXCursor_PackExpansionExpr = 143; + static const int CXCursor_PackExpansionExpr = 142; /// Represents an expression that computes the length of a parameter /// pack. @@ -1504,30 +1644,24 @@ abstract class CXCursorKind { /// static const unsigned value = sizeof...(Types); /// }; /// \endcode - static const int CXCursor_SizeOfPackExpr = 144; - static const int CXCursor_LambdaExpr = 145; + static const int CXCursor_SizeOfPackExpr = 143; + static const int CXCursor_LambdaExpr = 144; /// Objective-c Boolean Literal. - static const int CXCursor_ObjCBoolLiteralExpr = 146; + static const int CXCursor_ObjCBoolLiteralExpr = 145; /// Represents the "self" expression in an Objective-C method. - static const int CXCursor_ObjCSelfExpr = 147; + static const int CXCursor_ObjCSelfExpr = 146; - /// OpenMP 5.0 [2.1.5, Array Section]. - static const int CXCursor_OMPArraySectionExpr = 148; + /// OpenMP 4.0 [2.4, Array Section]. + static const int CXCursor_OMPArraySectionExpr = 147; /// Represents an @available(...) check. - static const int CXCursor_ObjCAvailabilityCheckExpr = 149; + static const int CXCursor_ObjCAvailabilityCheckExpr = 148; /// Fixed point literal - static const int CXCursor_FixedPointLiteral = 150; - - /// OpenMP 5.0 [2.1.4, Array Shaping]. - static const int CXCursor_OMPArrayShapingExpr = 151; - - /// OpenMP 5.0 [2.1.6 Iterators] - static const int CXCursor_OMPIteratorExpr = 152; - static const int CXCursor_LastExpr = 152; + static const int CXCursor_FixedPointLiteral = 149; + static const int CXCursor_LastExpr = 149; static const int CXCursor_FirstStmt = 200; /// A statement whose specific kind is not exposed via this @@ -1809,13 +1943,7 @@ abstract class CXCursorKind { /// OpenMP parallel master directive. static const int CXCursor_OMPParallelMasterDirective = 285; - - /// OpenMP depobj directive. - static const int CXCursor_OMPDepobjDirective = 286; - - /// OpenMP scan directive. - static const int CXCursor_OMPScanDirective = 287; - static const int CXCursor_LastStmt = 287; + static const int CXCursor_LastStmt = 285; /// Cursor that represents the translation unit itself. /// @@ -2018,9 +2146,8 @@ abstract class CXTypeKind { static const int CXType_UShortAccum = 36; static const int CXType_UAccum = 37; static const int CXType_ULongAccum = 38; - static const int CXType_BFloat16 = 39; static const int CXType_FirstBuiltin = 2; - static const int CXType_LastBuiltin = 39; + static const int CXType_LastBuiltin = 38; static const int CXType_Complex = 100; static const int CXType_Pointer = 101; static const int CXType_BlockPointer = 102; @@ -2102,7 +2229,6 @@ abstract class CXTypeKind { static const int CXType_OCLIntelSubgroupAVCImeSingleRefStreamin = 174; static const int CXType_OCLIntelSubgroupAVCImeDualRefStreamin = 175; static const int CXType_ExtVector = 176; - static const int CXType_Atomic = 177; } /// The type of an element in the abstract syntax tree. @@ -2191,11 +2317,27 @@ abstract class CXEvalResultKind { const int CINDEX_VERSION_MAJOR = 0; -const int CINDEX_VERSION_MINOR = 60; +const int CINDEX_VERSION_MINOR = 59; -const int CINDEX_VERSION = 60; +const int CINDEX_VERSION = 59; -const String CINDEX_VERSION_STRING = '0.60'; +const String CINDEX_VERSION_STRING = '0.59'; + +typedef _c_clang_getCString = ffi.Pointer Function( + CXString string, +); + +typedef _dart_clang_getCString = ffi.Pointer Function( + CXString string, +); + +typedef _c_clang_disposeString = ffi.Void Function( + CXString string, +); + +typedef _dart_clang_disposeString = void Function( + CXString string, +); typedef _c_clang_createIndex = ffi.Pointer Function( ffi.Int32 excludeDeclarationsFromPCH, @@ -2215,6 +2357,40 @@ typedef _dart_clang_disposeIndex = void Function( ffi.Pointer index, ); +typedef _c_clang_getFileName = CXString Function( + ffi.Pointer SFile, +); + +typedef _dart_clang_getFileName = CXString Function( + ffi.Pointer SFile, +); + +typedef _c_clang_equalRanges = ffi.Uint32 Function( + CXSourceRange range1, + CXSourceRange range2, +); + +typedef _dart_clang_equalRanges = int Function( + CXSourceRange range1, + CXSourceRange range2, +); + +typedef _c_clang_getFileLocation = ffi.Void Function( + CXSourceLocation location, + ffi.Pointer> file, + ffi.Pointer line, + ffi.Pointer column, + ffi.Pointer offset, +); + +typedef _dart_clang_getFileLocation = void Function( + CXSourceLocation location, + ffi.Pointer> file, + ffi.Pointer line, + ffi.Pointer column, + ffi.Pointer offset, +); + typedef _c_clang_getNumDiagnostics = ffi.Uint32 Function( ffi.Pointer Unit, ); @@ -2241,6 +2417,16 @@ typedef _dart_clang_disposeDiagnostic = void Function( ffi.Pointer Diagnostic, ); +typedef _c_clang_formatDiagnostic = CXString Function( + ffi.Pointer Diagnostic, + ffi.Uint32 Options, +); + +typedef _dart_clang_formatDiagnostic = CXString Function( + ffi.Pointer Diagnostic, + int Options, +); + typedef _c_clang_parseTranslationUnit = ffi.Pointer Function( ffi.Pointer CIdx, @@ -2271,390 +2457,320 @@ typedef _dart_clang_disposeTranslationUnit = void Function( ffi.Pointer arg0, ); -typedef _c_clang_EvalResult_getKind = ffi.Int32 Function( - ffi.Pointer E, -); - -typedef _dart_clang_EvalResult_getKind = int Function( - ffi.Pointer E, -); - -typedef _c_clang_EvalResult_getAsInt = ffi.Int32 Function( - ffi.Pointer E, -); - -typedef _dart_clang_EvalResult_getAsInt = int Function( - ffi.Pointer E, -); - -typedef _c_clang_EvalResult_getAsLongLong = ffi.Int64 Function( - ffi.Pointer E, -); - -typedef _dart_clang_EvalResult_getAsLongLong = int Function( - ffi.Pointer E, -); - -typedef _c_clang_EvalResult_getAsDouble = ffi.Double Function( - ffi.Pointer E, -); - -typedef _dart_clang_EvalResult_getAsDouble = double Function( - ffi.Pointer E, -); - -typedef _c_clang_EvalResult_getAsStr = ffi.Pointer Function( - ffi.Pointer E, -); - -typedef _dart_clang_EvalResult_getAsStr = ffi.Pointer Function( - ffi.Pointer E, -); - -typedef _c_clang_EvalResult_dispose = ffi.Void Function( - ffi.Pointer E, -); - -typedef _dart_clang_EvalResult_dispose = void Function( - ffi.Pointer E, -); - -typedef _c_clang_getCString_wrap = ffi.Pointer Function( - ffi.Pointer string, +typedef _c_clang_getTranslationUnitCursor = CXCursor Function( + ffi.Pointer arg0, ); -typedef _dart_clang_getCString_wrap = ffi.Pointer Function( - ffi.Pointer string, +typedef _dart_clang_getTranslationUnitCursor = CXCursor Function( + ffi.Pointer arg0, ); -typedef _c_clang_disposeString_wrap = ffi.Void Function( - ffi.Pointer string, +typedef _c_clang_getCursorKind = ffi.Int32 Function( + CXCursor arg0, ); -typedef _dart_clang_disposeString_wrap = void Function( - ffi.Pointer string, +typedef _dart_clang_getCursorKind = int Function( + CXCursor arg0, ); -typedef _c_clang_getCursorKind_wrap = ffi.Int32 Function( - ffi.Pointer cursor, +typedef _c_clang_getCursorLocation = CXSourceLocation Function( + CXCursor arg0, ); -typedef _dart_clang_getCursorKind_wrap = int Function( - ffi.Pointer cursor, +typedef _dart_clang_getCursorLocation = CXSourceLocation Function( + CXCursor arg0, ); -typedef _c_clang_getCursorKindSpelling_wrap = ffi.Pointer Function( - ffi.Int32 kind, +typedef _c_clang_getCursorType = CXType Function( + CXCursor C, ); -typedef _dart_clang_getCursorKindSpelling_wrap = ffi.Pointer Function( - int kind, +typedef _dart_clang_getCursorType = CXType Function( + CXCursor C, ); -typedef _c_clang_getCursorType_wrap = ffi.Pointer Function( - ffi.Pointer cursor, +typedef _c_clang_getTypeSpelling = CXString Function( + CXType CT, ); -typedef _dart_clang_getCursorType_wrap = ffi.Pointer Function( - ffi.Pointer cursor, +typedef _dart_clang_getTypeSpelling = CXString Function( + CXType CT, ); -typedef _c_clang_getTypeSpelling_wrap = ffi.Pointer Function( - ffi.Pointer type, +typedef _c_clang_getTypedefDeclUnderlyingType = CXType Function( + CXCursor C, ); -typedef _dart_clang_getTypeSpelling_wrap = ffi.Pointer Function( - ffi.Pointer type, +typedef _dart_clang_getTypedefDeclUnderlyingType = CXType Function( + CXCursor C, ); -typedef _c_clang_getTypeKindSpelling_wrap = ffi.Pointer Function( - ffi.Int32 typeKind, +typedef _c_clang_getEnumConstantDeclValue = ffi.Int64 Function( + CXCursor C, ); -typedef _dart_clang_getTypeKindSpelling_wrap = ffi.Pointer Function( - int typeKind, +typedef _dart_clang_getEnumConstantDeclValue = int Function( + CXCursor C, ); -typedef _c_clang_getResultType_wrap = ffi.Pointer Function( - ffi.Pointer functionType, +typedef _c_clang_getFieldDeclBitWidth = ffi.Int32 Function( + CXCursor C, ); -typedef _dart_clang_getResultType_wrap = ffi.Pointer Function( - ffi.Pointer functionType, +typedef _dart_clang_getFieldDeclBitWidth = int Function( + CXCursor C, ); -typedef _c_clang_getPointeeType_wrap = ffi.Pointer Function( - ffi.Pointer pointerType, +typedef _c_clang_Cursor_getNumArguments = ffi.Int32 Function( + CXCursor C, ); -typedef _dart_clang_getPointeeType_wrap = ffi.Pointer Function( - ffi.Pointer pointerType, +typedef _dart_clang_Cursor_getNumArguments = int Function( + CXCursor C, ); -typedef _c_clang_getCanonicalType_wrap = ffi.Pointer Function( - ffi.Pointer typerefType, +typedef _c_clang_Cursor_getArgument = CXCursor Function( + CXCursor C, + ffi.Uint32 i, ); -typedef _dart_clang_getCanonicalType_wrap = ffi.Pointer Function( - ffi.Pointer typerefType, +typedef _dart_clang_Cursor_getArgument = CXCursor Function( + CXCursor C, + int i, ); -typedef _c_clang_Type_getNamedType_wrap = ffi.Pointer Function( - ffi.Pointer elaboratedType, +typedef _c_clang_getCanonicalType = CXType Function( + CXType T, ); -typedef _dart_clang_Type_getNamedType_wrap = ffi.Pointer Function( - ffi.Pointer elaboratedType, +typedef _dart_clang_getCanonicalType = CXType Function( + CXType T, ); -typedef _c_clang_getTypeDeclaration_wrap = ffi.Pointer Function( - ffi.Pointer cxtype, +typedef _c_clang_Cursor_isMacroFunctionLike = ffi.Uint32 Function( + CXCursor C, ); -typedef _dart_clang_getTypeDeclaration_wrap = ffi.Pointer Function( - ffi.Pointer cxtype, +typedef _dart_clang_Cursor_isMacroFunctionLike = int Function( + CXCursor C, ); -typedef _c_clang_getTypedefDeclUnderlyingType_wrap = ffi.Pointer - Function( - ffi.Pointer cxcursor, +typedef _c_clang_Cursor_isMacroBuiltin = ffi.Uint32 Function( + CXCursor C, ); -typedef _dart_clang_getTypedefDeclUnderlyingType_wrap = ffi.Pointer - Function( - ffi.Pointer cxcursor, +typedef _dart_clang_Cursor_isMacroBuiltin = int Function( + CXCursor C, ); -typedef _c_clang_getCursorSpelling_wrap = ffi.Pointer Function( - ffi.Pointer cursor, +typedef _c_clang_getPointeeType = CXType Function( + CXType T, ); -typedef _dart_clang_getCursorSpelling_wrap = ffi.Pointer Function( - ffi.Pointer cursor, +typedef _dart_clang_getPointeeType = CXType Function( + CXType T, ); -typedef _c_clang_getTranslationUnitCursor_wrap = ffi.Pointer Function( - ffi.Pointer tu, +typedef _c_clang_getTypeDeclaration = CXCursor Function( + CXType T, ); -typedef _dart_clang_getTranslationUnitCursor_wrap = ffi.Pointer - Function( - ffi.Pointer tu, +typedef _dart_clang_getTypeDeclaration = CXCursor Function( + CXType T, ); -typedef _c_clang_formatDiagnostic_wrap = ffi.Pointer Function( - ffi.Pointer diag, - ffi.Int32 opts, +typedef _c_clang_getTypeKindSpelling = CXString Function( + ffi.Int32 K, ); -typedef _dart_clang_formatDiagnostic_wrap = ffi.Pointer Function( - ffi.Pointer diag, - int opts, +typedef _dart_clang_getTypeKindSpelling = CXString Function( + int K, ); -typedef ModifiedCXCursorVisitor = ffi.Int32 Function( - ffi.Pointer, - ffi.Pointer, - ffi.Pointer, +typedef _c_clang_getResultType = CXType Function( + CXType T, ); -typedef _c_clang_visitChildren_wrap = ffi.Uint32 Function( - ffi.Pointer parent, - ffi.Pointer> _modifiedVisitor, - ffi.Int64 uid, +typedef _dart_clang_getResultType = CXType Function( + CXType T, ); -typedef _dart_clang_visitChildren_wrap = int Function( - ffi.Pointer parent, - ffi.Pointer> _modifiedVisitor, - int uid, +typedef _c_clang_getNumArgTypes = ffi.Int32 Function( + CXType T, ); -typedef _c_clang_Cursor_getNumArguments_wrap = ffi.Int32 Function( - ffi.Pointer cursor, +typedef _dart_clang_getNumArgTypes = int Function( + CXType T, ); -typedef _dart_clang_Cursor_getNumArguments_wrap = int Function( - ffi.Pointer cursor, -); - -typedef _c_clang_Cursor_getArgument_wrap = ffi.Pointer Function( - ffi.Pointer cursor, +typedef _c_clang_getArgType = CXType Function( + CXType T, ffi.Uint32 i, ); -typedef _dart_clang_Cursor_getArgument_wrap = ffi.Pointer Function( - ffi.Pointer cursor, +typedef _dart_clang_getArgType = CXType Function( + CXType T, int i, ); -typedef _c_clang_getNumArgTypes_wrap = ffi.Int32 Function( - ffi.Pointer cxtype, +typedef _c_clang_getNumElements = ffi.Int64 Function( + CXType T, ); -typedef _dart_clang_getNumArgTypes_wrap = int Function( - ffi.Pointer cxtype, +typedef _dart_clang_getNumElements = int Function( + CXType T, ); -typedef _c_clang_getArgType_wrap = ffi.Pointer Function( - ffi.Pointer cxtype, - ffi.Uint32 i, +typedef _c_clang_getArrayElementType = CXType Function( + CXType T, ); -typedef _dart_clang_getArgType_wrap = ffi.Pointer Function( - ffi.Pointer cxtype, - int i, +typedef _dart_clang_getArrayElementType = CXType Function( + CXType T, ); -typedef _c_clang_getEnumConstantDeclValue_wrap = ffi.Int64 Function( - ffi.Pointer cursor, +typedef _c_clang_Type_getNamedType = CXType Function( + CXType T, ); -typedef _dart_clang_getEnumConstantDeclValue_wrap = int Function( - ffi.Pointer cursor, +typedef _dart_clang_Type_getNamedType = CXType Function( + CXType T, ); -typedef _c_clang_equalRanges_wrap = ffi.Uint32 Function( - ffi.Pointer c1, - ffi.Pointer c2, +typedef _c_clang_Cursor_isAnonymous = ffi.Uint32 Function( + CXCursor C, ); -typedef _dart_clang_equalRanges_wrap = int Function( - ffi.Pointer c1, - ffi.Pointer c2, +typedef _dart_clang_Cursor_isAnonymous = int Function( + CXCursor C, ); -typedef _c_clang_Cursor_getCommentRange_wrap = ffi.Pointer - Function( - ffi.Pointer cursor, +typedef _c_clang_Cursor_isAnonymousRecordDecl = ffi.Uint32 Function( + CXCursor C, ); -typedef _dart_clang_Cursor_getCommentRange_wrap = ffi.Pointer - Function( - ffi.Pointer cursor, +typedef _dart_clang_Cursor_isAnonymousRecordDecl = int Function( + CXCursor C, ); -typedef _c_clang_Cursor_getRawCommentText_wrap = ffi.Pointer Function( - ffi.Pointer cursor, +typedef CXCursorVisitor = ffi.Int32 Function( + CXCursor, + CXCursor, + ffi.Pointer, ); -typedef _dart_clang_Cursor_getRawCommentText_wrap = ffi.Pointer - Function( - ffi.Pointer cursor, +typedef _c_clang_visitChildren = ffi.Uint32 Function( + CXCursor parent, + ffi.Pointer> visitor, + ffi.Pointer client_data, ); -typedef _c_clang_Cursor_getBriefCommentText_wrap = ffi.Pointer - Function( - ffi.Pointer cursor, +typedef _dart_clang_visitChildren = int Function( + CXCursor parent, + ffi.Pointer> visitor, + ffi.Pointer client_data, ); -typedef _dart_clang_Cursor_getBriefCommentText_wrap = ffi.Pointer - Function( - ffi.Pointer cursor, +typedef _c_clang_getCursorUSR = CXString Function( + CXCursor arg0, ); -typedef _c_clang_getCursorLocation_wrap = ffi.Pointer - Function( - ffi.Pointer cursor, +typedef _dart_clang_getCursorUSR = CXString Function( + CXCursor arg0, ); -typedef _dart_clang_getCursorLocation_wrap = ffi.Pointer - Function( - ffi.Pointer cursor, +typedef _c_clang_getCursorSpelling = CXString Function( + CXCursor arg0, ); -typedef _c_clang_getFileLocation_wrap = ffi.Void Function( - ffi.Pointer location, - ffi.Pointer> file, - ffi.Pointer line, - ffi.Pointer column, - ffi.Pointer offset, +typedef _dart_clang_getCursorSpelling = CXString Function( + CXCursor arg0, ); -typedef _dart_clang_getFileLocation_wrap = void Function( - ffi.Pointer location, - ffi.Pointer> file, - ffi.Pointer line, - ffi.Pointer column, - ffi.Pointer offset, +typedef _c_clang_Cursor_getCommentRange = CXSourceRange Function( + CXCursor C, ); -typedef _c_clang_getFileName_wrap = ffi.Pointer Function( - ffi.Pointer SFile, +typedef _dart_clang_Cursor_getCommentRange = CXSourceRange Function( + CXCursor C, ); -typedef _dart_clang_getFileName_wrap = ffi.Pointer Function( - ffi.Pointer SFile, +typedef _c_clang_Cursor_getRawCommentText = CXString Function( + CXCursor C, +); + +typedef _dart_clang_Cursor_getRawCommentText = CXString Function( + CXCursor C, ); -typedef _c_clang_getNumElements_wrap = ffi.Uint64 Function( - ffi.Pointer cxtype, +typedef _c_clang_Cursor_getBriefCommentText = CXString Function( + CXCursor C, ); -typedef _dart_clang_getNumElements_wrap = int Function( - ffi.Pointer cxtype, +typedef _dart_clang_Cursor_getBriefCommentText = CXString Function( + CXCursor C, ); -typedef _c_clang_getArrayElementType_wrap = ffi.Pointer Function( - ffi.Pointer cxtype, +typedef _c_clang_getCursorKindSpelling = CXString Function( + ffi.Int32 Kind, ); -typedef _dart_clang_getArrayElementType_wrap = ffi.Pointer Function( - ffi.Pointer cxtype, +typedef _dart_clang_getCursorKindSpelling = CXString Function( + int Kind, ); -typedef _c_clang_Cursor_isMacroFunctionLike_wrap = ffi.Uint32 Function( - ffi.Pointer cursor, +typedef _c_clang_Cursor_Evaluate = ffi.Pointer Function( + CXCursor C, ); -typedef _dart_clang_Cursor_isMacroFunctionLike_wrap = int Function( - ffi.Pointer cursor, +typedef _dart_clang_Cursor_Evaluate = ffi.Pointer Function( + CXCursor C, ); -typedef _c_clang_Cursor_isMacroBuiltin_wrap = ffi.Uint32 Function( - ffi.Pointer cursor, +typedef _c_clang_EvalResult_getKind = ffi.Int32 Function( + ffi.Pointer E, ); -typedef _dart_clang_Cursor_isMacroBuiltin_wrap = int Function( - ffi.Pointer cursor, +typedef _dart_clang_EvalResult_getKind = int Function( + ffi.Pointer E, ); -typedef _c_clang_Cursor_Evaluate_wrap = ffi.Pointer Function( - ffi.Pointer cursor, +typedef _c_clang_EvalResult_getAsInt = ffi.Int32 Function( + ffi.Pointer E, ); -typedef _dart_clang_Cursor_Evaluate_wrap = ffi.Pointer Function( - ffi.Pointer cursor, +typedef _dart_clang_EvalResult_getAsInt = int Function( + ffi.Pointer E, ); -typedef _c_clang_Cursor_isAnonymous_wrap = ffi.Uint32 Function( - ffi.Pointer cursor, +typedef _c_clang_EvalResult_getAsLongLong = ffi.Int64 Function( + ffi.Pointer E, ); -typedef _dart_clang_Cursor_isAnonymous_wrap = int Function( - ffi.Pointer cursor, +typedef _dart_clang_EvalResult_getAsLongLong = int Function( + ffi.Pointer E, ); -typedef _c_clang_Cursor_isAnonymousRecordDecl_wrap = ffi.Uint32 Function( - ffi.Pointer cursor, +typedef _c_clang_EvalResult_getAsDouble = ffi.Double Function( + ffi.Pointer E, ); -typedef _dart_clang_Cursor_isAnonymousRecordDecl_wrap = int Function( - ffi.Pointer cursor, +typedef _dart_clang_EvalResult_getAsDouble = double Function( + ffi.Pointer E, ); -typedef _c_clang_getCursorUSR_wrap = ffi.Pointer Function( - ffi.Pointer cursor, +typedef _c_clang_EvalResult_getAsStr = ffi.Pointer Function( + ffi.Pointer E, ); -typedef _dart_clang_getCursorUSR_wrap = ffi.Pointer Function( - ffi.Pointer cursor, +typedef _dart_clang_EvalResult_getAsStr = ffi.Pointer Function( + ffi.Pointer E, ); -typedef _c_clang_getFieldDeclBitWidth_wrap = ffi.Int32 Function( - ffi.Pointer cursor, +typedef _c_clang_EvalResult_dispose = ffi.Void Function( + ffi.Pointer E, ); -typedef _dart_clang_getFieldDeclBitWidth_wrap = int Function( - ffi.Pointer cursor, +typedef _dart_clang_EvalResult_dispose = void Function( + ffi.Pointer E, ); diff --git a/lib/src/header_parser/data.dart b/lib/src/header_parser/data.dart index 462f069f..c2b371e4 100644 --- a/lib/src/header_parser/data.dart +++ b/lib/src/header_parser/data.dart @@ -29,12 +29,6 @@ BindingsIndex _bindingsIndex = BindingsIndex(); IncrementalNamer get incrementalNamer => _incrementalNamer; IncrementalNamer _incrementalNamer = IncrementalNamer(); -/// Holds the unique id refering to this isolate. -/// -/// Used by visitChildren_wrap to call the correct dart function from C. -// int get uid => Isolate.current.controlPort.; -final uid = Isolate.current.controlPort.nativePort; - /// Saved macros, Key: prefixedName, Value originalName. Map get savedMacros => _savedMacros; Map _savedMacros = {}; @@ -43,9 +37,9 @@ Map _savedMacros = {}; List get unnamedEnumConstants => _unnamedEnumConstants; List _unnamedEnumConstants = []; -void initializeGlobals({required Config config, required Clang clang}) { +void initializeGlobals({required Config config}) { _config = config; - _clang = clang; + _clang = Clang(DynamicLibrary.open(config.libclangDylib)); _incrementalNamer = IncrementalNamer(); _savedMacros = {}; _unnamedEnumConstants = []; diff --git a/lib/src/header_parser/parser.dart b/lib/src/header_parser/parser.dart index 7ce92fe3..2ce1cb98 100644 --- a/lib/src/header_parser/parser.dart +++ b/lib/src/header_parser/parser.dart @@ -9,11 +9,9 @@ import 'package:ffigen/src/code_generator.dart'; import 'package:ffigen/src/config_provider.dart'; import 'package:ffigen/src/header_parser/sub_parsers/macro_parser.dart'; import 'package:ffigen/src/config_provider/config_types.dart'; -import 'package:ffigen/src/find_resource.dart'; import 'package:ffigen/src/header_parser/translation_unit_parser.dart'; import 'package:ffigen/src/strings.dart' as strings; import 'package:logging/logging.dart'; -import 'package:path/path.dart' as path; import 'clang_bindings/clang_bindings.dart' as clang_types; import 'data.dart'; @@ -47,23 +45,10 @@ final _logger = Logger('ffigen.header_parser.parser'); /// Initializes parser, clears any previous values. void initParser(Config c) { - // Find full path of dynamic library and initialize bindings. - final ddt = findDotDartTool(); - if (ddt == null) { - throw Exception('Unable to find .dart_tool.'); - } else { - final fullDylibPath = path.join( - ddt.toFilePath(), - strings.ffigenFolderName, - strings.dylibFileName, - ); - - // Initialize global variables. - initializeGlobals( - config: c, - clang: clang_types.Clang(DynamicLibrary.open(fullDylibPath)), - ); - } + // Initialize global variables. + initializeGlobals( + config: c, + ); } /// Parses source files and adds generated bindings to [bindings]. @@ -111,12 +96,11 @@ List parseToBindings() { } logTuDiagnostics(tu, _logger, headerLocation); - final rootCursor = clang.clang_getTranslationUnitCursor_wrap(tu); + final rootCursor = clang.clang_getTranslationUnitCursor(tu); - bindings.addAll(parseTranslationUnit(rootCursor)!); + bindings.addAll(parseTranslationUnit(rootCursor)); // Cleanup. - rootCursor.dispose(); clang.clang_disposeTranslationUnit(tu); } diff --git a/lib/src/header_parser/sub_parsers/enumdecl_parser.dart b/lib/src/header_parser/sub_parsers/enumdecl_parser.dart index 1097372c..7da0ab43 100644 --- a/lib/src/header_parser/sub_parsers/enumdecl_parser.dart +++ b/lib/src/header_parser/sub_parsers/enumdecl_parser.dart @@ -26,7 +26,7 @@ final _stack = Stack<_ParsedEnum>(); /// Parses a function declaration. EnumClass? parseEnumDeclaration( - Pointer cursor, { + clang_types.CXCursor cursor, { /// Optionally provide name to use (useful in case enum is inside a typedef). String? name, @@ -36,7 +36,7 @@ EnumClass? parseEnumDeclaration( final enumName = name ?? cursor.spelling(); if (enumName == '') { // Save this unnamed enum if it is anonymous (therefore not in a typedef). - if (clang.clang_Cursor_isAnonymous_wrap(cursor) != 0) { + if (clang.clang_Cursor_isAnonymous(cursor) != 0) { _logger.fine('Saving anonymous enum.'); saveUnNamedEnum(cursor); } else { @@ -64,12 +64,12 @@ EnumClass? parseEnumDeclaration( return _stack.pop().enumClass; } -void _addEnumConstant(Pointer cursor) { - final resultCode = clang.clang_visitChildren_wrap( +void _addEnumConstant(clang_types.CXCursor cursor) { + final resultCode = clang.clang_visitChildren( cursor, Pointer.fromFunction( _enumCursorVisitor, clang_types.CXChildVisitResult.CXChildVisit_Break), - uid, + nullptr, ); visitChildrenResultChecker(resultCode); @@ -79,19 +79,17 @@ void _addEnumConstant(Pointer cursor) { /// /// Invoked on every enum directly under rootCursor. /// Used for for extracting enum values. -int _enumCursorVisitor(Pointer cursor, - Pointer parent, Pointer clientData) { +int _enumCursorVisitor(clang_types.CXCursor cursor, clang_types.CXCursor parent, + Pointer clientData) { try { _logger.finest(' enumCursorVisitor: ${cursor.completeStringRepr()}'); - switch (clang.clang_getCursorKind_wrap(cursor)) { + switch (clang.clang_getCursorKind(cursor)) { case clang_types.CXCursorKind.CXCursor_EnumConstantDecl: _addEnumConstantToEnumClass(cursor); break; default: _logger.fine('invalid enum constant'); } - cursor.dispose(); - parent.dispose(); } catch (e, s) { _logger.severe(e); _logger.severe(s); @@ -101,7 +99,7 @@ int _enumCursorVisitor(Pointer cursor, } /// Adds the parameter to func in [functiondecl_parser.dart]. -void _addEnumConstantToEnumClass(Pointer cursor) { +void _addEnumConstantToEnumClass(clang_types.CXCursor cursor) { _stack.top.enumClass!.enumConstants.add( EnumConstant( dartDoc: getCursorDocComment( @@ -113,6 +111,6 @@ void _addEnumConstantToEnumClass(Pointer cursor) { _stack.top.enumClass!.originalName, cursor.spelling(), ), - value: clang.clang_getEnumConstantDeclValue_wrap(cursor)), + value: clang.clang_getEnumConstantDeclValue(cursor)), ); } diff --git a/lib/src/header_parser/sub_parsers/functiondecl_parser.dart b/lib/src/header_parser/sub_parsers/functiondecl_parser.dart index acb223a3..7bf089ab 100644 --- a/lib/src/header_parser/sub_parsers/functiondecl_parser.dart +++ b/lib/src/header_parser/sub_parsers/functiondecl_parser.dart @@ -2,8 +2,6 @@ // 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 'dart:ffi'; - import 'package:ffigen/src/code_generator.dart'; import 'package:ffigen/src/header_parser/data.dart'; import 'package:logging/logging.dart'; @@ -26,7 +24,7 @@ class _ParserFunc { final _stack = Stack<_ParserFunc>(); /// Parses a function declaration. -Func? parseFunctionDeclaration(Pointer cursor) { +Func? parseFunctionDeclaration(clang_types.CXCursor cursor) { _stack.push(_ParserFunc()); final funcUsr = cursor.usr(); @@ -77,17 +75,16 @@ Func? parseFunctionDeclaration(Pointer cursor) { return _stack.pop().func; } -Type _getFunctionReturnType(Pointer cursor) { - return cursor.returnType().toCodeGenTypeAndDispose(); +Type _getFunctionReturnType(clang_types.CXCursor cursor) { + return cursor.returnType().toCodeGenType(); } -List _getParameters( - Pointer cursor, String funcName) { +List _getParameters(clang_types.CXCursor cursor, String funcName) { final parameters = []; - final totalArgs = clang.clang_Cursor_getNumArguments_wrap(cursor); + final totalArgs = clang.clang_Cursor_getNumArguments(cursor); for (var i = 0; i < totalArgs; i++) { - final paramCursor = clang.clang_Cursor_getArgument_wrap(cursor, i); + final paramCursor = clang.clang_Cursor_getArgument(cursor, i); _logger.finer('===== parameter: ${paramCursor.completeStringRepr()}'); @@ -110,12 +107,11 @@ List _getParameters( type: pt, ), ); - paramCursor.dispose(); } return parameters; } -Type _getParameterType(Pointer cursor) { - return cursor.type().toCodeGenTypeAndDispose(); +Type _getParameterType(clang_types.CXCursor cursor) { + return cursor.type().toCodeGenType(); } diff --git a/lib/src/header_parser/sub_parsers/macro_parser.dart b/lib/src/header_parser/sub_parsers/macro_parser.dart index 02618386..4f18ce6a 100644 --- a/lib/src/header_parser/sub_parsers/macro_parser.dart +++ b/lib/src/header_parser/sub_parsers/macro_parser.dart @@ -21,11 +21,11 @@ import '../utils.dart'; final _logger = Logger('ffigen.header_parser.macro_parser'); /// Adds a macro definition to be parsed later. -void saveMacroDefinition(Pointer cursor) { +void saveMacroDefinition(clang_types.CXCursor cursor) { final macroUsr = cursor.usr(); final originalMacroName = cursor.spelling(); - if (clang.clang_Cursor_isMacroBuiltin_wrap(cursor) == 0 && - clang.clang_Cursor_isMacroFunctionLike_wrap(cursor) == 0 && + if (clang.clang_Cursor_isMacroBuiltin(cursor) == 0 && + clang.clang_Cursor_isMacroFunctionLike(cursor) == 0 && shouldIncludeMacro(macroUsr, originalMacroName)) { // Parse macro only if it's not builtin or function-like. _logger.fine( @@ -76,17 +76,16 @@ List? parseSavedMacros() { if (tu == nullptr) { _logger.severe('Unable to parse Macros.'); } else { - final rootCursor = clang.clang_getTranslationUnitCursor_wrap(tu); + final rootCursor = clang.clang_getTranslationUnitCursor(tu); - final resultCode = clang.clang_visitChildren_wrap( + final resultCode = clang.clang_visitChildren( rootCursor, Pointer.fromFunction(_macroVariablevisitor, clang_types.CXChildVisitResult.CXChildVisit_Break), - uid, + nullptr, ); visitChildrenResultChecker(resultCode); - rootCursor.dispose(); } clang.clang_disposeTranslationUnit(tu); @@ -98,14 +97,14 @@ List? parseSavedMacros() { } /// Child visitor invoked on translationUnitCursor for parsing macroVariables. -int _macroVariablevisitor(Pointer cursor, - Pointer parent, Pointer clientData) { +int _macroVariablevisitor(clang_types.CXCursor cursor, + clang_types.CXCursor parent, Pointer clientData) { Constant? constant; try { if (isFromGeneratedFile(cursor) && _macroVarNames.contains(cursor.spelling()) && - cursor.kind() == clang_types.CXCursorKind.CXCursor_VarDecl) { - final e = clang.clang_Cursor_Evaluate_wrap(cursor); + cursor.kind == clang_types.CXCursorKind.CXCursor_VarDecl) { + final e = clang.clang_Cursor_Evaluate(cursor); final k = clang.clang_EvalResult_getKind(e); _logger.fine('macroVariablevisitor: ${cursor.completeStringRepr()}'); @@ -151,8 +150,6 @@ int _macroVariablevisitor(Pointer cursor, _bindings!.add(constant); } } - cursor.dispose(); - parent.dispose(); } catch (e, s) { _logger.severe(e); _logger.severe(s); @@ -162,7 +159,7 @@ int _macroVariablevisitor(Pointer cursor, } /// Returns true if cursor is from generated file. -bool isFromGeneratedFile(Pointer cursor) { +bool isFromGeneratedFile(clang_types.CXCursor cursor) { final s = cursor.sourceFileName(); return p.basename(s) == _generatedFileBaseName; } diff --git a/lib/src/header_parser/sub_parsers/structdecl_parser.dart b/lib/src/header_parser/sub_parsers/structdecl_parser.dart index ffa4109d..dffd5028 100644 --- a/lib/src/header_parser/sub_parsers/structdecl_parser.dart +++ b/lib/src/header_parser/sub_parsers/structdecl_parser.dart @@ -5,7 +5,6 @@ import 'dart:ffi'; import 'package:ffigen/src/code_generator.dart'; -import 'package:ffigen/src/strings.dart'; import 'package:logging/logging.dart'; import '../clang_bindings/clang_bindings.dart' as clang_types; @@ -40,7 +39,7 @@ final _stack = Stack<_ParsedStruc>(); /// Parses a struct declaration. Struc? parseStructDeclaration( - Pointer cursor, { + clang_types.CXCursor cursor, { /// Optionally provide name (useful in case struct is inside a typedef). String? name, @@ -81,15 +80,15 @@ Struc? parseStructDeclaration( return _stack.pop().struc; } -void _setStructMembers(Pointer cursor) { +void _setStructMembers(clang_types.CXCursor cursor) { _stack.top.arrayMember = false; _stack.top.unimplementedMemberType = false; - final resultCode = clang.clang_visitChildren_wrap( + final resultCode = clang.clang_visitChildren( cursor, Pointer.fromFunction(_structMembersVisitor, clang_types.CXChildVisitResult.CXChildVisit_Break), - uid, + nullptr, ); visitChildrenResultChecker(resultCode); @@ -137,19 +136,19 @@ void _setStructMembers(Pointer cursor) { /// Visitor for the struct cursor [CXCursorKind.CXCursor_StructDecl]. /// /// Child visitor invoked on struct cursor. -int _structMembersVisitor(Pointer cursor, - Pointer parent, Pointer clientData) { +int _structMembersVisitor(clang_types.CXCursor cursor, + clang_types.CXCursor parent, Pointer clientData) { try { - if (cursor.kind() == clang_types.CXCursorKind.CXCursor_FieldDecl) { + if (cursor.kind == clang_types.CXCursorKind.CXCursor_FieldDecl) { _logger.finer('===== member: ${cursor.completeStringRepr()}'); - final mt = cursor.type().toCodeGenTypeAndDispose(); + final mt = cursor.type().toCodeGenType(); if (mt.broadType == BroadType.ConstantArray) { _stack.top.arrayMember = true; } else if (mt.broadType == BroadType.IncompleteArray) { // TODO(68): Structs with flexible Array Members are not supported. _stack.top.flexibleArrayMember = true; - } else if (clang.clang_getFieldDeclBitWidth_wrap(cursor) != -1) { + } else if (clang.clang_getFieldDeclBitWidth(cursor) != -1) { // TODO(84): Struct with bitfields are not suppoorted. _stack.top.bitFieldMember = true; } else if (mt.broadType == BroadType.Handle) { @@ -177,8 +176,6 @@ int _structMembersVisitor(Pointer cursor, ), ); } - cursor.dispose(); - parent.dispose(); } catch (e, s) { _logger.severe(e); _logger.severe(s); diff --git a/lib/src/header_parser/sub_parsers/typedefdecl_parser.dart b/lib/src/header_parser/sub_parsers/typedefdecl_parser.dart index de39f207..57ab11c1 100644 --- a/lib/src/header_parser/sub_parsers/typedefdecl_parser.dart +++ b/lib/src/header_parser/sub_parsers/typedefdecl_parser.dart @@ -26,15 +26,15 @@ class _ParsedTypedef { final _stack = Stack<_ParsedTypedef>(); /// Parses a typedef declaration. -Binding? parseTypedefDeclaration(Pointer cursor) { +Binding? parseTypedefDeclaration(clang_types.CXCursor cursor) { _stack.push(_ParsedTypedef()); // Name of typedef. _stack.top.typedefName = cursor.spelling(); - final resultCode = clang.clang_visitChildren_wrap( + final resultCode = clang.clang_visitChildren( cursor, Pointer.fromFunction(_typedefdeclarationCursorVisitor, clang_types.CXChildVisitResult.CXChildVisit_Break), - uid, + nullptr, ); visitChildrenResultChecker(resultCode); @@ -46,13 +46,13 @@ Binding? parseTypedefDeclaration(Pointer cursor) { /// /// Visitor invoked on cursor of type declaration returned by /// [clang.clang_getTypeDeclaration_wrap]. -int _typedefdeclarationCursorVisitor(Pointer cursor, - Pointer parent, Pointer clientData) { +int _typedefdeclarationCursorVisitor(clang_types.CXCursor cursor, + clang_types.CXCursor parent, Pointer clientData) { try { _logger.finest( 'typedefdeclarationCursorVisitor: ${cursor.completeStringRepr()}'); - switch (clang.clang_getCursorKind_wrap(cursor)) { + switch (clang.clang_getCursorKind(cursor)) { case clang_types.CXCursorKind.CXCursor_StructDecl: _stack.top.binding = parseStructDeclaration(cursor, name: _stack.top.typedefName); @@ -64,9 +64,6 @@ int _typedefdeclarationCursorVisitor(Pointer cursor, default: _logger.finest('typedefdeclarationCursorVisitor: Ignored'); } - - cursor.dispose(); - parent.dispose(); } catch (e, s) { _logger.severe(e); _logger.severe(s); diff --git a/lib/src/header_parser/sub_parsers/unnamed_enumdecl_parser.dart b/lib/src/header_parser/sub_parsers/unnamed_enumdecl_parser.dart index 4c1e244d..584694d8 100644 --- a/lib/src/header_parser/sub_parsers/unnamed_enumdecl_parser.dart +++ b/lib/src/header_parser/sub_parsers/unnamed_enumdecl_parser.dart @@ -16,12 +16,12 @@ import '../utils.dart'; final _logger = Logger('ffigen.header_parser.unnamed_enumdecl_parser'); /// Saves unnamed enums. -void saveUnNamedEnum(Pointer cursor) { - final resultCode = clang.clang_visitChildren_wrap( +void saveUnNamedEnum(clang_types.CXCursor cursor) { + final resultCode = clang.clang_visitChildren( cursor, Pointer.fromFunction(_unnamedenumCursorVisitor, clang_types.CXChildVisitResult.CXChildVisit_Break), - uid, + nullptr, ); visitChildrenResultChecker(resultCode); @@ -31,12 +31,12 @@ void saveUnNamedEnum(Pointer cursor) { /// /// Invoked on every enum directly under rootCursor. /// Used for for extracting enum values. -int _unnamedenumCursorVisitor(Pointer cursor, - Pointer parent, Pointer clientData) { +int _unnamedenumCursorVisitor(clang_types.CXCursor cursor, + clang_types.CXCursor parent, Pointer clientData) { try { _logger .finest(' unnamedenumCursorVisitor: ${cursor.completeStringRepr()}'); - switch (clang.clang_getCursorKind_wrap(cursor)) { + switch (clang.clang_getCursorKind(cursor)) { case clang_types.CXCursorKind.CXCursor_EnumConstantDecl: if (shouldIncludeUnnamedEnumConstant(cursor.usr(), cursor.spelling())) { _addUnNamedEnumConstant(cursor); @@ -45,8 +45,6 @@ int _unnamedenumCursorVisitor(Pointer cursor, default: _logger.severe('Invalid enum constant.'); } - cursor.dispose(); - parent.dispose(); } catch (e, s) { _logger.severe(e); _logger.severe(s); @@ -56,7 +54,7 @@ int _unnamedenumCursorVisitor(Pointer cursor, } /// Adds the parameter to func in [functiondecl_parser.dart]. -void _addUnNamedEnumConstant(Pointer cursor) { +void _addUnNamedEnumConstant(clang_types.CXCursor cursor) { unnamedEnumConstants.add( Constant( usr: cursor.usr(), @@ -65,7 +63,7 @@ void _addUnNamedEnumConstant(Pointer cursor) { cursor.spelling(), ), rawType: 'int', - rawValue: clang.clang_getEnumConstantDeclValue_wrap(cursor).toString(), + rawValue: clang.clang_getEnumConstantDeclValue(cursor).toString(), ), ); } diff --git a/lib/src/header_parser/translation_unit_parser.dart b/lib/src/header_parser/translation_unit_parser.dart index c4ad7e9e..7c08410c 100644 --- a/lib/src/header_parser/translation_unit_parser.dart +++ b/lib/src/header_parser/translation_unit_parser.dart @@ -19,17 +19,16 @@ import 'utils.dart'; final _logger = Logger('ffigen.header_parser.translation_unit_parser'); -Set? _bindings; +late Set _bindings; /// Parses the translation unit and returns the generated bindings. -Set? parseTranslationUnit( - Pointer translationUnitCursor) { +Set parseTranslationUnit(clang_types.CXCursor translationUnitCursor) { _bindings = {}; - final resultCode = clang.clang_visitChildren_wrap( + final resultCode = clang.clang_visitChildren( translationUnitCursor, Pointer.fromFunction( _rootCursorVisitor, clang_types.CXChildVisitResult.CXChildVisit_Break), - uid, + nullptr, ); visitChildrenResultChecker(resultCode); @@ -38,12 +37,12 @@ Set? parseTranslationUnit( } /// Child visitor invoked on translationUnitCursor [CXCursorKind.CXCursor_TranslationUnit]. -int _rootCursorVisitor(Pointer cursor, - Pointer parent, Pointer clientData) { +int _rootCursorVisitor(clang_types.CXCursor cursor, clang_types.CXCursor parent, + Pointer clientData) { try { if (shouldIncludeRootCursor(cursor.sourceFileName())) { _logger.finest('rootCursorVisitor: ${cursor.completeStringRepr()}'); - switch (clang.clang_getCursorKind_wrap(cursor)) { + switch (clang.clang_getCursorKind(cursor)) { case clang_types.CXCursorKind.CXCursor_FunctionDecl: addToBindings(parseFunctionDeclaration(cursor)); break; @@ -66,9 +65,6 @@ int _rootCursorVisitor(Pointer cursor, _logger.finest( 'rootCursorVisitor:(not included) ${cursor.completeStringRepr()}'); } - - cursor.dispose(); - parent.dispose(); } catch (e, s) { _logger.severe(e); _logger.severe(s); @@ -81,6 +77,6 @@ int _rootCursorVisitor(Pointer cursor, void addToBindings(Binding? b) { if (b != null) { // This is a set, and hence will not have duplicates. - _bindings!.add(b); + _bindings.add(b); } } diff --git a/lib/src/header_parser/type_extractor/extractor.dart b/lib/src/header_parser/type_extractor/extractor.dart index d1a7883b..e216d02a 100644 --- a/lib/src/header_parser/type_extractor/extractor.dart +++ b/lib/src/header_parser/type_extractor/extractor.dart @@ -3,8 +3,6 @@ // BSD-style license that can be found in the LICENSE file. /// Extracts code_gen Type from type. -import 'dart:ffi'; - import 'package:ffigen/src/code_generator.dart'; import 'package:ffigen/src/strings.dart' as strings; import 'package:logging/logging.dart'; @@ -20,15 +18,14 @@ final _logger = Logger('ffigen.header_parser.extractor'); const _padding = ' '; /// Converts cxtype to a typestring code_generator can accept. -Type getCodeGenType(Pointer cxtype, {String? parentName}) { +Type getCodeGenType(clang_types.CXType cxtype, {String? parentName}) { _logger.fine('${_padding}getCodeGenType ${cxtype.completeStringRepr()}'); - final kind = cxtype.kind(); + final kind = cxtype.kind; switch (kind) { case clang_types.CXTypeKind.CXType_Pointer: - final pt = clang.clang_getPointeeType_wrap(cxtype); + final pt = clang.clang_getPointeeType(cxtype); final s = getCodeGenType(pt, parentName: parentName); - pt.dispose(); // Replace Pointer<_Dart_Handle> with Handle. if (config.useDartHandle && @@ -52,16 +49,14 @@ Type getCodeGenType(Pointer cxtype, {String? parentName}) { } // This is important or we get stuck in infinite recursion. - final ct = clang.clang_getTypedefDeclUnderlyingType_wrap( - clang.clang_getTypeDeclaration_wrap(cxtype)); + final ct = clang.clang_getTypedefDeclUnderlyingType( + clang.clang_getTypeDeclaration(cxtype)); final s = getCodeGenType(ct, parentName: parentName ?? cxtype.spelling()); - ct.dispose(); return s; case clang_types.CXTypeKind.CXType_Elaborated: - final et = clang.clang_Type_getNamedType_wrap(cxtype); + final et = clang.clang_Type_getNamedType(cxtype); final s = getCodeGenType(et, parentName: parentName); - et.dispose(); return s; case clang_types.CXTypeKind.CXType_Record: return _extractfromRecord(cxtype, parentName); @@ -78,20 +73,20 @@ Type getCodeGenType(Pointer cxtype, {String? parentName}) { case clang_types.CXTypeKind .CXType_ConstantArray: // Primarily used for constant array in struct members. return Type.constantArray( - clang.clang_getNumElements_wrap(cxtype), - clang.clang_getArrayElementType_wrap(cxtype).toCodeGenTypeAndDispose(), + clang.clang_getNumElements(cxtype), + clang.clang_getArrayElementType(cxtype).toCodeGenType(), ); case clang_types.CXTypeKind .CXType_IncompleteArray: // Primarily used for incomplete array in function parameters. return Type.incompleteArray( - clang.clang_getArrayElementType_wrap(cxtype).toCodeGenTypeAndDispose(), + clang.clang_getArrayElementType(cxtype).toCodeGenType(), ); case clang_types.CXTypeKind.CXType_Bool: return Type.boolean(); default: if (cxTypeKindToSupportedNativeTypes.containsKey(kind)) { return Type.nativeType( - cxTypeKindToSupportedNativeTypes[kind!], + cxTypeKindToSupportedNativeTypes[kind], ); } else { _logger.fine( @@ -102,16 +97,14 @@ Type getCodeGenType(Pointer cxtype, {String? parentName}) { } } -Type _extractfromRecord( - Pointer cxtype, String? parentName) { +Type _extractfromRecord(clang_types.CXType cxtype, String? parentName) { Type type; - final cursor = clang.clang_getTypeDeclaration_wrap(cxtype); + final cursor = clang.clang_getTypeDeclaration(cxtype); _logger.fine('${_padding}_extractfromRecord: ${cursor.completeStringRepr()}'); - switch (clang.clang_getCursorKind_wrap(cursor)) { + switch (clang.clang_getCursorKind(cursor)) { case clang_types.CXCursorKind.CXCursor_StructDecl: - final cxtype = cursor.type(); final structUsr = cursor.usr(); // Name of typedef (parentName) is used if available. @@ -132,7 +125,6 @@ Type _extractfromRecord( } } - cxtype.dispose(); break; default: _logger.fine( @@ -140,23 +132,21 @@ Type _extractfromRecord( return Type.unimplemented( 'Type: ${cxtype.kindSpelling()} not implemented'); } - cursor.dispose(); return type; } // Used for function pointer arguments. -Type _extractFromFunctionProto( - Pointer cxtype, String? parentName) { +Type _extractFromFunctionProto(clang_types.CXType cxtype, String? parentName) { var name = parentName; // An empty name means the function prototype was declared in-place, instead // of using a typedef. name = name ?? ''; final _parameters = []; - final totalArgs = clang.clang_getNumArgTypes_wrap(cxtype); + final totalArgs = clang.clang_getNumArgTypes(cxtype); for (var i = 0; i < totalArgs; i++) { - final t = clang.clang_getArgType_wrap(cxtype, i); - final pt = t.toCodeGenTypeAndDispose(); + final t = clang.clang_getArgType(cxtype, i); + final pt = t.toCodeGenType(); if (pt.isIncompleteStruct) { return Type.unimplemented( @@ -178,8 +168,7 @@ Type _extractFromFunctionProto( name: name.isNotEmpty ? name : incrementalNamer.name('_typedefC'), typedefType: TypedefType.C, parameters: _parameters, - returnType: - clang.clang_getResultType_wrap(cxtype).toCodeGenTypeAndDispose(), + returnType: clang.clang_getResultType(cxtype).toCodeGenType(), ); // Add to seen, if name isn't empty. if (name.isNotEmpty) { diff --git a/lib/src/header_parser/utils.dart b/lib/src/header_parser/utils.dart index f24c1873..f0a41278 100644 --- a/lib/src/header_parser/utils.dart +++ b/lib/src/header_parser/utils.dart @@ -37,7 +37,7 @@ void logTuDiagnostics( logger.severe('Header $header: Total errors/warnings: $total.'); for (var i = 0; i < total; i++) { final diag = clang.clang_getDiagnostic(tu, i); - final cxstring = clang.clang_formatDiagnostic_wrap( + final cxstring = clang.clang_formatDiagnostic( diag, clang_types .CXDiagnosticDisplayOptions.CXDiagnostic_DisplaySourceLocation | @@ -56,25 +56,25 @@ extension CXSourceRangeExt on Pointer { } } -extension CXCursorExt on Pointer { +extension CXCursorExt on clang_types.CXCursor { String usr() { - return clang.clang_getCursorUSR_wrap(this).toStringAndDispose(); + return clang.clang_getCursorUSR(this).toStringAndDispose(); } /// Returns the kind int from [clang_types.CXCursorKind]. int kind() { - return clang.clang_getCursorKind_wrap(this); + return clang.clang_getCursorKind(this); } /// Name of the cursor (E.g function name, Struct name, Parameter name). String spelling() { - return clang.clang_getCursorSpelling_wrap(this).toStringAndDispose(); + return clang.clang_getCursorSpelling(this).toStringAndDispose(); } /// Spelling for a [clang_types.CXCursorKind], useful for debug purposes. String kindSpelling() { return clang - .clang_getCursorKindSpelling_wrap(clang.clang_getCursorKind_wrap(this)) + .clang_getCursorKindSpelling(clang.clang_getCursorKind(this)) .toStringAndDispose(); } @@ -82,92 +82,77 @@ extension CXCursorExt on Pointer { String completeStringRepr() { final cxtype = type(); final s = - '(Cursor) spelling: ${spelling()}, kind: ${kind()}, kindSpelling: ${kindSpelling()}, type: ${cxtype.kind()}, typeSpelling: ${cxtype.spelling()}, usr: ${usr()}'; - cxtype.dispose(); + '(Cursor) spelling: ${spelling()}, kind: ${kind()}, kindSpelling: ${kindSpelling()}, type: ${cxtype.kind}, typeSpelling: ${cxtype.spelling()}, usr: ${usr()}'; return s; } /// Dispose type using [type.dispose]. - Pointer type() { - return clang.clang_getCursorType_wrap(this); + clang_types.CXType type() { + return clang.clang_getCursorType(this); } /// Only valid for [clang.CXCursorKind.CXCursor_FunctionDecl]. /// /// Dispose type using [type.dispose]. - Pointer returnType() { - final t = type(); - final r = clang.clang_getResultType_wrap(t); - t.dispose(); - return r; + clang_types.CXType returnType() { + return clang.clang_getResultType(type()); } String sourceFileName() { - final cxsource = clang.clang_getCursorLocation_wrap(this); + final cxsource = clang.clang_getCursorLocation(this); final cxfilePtr = allocate>(); final line = allocate(); final column = allocate(); final offset = allocate(); // Puts the values in these pointers. - clang.clang_getFileLocation_wrap(cxsource, cxfilePtr, line, column, offset); - final s = - clang.clang_getFileName_wrap(cxfilePtr.value).toStringAndDispose(); - free(cxsource); + clang.clang_getFileLocation(cxsource, cxfilePtr, line, column, offset); + final s = clang.clang_getFileName(cxfilePtr.value).toStringAndDispose(); + free(cxfilePtr); free(line); free(column); free(offset); return s; } - - void dispose() { - free(this); - } } const commentPrefix = '/// '; const nesting = ' '; /// Stores the [clang_types.CXSourceRange] of the last comment. -Pointer lastCommentRange = nullptr; +clang_types.CXSourceRange? lastCommentRange; /// Returns a cursor's associated comment. /// /// The given string is wrapped at line width = 80 - [indent]. The [indent] is /// [commentPrefix.dimensions] by default because a comment starts with /// [commentPrefix]. -String? getCursorDocComment(Pointer cursor, +String? getCursorDocComment(clang_types.CXCursor cursor, [int indent = commentPrefix.length]) { String? formattedDocComment; - final currentCommentRange = clang.clang_Cursor_getCommentRange_wrap(cursor); + final currentCommentRange = clang.clang_Cursor_getCommentRange(cursor); // See if this comment and the last comment both point to the same source // range. - if (lastCommentRange != nullptr && - currentCommentRange != nullptr && - clang.clang_equalRanges_wrap(lastCommentRange, currentCommentRange) != - 0) { + if (lastCommentRange != null && + clang.clang_equalRanges(lastCommentRange!, currentCommentRange) != 0) { formattedDocComment = null; } else { switch (config.commentType.length) { case CommentLength.full: - formattedDocComment = removeRawCommentMarkups(clang - .clang_Cursor_getRawCommentText_wrap(cursor) - .toStringAndDispose()); + formattedDocComment = removeRawCommentMarkups( + clang.clang_Cursor_getRawCommentText(cursor).toStringAndDispose()); break; case CommentLength.brief: formattedDocComment = _wrapNoNewLineString( - clang - .clang_Cursor_getBriefCommentText_wrap(cursor) - .toStringAndDispose(), + clang.clang_Cursor_getBriefCommentText(cursor).toStringAndDispose(), 80 - indent); break; default: formattedDocComment = null; } } - lastCommentRange.dispose(); lastCommentRange = currentCommentRange; return formattedDocComment; } @@ -220,31 +205,24 @@ String? removeRawCommentMarkups(String? string) { return sb.toString().trim(); } -extension CXTypeExt on Pointer { +extension CXTypeExt on clang_types.CXType { /// Get code_gen [Type] representation of [clang_types.CXType]. Type toCodeGenType() { return getCodeGenType(this); } - /// Get code_gen [Type] representation of [clang_types.CXType] and dispose the type. - Type toCodeGenTypeAndDispose() { - final t = getCodeGenType(this); - dispose(); - return t; - } - /// Spelling for a [clang_types.CXTypeKind], useful for debug purposes. String spelling() { - return clang.clang_getTypeSpelling_wrap(this).toStringAndDispose(); + return clang.clang_getTypeSpelling(this).toStringAndDispose(); } /// Returns the typeKind int from [clang_types.CXTypeKind]. - int? kind() { - return ref.kind; + int kind() { + return this.kind; } String kindSpelling() { - return clang.clang_getTypeKindSpelling_wrap(kind()!).toStringAndDispose(); + return clang.clang_getTypeKindSpelling(kind()).toStringAndDispose(); } /// For debugging: returns [spelling] [kind] [kindSpelling]. @@ -253,19 +231,15 @@ extension CXTypeExt on Pointer { '(Type) spelling: ${spelling()}, kind: ${kind()}, kindSpelling: ${kindSpelling()}'; return s; } - - void dispose() { - free(this); - } } -extension CXStringExt on Pointer { +extension CXStringExt on clang_types.CXString { /// Convert CXString to a Dart string /// /// Make sure to dispose CXstring using dispose method, or use the /// [toStringAndDispose] method. String string() { - final cstring = clang.clang_getCString_wrap(this); + final cstring = clang.clang_getCString(this); if (cstring != nullptr) { return Utf8.fromUtf8(cstring.cast()); } else { @@ -277,12 +251,12 @@ extension CXStringExt on Pointer { String toStringAndDispose() { // Note: clang_getCString_wrap returns a const char *, calling free will result in error. final s = string(); - clang.clang_disposeString_wrap(this); + clang.clang_disposeString(this); return s; } void dispose() { - clang.clang_disposeString_wrap(this); + clang.clang_disposeString(this); } } diff --git a/lib/src/strings.dart b/lib/src/strings.dart index 0abc9de2..8f0ac937 100644 --- a/lib/src/strings.dart +++ b/lib/src/strings.dart @@ -4,12 +4,9 @@ import 'dart:io'; import 'package:ffigen/src/code_generator/type.dart'; -import 'package:ffigen/src/find_resource.dart'; import 'package:ffigen/src/header_parser/clang_bindings/clang_bindings.dart' as clang; -String? get dylibVersion => ffigenVersion; - /// Name of the dynamic library file according to current platform. String get dylibFileName { String name; @@ -22,10 +19,10 @@ String get dylibFileName { } else { throw Exception('Unsupported Platform.'); } - return '_${dylibVersion}_$name'; + return name; } -const ffigenFolderName = 'ffigen'; +const llvmLib = 'llvm-lib'; const output = 'output'; @@ -123,9 +120,22 @@ const description = 'description'; const preamble = 'preamble'; // Dynamic library names. -const libclang_dylib_linux = 'libwrapped_clang.so'; -const libclang_dylib_macos = 'libwrapped_clang.dylib'; -const libclang_dylib_windows = 'wrapped_clang.dll'; +const libclang_dylib_linux = 'libclang.so'; +const libclang_dylib_macos = 'libclang.dylib'; +const libclang_dylib_windows = 'libclang.dll'; + +// Dynamic library default locations. +const linuxDylibLocations = [ + '/usr/lib/llvm-9/lib/', + '/usr/lib/llvm-10/lib/', + '/usr/lib/llvm-11/lib/' +]; +const windowsDylibLocations = [ + r'C:\Program Files\LLVM\lib', +]; +const macOsDylibLocations = [ + '/usr/local/opt/llvm/lib/', +]; // Writen doubles. const doubleInfinity = 'double.infinity'; diff --git a/pubspec.yaml b/pubspec.yaml index d3c8da00..d1786689 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: 2.0.0-dev.1 +version: 2.0.0-dev.2 homepage: https://github.com/dart-lang/ffigen description: Experimental generator for FFI bindings, using LibClang to parse C header files. diff --git a/tool/libclang_config.yaml b/tool/libclang_config.yaml index 4262736a..ebba0303 100644 --- a/tool/libclang_config.yaml +++ b/tool/libclang_config.yaml @@ -16,7 +16,7 @@ sort: true compiler-opts: '-I/usr/lib/llvm-9/include/ -I/usr/lib/llvm-10/include/ -I/usr/local/opt/llvm/include/ -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/ -Wno-nullability-completeness' headers: entry-points: - - 'lib/src/clang_library/wrapper.c' + - 'third_party/libclang/include/clang-c/Index.h' include-directives: - '**wrapper.c' - '**Index.h' @@ -63,41 +63,41 @@ functions: - clang_EvalResult_getAsDouble - clang_EvalResult_getAsStr - clang_EvalResult_dispose - - clang_getCString_wrap - - clang_disposeString_wrap - - clang_getCursorKind_wrap - - clang_getCursorKindSpelling_wrap - - clang_getCursorType_wrap - - clang_getTypeSpelling_wrap - - clang_getTypeKindSpelling_wrap - - clang_getResultType_wrap - - clang_getPointeeType_wrap - - clang_getCanonicalType_wrap - - clang_Type_getNamedType_wrap - - clang_getTypeDeclaration_wrap - - clang_getTypedefDeclUnderlyingType_wrap - - clang_getCursorSpelling_wrap - - clang_getTranslationUnitCursor_wrap - - clang_formatDiagnostic_wrap - - clang_visitChildren_wrap - - clang_Cursor_getNumArguments_wrap - - clang_Cursor_getArgument_wrap - - clang_getNumArgTypes_wrap - - clang_getArgType_wrap - - clang_getEnumConstantDeclValue_wrap - - clang_equalRanges_wrap - - clang_Cursor_getCommentRange_wrap - - clang_Cursor_getRawCommentText_wrap - - clang_Cursor_getBriefCommentText_wrap - - clang_getCursorLocation_wrap - - clang_getFileLocation_wrap - - clang_getFileName_wrap - - clang_getNumElements_wrap - - clang_getArrayElementType_wrap - - clang_Cursor_isMacroFunctionLike_wrap - - clang_Cursor_isMacroBuiltin_wrap - - clang_Cursor_Evaluate_wrap - - clang_Cursor_isAnonymous_wrap - - clang_Cursor_isAnonymousRecordDecl_wrap - - clang_getCursorUSR_wrap - - clang_getFieldDeclBitWidth_wrap + - clang_getCString + - clang_disposeString + - clang_getCursorKind + - clang_getCursorKindSpelling + - clang_getCursorType + - clang_getTypeSpelling + - clang_getTypeKindSpelling + - clang_getResultType + - clang_getPointeeType + - clang_getCanonicalType + - clang_Type_getNamedType + - clang_getTypeDeclaration + - clang_getTypedefDeclUnderlyingType + - clang_getCursorSpelling + - clang_getTranslationUnitCursor + - clang_formatDiagnostic + - clang_visitChildren + - clang_Cursor_getNumArguments + - clang_Cursor_getArgument + - clang_getNumArgTypes + - clang_getArgType + - clang_getEnumConstantDeclValue + - clang_equalRanges + - clang_Cursor_getCommentRange + - clang_Cursor_getRawCommentText + - clang_Cursor_getBriefCommentText + - clang_getCursorLocation + - clang_getFileLocation + - clang_getFileName + - clang_getNumElements + - clang_getArrayElementType + - clang_Cursor_isMacroFunctionLike + - clang_Cursor_isMacroBuiltin + - clang_Cursor_Evaluate + - clang_Cursor_isAnonymous + - clang_Cursor_isAnonymousRecordDecl + - clang_getCursorUSR + - clang_getFieldDeclBitWidth