Support indirect C++ dependency by sharing domains more broadly (#7763)

Fixes #7731, at least under `--share-cpp-ast` which is expected to be
the future direction.

When --share-cpp-ast is enabled and any compilation unit has C++
imports, include all compilation units in the shared CppDomain inputs
and assign the domain to every unit. In ImportCpp, when a unit has no
direct C++ imports but is covered by a shared CppDomain, initialize
its C++ AST context and import namespace. This ensures units without
direct C++ imports have access to the C++ AST and code generator when
instantiating generics or referencing declarations from units that do.

Assisted-by: Antigravity with Gemini
This commit is contained in:
David Blaikie
2026-09-15 20:45:18 +00:00
committed by GitHub
parent 37949a2066
commit 9e68ee0806
4 changed files with 297 additions and 124 deletions
+21 -12
View File
@@ -99,13 +99,28 @@ auto AddIdentifierName(Context& context, llvm::StringRef name)
}
// Adds a namespace for the `Cpp` import and returns its `NameScopeId`.
static auto AddNamespace(Context& context, PackageNameId cpp_package_id,
static auto AddNamespace(Context& context,
llvm::ArrayRef<Parse::Tree::PackagingNames> imports)
-> SemIR::NameScopeId {
if (imports.empty()) {
return AddImportNamespace(
context,
GetSingletonType(context, SemIR::NamespaceType::TypeInstId),
SemIR::NameId::Cpp, SemIR::NameScopeId::Package,
/*import_id=*/SemIR::InstId::None)
.name_scope_id;
}
PackageNameId package_id = imports.front().package_id;
CARBON_CHECK(
llvm::all_of(imports, [&](const Parse::Tree::PackagingNames& import) {
return import.package_id == package_id;
}));
return AddImportNamespaceToScope(
context,
GetSingletonType(context, SemIR::NamespaceType::TypeInstId),
SemIR::NameId::ForPackageName(cpp_package_id),
SemIR::NameId::ForPackageName(package_id),
SemIR::NameScopeId::Package,
/*diagnose_duplicate_namespace=*/false,
[&] {
@@ -121,19 +136,13 @@ static auto AddNamespace(Context& context, PackageNameId cpp_package_id,
auto ImportCpp(Context& context,
llvm::ArrayRef<Parse::Tree::PackagingNames> imports,
SemIR::CppDomain* domain) -> void {
if (imports.empty()) {
// TODO: Consider always having a (non-null) AST even if there are no Cpp
// imports.
// If there are no direct C++ imports and no shared domain covers this unit,
// there is nothing to import.
if (imports.empty() && !domain) {
return;
}
PackageNameId package_id = imports.front().package_id;
CARBON_CHECK(
llvm::all_of(imports, [&](const Parse::Tree::PackagingNames& import) {
return import.package_id == package_id;
}));
auto name_scope_id = AddNamespace(context, package_id, imports);
auto name_scope_id = AddNamespace(context, imports);
SemIR::NameScope& name_scope = context.name_scopes().Get(name_scope_id);
name_scope.set_is_closed_import(true);