Support `__crubit::annotate(cpp_name="X")` to rename Rust function names that are C++ reserved keywords.

We keep the thunk name untouched for two reasons:

1. First, it doesn't affect the C++ usage.
2. We can avoid demangling and mangling the thunk name as there is no straight-forward way to replace the name in the thunk name.

PiperOrigin-RevId: 648856269
Change-Id: I3e5c1d2f6822e0a750298c0195efa183162139ba
diff --git a/bazel/llvm.bzl b/bazel/llvm.bzl
index 8312583..12374f3 100644
--- a/bazel/llvm.bzl
+++ b/bazel/llvm.bzl
@@ -53,7 +53,7 @@
             executable = False,
         )
 
-LLVM_COMMIT_SHA = "9b8c2fae38bcff0b16d996ee002ff1e989fa23ea"
+LLVM_COMMIT_SHA = "9ceb45cc191628926496bd33b4d52011ed519151"
 
 def llvm_loader_repository_dependencies():
     # This *declares* the dependency, but it won't actually be *downloaded* unless it's used.
diff --git a/cc_bindings_from_rs/bindings.rs b/cc_bindings_from_rs/bindings.rs
index 2144142..11ae5c9 100644
--- a/cc_bindings_from_rs/bindings.rs
+++ b/cc_bindings_from_rs/bindings.rs
@@ -1107,10 +1107,13 @@
     };
 
     let fully_qualified_fn_name = FullyQualifiedName::new(tcx, def_id);
-    let short_fn_name =
+    let unqualified_rust_fn_name =
         fully_qualified_fn_name.name.expect("Functions are assumed to always have a name");
-    let main_api_fn_name =
-        format_cc_ident(short_fn_name.as_str()).context("Error formatting function name")?;
+    let attribute = crubit_attr::get(tcx, def_id).unwrap();
+    let cpp_name = attribute.cpp_name;
+    // The generated C++ function name.
+    let main_api_fn_name = format_cc_ident(cpp_name.unwrap_or(unqualified_rust_fn_name).as_str())
+        .context("Error formatting function name")?;
 
     let mut main_api_prereqs = CcPrerequisites::default();
     let main_api_ret_type = format_ret_ty_for_cc(db, &sig)?.into_tokens(&mut main_api_prereqs);
@@ -1190,7 +1193,7 @@
         },
         None => None,
     };
-    let needs_definition = short_fn_name.as_str() != thunk_name;
+    let needs_definition = unqualified_rust_fn_name.as_str() != thunk_name;
     let main_api_params = params
         .iter()
         .skip(if method_kind.has_self_param() { 1 } else { 0 })
@@ -1329,7 +1332,7 @@
         let fully_qualified_fn_name = match struct_name.as_ref() {
             None => fully_qualified_fn_name.format_for_rs(),
             Some(struct_name) => {
-                let fn_name = make_rs_ident(short_fn_name.as_str());
+                let fn_name = make_rs_ident(unqualified_rust_fn_name.as_str());
                 let struct_name = struct_name.format_for_rs();
                 quote! { #struct_name :: #fn_name }
             }
@@ -3678,6 +3681,52 @@
         });
     }
 
+    #[test]
+    fn test_format_fn_cpp_name() {
+        let test_src = r#"
+                #![feature(register_tool)]
+                #![register_tool(__crubit)]
+
+                #[no_mangle]
+                #[__crubit::annotate(cpp_name="Create")]
+                pub fn foo() {}
+            "#;
+        test_format_item(test_src, "foo", |result| {
+            let result = result.unwrap().unwrap();
+            let main_api = &result.main_api;
+            assert!(main_api.prereqs.is_empty());
+
+            assert_rs_matches!(
+                result.rs_details,
+                quote! {
+                    #[no_mangle]
+                    extern "C" fn __crubit_thunk_foo() -> () {
+                         ::rust_out::foo()
+                    }
+                }
+            );
+
+            assert_cc_matches!(
+                main_api.tokens,
+                quote! {
+                    void Create();
+                }
+            );
+            assert_cc_matches!(
+                result.cc_details.tokens,
+                quote! {
+                    namespace __crubit_internal {
+                        extern "C" void __crubit_thunk_foo();
+                    }
+                    ...
+                    inline void Create() {
+                        return __crubit_internal::__crubit_thunk_foo();
+                    }
+                }
+            );
+        });
+    }
+
     /// `test_format_item_fn_const` tests how bindings for an `const fn` are
     /// generated.
     ///
