From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- third_party/rust/clang-sys/.cargo-checksum.json | 1 + third_party/rust/clang-sys/CHANGELOG.md | 517 +++++ third_party/rust/clang-sys/Cargo.toml | 73 + third_party/rust/clang-sys/LICENSE.txt | 202 ++ third_party/rust/clang-sys/README.md | 89 + third_party/rust/clang-sys/build.rs | 79 + third_party/rust/clang-sys/build/common.rs | 355 ++++ third_party/rust/clang-sys/build/dynamic.rs | 257 +++ third_party/rust/clang-sys/build/macros.rs | 38 + third_party/rust/clang-sys/build/static.rs | 140 ++ third_party/rust/clang-sys/clippy.toml | 1 + third_party/rust/clang-sys/src/lib.rs | 2291 +++++++++++++++++++++++ third_party/rust/clang-sys/src/link.rs | 273 +++ third_party/rust/clang-sys/src/support.rs | 236 +++ third_party/rust/clang-sys/tests/build.rs | 281 +++ third_party/rust/clang-sys/tests/header.h | 6 + third_party/rust/clang-sys/tests/lib.rs | 55 + 17 files changed, 4894 insertions(+) create mode 100644 third_party/rust/clang-sys/.cargo-checksum.json create mode 100644 third_party/rust/clang-sys/CHANGELOG.md create mode 100644 third_party/rust/clang-sys/Cargo.toml create mode 100644 third_party/rust/clang-sys/LICENSE.txt create mode 100644 third_party/rust/clang-sys/README.md create mode 100644 third_party/rust/clang-sys/build.rs create mode 100644 third_party/rust/clang-sys/build/common.rs create mode 100644 third_party/rust/clang-sys/build/dynamic.rs create mode 100644 third_party/rust/clang-sys/build/macros.rs create mode 100644 third_party/rust/clang-sys/build/static.rs create mode 100644 third_party/rust/clang-sys/clippy.toml create mode 100644 third_party/rust/clang-sys/src/lib.rs create mode 100644 third_party/rust/clang-sys/src/link.rs create mode 100644 third_party/rust/clang-sys/src/support.rs create mode 100644 third_party/rust/clang-sys/tests/build.rs create mode 100644 third_party/rust/clang-sys/tests/header.h create mode 100644 third_party/rust/clang-sys/tests/lib.rs (limited to 'third_party/rust/clang-sys') diff --git a/third_party/rust/clang-sys/.cargo-checksum.json b/third_party/rust/clang-sys/.cargo-checksum.json new file mode 100644 index 0000000000..b6a353c3b3 --- /dev/null +++ b/third_party/rust/clang-sys/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"0d30b4166abd35d7a300478c089a4f0ade53cb81ce3333876b1461151810bd69","Cargo.toml":"0a419871f05f413d27701e336c3c8e9253b980243025be0adf47a6c101d69430","LICENSE.txt":"3ddf9be5c28fe27dad143a5dc76eea25222ad1dd68934a047064e56ed2fa40c5","README.md":"0970fc9c7d9933e1900a465d95b9300bd68435ef56436a665b998108bf1b0abd","build.rs":"da53087156a235fe65cab1ee34e12d97b6c3e540e2c8e3ae9b2aeac71efcf1ce","build/common.rs":"52fcb086e5cf1f47a528bdc4474206a2299b6d54e536f164e288344904cdd7ed","build/dynamic.rs":"2754e488d48920681351c32b89ead0ebd03a83705b55b36f32eed54e68fa8f73","build/macros.rs":"cdd7553864bf1e5565ea3eb71561718f1485d75f277020ed37af4c272d97b5c8","build/static.rs":"b8b2654504fe509f42091b658b323214030161beb7850bbdb45924959bccc0c2","clippy.toml":"fcf54943ba571514b244cc098ce08671b4117167733e8107e799d533a12a2195","src/lib.rs":"d70eee9a78304b3daaf090471a2ae93b8007ffa181aab654b5631f53eb14475e","src/link.rs":"4d257be78d4fd654133102ec26e855cce9d9376143cff0ba0aea7c2e5b4216f8","src/support.rs":"da7e4e08a5fce844f563943588fca5de3b72972fc61db96c5158b1246737e006","tests/build.rs":"db3df3417906a77aafc8f8b4bf936dbd2cf89f2f6a7b728f14ff967897597f58","tests/header.h":"1b15a686d1c06561960045a26c25a34d840f26c8246f2f5e630f993b69c7492c","tests/lib.rs":"81a459e9f48e6d384b3fd61e7942e685f7ea39af6574bc2b382a0fbe7820ff65"},"package":"77ed9a53e5d4d9c573ae844bfac6872b159cb1d1585a83b29e7a64b7eef7332a"} \ No newline at end of file diff --git a/third_party/rust/clang-sys/CHANGELOG.md b/third_party/rust/clang-sys/CHANGELOG.md new file mode 100644 index 0000000000..c961bf10b0 --- /dev/null +++ b/third_party/rust/clang-sys/CHANGELOG.md @@ -0,0 +1,517 @@ +## [1.6.0] - 2023-02-18 +w +### Changed +- MinGW directories are not searched for `libclang` instances on Windows when +compiling for an MSVC target +- Bumped minimum supported Rust version (MSRV) to 1.51.0 +- Changed Windows search directory preferences (`libclang` instances from +Visual Studio installs are now the lowest priority rather than the second +highest) + +## ~~[1.5.1] - 2023-02-05~~ (YANKED) + +### Changed +- MinGW directories are not searched for `libclang` instances on Windows when +compiling for an MSVC target + +## ~~[1.5.0] - 2023-02-05~~ (YANKED) + +### Changed +- Bumped minimum supported Rust version (MSRV) to 1.51.0 +- Changed Windows search directory preferences (`libclang` instances from +Visual Studio installs are now the lowest priority rather than the second +highest) + +### Added +- Added additional support for `clang` 16.0.x + +## [1.4.0] - 2022-09-22 + +### Changed +- The value of an `EntityKind` enum variant +(`EntityKind::CXCursor_TranslationUnit`) has been updated for Clang 15.0 and +later to match the +[breaking change made in `libclang`](https://github.com/llvm/llvm-project/commit/bb83f8e70bd1d56152f02307adacd718cd67e312#diff-674613a0e47f4e66cc19061e28e3296d39be2d124dceefb68237b30b8e241e7c) + +### Added +- Added support for `clang` 16.0.x +- Added support for `clang` 15.0.x +- Added support for `clang` 14.0.x + +## [1.3.3] - 2022-05-28 + +### Fixed +- Fixed `Clang::find` to check that `CLANG_PATH` is an executable file before +selecting it + +## [1.3.2] - 2022-05-18 + +### Added +- Added support for illumos and derivatives + +## [1.3.1] - 2022-02-03 + +### Added +- Added missing `clang_getToken` function + +## [1.3.0] - 2021-10-31 + +### Added +- Added support for `clang` 13.0.x +- Added support for `clang` 12.0.x +- Added support for the Haiku operating system + +## [1.2.2] - 2021-09-02 + +### Fixed +- Fixed handling of paths that contain characters that have special meaning in +glob patterns (e.g., `[` or `]`) + +## [1.2.1] - 2021-08-24 + +### Changed +- Updated build script to check the install location used by the +[Scoop](https://scoop.sh/) command-line installer on Windows + +### Fixed +- Updated build script to support environments where the `PATH` environment +variable is not set + +## [1.2.0] - 2021-04-08 + +### Changed +- Changed `Clang::find` to prefer target-prefixed binaries when a `-target` +argument is provided (e.g., if the arguments `-target` and +`x86_64-unknown-linux-gnu` are provided, a target-prefixed Clang executable +such as `x86_64-unknown-linux-gnu-clang` will be preferred over a non-target +prefixed Clang executable) + +### Fixed +- Fixed build script to split paths in environment variables (e.g., +`LD_LIBRARY_PATH`) using the appropriate separator for the platform (previously +`:` was used as the separator but some platforms such as Windows use `;`) + +## [1.1.1] - 2021-02-19 + +### Changed +- Bumped `libloading` version to `0.7` + +## [1.1.0] - 2021-02-09 + +### Changed +- Added Visual Studio LLVM component directory to search paths on Windows +([#121](https://github.com/KyleMayes/clang-sys/issues/121)) + +### Added +- Added support for `clang` 11.0.x + +## [1.0.3] - 2020-11-19 + +### Fixed +- Fixed `Clang::find` panicking when `llvm-config` or `xcode-build` don't output anything to `stdout` + +## [1.0.2] - 2020-11-17 + +### Fixed +- Fixed `Clang::find` to properly search directories returned by the +`llvm-config --bindir` and `xcodebuild -find clang` commands +- Improved version selection algorithm in the case where there are multiple +instances of `libclang` with the highest version found; previously the lowest +priority instance would be selected instead of the highest priority instance +(e.g., the versions found by searching the fallback directories were preferred +over the versions found by searching the `llvm-config --prefix` directory) + +## [1.0.1] - 2020-10-01 + +### Changed +- Improved panic error message when calling an unloaded function + +## [1.0.0] - 2020-07-14 + +### Changed +- Bumped `libloading` version to `0.6.0` +- Updated build script to not print warnings about failures to execute +`llvm-config` and `xcode-select` unless an instance of `libclang` is not found + +### Added +- Added support for `clang` 10.0.x + +### Removed +- Removed `gte_clang_*` Cargo features (these were an implementation detail) + +## [0.29.3] - 2020-03-31 + +### Added +- Added ability to determine version of runtime-linked instance of `libclang` + +## [0.29.2] - 2020-03-09 + +### Added +- Revert unnecessary increase of minimum version of `libc` and `libloading` + +## [0.29.2] - 2020-03-09 + +### Added +- Revert unnecessary increase of minimum version of `libc` and `libloading` + +## [0.29.1] - 2020-03-06 + +### Added +- Added support for finding instances of `libclang` matching `libclang-*.so.*` + +## [0.29.0] - 2020-02-17 + +### Changed +- Wrapped function pointer fields in `Option` in the `CXCursorAndRangeVisitor` +and `IndexerCallbacks` structs (to permit nullability and to avoid undefined +behavior caused by `Default` implementations for these structs which returns a +zeroed value) + +### Added +- Added support for `clang` 9.0.x +- Added missing `CXCallingConv_AArch64VectorCall` variant to `CXCallingConv` enum +- Added missing `clang_CompileCommand_getNumMappedSources` function + +## [0.28.1] - 2019-07-28 + +### Changed +- Bumped `glob` version to `0.3.0` +- Improved error message when an invocation of an executable is not successful +- Allowed `LIBCLANG_PATH` to refer to a specific `libclang` instance (e.g., + `/usr/local/lib/libclang.so.10`) + +### Fixed +- Fixed + [`libclang-cpp`](https://github.com/llvm-mirror/clang/commit/90d6722bdcbc2af52306f7e948c556ad6185ac48) + being linked instead of `libclang` + +## [0.28.0] - 2019-02-17 + +### Changed +- Changed `llvm-config` to be first search candidate on macOS + +### Added +- Added support for `clang` 8.0.x + +### Removed +- Removed `assert-minimum` feature +- Removed version detection for libraries without versions embedded in the filename + +## [0.27.0] - 2019-01-10 + +### Changed +- Added version detection for libraries without versions embedded in the filename + +### Added +- Added `assert-minimum` feature (see `README.md` for details) + +## [0.26.4] - 2018-12-29 + +### Changed +- Added shared library path to `SharedLibrary` struct + +## [0.26.3] - 2018-11-14 + +### Changed +- Disable default features of `libc` dependency + +## [0.26.2] - 2018-11-03 + +### Fixed +- Fixed dynamic linking on macOS + +## [0.26.1] - 2018-10-10 + +### Fixed +- Fixed support for finding libraries in `bin` directories on Windows + +## [0.26.0] - 2018-10-07 + +### Changed +- Added support for finding libraries with version suffixes on Linux when using runtime linking (e.g., `libclang.so.1`) + +## [0.25.0] - 2018-10-06 + +### Changed +- Added support for versioned libraries on BSDs + +## [0.24.0] - 2018-09-15 + +### Changed +- Reworked finding of libraries (see `README.md` for details) + +### Added +- Added support for `clang` 7.0.x + +## [0.23.0] - 2018-06-16 + +### Changed +- Changed `Clang::find` to skip dynamic libraries for an incorrect architecture on Windows + +## [0.22.0] - 2018-03-11 + +### Added +- Added support for `clang` 6.0.x +- Bumped `libc` version to `0.2.39` +- Bumped `libloading` version to `0.5.0` + +## [0.21.2] - 2018-02-17 + +### Changed +- Added original errors to error messages +- Added support for searching for libraries in `LD_LIBRARY_PATH` directories + +## [0.21.1] - 2017-11-24 + +### Changed +- Improved finding of versioned libraries (e.g., `libclang-3.9.so`) + +### Fixed +* Fixed compilation failures on the beta and nightly channels caused by a [compiler bug](https://github.com/KyleMayes/clang-sys/pull/69) + +## [0.21.0] - 2017-10-11 + +### Changed +* Replaced `bitflags` usage with constants which avoids crashes on 32-bit Linux platforms + +## [0.20.1] - 2017-09-16 + +### Fixed +- Fixed static linking + +## [0.20.0] - 2017-09-14 + +### Added +- Added support for `clang` 5.0.x +- Added `clang` as a link target of this package +- Added dummy implementations of `is_loaded` for builds with the `static` Cargo feature enabled + +## [0.19.0] - 2017-07-02 + +### Changed +- Bumped `bitflags` version to `0.9.1` +- Added `args` parameter to `Clang::new` function which passes arguments to the Clang executable + +## [0.18.0] - 2017-05-16 + +### Changed +- Improved finding of versioned libraries (e.g., `libclang.so.3.9`) + +## [0.17.0] - 2017-05-08 + +### Changed +- Changed storage type of include search paths from `Vec` to `Option>` + +## [0.16.0] - 2017-05-02 + +### Changed +- Bumped `libloading` version to `0.4.0` + +## [0.15.2] - 2017-04-28 + +### Fixed +- Fixed finding of `libclang.so.1` on Linux + +## [0.15.1] - 2017-03-29 + +### Fixed +- Fixed static linking when libraries are in [different directories](https://github.com/KyleMayes/clang-sys/issues/50) + +## [0.15.0] - 2017-03-13 + +### Added +- Added support for `clang` 4.0.x + +### Changed +- Changed functions in the `Functions` struct to be `unsafe` (`runtime` feature only) +- Changed `Clang::find` method to ignore directories and non-executable files +- Changed `Clang::find` to skip dynamic libraries for an incorrect architecture on FreeBSD and Linux +- Bumped `bitflags` version to `0.7.0` + +## [0.14.0] - 2017-01-30 + +### Changed +- Changed all enum types from tuple structs to raw integers to avoid + [segmentation faults](https://github.com/rust-lang/rust/issues/39394) on some platforms + +## [0.13.0] - 2017-01-29 + +### Changed +- Changed all opaque pointers types from tuple structs to raw pointers to avoid + [segmentation faults](https://github.com/rust-lang/rust/issues/39394) on some platforms + +## [0.12.0] - 2016-12-13 + +### Changed +- Altered the runtime linking API to allow for testing the presence of functions + +## [0.11.1] - 2016-12-07 + +### Added +- Added support for linking to Clang on Windows from unofficial LLVM sources such as MSYS and MinGW + +## [0.11.0] - 2016-10-07 + +### Changed +- Changed all enums from Rust enums to typed constants to avoid + [undefined behavior](https://github.com/KyleMayes/clang-sys/issues/42) + +## [0.10.1] - 2016-08-21 + +### Changed +- Changed static linking on FreeBSD and macOS to link against `libc++` instead of `libstd++` + +## [0.10.0] - 2016-08-01 + +### Changed +- Added `runtime` Cargo feature that links to `libclang` shared library at runtime +- Added `from_raw` method to `CXTypeLayoutError` enum +- Added implementations of `Deref` for opaque FFI structs +- Changed `Default` implementations for structs to zero out the struct + +## [0.9.0] - 2016-07-21 + +### Added +- Added documentation bindings + +## [0.8.1] - 2016-07-20 + +### Changed +- Added `CLANG_PATH` environment variable for providing a path to `clang` executable +- Added usage of `llvm-config` to search for `clang` +- Added usage of `xcodebuild` to search for `clang` on macOS + +## [0.8.0] - 2016-07-18 + +### Added +- Added support for `clang` 3.9.x + +### Changed +- Bumped `libc` version to `0.2.14` + +### Fixed +- Fixed `LIBCLANG_PATH` usage on Windows to search both the `bin` and `lib` directories +- Fixed search path parsing on macOS +- Fixed search path parsing on Windows +- Fixed default search path ordering on macOS + +## [0.7.2] - 2016-06-17 + +### Fixed +- Fixed finding of `clang` executables when system has executables matching `clang-*` + (e.g., `clang-format`) + +## [0.7.1] - 2016-06-10 + +### Changed +- Bumped `libc` version to `0.2.12` + +### Fixed +- Fixed finding of `clang` executables suffixed by their version (e.g., `clang-3.5`) + +## [0.7.0] - 2016-05-31 + +### Changed +- Changed `Clang` struct `version` field type to `Option` + +## [0.6.0] - 2016-05-26 + +### Added +- Added `support` module + +### Fixed +- Fixed `libclang` linking on FreeBSD +- Fixed `libclang` linking on Windows with the MSVC toolchain +- Improved `libclang` static linking + +## [0.5.4] - 20160-5-19 + +### Changed +- Added implementations of `Default` for FFI structs + +## [0.5.3] - 2016-05-17 + +### Changed +- Bumped `bitflags` version to `0.7.0` + +## [0.5.2] - 2016-05-12 + +### Fixed +- Fixed `libclang` static linking + +## [0.5.1] - 2016-05-10 + +### Fixed +- Fixed `libclang` linking on macOS +- Fixed `libclang` linking on Windows + +## [0.5.0] - 2016-05-10 + +### Removed +- Removed `rustc_version` dependency +- Removed support for `LIBCLANG_STATIC` environment variable + +### Changed +- Bumped `bitflags` version to `0.6.0` +- Bumped `libc` version to `0.2.11` +- Improved `libclang` search path +- Improved `libclang` static linking + +## [0.4.2] - 2016-04-20 + +### Changed +- Bumped `libc` version to `0.2.10` + +## [0.4.1] - 2016-04-02 + +### Changed +- Bumped `libc` version to `0.2.9` +- Bumped `rustc_version` version to `0.1.7` + +## [0.4.0] - 2016-03-28 + +### Removed +- Removed support for `clang` 3.4.x + +## [0.3.1] - 2016-03-21 + +### Added +- Added support for finding `libclang` + +## [0.3.0] - 2016-03-16 + +### Removed +- Removed build system types and functions + +### Added +- Added support for `clang` 3.4.x + +### Changed +- Bumped `bitflags` version to `0.5.0` +- Bumped `libc` version to `0.2.8` + +## [0.2.1] - 2016-02-13 + +### Changed +- Simplified internal usage of conditional compilation +- Bumped `bitflags` version to `0.4.0` +- Bumped `libc` version to `0.2.7` +- Bumped `rustc_version` version to `0.1.6` + +## [0.2.0] - 2016-02-12 + +### Added +- Added support for `clang` 3.8.x + +## [0.1.2] - 2015-12-29 + +### Added +- Added derivations of `Debug` for FFI structs + +## [0.1.1] - 2015-12-26 + +### Added +- Added derivations of `PartialOrd` and `Ord` for FFI enums + +## [0.1.0] - 2015-12-22 +- Initial release diff --git a/third_party/rust/clang-sys/Cargo.toml b/third_party/rust/clang-sys/Cargo.toml new file mode 100644 index 0000000000..5c6c0a291c --- /dev/null +++ b/third_party/rust/clang-sys/Cargo.toml @@ -0,0 +1,73 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +name = "clang-sys" +version = "1.6.0" +authors = ["Kyle Mayes "] +build = "build.rs" +links = "clang" +description = "Rust bindings for libclang." +documentation = "https://docs.rs/clang-sys" +readme = "README.md" +license = "Apache-2.0" +repository = "https://github.com/KyleMayes/clang-sys" + +[package.metadata.docs.rs] +features = [ + "clang_16_0", + "runtime", +] + +[dependencies.glob] +version = "0.3" + +[dependencies.libc] +version = "0.2.39" +default-features = false + +[dependencies.libloading] +version = "0.7" +optional = true + +[dev-dependencies.glob] +version = "0.3" + +[dev-dependencies.serial_test] +version = "1" + +[dev-dependencies.tempdir] +version = "0.3" + +[build-dependencies.glob] +version = "0.3" + +[features] +clang_10_0 = ["clang_9_0"] +clang_11_0 = ["clang_10_0"] +clang_12_0 = ["clang_11_0"] +clang_13_0 = ["clang_12_0"] +clang_14_0 = ["clang_13_0"] +clang_15_0 = ["clang_14_0"] +clang_16_0 = ["clang_15_0"] +clang_3_5 = [] +clang_3_6 = ["clang_3_5"] +clang_3_7 = ["clang_3_6"] +clang_3_8 = ["clang_3_7"] +clang_3_9 = ["clang_3_8"] +clang_4_0 = ["clang_3_9"] +clang_5_0 = ["clang_4_0"] +clang_6_0 = ["clang_5_0"] +clang_7_0 = ["clang_6_0"] +clang_8_0 = ["clang_7_0"] +clang_9_0 = ["clang_8_0"] +runtime = ["libloading"] +static = [] diff --git a/third_party/rust/clang-sys/LICENSE.txt b/third_party/rust/clang-sys/LICENSE.txt new file mode 100644 index 0000000000..75b52484ea --- /dev/null +++ b/third_party/rust/clang-sys/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/third_party/rust/clang-sys/README.md b/third_party/rust/clang-sys/README.md new file mode 100644 index 0000000000..a0ed842fec --- /dev/null +++ b/third_party/rust/clang-sys/README.md @@ -0,0 +1,89 @@ +# clang-sys + +[![Crate](https://img.shields.io/crates/v/clang-sys.svg)](https://crates.io/crates/clang-sys) +[![Documentation](https://docs.rs/clang-sys/badge.svg)](https://docs.rs/clang-sys) +[![CI](https://img.shields.io/github/actions/workflow/status/KyleMayes/clang-sys/ci.yml?branch=master)](https://github.com/KyleMayes/clang-sys/actions?query=workflow%3ACI) +![MSRV](https://img.shields.io/badge/MSRV-1.51.0-blue) + +Rust bindings for `libclang`. + +If you are interested in a somewhat idiomatic Rust wrapper for these bindings, see [`clang-rs`](https://github.com/KyleMayes/clang-rs). + +Released under the Apache License 2.0. + +## [Documentation](https://docs.rs/clang-sys) + +Note that the documentation on https://docs.rs for this crate assumes usage of the `runtime` Cargo feature as well as the Cargo feature for the latest supported version of `libclang` (e.g., `clang_16_0`), neither of which are enabled by default. + +Due to the usage of the `runtime` Cargo feature, this documentation will contain some additional types and functions to manage a dynamically loaded `libclang` instance at runtime. + +Due to the usage of the Cargo feature for the latest supported version of `libclang`, this documentation will contain constants and functions that are not available in the oldest supported version of `libclang` (3.5). All of these types and functions have a documentation comment which specifies the minimum `libclang` version required to use the item. + +## Supported Versions + +To target a version of `libclang`, enable a Cargo features such as one of the following: + +* `clang_3_5` - requires `libclang` 3.5 or later +* `clang_3_6` - requires `libclang` 3.6 or later +* etc... +* `clang_15_0` - requires `libclang` 15.0 or later +* `clang_16_0` - requires `libclang` 16.0 or later + +If you do not enable one of these features, the API provided by `libclang` 3.5 will be available by default. + +**Note:** If you are using Clang 15.0 or later, you should enable the `clang_15_0` feature or a more recent version feature. Clang 15.0 introduced [a breaking change to the `EntityKind` enum](https://github.com/llvm/llvm-project/commit/bb83f8e70bd1d56152f02307adacd718cd67e312#diff-674613a0e47f4e66cc19061e28e3296d39be2d124dceefb68237b30b8e241e7c) which resulted in a mismatch between the values returned by `libclang` and the values for `EntityKind` defined by this crate in previous versions. + +## Dependencies + +By default, this crate will attempt to link to `libclang` dynamically. In this case, this crate depends on the `libclang` shared library (`libclang.so` on Linux, `libclang.dylib` on macOS, `libclang.dll` on Windows). If you want to link to `libclang` statically instead, enable the `static` Cargo feature. In this case, this crate depends on the LLVM and Clang static libraries. If you don't want to link to `libclang` at compiletime but instead want to load it at runtime, enable the `runtime` Cargo feature. + +These libraries can be either be installed as a part of Clang or downloaded [here](http://llvm.org/releases/download.html). + +**Note:** The downloads for LLVM and Clang 3.8 and later do not include the `libclang.a` static library. This means you cannot link to any of these versions of `libclang` statically unless you build it from source. + +### Versioned Dependencies + +This crate supports finding versioned instances of `libclang.so` (e.g.,`libclang-3.9.so`). In the case where there are multiple instances to choose from, this crate will prefer instances with higher versions. For example, the following instances of `libclang.so` are listed in descending order of preference: + +1. `libclang-4.0.so` +2. `libclang-4.so` +3. `libclang-3.9.so` +4. `libclang-3.so` +5. `libclang.so` + +**Note:** On BSD distributions, versioned instances of `libclang.so` matching the pattern `libclang.so.*` (e.g., `libclang.so.7.0`) are also included. + +**Note:** On Linux distributions when the `runtime` features is enabled, versioned instances of `libclang.so` matching the pattern `libclang.so.*` (e.g., `libclang.so.1`) are also included. + +## Environment Variables + +The following environment variables, if set, are used by this crate to find the required libraries and executables: + +* `LLVM_CONFIG_PATH` **(compiletime)** - provides a full path to an `llvm-config` executable (including the executable itself [i.e., `/usr/local/bin/llvm-config-8.0`]) +* `LIBCLANG_PATH` **(compiletime)** - provides a path to a directory containing a `libclang` shared library or a full path to a specific `libclang` shared library +* `LIBCLANG_STATIC_PATH` **(compiletime)** - provides a path to a directory containing LLVM and Clang static libraries +* `CLANG_PATH` **(runtime)** - provides a path to a `clang` executable + +## Linking + +### Dynamic + +`libclang` shared libraries will be searched for in the following directories: + +* the directory provided by the `LIBCLANG_PATH` environment variable +* the `bin` and `lib` directories in the directory provided by `llvm-config --libdir` +* the directories provided by `LD_LIBRARY_PATH` environment variable +* a list of likely directories for the target platform (e.g., `/usr/local/lib` on Linux) +* **macOS only:** the toolchain directory in the directory provided by `xcode-select --print-path` + +On Linux, running an executable that has been dynamically linked to `libclang` may require you to add a path to `libclang.so` to the `LD_LIBRARY_PATH` environment variable. The same is true on OS X, except the `DYLD_LIBRARY_PATH` environment variable is used instead. + +On Windows, running an executable that has been dynamically linked to `libclang` requires that `libclang.dll` can be found by the executable at runtime. See [here](https://msdn.microsoft.com/en-us/library/7d83bc18.aspx) for more information. + +### Static + +The availability of `llvm-config` is not optional for static linking. Ensure that an instance of this executable can be found on your system's path or set the `LLVM_CONFIG_PATH` environment variable. The required LLVM and Clang static libraries will be searched for in the same way as shared libraries are searched for, except the `LIBCLANG_STATIC_PATH` environment variable is used in place of the `LIBCLANG_PATH` environment variable. + +### Runtime + +The `clang_sys::load` function is used to load a `libclang` shared library for use in the thread in which it is called. The `clang_sys::unload` function will unload the `libclang` shared library. `clang_sys::load` searches for a `libclang` shared library in the same way one is searched for when linking to `libclang` dynamically at compiletime. diff --git a/third_party/rust/clang-sys/build.rs b/third_party/rust/clang-sys/build.rs new file mode 100644 index 0000000000..2eed15cea9 --- /dev/null +++ b/third_party/rust/clang-sys/build.rs @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: Apache-2.0 + +//! Finds `libclang` static or shared libraries and links to them. +//! +//! # Environment Variables +//! +//! This build script can make use of several environment variables to help it +//! find the required static or shared libraries. +//! +//! * `LLVM_CONFIG_PATH` - provides a path to an `llvm-config` executable +//! * `LIBCLANG_PATH` - provides a path to a directory containing a `libclang` +//! shared library or a path to a specific `libclang` shared library +//! * `LIBCLANG_STATIC_PATH` - provides a path to a directory containing LLVM +//! and Clang static libraries + +#![allow(unused_attributes)] + +extern crate glob; + +use std::path::Path; + +#[macro_use] +#[path = "build/macros.rs"] +pub mod macros; + +#[path = "build/common.rs"] +pub mod common; +#[path = "build/dynamic.rs"] +pub mod dynamic; +#[path = "build/static.rs"] +pub mod r#static; + +/// Copies a file. +#[cfg(feature = "runtime")] +fn copy(source: &str, destination: &Path) { + use std::fs::File; + use std::io::{Read, Write}; + + let mut string = String::new(); + File::open(source) + .unwrap() + .read_to_string(&mut string) + .unwrap(); + File::create(destination) + .unwrap() + .write_all(string.as_bytes()) + .unwrap(); +} + +/// Copies the code used to find and link to `libclang` shared libraries into +/// the build output directory so that it may be used when linking at runtime. +#[cfg(feature = "runtime")] +fn main() { + use std::env; + + if cfg!(feature = "static") { + panic!("`runtime` and `static` features can't be combined"); + } + + let out = env::var("OUT_DIR").unwrap(); + copy("build/macros.rs", &Path::new(&out).join("macros.rs")); + copy("build/common.rs", &Path::new(&out).join("common.rs")); + copy("build/dynamic.rs", &Path::new(&out).join("dynamic.rs")); +} + +/// Finds and links to the required libraries dynamically or statically. +#[cfg(not(feature = "runtime"))] +fn main() { + if cfg!(feature = "static") { + r#static::link(); + } else { + dynamic::link(); + } + + if let Some(output) = common::run_llvm_config(&["--includedir"]) { + let directory = Path::new(output.trim_end()); + println!("cargo:include={}", directory.display()); + } +} diff --git a/third_party/rust/clang-sys/build/common.rs b/third_party/rust/clang-sys/build/common.rs new file mode 100644 index 0000000000..bd94447c9e --- /dev/null +++ b/third_party/rust/clang-sys/build/common.rs @@ -0,0 +1,355 @@ +// SPDX-License-Identifier: Apache-2.0 + +extern crate glob; + +use std::cell::RefCell; +use std::collections::HashMap; +use std::env; +use std::path::{Path, PathBuf}; +use std::process::Command; + +use glob::{MatchOptions, Pattern}; + +//================================================ +// Commands +//================================================ + +thread_local! { + /// The errors encountered by the build script while executing commands. + static COMMAND_ERRORS: RefCell>> = RefCell::default(); +} + +/// Adds an error encountered by the build script while executing a command. +fn add_command_error(name: &str, path: &str, arguments: &[&str], message: String) { + COMMAND_ERRORS.with(|e| { + e.borrow_mut() + .entry(name.into()) + .or_insert_with(Vec::new) + .push(format!( + "couldn't execute `{} {}` (path={}) ({})", + name, + arguments.join(" "), + path, + message, + )) + }); +} + +/// A struct that prints the errors encountered by the build script while +/// executing commands when dropped (unless explictly discarded). +/// +/// This is handy because we only want to print these errors when the build +/// script fails to link to an instance of `libclang`. For example, if +/// `llvm-config` couldn't be executed but an instance of `libclang` was found +/// anyway we don't want to pollute the build output with irrelevant errors. +#[derive(Default)] +pub struct CommandErrorPrinter { + discard: bool, +} + +impl CommandErrorPrinter { + pub fn discard(mut self) { + self.discard = true; + } +} + +impl Drop for CommandErrorPrinter { + fn drop(&mut self) { + if self.discard { + return; + } + + let errors = COMMAND_ERRORS.with(|e| e.borrow().clone()); + + if let Some(errors) = errors.get("llvm-config") { + println!( + "cargo:warning=could not execute `llvm-config` one or more \ + times, if the LLVM_CONFIG_PATH environment variable is set to \ + a full path to valid `llvm-config` executable it will be used \ + to try to find an instance of `libclang` on your system: {}", + errors + .iter() + .map(|e| format!("\"{}\"", e)) + .collect::>() + .join("\n "), + ) + } + + if let Some(errors) = errors.get("xcode-select") { + println!( + "cargo:warning=could not execute `xcode-select` one or more \ + times, if a valid instance of this executable is on your PATH \ + it will be used to try to find an instance of `libclang` on \ + your system: {}", + errors + .iter() + .map(|e| format!("\"{}\"", e)) + .collect::>() + .join("\n "), + ) + } + } +} + +#[cfg(test)] +pub static RUN_COMMAND_MOCK: std::sync::Mutex< + Option Option + Send + Sync + 'static>>, +> = std::sync::Mutex::new(None); + +/// Executes a command and returns the `stdout` output if the command was +/// successfully executed (errors are added to `COMMAND_ERRORS`). +fn run_command(name: &str, path: &str, arguments: &[&str]) -> Option { + #[cfg(test)] + if let Some(command) = &*RUN_COMMAND_MOCK.lock().unwrap() { + return command(name, path, arguments); + } + + let output = match Command::new(path).args(arguments).output() { + Ok(output) => output, + Err(error) => { + let message = format!("error: {}", error); + add_command_error(name, path, arguments, message); + return None; + } + }; + + if output.status.success() { + Some(String::from_utf8_lossy(&output.stdout).into_owned()) + } else { + let message = format!("exit code: {}", output.status); + add_command_error(name, path, arguments, message); + None + } +} + +/// Executes the `llvm-config` command and returns the `stdout` output if the +/// command was successfully executed (errors are added to `COMMAND_ERRORS`). +pub fn run_llvm_config(arguments: &[&str]) -> Option { + let path = env::var("LLVM_CONFIG_PATH").unwrap_or_else(|_| "llvm-config".into()); + run_command("llvm-config", &path, arguments) +} + +/// Executes the `xcode-select` command and returns the `stdout` output if the +/// command was successfully executed (errors are added to `COMMAND_ERRORS`). +pub fn run_xcode_select(arguments: &[&str]) -> Option { + run_command("xcode-select", "xcode-select", arguments) +} + +//================================================ +// Search Directories +//================================================ +// These search directories are listed in order of +// preference, so if multiple `libclang` instances +// are found when searching matching directories, +// the `libclang` instances from earlier +// directories will be preferred (though version +// takes precedence over location). +//================================================ + +/// `libclang` directory patterns for Haiku. +const DIRECTORIES_HAIKU: &[&str] = &[ + "/boot/home/config/non-packaged/develop/lib", + "/boot/home/config/non-packaged/lib", + "/boot/system/non-packaged/develop/lib", + "/boot/system/non-packaged/lib", + "/boot/system/develop/lib", + "/boot/system/lib", +]; + +/// `libclang` directory patterns for Linux (and FreeBSD). +const DIRECTORIES_LINUX: &[&str] = &[ + "/usr/local/llvm*/lib*", + "/usr/local/lib*/*/*", + "/usr/local/lib*/*", + "/usr/local/lib*", + "/usr/lib*/*/*", + "/usr/lib*/*", + "/usr/lib*", +]; + +/// `libclang` directory patterns for macOS. +const DIRECTORIES_MACOS: &[&str] = &[ + "/usr/local/opt/llvm*/lib/llvm*/lib", + "/Library/Developer/CommandLineTools/usr/lib", + "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib", + "/usr/local/opt/llvm*/lib", +]; + +/// `libclang` directory patterns for Windows. +/// +/// The boolean indicates whether the directory pattern should be used when +/// compiling for an MSVC target environment. +const DIRECTORIES_WINDOWS: &[(&str, bool)] = &[ + // LLVM + Clang can be installed using Scoop (https://scoop.sh). + // Other Windows package managers install LLVM + Clang to other listed + // system-wide directories. + ("C:\\Users\\*\\scoop\\apps\\llvm\\current\\lib", true), + ("C:\\MSYS*\\MinGW*\\lib", false), + ("C:\\Program Files*\\LLVM\\lib", true), + ("C:\\LLVM\\lib", true), + // LLVM + Clang can be installed as a component of Visual Studio. + // https://github.com/KyleMayes/clang-sys/issues/121 + ("C:\\Program Files*\\Microsoft Visual Studio\\*\\BuildTools\\VC\\Tools\\Llvm\\**\\lib", true), +]; + +/// `libclang` directory patterns for illumos +const DIRECTORIES_ILLUMOS: &[&str] = &[ + "/opt/ooce/llvm-*/lib", + "/opt/ooce/clang-*/lib", +]; + +//================================================ +// Searching +//================================================ + +/// Finds the files in a directory that match one or more filename glob patterns +/// and returns the paths to and filenames of those files. +fn search_directory(directory: &Path, filenames: &[String]) -> Vec<(PathBuf, String)> { + // Escape the specified directory in case it contains characters that have + // special meaning in glob patterns (e.g., `[` or `]`). + let directory = Pattern::escape(directory.to_str().unwrap()); + let directory = Path::new(&directory); + + // Join the escaped directory to the filename glob patterns to obtain + // complete glob patterns for the files being searched for. + let paths = filenames + .iter() + .map(|f| directory.join(f).to_str().unwrap().to_owned()); + + // Prevent wildcards from matching path separators to ensure that the search + // is limited to the specified directory. + let mut options = MatchOptions::new(); + options.require_literal_separator = true; + + paths + .map(|p| glob::glob_with(&p, options)) + .filter_map(Result::ok) + .flatten() + .filter_map(|p| { + let path = p.ok()?; + let filename = path.file_name()?.to_str().unwrap(); + + // The `libclang_shared` library has been renamed to `libclang-cpp` + // in Clang 10. This can cause instances of this library (e.g., + // `libclang-cpp.so.10`) to be matched by patterns looking for + // instances of `libclang`. + if filename.contains("-cpp.") { + return None; + } + + Some((directory.to_owned(), filename.into())) + }) + .collect::>() +} + +/// Finds the files in a directory (and any relevant sibling directories) that +/// match one or more filename glob patterns and returns the paths to and +/// filenames of those files. +fn search_directories(directory: &Path, filenames: &[String]) -> Vec<(PathBuf, String)> { + let mut results = search_directory(directory, filenames); + + // On Windows, `libclang.dll` is usually found in the LLVM `bin` directory + // while `libclang.lib` is usually found in the LLVM `lib` directory. To + // keep things consistent with other platforms, only LLVM `lib` directories + // are included in the backup search directory globs so we need to search + // the LLVM `bin` directory here. + if target_os!("windows") && directory.ends_with("lib") { + let sibling = directory.parent().unwrap().join("bin"); + results.extend(search_directory(&sibling, filenames).into_iter()); + } + + results +} + +/// Finds the `libclang` static or dynamic libraries matching one or more +/// filename glob patterns and returns the paths to and filenames of those files. +pub fn search_libclang_directories(filenames: &[String], variable: &str) -> Vec<(PathBuf, String)> { + // Search only the path indicated by the relevant environment variable + // (e.g., `LIBCLANG_PATH`) if it is set. + if let Ok(path) = env::var(variable).map(|d| Path::new(&d).to_path_buf()) { + // Check if the path is a matching file. + if let Some(parent) = path.parent() { + let filename = path.file_name().unwrap().to_str().unwrap(); + let libraries = search_directories(parent, filenames); + if libraries.iter().any(|(_, f)| f == filename) { + return vec![(parent.into(), filename.into())]; + } + } + + // Check if the path is directory containing a matching file. + return search_directories(&path, filenames); + } + + let mut found = vec![]; + + // Search the `bin` and `lib` directories in the directory returned by + // `llvm-config --prefix`. + if let Some(output) = run_llvm_config(&["--prefix"]) { + let directory = Path::new(output.lines().next().unwrap()).to_path_buf(); + found.extend(search_directories(&directory.join("bin"), filenames)); + found.extend(search_directories(&directory.join("lib"), filenames)); + found.extend(search_directories(&directory.join("lib64"), filenames)); + } + + // Search the toolchain directory in the directory returned by + // `xcode-select --print-path`. + if target_os!("macos") { + if let Some(output) = run_xcode_select(&["--print-path"]) { + let directory = Path::new(output.lines().next().unwrap()).to_path_buf(); + let directory = directory.join("Toolchains/XcodeDefault.xctoolchain/usr/lib"); + found.extend(search_directories(&directory, filenames)); + } + } + + // Search the directories in the `LD_LIBRARY_PATH` environment variable. + if let Ok(path) = env::var("LD_LIBRARY_PATH") { + for directory in env::split_paths(&path) { + found.extend(search_directories(&directory, filenames)); + } + } + + // Determine the `libclang` directory patterns. + let directories: Vec<&str> = if target_os!("haiku") { + DIRECTORIES_HAIKU.into() + } else if target_os!("linux") || target_os!("freebsd") { + DIRECTORIES_LINUX.into() + } else if target_os!("macos") { + DIRECTORIES_MACOS.into() + } else if target_os!("windows") { + let msvc = target_env!("msvc"); + DIRECTORIES_WINDOWS + .iter() + .filter(|d| d.1 || !msvc) + .map(|d| d.0) + .collect() + } else if target_os!("illumos") { + DIRECTORIES_ILLUMOS.into() + } else { + vec![] + }; + + // We use temporary directories when testing the build script so we'll + // remove the prefixes that make the directories absolute. + let directories = if test!() { + directories + .iter() + .map(|d| d.strip_prefix('/').or_else(|| d.strip_prefix("C:\\")).unwrap_or(d)) + .collect::>() + } else { + directories.into() + }; + + // Search the directories provided by the `libclang` directory patterns. + let mut options = MatchOptions::new(); + options.case_sensitive = false; + options.require_literal_separator = true; + for directory in directories.iter() { + if let Ok(directories) = glob::glob_with(directory, options) { + for directory in directories.filter_map(Result::ok).filter(|p| p.is_dir()) { + found.extend(search_directories(&directory, filenames)); + } + } + } + + found +} diff --git a/third_party/rust/clang-sys/build/dynamic.rs b/third_party/rust/clang-sys/build/dynamic.rs new file mode 100644 index 0000000000..8039364299 --- /dev/null +++ b/third_party/rust/clang-sys/build/dynamic.rs @@ -0,0 +1,257 @@ +// SPDX-License-Identifier: Apache-2.0 + +use std::env; +use std::fs::File; +use std::io::{self, Error, ErrorKind, Read, Seek, SeekFrom}; +use std::path::{Path, PathBuf}; + +use super::common; + +//================================================ +// Validation +//================================================ + +/// Extracts the ELF class from the ELF header in a shared library. +fn parse_elf_header(path: &Path) -> io::Result { + let mut file = File::open(path)?; + let mut buffer = [0; 5]; + file.read_exact(&mut buffer)?; + if buffer[..4] == [127, 69, 76, 70] { + Ok(buffer[4]) + } else { + Err(Error::new(ErrorKind::InvalidData, "invalid ELF header")) + } +} + +/// Extracts the magic number from the PE header in a shared library. +fn parse_pe_header(path: &Path) -> io::Result { + let mut file = File::open(path)?; + + // Extract the header offset. + let mut buffer = [0; 4]; + let start = SeekFrom::Start(0x3C); + file.seek(start)?; + file.read_exact(&mut buffer)?; + let offset = i32::from_le_bytes(buffer); + + // Check the validity of the header. + file.seek(SeekFrom::Start(offset as u64))?; + file.read_exact(&mut buffer)?; + if buffer != [80, 69, 0, 0] { + return Err(Error::new(ErrorKind::InvalidData, "invalid PE header")); + } + + // Extract the magic number. + let mut buffer = [0; 2]; + file.seek(SeekFrom::Current(20))?; + file.read_exact(&mut buffer)?; + Ok(u16::from_le_bytes(buffer)) +} + +/// Checks that a `libclang` shared library matches the target platform. +fn validate_library(path: &Path) -> Result<(), String> { + if target_os!("linux") || target_os!("freebsd") { + let class = parse_elf_header(path).map_err(|e| e.to_string())?; + + if target_pointer_width!("32") && class != 1 { + return Err("invalid ELF class (64-bit)".into()); + } + + if target_pointer_width!("64") && class != 2 { + return Err("invalid ELF class (32-bit)".into()); + } + + Ok(()) + } else if target_os!("windows") { + let magic = parse_pe_header(path).map_err(|e| e.to_string())?; + + if target_pointer_width!("32") && magic != 267 { + return Err("invalid DLL (64-bit)".into()); + } + + if target_pointer_width!("64") && magic != 523 { + return Err("invalid DLL (32-bit)".into()); + } + + Ok(()) + } else { + Ok(()) + } +} + +//================================================ +// Searching +//================================================ + +/// Extracts the version components in a `libclang` shared library filename. +fn parse_version(filename: &str) -> Vec { + let version = if let Some(version) = filename.strip_prefix("libclang.so.") { + version + } else if filename.starts_with("libclang-") { + &filename[9..filename.len() - 3] + } else { + return vec![]; + }; + + version.split('.').map(|s| s.parse().unwrap_or(0)).collect() +} + +/// Finds `libclang` shared libraries and returns the paths to, filenames of, +/// and versions of those shared libraries. +fn search_libclang_directories(runtime: bool) -> Result)>, String> { + let mut files = vec![format!( + "{}clang{}", + env::consts::DLL_PREFIX, + env::consts::DLL_SUFFIX + )]; + + if target_os!("linux") { + // Some Linux distributions don't create a `libclang.so` symlink, so we + // need to look for versioned files (e.g., `libclang-3.9.so`). + files.push("libclang-*.so".into()); + + // Some Linux distributions don't create a `libclang.so` symlink and + // don't have versioned files as described above, so we need to look for + // suffix versioned files (e.g., `libclang.so.1`). However, `ld` cannot + // link to these files, so this will only be included when linking at + // runtime. + if runtime { + files.push("libclang.so.*".into()); + files.push("libclang-*.so.*".into()); + } + } + + if target_os!("freebsd") || target_os!("haiku") || target_os!("netbsd") || target_os!("openbsd") { + // Some BSD distributions don't create a `libclang.so` symlink either, + // but use a different naming scheme for versioned files (e.g., + // `libclang.so.7.0`). + files.push("libclang.so.*".into()); + } + + if target_os!("windows") { + // The official LLVM build uses `libclang.dll` on Windows instead of + // `clang.dll`. However, unofficial builds such as MinGW use `clang.dll`. + files.push("libclang.dll".into()); + } + + // Find and validate `libclang` shared libraries and collect the versions. + let mut valid = vec![]; + let mut invalid = vec![]; + for (directory, filename) in common::search_libclang_directories(&files, "LIBCLANG_PATH") { + let path = directory.join(&filename); + match validate_library(&path) { + Ok(()) => { + let version = parse_version(&filename); + valid.push((directory, filename, version)) + } + Err(message) => invalid.push(format!("({}: {})", path.display(), message)), + } + } + + if !valid.is_empty() { + return Ok(valid); + } + + let message = format!( + "couldn't find any valid shared libraries matching: [{}], set the \ + `LIBCLANG_PATH` environment variable to a path where one of these files \ + can be found (invalid: [{}])", + files + .iter() + .map(|f| format!("'{}'", f)) + .collect::>() + .join(", "), + invalid.join(", "), + ); + + Err(message) +} + +/// Finds the "best" `libclang` shared library and returns the directory and +/// filename of that library. +pub fn find(runtime: bool) -> Result<(PathBuf, String), String> { + search_libclang_directories(runtime)? + .iter() + // We want to find the `libclang` shared library with the highest + // version number, hence `max_by_key` below. + // + // However, in the case where there are multiple such `libclang` shared + // libraries, we want to use the order in which they appeared in the + // list returned by `search_libclang_directories` as a tiebreaker since + // that function returns `libclang` shared libraries in descending order + // of preference by how they were found. + // + // `max_by_key`, perhaps surprisingly, returns the *last* item with the + // maximum key rather than the first which results in the opposite of + // the tiebreaking behavior we want. This is easily fixed by reversing + // the list first. + .rev() + .max_by_key(|f| &f.2) + .cloned() + .map(|(path, filename, _)| (path, filename)) + .ok_or_else(|| "unreachable".into()) +} + +//================================================ +// Linking +//================================================ + +/// Finds and links to a `libclang` shared library. +#[cfg(not(feature = "runtime"))] +pub fn link() { + let cep = common::CommandErrorPrinter::default(); + + use std::fs; + + let (directory, filename) = find(false).unwrap(); + println!("cargo:rustc-link-search={}", directory.display()); + + if cfg!(all(target_os = "windows", target_env = "msvc")) { + // Find the `libclang` stub static library required for the MSVC + // toolchain. + let lib = if !directory.ends_with("bin") { + directory + } else { + directory.parent().unwrap().join("lib") + }; + + if lib.join("libclang.lib").exists() { + println!("cargo:rustc-link-search={}", lib.display()); + } else if lib.join("libclang.dll.a").exists() { + // MSYS and MinGW use `libclang.dll.a` instead of `libclang.lib`. + // It is linkable with the MSVC linker, but Rust doesn't recognize + // the `.a` suffix, so we need to copy it with a different name. + // + // FIXME: Maybe we can just hardlink or symlink it? + let out = env::var("OUT_DIR").unwrap(); + fs::copy( + lib.join("libclang.dll.a"), + Path::new(&out).join("libclang.lib"), + ) + .unwrap(); + println!("cargo:rustc-link-search=native={}", out); + } else { + panic!( + "using '{}', so 'libclang.lib' or 'libclang.dll.a' must be \ + available in {}", + filename, + lib.display(), + ); + } + + println!("cargo:rustc-link-lib=dylib=libclang"); + } else { + let name = filename.trim_start_matches("lib"); + + // Strip extensions and trailing version numbers (e.g., the `.so.7.0` in + // `libclang.so.7.0`). + let name = match name.find(".dylib").or_else(|| name.find(".so")) { + Some(index) => &name[0..index], + None => name, + }; + + println!("cargo:rustc-link-lib=dylib={}", name); + } + + cep.discard(); +} diff --git a/third_party/rust/clang-sys/build/macros.rs b/third_party/rust/clang-sys/build/macros.rs new file mode 100644 index 0000000000..b70aa6897e --- /dev/null +++ b/third_party/rust/clang-sys/build/macros.rs @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: Apache-2.0 + +macro_rules! test { + () => (cfg!(test) && ::std::env::var("_CLANG_SYS_TEST").is_ok()); +} + +macro_rules! target_os { + ($os:expr) => { + if cfg!(test) && ::std::env::var("_CLANG_SYS_TEST").is_ok() { + let var = ::std::env::var("_CLANG_SYS_TEST_OS"); + var.map_or(false, |v| v == $os) + } else { + cfg!(target_os = $os) + } + }; +} + +macro_rules! target_pointer_width { + ($pointer_width:expr) => { + if cfg!(test) && ::std::env::var("_CLANG_SYS_TEST").is_ok() { + let var = ::std::env::var("_CLANG_SYS_TEST_POINTER_WIDTH"); + var.map_or(false, |v| v == $pointer_width) + } else { + cfg!(target_pointer_width = $pointer_width) + } + }; +} + +macro_rules! target_env { + ($env:expr) => { + if cfg!(test) && ::std::env::var("_CLANG_SYS_TEST").is_ok() { + let var = ::std::env::var("_CLANG_SYS_TEST_ENV"); + var.map_or(false, |v| v == $env) + } else { + cfg!(target_env = $env) + } + }; +} diff --git a/third_party/rust/clang-sys/build/static.rs b/third_party/rust/clang-sys/build/static.rs new file mode 100644 index 0000000000..6d86b9a8d8 --- /dev/null +++ b/third_party/rust/clang-sys/build/static.rs @@ -0,0 +1,140 @@ +// SPDX-License-Identifier: Apache-2.0 + +extern crate glob; + +use std::path::{Path, PathBuf}; + +use glob::Pattern; + +use super::common; + +//================================================ +// Searching +//================================================ + +/// Clang static libraries required to link to `libclang` 3.5 and later. +const CLANG_LIBRARIES: &[&str] = &[ + "clang", + "clangAST", + "clangAnalysis", + "clangBasic", + "clangDriver", + "clangEdit", + "clangFrontend", + "clangIndex", + "clangLex", + "clangParse", + "clangRewrite", + "clangSema", + "clangSerialization", +]; + +/// Gets the name of an LLVM or Clang static library from a path. +fn get_library_name(path: &Path) -> Option { + path.file_stem().map(|p| { + let string = p.to_string_lossy(); + if let Some(name) = string.strip_prefix("lib") { + name.to_owned() + } else { + string.to_string() + } + }) +} + +/// Gets the LLVM static libraries required to link to `libclang`. +fn get_llvm_libraries() -> Vec { + common::run_llvm_config(&["--libs"]) + .unwrap() + .split_whitespace() + .filter_map(|p| { + // Depending on the version of `llvm-config` in use, listed + // libraries may be in one of two forms, a full path to the library + // or simply prefixed with `-l`. + if let Some(path) = p.strip_prefix("-l") { + Some(path.into()) + } else { + get_library_name(Path::new(p)) + } + }) + .collect() +} + +/// Gets the Clang static libraries required to link to `libclang`. +fn get_clang_libraries>(directory: P) -> Vec { + // Escape the directory in case it contains characters that have special + // meaning in glob patterns (e.g., `[` or `]`). + let directory = Pattern::escape(directory.as_ref().to_str().unwrap()); + let directory = Path::new(&directory); + + let pattern = directory.join("libclang*.a").to_str().unwrap().to_owned(); + if let Ok(libraries) = glob::glob(&pattern) { + libraries + .filter_map(|l| l.ok().and_then(|l| get_library_name(&l))) + .collect() + } else { + CLANG_LIBRARIES.iter().map(|l| (*l).to_string()).collect() + } +} + +/// Finds a directory containing LLVM and Clang static libraries and returns the +/// path to that directory. +fn find() -> PathBuf { + let name = if target_os!("windows") { + "libclang.lib" + } else { + "libclang.a" + }; + + let files = common::search_libclang_directories(&[name.into()], "LIBCLANG_STATIC_PATH"); + if let Some((directory, _)) = files.into_iter().next() { + directory + } else { + panic!("could not find any static libraries"); + } +} + +//================================================ +// Linking +//================================================ + +/// Finds and links to `libclang` static libraries. +pub fn link() { + let cep = common::CommandErrorPrinter::default(); + + let directory = find(); + + // Specify required Clang static libraries. + println!("cargo:rustc-link-search=native={}", directory.display()); + for library in get_clang_libraries(directory) { + println!("cargo:rustc-link-lib=static={}", library); + } + + // Determine the shared mode used by LLVM. + let mode = common::run_llvm_config(&["--shared-mode"]).map(|m| m.trim().to_owned()); + let prefix = if mode.map_or(false, |m| m == "static") { + "static=" + } else { + "" + }; + + // Specify required LLVM static libraries. + println!( + "cargo:rustc-link-search=native={}", + common::run_llvm_config(&["--libdir"]).unwrap().trim_end() + ); + for library in get_llvm_libraries() { + println!("cargo:rustc-link-lib={}{}", prefix, library); + } + + // Specify required system libraries. + // MSVC doesn't need this, as it tracks dependencies inside `.lib` files. + if cfg!(target_os = "freebsd") { + println!("cargo:rustc-flags=-l ffi -l ncursesw -l c++ -l z"); + } else if cfg!(any(target_os = "haiku", target_os = "linux")) { + println!("cargo:rustc-flags=-l ffi -l ncursesw -l stdc++ -l z"); + } else if cfg!(target_os = "macos") { + println!("cargo:rustc-flags=-l ffi -l ncurses -l c++ -l z"); + } + + cep.discard(); +} diff --git a/third_party/rust/clang-sys/clippy.toml b/third_party/rust/clang-sys/clippy.toml new file mode 100644 index 0000000000..6f41284e10 --- /dev/null +++ b/third_party/rust/clang-sys/clippy.toml @@ -0,0 +1 @@ +doc-valid-idents = ["FreeBSD"] diff --git a/third_party/rust/clang-sys/src/lib.rs b/third_party/rust/clang-sys/src/lib.rs new file mode 100644 index 0000000000..bb1f7bdf15 --- /dev/null +++ b/third_party/rust/clang-sys/src/lib.rs @@ -0,0 +1,2291 @@ +// SPDX-License-Identifier: Apache-2.0 + +//! Rust bindings for `libclang`. +//! +//! ## [Documentation](https://docs.rs/clang-sys) +//! +//! Note that the documentation on https://docs.rs for this crate assumes usage +//! of the `runtime` Cargo feature as well as the Cargo feature for the latest +//! supported version of `libclang` (e.g., `clang_11_0`), neither of which are +//! enabled by default. +//! +//! Due to the usage of the `runtime` Cargo feature, this documentation will +//! contain some additional types and functions to manage a dynamically loaded +//! `libclang` instance at runtime. +//! +//! Due to the usage of the Cargo feature for the latest supported version of +//! `libclang`, this documentation will contain constants and functions that are +//! not available in the oldest supported version of `libclang` (3.5). All of +//! these types and functions have a documentation comment which specifies the +//! minimum `libclang` version required to use the item. + +#![allow(non_camel_case_types, non_snake_case, non_upper_case_globals)] +#![cfg_attr(feature = "cargo-clippy", allow(clippy::unreadable_literal))] + +extern crate glob; +extern crate libc; +#[cfg(feature = "runtime")] +extern crate libloading; + +pub mod support; + +#[macro_use] +mod link; + +use std::mem; + +use libc::*; + +pub type CXClientData = *mut c_void; +pub type CXCursorVisitor = extern "C" fn(CXCursor, CXCursor, CXClientData) -> CXChildVisitResult; +#[cfg(feature = "clang_3_7")] +pub type CXFieldVisitor = extern "C" fn(CXCursor, CXClientData) -> CXVisitorResult; +pub type CXInclusionVisitor = extern "C" fn(CXFile, *mut CXSourceLocation, c_uint, CXClientData); + +//================================================ +// Macros +//================================================ + +/// Defines a C enum as a series of constants. +macro_rules! cenum { + ($(#[$meta:meta])* enum $name:ident { + $($(#[$vmeta:meta])* const $variant:ident = $value:expr), +, + }) => ( + pub type $name = c_int; + + $($(#[$vmeta])* pub const $variant: $name = $value;)+ + ); + ($(#[$meta:meta])* enum $name:ident { + $($(#[$vmeta:meta])* const $variant:ident = $value:expr); +; + }) => ( + pub type $name = c_int; + + $($(#[$vmeta])* pub const $variant: $name = $value;)+ + ); +} + +/// Implements a zeroing implementation of `Default` for the supplied type. +macro_rules! default { + (#[$meta:meta] $ty:ty) => { + #[$meta] + impl Default for $ty { + fn default() -> $ty { + unsafe { mem::zeroed() } + } + } + }; + + ($ty:ty) => { + impl Default for $ty { + fn default() -> $ty { + unsafe { mem::zeroed() } + } + } + }; +} + +//================================================ +// Enums +//================================================ + +cenum! { + enum CXAvailabilityKind { + const CXAvailability_Available = 0, + const CXAvailability_Deprecated = 1, + const CXAvailability_NotAvailable = 2, + const CXAvailability_NotAccessible = 3, + } +} + +cenum! { + enum CXCallingConv { + const CXCallingConv_Default = 0, + const CXCallingConv_C = 1, + const CXCallingConv_X86StdCall = 2, + const CXCallingConv_X86FastCall = 3, + const CXCallingConv_X86ThisCall = 4, + const CXCallingConv_X86Pascal = 5, + const CXCallingConv_AAPCS = 6, + const CXCallingConv_AAPCS_VFP = 7, + /// Only produced by `libclang` 4.0 and later. + const CXCallingConv_X86RegCall = 8, + const CXCallingConv_IntelOclBicc = 9, + const CXCallingConv_Win64 = 10, + const CXCallingConv_X86_64Win64 = 10, + const CXCallingConv_X86_64SysV = 11, + /// Only produced by `libclang` 3.6 and later. + const CXCallingConv_X86VectorCall = 12, + /// Only produced by `libclang` 3.9 and later. + const CXCallingConv_Swift = 13, + /// Only produced by `libclang` 3.9 and later. + const CXCallingConv_PreserveMost = 14, + /// Only produced by `libclang` 3.9 and later. + const CXCallingConv_PreserveAll = 15, + /// Only produced by `libclang` 8.0 and later. + const CXCallingConv_AArch64VectorCall = 16, + const CXCallingConv_Invalid = 100, + const CXCallingConv_Unexposed = 200, + /// Only produced by `libclang` 13.0 and later. + const CXCallingConv_SwiftAsync = 17, + /// Only produced by `libclang` 15.0 and later. + const CXCallingConv_AArch64SVEPCS = 18, + } +} + +cenum! { + enum CXChildVisitResult { + const CXChildVisit_Break = 0, + const CXChildVisit_Continue = 1, + const CXChildVisit_Recurse = 2, + } +} + +cenum! { + enum CXCommentInlineCommandRenderKind { + const CXCommentInlineCommandRenderKind_Normal = 0, + const CXCommentInlineCommandRenderKind_Bold = 1, + const CXCommentInlineCommandRenderKind_Monospaced = 2, + const CXCommentInlineCommandRenderKind_Emphasized = 3, + } +} + +cenum! { + enum CXCommentKind { + const CXComment_Null = 0, + const CXComment_Text = 1, + const CXComment_InlineCommand = 2, + const CXComment_HTMLStartTag = 3, + const CXComment_HTMLEndTag = 4, + const CXComment_Paragraph = 5, + const CXComment_BlockCommand = 6, + const CXComment_ParamCommand = 7, + const CXComment_TParamCommand = 8, + const CXComment_VerbatimBlockCommand = 9, + const CXComment_VerbatimBlockLine = 10, + const CXComment_VerbatimLine = 11, + const CXComment_FullComment = 12, + } +} + +cenum! { + enum CXCommentParamPassDirection { + const CXCommentParamPassDirection_In = 0, + const CXCommentParamPassDirection_Out = 1, + const CXCommentParamPassDirection_InOut = 2, + } +} + +cenum! { + enum CXCompilationDatabase_Error { + const CXCompilationDatabase_NoError = 0, + const CXCompilationDatabase_CanNotLoadDatabase = 1, + } +} + +cenum! { + enum CXCompletionChunkKind { + const CXCompletionChunk_Optional = 0, + const CXCompletionChunk_TypedText = 1, + const CXCompletionChunk_Text = 2, + const CXCompletionChunk_Placeholder = 3, + const CXCompletionChunk_Informative = 4, + const CXCompletionChunk_CurrentParameter = 5, + const CXCompletionChunk_LeftParen = 6, + const CXCompletionChunk_RightParen = 7, + const CXCompletionChunk_LeftBracket = 8, + const CXCompletionChunk_RightBracket = 9, + const CXCompletionChunk_LeftBrace = 10, + const CXCompletionChunk_RightBrace = 11, + const CXCompletionChunk_LeftAngle = 12, + const CXCompletionChunk_RightAngle = 13, + const CXCompletionChunk_Comma = 14, + const CXCompletionChunk_ResultType = 15, + const CXCompletionChunk_Colon = 16, + const CXCompletionChunk_SemiColon = 17, + const CXCompletionChunk_Equal = 18, + const CXCompletionChunk_HorizontalSpace = 19, + const CXCompletionChunk_VerticalSpace = 20, + } +} + +cenum! { + enum CXCursorKind { + const CXCursor_UnexposedDecl = 1, + const CXCursor_StructDecl = 2, + const CXCursor_UnionDecl = 3, + const CXCursor_ClassDecl = 4, + const CXCursor_EnumDecl = 5, + const CXCursor_FieldDecl = 6, + const CXCursor_EnumConstantDecl = 7, + const CXCursor_FunctionDecl = 8, + const CXCursor_VarDecl = 9, + const CXCursor_ParmDecl = 10, + const CXCursor_ObjCInterfaceDecl = 11, + const CXCursor_ObjCCategoryDecl = 12, + const CXCursor_ObjCProtocolDecl = 13, + const CXCursor_ObjCPropertyDecl = 14, + const CXCursor_ObjCIvarDecl = 15, + const CXCursor_ObjCInstanceMethodDecl = 16, + const CXCursor_ObjCClassMethodDecl = 17, + const CXCursor_ObjCImplementationDecl = 18, + const CXCursor_ObjCCategoryImplDecl = 19, + const CXCursor_TypedefDecl = 20, + const CXCursor_CXXMethod = 21, + const CXCursor_Namespace = 22, + const CXCursor_LinkageSpec = 23, + const CXCursor_Constructor = 24, + const CXCursor_Destructor = 25, + const CXCursor_ConversionFunction = 26, + const CXCursor_TemplateTypeParameter = 27, + const CXCursor_NonTypeTemplateParameter = 28, + const CXCursor_TemplateTemplateParameter = 29, + const CXCursor_FunctionTemplate = 30, + const CXCursor_ClassTemplate = 31, + const CXCursor_ClassTemplatePartialSpecialization = 32, + const CXCursor_NamespaceAlias = 33, + const CXCursor_UsingDirective = 34, + const CXCursor_UsingDeclaration = 35, + const CXCursor_TypeAliasDecl = 36, + const CXCursor_ObjCSynthesizeDecl = 37, + const CXCursor_ObjCDynamicDecl = 38, + const CXCursor_CXXAccessSpecifier = 39, + const CXCursor_ObjCSuperClassRef = 40, + const CXCursor_ObjCProtocolRef = 41, + const CXCursor_ObjCClassRef = 42, + const CXCursor_TypeRef = 43, + const CXCursor_CXXBaseSpecifier = 44, + const CXCursor_TemplateRef = 45, + const CXCursor_NamespaceRef = 46, + const CXCursor_MemberRef = 47, + const CXCursor_LabelRef = 48, + const CXCursor_OverloadedDeclRef = 49, + const CXCursor_VariableRef = 50, + const CXCursor_InvalidFile = 70, + const CXCursor_NoDeclFound = 71, + const CXCursor_NotImplemented = 72, + const CXCursor_InvalidCode = 73, + const CXCursor_UnexposedExpr = 100, + const CXCursor_DeclRefExpr = 101, + const CXCursor_MemberRefExpr = 102, + const CXCursor_CallExpr = 103, + const CXCursor_ObjCMessageExpr = 104, + const CXCursor_BlockExpr = 105, + const CXCursor_IntegerLiteral = 106, + const CXCursor_FloatingLiteral = 107, + const CXCursor_ImaginaryLiteral = 108, + const CXCursor_StringLiteral = 109, + const CXCursor_CharacterLiteral = 110, + const CXCursor_ParenExpr = 111, + const CXCursor_UnaryOperator = 112, + const CXCursor_ArraySubscriptExpr = 113, + const CXCursor_BinaryOperator = 114, + const CXCursor_CompoundAssignOperator = 115, + const CXCursor_ConditionalOperator = 116, + const CXCursor_CStyleCastExpr = 117, + const CXCursor_CompoundLiteralExpr = 118, + const CXCursor_InitListExpr = 119, + const CXCursor_AddrLabelExpr = 120, + const CXCursor_StmtExpr = 121, + const CXCursor_GenericSelectionExpr = 122, + const CXCursor_GNUNullExpr = 123, + const CXCursor_CXXStaticCastExpr = 124, + const CXCursor_CXXDynamicCastExpr = 125, + const CXCursor_CXXReinterpretCastExpr = 126, + const CXCursor_CXXConstCastExpr = 127, + const CXCursor_CXXFunctionalCastExpr = 128, + const CXCursor_CXXTypeidExpr = 129, + const CXCursor_CXXBoolLiteralExpr = 130, + const CXCursor_CXXNullPtrLiteralExpr = 131, + const CXCursor_CXXThisExpr = 132, + const CXCursor_CXXThrowExpr = 133, + const CXCursor_CXXNewExpr = 134, + const CXCursor_CXXDeleteExpr = 135, + const CXCursor_UnaryExpr = 136, + const CXCursor_ObjCStringLiteral = 137, + const CXCursor_ObjCEncodeExpr = 138, + const CXCursor_ObjCSelectorExpr = 139, + const CXCursor_ObjCProtocolExpr = 140, + const CXCursor_ObjCBridgedCastExpr = 141, + const CXCursor_PackExpansionExpr = 142, + const CXCursor_SizeOfPackExpr = 143, + const CXCursor_LambdaExpr = 144, + const CXCursor_ObjCBoolLiteralExpr = 145, + const CXCursor_ObjCSelfExpr = 146, + /// Only produced by `libclang` 3.8 and later. + const CXCursor_OMPArraySectionExpr = 147, + /// Only produced by `libclang` 3.9 and later. + const CXCursor_ObjCAvailabilityCheckExpr = 148, + /// Only produced by `libclang` 7.0 and later. + const CXCursor_FixedPointLiteral = 149, + /// Only produced by `libclang` 12.0 and later. + const CXCursor_OMPArrayShapingExpr = 150, + /// Only produced by `libclang` 12.0 and later. + const CXCursor_OMPIteratorExpr = 151, + /// Only produced by `libclang` 12.0 and later. + const CXCursor_CXXAddrspaceCastExpr = 152, + /// Only produced by `libclang` 15.0 and later. + const CXCursor_ConceptSpecializationExpr = 153, + /// Only produced by `libclang` 15.0 and later. + const CXCursor_RequiresExpr = 154, + /// Only produced by `libclang` 16.0 and later. + const CXCursor_CXXParenListInitExpr = 155, + const CXCursor_UnexposedStmt = 200, + const CXCursor_LabelStmt = 201, + const CXCursor_CompoundStmt = 202, + const CXCursor_CaseStmt = 203, + const CXCursor_DefaultStmt = 204, + const CXCursor_IfStmt = 205, + const CXCursor_SwitchStmt = 206, + const CXCursor_WhileStmt = 207, + const CXCursor_DoStmt = 208, + const CXCursor_ForStmt = 209, + const CXCursor_GotoStmt = 210, + const CXCursor_IndirectGotoStmt = 211, + const CXCursor_ContinueStmt = 212, + const CXCursor_BreakStmt = 213, + const CXCursor_ReturnStmt = 214, + /// Duplicate of `CXCursor_GccAsmStmt`. + const CXCursor_AsmStmt = 215, + const CXCursor_ObjCAtTryStmt = 216, + const CXCursor_ObjCAtCatchStmt = 217, + const CXCursor_ObjCAtFinallyStmt = 218, + const CXCursor_ObjCAtThrowStmt = 219, + const CXCursor_ObjCAtSynchronizedStmt = 220, + const CXCursor_ObjCAutoreleasePoolStmt = 221, + const CXCursor_ObjCForCollectionStmt = 222, + const CXCursor_CXXCatchStmt = 223, + const CXCursor_CXXTryStmt = 224, + const CXCursor_CXXForRangeStmt = 225, + const CXCursor_SEHTryStmt = 226, + const CXCursor_SEHExceptStmt = 227, + const CXCursor_SEHFinallyStmt = 228, + const CXCursor_MSAsmStmt = 229, + const CXCursor_NullStmt = 230, + const CXCursor_DeclStmt = 231, + const CXCursor_OMPParallelDirective = 232, + const CXCursor_OMPSimdDirective = 233, + const CXCursor_OMPForDirective = 234, + const CXCursor_OMPSectionsDirective = 235, + const CXCursor_OMPSectionDirective = 236, + const CXCursor_OMPSingleDirective = 237, + const CXCursor_OMPParallelForDirective = 238, + const CXCursor_OMPParallelSectionsDirective = 239, + const CXCursor_OMPTaskDirective = 240, + const CXCursor_OMPMasterDirective = 241, + const CXCursor_OMPCriticalDirective = 242, + const CXCursor_OMPTaskyieldDirective = 243, + const CXCursor_OMPBarrierDirective = 244, + const CXCursor_OMPTaskwaitDirective = 245, + const CXCursor_OMPFlushDirective = 246, + const CXCursor_SEHLeaveStmt = 247, + /// Only produced by `libclang` 3.6 and later. + const CXCursor_OMPOrderedDirective = 248, + /// Only produced by `libclang` 3.6 and later. + const CXCursor_OMPAtomicDirective = 249, + /// Only produced by `libclang` 3.6 and later. + const CXCursor_OMPForSimdDirective = 250, + /// Only produced by `libclang` 3.6 and later. + const CXCursor_OMPParallelForSimdDirective = 251, + /// Only produced by `libclang` 3.6 and later. + const CXCursor_OMPTargetDirective = 252, + /// Only produced by `libclang` 3.6 and later. + const CXCursor_OMPTeamsDirective = 253, + /// Only produced by `libclang` 3.7 and later. + const CXCursor_OMPTaskgroupDirective = 254, + /// Only produced by `libclang` 3.7 and later. + const CXCursor_OMPCancellationPointDirective = 255, + /// Only produced by `libclang` 3.7 and later. + const CXCursor_OMPCancelDirective = 256, + /// Only produced by `libclang` 3.8 and later. + const CXCursor_OMPTargetDataDirective = 257, + /// Only produced by `libclang` 3.8 and later. + const CXCursor_OMPTaskLoopDirective = 258, + /// Only produced by `libclang` 3.8 and later. + const CXCursor_OMPTaskLoopSimdDirective = 259, + /// Only produced by `libclang` 3.8 and later. + const CXCursor_OMPDistributeDirective = 260, + /// Only produced by `libclang` 3.9 and later. + const CXCursor_OMPTargetEnterDataDirective = 261, + /// Only produced by `libclang` 3.9 and later. + const CXCursor_OMPTargetExitDataDirective = 262, + /// Only produced by `libclang` 3.9 and later. + const CXCursor_OMPTargetParallelDirective = 263, + /// Only produced by `libclang` 3.9 and later. + const CXCursor_OMPTargetParallelForDirective = 264, + /// Only produced by `libclang` 3.9 and later. + const CXCursor_OMPTargetUpdateDirective = 265, + /// Only produced by `libclang` 3.9 and later. + const CXCursor_OMPDistributeParallelForDirective = 266, + /// Only produced by `libclang` 3.9 and later. + const CXCursor_OMPDistributeParallelForSimdDirective = 267, + /// Only produced by `libclang` 3.9 and later. + const CXCursor_OMPDistributeSimdDirective = 268, + /// Only produced by `libclang` 3.9 and later. + const CXCursor_OMPTargetParallelForSimdDirective = 269, + /// Only produced by `libclang` 4.0 and later. + const CXCursor_OMPTargetSimdDirective = 270, + /// Only produced by `libclang` 4.0 and later. + const CXCursor_OMPTeamsDistributeDirective = 271, + /// Only produced by `libclang` 4.0 and later. + const CXCursor_OMPTeamsDistributeSimdDirective = 272, + /// Only produced by `libclang` 4.0 and later. + const CXCursor_OMPTeamsDistributeParallelForSimdDirective = 273, + /// Only produced by `libclang` 4.0 and later. + const CXCursor_OMPTeamsDistributeParallelForDirective = 274, + /// Only produced by `libclang` 4.0 and later. + const CXCursor_OMPTargetTeamsDirective = 275, + /// Only produced by `libclang` 4.0 and later. + const CXCursor_OMPTargetTeamsDistributeDirective = 276, + /// Only produced by `libclang` 4.0 and later. + const CXCursor_OMPTargetTeamsDistributeParallelForDirective = 277, + /// Only produced by `libclang` 4.0 and later. + const CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective = 278, + /// Only producer by `libclang` 4.0 and later. + const CXCursor_OMPTargetTeamsDistributeSimdDirective = 279, + /// Only produced by 'libclang' 9.0 and later. + const CXCursor_BuiltinBitCastExpr = 280, + /// Only produced by `libclang` 10.0 and later. + const CXCursor_OMPMasterTaskLoopDirective = 281, + /// Only produced by `libclang` 10.0 and later. + const CXCursor_OMPParallelMasterTaskLoopDirective = 282, + /// Only produced by `libclang` 10.0 and later. + const CXCursor_OMPMasterTaskLoopSimdDirective = 283, + /// Only produced by `libclang` 10.0 and later. + const CXCursor_OMPParallelMasterTaskLoopSimdDirective = 284, + /// Only produced by `libclang` 10.0 and later. + const CXCursor_OMPParallelMasterDirective = 285, + /// Only produced by `libclang` 11.0 and later. + const CXCursor_OMPDepobjDirective = 286, + /// Only produced by `libclang` 11.0 and later. + const CXCursor_OMPScanDirective = 287, + /// Only produced by `libclang` 13.0 and later. + const CXCursor_OMPTileDirective = 288, + /// Only produced by `libclang` 13.0 and later. + const CXCursor_OMPCanonicalLoop = 289, + /// Only produced by `libclang` 13.0 and later. + const CXCursor_OMPInteropDirective = 290, + /// Only produced by `libclang` 13.0 and later. + const CXCursor_OMPDispatchDirective = 291, + /// Only produced by `libclang` 13.0 and later. + const CXCursor_OMPMaskedDirective = 292, + /// Only produced by `libclang` 13.0 and later. + const CXCursor_OMPUnrollDirective = 293, + /// Only produced by `libclang` 14.0 and later. + const CXCursor_OMPMetaDirective = 294, + /// Only produced by `libclang` 14.0 and later. + const CXCursor_OMPGenericLoopDirective = 295, + /// Only produced by `libclang` 15.0 and later. + const CXCursor_OMPTeamsGenericLoopDirective = 296, + /// Only produced by `libclang` 15.0 and later. + const CXCursor_OMPTargetTeamsGenericLoopDirective = 297, + /// Only produced by `libclang` 15.0 and later. + const CXCursor_OMPParallelGenericLoopDirective = 298, + /// Only produced by `libclang` 15.0 and later. + const CXCursor_OMPTargetParallelGenericLoopDirective = 299, + /// Only produced by `libclang` 15.0 and later. + const CXCursor_OMPParallelMaskedDirective = 300, + /// Only produced by `libclang` 15.0 and later. + const CXCursor_OMPMaskedTaskLoopDirective = 301, + /// Only produced by `libclang` 15.0 and later. + const CXCursor_OMPMaskedTaskLoopSimdDirective = 302, + /// Only produced by `libclang` 15.0 and later. + const CXCursor_OMPParallelMaskedTaskLoopDirective = 303, + /// Only produced by `libclang` 15.0 and later. + const CXCursor_OMPParallelMaskedTaskLoopSimdDirective = 304, + /// Only produced by `libclang` 16.0 and later. + const CXCursor_OMPErrorDirective = 305, + #[cfg(not(feature="clang_15_0"))] + const CXCursor_TranslationUnit = 300, + #[cfg(feature="clang_15_0")] + const CXCursor_TranslationUnit = 350, + const CXCursor_UnexposedAttr = 400, + const CXCursor_IBActionAttr = 401, + const CXCursor_IBOutletAttr = 402, + const CXCursor_IBOutletCollectionAttr = 403, + const CXCursor_CXXFinalAttr = 404, + const CXCursor_CXXOverrideAttr = 405, + const CXCursor_AnnotateAttr = 406, + const CXCursor_AsmLabelAttr = 407, + const CXCursor_PackedAttr = 408, + const CXCursor_PureAttr = 409, + const CXCursor_ConstAttr = 410, + const CXCursor_NoDuplicateAttr = 411, + const CXCursor_CUDAConstantAttr = 412, + const CXCursor_CUDADeviceAttr = 413, + const CXCursor_CUDAGlobalAttr = 414, + const CXCursor_CUDAHostAttr = 415, + /// Only produced by `libclang` 3.6 and later. + const CXCursor_CUDASharedAttr = 416, + /// Only produced by `libclang` 3.8 and later. + const CXCursor_VisibilityAttr = 417, + /// Only produced by `libclang` 3.8 and later. + const CXCursor_DLLExport = 418, + /// Only produced by `libclang` 3.8 and later. + const CXCursor_DLLImport = 419, + /// Only produced by `libclang` 8.0 and later. + const CXCursor_NSReturnsRetained = 420, + /// Only produced by `libclang` 8.0 and later. + const CXCursor_NSReturnsNotRetained = 421, + /// Only produced by `libclang` 8.0 and later. + const CXCursor_NSReturnsAutoreleased = 422, + /// Only produced by `libclang` 8.0 and later. + const CXCursor_NSConsumesSelf = 423, + /// Only produced by `libclang` 8.0 and later. + const CXCursor_NSConsumed = 424, + /// Only produced by `libclang` 8.0 and later. + const CXCursor_ObjCException = 425, + /// Only produced by `libclang` 8.0 and later. + const CXCursor_ObjCNSObject = 426, + /// Only produced by `libclang` 8.0 and later. + const CXCursor_ObjCIndependentClass = 427, + /// Only produced by `libclang` 8.0 and later. + const CXCursor_ObjCPreciseLifetime = 428, + /// Only produced by `libclang` 8.0 and later. + const CXCursor_ObjCReturnsInnerPointer = 429, + /// Only produced by `libclang` 8.0 and later. + const CXCursor_ObjCRequiresSuper = 430, + /// Only produced by `libclang` 8.0 and later. + const CXCursor_ObjCRootClass = 431, + /// Only produced by `libclang` 8.0 and later. + const CXCursor_ObjCSubclassingRestricted = 432, + /// Only produced by `libclang` 8.0 and later. + const CXCursor_ObjCExplicitProtocolImpl = 433, + /// Only produced by `libclang` 8.0 and later. + const CXCursor_ObjCDesignatedInitializer = 434, + /// Only produced by `libclang` 8.0 and later. + const CXCursor_ObjCRuntimeVisible = 435, + /// Only produced by `libclang` 8.0 and later. + const CXCursor_ObjCBoxable = 436, + /// Only produced by `libclang` 8.0 and later. + const CXCursor_FlagEnum = 437, + /// Only produced by `libclang` 9.0 and later. + const CXCursor_ConvergentAttr = 438, + /// Only produced by `libclang` 9.0 and later. + const CXCursor_WarnUnusedAttr = 439, + /// Only produced by `libclang` 9.0 and later. + const CXCursor_WarnUnusedResultAttr = 440, + /// Only produced by `libclang` 9.0 and later. + const CXCursor_AlignedAttr = 441, + const CXCursor_PreprocessingDirective = 500, + const CXCursor_MacroDefinition = 501, + /// Duplicate of `CXCursor_MacroInstantiation`. + const CXCursor_MacroExpansion = 502, + const CXCursor_InclusionDirective = 503, + const CXCursor_ModuleImportDecl = 600, + /// Only produced by `libclang` 3.8 and later. + const CXCursor_TypeAliasTemplateDecl = 601, + /// Only produced by `libclang` 3.9 and later. + const CXCursor_StaticAssert = 602, + /// Only produced by `libclang` 4.0 and later. + const CXCursor_FriendDecl = 603, + /// Only produced by `libclang` 15.0 and later. + const CXCursor_ConceptDecl = 604, + /// Only produced by `libclang` 3.7 and later. + const CXCursor_OverloadCandidate = 700, + } +} + +cenum! { + /// Only available on `libclang` 5.0 and later. + #[cfg(feature = "clang_5_0")] + enum CXCursor_ExceptionSpecificationKind { + const CXCursor_ExceptionSpecificationKind_None = 0, + const CXCursor_ExceptionSpecificationKind_DynamicNone = 1, + const CXCursor_ExceptionSpecificationKind_Dynamic = 2, + const CXCursor_ExceptionSpecificationKind_MSAny = 3, + const CXCursor_ExceptionSpecificationKind_BasicNoexcept = 4, + const CXCursor_ExceptionSpecificationKind_ComputedNoexcept = 5, + const CXCursor_ExceptionSpecificationKind_Unevaluated = 6, + const CXCursor_ExceptionSpecificationKind_Uninstantiated = 7, + const CXCursor_ExceptionSpecificationKind_Unparsed = 8, + /// Only available on `libclang` 9.0 and later. + #[cfg(feature = "clang_9_0")] + const CXCursor_ExceptionSpecificationKind_NoThrow = 9, + } +} + +cenum! { + enum CXDiagnosticSeverity { + const CXDiagnostic_Ignored = 0, + const CXDiagnostic_Note = 1, + const CXDiagnostic_Warning = 2, + const CXDiagnostic_Error = 3, + const CXDiagnostic_Fatal = 4, + } +} + +cenum! { + enum CXErrorCode { + const CXError_Success = 0, + const CXError_Failure = 1, + const CXError_Crashed = 2, + const CXError_InvalidArguments = 3, + const CXError_ASTReadError = 4, + } +} + +cenum! { + enum CXEvalResultKind { + const CXEval_UnExposed = 0, + const CXEval_Int = 1 , + const CXEval_Float = 2, + const CXEval_ObjCStrLiteral = 3, + const CXEval_StrLiteral = 4, + const CXEval_CFStr = 5, + const CXEval_Other = 6, + } +} + +cenum! { + enum CXIdxAttrKind { + const CXIdxAttr_Unexposed = 0, + const CXIdxAttr_IBAction = 1, + const CXIdxAttr_IBOutlet = 2, + const CXIdxAttr_IBOutletCollection = 3, + } +} + +cenum! { + enum CXIdxEntityCXXTemplateKind { + const CXIdxEntity_NonTemplate = 0, + const CXIdxEntity_Template = 1, + const CXIdxEntity_TemplatePartialSpecialization = 2, + const CXIdxEntity_TemplateSpecialization = 3, + } +} + +cenum! { + enum CXIdxEntityKind { + const CXIdxEntity_Unexposed = 0, + const CXIdxEntity_Typedef = 1, + const CXIdxEntity_Function = 2, + const CXIdxEntity_Variable = 3, + const CXIdxEntity_Field = 4, + const CXIdxEntity_EnumConstant = 5, + const CXIdxEntity_ObjCClass = 6, + const CXIdxEntity_ObjCProtocol = 7, + const CXIdxEntity_ObjCCategory = 8, + const CXIdxEntity_ObjCInstanceMethod = 9, + const CXIdxEntity_ObjCClassMethod = 10, + const CXIdxEntity_ObjCProperty = 11, + const CXIdxEntity_ObjCIvar = 12, + const CXIdxEntity_Enum = 13, + const CXIdxEntity_Struct = 14, + const CXIdxEntity_Union = 15, + const CXIdxEntity_CXXClass = 16, + const CXIdxEntity_CXXNamespace = 17, + const CXIdxEntity_CXXNamespaceAlias = 18, + const CXIdxEntity_CXXStaticVariable = 19, + const CXIdxEntity_CXXStaticMethod = 20, + const CXIdxEntity_CXXInstanceMethod = 21, + const CXIdxEntity_CXXConstructor = 22, + const CXIdxEntity_CXXDestructor = 23, + const CXIdxEntity_CXXConversionFunction = 24, + const CXIdxEntity_CXXTypeAlias = 25, + const CXIdxEntity_CXXInterface = 26, + /// Only produced by `libclang` 15.0 and later. + const CXIdxEntity_CXXConcept = 27, + } +} + +cenum! { + enum CXIdxEntityLanguage { + const CXIdxEntityLang_None = 0, + const CXIdxEntityLang_C = 1, + const CXIdxEntityLang_ObjC = 2, + const CXIdxEntityLang_CXX = 3, + /// Only produced by `libclang` 5.0 and later. + const CXIdxEntityLang_Swift = 4, + } +} + +cenum! { + enum CXIdxEntityRefKind { + const CXIdxEntityRef_Direct = 1, + const CXIdxEntityRef_Implicit = 2, + } +} + +cenum! { + enum CXIdxObjCContainerKind { + const CXIdxObjCContainer_ForwardRef = 0, + const CXIdxObjCContainer_Interface = 1, + const CXIdxObjCContainer_Implementation = 2, + } +} + +cenum! { + enum CXLanguageKind { + const CXLanguage_Invalid = 0, + const CXLanguage_C = 1, + const CXLanguage_ObjC = 2, + const CXLanguage_CPlusPlus = 3, + } +} + +cenum! { + enum CXLinkageKind { + const CXLinkage_Invalid = 0, + const CXLinkage_NoLinkage = 1, + const CXLinkage_Internal = 2, + const CXLinkage_UniqueExternal = 3, + const CXLinkage_External = 4, + } +} + +cenum! { + enum CXLoadDiag_Error { + const CXLoadDiag_None = 0, + const CXLoadDiag_Unknown = 1, + const CXLoadDiag_CannotLoad = 2, + const CXLoadDiag_InvalidFile = 3, + } +} + +cenum! { + /// Only available on `libclang` 7.0 and later. + #[cfg(feature = "clang_7_0")] + enum CXPrintingPolicyProperty { + const CXPrintingPolicy_Indentation = 0, + const CXPrintingPolicy_SuppressSpecifiers = 1, + const CXPrintingPolicy_SuppressTagKeyword = 2, + const CXPrintingPolicy_IncludeTagDefinition = 3, + const CXPrintingPolicy_SuppressScope = 4, + const CXPrintingPolicy_SuppressUnwrittenScope = 5, + const CXPrintingPolicy_SuppressInitializers = 6, + const CXPrintingPolicy_ConstantArraySizeAsWritten = 7, + const CXPrintingPolicy_AnonymousTagLocations = 8, + const CXPrintingPolicy_SuppressStrongLifetime = 9, + const CXPrintingPolicy_SuppressLifetimeQualifiers = 10, + const CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors = 11, + const CXPrintingPolicy_Bool = 12, + const CXPrintingPolicy_Restrict = 13, + const CXPrintingPolicy_Alignof = 14, + const CXPrintingPolicy_UnderscoreAlignof = 15, + const CXPrintingPolicy_UseVoidForZeroParams = 16, + const CXPrintingPolicy_TerseOutput = 17, + const CXPrintingPolicy_PolishForDeclaration = 18, + const CXPrintingPolicy_Half = 19, + const CXPrintingPolicy_MSWChar = 20, + const CXPrintingPolicy_IncludeNewlines = 21, + const CXPrintingPolicy_MSVCFormatting = 22, + const CXPrintingPolicy_ConstantsAsWritten = 23, + const CXPrintingPolicy_SuppressImplicitBase = 24, + const CXPrintingPolicy_FullyQualifiedName = 25, + } +} + +cenum! { + enum CXRefQualifierKind { + const CXRefQualifier_None = 0, + const CXRefQualifier_LValue = 1, + const CXRefQualifier_RValue = 2, + } +} + +cenum! { + enum CXResult { + const CXResult_Success = 0, + const CXResult_Invalid = 1, + const CXResult_VisitBreak = 2, + } +} + +cenum! { + enum CXSaveError { + const CXSaveError_None = 0, + const CXSaveError_Unknown = 1, + const CXSaveError_TranslationErrors = 2, + const CXSaveError_InvalidTU = 3, + } +} + +cenum! { + /// Only available on `libclang` 6.0 and later. + #[cfg(feature = "clang_6_0")] + enum CXTLSKind { + const CXTLS_None = 0, + const CXTLS_Dynamic = 1, + const CXTLS_Static = 2, + } +} + +cenum! { + enum CXTUResourceUsageKind { + const CXTUResourceUsage_AST = 1, + const CXTUResourceUsage_Identifiers = 2, + const CXTUResourceUsage_Selectors = 3, + const CXTUResourceUsage_GlobalCompletionResults = 4, + const CXTUResourceUsage_SourceManagerContentCache = 5, + const CXTUResourceUsage_AST_SideTables = 6, + const CXTUResourceUsage_SourceManager_Membuffer_Malloc = 7, + const CXTUResourceUsage_SourceManager_Membuffer_MMap = 8, + const CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc = 9, + const CXTUResourceUsage_ExternalASTSource_Membuffer_MMap = 10, + const CXTUResourceUsage_Preprocessor = 11, + const CXTUResourceUsage_PreprocessingRecord = 12, + const CXTUResourceUsage_SourceManager_DataStructures = 13, + const CXTUResourceUsage_Preprocessor_HeaderSearch = 14, + } +} + +cenum! { + /// Only available on `libclang` 3.6 and later. + #[cfg(feature = "clang_3_6")] + enum CXTemplateArgumentKind { + const CXTemplateArgumentKind_Null = 0, + const CXTemplateArgumentKind_Type = 1, + const CXTemplateArgumentKind_Declaration = 2, + const CXTemplateArgumentKind_NullPtr = 3, + const CXTemplateArgumentKind_Integral = 4, + const CXTemplateArgumentKind_Template = 5, + const CXTemplateArgumentKind_TemplateExpansion = 6, + const CXTemplateArgumentKind_Expression = 7, + const CXTemplateArgumentKind_Pack = 8, + const CXTemplateArgumentKind_Invalid = 9, + } +} + +cenum! { + enum CXTokenKind { + const CXToken_Punctuation = 0, + const CXToken_Keyword = 1, + const CXToken_Identifier = 2, + const CXToken_Literal = 3, + const CXToken_Comment = 4, + } +} + +cenum! { + enum CXTypeKind { + const CXType_Invalid = 0, + const CXType_Unexposed = 1, + const CXType_Void = 2, + const CXType_Bool = 3, + const CXType_Char_U = 4, + const CXType_UChar = 5, + const CXType_Char16 = 6, + const CXType_Char32 = 7, + const CXType_UShort = 8, + const CXType_UInt = 9, + const CXType_ULong = 10, + const CXType_ULongLong = 11, + const CXType_UInt128 = 12, + const CXType_Char_S = 13, + const CXType_SChar = 14, + const CXType_WChar = 15, + const CXType_Short = 16, + const CXType_Int = 17, + const CXType_Long = 18, + const CXType_LongLong = 19, + const CXType_Int128 = 20, + const CXType_Float = 21, + const CXType_Double = 22, + const CXType_LongDouble = 23, + const CXType_NullPtr = 24, + const CXType_Overload = 25, + const CXType_Dependent = 26, + const CXType_ObjCId = 27, + const CXType_ObjCClass = 28, + const CXType_ObjCSel = 29, + /// Only produced by `libclang` 3.9 and later. + const CXType_Float128 = 30, + /// Only produced by `libclang` 5.0 and later. + const CXType_Half = 31, + /// Only produced by `libclang` 6.0 and later. + const CXType_Float16 = 32, + /// Only produced by `libclang` 7.0 and later. + const CXType_ShortAccum = 33, + /// Only produced by `libclang` 7.0 and later. + const CXType_Accum = 34, + /// Only produced by `libclang` 7.0 and later. + const CXType_LongAccum = 35, + /// Only produced by `libclang` 7.0 and later. + const CXType_UShortAccum = 36, + /// Only produced by `libclang` 7.0 and later. + const CXType_UAccum = 37, + /// Only produced by `libclang` 7.0 and later. + const CXType_ULongAccum = 38, + /// Only produced by `libclang` 11.0 and later. + const CXType_BFloat16 = 39, + /// Only produced by `libclang` 14.0 and later. + const CXType_Ibm128 = 40, + const CXType_Complex = 100, + const CXType_Pointer = 101, + const CXType_BlockPointer = 102, + const CXType_LValueReference = 103, + const CXType_RValueReference = 104, + const CXType_Record = 105, + const CXType_Enum = 106, + const CXType_Typedef = 107, + const CXType_ObjCInterface = 108, + const CXType_ObjCObjectPointer = 109, + const CXType_FunctionNoProto = 110, + const CXType_FunctionProto = 111, + const CXType_ConstantArray = 112, + const CXType_Vector = 113, + const CXType_IncompleteArray = 114, + const CXType_VariableArray = 115, + const CXType_DependentSizedArray = 116, + const CXType_MemberPointer = 117, + /// Only produced by `libclang` 3.8 and later. + const CXType_Auto = 118, + /// Only produced by `libclang` 3.9 and later. + const CXType_Elaborated = 119, + /// Only produced by `libclang` 5.0 and later. + const CXType_Pipe = 120, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage1dRO = 121, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage1dArrayRO = 122, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage1dBufferRO = 123, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage2dRO = 124, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage2dArrayRO = 125, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage2dDepthRO = 126, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage2dArrayDepthRO = 127, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage2dMSAARO = 128, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage2dArrayMSAARO = 129, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage2dMSAADepthRO = 130, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage2dArrayMSAADepthRO = 131, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage3dRO = 132, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage1dWO = 133, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage1dArrayWO = 134, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage1dBufferWO = 135, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage2dWO = 136, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage2dArrayWO = 137, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage2dDepthWO = 138, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage2dArrayDepthWO = 139, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage2dMSAAWO = 140, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage2dArrayMSAAWO = 141, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage2dMSAADepthWO = 142, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage2dArrayMSAADepthWO = 143, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage3dWO = 144, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage1dRW = 145, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage1dArrayRW = 146, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage1dBufferRW = 147, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage2dRW = 148, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage2dArrayRW = 149, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage2dDepthRW = 150, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage2dArrayDepthRW = 151, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage2dMSAARW = 152, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage2dArrayMSAARW = 153, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage2dMSAADepthRW = 154, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage2dArrayMSAADepthRW = 155, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLImage3dRW = 156, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLSampler = 157, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLEvent = 158, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLQueue = 159, + /// Only produced by `libclang` 5.0 and later. + const CXType_OCLReserveID = 160, + /// Only produced by `libclang` 8.0 and later. + const CXType_ObjCObject = 161, + /// Only produced by `libclang` 8.0 and later. + const CXType_ObjCTypeParam = 162, + /// Only produced by `libclang` 8.0 and later. + const CXType_Attributed = 163, + /// Only produced by `libclang` 8.0 and later. + const CXType_OCLIntelSubgroupAVCMcePayload = 164, + /// Only produced by `libclang` 8.0 and later. + const CXType_OCLIntelSubgroupAVCImePayload = 165, + /// Only produced by `libclang` 8.0 and later. + const CXType_OCLIntelSubgroupAVCRefPayload = 166, + /// Only produced by `libclang` 8.0 and later. + const CXType_OCLIntelSubgroupAVCSicPayload = 167, + /// Only produced by `libclang` 8.0 and later. + const CXType_OCLIntelSubgroupAVCMceResult = 168, + /// Only produced by `libclang` 8.0 and later. + const CXType_OCLIntelSubgroupAVCImeResult = 169, + /// Only produced by `libclang` 8.0 and later. + const CXType_OCLIntelSubgroupAVCRefResult = 170, + /// Only produced by `libclang` 8.0 and later. + const CXType_OCLIntelSubgroupAVCSicResult = 171, + /// Only produced by `libclang` 8.0 and later. + const CXType_OCLIntelSubgroupAVCImeResultSingleRefStreamout = 172, + /// Only produced by `libclang` 8.0 and later. + const CXType_OCLIntelSubgroupAVCImeResultDualRefStreamout = 173, + /// Only produced by `libclang` 8.0 and later. + const CXType_OCLIntelSubgroupAVCImeSingleRefStreamin = 174, + /// Only produced by `libclang` 8.0 and later. + const CXType_OCLIntelSubgroupAVCImeDualRefStreamin = 175, + /// Only produced by `libclang` 9.0 and later. + const CXType_ExtVector = 176, + /// Only produced by `libclang` 11.0 and later. + const CXType_Atomic = 177, + /// Only produced by `libclang` 15.0 and later. + const CXType_BTFTagAttributed = 178, + } +} + +cenum! { + enum CXTypeLayoutError { + const CXTypeLayoutError_Invalid = -1, + const CXTypeLayoutError_Incomplete = -2, + const CXTypeLayoutError_Dependent = -3, + const CXTypeLayoutError_NotConstantSize = -4, + const CXTypeLayoutError_InvalidFieldName = -5, + /// Only produced by `libclang` 9.0 and later. + const CXTypeLayoutError_Undeduced = -6, + } +} + +cenum! { + /// Only available on `libclang` 3.8 and later. + #[cfg(feature = "clang_3_8")] + enum CXVisibilityKind { + const CXVisibility_Invalid = 0, + const CXVisibility_Hidden = 1, + const CXVisibility_Protected = 2, + const CXVisibility_Default = 3, + } +} + +cenum! { + /// Only available on `libclang` 8.0 and later. + #[cfg(feature = "clang_8_0")] + enum CXTypeNullabilityKind { + const CXTypeNullability_NonNull = 0, + const CXTypeNullability_Nullable = 1, + const CXTypeNullability_Unspecified = 2, + const CXTypeNullability_Invalid = 3, + /// Only produced by `libclang` 12.0 and later. + const CXTypeNullability_NullableResult = 4, + } +} + +cenum! { + enum CXVisitorResult { + const CXVisit_Break = 0, + const CXVisit_Continue = 1, + } +} + +cenum! { + enum CX_CXXAccessSpecifier { + const CX_CXXInvalidAccessSpecifier = 0, + const CX_CXXPublic = 1, + const CX_CXXProtected = 2, + const CX_CXXPrivate = 3, + } +} + +cenum! { + /// Only available on `libclang` 3.6 and later. + #[cfg(feature = "clang_3_6")] + enum CX_StorageClass { + const CX_SC_Invalid = 0, + const CX_SC_None = 1, + const CX_SC_Extern = 2, + const CX_SC_Static = 3, + const CX_SC_PrivateExtern = 4, + const CX_SC_OpenCLWorkGroupLocal = 5, + const CX_SC_Auto = 6, + const CX_SC_Register = 7, + } +} + +//================================================ +// Flags +//================================================ + +cenum! { + enum CXCodeComplete_Flags { + const CXCodeComplete_IncludeMacros = 1; + const CXCodeComplete_IncludeCodePatterns = 2; + const CXCodeComplete_IncludeBriefComments = 4; + const CXCodeComplete_SkipPreamble = 8; + const CXCodeComplete_IncludeCompletionsWithFixIts = 16; + } +} + +cenum! { + enum CXCompletionContext { + const CXCompletionContext_Unexposed = 0; + const CXCompletionContext_AnyType = 1; + const CXCompletionContext_AnyValue = 2; + const CXCompletionContext_ObjCObjectValue = 4; + const CXCompletionContext_ObjCSelectorValue = 8; + const CXCompletionContext_CXXClassTypeValue = 16; + const CXCompletionContext_DotMemberAccess = 32; + const CXCompletionContext_ArrowMemberAccess = 64; + const CXCompletionContext_ObjCPropertyAccess = 128; + const CXCompletionContext_EnumTag = 256; + const CXCompletionContext_UnionTag = 512; + const CXCompletionContext_StructTag = 1024; + const CXCompletionContext_ClassTag = 2048; + const CXCompletionContext_Namespace = 4096; + const CXCompletionContext_NestedNameSpecifier = 8192; + const CXCompletionContext_ObjCInterface = 16384; + const CXCompletionContext_ObjCProtocol = 32768; + const CXCompletionContext_ObjCCategory = 65536; + const CXCompletionContext_ObjCInstanceMessage = 131072; + const CXCompletionContext_ObjCClassMessage = 262144; + const CXCompletionContext_ObjCSelectorName = 524288; + const CXCompletionContext_MacroName = 1048576; + const CXCompletionContext_NaturalLanguage = 2097152; + const CXCompletionContext_IncludedFile = 4194304; + const CXCompletionContext_Unknown = 8388607; + } +} + +cenum! { + enum CXDiagnosticDisplayOptions { + const CXDiagnostic_DisplaySourceLocation = 1; + const CXDiagnostic_DisplayColumn = 2; + const CXDiagnostic_DisplaySourceRanges = 4; + const CXDiagnostic_DisplayOption = 8; + const CXDiagnostic_DisplayCategoryId = 16; + const CXDiagnostic_DisplayCategoryName = 32; + } +} + +cenum! { + enum CXGlobalOptFlags { + const CXGlobalOpt_None = 0; + const CXGlobalOpt_ThreadBackgroundPriorityForIndexing = 1; + const CXGlobalOpt_ThreadBackgroundPriorityForEditing = 2; + const CXGlobalOpt_ThreadBackgroundPriorityForAll = 3; + } +} + +cenum! { + enum CXIdxDeclInfoFlags { + const CXIdxDeclFlag_Skipped = 1; + } +} + +cenum! { + enum CXIndexOptFlags { + const CXIndexOptNone = 0; + const CXIndexOptSuppressRedundantRefs = 1; + const CXIndexOptIndexFunctionLocalSymbols = 2; + const CXIndexOptIndexImplicitTemplateInstantiations = 4; + const CXIndexOptSuppressWarnings = 8; + const CXIndexOptSkipParsedBodiesInSession = 16; + } +} + +cenum! { + enum CXNameRefFlags { + const CXNameRange_WantQualifier = 1; + const CXNameRange_WantTemplateArgs = 2; + const CXNameRange_WantSinglePiece = 4; + } +} + +cenum! { + enum CXObjCDeclQualifierKind { + const CXObjCDeclQualifier_None = 0; + const CXObjCDeclQualifier_In = 1; + const CXObjCDeclQualifier_Inout = 2; + const CXObjCDeclQualifier_Out = 4; + const CXObjCDeclQualifier_Bycopy = 8; + const CXObjCDeclQualifier_Byref = 16; + const CXObjCDeclQualifier_Oneway = 32; + } +} + +cenum! { + enum CXObjCPropertyAttrKind { + const CXObjCPropertyAttr_noattr = 0; + const CXObjCPropertyAttr_readonly = 1; + const CXObjCPropertyAttr_getter = 2; + const CXObjCPropertyAttr_assign = 4; + const CXObjCPropertyAttr_readwrite = 8; + const CXObjCPropertyAttr_retain = 16; + const CXObjCPropertyAttr_copy = 32; + const CXObjCPropertyAttr_nonatomic = 64; + const CXObjCPropertyAttr_setter = 128; + const CXObjCPropertyAttr_atomic = 256; + const CXObjCPropertyAttr_weak = 512; + const CXObjCPropertyAttr_strong = 1024; + const CXObjCPropertyAttr_unsafe_unretained = 2048; + /// Only available on `libclang` 3.9 and later. + #[cfg(feature = "clang_3_9")] + const CXObjCPropertyAttr_class = 4096; + } +} + +cenum! { + enum CXReparse_Flags { + const CXReparse_None = 0; + } +} + +cenum! { + enum CXSaveTranslationUnit_Flags { + const CXSaveTranslationUnit_None = 0; + } +} + +cenum! { + /// Only available on `libclang` 7.0 and later. + #[cfg(feature = "clang_7_0")] + enum CXSymbolRole { + const CXSymbolRole_None = 0; + const CXSymbolRole_Declaration = 1; + const CXSymbolRole_Definition = 2; + const CXSymbolRole_Reference = 4; + const CXSymbolRole_Read = 8; + const CXSymbolRole_Write = 16; + const CXSymbolRole_Call = 32; + const CXSymbolRole_Dynamic = 64; + const CXSymbolRole_AddressOf = 128; + const CXSymbolRole_Implicit = 256; + } +} + +cenum! { + enum CXTranslationUnit_Flags { + const CXTranslationUnit_None = 0; + const CXTranslationUnit_DetailedPreprocessingRecord = 1; + const CXTranslationUnit_Incomplete = 2; + const CXTranslationUnit_PrecompiledPreamble = 4; + const CXTranslationUnit_CacheCompletionResults = 8; + const CXTranslationUnit_ForSerialization = 16; + const CXTranslationUnit_CXXChainedPCH = 32; + const CXTranslationUnit_SkipFunctionBodies = 64; + const CXTranslationUnit_IncludeBriefCommentsInCodeCompletion = 128; + /// Only available on `libclang` 3.8 and later. + #[cfg(feature = "clang_3_8")] + const CXTranslationUnit_CreatePreambleOnFirstParse = 256; + /// Only available on `libclang` 3.9 and later. + #[cfg(feature = "clang_3_9")] + const CXTranslationUnit_KeepGoing = 512; + /// Only available on `libclang` 5.0 and later. + #[cfg(feature = "clang_5_0")] + const CXTranslationUnit_SingleFileParse = 1024; + /// Only available on `libclang` 7.0 and later. + #[cfg(feature = "clang_7_0")] + const CXTranslationUnit_LimitSkipFunctionBodiesToPreamble = 2048; + /// Only available on `libclang` 8.0 and later. + #[cfg(feature = "clang_8_0")] + const CXTranslationUnit_IncludeAttributedTypes = 4096; + /// Only available on `libclang` 8.0 and later. + #[cfg(feature = "clang_8_0")] + const CXTranslationUnit_VisitImplicitAttributes = 8192; + /// Only available on `libclang` 9.0 and later. + #[cfg(feature = "clang_9_0")] + const CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles = 16384; + /// Only available on `libclang` 10.0 and later. + #[cfg(feature = "clang_10_0")] + const CXTranslationUnit_RetainExcludedConditionalBlocks = 32768; + } +} + +//================================================ +// Structs +//================================================ + +// Opaque ________________________________________ + +macro_rules! opaque { + ($name:ident) => { + pub type $name = *mut c_void; + }; +} + +opaque!(CXCompilationDatabase); +opaque!(CXCompileCommand); +opaque!(CXCompileCommands); +opaque!(CXCompletionString); +opaque!(CXCursorSet); +opaque!(CXDiagnostic); +opaque!(CXDiagnosticSet); +#[cfg(feature = "clang_3_9")] +opaque!(CXEvalResult); +opaque!(CXFile); +opaque!(CXIdxClientASTFile); +opaque!(CXIdxClientContainer); +opaque!(CXIdxClientEntity); +opaque!(CXIdxClientFile); +opaque!(CXIndex); +opaque!(CXIndexAction); +opaque!(CXModule); +#[cfg(feature = "clang_7_0")] +opaque!(CXPrintingPolicy); +opaque!(CXRemapping); +#[cfg(feature = "clang_5_0")] +opaque!(CXTargetInfo); +opaque!(CXTranslationUnit); + +// Transparent ___________________________________ + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXCodeCompleteResults { + pub Results: *mut CXCompletionResult, + pub NumResults: c_uint, +} + +default!(CXCodeCompleteResults); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXComment { + pub ASTNode: *const c_void, + pub TranslationUnit: CXTranslationUnit, +} + +default!(CXComment); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXCompletionResult { + pub CursorKind: CXCursorKind, + pub CompletionString: CXCompletionString, +} + +default!(CXCompletionResult); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXCursor { + pub kind: CXCursorKind, + pub xdata: c_int, + pub data: [*const c_void; 3], +} + +default!(CXCursor); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXCursorAndRangeVisitor { + pub context: *mut c_void, + pub visit: Option CXVisitorResult>, +} + +default!(CXCursorAndRangeVisitor); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXFileUniqueID { + pub data: [c_ulonglong; 3], +} + +default!(CXFileUniqueID); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXIdxAttrInfo { + pub kind: CXIdxAttrKind, + pub cursor: CXCursor, + pub loc: CXIdxLoc, +} + +default!(CXIdxAttrInfo); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXIdxBaseClassInfo { + pub base: *const CXIdxEntityInfo, + pub cursor: CXCursor, + pub loc: CXIdxLoc, +} + +default!(CXIdxBaseClassInfo); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXIdxCXXClassDeclInfo { + pub declInfo: *const CXIdxDeclInfo, + pub bases: *const *const CXIdxBaseClassInfo, + pub numBases: c_uint, +} + +default!(CXIdxCXXClassDeclInfo); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXIdxContainerInfo { + pub cursor: CXCursor, +} + +default!(CXIdxContainerInfo); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXIdxDeclInfo { + pub entityInfo: *const CXIdxEntityInfo, + pub cursor: CXCursor, + pub loc: CXIdxLoc, + pub semanticContainer: *const CXIdxContainerInfo, + pub lexicalContainer: *const CXIdxContainerInfo, + pub isRedeclaration: c_int, + pub isDefinition: c_int, + pub isContainer: c_int, + pub declAsContainer: *const CXIdxContainerInfo, + pub isImplicit: c_int, + pub attributes: *const *const CXIdxAttrInfo, + pub numAttributes: c_uint, + pub flags: c_uint, +} + +default!(CXIdxDeclInfo); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXIdxEntityInfo { + pub kind: CXIdxEntityKind, + pub templateKind: CXIdxEntityCXXTemplateKind, + pub lang: CXIdxEntityLanguage, + pub name: *const c_char, + pub USR: *const c_char, + pub cursor: CXCursor, + pub attributes: *const *const CXIdxAttrInfo, + pub numAttributes: c_uint, +} + +default!(CXIdxEntityInfo); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXIdxEntityRefInfo { + pub kind: CXIdxEntityRefKind, + pub cursor: CXCursor, + pub loc: CXIdxLoc, + pub referencedEntity: *const CXIdxEntityInfo, + pub parentEntity: *const CXIdxEntityInfo, + pub container: *const CXIdxContainerInfo, + /// Only available on `libclang` 7.0 and later. + #[cfg(feature = "clang_7_0")] + pub role: CXSymbolRole, +} + +default!(CXIdxEntityRefInfo); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXIdxIBOutletCollectionAttrInfo { + pub attrInfo: *const CXIdxAttrInfo, + pub objcClass: *const CXIdxEntityInfo, + pub classCursor: CXCursor, + pub classLoc: CXIdxLoc, +} + +default!(CXIdxIBOutletCollectionAttrInfo); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXIdxImportedASTFileInfo { + pub file: CXFile, + pub module: CXModule, + pub loc: CXIdxLoc, + pub isImplicit: c_int, +} + +default!(CXIdxImportedASTFileInfo); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXIdxIncludedFileInfo { + pub hashLoc: CXIdxLoc, + pub filename: *const c_char, + pub file: CXFile, + pub isImport: c_int, + pub isAngled: c_int, + pub isModuleImport: c_int, +} + +default!(CXIdxIncludedFileInfo); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXIdxLoc { + pub ptr_data: [*mut c_void; 2], + pub int_data: c_uint, +} + +default!(CXIdxLoc); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXIdxObjCCategoryDeclInfo { + pub containerInfo: *const CXIdxObjCContainerDeclInfo, + pub objcClass: *const CXIdxEntityInfo, + pub classCursor: CXCursor, + pub classLoc: CXIdxLoc, + pub protocols: *const CXIdxObjCProtocolRefListInfo, +} + +default!(CXIdxObjCCategoryDeclInfo); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXIdxObjCContainerDeclInfo { + pub declInfo: *const CXIdxDeclInfo, + pub kind: CXIdxObjCContainerKind, +} + +default!(CXIdxObjCContainerDeclInfo); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXIdxObjCInterfaceDeclInfo { + pub containerInfo: *const CXIdxObjCContainerDeclInfo, + pub superInfo: *const CXIdxBaseClassInfo, + pub protocols: *const CXIdxObjCProtocolRefListInfo, +} + +default!(CXIdxObjCInterfaceDeclInfo); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXIdxObjCPropertyDeclInfo { + pub declInfo: *const CXIdxDeclInfo, + pub getter: *const CXIdxEntityInfo, + pub setter: *const CXIdxEntityInfo, +} + +default!(CXIdxObjCPropertyDeclInfo); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXIdxObjCProtocolRefInfo { + pub protocol: *const CXIdxEntityInfo, + pub cursor: CXCursor, + pub loc: CXIdxLoc, +} + +default!(CXIdxObjCProtocolRefInfo); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXIdxObjCProtocolRefListInfo { + pub protocols: *const *const CXIdxObjCProtocolRefInfo, + pub numProtocols: c_uint, +} + +default!(CXIdxObjCProtocolRefListInfo); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXPlatformAvailability { + pub Platform: CXString, + pub Introduced: CXVersion, + pub Deprecated: CXVersion, + pub Obsoleted: CXVersion, + pub Unavailable: c_int, + pub Message: CXString, +} + +default!(CXPlatformAvailability); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXSourceLocation { + pub ptr_data: [*const c_void; 2], + pub int_data: c_uint, +} + +default!(CXSourceLocation); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXSourceRange { + pub ptr_data: [*const c_void; 2], + pub begin_int_data: c_uint, + pub end_int_data: c_uint, +} + +default!(CXSourceRange); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXSourceRangeList { + pub count: c_uint, + pub ranges: *mut CXSourceRange, +} + +default!(CXSourceRangeList); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXString { + pub data: *const c_void, + pub private_flags: c_uint, +} + +default!(CXString); + +#[cfg(feature = "clang_3_8")] +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXStringSet { + pub Strings: *mut CXString, + pub Count: c_uint, +} + +#[cfg(feature = "clang_3_8")] +default!(CXStringSet); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXTUResourceUsage { + pub data: *mut c_void, + pub numEntries: c_uint, + pub entries: *mut CXTUResourceUsageEntry, +} + +default!(CXTUResourceUsage); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXTUResourceUsageEntry { + pub kind: CXTUResourceUsageKind, + pub amount: c_ulong, +} + +default!(CXTUResourceUsageEntry); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXToken { + pub int_data: [c_uint; 4], + pub ptr_data: *mut c_void, +} + +default!(CXToken); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXType { + pub kind: CXTypeKind, + pub data: [*mut c_void; 2], +} + +default!(CXType); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXUnsavedFile { + pub Filename: *const c_char, + pub Contents: *const c_char, + pub Length: c_ulong, +} + +default!(CXUnsavedFile); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CXVersion { + pub Major: c_int, + pub Minor: c_int, + pub Subminor: c_int, +} + +default!(CXVersion); + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +#[rustfmt::skip] +pub struct IndexerCallbacks { + pub abortQuery: Option c_int>, + pub diagnostic: Option, + pub enteredMainFile: Option CXIdxClientFile>, + pub ppIncludedFile: Option CXIdxClientFile>, + pub importedASTFile: Option CXIdxClientASTFile>, + pub startedTranslationUnit: Option CXIdxClientContainer>, + pub indexDeclaration: Option, + pub indexEntityReference: Option, +} + +default!(IndexerCallbacks); + +//================================================ +// Functions +//================================================ + +link! { + pub fn clang_CXCursorSet_contains(set: CXCursorSet, cursor: CXCursor) -> c_uint; + pub fn clang_CXCursorSet_insert(set: CXCursorSet, cursor: CXCursor) -> c_uint; + pub fn clang_CXIndex_getGlobalOptions(index: CXIndex) -> CXGlobalOptFlags; + pub fn clang_CXIndex_setGlobalOptions(index: CXIndex, flags: CXGlobalOptFlags); + /// Only available on `libclang` 6.0 and later. + #[cfg(feature = "clang_6_0")] + pub fn clang_CXIndex_setInvocationEmissionPathOption(index: CXIndex, path: *const c_char); + /// Only available on `libclang` 3.9 and later. + #[cfg(feature = "clang_3_9")] + pub fn clang_CXXConstructor_isConvertingConstructor(cursor: CXCursor) -> c_uint; + /// Only available on `libclang` 3.9 and later. + #[cfg(feature = "clang_3_9")] + pub fn clang_CXXConstructor_isCopyConstructor(cursor: CXCursor) -> c_uint; + /// Only available on `libclang` 3.9 and later. + #[cfg(feature = "clang_3_9")] + pub fn clang_CXXConstructor_isDefaultConstructor(cursor: CXCursor) -> c_uint; + /// Only available on `libclang` 3.9 and later. + #[cfg(feature = "clang_3_9")] + pub fn clang_CXXConstructor_isMoveConstructor(cursor: CXCursor) -> c_uint; + /// Only available on `libclang` 3.8 and later. + #[cfg(feature = "clang_3_8")] + pub fn clang_CXXField_isMutable(cursor: CXCursor) -> c_uint; + pub fn clang_CXXMethod_isConst(cursor: CXCursor) -> c_uint; + /// Only available on `libclang` 16.0 and later. + #[cfg(feature = "clang_16_0")] + pub fn clang_CXXMethod_isCopyAssignmentOperator(cursor: CXCursor) -> c_uint; + /// Only available on `libclang` 3.9 and later. + #[cfg(feature = "clang_3_9")] + pub fn clang_CXXMethod_isDefaulted(cursor: CXCursor) -> c_uint; + /// Only available on `libclang` 16.0 and later. + #[cfg(feature = "clang_16_0")] + pub fn clang_CXXMethod_isDeleted(cursor: CXCursor) -> c_uint; + /// Only available on `libclang` 16.0 and later. + #[cfg(feature = "clang_16_0")] + pub fn clang_CXXMethod_isMoveAssignmentOperator(cursor: CXCursor) -> c_uint; + pub fn clang_CXXMethod_isPureVirtual(cursor: CXCursor) -> c_uint; + pub fn clang_CXXMethod_isStatic(cursor: CXCursor) -> c_uint; + pub fn clang_CXXMethod_isVirtual(cursor: CXCursor) -> c_uint; + /// Only available on `libclang` 6.0 and later. + #[cfg(feature = "clang_6_0")] + pub fn clang_CXXRecord_isAbstract(cursor: CXCursor) -> c_uint; + pub fn clang_CompilationDatabase_dispose(database: CXCompilationDatabase); + pub fn clang_CompilationDatabase_fromDirectory(directory: *const c_char, error: *mut CXCompilationDatabase_Error) -> CXCompilationDatabase; + pub fn clang_CompilationDatabase_getAllCompileCommands(database: CXCompilationDatabase) -> CXCompileCommands; + pub fn clang_CompilationDatabase_getCompileCommands(database: CXCompilationDatabase, filename: *const c_char) -> CXCompileCommands; + pub fn clang_CompileCommand_getArg(command: CXCompileCommand, index: c_uint) -> CXString; + pub fn clang_CompileCommand_getDirectory(command: CXCompileCommand) -> CXString; + /// Only available on `libclang` 3.8 and later. + #[cfg(feature = "clang_3_8")] + pub fn clang_CompileCommand_getFilename(command: CXCompileCommand) -> CXString; + /// Only available on `libclang` 3.8 and later. + #[cfg(feature = "clang_3_8")] + pub fn clang_CompileCommand_getMappedSourceContent(command: CXCompileCommand, index: c_uint) -> CXString; + /// Only available on `libclang` 3.8 and later. + #[cfg(feature = "clang_3_8")] + pub fn clang_CompileCommand_getMappedSourcePath(command: CXCompileCommand, index: c_uint) -> CXString; + pub fn clang_CompileCommand_getNumArgs(command: CXCompileCommand) -> c_uint; + pub fn clang_CompileCommand_getNumMappedSources(command: CXCompileCommand) -> c_uint; + pub fn clang_CompileCommands_dispose(command: CXCompileCommands); + pub fn clang_CompileCommands_getCommand(command: CXCompileCommands, index: c_uint) -> CXCompileCommand; + pub fn clang_CompileCommands_getSize(command: CXCompileCommands) -> c_uint; + /// Only available on `libclang` 3.9 and later. + #[cfg(feature = "clang_3_9")] + pub fn clang_Cursor_Evaluate(cursor: CXCursor) -> CXEvalResult; + pub fn clang_Cursor_getArgument(cursor: CXCursor, index: c_uint) -> CXCursor; + pub fn clang_Cursor_getBriefCommentText(cursor: CXCursor) -> CXString; + /// Only available on `libclang` 3.8 and later. + #[cfg(feature = "clang_3_8")] + pub fn clang_Cursor_getCXXManglings(cursor: CXCursor) -> *mut CXStringSet; + pub fn clang_Cursor_getCommentRange(cursor: CXCursor) -> CXSourceRange; + /// Only available on `libclang` 3.6 and later. + #[cfg(feature = "clang_3_6")] + pub fn clang_Cursor_getMangling(cursor: CXCursor) -> CXString; + pub fn clang_Cursor_getModule(cursor: CXCursor) -> CXModule; + pub fn clang_Cursor_getNumArguments(cursor: CXCursor) -> c_int; + /// Only available on `libclang` 3.6 and later. + #[cfg(feature = "clang_3_6")] + pub fn clang_Cursor_getNumTemplateArguments(cursor: CXCursor) -> c_int; + pub fn clang_Cursor_getObjCDeclQualifiers(cursor: CXCursor) -> CXObjCDeclQualifierKind; + /// Only available on `libclang` 6.0 and later. + #[cfg(feature = "clang_6_0")] + pub fn clang_Cursor_getObjCManglings(cursor: CXCursor) -> *mut CXStringSet; + pub fn clang_Cursor_getObjCPropertyAttributes(cursor: CXCursor, reserved: c_uint) -> CXObjCPropertyAttrKind; + /// Only available on `libclang` 8.0 and later. + #[cfg(feature = "clang_8_0")] + pub fn clang_Cursor_getObjCPropertyGetterName(cursor: CXCursor) -> CXString; + /// Only available on `libclang` 8.0 and later. + #[cfg(feature = "clang_8_0")] + pub fn clang_Cursor_getObjCPropertySetterName(cursor: CXCursor) -> CXString; + pub fn clang_Cursor_getObjCSelectorIndex(cursor: CXCursor) -> c_int; + /// Only available on `libclang` 3.7 and later. + #[cfg(feature = "clang_3_7")] + pub fn clang_Cursor_getOffsetOfField(cursor: CXCursor) -> c_longlong; + pub fn clang_Cursor_getRawCommentText(cursor: CXCursor) -> CXString; + pub fn clang_Cursor_getReceiverType(cursor: CXCursor) -> CXType; + pub fn clang_Cursor_getSpellingNameRange(cursor: CXCursor, index: c_uint, reserved: c_uint) -> CXSourceRange; + /// Only available on `libclang` 3.6 and later. + #[cfg(feature = "clang_3_6")] + pub fn clang_Cursor_getStorageClass(cursor: CXCursor) -> CX_StorageClass; + /// Only available on `libclang` 3.6 and later. + #[cfg(feature = "clang_3_6")] + pub fn clang_Cursor_getTemplateArgumentKind(cursor: CXCursor, index: c_uint) -> CXTemplateArgumentKind; + /// Only available on `libclang` 3.6 and later. + #[cfg(feature = "clang_3_6")] + pub fn clang_Cursor_getTemplateArgumentType(cursor: CXCursor, index: c_uint) -> CXType; + /// Only available on `libclang` 3.6 and later. + #[cfg(feature = "clang_3_6")] + pub fn clang_Cursor_getTemplateArgumentUnsignedValue(cursor: CXCursor, index: c_uint) -> c_ulonglong; + /// Only available on `libclang` 3.6 and later. + #[cfg(feature = "clang_3_6")] + pub fn clang_Cursor_getTemplateArgumentValue(cursor: CXCursor, index: c_uint) -> c_longlong; + pub fn clang_Cursor_getTranslationUnit(cursor: CXCursor) -> CXTranslationUnit; + /// Only available on `libclang` 12.0 and later. + #[cfg(feature = "clang_12_0")] + pub fn clang_Cursor_getVarDeclInitializer(cursor: CXCursor) -> CXCursor; + /// Only available on `libclang` 3.9 and later. + #[cfg(feature = "clang_3_9")] + pub fn clang_Cursor_hasAttrs(cursor: CXCursor) -> c_uint; + /// Only available on `libclang` 12.0 and later. + #[cfg(feature = "clang_12_0")] + pub fn clang_Cursor_hasVarDeclGlobalStorage(cursor: CXCursor) -> c_uint; + /// Only available on `libclang` 12.0 and later. + #[cfg(feature = "clang_12_0")] + pub fn clang_Cursor_hasVarDeclExternalStorage(cursor: CXCursor) -> c_uint; + /// Only available on `libclang` 3.7 and later. + #[cfg(feature = "clang_3_7")] + pub fn clang_Cursor_isAnonymous(cursor: CXCursor) -> c_uint; + /// Only available on `libclang` 9.0 and later. + #[cfg(feature = "clang_9_0")] + pub fn clang_Cursor_isAnonymousRecordDecl(cursor: CXCursor) -> c_uint; + pub fn clang_Cursor_isBitField(cursor: CXCursor) -> c_uint; + pub fn clang_Cursor_isDynamicCall(cursor: CXCursor) -> c_int; + /// Only available on `libclang` 5.0 and later. + #[cfg(feature = "clang_5_0")] + pub fn clang_Cursor_isExternalSymbol(cursor: CXCursor, language: *mut CXString, from: *mut CXString, generated: *mut c_uint) -> c_uint; + /// Only available on `libclang` 3.9 and later. + #[cfg(feature = "clang_3_9")] + pub fn clang_Cursor_isFunctionInlined(cursor: CXCursor) -> c_uint; + /// Only available on `libclang` 9.0 and later. + #[cfg(feature = "clang_9_0")] + pub fn clang_Cursor_isInlineNamespace(cursor: CXCursor) -> c_uint; + /// Only available on `libclang` 3.9 and later. + #[cfg(feature = "clang_3_9")] + pub fn clang_Cursor_isMacroBuiltin(cursor: CXCursor) -> c_uint; + /// Only available on `libclang` 3.9 and later. + #[cfg(feature = "clang_3_9")] + pub fn clang_Cursor_isMacroFunctionLike(cursor: CXCursor) -> c_uint; + pub fn clang_Cursor_isNull(cursor: CXCursor) -> c_int; + pub fn clang_Cursor_isObjCOptional(cursor: CXCursor) -> c_uint; + pub fn clang_Cursor_isVariadic(cursor: CXCursor) -> c_uint; + /// Only available on `libclang` 5.0 and later. + #[cfg(feature = "clang_5_0")] + pub fn clang_EnumDecl_isScoped(cursor: CXCursor) -> c_uint; + /// Only available on `libclang` 3.9 and later. + #[cfg(feature = "clang_3_9")] + pub fn clang_EvalResult_dispose(result: CXEvalResult); + /// Only available on `libclang` 3.9 and later. + #[cfg(feature = "clang_3_9")] + pub fn clang_EvalResult_getAsDouble(result: CXEvalResult) -> libc::c_double; + /// Only available on `libclang` 3.9 and later. + #[cfg(feature = "clang_3_9")] + pub fn clang_EvalResult_getAsInt(result: CXEvalResult) -> c_int; + /// Only available on `libclang` 4.0 and later. + #[cfg(feature = "clang_4_0")] + pub fn clang_EvalResult_getAsLongLong(result: CXEvalResult) -> c_longlong; + /// Only available on `libclang` 3.9 and later. + #[cfg(feature = "clang_3_9")] + pub fn clang_EvalResult_getAsStr(result: CXEvalResult) -> *const c_char; + /// Only available on `libclang` 4.0 and later. + #[cfg(feature = "clang_4_0")] + pub fn clang_EvalResult_getAsUnsigned(result: CXEvalResult) -> c_ulonglong; + /// Only available on `libclang` 3.9 and later. + #[cfg(feature = "clang_3_9")] + pub fn clang_EvalResult_getKind(result: CXEvalResult) -> CXEvalResultKind; + /// Only available on `libclang` 4.0 and later. + #[cfg(feature = "clang_4_0")] + pub fn clang_EvalResult_isUnsignedInt(result: CXEvalResult) -> c_uint; + /// Only available on `libclang` 3.6 and later. + #[cfg(feature = "clang_3_6")] + pub fn clang_File_isEqual(left: CXFile, right: CXFile) -> c_int; + /// Only available on `libclang` 7.0 and later. + #[cfg(feature = "clang_7_0")] + pub fn clang_File_tryGetRealPathName(file: CXFile) -> CXString; + pub fn clang_IndexAction_create(index: CXIndex) -> CXIndexAction; + pub fn clang_IndexAction_dispose(index: CXIndexAction); + pub fn clang_Location_isFromMainFile(location: CXSourceLocation) -> c_int; + pub fn clang_Location_isInSystemHeader(location: CXSourceLocation) -> c_int; + pub fn clang_Module_getASTFile(module: CXModule) -> CXFile; + pub fn clang_Module_getFullName(module: CXModule) -> CXString; + pub fn clang_Module_getName(module: CXModule) -> CXString; + pub fn clang_Module_getNumTopLevelHeaders(tu: CXTranslationUnit, module: CXModule) -> c_uint; + pub fn clang_Module_getParent(module: CXModule) -> CXModule; + pub fn clang_Module_getTopLevelHeader(tu: CXTranslationUnit, module: CXModule, index: c_uint) -> CXFile; + pub fn clang_Module_isSystem(module: CXModule) -> c_int; + /// Only available on `libclang` 7.0 and later. + #[cfg(feature = "clang_7_0")] + pub fn clang_PrintingPolicy_dispose(policy: CXPrintingPolicy); + /// Only available on `libclang` 7.0 and later. + #[cfg(feature = "clang_7_0")] + pub fn clang_PrintingPolicy_getProperty(policy: CXPrintingPolicy, property: CXPrintingPolicyProperty) -> c_uint; + /// Only available on `libclang` 7.0 and later. + #[cfg(feature = "clang_7_0")] + pub fn clang_PrintingPolicy_setProperty(policy: CXPrintingPolicy, property: CXPrintingPolicyProperty, value: c_uint); + pub fn clang_Range_isNull(range: CXSourceRange) -> c_int; + /// Only available on `libclang` 5.0 and later. + #[cfg(feature = "clang_5_0")] + pub fn clang_TargetInfo_dispose(info: CXTargetInfo); + /// Only available on `libclang` 5.0 and later. + #[cfg(feature = "clang_5_0")] + pub fn clang_TargetInfo_getPointerWidth(info: CXTargetInfo) -> c_int; + /// Only available on `libclang` 5.0 and later. + #[cfg(feature = "clang_5_0")] + pub fn clang_TargetInfo_getTriple(info: CXTargetInfo) -> CXString; + pub fn clang_Type_getAlignOf(type_: CXType) -> c_longlong; + pub fn clang_Type_getCXXRefQualifier(type_: CXType) -> CXRefQualifierKind; + pub fn clang_Type_getClassType(type_: CXType) -> CXType; + /// Only available on `libclang` 8.0 and later. + #[cfg(feature = "clang_8_0")] + pub fn clang_Type_getModifiedType(type_: CXType) -> CXType; + /// Only available on `libclang` 3.9 and later. + #[cfg(feature = "clang_3_9")] + pub fn clang_Type_getNamedType(type_: CXType) -> CXType; + /// Only available on `libclang` 8.0 and later. + #[cfg(feature = "clang_8_0")] + pub fn clang_Type_getNullability(type_: CXType) -> CXTypeNullabilityKind; + /// Only available on `libclang` 8.0 and later. + #[cfg(feature = "clang_8_0")] + pub fn clang_Type_getNumObjCProtocolRefs(type_: CXType) -> c_uint; + /// Only available on `libclang` 8.0 and later. + #[cfg(feature = "clang_8_0")] + pub fn clang_Type_getNumObjCTypeArgs(type_: CXType) -> c_uint; + pub fn clang_Type_getNumTemplateArguments(type_: CXType) -> c_int; + /// Only available on `libclang` 3.9 and later. + #[cfg(feature = "clang_3_9")] + pub fn clang_Type_getObjCEncoding(type_: CXType) -> CXString; + /// Only available on `libclang` 8.0 and later. + #[cfg(feature = "clang_8_0")] + pub fn clang_Type_getObjCObjectBaseType(type_: CXType) -> CXType; + /// Only available on `libclang` 8.0 and later. + #[cfg(feature = "clang_8_0")] + pub fn clang_Type_getObjCProtocolDecl(type_: CXType, index: c_uint) -> CXCursor; + /// Only available on `libclang` 8.0 and later. + #[cfg(feature = "clang_8_0")] + pub fn clang_Type_getObjCTypeArg(type_: CXType, index: c_uint) -> CXType; + pub fn clang_Type_getOffsetOf(type_: CXType, field: *const c_char) -> c_longlong; + pub fn clang_Type_getSizeOf(type_: CXType) -> c_longlong; + pub fn clang_Type_getTemplateArgumentAsType(type_: CXType, index: c_uint) -> CXType; + /// Only available on `libclang` 11.0 and later. + #[cfg(feature = "clang_11_0")] + pub fn clang_Type_getValueType(type_: CXType) -> CXType; + /// Only available on `libclang` 5.0 and later. + #[cfg(feature = "clang_5_0")] + pub fn clang_Type_isTransparentTagTypedef(type_: CXType) -> c_uint; + /// Only available on `libclang` 3.7 and later. + #[cfg(feature = "clang_3_7")] + pub fn clang_Type_visitFields(type_: CXType, visitor: CXFieldVisitor, data: CXClientData) -> CXVisitorResult; + pub fn clang_annotateTokens(tu: CXTranslationUnit, tokens: *mut CXToken, n_tokens: c_uint, cursors: *mut CXCursor); + pub fn clang_codeCompleteAt(tu: CXTranslationUnit, file: *const c_char, line: c_uint, column: c_uint, unsaved: *mut CXUnsavedFile, n_unsaved: c_uint, flags: CXCodeComplete_Flags) -> *mut CXCodeCompleteResults; + pub fn clang_codeCompleteGetContainerKind(results: *mut CXCodeCompleteResults, incomplete: *mut c_uint) -> CXCursorKind; + pub fn clang_codeCompleteGetContainerUSR(results: *mut CXCodeCompleteResults) -> CXString; + pub fn clang_codeCompleteGetContexts(results: *mut CXCodeCompleteResults) -> c_ulonglong; + pub fn clang_codeCompleteGetDiagnostic(results: *mut CXCodeCompleteResults, index: c_uint) -> CXDiagnostic; + pub fn clang_codeCompleteGetNumDiagnostics(results: *mut CXCodeCompleteResults) -> c_uint; + pub fn clang_codeCompleteGetObjCSelector(results: *mut CXCodeCompleteResults) -> CXString; + pub fn clang_constructUSR_ObjCCategory(class: *const c_char, category: *const c_char) -> CXString; + pub fn clang_constructUSR_ObjCClass(class: *const c_char) -> CXString; + pub fn clang_constructUSR_ObjCIvar(name: *const c_char, usr: CXString) -> CXString; + pub fn clang_constructUSR_ObjCMethod(name: *const c_char, instance: c_uint, usr: CXString) -> CXString; + pub fn clang_constructUSR_ObjCProperty(property: *const c_char, usr: CXString) -> CXString; + pub fn clang_constructUSR_ObjCProtocol(protocol: *const c_char) -> CXString; + pub fn clang_createCXCursorSet() -> CXCursorSet; + pub fn clang_createIndex(exclude: c_int, display: c_int) -> CXIndex; + pub fn clang_createTranslationUnit(index: CXIndex, file: *const c_char) -> CXTranslationUnit; + pub fn clang_createTranslationUnit2(index: CXIndex, file: *const c_char, tu: *mut CXTranslationUnit) -> CXErrorCode; + pub fn clang_createTranslationUnitFromSourceFile(index: CXIndex, file: *const c_char, n_arguments: c_int, arguments: *const *const c_char, n_unsaved: c_uint, unsaved: *mut CXUnsavedFile) -> CXTranslationUnit; + pub fn clang_defaultCodeCompleteOptions() -> CXCodeComplete_Flags; + pub fn clang_defaultDiagnosticDisplayOptions() -> CXDiagnosticDisplayOptions; + pub fn clang_defaultEditingTranslationUnitOptions() -> CXTranslationUnit_Flags; + pub fn clang_defaultReparseOptions(tu: CXTranslationUnit) -> CXReparse_Flags; + pub fn clang_defaultSaveOptions(tu: CXTranslationUnit) -> CXSaveTranslationUnit_Flags; + pub fn clang_disposeCXCursorSet(set: CXCursorSet); + pub fn clang_disposeCXPlatformAvailability(availability: *mut CXPlatformAvailability); + pub fn clang_disposeCXTUResourceUsage(usage: CXTUResourceUsage); + pub fn clang_disposeCodeCompleteResults(results: *mut CXCodeCompleteResults); + pub fn clang_disposeDiagnostic(diagnostic: CXDiagnostic); + pub fn clang_disposeDiagnosticSet(diagnostic: CXDiagnosticSet); + pub fn clang_disposeIndex(index: CXIndex); + pub fn clang_disposeOverriddenCursors(cursors: *mut CXCursor); + pub fn clang_disposeSourceRangeList(list: *mut CXSourceRangeList); + pub fn clang_disposeString(string: CXString); + /// Only available on `libclang` 3.8 and later. + #[cfg(feature = "clang_3_8")] + pub fn clang_disposeStringSet(set: *mut CXStringSet); + pub fn clang_disposeTokens(tu: CXTranslationUnit, tokens: *mut CXToken, n_tokens: c_uint); + pub fn clang_disposeTranslationUnit(tu: CXTranslationUnit); + pub fn clang_enableStackTraces(); + pub fn clang_equalCursors(left: CXCursor, right: CXCursor) -> c_uint; + pub fn clang_equalLocations(left: CXSourceLocation, right: CXSourceLocation) -> c_uint; + pub fn clang_equalRanges(left: CXSourceRange, right: CXSourceRange) -> c_uint; + pub fn clang_equalTypes(left: CXType, right: CXType) -> c_uint; + pub fn clang_executeOnThread(function: extern fn(*mut c_void), data: *mut c_void, stack: c_uint); + pub fn clang_findIncludesInFile(tu: CXTranslationUnit, file: CXFile, cursor: CXCursorAndRangeVisitor) -> CXResult; + pub fn clang_findReferencesInFile(cursor: CXCursor, file: CXFile, visitor: CXCursorAndRangeVisitor) -> CXResult; + pub fn clang_formatDiagnostic(diagnostic: CXDiagnostic, flags: CXDiagnosticDisplayOptions) -> CXString; + /// Only available on `libclang` 3.7 and later. + #[cfg(feature = "clang_3_7")] + pub fn clang_free(buffer: *mut c_void); + /// Only available on `libclang` 5.0 and later. + #[cfg(feature = "clang_5_0")] + pub fn clang_getAddressSpace(type_: CXType) -> c_uint; + /// Only available on `libclang` 4.0 and later. + #[cfg(feature = "clang_4_0")] + pub fn clang_getAllSkippedRanges(tu: CXTranslationUnit) -> *mut CXSourceRangeList; + pub fn clang_getArgType(type_: CXType, index: c_uint) -> CXType; + pub fn clang_getArrayElementType(type_: CXType) -> CXType; + pub fn clang_getArraySize(type_: CXType) -> c_longlong; + pub fn clang_getCString(string: CXString) -> *const c_char; + pub fn clang_getCXTUResourceUsage(tu: CXTranslationUnit) -> CXTUResourceUsage; + pub fn clang_getCXXAccessSpecifier(cursor: CXCursor) -> CX_CXXAccessSpecifier; + pub fn clang_getCanonicalCursor(cursor: CXCursor) -> CXCursor; + pub fn clang_getCanonicalType(type_: CXType) -> CXType; + pub fn clang_getChildDiagnostics(diagnostic: CXDiagnostic) -> CXDiagnosticSet; + pub fn clang_getClangVersion() -> CXString; + pub fn clang_getCompletionAnnotation(string: CXCompletionString, index: c_uint) -> CXString; + pub fn clang_getCompletionAvailability(string: CXCompletionString) -> CXAvailabilityKind; + pub fn clang_getCompletionBriefComment(string: CXCompletionString) -> CXString; + pub fn clang_getCompletionChunkCompletionString(string: CXCompletionString, index: c_uint) -> CXCompletionString; + pub fn clang_getCompletionChunkKind(string: CXCompletionString, index: c_uint) -> CXCompletionChunkKind; + pub fn clang_getCompletionChunkText(string: CXCompletionString, index: c_uint) -> CXString; + /// Only available on `libclang` 7.0 and later. + #[cfg(feature = "clang_7_0")] + pub fn clang_getCompletionFixIt(results: *mut CXCodeCompleteResults, completion_index: c_uint, fixit_index: c_uint, range: *mut CXSourceRange) -> CXString; + pub fn clang_getCompletionNumAnnotations(string: CXCompletionString) -> c_uint; + /// Only available on `libclang` 7.0 and later. + #[cfg(feature = "clang_7_0")] + pub fn clang_getCompletionNumFixIts(results: *mut CXCodeCompleteResults, completion_index: c_uint) -> c_uint; + pub fn clang_getCompletionParent(string: CXCompletionString, kind: *mut CXCursorKind) -> CXString; + pub fn clang_getCompletionPriority(string: CXCompletionString) -> c_uint; + pub fn clang_getCursor(tu: CXTranslationUnit, location: CXSourceLocation) -> CXCursor; + pub fn clang_getCursorAvailability(cursor: CXCursor) -> CXAvailabilityKind; + pub fn clang_getCursorCompletionString(cursor: CXCursor) -> CXCompletionString; + pub fn clang_getCursorDefinition(cursor: CXCursor) -> CXCursor; + pub fn clang_getCursorDisplayName(cursor: CXCursor) -> CXString; + /// Only available on `libclang` 5.0 and later. + #[cfg(feature = "clang_5_0")] + pub fn clang_getCursorExceptionSpecificationType(cursor: CXCursor) -> CXCursor_ExceptionSpecificationKind; + pub fn clang_getCursorExtent(cursor: CXCursor) -> CXSourceRange; + pub fn clang_getCursorKind(cursor: CXCursor) -> CXCursorKind; + pub fn clang_getCursorKindSpelling(kind: CXCursorKind) -> CXString; + pub fn clang_getCursorLanguage(cursor: CXCursor) -> CXLanguageKind; + pub fn clang_getCursorLexicalParent(cursor: CXCursor) -> CXCursor; + pub fn clang_getCursorLinkage(cursor: CXCursor) -> CXLinkageKind; + pub fn clang_getCursorLocation(cursor: CXCursor) -> CXSourceLocation; + pub fn clang_getCursorPlatformAvailability(cursor: CXCursor, deprecated: *mut c_int, deprecated_message: *mut CXString, unavailable: *mut c_int, unavailable_message: *mut CXString, availability: *mut CXPlatformAvailability, n_availability: c_int) -> c_int; + /// Only available on `libclang` 7.0 and later. + #[cfg(feature = "clang_7_0")] + pub fn clang_getCursorPrettyPrinted(cursor: CXCursor, policy: CXPrintingPolicy) -> CXString; + /// Only available on `libclang` 7.0 and later. + #[cfg(feature = "clang_7_0")] + pub fn clang_getCursorPrintingPolicy(cursor: CXCursor) -> CXPrintingPolicy; + pub fn clang_getCursorReferenceNameRange(cursor: CXCursor, flags: CXNameRefFlags, index: c_uint) -> CXSourceRange; + pub fn clang_getCursorReferenced(cursor: CXCursor) -> CXCursor; + pub fn clang_getCursorResultType(cursor: CXCursor) -> CXType; + pub fn clang_getCursorSemanticParent(cursor: CXCursor) -> CXCursor; + pub fn clang_getCursorSpelling(cursor: CXCursor) -> CXString; + /// Only available on `libclang` 6.0 and later. + #[cfg(feature = "clang_6_0")] + pub fn clang_getCursorTLSKind(cursor: CXCursor) -> CXTLSKind; + pub fn clang_getCursorType(cursor: CXCursor) -> CXType; + pub fn clang_getCursorUSR(cursor: CXCursor) -> CXString; + /// Only available on `libclang` 3.8 and later. + #[cfg(feature = "clang_3_8")] + pub fn clang_getCursorVisibility(cursor: CXCursor) -> CXVisibilityKind; + pub fn clang_getDeclObjCTypeEncoding(cursor: CXCursor) -> CXString; + pub fn clang_getDefinitionSpellingAndExtent(cursor: CXCursor, start: *mut *const c_char, end: *mut *const c_char, start_line: *mut c_uint, start_column: *mut c_uint, end_line: *mut c_uint, end_column: *mut c_uint); + pub fn clang_getDiagnostic(tu: CXTranslationUnit, index: c_uint) -> CXDiagnostic; + pub fn clang_getDiagnosticCategory(diagnostic: CXDiagnostic) -> c_uint; + pub fn clang_getDiagnosticCategoryName(category: c_uint) -> CXString; + pub fn clang_getDiagnosticCategoryText(diagnostic: CXDiagnostic) -> CXString; + pub fn clang_getDiagnosticFixIt(diagnostic: CXDiagnostic, index: c_uint, range: *mut CXSourceRange) -> CXString; + pub fn clang_getDiagnosticInSet(diagnostic: CXDiagnosticSet, index: c_uint) -> CXDiagnostic; + pub fn clang_getDiagnosticLocation(diagnostic: CXDiagnostic) -> CXSourceLocation; + pub fn clang_getDiagnosticNumFixIts(diagnostic: CXDiagnostic) -> c_uint; + pub fn clang_getDiagnosticNumRanges(diagnostic: CXDiagnostic) -> c_uint; + pub fn clang_getDiagnosticOption(diagnostic: CXDiagnostic, option: *mut CXString) -> CXString; + pub fn clang_getDiagnosticRange(diagnostic: CXDiagnostic, index: c_uint) -> CXSourceRange; + pub fn clang_getDiagnosticSetFromTU(tu: CXTranslationUnit) -> CXDiagnosticSet; + pub fn clang_getDiagnosticSeverity(diagnostic: CXDiagnostic) -> CXDiagnosticSeverity; + pub fn clang_getDiagnosticSpelling(diagnostic: CXDiagnostic) -> CXString; + pub fn clang_getElementType(type_: CXType) -> CXType; + pub fn clang_getEnumConstantDeclUnsignedValue(cursor: CXCursor) -> c_ulonglong; + pub fn clang_getEnumConstantDeclValue(cursor: CXCursor) -> c_longlong; + pub fn clang_getEnumDeclIntegerType(cursor: CXCursor) -> CXType; + /// Only available on `libclang` 5.0 and later. + #[cfg(feature = "clang_5_0")] + pub fn clang_getExceptionSpecificationType(type_: CXType) -> CXCursor_ExceptionSpecificationKind; + pub fn clang_getExpansionLocation(location: CXSourceLocation, file: *mut CXFile, line: *mut c_uint, column: *mut c_uint, offset: *mut c_uint); + pub fn clang_getFieldDeclBitWidth(cursor: CXCursor) -> c_int; + pub fn clang_getFile(tu: CXTranslationUnit, file: *const c_char) -> CXFile; + /// Only available on `libclang` 6.0 and later. + #[cfg(feature = "clang_6_0")] + pub fn clang_getFileContents(tu: CXTranslationUnit, file: CXFile, size: *mut size_t) -> *const c_char; + pub fn clang_getFileLocation(location: CXSourceLocation, file: *mut CXFile, line: *mut c_uint, column: *mut c_uint, offset: *mut c_uint); + pub fn clang_getFileName(file: CXFile) -> CXString; + pub fn clang_getFileTime(file: CXFile) -> time_t; + pub fn clang_getFileUniqueID(file: CXFile, id: *mut CXFileUniqueID) -> c_int; + pub fn clang_getFunctionTypeCallingConv(type_: CXType) -> CXCallingConv; + pub fn clang_getIBOutletCollectionType(cursor: CXCursor) -> CXType; + pub fn clang_getIncludedFile(cursor: CXCursor) -> CXFile; + pub fn clang_getInclusions(tu: CXTranslationUnit, visitor: CXInclusionVisitor, data: CXClientData); + pub fn clang_getInstantiationLocation(location: CXSourceLocation, file: *mut CXFile, line: *mut c_uint, column: *mut c_uint, offset: *mut c_uint); + pub fn clang_getLocation(tu: CXTranslationUnit, file: CXFile, line: c_uint, column: c_uint) -> CXSourceLocation; + pub fn clang_getLocationForOffset(tu: CXTranslationUnit, file: CXFile, offset: c_uint) -> CXSourceLocation; + pub fn clang_getModuleForFile(tu: CXTranslationUnit, file: CXFile) -> CXModule; + /// Only available on `libclang` 16.0 and later. + #[cfg(feature = "clang_16_0")] + pub fn clang_getNonReferenceType(type_: CXType) -> CXType; + pub fn clang_getNullCursor() -> CXCursor; + pub fn clang_getNullLocation() -> CXSourceLocation; + pub fn clang_getNullRange() -> CXSourceRange; + pub fn clang_getNumArgTypes(type_: CXType) -> c_int; + pub fn clang_getNumCompletionChunks(string: CXCompletionString) -> c_uint; + pub fn clang_getNumDiagnostics(tu: CXTranslationUnit) -> c_uint; + pub fn clang_getNumDiagnosticsInSet(diagnostic: CXDiagnosticSet) -> c_uint; + pub fn clang_getNumElements(type_: CXType) -> c_longlong; + pub fn clang_getNumOverloadedDecls(cursor: CXCursor) -> c_uint; + pub fn clang_getOverloadedDecl(cursor: CXCursor, index: c_uint) -> CXCursor; + pub fn clang_getOverriddenCursors(cursor: CXCursor, cursors: *mut *mut CXCursor, n_cursors: *mut c_uint); + pub fn clang_getPointeeType(type_: CXType) -> CXType; + pub fn clang_getPresumedLocation(location: CXSourceLocation, file: *mut CXString, line: *mut c_uint, column: *mut c_uint); + pub fn clang_getRange(start: CXSourceLocation, end: CXSourceLocation) -> CXSourceRange; + pub fn clang_getRangeEnd(range: CXSourceRange) -> CXSourceLocation; + pub fn clang_getRangeStart(range: CXSourceRange) -> CXSourceLocation; + pub fn clang_getRemappings(file: *const c_char) -> CXRemapping; + pub fn clang_getRemappingsFromFileList(files: *mut *const c_char, n_files: c_uint) -> CXRemapping; + pub fn clang_getResultType(type_: CXType) -> CXType; + pub fn clang_getSkippedRanges(tu: CXTranslationUnit, file: CXFile) -> *mut CXSourceRangeList; + pub fn clang_getSpecializedCursorTemplate(cursor: CXCursor) -> CXCursor; + pub fn clang_getSpellingLocation(location: CXSourceLocation, file: *mut CXFile, line: *mut c_uint, column: *mut c_uint, offset: *mut c_uint); + pub fn clang_getTUResourceUsageName(kind: CXTUResourceUsageKind) -> *const c_char; + pub fn clang_getTemplateCursorKind(cursor: CXCursor) -> CXCursorKind; + pub fn clang_getToken(tu: CXTranslationUnit, location: CXSourceLocation) -> *mut CXToken; + pub fn clang_getTokenExtent(tu: CXTranslationUnit, token: CXToken) -> CXSourceRange; + pub fn clang_getTokenKind(token: CXToken) -> CXTokenKind; + pub fn clang_getTokenLocation(tu: CXTranslationUnit, token: CXToken) -> CXSourceLocation; + pub fn clang_getTokenSpelling(tu: CXTranslationUnit, token: CXToken) -> CXString; + pub fn clang_getTranslationUnitCursor(tu: CXTranslationUnit) -> CXCursor; + pub fn clang_getTranslationUnitSpelling(tu: CXTranslationUnit) -> CXString; + /// Only available on `libclang` 5.0 and later. + #[cfg(feature = "clang_5_0")] + pub fn clang_getTranslationUnitTargetInfo(tu: CXTranslationUnit) -> CXTargetInfo; + /// Only available on `libclang` 16.0 and later. + #[cfg(feature = "clang_16_0")] + pub fn clang_getUnqualifiedType(type_: CXType) -> CXType; + pub fn clang_getTypeDeclaration(type_: CXType) -> CXCursor; + pub fn clang_getTypeKindSpelling(type_: CXTypeKind) -> CXString; + pub fn clang_getTypeSpelling(type_: CXType) -> CXString; + pub fn clang_getTypedefDeclUnderlyingType(cursor: CXCursor) -> CXType; + /// Only available on `libclang` 5.0 and later. + #[cfg(feature = "clang_5_0")] + pub fn clang_getTypedefName(type_: CXType) -> CXString; + pub fn clang_hashCursor(cursor: CXCursor) -> c_uint; + pub fn clang_indexLoc_getCXSourceLocation(location: CXIdxLoc) -> CXSourceLocation; + pub fn clang_indexLoc_getFileLocation(location: CXIdxLoc, index_file: *mut CXIdxClientFile, file: *mut CXFile, line: *mut c_uint, column: *mut c_uint, offset: *mut c_uint); + pub fn clang_indexSourceFile(index: CXIndexAction, data: CXClientData, callbacks: *mut IndexerCallbacks, n_callbacks: c_uint, index_flags: CXIndexOptFlags, file: *const c_char, arguments: *const *const c_char, n_arguments: c_int, unsaved: *mut CXUnsavedFile, n_unsaved: c_uint, tu: *mut CXTranslationUnit, tu_flags: CXTranslationUnit_Flags) -> CXErrorCode; + /// Only available on `libclang` 3.8 and later. + #[cfg(feature = "clang_3_8")] + pub fn clang_indexSourceFileFullArgv(index: CXIndexAction, data: CXClientData, callbacks: *mut IndexerCallbacks, n_callbacks: c_uint, index_flags: CXIndexOptFlags, file: *const c_char, arguments: *const *const c_char, n_arguments: c_int, unsaved: *mut CXUnsavedFile, n_unsaved: c_uint, tu: *mut CXTranslationUnit, tu_flags: CXTranslationUnit_Flags) -> CXErrorCode; + pub fn clang_indexTranslationUnit(index: CXIndexAction, data: CXClientData, callbacks: *mut IndexerCallbacks, n_callbacks: c_uint, flags: CXIndexOptFlags, tu: CXTranslationUnit) -> c_int; + pub fn clang_index_getCXXClassDeclInfo(info: *const CXIdxDeclInfo) -> *const CXIdxCXXClassDeclInfo; + pub fn clang_index_getClientContainer(info: *const CXIdxContainerInfo) -> CXIdxClientContainer; + pub fn clang_index_getClientEntity(info: *const CXIdxEntityInfo) -> CXIdxClientEntity; + pub fn clang_index_getIBOutletCollectionAttrInfo(info: *const CXIdxAttrInfo) -> *const CXIdxIBOutletCollectionAttrInfo; + pub fn clang_index_getObjCCategoryDeclInfo(info: *const CXIdxDeclInfo) -> *const CXIdxObjCCategoryDeclInfo; + pub fn clang_index_getObjCContainerDeclInfo(info: *const CXIdxDeclInfo) -> *const CXIdxObjCContainerDeclInfo; + pub fn clang_index_getObjCInterfaceDeclInfo(info: *const CXIdxDeclInfo) -> *const CXIdxObjCInterfaceDeclInfo; + pub fn clang_index_getObjCPropertyDeclInfo(info: *const CXIdxDeclInfo) -> *const CXIdxObjCPropertyDeclInfo; + pub fn clang_index_getObjCProtocolRefListInfo(info: *const CXIdxDeclInfo) -> *const CXIdxObjCProtocolRefListInfo; + pub fn clang_index_isEntityObjCContainerKind(info: CXIdxEntityKind) -> c_int; + pub fn clang_index_setClientContainer(info: *const CXIdxContainerInfo, container: CXIdxClientContainer); + pub fn clang_index_setClientEntity(info: *const CXIdxEntityInfo, entity: CXIdxClientEntity); + pub fn clang_isAttribute(kind: CXCursorKind) -> c_uint; + pub fn clang_isConstQualifiedType(type_: CXType) -> c_uint; + pub fn clang_isCursorDefinition(cursor: CXCursor) -> c_uint; + pub fn clang_isDeclaration(kind: CXCursorKind) -> c_uint; + pub fn clang_isExpression(kind: CXCursorKind) -> c_uint; + pub fn clang_isFileMultipleIncludeGuarded(tu: CXTranslationUnit, file: CXFile) -> c_uint; + pub fn clang_isFunctionTypeVariadic(type_: CXType) -> c_uint; + pub fn clang_isInvalid(kind: CXCursorKind) -> c_uint; + /// Only available on `libclang` 7.0 and later. + #[cfg(feature = "clang_7_0")] + pub fn clang_isInvalidDeclaration(cursor: CXCursor) -> c_uint; + pub fn clang_isPODType(type_: CXType) -> c_uint; + pub fn clang_isPreprocessing(kind: CXCursorKind) -> c_uint; + pub fn clang_isReference(kind: CXCursorKind) -> c_uint; + pub fn clang_isRestrictQualifiedType(type_: CXType) -> c_uint; + pub fn clang_isStatement(kind: CXCursorKind) -> c_uint; + pub fn clang_isTranslationUnit(kind: CXCursorKind) -> c_uint; + pub fn clang_isUnexposed(kind: CXCursorKind) -> c_uint; + pub fn clang_isVirtualBase(cursor: CXCursor) -> c_uint; + pub fn clang_isVolatileQualifiedType(type_: CXType) -> c_uint; + pub fn clang_loadDiagnostics(file: *const c_char, error: *mut CXLoadDiag_Error, message: *mut CXString) -> CXDiagnosticSet; + pub fn clang_parseTranslationUnit(index: CXIndex, file: *const c_char, arguments: *const *const c_char, n_arguments: c_int, unsaved: *mut CXUnsavedFile, n_unsaved: c_uint, flags: CXTranslationUnit_Flags) -> CXTranslationUnit; + pub fn clang_parseTranslationUnit2(index: CXIndex, file: *const c_char, arguments: *const *const c_char, n_arguments: c_int, unsaved: *mut CXUnsavedFile, n_unsaved: c_uint, flags: CXTranslationUnit_Flags, tu: *mut CXTranslationUnit) -> CXErrorCode; + /// Only available on `libclang` 3.8 and later. + #[cfg(feature = "clang_3_8")] + pub fn clang_parseTranslationUnit2FullArgv(index: CXIndex, file: *const c_char, arguments: *const *const c_char, n_arguments: c_int, unsaved: *mut CXUnsavedFile, n_unsaved: c_uint, flags: CXTranslationUnit_Flags, tu: *mut CXTranslationUnit) -> CXErrorCode; + pub fn clang_remap_dispose(remapping: CXRemapping); + pub fn clang_remap_getFilenames(remapping: CXRemapping, index: c_uint, original: *mut CXString, transformed: *mut CXString); + pub fn clang_remap_getNumFiles(remapping: CXRemapping) -> c_uint; + pub fn clang_reparseTranslationUnit(tu: CXTranslationUnit, n_unsaved: c_uint, unsaved: *mut CXUnsavedFile, flags: CXReparse_Flags) -> CXErrorCode; + pub fn clang_saveTranslationUnit(tu: CXTranslationUnit, file: *const c_char, options: CXSaveTranslationUnit_Flags) -> CXSaveError; + pub fn clang_sortCodeCompletionResults(results: *mut CXCompletionResult, n_results: c_uint); + /// Only available on `libclang` 5.0 and later. + #[cfg(feature = "clang_5_0")] + pub fn clang_suspendTranslationUnit(tu: CXTranslationUnit) -> c_uint; + pub fn clang_toggleCrashRecovery(recovery: c_uint); + pub fn clang_tokenize(tu: CXTranslationUnit, range: CXSourceRange, tokens: *mut *mut CXToken, n_tokens: *mut c_uint); + pub fn clang_visitChildren(cursor: CXCursor, visitor: CXCursorVisitor, data: CXClientData) -> c_uint; + + // Documentation + pub fn clang_BlockCommandComment_getArgText(comment: CXComment, index: c_uint) -> CXString; + pub fn clang_BlockCommandComment_getCommandName(comment: CXComment) -> CXString; + pub fn clang_BlockCommandComment_getNumArgs(comment: CXComment) -> c_uint; + pub fn clang_BlockCommandComment_getParagraph(comment: CXComment) -> CXComment; + pub fn clang_Comment_getChild(comment: CXComment, index: c_uint) -> CXComment; + pub fn clang_Comment_getKind(comment: CXComment) -> CXCommentKind; + pub fn clang_Comment_getNumChildren(comment: CXComment) -> c_uint; + pub fn clang_Comment_isWhitespace(comment: CXComment) -> c_uint; + pub fn clang_Cursor_getParsedComment(C: CXCursor) -> CXComment; + pub fn clang_FullComment_getAsHTML(comment: CXComment) -> CXString; + pub fn clang_FullComment_getAsXML(comment: CXComment) -> CXString; + pub fn clang_HTMLStartTag_getAttrName(comment: CXComment, index: c_uint) -> CXString; + pub fn clang_HTMLStartTag_getAttrValue(comment: CXComment, index: c_uint) -> CXString; + pub fn clang_HTMLStartTag_getNumAttrs(comment: CXComment) -> c_uint; + pub fn clang_HTMLStartTagComment_isSelfClosing(comment: CXComment) -> c_uint; + pub fn clang_HTMLTagComment_getAsString(comment: CXComment) -> CXString; + pub fn clang_HTMLTagComment_getTagName(comment: CXComment) -> CXString; + pub fn clang_InlineCommandComment_getArgText(comment: CXComment, index: c_uint) -> CXString; + pub fn clang_InlineCommandComment_getCommandName(comment: CXComment) -> CXString; + pub fn clang_InlineCommandComment_getNumArgs(comment: CXComment) -> c_uint; + pub fn clang_InlineCommandComment_getRenderKind(comment: CXComment) -> CXCommentInlineCommandRenderKind; + pub fn clang_InlineContentComment_hasTrailingNewline(comment: CXComment) -> c_uint; + pub fn clang_ParamCommandComment_getDirection(comment: CXComment) -> CXCommentParamPassDirection; + pub fn clang_ParamCommandComment_getParamIndex(comment: CXComment) -> c_uint; + pub fn clang_ParamCommandComment_getParamName(comment: CXComment) -> CXString; + pub fn clang_ParamCommandComment_isDirectionExplicit(comment: CXComment) -> c_uint; + pub fn clang_ParamCommandComment_isParamIndexValid(comment: CXComment) -> c_uint; + pub fn clang_TextComment_getText(comment: CXComment) -> CXString; + pub fn clang_TParamCommandComment_getDepth(comment: CXComment) -> c_uint; + pub fn clang_TParamCommandComment_getIndex(comment: CXComment, depth: c_uint) -> c_uint; + pub fn clang_TParamCommandComment_getParamName(comment: CXComment) -> CXString; + pub fn clang_TParamCommandComment_isParamPositionValid(comment: CXComment) -> c_uint; + pub fn clang_VerbatimBlockLineComment_getText(comment: CXComment) -> CXString; + pub fn clang_VerbatimLineComment_getText(comment: CXComment) -> CXString; +} diff --git a/third_party/rust/clang-sys/src/link.rs b/third_party/rust/clang-sys/src/link.rs new file mode 100644 index 0000000000..45d98dbd09 --- /dev/null +++ b/third_party/rust/clang-sys/src/link.rs @@ -0,0 +1,273 @@ +// SPDX-License-Identifier: Apache-2.0 + +//================================================ +// Macros +//================================================ + +#[cfg(feature = "runtime")] +macro_rules! link { + ( + @LOAD: + $(#[doc=$doc:expr])* + #[cfg($cfg:meta)] + fn $name:ident($($pname:ident: $pty:ty), *) $(-> $ret:ty)* + ) => ( + $(#[doc=$doc])* + #[cfg($cfg)] + pub fn $name(library: &mut super::SharedLibrary) { + let symbol = unsafe { library.library.get(stringify!($name).as_bytes()) }.ok(); + library.functions.$name = match symbol { + Some(s) => *s, + None => None, + }; + } + + #[cfg(not($cfg))] + pub fn $name(_: &mut super::SharedLibrary) {} + ); + + ( + @LOAD: + fn $name:ident($($pname:ident: $pty:ty), *) $(-> $ret:ty)* + ) => ( + link!(@LOAD: #[cfg(feature = "runtime")] fn $name($($pname: $pty), *) $(-> $ret)*); + ); + + ( + $( + $(#[doc=$doc:expr] #[cfg($cfg:meta)])* + pub fn $name:ident($($pname:ident: $pty:ty), *) $(-> $ret:ty)*; + )+ + ) => ( + use std::cell::{RefCell}; + use std::sync::{Arc}; + use std::path::{Path, PathBuf}; + + /// The (minimum) version of a `libclang` shared library. + #[allow(missing_docs)] + #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] + pub enum Version { + V3_5 = 35, + V3_6 = 36, + V3_7 = 37, + V3_8 = 38, + V3_9 = 39, + V4_0 = 40, + V5_0 = 50, + V6_0 = 60, + V7_0 = 70, + V8_0 = 80, + V9_0 = 90, + } + + /// The set of functions loaded dynamically. + #[derive(Debug, Default)] + pub struct Functions { + $( + $(#[doc=$doc] #[cfg($cfg)])* + pub $name: Option $ret)*>, + )+ + } + + /// A dynamically loaded instance of the `libclang` library. + #[derive(Debug)] + pub struct SharedLibrary { + library: libloading::Library, + path: PathBuf, + pub functions: Functions, + } + + impl SharedLibrary { + fn new(library: libloading::Library, path: PathBuf) -> Self { + Self { library, path, functions: Functions::default() } + } + + /// Returns the path to this `libclang` shared library. + pub fn path(&self) -> &Path { + &self.path + } + + /// Returns the (minimum) version of this `libclang` shared library. + /// + /// If this returns `None`, it indicates that the version is too old + /// to be supported by this crate (i.e., `3.4` or earlier). If the + /// version of this shared library is more recent than that fully + /// supported by this crate, the most recent fully supported version + /// will be returned. + pub fn version(&self) -> Option { + macro_rules! check { + ($fn:expr, $version:ident) => { + if self.library.get::($fn).is_ok() { + return Some(Version::$version); + } + }; + } + + unsafe { + check!(b"clang_Cursor_isAnonymousRecordDecl", V9_0); + check!(b"clang_Cursor_getObjCPropertyGetterName", V8_0); + check!(b"clang_File_tryGetRealPathName", V7_0); + check!(b"clang_CXIndex_setInvocationEmissionPathOption", V6_0); + check!(b"clang_Cursor_isExternalSymbol", V5_0); + check!(b"clang_EvalResult_getAsLongLong", V4_0); + check!(b"clang_CXXConstructor_isConvertingConstructor", V3_9); + check!(b"clang_CXXField_isMutable", V3_8); + check!(b"clang_Cursor_getOffsetOfField", V3_7); + check!(b"clang_Cursor_getStorageClass", V3_6); + check!(b"clang_Type_getNumTemplateArguments", V3_5); + } + + None + } + } + + thread_local!(static LIBRARY: RefCell>> = RefCell::new(None)); + + /// Returns whether a `libclang` shared library is loaded on this thread. + pub fn is_loaded() -> bool { + LIBRARY.with(|l| l.borrow().is_some()) + } + + fn with_library(f: F) -> Option where F: FnOnce(&SharedLibrary) -> T { + LIBRARY.with(|l| { + match l.borrow().as_ref() { + Some(library) => Some(f(&library)), + _ => None, + } + }) + } + + $( + #[cfg_attr(feature="cargo-clippy", allow(clippy::missing_safety_doc))] + #[cfg_attr(feature="cargo-clippy", allow(clippy::too_many_arguments))] + $(#[doc=$doc] #[cfg($cfg)])* + pub unsafe fn $name($($pname: $pty), *) $(-> $ret)* { + let f = with_library(|l| { + l.functions.$name.expect(concat!( + "`libclang` function not loaded: `", + stringify!($name), + "`. This crate requires that `libclang` 3.9 or later be installed on your ", + "system. For more information on how to accomplish this, see here: ", + "https://rust-lang.github.io/rust-bindgen/requirements.html#installing-clang-39")) + }).expect("a `libclang` shared library is not loaded on this thread"); + f($($pname), *) + } + + $(#[doc=$doc] #[cfg($cfg)])* + pub mod $name { + pub fn is_loaded() -> bool { + super::with_library(|l| l.functions.$name.is_some()).unwrap_or(false) + } + } + )+ + + mod load { + $(link!(@LOAD: $(#[cfg($cfg)])* fn $name($($pname: $pty), *) $(-> $ret)*);)+ + } + + /// Loads a `libclang` shared library and returns the library instance. + /// + /// This function does not attempt to load any functions from the shared library. The caller + /// is responsible for loading the functions they require. + /// + /// # Failures + /// + /// * a `libclang` shared library could not be found + /// * the `libclang` shared library could not be opened + pub fn load_manually() -> Result { + #[allow(dead_code)] + mod build { + include!(concat!(env!("OUT_DIR"), "/macros.rs")); + pub mod common { include!(concat!(env!("OUT_DIR"), "/common.rs")); } + pub mod dynamic { include!(concat!(env!("OUT_DIR"), "/dynamic.rs")); } + } + + let (directory, filename) = build::dynamic::find(true)?; + let path = directory.join(filename); + + unsafe { + let library = libloading::Library::new(&path).map_err(|e| { + format!( + "the `libclang` shared library at {} could not be opened: {}", + path.display(), + e, + ) + }); + + let mut library = SharedLibrary::new(library?, path); + $(load::$name(&mut library);)+ + Ok(library) + } + } + + /// Loads a `libclang` shared library for use in the current thread. + /// + /// This functions attempts to load all the functions in the shared library. Whether a + /// function has been loaded can be tested by calling the `is_loaded` function on the + /// module with the same name as the function (e.g., `clang_createIndex::is_loaded()` for + /// the `clang_createIndex` function). + /// + /// # Failures + /// + /// * a `libclang` shared library could not be found + /// * the `libclang` shared library could not be opened + #[allow(dead_code)] + pub fn load() -> Result<(), String> { + let library = Arc::new(load_manually()?); + LIBRARY.with(|l| *l.borrow_mut() = Some(library)); + Ok(()) + } + + /// Unloads the `libclang` shared library in use in the current thread. + /// + /// # Failures + /// + /// * a `libclang` shared library is not in use in the current thread + pub fn unload() -> Result<(), String> { + let library = set_library(None); + if library.is_some() { + Ok(()) + } else { + Err("a `libclang` shared library is not in use in the current thread".into()) + } + } + + /// Returns the library instance stored in TLS. + /// + /// This functions allows for sharing library instances between threads. + pub fn get_library() -> Option> { + LIBRARY.with(|l| l.borrow_mut().clone()) + } + + /// Sets the library instance stored in TLS and returns the previous library. + /// + /// This functions allows for sharing library instances between threads. + pub fn set_library(library: Option>) -> Option> { + LIBRARY.with(|l| mem::replace(&mut *l.borrow_mut(), library)) + } + ) +} + +#[cfg(not(feature = "runtime"))] +macro_rules! link { + ( + $( + $(#[doc=$doc:expr] #[cfg($cfg:meta)])* + pub fn $name:ident($($pname:ident: $pty:ty), *) $(-> $ret:ty)*; + )+ + ) => ( + extern { + $( + $(#[doc=$doc] #[cfg($cfg)])* + pub fn $name($($pname: $pty), *) $(-> $ret)*; + )+ + } + + $( + $(#[doc=$doc] #[cfg($cfg)])* + pub mod $name { + pub fn is_loaded() -> bool { true } + } + )+ + ) +} diff --git a/third_party/rust/clang-sys/src/support.rs b/third_party/rust/clang-sys/src/support.rs new file mode 100644 index 0000000000..11247123a6 --- /dev/null +++ b/third_party/rust/clang-sys/src/support.rs @@ -0,0 +1,236 @@ +// SPDX-License-Identifier: Apache-2.0 + +//! Provides helper functionality. + +use std::path::{Path, PathBuf}; +use std::process::Command; +use std::{env, io}; + +use glob::{self, Pattern}; + +use libc::c_int; + +use super::CXVersion; + +//================================================ +// Structs +//================================================ + +/// A `clang` executable. +#[derive(Clone, Debug)] +pub struct Clang { + /// The path to this `clang` executable. + pub path: PathBuf, + /// The version of this `clang` executable if it could be parsed. + pub version: Option, + /// The directories searched by this `clang` executable for C headers if + /// they could be parsed. + pub c_search_paths: Option>, + /// The directories searched by this `clang` executable for C++ headers if + /// they could be parsed. + pub cpp_search_paths: Option>, +} + +impl Clang { + fn new(path: impl AsRef, args: &[String]) -> Self { + Self { + path: path.as_ref().into(), + version: parse_version(path.as_ref()), + c_search_paths: parse_search_paths(path.as_ref(), "c", args), + cpp_search_paths: parse_search_paths(path.as_ref(), "c++", args), + } + } + + /// Returns a `clang` executable if one can be found. + /// + /// If the `CLANG_PATH` environment variable is set, that is the instance of + /// `clang` used. Otherwise, a series of directories are searched. First, if + /// a path is supplied, that is the first directory searched. Then, the + /// directory returned by `llvm-config --bindir` is searched. On macOS + /// systems, `xcodebuild -find clang` will next be queried. Last, the + /// directories in the system's `PATH` are searched. + /// + /// ## Cross-compilation + /// + /// If target arguments are provided (e.g., `-target` followed by a target + /// like `x86_64-unknown-linux-gnu`) then this method will prefer a + /// target-prefixed instance of `clang` (e.g., + /// `x86_64-unknown-linux-gnu-clang` for the above example). + pub fn find(path: Option<&Path>, args: &[String]) -> Option { + if let Ok(path) = env::var("CLANG_PATH") { + let p = Path::new(&path); + if p.is_file() && is_executable(&p).unwrap_or(false) { + return Some(Clang::new(p, args)); + } + } + + // Determine the cross-compilation target, if any. + + let mut target = None; + for i in 0..args.len() { + if args[i] == "-target" && i + 1 < args.len() { + target = Some(&args[i + 1]); + } + } + + // Collect the paths to search for a `clang` executable in. + + let mut paths = vec![]; + + if let Some(path) = path { + paths.push(path.into()); + } + + if let Ok(path) = run_llvm_config(&["--bindir"]) { + if let Some(line) = path.lines().next() { + paths.push(line.into()); + } + } + + if cfg!(target_os = "macos") { + if let Ok((path, _)) = run("xcodebuild", &["-find", "clang"]) { + if let Some(line) = path.lines().next() { + paths.push(line.into()); + } + } + } + + if let Ok(path) = env::var("PATH") { + paths.extend(env::split_paths(&path)); + } + + // First, look for a target-prefixed `clang` executable. + + if let Some(target) = target { + let default = format!("{}-clang{}", target, env::consts::EXE_SUFFIX); + let versioned = format!("{}-clang-[0-9]*{}", target, env::consts::EXE_SUFFIX); + let patterns = &[&default[..], &versioned[..]]; + for path in &paths { + if let Some(path) = find(path, patterns) { + return Some(Clang::new(path, args)); + } + } + } + + // Otherwise, look for any other `clang` executable. + + let default = format!("clang{}", env::consts::EXE_SUFFIX); + let versioned = format!("clang-[0-9]*{}", env::consts::EXE_SUFFIX); + let patterns = &[&default[..], &versioned[..]]; + for path in paths { + if let Some(path) = find(&path, patterns) { + return Some(Clang::new(path, args)); + } + } + + None + } +} + +//================================================ +// Functions +//================================================ + +/// Returns the first match to the supplied glob patterns in the supplied +/// directory if there are any matches. +fn find(directory: &Path, patterns: &[&str]) -> Option { + // Escape the directory in case it contains characters that have special + // meaning in glob patterns (e.g., `[` or `]`). + let directory = if let Some(directory) = directory.to_str() { + Path::new(&Pattern::escape(directory)).to_owned() + } else { + return None; + }; + + for pattern in patterns { + let pattern = directory.join(pattern).to_string_lossy().into_owned(); + if let Some(path) = glob::glob(&pattern).ok()?.filter_map(|p| p.ok()).next() { + if path.is_file() && is_executable(&path).unwrap_or(false) { + return Some(path); + } + } + } + + None +} + +#[cfg(unix)] +fn is_executable(path: &Path) -> io::Result { + use std::ffi::CString; + use std::os::unix::ffi::OsStrExt; + + let path = CString::new(path.as_os_str().as_bytes())?; + unsafe { Ok(libc::access(path.as_ptr(), libc::X_OK) == 0) } +} + +#[cfg(not(unix))] +fn is_executable(_: &Path) -> io::Result { + Ok(true) +} + +/// Attempts to run an executable, returning the `stdout` and `stderr` output if +/// successful. +fn run(executable: &str, arguments: &[&str]) -> Result<(String, String), String> { + Command::new(executable) + .args(arguments) + .output() + .map(|o| { + let stdout = String::from_utf8_lossy(&o.stdout).into_owned(); + let stderr = String::from_utf8_lossy(&o.stderr).into_owned(); + (stdout, stderr) + }) + .map_err(|e| format!("could not run executable `{}`: {}", executable, e)) +} + +/// Runs `clang`, returning the `stdout` and `stderr` output. +fn run_clang(path: &Path, arguments: &[&str]) -> (String, String) { + run(&path.to_string_lossy().into_owned(), arguments).unwrap() +} + +/// Runs `llvm-config`, returning the `stdout` output if successful. +fn run_llvm_config(arguments: &[&str]) -> Result { + let config = env::var("LLVM_CONFIG_PATH").unwrap_or_else(|_| "llvm-config".to_string()); + run(&config, arguments).map(|(o, _)| o) +} + +/// Parses a version number if possible, ignoring trailing non-digit characters. +fn parse_version_number(number: &str) -> Option { + number + .chars() + .take_while(|c| c.is_digit(10)) + .collect::() + .parse() + .ok() +} + +/// Parses the version from the output of a `clang` executable if possible. +fn parse_version(path: &Path) -> Option { + let output = run_clang(path, &["--version"]).0; + let start = output.find("version ")? + 8; + let mut numbers = output[start..].split_whitespace().next()?.split('.'); + let major = numbers.next().and_then(parse_version_number)?; + let minor = numbers.next().and_then(parse_version_number)?; + let subminor = numbers.next().and_then(parse_version_number).unwrap_or(0); + Some(CXVersion { + Major: major, + Minor: minor, + Subminor: subminor, + }) +} + +/// Parses the search paths from the output of a `clang` executable if possible. +fn parse_search_paths(path: &Path, language: &str, args: &[String]) -> Option> { + let mut clang_args = vec!["-E", "-x", language, "-", "-v"]; + clang_args.extend(args.iter().map(|s| &**s)); + let output = run_clang(path, &clang_args).1; + let start = output.find("#include <...> search starts here:")? + 34; + let end = output.find("End of search list.")?; + let paths = output[start..end].replace("(framework directory)", ""); + Some( + paths + .lines() + .filter(|l| !l.is_empty()) + .map(|l| Path::new(l.trim()).into()) + .collect(), + ) +} diff --git a/third_party/rust/clang-sys/tests/build.rs b/third_party/rust/clang-sys/tests/build.rs new file mode 100644 index 0000000000..224421b221 --- /dev/null +++ b/third_party/rust/clang-sys/tests/build.rs @@ -0,0 +1,281 @@ +#![allow(dead_code)] + +extern crate glob; +extern crate serial_test; +extern crate tempdir; + +use std::collections::HashMap; +use std::env; +use std::fs; +use std::path::PathBuf; +use std::sync::Arc; +use std::sync::Mutex; + +use serial_test::serial; +use tempdir::TempDir; + +#[macro_use] +#[path = "../build/macros.rs"] +mod macros; + +#[path = "../build/common.rs"] +mod common; +#[path = "../build/dynamic.rs"] +mod dynamic; +#[path = "../build/static.rs"] +mod r#static; + +#[derive(Debug, Default)] +struct RunCommandMock { + invocations: Vec<(String, String, Vec)>, + responses: HashMap, String>, +} + +#[derive(Debug)] +struct Env { + os: String, + pointer_width: String, + env: Option, + vars: HashMap, Option)>, + cwd: PathBuf, + tmp: TempDir, + files: Vec, + commands: Arc>, +} + +impl Env { + fn new(os: &str, pointer_width: &str) -> Self { + Env { + os: os.into(), + pointer_width: pointer_width.into(), + env: None, + vars: HashMap::new(), + cwd: env::current_dir().unwrap(), + tmp: TempDir::new("clang_sys_test").unwrap(), + files: vec![], + commands: Default::default(), + } + .var("CLANG_PATH", None) + .var("LD_LIBRARY_PATH", None) + .var("LIBCLANG_PATH", None) + .var("LIBCLANG_STATIC_PATH", None) + .var("LLVM_CONFIG_PATH", None) + .var("PATH", None) + } + + fn env(mut self, env: &str) -> Self { + self.env = Some(env.into()); + self + } + + fn var(mut self, name: &str, value: Option<&str>) -> Self { + let previous = env::var(name).ok(); + self.vars.insert(name.into(), (value.map(|v| v.into()), previous)); + self + } + + fn dir(mut self, path: &str) -> Self { + self.files.push(path.into()); + let path = self.tmp.path().join(path); + fs::create_dir_all(path).unwrap(); + self + } + + fn file(mut self, path: &str, contents: &[u8]) -> Self { + self.files.push(path.into()); + let path = self.tmp.path().join(path); + fs::create_dir_all(path.parent().unwrap()).unwrap(); + fs::write(self.tmp.path().join(path), contents).unwrap(); + self + } + + fn dll(self, path: &str, pointer_width: &str) -> Self { + // PE header. + let mut contents = [0; 64]; + contents[0x3C..0x3C + 4].copy_from_slice(&i32::to_le_bytes(10)); + contents[10..14].copy_from_slice(&[b'P', b'E', 0, 0]); + let magic = if pointer_width == "64" { 523 } else { 267 }; + contents[34..36].copy_from_slice(&u16::to_le_bytes(magic)); + + self.file(path, &contents) + } + + fn so(self, path: &str, pointer_width: &str) -> Self { + // ELF header. + let class = if pointer_width == "64" { 2 } else { 1 }; + let contents = [127, 69, 76, 70, class]; + + self.file(path, &contents) + } + + fn command(self, command: &str, args: &[&str], response: &str) -> Self { + let command = command.to_string(); + let args = args.iter().map(|a| a.to_string()).collect::>(); + + let mut key = vec![command]; + key.extend(args); + self.commands.lock().unwrap().responses.insert(key, response.into()); + + self + } + + fn enable(self) -> Self { + env::set_var("_CLANG_SYS_TEST", "yep"); + env::set_var("_CLANG_SYS_TEST_OS", &self.os); + env::set_var("_CLANG_SYS_TEST_POINTER_WIDTH", &self.pointer_width); + if let Some(env) = &self.env { + env::set_var("_CLANG_SYS_TEST_ENV", env); + } + + for (name, (value, _)) in &self.vars { + if let Some(value) = value { + env::set_var(name, value); + } else { + env::remove_var(name); + } + } + + env::set_current_dir(&self.tmp).unwrap(); + + let commands = self.commands.clone(); + let mock = &mut *common::RUN_COMMAND_MOCK.lock().unwrap(); + *mock = Some(Box::new(move |command, path, args| { + let command = command.to_string(); + let path = path.to_string(); + let args = args.iter().map(|a| a.to_string()).collect::>(); + + let mut commands = commands.lock().unwrap(); + commands.invocations.push((command.clone(), path, args.clone())); + + let mut key = vec![command]; + key.extend(args); + commands.responses.get(&key).cloned() + })); + + self + } +} + +impl Drop for Env { + fn drop(&mut self) { + env::remove_var("_CLANG_SYS_TEST"); + env::remove_var("_CLANG_SYS_TEST_OS"); + env::remove_var("_CLANG_SYS_TEST_POINTER_WIDTH"); + env::remove_var("_CLANG_SYS_TEST_ENV"); + + for (name, (_, previous)) in &self.vars { + if let Some(previous) = previous { + env::set_var(name, previous); + } else { + env::remove_var(name); + } + } + + if let Err(error) = env::set_current_dir(&self.cwd) { + println!("Failed to reset working directory: {:?}", error); + } + } +} + +//================================================ +// Dynamic +//================================================ + +// Linux ----------------------------------------- + +#[test] +#[serial] +fn test_linux_directory_preference() { + let _env = Env::new("linux", "64") + .so("usr/lib/libclang.so.1", "64") + .so("usr/local/lib/libclang.so.1", "64") + .enable(); + + assert_eq!( + dynamic::find(true), + Ok(("usr/local/lib".into(), "libclang.so.1".into())), + ); +} + +#[test] +#[serial] +fn test_linux_version_preference() { + let _env = Env::new("linux", "64") + .so("usr/lib/libclang-3.so", "64") + .so("usr/lib/libclang-3.5.so", "64") + .so("usr/lib/libclang-3.5.0.so", "64") + .enable(); + + assert_eq!( + dynamic::find(true), + Ok(("usr/lib".into(), "libclang-3.5.0.so".into())), + ); +} + +#[test] +#[serial] +fn test_linux_directory_and_version_preference() { + let _env = Env::new("linux", "64") + .so("usr/local/llvm/lib/libclang-3.so", "64") + .so("usr/local/lib/libclang-3.5.so", "64") + .so("usr/lib/libclang-3.5.0.so", "64") + .enable(); + + assert_eq!( + dynamic::find(true), + Ok(("usr/lib".into(), "libclang-3.5.0.so".into())), + ); +} + +// Windows --------------------------------------- + +#[cfg(target_os = "windows")] +#[test] +#[serial] +fn test_windows_bin_sibling() { + let _env = Env::new("windows", "64") + .dir("Program Files\\LLVM\\lib") + .dll("Program Files\\LLVM\\bin\\libclang.dll", "64") + .enable(); + + assert_eq!( + dynamic::find(true), + Ok(("Program Files\\LLVM\\bin".into(), "libclang.dll".into())), + ); +} + +#[cfg(target_os = "windows")] +#[test] +#[serial] +fn test_windows_mingw_gnu() { + let _env = Env::new("windows", "64") + .env("gnu") + .dir("MSYS\\MinGW\\lib") + .dll("MSYS\\MinGW\\bin\\clang.dll", "64") + .dir("Program Files\\LLVM\\lib") + .dll("Program Files\\LLVM\\bin\\libclang.dll", "64") + .enable(); + + assert_eq!( + dynamic::find(true), + Ok(("MSYS\\MinGW\\bin".into(), "clang.dll".into())), + ); +} + +#[cfg(target_os = "windows")] +#[test] +#[serial] +fn test_windows_mingw_msvc() { + let _env = Env::new("windows", "64") + .env("msvc") + .dir("MSYS\\MinGW\\lib") + .dll("MSYS\\MinGW\\bin\\clang.dll", "64") + .dir("Program Files\\LLVM\\lib") + .dll("Program Files\\LLVM\\bin\\libclang.dll", "64") + .enable(); + + assert_eq!( + dynamic::find(true), + Ok(("Program Files\\LLVM\\bin".into(), "libclang.dll".into())), + ); +} diff --git a/third_party/rust/clang-sys/tests/header.h b/third_party/rust/clang-sys/tests/header.h new file mode 100644 index 0000000000..5c392d3145 --- /dev/null +++ b/third_party/rust/clang-sys/tests/header.h @@ -0,0 +1,6 @@ +#ifndef HEADER_H_ +#define HEADER_H_ + +int add(int a, int b); + +#endif diff --git a/third_party/rust/clang-sys/tests/lib.rs b/third_party/rust/clang-sys/tests/lib.rs new file mode 100644 index 0000000000..f906f9b329 --- /dev/null +++ b/third_party/rust/clang-sys/tests/lib.rs @@ -0,0 +1,55 @@ +extern crate clang_sys; +extern crate libc; + +use std::ptr; + +use clang_sys::*; + +use libc::c_char; + +fn parse() { + unsafe { + let index = clang_createIndex(0, 0); + assert!(!index.is_null()); + + let tu = clang_parseTranslationUnit( + index, + "tests/header.h\0".as_ptr() as *const c_char, + ptr::null_mut(), + 0, + ptr::null_mut(), + 0, + 0, + ); + assert!(!tu.is_null()); + } +} + +#[cfg(feature = "runtime")] +#[test] +fn test() { + load().unwrap(); + let library = get_library().unwrap(); + println!("{:?} ({:?})", library.version(), library.path()); + parse(); + unload().unwrap(); +} + +#[cfg(not(feature = "runtime"))] +#[test] +fn test() { + parse(); +} + +#[test] +fn test_support() { + let clang = support::Clang::find(None, &[]).unwrap(); + println!("{:?}", clang); +} + +#[test] +fn test_support_target() { + let args = &["-target".into(), "x86_64-unknown-linux-gnu".into()]; + let clang = support::Clang::find(None, args).unwrap(); + println!("{:?}", clang); +} -- cgit v1.2.3