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

Code before:
  auto* tag_decl = type.getDecl();
  CARBON_CHECK(tag_decl);

  // Check if the declaration is already mapped.
  auto key = SemIR::ClangDeclKey(tag_decl);
  SemIR::InstId tag_inst_id = LookupClangDeclInstId(context, key);
  if (!tag_inst_id.has_value()) {
    if (auto* record_decl = dyn_cast<clang::CXXRecordDecl>(tag_decl)) {
      auto custom_type = LookupCustomRecordType(context, record_decl);
      if (custom_type.inst_id.has_value()) {
        context.clang_decls().Add({.key = key, .inst_id = custom_type.inst_id});
        return custom_type;
      }
    }

    tag_inst_id = ImportTagDecl(context, tag_decl);
  }
  SemIR::TypeInstId record_type_inst_id =
      context.types().GetAsTypeInstId(tag_inst_id);
  return {
      .inst_id = record_type_inst_id,
      .type_id = context.types().GetTypeIdForTypeInstId(record_type_inst_id)};
}

// Maps a C++ type that is not a wrapper type such as a pointer to a Carbon
// type.
// TODO: Support more types.
static auto MapNonWrapperType(Context& context, SemIR::LocId loc_id,
                              clang::QualType type) -> TypeExpr {
  if (const auto* builtin_type = type->getAs<clang::BuiltinType>()) {
    return MapBuiltinType(context, loc_id, type, *builtin_type);
  }

  if (const auto* tag_type = type->getAs<clang::TagType>()) {
    return MapTagType(context, *tag_type);
  }

  CARBON_CHECK(!type.hasQualifiers() && !type->isPointerType(),
               "Should not see wrapper types here");

  return TypeExpr::None;
}

// Maps a qualified C++ type to a Carbon type.
static auto MapQualifiedType(Context& context, clang::QualType type,
                             TypeExpr type_expr) -> TypeExpr {
  auto quals = type.getQualifiers();

  if (quals.hasConst()) {
    auto type_id = GetConstType(context, type_expr.inst_id);
    type_expr = TypeExpr::ForUnsugared(context, type_id);

Review comment (suggestion):
Looks like the version of LLVM we're moving to doesn't have this rename yet (https://github.com/llvm/llvm-project/commit/b516dcc998d06c97d874af543489887f7e5a680c landed on October 15, but this PR is picking [an LLVM revision from September](https://github.com/llvm/llvm-project/commit/113f01aa82d055410f22a9d03b3468fa68600589)).

Code after:
  }

  return TypeExpr::None;
}

// Determines whether record_decl is a C++ class that has a custom mapping into
// Carbon, and if so, returns the corresponding Carbon type. Otherwise returns
// None.
static auto LookupCustomRecordType(Context& context,
                                   const clang::CXXRecordDecl* record_decl)
    -> TypeExpr {
  switch (GetCustomCppTypeMapping(record_decl)) {
    case CustomCppTypeMapping::None:
      return TypeExpr::None;

    case CustomCppTypeMapping::Str:
      return MakeStringType(
          context,
          AddImportIRInst(context.sem_ir(), record_decl->getLocation()));
  }
}

// Maps a C++ tag type (class, struct, union, enum) to a Carbon type.
static auto MapTagType(Context& context, const clang::TagType& type)
    -> TypeExpr {
  auto* tag_decl = type.getDecl();
  CARBON_CHECK(tag_decl);

  // Check if the declaration is already mapped.
  auto key = SemIR::ClangDeclKey(tag_decl);
  SemIR::InstId tag_inst_id = LookupClangDeclInstId(context, key);
  if (!tag_inst_id.has_value()) {
    if (auto* record_decl = dyn_cast<clang::CXXRecordDecl>(tag_decl)) {
      auto custom_type = LookupCustomRecordType(context, record_decl);
      if (custom_type.inst_id.has_value()) {
        context.clang_decls().Add({.key = key, .inst_id = custom_type.inst_id});
        return custom_type;
      }
    }

    tag_inst_id = ImportTagDecl(context, tag_decl);
  }
  SemIR::TypeInstId record_type_inst_id =
      context.types().GetAsTypeInstId(tag_inst_id);
  return {
      .inst_id = record_type_inst_id,
      .type_id = context.types().GetTypeIdForTypeInstId(record_type_inst_id)};
}

// Maps a C++ type that is not a wrapper type such as a pointer to a Carbon
// type.