From 0f171611d442ebdd5e21db023adf1b9855158a96 Mon Sep 17 00:00:00 2001 From: Boaz Brickner Date: Thu, 7 Aug 2025 16:50:46 +0200 Subject: [PATCH] Create `clang::MangleContext` once per file instead of once per C++ thunk (#5924) Part of #5514. --- toolchain/check/cpp_thunk.cpp | 26 ++++++++++---------------- toolchain/sem_ir/file.cpp | 8 ++++++++ toolchain/sem_ir/file.h | 10 +++++++++- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/toolchain/check/cpp_thunk.cpp b/toolchain/check/cpp_thunk.cpp index 508a08e9ec7e..8db03d43d0bf 100644 --- a/toolchain/check/cpp_thunk.cpp +++ b/toolchain/check/cpp_thunk.cpp @@ -20,17 +20,11 @@ namespace Carbon::Check { // Returns the C++ thunk mangled name given the callee function. static auto GenerateThunkMangledName( - clang::ASTContext& ast_context, + clang::MangleContext& mangle_context, const clang::FunctionDecl& callee_function_decl) -> std::string { RawStringOstream mangled_name_stream; - { - // TODO: Create `MangleContext` once. - std::unique_ptr mangle_context( - ast_context.createMangleContext()); - mangle_context->mangleName(clang::GlobalDecl(&callee_function_decl), - mangled_name_stream); - } - + mangle_context.mangleName(clang::GlobalDecl(&callee_function_decl), + mangled_name_stream); mangled_name_stream << ".carbon_thunk"; return mangled_name_stream.TakeStr(); @@ -185,9 +179,9 @@ static auto BuildThunkParameters( // Returns the thunk function declaration given the callee function and the // thunk parameter types. static auto CreateThunkFunctionDecl( - clang::ASTContext& ast_context, - const clang::FunctionDecl& callee_function_decl, + Context& context, const clang::FunctionDecl& callee_function_decl, llvm::ArrayRef thunk_param_types) -> clang::FunctionDecl* { + clang::ASTContext& ast_context = context.ast_context(); clang::SourceLocation clang_loc = callee_function_decl.getLocation(); clang::IdentifierInfo& identifier_info = ast_context.Idents.get( @@ -216,7 +210,9 @@ static auto CreateThunkFunctionDecl( // Set asm(".carbon_thunk"). thunk_function_decl->addAttr(clang::AsmLabelAttr::CreateImplicit( - ast_context, GenerateThunkMangledName(ast_context, callee_function_decl), + ast_context, + GenerateThunkMangledName(*context.sem_ir().clang_mangle_context(), + callee_function_decl), clang_loc)); return thunk_function_decl; @@ -278,8 +274,6 @@ static auto BuildThunkBody(clang::Sema& sema, auto BuildCppThunk(Context& context, const SemIR::Function& callee_function) -> clang::FunctionDecl* { - clang::ASTContext& ast_context = context.ast_context(); - clang::FunctionDecl* callee_function_decl = context.sem_ir() .clang_decls() @@ -289,9 +283,9 @@ auto BuildCppThunk(Context& context, const SemIR::Function& callee_function) // Build the thunk function declaration. auto [thunk_param_types, param_type_changed] = - BuildThunkParameterTypes(ast_context, *callee_function_decl); + BuildThunkParameterTypes(context.ast_context(), *callee_function_decl); clang::FunctionDecl* thunk_function_decl = CreateThunkFunctionDecl( - ast_context, *callee_function_decl, thunk_param_types); + context, *callee_function_decl, thunk_param_types); // Build the thunk function body. clang::Sema& sema = context.sem_ir().cpp_ast()->getSema(); diff --git a/toolchain/sem_ir/file.cpp b/toolchain/sem_ir/file.cpp index a9f0edb49e26..d690661067ac 100644 --- a/toolchain/sem_ir/file.cpp +++ b/toolchain/sem_ir/file.cpp @@ -8,6 +8,7 @@ #include #include +#include "clang/AST/Mangle.h" #include "common/check.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" @@ -54,6 +55,8 @@ File::File(const Parse::Tree* parse_tree, CheckIRId check_ir_id, } } +File::~File() = default; + auto File::Verify() const -> ErrorOr { // Invariants don't necessarily hold for invalid IR. if (has_errors_) { @@ -147,4 +150,9 @@ auto File::CollectMemUsage(MemUsage& mem_usage, llvm::StringRef label) const mem_usage.Collect(MemUsage::ConcatLabel(label, "types_"), types_); } +auto File::set_cpp_ast(clang::ASTUnit* cpp_ast) -> void { + cpp_ast_ = cpp_ast; + clang_mangle_context_.reset(cpp_ast->getASTContext().createMangleContext()); +} + } // namespace Carbon::SemIR diff --git a/toolchain/sem_ir/file.h b/toolchain/sem_ir/file.h index 10d6bc343026..f22a9d3883e2 100644 --- a/toolchain/sem_ir/file.h +++ b/toolchain/sem_ir/file.h @@ -76,6 +76,7 @@ class File : public Printable { SharedValueStores& value_stores, std::string filename); File(const File&) = delete; + ~File(); auto operator=(const File&) -> File& = delete; // Verifies that invariants of the semantics IR hold. @@ -198,7 +199,10 @@ class File : public Printable { // TODO: When the AST can be created before creating `File`, initialize the // pointer in the constructor and remove this function. This is part of // https://github.com/carbon-language/carbon-lang/issues/4666 - auto set_cpp_ast(clang::ASTUnit* cpp_ast) -> void { cpp_ast_ = cpp_ast; } + auto set_cpp_ast(clang::ASTUnit* cpp_ast) -> void; + auto clang_mangle_context() -> clang::MangleContext* { + return clang_mangle_context_.get(); + } auto clang_decls() -> ClangDeclStore& { return clang_decls_; } auto clang_decls() const -> const ClangDeclStore& { return clang_decls_; } auto names() const -> NameStoreWrapper { @@ -333,6 +337,10 @@ class File : public Printable { // `Cpp` imports. clang::ASTUnit* cpp_ast_ = nullptr; + // The Clang mangle context for the target in the ASTContext. Initialized + // together with `cpp_ast_`. + std::unique_ptr clang_mangle_context_; + // Clang AST declarations pointing to the AST and their mapped Carbon // instructions. When calling `Lookup()`, `inst_id` is ignored. `Add()` will // not add multiple entries with the same `decl` and different `inst_id`.