Ver código fonte

Refactor `ImportNameFromCpp` in cpp/import.cpp (#6100)

Cleaned up `ImportNameFromCpp`, extracting smaller functions out of it.
Also added a documentation for `ClangLookup`. No changes in
functionality.

Part of #5915
Ivana Ivanovska 7 meses atrás
pai
commit
6ca443afc7
1 arquivos alterados com 86 adições e 68 exclusões
  1. 86 68
      toolchain/check/cpp/import.cpp

+ 86 - 68
toolchain/check/cpp/import.cpp

@@ -503,28 +503,6 @@ static auto GetDeclContext(Context& context, SemIR::NameScopeId scope_id)
       context.clang_decls().Get(scope_clang_decl_context_id).decl);
       context.clang_decls().Get(scope_clang_decl_context_id).decl);
 }
 }
 
 
-static auto ClangLookup(Context& context, SemIR::NameScopeId scope_id,
-                        clang::DeclarationName name)
-    -> std::optional<clang::LookupResult> {
-  clang::Sema& sema = context.clang_sema();
-
-  // TODO: Map the LocId of the lookup to a clang SourceLocation and provide it
-  // here so that clang's diagnostics can point into the carbon code that uses
-  // the name.
-  clang::LookupResult lookup(
-      sema, clang::DeclarationNameInfo(name, clang::SourceLocation()),
-      clang::Sema::LookupNameKind::LookupOrdinaryName);
-
-  bool found =
-      sema.LookupQualifiedName(lookup, GetDeclContext(context, scope_id));
-
-  if (!found) {
-    return std::nullopt;
-  }
-
-  return lookup;
-}
-
 // Looks up for constructors in the class scope and returns the lookup result.
 // Looks up for constructors in the class scope and returns the lookup result.
 static auto ClangConstructorLookup(Context& context,
 static auto ClangConstructorLookup(Context& context,
                                    SemIR::NameScopeId scope_id)
                                    SemIR::NameScopeId scope_id)
@@ -580,9 +558,32 @@ static auto GetDeclarationName(Context& context, SemIR::NameId name_id)
       context.clang_sema().getPreprocessor().getIdentifierInfo(*name));
       context.clang_sema().getPreprocessor().getIdentifierInfo(*name));
 }
 }
 
 
+// Performs a qualified name lookup of the declaration name in the given scope.
+// Returns the lookup result if lookup was successful.
+static auto ClangLookup(Context& context, SemIR::NameScopeId scope_id,
+                        clang::DeclarationName name)
+    -> std::optional<clang::LookupResult> {
+  clang::Sema& sema = context.clang_sema();
+
+  // TODO: Map the LocId of the lookup to a clang SourceLocation and provide it
+  // here so that clang's diagnostics can point into the carbon code that uses
+  // the name.
+  clang::LookupResult lookup(
+      sema, clang::DeclarationNameInfo(name, clang::SourceLocation()),
+      clang::Sema::LookupNameKind::LookupOrdinaryName);
+
+  bool found =
+      sema.LookupQualifiedName(lookup, GetDeclContext(context, scope_id));
+
+  if (!found) {
+    return std::nullopt;
+  }
+
+  return lookup;
+}
+
 // Looks up the given name in the Clang AST in a specific scope. Returns the
 // Looks up the given name in the Clang AST in a specific scope. Returns the
 // lookup result if lookup was successful.
 // lookup result if lookup was successful.
-// TODO: Merge this with `ClangLookupDeclarationName`.
 static auto ClangLookupName(Context& context, SemIR::NameScopeId scope_id,
 static auto ClangLookupName(Context& context, SemIR::NameScopeId scope_id,
                             SemIR::NameId name_id)
                             SemIR::NameId name_id)
     -> std::optional<clang::LookupResult> {
     -> std::optional<clang::LookupResult> {
@@ -2083,7 +2084,59 @@ static auto ImportOverloadSetIntoScope(
                                                            access_kind.value());
                                                            access_kind.value());
 }
 }
 
 
-// TODO: Refactor this method.
+// Imports the constructors for a given class name. The found constructors are
+// imported as part of an overload set into the scope. Currently copy/move
+// constructors are not imported.
+static auto ImportConstructorsIntoScope(Context& context, SemIR::LocId loc_id,
+                                        SemIR::NameScopeId scope_id,
+                                        SemIR::NameId name_id)
+    -> SemIR::ScopeLookupResult {
+  clang::DeclContextLookupResult constructors_lookup =
+      ClangConstructorLookup(context, scope_id);
+
+  clang::UnresolvedSet<4> overload_set;
+  for (clang::Decl* decl : constructors_lookup) {
+    auto* constructor = cast<clang::CXXConstructorDecl>(decl);
+    if (constructor->isDeleted() || constructor->isCopyOrMoveConstructor()) {
+      continue;
+    }
+    overload_set.addDecl(constructor, constructor->getAccess());
+  }
+  if (overload_set.empty()) {
+    return SemIR::ScopeLookupResult::MakeNotFound();
+  }
+
+  return ImportOverloadSetIntoScope(context, loc_id, scope_id, name_id,
+                                    overload_set);
+}
+
+// Imports a builtin type from Clang to Carbon and adds the name into the
+// scope.
+static auto ImportBuiltinTypesIntoScope(Context& context, SemIR::LocId loc_id,
+                                        SemIR::NameScopeId scope_id,
+                                        SemIR::NameId name_id)
+    -> SemIR::ScopeLookupResult {
+  SemIR::InstId builtin_inst_id =
+      LookupBuiltinTypes(context, loc_id, scope_id, name_id);
+  if (builtin_inst_id.has_value()) {
+    AddNameToScope(context, scope_id, name_id, SemIR::AccessKind::Public,
+                   builtin_inst_id);
+    return SemIR::ScopeLookupResult::MakeWrappedLookupResult(
+        builtin_inst_id, SemIR::AccessKind::Public);
+  }
+  return SemIR::ScopeLookupResult::MakeNotFound();
+}
+
+// Checks if the name scope is a class that is not complete.
+static auto IsIncompleteClass(Context& context, SemIR::NameScopeId scope_id)
+    -> bool {
+  auto class_decl = context.insts().TryGetAs<SemIR::ClassDecl>(
+      context.name_scopes().Get(scope_id).inst_id());
+  return class_decl.has_value() &&
+         !context.types().IsComplete(
+             context.classes().Get(class_decl->class_id).self_type_id);
+}
+
 // TODO: Do we need to import the dependences for all functions in the overload
 // TODO: Do we need to import the dependences for all functions in the overload
 // set?
 // set?
 auto ImportNameFromCpp(Context& context, SemIR::LocId loc_id,
 auto ImportNameFromCpp(Context& context, SemIR::LocId loc_id,
@@ -2095,29 +2148,13 @@ auto ImportNameFromCpp(Context& context, SemIR::LocId loc_id,
                           "in `Cpp` name lookup for `{0}`", SemIR::NameId);
                           "in `Cpp` name lookup for `{0}`", SemIR::NameId);
         builder.Note(loc_id, InCppNameLookup, name_id);
         builder.Note(loc_id, InCppNameLookup, name_id);
       });
       });
