Fix contention between Clang and Carbon over external name lookup. (#7411)

The function to set the visible declarations with a given name
overwrites any existing declarations imported from an AST file, so we
need to avoid calling that for declaration contexts whose names are
managed by Clang to avoid clobbering names imported from modules.

Assisted-by: Gemini via Antigravity
This commit is contained in:
Richard Smith
2026-06-24 18:36:59 +00:00
committed by GitHub
parent 999dcc5bf0
commit f2d99f31f0
2 changed files with 68 additions and 5 deletions
+15 -5
View File
@@ -523,12 +523,22 @@ auto CarbonExternalASTSource::FindExternalVisibleDeclsByName(
// Find the Carbon declaration corresponding to this Clang declaration.
auto* decl = cast<clang::Decl>(
const_cast<clang::DeclContext*>(decl_context->getPrimaryContext()));
if (isa<clang::FunctionDecl>(decl)) {
// Functions don't meaningfully have visible decls, but bail out early since
// we can't form a `ClangDeclKey` for a function in the abstract.
return false;
}
auto key = SemIR::ClangDeclKey::ForNonFunctionDecl(decl);
auto decl_id = context_->clang_decls().LookupId(key);
CARBON_CHECK(
decl_id.has_value(),
"The DeclContext should already be associated with a Carbon InstId.");
auto decl_context_inst_id = context_->clang_decls().Get(decl_id).inst_id;
if (!decl_id.has_value()) {
return false;
}
auto clang_decl = context_->clang_decls().Get(decl_id);
if (clang_decl.is_imported) {
// This is imported from C++, presumably from a Clang AST file, so it's not
// our responsibility to provide its name lookup results.
return false;
}
llvm::SmallVector<Check::LookupScope> lookup_scopes;
@@ -536,7 +546,7 @@ auto CarbonExternalASTSource::FindExternalVisibleDeclsByName(
// here - completeness should've been checked by clang before this point.
if (!AppendLookupScopesForConstant(
*context_, SemIR::LocId::None,
context_->constant_values().Get(decl_context_inst_id),
context_->constant_values().Get(clang_decl.inst_id),
SemIR::ConstantId::None, /*extended_scope=*/false, &lookup_scopes)) {
return false;
}