4
4
5
5
#include " toolchain/check/cpp/overload_resolution.h"
6
6
7
+ #include " clang/Basic/DiagnosticSema.h"
7
8
#include " clang/Sema/Overload.h"
8
9
#include " clang/Sema/Sema.h"
9
10
#include " toolchain/check/cpp/import.h"
11
+ #include " toolchain/check/cpp/location.h"
10
12
#include " toolchain/check/cpp/type_mapping.h"
11
13
#include " toolchain/sem_ir/ids.h"
12
14
#include " toolchain/sem_ir/typed_insts.h"
13
15
14
16
namespace Carbon ::Check {
15
17
18
+ // Map a Carbon name into a C++ name.
19
+ static auto GetCppName (Context& context, SemIR::NameId name_id)
20
+ -> clang::DeclarationName {
21
+ // TODO: Some special names should probably use different formatting. In
22
+ // particular, NameId::CppOperator should probably map back to a
23
+ // CXXOperatorName.
24
+ auto name_str = context.names ().GetFormatted (name_id);
25
+ return clang::DeclarationName (&context.ast_context ().Idents .get (name_str));
26
+ }
27
+
16
28
// Adds the given overload candidates to the candidate set.
17
29
static auto AddOverloadCandidataes (clang::Sema& sema,
18
30
clang::OverloadCandidateSet& candidate_set,
@@ -67,13 +79,6 @@ auto PerformCppOverloadResolution(Context& context, SemIR::LocId loc_id,
67
79
SemIR::InstId self_id,
68
80
llvm::ArrayRef<SemIR::InstId> arg_ids)
69
81
-> SemIR::InstId {
70
- Diagnostics::AnnotationScope annotate_diagnostics (
71
- &context.emitter (), [&](auto & builder) {
72
- CARBON_DIAGNOSTIC (InCallToCppFunction, Note,
73
- " in call to Cpp function here" );
74
- builder.Note (loc_id, InCallToCppFunction);
75
- });
76
-
77
82
// Map Carbon call argument types to C++ types.
78
83
clang::Expr* self_expr = nullptr ;
79
84
if (self_id.has_value ()) {
@@ -82,67 +87,63 @@ auto PerformCppOverloadResolution(Context& context, SemIR::LocId loc_id,
82
87
return SemIR::ErrorInst::InstId;
83
88
}
84
89
}
85
- auto arg_exprs = InventClangArgs (context, arg_ids);
86
- if (!arg_exprs .has_value ()) {
90
+ auto maybe_arg_exprs = InventClangArgs (context, arg_ids);
91
+ if (!maybe_arg_exprs .has_value ()) {
87
92
return SemIR::ErrorInst::InstId;
88
93
}
94
+ auto & arg_exprs = *maybe_arg_exprs;
89
95
90
96
const SemIR::CppOverloadSet& overload_set =
91
97
context.cpp_overload_sets ().Get (overload_set_id);
92
98
99
+ clang::SourceLocation loc = GetCppLocation (context, loc_id);
100
+
93
101
// Add candidate functions from the name lookup.
94
102
clang::OverloadCandidateSet candidate_set (
95
- // TODO: Add location accordingly.
96
- clang::SourceLocation (),
97
- clang::OverloadCandidateSet::CandidateSetKind::CSK_Normal);
103
+ loc, clang::OverloadCandidateSet::CandidateSetKind::CSK_Normal);
98
104
99
105
clang::ASTUnit* ast = context.sem_ir ().clang_ast_unit ();
100
106
CARBON_CHECK (ast);
101
107
clang::Sema& sema = ast->getSema ();
102
108
103
109
AddOverloadCandidataes (sema, candidate_set, overload_set.candidate_functions ,
104
- self_expr, * arg_exprs);
110
+ self_expr, arg_exprs);
105
111
106
112
// Find best viable function among the candidates.
107
113
clang::OverloadCandidateSet::iterator best_viable_fn;
108
114
clang::OverloadingResult overloading_result =
109
- // TODO: Add location accordingly.
110
- candidate_set.BestViableFunction (sema, clang::SourceLocation (),
111
- best_viable_fn);
115
+ candidate_set.BestViableFunction (sema, loc, best_viable_fn);
112
116
113
117
switch (overloading_result) {
114
118
case clang::OverloadingResult::OR_Success: {
115
119
// TODO: Handle the cases when Function is null.
116
120
CARBON_CHECK (best_viable_fn->Function );
117
- sema.MarkFunctionReferenced (clang::SourceLocation (),
118
- best_viable_fn->Function );
121
+ sema.MarkFunctionReferenced (loc, best_viable_fn->Function );
119
122
SemIR::InstId result =
120
123
ImportCppFunctionDecl (context, loc_id, best_viable_fn->Function );
121
124
return result;
122
125
}
123
126
case clang::OverloadingResult::OR_No_Viable_Function: {
124
- // TODO: Add notes with the candidates.
125
- CARBON_DIAGNOSTIC (CppOverloadingNoViableFunctionFound, Error,
126
- " no matching function for call to `{0}`" ,
127
- SemIR::NameId);
128
- context.emitter ().Emit (loc_id, CppOverloadingNoViableFunctionFound,
129
- overload_set.name_id );
127
+ candidate_set.NoteCandidates (
128
+ clang::PartialDiagnosticAt (
129
+ loc, sema.PDiag (clang::diag::err_ovl_no_viable_function_in_call)
130
+ << GetCppName (context, overload_set.name_id )),
131
+ sema, clang::OCD_AllCandidates, arg_exprs);
130
132
return SemIR::ErrorInst::InstId;
131
133
}
132
134
case clang::OverloadingResult::OR_Ambiguous: {
133
- // TODO: Add notes with the candidates.
134
- CARBON_DIAGNOSTIC (CppOverloadingAmbiguousCandidatesFound, Error,
135
- " call to `{0}` is ambiguous " , SemIR::NameId);
136
- context. emitter (). Emit (loc_id, CppOverloadingAmbiguousCandidatesFound ,
137
- overload_set. name_id );
135
+ candidate_set. NoteCandidates (
136
+ clang::PartialDiagnosticAt (
137
+ loc, sema. PDiag (clang::diag::err_ovl_ambiguous_call)
138
+ << GetCppName (context, overload_set. name_id )) ,
139
+ sema, clang::OCD_AmbiguousCandidates, arg_exprs );
138
140
return SemIR::ErrorInst::InstId;
139
141
}
140
142
case clang::OverloadingResult::OR_Deleted: {
141
- // TODO: Add notes with the candidates.
142
- CARBON_DIAGNOSTIC (CppOverloadingDeletedFunctionFound, Error,
143
- " call to deleted function `{0}`" , SemIR::NameId);
144
- context.emitter ().Emit (loc_id, CppOverloadingDeletedFunctionFound,
145
- overload_set.name_id );
143
+ sema.DiagnoseUseOfDeletedFunction (
144
+ loc, clang::SourceRange (loc, loc),
145
+ GetCppName (context, overload_set.name_id ), candidate_set,
146
+ best_viable_fn->Function , arg_exprs);
146
147
return SemIR::ErrorInst::InstId;
147
148
}
148
149
}
0 commit comments