@@ -508,18 +508,6 @@ static auto GetDeclContext(Context& context, SemIR::NameScopeId scope_id)
508508 context.clang_decls ().Get (scope_clang_decl_context_id).key .decl );
509509}
510510
511- // Looks up for constructors in the class scope and returns the lookup result.
512- static auto ClangConstructorLookup (Context& context,
513- SemIR::NameScopeId scope_id)
514- -> clang::DeclContextLookupResult {
515- const SemIR::NameScope& scope = context.name_scopes ().Get (scope_id);
516-
517- clang::Sema& sema = context.clang_sema ();
518- clang::Decl* decl =
519- context.clang_decls ().Get (scope.clang_decl_context_id ()).key .decl ;
520- return sema.LookupConstructors (cast<clang::CXXRecordDecl>(decl));
521- }
522-
523511// Returns true if the given Clang declaration is the implicit injected class
524512// name within the class.
525513static auto IsDeclInjectedClassName (Context& context,
@@ -2074,12 +2062,14 @@ static auto LookupBuiltinTypes(Context& context, SemIR::LocId loc_id,
20742062
20752063auto ImportCppOverloadSet (Context& context, SemIR::NameScopeId scope_id,
20762064 SemIR::NameId name_id,
2077- const clang::UnresolvedSet<4 >& overload_set)
2065+ clang::CXXRecordDecl* naming_class,
2066+ clang::UnresolvedSet<4 >&& overload_set)
20782067 -> SemIR::InstId {
20792068 SemIR::CppOverloadSetId overload_set_id = context.cpp_overload_sets ().Add (
20802069 SemIR::CppOverloadSet{.name_id = name_id,
20812070 .parent_scope_id = scope_id,
2082- .candidate_functions = overload_set});
2071+ .naming_class = naming_class,
2072+ .candidate_functions = std::move (overload_set)});
20832073
20842074 auto overload_set_inst_id =
20852075 // TODO: Add a location.
@@ -2093,65 +2083,65 @@ auto ImportCppOverloadSet(Context& context, SemIR::NameScopeId scope_id,
20932083 return overload_set_inst_id;
20942084}
20952085
2096- // Gets the access for an overloaded function set. Returns std::nullopt
2097- // if the access is not the same for all functions in the overload set.
2098- // TODO: Fix to support functions with different access levels.
2099- static auto GetOverloadSetAccess (Context& context, SemIR::LocId loc_id,
2100- const clang::UnresolvedSet<4 >& overload_set)
2101- -> std::optional<SemIR::AccessKind> {
2086+ // Gets the best access for an overloaded function set. This is the access that
2087+ // we use for the overload set as a whole. More fine-grained checking is done
2088+ // after overload resolution.
2089+ static auto GetOverloadSetAccess (const clang::UnresolvedSet<4 >& overload_set)
2090+ -> SemIR::AccessKind {
21022091 clang::AccessSpecifier access = overload_set.begin ().getAccess ();
21032092 for (auto it = overload_set.begin () + 1 ; it != overload_set.end (); ++it) {
2104- if (it.getAccess () != access) {
2105- context.TODO (loc_id, " Unsupported: Overloaded set with mixed access" );
2106- return std::nullopt ;
2093+ CARBON_CHECK (
2094+ (it.getAccess () == clang::AS_none) == (access == clang::AS_none),
2095+ " Unexpected mixture of members and non-members" );
2096+ if (it.getAccess () < access) {
2097+ access = it->getAccess ();
21072098 }
21082099 }
21092100 return MapAccess (access);
21102101}
21112102
21122103// Imports an overload set from Clang to Carbon and adds the name into the
21132104// `NameScope`.
2114- static auto ImportOverloadSetIntoScope (
2115- Context& context, SemIR::LocId loc_id, SemIR::NameScopeId scope_id,
2116- SemIR::NameId name_id, const clang::UnresolvedSet<4 >& overload_set)
2105+ static auto ImportOverloadSetIntoScope (Context& context,
2106+ SemIR::NameScopeId scope_id,
2107+ SemIR::NameId name_id,
2108+ clang::CXXRecordDecl* naming_class,
2109+ clang::UnresolvedSet<4 >&& overload_set)
21172110 -> SemIR::ScopeLookupResult {
2118- std::optional<SemIR::AccessKind> access_kind =
2119- GetOverloadSetAccess (context, loc_id, overload_set);
2120- if (!access_kind.has_value ()) {
2121- return SemIR::ScopeLookupResult::MakeError ();
2122- }
2123-
2124- SemIR::InstId inst_id =
2125- ImportCppOverloadSet (context, scope_id, name_id, overload_set);
2126- AddNameToScope (context, scope_id, name_id, access_kind.value (), inst_id);
2111+ SemIR::AccessKind access_kind = GetOverloadSetAccess (overload_set);
2112+ SemIR::InstId inst_id = ImportCppOverloadSet (
2113+ context, scope_id, name_id, naming_class, std::move (overload_set));
2114+ AddNameToScope (context, scope_id, name_id, access_kind, inst_id);
21272115 return SemIR::ScopeLookupResult::MakeWrappedLookupResult (inst_id,
2128- access_kind. value () );
2116+ access_kind);
21292117}
21302118
21312119// Imports the constructors for a given class name. The found constructors are
21322120// imported as part of an overload set into the scope. Currently copy/move
21332121// constructors are not imported.
2134- static auto ImportConstructorsIntoScope (Context& context, SemIR::LocId loc_id,
2122+ static auto ImportConstructorsIntoScope (Context& context,
21352123 SemIR::NameScopeId scope_id,
21362124 SemIR::NameId name_id)
21372125 -> SemIR::ScopeLookupResult {
2126+ auto * naming_class =
2127+ cast<clang::CXXRecordDecl>(GetDeclContext (context, scope_id));
21382128 clang::DeclContextLookupResult constructors_lookup =
2139- ClangConstructorLookup ( context, scope_id );
2129+ context. clang_sema (). LookupConstructors (naming_class );
21402130
21412131 clang::UnresolvedSet<4 > overload_set;
21422132 for (auto * decl : constructors_lookup) {
21432133 auto info = clang::getConstructorInfo (decl);
21442134 if (!info.Constructor || info.Constructor ->isCopyOrMoveConstructor ()) {
21452135 continue ;
21462136 }
2147- overload_set.addDecl (info.FoundDecl , info.FoundDecl -> getAccess ());
2137+ overload_set.addDecl (info.FoundDecl , info.FoundDecl . getAccess ());
21482138 }
21492139 if (overload_set.empty ()) {
21502140 return SemIR::ScopeLookupResult::MakeNotFound ();
21512141 }
21522142
2153- return ImportOverloadSetIntoScope (context, loc_id, scope_id, name_id,
2154- overload_set);
2143+ return ImportOverloadSetIntoScope (context, scope_id, name_id, naming_class ,
2144+ std::move ( overload_set) );
21552145}
21562146
21572147// Imports a builtin type from Clang to Carbon and adds the name into the
@@ -2207,8 +2197,9 @@ auto ImportNameFromCpp(Context& context, SemIR::LocId loc_id,
22072197 lookup->getFoundDecl ()->isFunctionOrFunctionTemplate ())) {
22082198 clang::UnresolvedSet<4 > overload_set;
22092199 overload_set.append (lookup->begin (), lookup->end ());
2210- return ImportOverloadSetIntoScope (context, loc_id, scope_id, name_id,
2211- overload_set);
2200+ return ImportOverloadSetIntoScope (context, scope_id, name_id,
2201+ lookup->getNamingClass (),
2202+ std::move (overload_set));
22122203 }
22132204 if (!lookup->isSingleResult ()) {
22142205 // Clang will diagnose ambiguous lookup results for us.
@@ -2224,7 +2215,7 @@ auto ImportNameFromCpp(Context& context, SemIR::LocId loc_id,
22242215 }
22252216 if (IsDeclInjectedClassName (context, scope_id, name_id,
22262217 lookup->getFoundDecl ())) {
2227- return ImportConstructorsIntoScope (context, loc_id, scope_id, name_id);
2218+ return ImportConstructorsIntoScope (context, scope_id, name_id);
22282219 }
22292220 auto key = SemIR::ClangDeclKey::ForNonFunctionDecl (lookup->getFoundDecl ());
22302221 return ImportNameDeclIntoScope (context, loc_id, scope_id, name_id, key,
0 commit comments