Repository: carbon-language/carbon-lang
File: toolchain/check/cpp/import.cpp (C++)

Code before:
  const auto* record_decl = dyn_cast<clang::CXXRecordDecl>(named_decl);
  if (!record_decl) {
    return false;
  }

  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 clang::ASTContext& ast_context = context.ast_context();
  CARBON_CHECK(ast_context.getCanonicalTagType(scope_record_decl) ==
               ast_context.getCanonicalTagType(record_decl));

  auto class_decl = context.insts().GetAs<SemIR::ClassDecl>(clang_decl.inst_id);
  CARBON_CHECK(name_id == context.classes().Get(class_decl.class_id).name_id);
  return true;
}

// Performs a qualified name lookup of the identifier in the given scope.
// Returns the lookup result if lookup was successful.
static auto ClangLookupName(Context& context, SemIR::NameScopeId scope_id,
                            clang::IdentifierInfo* identifier_name)
    -> std::optional<clang::LookupResult> {
  clang::Sema& sema = context.clang_sema();
  CARBON_CHECK(identifier_name, "Identifier name is empty");

  // 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(clang::DeclarationName(identifier_name),
                                 clang::SourceLocation()),
      clang::Sema::LookupNameKind::LookupOrdinaryName);

  bool found =
      sema.LookupQualifiedName(lookup, GetDeclContext(context, scope_id));

  if (!found) {
    return std::nullopt;
  }

  return lookup;
}

// 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();
}

Review comment (suggestion):
```suggestion
  CARBON_CHECK(identifier_name, "Identifier name is empty");
  clang::Sema& sema = context.clang_sema();
```
nit: preconditions come first

The indenting in the suggestion block was weird, hopefully this applies correctly...

Code after:
  const auto* record_decl = dyn_cast<clang::CXXRecordDecl>(named_decl);
  if (!record_decl) {
    return false;
  }

  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 clang::ASTContext& ast_context = context.ast_context();
  CARBON_CHECK(ast_context.getCanonicalTagType(scope_record_decl) ==
               ast_context.getCanonicalTagType(record_decl));

  auto class_decl = context.insts().GetAs<SemIR::ClassDecl>(clang_decl.inst_id);
  CARBON_CHECK(name_id == context.classes().Get(class_decl.class_id).name_id);
  return true;
}

// Performs a qualified name lookup of the identifier in the given scope.
// Returns the lookup result if lookup was successful.
static auto ClangLookupName(Context& context, SemIR::NameScopeId scope_id,
                            clang::IdentifierInfo* identifier_name)
    -> std::optional<clang::LookupResult> {
  CARBON_CHECK(identifier_name, "Identifier name is empty");
  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(clang::DeclarationName(identifier_name),
                                 clang::SourceLocation()),
      clang::Sema::LookupNameKind::LookupOrdinaryName);

  bool found =
      sema.LookupQualifiedName(lookup, GetDeclContext(context, scope_id));

  if (!found) {
    return std::nullopt;
  }

  return lookup;
}

// 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();
}