When specifying the `namespace` argument in Bazel (`NAMESPACE` in CMake), the
Clang tool used to put _all_ dependent types in that namespace.
For a declaration of `namespace a::b { struct S {...};` and a `namespace`
argument of `a::b`, this means that the header output was similar to
```
namespace a::b {
namespace a::b {
struct S { ...
```
This was never intended and also does not match the Python based header
generator. The Clang tool now "merges" those same namespaces. This is
correct, as it processes `namespace`d spellings with their full namespace
path.
PiperOrigin-RevId: 557393076
Change-Id: I1474dd30b6c4150d0ae3c1c48579f88060974980
The Python code has been relying on `spelling` to return `None` for skipping
anonymous structs/unions.
libclang has been returning a "spelling" for those for a while now (LLVM 16
introduced this in its branch in 2022), though, so this check no longer works.
Use the correct method `clang.CIndex.is_anonymous()` instead.
PiperOrigin-RevId: 557099905
Change-Id: I13707509dbae03481c5edce7fa92554cefdd57e7
To avoid code that is being parsed to include the intrinsics headers, undefine
a few key preprocessor defines.
PiperOrigin-RevId: 539878995
Change-Id: I8afb7cbdadcab3214c943c0acb9006e8bcc30611
- Abseil
- Protobuf
- Benchmark
- Googletest
In turn, some code changes were necessary:
- Use absolute imports in `sapi_generator.py` when invoked by Bazel
- Add Abseil's source dir as include dir in generated proto `.cc` files
- Bazel: Use `@rules_proto` for `proto_library` and use native `cc_proto_library`
Drive-by:
- Update year in `README.md`
- Look for clang versions 16, 15, 14, and 13 as well in `code.py`
PiperOrigin-RevId: 539032012
Change-Id: Ib9cd1d7fb38409d884eb45e1fa08927f6af83a21
This should only affect the Bazel `BUILD.bazel` files and their formatting.
PiperOrigin-RevId: 538426054
Change-Id: I0162726d3fb4bcb4d7938cddc6f39e0d9f2b4a3d
Drive-by:
- Add flags to link libgcc and libstdc++ statically into the binary, making it
"mostly static"
PiperOrigin-RevId: 532349354
Change-Id: I0a86eb29b6a40aec4cec3cffeaf9511726ee4dc8
Tested on Debian 10.13 with `LLVM-{11,12,13,14,15,16,17}` packages from https://apt.llvm.org/.
PiperOrigin-RevId: 531211601
Change-Id: I91babb5d85be2a22a4b17d757a5f626de6c03881
Use locally unqualified types to filter ordered type declarations in
`TypeCollector::GetTypeDeclarations()`. This is necessary, as
`clang::TypeName::getFullyQualifiedName()` and
`TypeDecl::getQualifiedNameAsString()` have different ideas which
qualifiers belong to the name. The former works on `QualType`s, while
the latter deals with the declaration directly. This change decays a
`TypeDecl` into its locally unqualified `QualType`.
PiperOrigin-RevId: 490500091
Change-Id: Ie2f4eece4e673f8b06ab6661d7b6611daf34fba9
Do not try to peel off all layers of pointers/references when collecting
types, recursion works well here. Also collect the function type itself,
even if it is a pointer or if the function was the underlying type of a
typedef.
PiperOrigin-RevId: 490475937
Change-Id: I13cb3d9d3de7d25b9e627f43112c46758c7e6a22
This change changes the emitter to work on `clang::TypeDecl`s instead of
`clang::QualType`s, as the latter only describe complete definitions. This
allows us to better deal with situations where we would otherwise have a kind
of circular type dependencies: For example, a `typedef` that depends on a
`struct` which in turn has a member that references the typedef.
For this to work, we now also record the actual source order of declarations,
similar to what the libclang based header generator does.
Also add some more tests for the newly covered cases.
PiperOrigin-RevId: 488370914
Change-Id: I2d1baa863fb12d1801bf11a20f3f88df7fde3129
When generating headers from libraries that export functions as `extern "C"`
but still use namespaces (C-compatible C++ libraries), we want to generate
a Sandboxed API that includes fully-qualified namespace names as well.
In addition, we want the generated API to have the same source order as the
original library. Not only is this less surprising when reading the generated
code, it's also more accurate. Previously, we'd bundle all definitions in a
namespace and sort those alphabetically, but for code that relies on symbols
from another namespace to be available, generation will fail:
```c++
namespace zzz {
using entity_count_t = uint64_t;
} // namespace zzz
namespace sheep_counter {
using sheep_count_t = :💤:entity_count_t;
extern "C" void IncreaseSheepCounter(sheep_count_t increment);
} // namespace sheep_counter
```
PiperOrigin-RevId: 486586024
Change-Id: I419c9db8e9cb5b904364b353e2dc3d7f1030fab3
An `absl::StatusCode` of `kCancelled` now indicates warnings inside the emitter.
PiperOrigin-RevId: 485851898
Change-Id: I10a57cbc1b6c2d4b708c3c19aa0fa71451845a22
The libclang based header generator disallows functions that pass structs (or
more generally "record types") by value. While this can be implemented, the
such functions as emitted by the clang_generator never worked.
We should revisit this when we implement support for passing 128-bit integer
types directly, as those will work the same as small structs.
PiperOrigin-RevId: 485522603
Change-Id: Iae8284720da52496d7a48fe3ca3c3c8605e6d19d
This makes it easier to write tests with expected compilation/parsing failures.
PiperOrigin-RevId: 485331205
Change-Id: Ia545934849d38bded9320537c71e970fb4730cb6
Follow-up changes might be required to fully fix up the contrib sandboxes.
PiperOrigin-RevId: 482475998
Change-Id: Iff631eb838a024b2f047a1be61bb27e35a8ff2f4
When not requesting any particular function, `sapi_library()` will try and
make available _all_ functions it finds. In this case, system headers should
be skipped to avoid inflating the API surface. Standard library functions
can still be manually requested by adding them to the `functions` (Bazel)/
`FUNCTIONS` (CMake) argument.
PiperOrigin-RevId: 472272506
Change-Id: I8f8d79796d3044e598eebb7f87ce4cf464b47ed7
`BUILD_TESTING` is a CMake provided option and we should use similar naming,
just like how Abseil does it.
- `SAPI_ENABLE_TESTS` -> `SAPI_BUILD_TESTING`
- `SAPI_ENABLE_CONTRIB_TESTS` -> `SAPI_CONTRIB_BUILD_TESTING`
- `SAPI_ENABLE_EXAMPLES` -> `SAPI_BUILD_EXAMPLES`
Drive-by:
- Fix option name in GitHub action
PiperOrigin-RevId: 443305932
Change-Id: Ice2b42be1229a0f9ae7c2ceda9ce87187baf22c4
Including the `CTest` modules ensures that the `BUILD_TESTING` option is
defined and automatically calls `enable_testing()` if needed. It does not
change the default or introduce any dependencies on its own.
This follows what Abseil already does in their top-level `CMakeLists.txt`.
PiperOrigin-RevId: 443305646
Change-Id: If067c17470f497437c7748aab4aab5227c26e84f
The corresponding command-line option `sapi_isystem` will be ignored for
compatibility.
PiperOrigin-RevId: 439806387
Change-Id: I8ad6d7feed2fba5fca9940281f03cfc757ada5be
This change introduces an experimental `generator_version` attribute to the
`sapi_library()` rule. Version `1` will select the current interface
generator, which is based on libclang and Python. Setting the attribute to
version `2`, will select the newer interface generator written in C++ that
uses a full clang compiler frontend for parsing. Both emit equivalent header
output, differences in parsing and/or edge cases notwithstanding.
The default, as of now, is still the old version `1` generator.
Note: CMake allows to select the new interface generator globally by setting
`SAPI_ENABLE_GENERATOR`.
PiperOrigin-RevId: 438765013
Change-Id: I69c49a6bcf1751724edb0bce5c3b2beea2097138
This adds a workspace rule that inspects the current system first and
downloads a suitable version of LLVM/Clang from GitHub if it can't
find one. In the latter case, the necessary parts are build from source,
which can take a while (~10-15m, depending on the build machine).
In order to be found, LLVM/Clang system libraries must be version 11
or higher. On Debian/Ubuntu, install `llvm-13-dev` and `libclang-13-dev`.
The new `llvm_config.bzl` implements this logic. It is loosely based on
upstream's https://github.com/llvm/llvm-project/blob/main/utils/bazel/configure.bzl.
Note that due to the way Bazel separates local repositories, we have to
duplictate some of this code.
PiperOrigin-RevId: 438759950
Change-Id: Ia65f473b4cdef6507e3816bf09794ea10963d87a
This uses the Google formatting style to format the prototype comments, with an
internal line length of 75, which accomodates the indentation in the generated
API class.
PiperOrigin-RevId: 435303665
Change-Id: I4dcdf0ed773a79ebc55ead3843f07ca8556fd985
This implements a custom compilation database to conditionally add the correct
language flags to the compiler frontend. Otherwise, a C header might receive
`--std=c++17` and fail.
Note: All headers are always processed in C++ mode. We expect that headers of
well-behaved C libraries contain `#ifdef __cplusplus`/`extern "C" {}` guards.
PiperOrigin-RevId: 435302048
Change-Id: Ib84e6e1f301ba434999846a012b3f8c16884648e
The enclosing type is enough to reconstruct the AST when writing the header and this
change avoids emitting the same struct twice.
PiperOrigin-RevId: 435300029
Change-Id: I34bd660db5ba5c68b64cce73ecf2f026727ac57b
This is a follow up to fa9e6e8a5c.
Drive-by:
- Replace deprecated calls to `getNameAsString()`
PiperOrigin-RevId: 435287759
Change-Id: I81d8c2f93b1ab23c781421b114779b7a241e4a7e
There are a lot of internal users depending on the old behavior of the
libclang-based generator.
PiperOrigin-RevId: 432281224
Change-Id: If82333fc3001f52de59e57a874f28bf8815d0877