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

Code before:
    parent_dc = parent_dc->getParent();
  }
  return cast<clang::Decl>(parent_dc);
}

// Returns the given declaration's parent scope. Assumes the parent declaration
// was already imported.
static auto GetParentNameScopeId(Context& context, clang::Decl* clang_decl)
    -> SemIR::NameScopeId {
  auto* parent_decl = GetParentDecl(clang_decl);

  if (auto* tag_decl = dyn_cast<clang::TagDecl>(parent_decl)) {
    auto class_inst_id =
        LookupClangDeclInstId(context, SemIR::ClangDeclKey(tag_decl));
    CARBON_CHECK(class_inst_id.has_value());
    auto class_inst = context.insts().Get(class_inst_id);
    auto class_id = SemIR::ClassId::None;
    if (auto class_decl = class_inst.TryAs<SemIR::ClassDecl>()) {
      // Common case: the tag was imported as a new Carbon class.
      class_id = class_decl->class_id;
    } else {
      // Rare case: the tag was imported as an existing Carbon class. This
      // happens for C++ classes that get mapped to Carbon prelude types, such
      // as `std::string_view`.
      // TODO: In this case, should we set the parent to be the prelude type, or
      // should we import the C++ class declaration and use it as the parent?
      class_id = class_inst.As<SemIR::ClassType>().class_id;
    }
    return context.classes().Get(class_id).scope_id;
  }

  if (isa<clang::NamespaceDecl, clang::TranslationUnitDecl>(parent_decl)) {
    auto namespace_inst_id = LookupClangDeclInstId(
        context, SemIR::ClangDeclKey::ForNonFunctionDecl(parent_decl));
    CARBON_CHECK(namespace_inst_id.has_value());
    return context.insts()
        .GetAs<SemIR::Namespace>(namespace_inst_id)
        .name_scope_id;
  }

  CARBON_FATAL("Unexpected kind of parent {0}", parent_decl->getDeclKindName());
}

// Imports a namespace declaration from Clang to Carbon. If successful, returns
// the new Carbon namespace declaration `InstId`. If the declaration was already
// imported, returns the mapped instruction.
static auto ImportNamespaceDecl(Context& context,
                                clang::NamespaceDecl* clang_decl)
    -> SemIR::InstId {
  auto key = SemIR::ClangDeclKey(clang_decl);
  // Check if the declaration is already mapped.

Review comment (suggestion):
```suggestion
      // TODO: In this case, should we should we import the C++ class declaration
      // and use it as the parent, rather than using the existing Carbon class?
```

That hopefully makes it clearer which of these we're currently doing (which is using the existing class, right?), and saying "existing Carbon class" rather than "prelude type" is more consistent with the opening sentence.

Code after:
    parent_dc = parent_dc->getParent();
  }
  return cast<clang::Decl>(parent_dc);
}

// Returns the given declaration's parent scope. Assumes the parent declaration
// was already imported.
static auto GetParentNameScopeId(Context& context, clang::Decl* clang_decl)
    -> SemIR::NameScopeId {
  auto* parent_decl = GetParentDecl(clang_decl);

  if (auto* tag_decl = dyn_cast<clang::TagDecl>(parent_decl)) {
    auto class_inst_id =
        LookupClangDeclInstId(context, SemIR::ClangDeclKey(tag_decl));
    CARBON_CHECK(class_inst_id.has_value());
    auto class_inst = context.insts().Get(class_inst_id);
    auto class_id = SemIR::ClassId::None;
    if (auto class_decl = class_inst.TryAs<SemIR::ClassDecl>()) {
      // Common case: the tag was imported as a new Carbon class.
      class_id = class_decl->class_id;
    } else {
      // Rare case: the tag was imported as an existing Carbon class. This
      // happens for C++ classes that get mapped to Carbon prelude types, such
      // as `std::string_view`.
      // TODO: In this case, should we import the C++ class declaration and use
      // it as the parent, rather than using the existing Carbon class?
      class_id = class_inst.As<SemIR::ClassType>().class_id;
    }
    return context.classes().Get(class_id).scope_id;
  }

  if (isa<clang::NamespaceDecl, clang::TranslationUnitDecl>(parent_decl)) {
    auto namespace_inst_id = LookupClangDeclInstId(
        context, SemIR::ClangDeclKey::ForNonFunctionDecl(parent_decl));
    CARBON_CHECK(namespace_inst_id.has_value());
    return context.insts()
        .GetAs<SemIR::Namespace>(namespace_inst_id)
        .name_scope_id;
  }

  CARBON_FATAL("Unexpected kind of parent {0}", parent_decl->getDeclKindName());
}

// Imports a namespace declaration from Clang to Carbon. If successful, returns
// the new Carbon namespace declaration `InstId`. If the declaration was already
// imported, returns the mapped instruction.
static auto ImportNamespaceDecl(Context& context,
                                clang::NamespaceDecl* clang_decl)
    -> SemIR::InstId {
  auto key = SemIR::ClangDeclKey(clang_decl);
  // Check if the declaration is already mapped.