diff --git a/cc_bindings_from_rs/crubit_attr.rs b/cc_bindings_from_rs/crubit_attr.rs
index 33bfc2c..f33e1a5 100644
--- a/cc_bindings_from_rs/crubit_attr.rs
+++ b/cc_bindings_from_rs/crubit_attr.rs
@@ -29,6 +29,18 @@
     /// For instance,
     /// `#[__crubit::annotate(internal_cc_type="std::basic_string<char>")]`
     pub cc_type: Option<Symbol>,
+    // The C++ name of the item. This allows us to rename Rust function names that are
+    // not C++-compatible like `new`.
+    //
+    // For instance,
+    //
+    // ```
+    // #[__crubit::annotate(cpp_name="Create")]
+    // pub fn new() -> i32 {...}
+    // ```
+    //
+    // will rename `new` in Rust to `Create` in C++.
+    pub cpp_name: Option<Symbol>,
 }
 
 /// Gets the `#[__crubit::annotate(...)]` attribute(s) applied to a definition.
@@ -40,6 +52,7 @@
     // reset in tests. The resulting test failures are very difficult.
     let crubit_annotate = &[Symbol::intern("__crubit"), Symbol::intern("annotate")];
     let cc_type = Symbol::intern("cc_type");
+    let cpp_name = Symbol::intern("cpp_name");
 
     let mut crubit_attr = CrubitAttr::default();
     // A quick note: the parsing logic is unfortunate, but such is life. We don't
@@ -75,6 +88,20 @@
                     "Unexpected duplicate #[__crubit::annotate(cc_type=...)]"
                 );
                 crubit_attr.cc_type = Some(s)
+            } else if arg.path == cpp_name {
+                let MetaItemKind::NameValue(value) = &arg.kind else {
+                    bail!("Invalid #[__crubit::annotate(cpp_name=...)] attribute (expected =...)");
+                };
+                let LitKind::Str(s, _raw) = value.kind else {
+                    bail!(
+                        "Invalid #[__crubit::annotate(cpp_name=...)] attribute (expected =\"...\")"
+                    );
+                };
+                ensure!(
+                    crubit_attr.cpp_name.is_none(),
+                    "Unexpected duplicate #[__crubit::annotate(cpp_name=...)]"
+                );
+                crubit_attr.cpp_name = Some(s);
             }
         }
     }
@@ -126,6 +153,34 @@
     }
 
     #[test]
+    fn test_cpp_name() {
+        let test_src = r#"
+                #![feature(register_tool)]
+                #![register_tool(__crubit)]
+                #[__crubit::annotate(cpp_name = "Create")]
+                pub fn new() -> i32 { 0 }
+            "#;
+        run_compiler_for_testing(test_src, |tcx| {
+            let attr = get(tcx, find_def_id_by_name(tcx, "new")).unwrap();
+            assert_eq!(attr.cpp_name.unwrap(), Symbol::intern("Create"));
+        });
+    }
+
+    #[test]
+    fn test_cpp_name_duplicated() {
+        let test_src = r#"
+                #![feature(register_tool)]
+                #![register_tool(__crubit)]
+                #[__crubit::annotate(cpp_name = "Create", cpp_name = "Create2")]
+                pub fn new() -> i32 { 0 }
+            "#;
+        run_compiler_for_testing(test_src, |tcx| {
+            let attr = get(tcx, find_def_id_by_name(tcx, "new"));
+            assert!(attr.is_err());
+        });
+    }
+
+    #[test]
     fn test_cc_type_multi() {
         let test_src = r#"
                 #![feature(register_tool)]