Improve ClangDeclStore ergonomics (#7311)

Change `Lookup` by InstId to return a ClangDecl pointer. All callers
were immediately calling `Get` anyway, so this makes call sites a little
shorter. The other `Lookup` method, by ClangDeclKey, is sometimes called
without calling `Get`, so left that as-is, but renamed to `LookupId`.

Also add a `decl` method to ClangDecl so that the commonly repeated
`clang_decl->key.decl` can be written `clang_decl->decl()`.
This commit is contained in:
Nicholas Bishop
2026-06-05 20:49:34 +00:00
committed by GitHub
parent 44b17ff436
commit 5e62791ad2
16 changed files with 70 additions and 95 deletions
+2 -2
View File
@@ -140,7 +140,7 @@ static auto ConvertArgToTemplateArg(
context.types().TryGetAs<SemIR::CppTemplateNameType>(
inst.type_id())) {
clang::TemplateName name(cast<clang::TemplateDecl>(
context.clang_decls().Get(template_name_type->decl_id).key.decl));
context.clang_decls().Get(template_name_type->decl_id).decl()));
return clang::TemplateArgumentLoc(
context.ast_context(), clang::TemplateArgument(name),
/*TemplateKWLoc=*/clang::SourceLocation(),
@@ -346,7 +346,7 @@ auto PerformCallToCppTemplateName(Context& context, SemIR::LocId loc_id,
llvm::ArrayRef<SemIR::InstId> arg_ids)
-> SemIR::InstId {
auto* template_decl = dyn_cast<clang::TemplateDecl>(
context.clang_decls().Get(template_decl_id).key.decl);
context.clang_decls().Get(template_decl_id).decl());
auto loc = GetCppLocation(context, loc_id);
// Form a template argument list for this template.
+4 -8
View File
@@ -219,13 +219,11 @@ static auto ConvertArgToExpr(Context& context, SemIR::InstId arg_inst_id,
}
auto EvalCppCall(Context& context, SemIR::LocId loc_id,
SemIR::ClangDeclId clang_decl_id, SemIR::InstBlockId args_id)
const SemIR::ClangDecl& clang_decl, SemIR::InstBlockId args_id)
-> SemIR::ConstantId {
const auto& args = context.inst_blocks().Get(args_id);
auto* decl = context.clang_decls().Get(clang_decl_id).GetAsKey().decl;
auto* function_decl = cast<clang::FunctionDecl>(decl);
auto* function_decl = cast<clang::FunctionDecl>(clang_decl.decl());
// Create expr for the function declaration.
auto* decl_ref_expr = clang::DeclRefExpr::Create(
@@ -305,10 +303,8 @@ auto MaybeModifyCppThunkCallForConstEval(Context& context, SemIR::Call* call)
function_decl = cast<clang::FunctionDecl>(
context.clang_decls()
.Get(context.clang_decls().Lookup(
thunk_callee_function.first_decl_id()))
.GetAsKey()
.decl);
.Lookup(thunk_callee_function.first_decl_id())
->decl());
if (!(function_decl->isConstexpr() || function_decl->isConsteval())) {
return;
+1 -1
View File
@@ -31,7 +31,7 @@ auto EvalCppVarDecl(Context& context, SemIR::LocId loc_id,
// Attempt to evaluate a call to a C++ constexpr/consteval function as a
// Carbon constant.
auto EvalCppCall(Context& context, SemIR::LocId loc_id,
SemIR::ClangDeclId clang_decl_id, SemIR::InstBlockId args_id)
const SemIR::ClangDecl& clang_decl, SemIR::InstBlockId args_id)
-> SemIR::ConstantId;
// If the callee is a C++ thunk, modify `call` to directly call the
+10 -15
View File
@@ -38,7 +38,7 @@ static auto GetClangDeclContextForScope(Context& context,
if (!clang_decl_context_id.has_value()) {
return nullptr;
}
auto* decl = context.clang_decls().Get(clang_decl_context_id).key.decl;
auto* decl = context.clang_decls().Get(clang_decl_context_id).decl();
return cast<clang::DeclContext>(decl);
}
@@ -137,11 +137,9 @@ auto ExportClassToCpp(Context& context, SemIR::LocId loc_id,
// If this class was produced by importing a C++ declaration or has
// already been exported to C++, return the corresponding Clang declaration.
// That could either be a CXXRecordDecl or an EnumDecl.
if (auto clang_decl_id =
context.clang_decls().Lookup(class_info.first_decl_id());
clang_decl_id.has_value()) {
return cast<clang::TagDecl>(
context.clang_decls().Get(clang_decl_id).key.decl);
if (const auto* clang_decl =
context.clang_decls().Lookup(class_info.first_decl_id())) {
return cast<clang::TagDecl>(clang_decl->decl());
}
auto* identifier_info = GetClangIdentifierInfo(context, class_info.name_id);
@@ -308,12 +306,10 @@ auto ExportFieldToCpp(Context& context, SemIR::InstId field_inst_id,
ExportAllFieldsToCpp(context, class_info);
// Get the exported `clang::FieldDecl`.
auto clang_decl_id = context.clang_decls().Lookup(field_inst_id);
if (clang_decl_id == SemIR::ClangDeclId::None) {
return nullptr;
if (const auto* clang_decl = context.clang_decls().Lookup(field_inst_id)) {
return cast<clang::FieldDecl>(clang_decl->decl());
}
return cast<clang::FieldDecl>(
context.clang_decls().Get(clang_decl_id).key.decl);
return nullptr;
}
auto CalculateCppFieldOffsets(
@@ -957,10 +953,9 @@ auto ExportVarToCpp(Context& context, SemIR::InstId inst_id,
// Check if the variable was already exported and return the existing
// `VarDecl` if so. Note that the `pattern_id` is used as the key
// rather than the `InstId` for the `VarStorage`.
auto clang_decl_id = context.clang_decls().Lookup(var_storage.pattern_id);
if (clang_decl_id.has_value()) {
return cast<clang::VarDecl>(
context.clang_decls().Get(clang_decl_id).key.decl);
if (const auto* clang_decl =
context.clang_decls().Lookup(var_storage.pattern_id)) {
return cast<clang::VarDecl>(clang_decl->decl());
}
// Look up the entity name and check the scope.
+5 -6
View File
@@ -447,10 +447,9 @@ auto CarbonExternalASTSource::GetOrExportFunctionToCpp(
SemIR::InstId target_inst_id, SemIR::FunctionId function_id)
-> clang::FunctionDecl* {
SemIR::Function& function = context_->functions().Get(function_id);
auto clang_decl_id = context_->clang_decls().Lookup(function.first_decl_id());
if (clang_decl_id.has_value()) {
return cast<clang::FunctionDecl>(
context_->clang_decls().Get(clang_decl_id).key.decl);
if (const auto* clang_decl =
context_->clang_decls().Lookup(function.first_decl_id())) {
return cast<clang::FunctionDecl>(clang_decl->decl());
}
auto* clang_function_decl =
@@ -510,7 +509,7 @@ auto CarbonExternalASTSource::FindExternalVisibleDeclsByName(
auto* decl = cast<clang::Decl>(
const_cast<clang::DeclContext*>(decl_context->getPrimaryContext()));
auto key = SemIR::ClangDeclKey::ForNonFunctionDecl(decl);
auto decl_id = context_->clang_decls().Lookup(key);
auto decl_id = context_->clang_decls().LookupId(key);
CARBON_CHECK(
decl_id.has_value(),
"The DeclContext should already be associated with a Carbon InstId.");
@@ -591,7 +590,7 @@ static auto GetAsCarbonOwnedClass(Context& context,
auto key = SemIR::ClangDeclKey::ForNonFunctionDecl(
const_cast<clang::TagDecl*>(tag_decl->getFirstDecl()));
auto clang_decl_id = context.clang_decls().Lookup(key);
auto clang_decl_id = context.clang_decls().LookupId(key);
if (!clang_decl_id.has_value()) {
return std::nullopt;
}
+1 -1
View File
@@ -64,7 +64,7 @@ static auto TypeAsTagDecl(Context& context,
return nullptr;
}
return dyn_cast<clang::TagDecl>(context.clang_decls().Get(decl_id).key.decl);
return dyn_cast<clang::TagDecl>(context.clang_decls().Get(decl_id).decl());
}
// If the given type is a C++ class type, returns the corresponding class
+8 -10
View File
@@ -378,7 +378,7 @@ static auto GetDeclContext(Context& context, SemIR::NameScopeId scope_id)
auto scope_clang_decl_context_id =
context.name_scopes().Get(scope_id).clang_decl_context_id();
return dyn_cast<clang::DeclContext>(
context.clang_decls().Get(scope_clang_decl_context_id).key.decl);
context.clang_decls().Get(scope_clang_decl_context_id).decl());
}
// Returns true if the given Clang declaration is the implicit injected class
@@ -399,8 +399,7 @@ static auto IsDeclInjectedClassName(Context& context,
const SemIR::ClangDecl& clang_decl = context.clang_decls().Get(
context.name_scopes().Get(scope_id).clang_decl_context_id());
const auto* scope_record_decl =
cast<clang::CXXRecordDecl>(clang_decl.key.decl);
const auto* scope_record_decl = cast<clang::CXXRecordDecl>(clang_decl.decl());
const clang::ASTContext& ast_context = context.ast_context();
CARBON_CHECK(ast_context.getCanonicalTagType(scope_record_decl) ==
@@ -441,7 +440,7 @@ static auto ClangLookupName(Context& context, SemIR::NameScopeId scope_id,
// Returns whether `decl` already mapped to an instruction.
static auto IsClangDeclImported(Context& context, SemIR::ClangDeclKey key)
-> bool {
return context.clang_decls().Lookup(key).has_value();
return context.clang_decls().LookupId(key).has_value();
}
// If `decl` already mapped to an instruction, returns that instruction.
@@ -449,7 +448,7 @@ static auto IsClangDeclImported(Context& context, SemIR::ClangDeclKey key)
static auto LookupClangDeclInstId(Context& context, SemIR::ClangDeclKey key)
-> SemIR::InstId {
const auto& clang_decls = context.clang_decls();
if (auto context_clang_decl_id = clang_decls.Lookup(key);
if (auto context_clang_decl_id = clang_decls.LookupId(key);
context_clang_decl_id.has_value()) {
return clang_decls.Get(context_clang_decl_id).inst_id;
}
@@ -2602,7 +2601,7 @@ auto ImportClassDefinitionForClangDecl(Context& context,
CARBON_CHECK(cpp_file);
auto* clang_decl =
cast<clang::TagDecl>(context.clang_decls().Get(clang_decl_id).key.decl);
cast<clang::TagDecl>(context.clang_decls().Get(clang_decl_id).decl());
auto class_inst_id = context.types().GetAsTypeInstId(
context.classes().Get(class_id).first_owning_decl_id);
@@ -2637,10 +2636,9 @@ auto GetAsClangVarDecl(Context& context, SemIR::InstId inst_id)
-> clang::VarDecl* {
if (const auto& var_storage =
context.insts().TryGetAs<SemIR::VarStorage>(inst_id)) {
auto clang_decl_id = context.clang_decls().Lookup(var_storage->pattern_id);
if (clang_decl_id.has_value()) {
return cast<clang::VarDecl>(
context.clang_decls().Get(clang_decl_id).key.decl);
if (const auto* clang_decl =
context.clang_decls().Lookup(var_storage->pattern_id)) {
return cast<clang::VarDecl>(clang_decl->decl());
}
}
+3 -5
View File
@@ -732,12 +732,10 @@ static auto GetAsCppFunctionDecl(Context& context, SemIR::InstId inst_id)
if (!function_type) {
return nullptr;
}
SemIR::ClangDeclId clang_decl_id = context.clang_decls().Lookup(
const auto* clang_decl = context.clang_decls().Lookup(
context.functions().Get(function_type->function_id).first_decl_id());
return clang_decl_id.has_value()
? dyn_cast<clang::FunctionDecl>(
context.clang_decls().Get(clang_decl_id).key.decl)
: nullptr;
return clang_decl ? dyn_cast<clang::FunctionDecl>(clang_decl->decl())
: nullptr;
}
auto IsCppOperatorMethod(Context& context, SemIR::InstId inst_id) -> bool {
+7 -10
View File
@@ -245,20 +245,19 @@ struct CalleeFunctionInfo {
auto IsCppThunkRequired(Context& context, const SemIR::Function& function)
-> bool {
auto clang_decl_id = context.clang_decls().Lookup(function.first_decl_id());
if (!clang_decl_id.has_value()) {
const auto* clang_decl =
context.clang_decls().Lookup(function.first_decl_id());
if (!clang_decl) {
return false;
}
const auto& decl_info = context.clang_decls().Get(clang_decl_id);
if (!decl_info.is_imported) {
if (!clang_decl->is_imported) {
return false;
}
const auto& signature =
context.clang_decl_signatures().Get(decl_info.key.signature_id);
auto* decl = cast<clang::FunctionDecl>(decl_info.key.decl);
context.clang_decl_signatures().Get(clang_decl->key.signature_id);
auto* decl = cast<clang::FunctionDecl>(clang_decl->decl());
if (signature.kind != SemIR::ClangDeclSignature::Normal ||
signature.num_params != static_cast<int>(decl->getNumNonObjectParams())) {
// We require a thunk if the number of parameters we want isn't all of them.
@@ -652,9 +651,7 @@ static auto BuildThunkBody(CppContext& cpp_context, clang::Sema& sema,
auto BuildCppThunk(Context& context, const SemIR::Function& callee_function)
-> clang::FunctionDecl* {
auto clang_decl_key =
context.clang_decls()
.Get(context.clang_decls().Lookup(callee_function.first_decl_id()))
.key;
context.clang_decls().Lookup(callee_function.first_decl_id())->key;
clang::FunctionDecl* callee_function_decl =
clang_decl_key.decl->getAsFunction();
CARBON_CHECK(callee_function_decl);