call.cpp 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include "toolchain/check/cpp/call.h"
  5. #include "toolchain/base/kind_switch.h"
  6. #include "toolchain/check/call.h"
  7. #include "toolchain/check/cpp/operators.h"
  8. #include "toolchain/check/cpp/overload_resolution.h"
  9. #include "toolchain/sem_ir/function.h"
  10. #include "toolchain/sem_ir/ids.h"
  11. #include "toolchain/sem_ir/typed_insts.h"
  12. namespace Carbon::Check {
  13. // Returns whether the function is an imported C++ operator member function.
  14. static auto IsCppOperatorMethod(Context& context, SemIR::FunctionId function_id)
  15. -> bool {
  16. SemIR::ClangDeclId clang_decl_id =
  17. context.functions().Get(function_id).clang_decl_id;
  18. return clang_decl_id.has_value() &&
  19. IsCppOperatorMethodDecl(
  20. context.clang_decls().Get(clang_decl_id).key.decl);
  21. }
  22. auto PerformCallToCppFunction(Context& context, SemIR::LocId loc_id,
  23. SemIR::CppOverloadSetId overload_set_id,
  24. SemIR::InstId self_id,
  25. llvm::ArrayRef<SemIR::InstId> arg_ids)
  26. -> SemIR::InstId {
  27. SemIR::InstId callee_id = PerformCppOverloadResolution(
  28. context, loc_id, overload_set_id, self_id, arg_ids);
  29. SemIR::Callee callee = GetCallee(context.sem_ir(), callee_id);
  30. CARBON_KIND_SWITCH(callee) {
  31. case CARBON_KIND(SemIR::CalleeError _): {
  32. return SemIR::ErrorInst::InstId;
  33. }
  34. case CARBON_KIND(SemIR::CalleeFunction fn): {
  35. CARBON_CHECK(!fn.self_id.has_value());
  36. if (self_id.has_value()) {
  37. // Preserve the `self` argument from the original callee.
  38. fn.self_id = self_id;
  39. } else if (IsCppOperatorMethod(context, fn.function_id)) {
  40. // Adjust `self` and args for C++ overloaded operator methods.
  41. fn.self_id = arg_ids.consume_front();
  42. }
  43. return PerformCallToFunction(context, loc_id, callee_id, fn, arg_ids);
  44. }
  45. case CARBON_KIND(SemIR::CalleeCppOverloadSet _): {
  46. CARBON_FATAL("overloads can't be recursive");
  47. }
  48. case CARBON_KIND(SemIR::CalleeNonFunction _): {
  49. CARBON_FATAL("overloads should produce functions");
  50. }
  51. }
  52. }
  53. } // namespace Carbon::Check