C++ Interop: Fix access calculation to handle private member of base classes correctly (#6238)

Always take into account both the lookup access specifier and the
declaration. When set, lookup access specifier takes precedence. When
not set, we have two use cases:
1. This is not a record member, so no access is specified at all. Treat
this as public.
2. This is a record member of a base class. Treat this as private.
[Reference](https://github.com/llvm/llvm-project/blob/4b1d7827c07381610ad4fa7bd9d1a9659008b963/clang/include/clang/AST/DeclCXX.h#L1724).

Also, deduplicate access mapping between import and overload resolution.

Background:
https://github.com/carbon-language/carbon-lang/pull/6221#issuecomment-3407981790

Part of #5859.
This commit is contained in:
Boaz Brickner
2025-10-21 08:12:57 +00:00
committed by GitHub
parent 3d6810beb6
commit 840562feb3
6 changed files with 1924 additions and 151 deletions
+4 -16
View File
@@ -8,6 +8,7 @@
#include "clang/Sema/Overload.h"
#include "clang/Sema/Sema.h"
#include "toolchain/base/kind_switch.h"
#include "toolchain/check/cpp/access.h"
#include "toolchain/check/cpp/import.h"
#include "toolchain/check/cpp/location.h"
#include "toolchain/check/cpp/operators.h"
@@ -88,22 +89,9 @@ static auto CheckOverloadAccess(Context& context, SemIR::LocId loc_id,
const SemIR::CppOverloadSet& overload_set,
clang::DeclAccessPair overload,
SemIR::InstId overload_inst_id) -> void {
SemIR::AccessKind member_access_kind;
switch (overload->getAccess()) {
case clang::AS_none:
case clang::AS_public: {
return;
}
case clang::AS_protected: {
member_access_kind = SemIR::AccessKind::Protected;
break;
}
case clang::AS_private: {
member_access_kind = SemIR::AccessKind::Private;
break;
}
SemIR::AccessKind member_access_kind = MapCppAccess(overload);
if (member_access_kind == SemIR::AccessKind::Public) {
return;
}
auto name_scope_const_id = context.constant_values().Get(