-
-  if (auto class_decl = context.insts().TryGetAs<SemIR::ClassDecl>(
-          context.name_scopes().Get(scope_id).inst_id());
-      class_decl.has_value()) {
-    if (!context.types().IsComplete(
-            context.classes().Get(class_decl->class_id).self_type_id)) {
-      return SemIR::ScopeLookupResult::MakeError();
-    }
+  if (IsIncompleteClass(context, scope_id)) {
+    return SemIR::ScopeLookupResult::MakeError();
   }
   }
-
   auto lookup = ClangLookupName(context, scope_id, name_id);
   auto lookup = ClangLookupName(context, scope_id, name_id);
   if (!lookup) {
   if (!lookup) {
-    SemIR::InstId builtin_inst_id =
-        LookupBuiltinTypes(context, loc_id, scope_id, name_id);
-    if (builtin_inst_id.has_value()) {
-      AddNameToScope(context, scope_id, name_id, SemIR::AccessKind::Public,
-                     builtin_inst_id);
-      return SemIR::ScopeLookupResult::MakeWrappedLookupResult(
-          builtin_inst_id, SemIR::AccessKind::Public);
-    }
-    return SemIR::ScopeLookupResult::MakeNotFound();
+    return ImportBuiltinTypesIntoScope(context, loc_id, scope_id, name_id);
   }
   }
-
   // Access checks are performed separately by the Carbon name lookup logic.
   // Access checks are performed separately by the Carbon name lookup logic.
   lookup->suppressAccessDiagnostics();
   lookup->suppressAccessDiagnostics();
 
 
@@ -2129,7 +2166,6 @@ auto ImportNameFromCpp(Context& context, SemIR::LocId loc_id,
     return ImportOverloadSetIntoScope(context, loc_id, scope_id, name_id,
     return ImportOverloadSetIntoScope(context, loc_id, scope_id, name_id,
                                       overload_set);
                                       overload_set);
   }
   }
-
   if (!lookup->isSingleResult()) {
   if (!lookup->isSingleResult()) {
     // Clang will diagnose ambiguous lookup results for us.
     // Clang will diagnose ambiguous lookup results for us.
     if (!lookup->isAmbiguous()) {
     if (!lookup->isAmbiguous()) {
@@ -2142,31 +2178,13 @@ auto ImportNameFromCpp(Context& context, SemIR::LocId loc_id,
                                           SemIR::ErrorInst::InstId);
                                           SemIR::ErrorInst::InstId);
     return SemIR::ScopeLookupResult::MakeError();
     return SemIR::ScopeLookupResult::MakeError();
   }
   }
-
-  if (!IsDeclInjectedClassName(context, scope_id, name_id,
-                               lookup->getFoundDecl())) {
-    return ImportNameDeclIntoScope(context, loc_id, scope_id, name_id,
-                                   lookup->getFoundDecl(),
-                                   lookup->begin().getAccess());
-  }
-
-  clang::DeclContextLookupResult constructors_lookup =
-      ClangConstructorLookup(context, scope_id);
-
-  clang::UnresolvedSet<4> overload_set;
-  for (clang::Decl* decl : constructors_lookup) {
-    auto* constructor = cast<clang::CXXConstructorDecl>(decl);
-    if (constructor->isDeleted() || constructor->isCopyOrMoveConstructor()) {
-      continue;
-    }
-    overload_set.addDecl(constructor, constructor->getAccess());
-  }
-  if (overload_set.empty()) {
-    return SemIR::ScopeLookupResult::MakeNotFound();
+  if (IsDeclInjectedClassName(context, scope_id, name_id,
+                              lookup->getFoundDecl())) {
+    return ImportConstructorsIntoScope(context, loc_id, scope_id, name_id);
   }
   }
-
-  return ImportOverloadSetIntoScope(context, loc_id, scope_id, name_id,
-                                    overload_set);
+  return ImportNameDeclIntoScope(context, loc_id, scope_id, name_id,
+                                 lookup->getFoundDecl(),
+                                 lookup->begin().getAccess());
 }
 }
 
 
 auto ImportClassDefinitionForClangDecl(Context& context, SemIR::LocId loc_id,
 auto ImportClassDefinitionForClangDecl(Context& context, SemIR::LocId loc_id,