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

Code before:

  clang::DeclContext* decl_context = ast_context.getTranslationUnitDecl();
  // TODO: Thunks should not have external linkage, consider using `SC_Static`.
  clang::FunctionDecl* thunk_function_decl = clang::FunctionDecl::Create(
      ast_context, decl_context, clang_loc, clang_loc,
      clang::DeclarationName(&identifier_info), thunk_function_type,
      /*TInfo=*/nullptr, clang::SC_Extern);
  decl_context->addDecl(thunk_function_decl);

  thunk_function_decl->setParams(
      BuildThunkParameters(ast_context, callee_info, thunk_function_decl));

  // Set always_inline.
  thunk_function_decl->addAttr(
      clang::AlwaysInlineAttr::CreateImplicit(ast_context));

  // Set asm("<callee function mangled name>.carbon_thunk").
  thunk_function_decl->addAttr(clang::AsmLabelAttr::CreateImplicit(
      ast_context,
      GenerateThunkMangledName(*context.sem_ir().clang_mangle_context(),
                               *callee_info.decl),
      clang_loc));

  // Set function declaration type source info.
  thunk_function_decl->setTypeSourceInfo(
      ast_context.getTrivialTypeSourceInfo(thunk_function_decl->getType()));

  return thunk_function_decl;
}

// Builds a reference to the given parameter thunk. If `type` is specified, that
// is the callee parameter type that's being held by the parameter, and
// conversions will be performed as necessary to recover a value of that type.
static auto BuildThunkParamRef(clang::Sema& sema,
                               clang::FunctionDecl* thunk_function_decl,
                               unsigned thunk_index,
                               clang::QualType type = clang::QualType())
    -> clang::Expr* {
  clang::ParmVarDecl* thunk_param =
      thunk_function_decl->getParamDecl(thunk_index);
  clang::SourceLocation clang_loc = thunk_param->getLocation();

  clang::Expr* call_arg = sema.BuildDeclRefExpr(
      thunk_param, thunk_param->getType().getNonReferenceType(),
      clang::VK_LValue, clang_loc);
  if (!type.isNull() && thunk_param->getType() != type) {
    // TODO: Consider inserting a cast to an rvalue. Note that we currently
    // pass pointers to non-temporary objects as the argument when calling a
    // thunk, so we'll need to either change that or generate different thunks
    // depending on whether we're moving from each parameter.
    clang::ExprResult deref_result =

Review comment (suggestion):
```suggestion
      ast_context.getTrivialTypeSourceInfo(thunk_function_decl->getType(), clang_loc));
```
I think we should supply a location here.

Code after:

  clang::DeclContext* decl_context = ast_context.getTranslationUnitDecl();
  // TODO: Thunks should not have external linkage, consider using `SC_Static`.
  clang::FunctionDecl* thunk_function_decl = clang::FunctionDecl::Create(
      ast_context, decl_context, clang_loc, clang_loc,
      clang::DeclarationName(&identifier_info), thunk_function_type,
      /*TInfo=*/nullptr, clang::SC_Extern);
  decl_context->addDecl(thunk_function_decl);

  thunk_function_decl->setParams(
      BuildThunkParameters(ast_context, callee_info, thunk_function_decl));

  // Set always_inline.
  thunk_function_decl->addAttr(
      clang::AlwaysInlineAttr::CreateImplicit(ast_context));

  // Set asm("<callee function mangled name>.carbon_thunk").
  thunk_function_decl->addAttr(clang::AsmLabelAttr::CreateImplicit(
      ast_context,
      GenerateThunkMangledName(*context.sem_ir().clang_mangle_context(),
                               *callee_info.decl),
      clang_loc));

  // Set function declaration type source info.
  thunk_function_decl->setTypeSourceInfo(ast_context.getTrivialTypeSourceInfo(
      thunk_function_decl->getType(), clang_loc));

  return thunk_function_decl;
}

// Builds a reference to the given parameter thunk. If `type` is specified, that
// is the callee parameter type that's being held by the parameter, and
// conversions will be performed as necessary to recover a value of that type.
static auto BuildThunkParamRef(clang::Sema& sema,
                               clang::FunctionDecl* thunk_function_decl,
                               unsigned thunk_index,
                               clang::QualType type = clang::QualType())
    -> clang::Expr* {
  clang::ParmVarDecl* thunk_param =
      thunk_function_decl->getParamDecl(thunk_index);
  clang::SourceLocation clang_loc = thunk_param->getLocation();

  clang::Expr* call_arg = sema.BuildDeclRefExpr(
      thunk_param, thunk_param->getType().getNonReferenceType(),
      clang::VK_LValue, clang_loc);
  if (!type.isNull() && thunk_param->getType() != type) {
    // TODO: Consider inserting a cast to an rvalue. Note that we currently
    // pass pointers to non-temporary objects as the argument when calling a
    // thunk, so we'll need to either change that or generate different thunks
    // depending on whether we're moving from each parameter.
    clang::ExprResult deref_result =