Files
carbon-lang/toolchain/check/cpp/import.h
T
David Blaikie f1f6005d4a Perform Clang IRGen during check (#6569)
Background:
https://docs.google.com/document/d/1wi85FRiWh4X9A-gCYMVGKR40-q5fM6-3JaSpePk-XCY/edit?usp=sharing
And specifically this work is essentially an alternative to #5543

Clang's code generation is implemented through an ASTListener
(clang::CodeGenerator) that is attached throughout Clang's
parsing/sema/code
generation phases and acts on Clang AST incrementally throughout that
process.

Prior to this patch, Carbon has only created the CodeGenerator during
Carbon's
`lower` phase, missing out on key callbacks that would be made by Clang
during
`check`. Some of these issues were addressed by #6237 and #6483 - but
there were
still remaining cases where the delayed processing lead to missing
functionality.

With #6483 much of the Clang code that made multithreaded complexity of
#5543 is
no longer present, and we have access to the point of ASTListener
registration
so we can register the CodeGenerator there and consume its resulting
llvm::Module during lower.

Examples of some of the bugs this addresses are seen in the linked doc,
and
checked in as tests in this change in
`clang_code_generator_callbacks.carbon`

An indicental bug that's also fixed, and caused all the other test case
churn,
is that the `CodeGenerator` created during `lower` wasn't getting passed
the
Clang `CodeGenOpts` and was creating its own default - so, most notably,
optimization flags were not respected. This meant that the LLVM IR from
Clang
was always -O0 style IR (optnone, no inlinehint, no TBAA, etc). With
this
change, now the Clang IRGen gets the real `CodeGenOpts` and respects
optimization/other flags specified there.

This is only meant to be a rough proof of concept - I'm totally open to
reworking this in any way (even quite substantially) if folks have ideas
about
how this should be implemented most generally/elegantly/etc.
2026-01-14 00:54:37 +00:00

80 lines
3.7 KiB
C++

// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#ifndef CARBON_TOOLCHAIN_CHECK_CPP_IMPORT_H_
#define CARBON_TOOLCHAIN_CHECK_CPP_IMPORT_H_
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "toolchain/check/context.h"
#include "toolchain/check/convert.h"
#include "toolchain/check/diagnostic_helpers.h"
#include "toolchain/diagnostics/diagnostic_emitter.h"
#include "toolchain/sem_ir/ids.h"
namespace Carbon::Check {
// Generates a C++ header that includes the imported cpp files, parses it,
// generates the AST from it and links `SemIR::File` to it. Reports C++ errors
// and warnings. If successful, adds a `Cpp` namespace.
auto ImportCpp(Context& context,
llvm::ArrayRef<Parse::Tree::PackagingNames> imports,
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs,
llvm::LLVMContext* llvm_context,
std::shared_ptr<clang::CompilerInvocation> invocation) -> void;
// Imports a declaration from Clang to Carbon. If successful, returns the new
// Carbon declaration `InstId`. If the declaration was already imported, returns
// the mapped instruction. All unimported dependencies are imported first.
auto ImportCppDecl(Context& context, SemIR::LocId loc_id,
SemIR::ClangDeclKey key) -> SemIR::InstId;
// Imports a function declaration from Clang to Carbon. If successful, returns
// the new Carbon function declaration `InstId`. If the declaration was already
// imported, returns the mapped instruction.
inline auto ImportCppFunctionDecl(Context& context, SemIR::LocId loc_id,
clang::FunctionDecl* clang_decl,
int num_params) -> SemIR::InstId {
return ImportCppDecl(
context, loc_id,
SemIR::ClangDeclKey::ForFunctionDecl(clang_decl, num_params));
}
// Imports a function declaration from Clang to Carbon. If successful, returns
// the new Carbon function declaration `InstId`. If the declaration was already
// imported, returns the mapped instruction. All unimported dependencies are
// imported first.
auto ImportCppType(Context& context, SemIR::LocId loc_id, clang::QualType type)
-> TypeExpr;
// Imports an overloaded function set from Clang to Carbon.
auto ImportCppOverloadSet(
Context& context, SemIR::LocId loc_id, SemIR::NameScopeId scope_id,
SemIR::NameId name_id, clang::CXXRecordDecl* naming_class,
clang::UnresolvedSet<4>&& overload_set,
clang::OverloadCandidateSet::OperatorRewriteInfo operator_rewrite_info)
-> SemIR::InstId;
// Looks up the given name in the Clang AST generated when importing C++ code
// and returns a lookup result. If using the injected class name (`X.X()`),
// imports the class constructor as a function named as the class.
auto ImportNameFromCpp(Context& context, SemIR::LocId loc_id,
SemIR::NameScopeId scope_id, SemIR::NameId name_id)
-> SemIR::ScopeLookupResult;
// Given a Carbon class declaration that was imported from some kind of C++
// declaration, such as a class or enum, attempt to import a corresponding class
// definition. Returns true if nothing went wrong (whether or not a definition
// could be imported), false if a diagnostic was produced.
auto ImportClassDefinitionForClangDecl(Context& context, SemIR::LocId loc_id,
SemIR::ClassId class_id,
SemIR::ClangDeclId clang_decl_id)
-> bool;
} // namespace Carbon::Check
#endif // CARBON_TOOLCHAIN_CHECK_CPP_IMPORT_H_