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

Code before:
        clang_type,
        context.ast_context().getTrivialTypeSourceInfo(
            clang_type, GetCppLocation(context, SemIR::LocId(arg_id))));
  }

  if (isa<clang::TemplateTemplateParmDecl>(param_decl)) {
    auto inst = context.sem_ir().insts().Get(arg_id);
    if (auto template_name_type =
            context.types().TryGetAs<SemIR::CppTemplateNameType>(
                inst.type_id())) {
      clang::TemplateName name(cast<clang::TemplateDecl>(
          context.clang_decls().Get(template_name_type->decl_id).key.decl));
      return clang::TemplateArgumentLoc(
          context.ast_context(), clang::TemplateArgument(name),
          /*TemplateKWLoc=*/clang::SourceLocation(),
          clang::NestedNameSpecifierLoc(),
          GetCppLocation(context, SemIR::LocId(arg_id)));
    }

    // TODO: Eventually we should also support passing Carbon generics as
    // template template arguments.
    return MakePlaceholderTemplateArg(context, arg_id);
  }

  if (isa<clang::NonTypeTemplateParmDecl>(param_decl)) {
    auto non_type = cast<clang::NonTypeTemplateParmDecl>(param_decl);
    auto param_type = non_type->getType();

    // Handle integer parameters.
    if (param_type.getTypePtr()->isIntegerType()) {
      // Get the Carbon type corresponding to the parameter's Clang type.
      const TypeExpr type_expr =
          ImportCppType(context, SemIR::LocId(arg_id), param_type);

      // Try to convert the argument to the parameter type.
      const SemIR::InstId converted_inst_id =
          Convert(context, SemIR::LocId(arg_id), arg_id,
                  {
                      .kind = ConversionTarget::Value,
                      .type_id = type_expr.type_id,
                  });

      if (converted_inst_id.has_value()) {
        auto const_inst_id =
            context.constant_values().GetConstantInstId(converted_inst_id);
        if (const_inst_id.has_value()) {
          if (auto int_value =
                  context.insts().TryGetAs<SemIR::IntValue>(const_inst_id)) {
            const llvm::APInt ap_int = context.ints().Get(int_value->int_id);
            auto aps_int = llvm::APSInt(ap_int).extOrTrunc(
                context.ast_context().getIntWidth(param_type));

Review comment (suggestion):
You can perform the `isa` and `cast` together using `dyn_cast`. We also prefer to use `auto*` when deduced type is a pointer.
```suggestion
  if (const auto* non_type = dyn_cast<clang::NonTypeTemplateParmDecl>(param_decl)) {
```

Code after:
        clang_type,
        context.ast_context().getTrivialTypeSourceInfo(
            clang_type, GetCppLocation(context, SemIR::LocId(arg_id))));
  }

  if (isa<clang::TemplateTemplateParmDecl>(param_decl)) {
    auto inst = context.sem_ir().insts().Get(arg_id);
    if (auto template_name_type =
            context.types().TryGetAs<SemIR::CppTemplateNameType>(
                inst.type_id())) {
      clang::TemplateName name(cast<clang::TemplateDecl>(
          context.clang_decls().Get(template_name_type->decl_id).key.decl));
      return clang::TemplateArgumentLoc(
          context.ast_context(), clang::TemplateArgument(name),
          /*TemplateKWLoc=*/clang::SourceLocation(),
          clang::NestedNameSpecifierLoc(),
          GetCppLocation(context, SemIR::LocId(arg_id)));
    }

    // TODO: Eventually we should also support passing Carbon generics as
    // template template arguments.
    return MakePlaceholderTemplateArg(context, arg_id);
  }

  if (const auto* non_type =
          dyn_cast<clang::NonTypeTemplateParmDecl>(param_decl)) {
    auto param_type = non_type->getType();

    // Handle integer parameters.
    if (param_type->isIntegerType()) {
      // Get the Carbon type corresponding to the parameter's Clang type.
      const auto type_expr =
          ImportCppType(context, SemIR::LocId(arg_id), param_type);

      // Try to convert the argument to the parameter type.
      const auto converted_inst_id =
          Convert(context, SemIR::LocId(arg_id), arg_id,
                  {
                      .kind = ConversionTarget::Value,
                      .type_id = type_expr.type_id,
                  });

      if (converted_inst_id == SemIR::ErrorInst::InstId) {
        return std::nullopt;
      }

      auto const_inst_id =
          context.constant_values().GetConstantInstId(converted_inst_id);
      if (const_inst_id.has_value()) {
        if (auto int_value =
                context.insts().TryGetAs<SemIR::IntValue>(const_inst_id)) {