Handling of identifiers that can't be escaped in Rust.

This CL special-cases how Crubit handles C++ identifiers that can't
_really_ be escape using Rust's `r#foo` syntax.  There are 4 such
identifiers: `self`, `super`, `crate`, and `Self`.

The CL detects the 4 special identifiers in C++ (in
`Importer::GetTranslatedName`) rather than in Rust.  This implementation
choice has been made because:
- We already handle some naming choices on C++ side (detecting empty
  parameter names, detecting template parameter packs, injecting names
  like `__param_3`, detecting type aliases of anonymous structs).
- Some of the naming scenarios are easier to handle on C++ side because
  of access to full Clang AST information (replicating this information
  via IR is possible but burdensome).
- Moving the existing logic from C++ side to Rust seems difficult:
    - The immutable nature of IR makes it difficult to replace
      identifiers directly in `FuncParam::identifier`.
    - Replacing identifiers on-the-fly is difficult, because identifing
      duplicate parameter names (originating from template parameter
      packs) requires looking at more than a single parameter.

There are arguments for handling the 4 special Rust identifiers on
Rust side (in `src_code_gen.rs`), but they seem less important than
the items above.  These arguments are:
- Some names are already handled on Rust side - e.g. anonymous members
  result in field names like `__unnamed_field3`.
- It seems natural to handle Rust quirks on Rust side and
  `make_rs_ident` seems like a natural place for this.
- Most of the source code generation happens in `src_code_gen.rs`.

PiperOrigin-RevId: 511919489
14 files changed
tree: 65f7b87c9cd9242d95ea9d03f1bdaa04495cb106
  1. .bazelci/
  2. bazel/
  3. cc_bindings_from_rs/
  4. common/
  5. docs/
  6. lifetime_analysis/
  7. lifetime_annotations/
  8. migrator/
  9. nullability_verification/
  10. rs_bindings_from_cc/
  11. support/
  12. .bazelrc
  13. .gitignore
  14. BUILD
  15. Cargo.Bazel.lock
  16. CODE_OF_CONDUCT
  17. CONTRIBUTING
  18. LICENSE
  19. README.md
  20. WORKSPACE
README.md

Crubit: C++/Rust Bidirectional Interop Tool

Build status

Extremely experimental interop tooling for C++ and Rust.

Please don‘t use, this is an experiment and we don’t yet know where will it take us. There will be breaking changes without warning. Unfortunately, we can't take contributions at this point.

Building Crubit

$ apt install clang lld bazel
$ git clone git@github.com:google/crubit.git
$ cd crubit
$ bazel build --linkopt=-fuse-ld=/usr/bin/ld.lld //rs_bindings_from_cc:rs_bindings_from_cc_impl

Using a prebuilt LLVM tree

$ git clone https://github.com/llvm/llvm-project
$ cd llvm-project
$ CC=clang CXX=clang++ cmake -S llvm -B build -DLLVM_ENABLE_PROJECTS='clang' -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=install
$ cmake --build build -j
$ # wait...
$ cmake --install build
$ cd ../crubit
$ LLVM_INSTALL_PATH=../llvm-project/install bazel build //rs_bindings_from_cc:rs_bindings_from_cc_impl