|
4 | 4 |
|
5 | 5 | #include "toolchain/check/context.h"
|
6 | 6 | #include "toolchain/check/convert.h"
|
| 7 | +#include "toolchain/check/pointer_dereference.h" |
| 8 | +#include "toolchain/diagnostics/diagnostic_emitter.h" |
7 | 9 |
|
8 | 10 | namespace Carbon::Check {
|
9 | 11 |
|
@@ -281,30 +283,31 @@ auto HandlePrefixOperatorPlusPlus(Context& context,
|
281 | 283 |
|
282 | 284 | auto HandlePrefixOperatorStar(Context& context,
|
283 | 285 | Parse::PrefixOperatorStarId node_id) -> bool {
|
284 |
| - auto value_id = context.node_stack().PopExpr(); |
285 |
| - value_id = ConvertToValueExpr(context, value_id); |
286 |
| - auto type_id = |
287 |
| - context.GetUnqualifiedType(context.insts().Get(value_id).type_id()); |
288 |
| - auto result_type_id = SemIR::TypeId::Error; |
289 |
| - if (auto pointer_type = |
290 |
| - context.types().TryGetAs<SemIR::PointerType>(type_id)) { |
291 |
| - result_type_id = pointer_type->pointee_id; |
292 |
| - } else if (type_id != SemIR::TypeId::Error) { |
293 |
| - CARBON_DIAGNOSTIC(DerefOfNonPointer, Error, |
294 |
| - "Cannot dereference operand of non-pointer type `{0}`.", |
295 |
| - SemIR::TypeId); |
296 |
| - auto builder = |
297 |
| - context.emitter().Build(TokenOnly(node_id), DerefOfNonPointer, type_id); |
298 |
| - // TODO: Check for any facet here, rather than only a type. |
299 |
| - if (type_id == SemIR::TypeId::TypeType) { |
300 |
| - CARBON_DIAGNOSTIC( |
301 |
| - DerefOfType, Note, |
302 |
| - "To form a pointer type, write the `*` after the pointee type."); |
303 |
| - builder.Note(TokenOnly(node_id), DerefOfType); |
304 |
| - } |
305 |
| - builder.Emit(); |
306 |
| - } |
307 |
| - context.AddInstAndPush({node_id, SemIR::Deref{result_type_id, value_id}}); |
| 286 | + auto base_id = context.node_stack().PopExpr(); |
| 287 | + |
| 288 | + auto deref_base_id = PerformPointerDereference( |
| 289 | + context, node_id, base_id, |
| 290 | + [&context, &node_id](SemIR::TypeId not_pointer_type_id) { |
| 291 | + CARBON_DIAGNOSTIC( |
| 292 | + DerefOfNonPointer, Error, |
| 293 | + "Cannot dereference operand of non-pointer type `{0}`.", |
| 294 | + SemIR::TypeId); |
| 295 | + |
| 296 | + auto builder = context.emitter().Build( |
| 297 | + TokenOnly(node_id), DerefOfNonPointer, not_pointer_type_id); |
| 298 | + |
| 299 | + // TODO: Check for any facet here, rather than only a type. |
| 300 | + if (not_pointer_type_id == SemIR::TypeId::TypeType) { |
| 301 | + CARBON_DIAGNOSTIC( |
| 302 | + DerefOfType, Note, |
| 303 | + "To form a pointer type, write the `*` after the pointee type."); |
| 304 | + builder.Note(TokenOnly(node_id), DerefOfType); |
| 305 | + } |
| 306 | + |
| 307 | + builder.Emit(); |
| 308 | + }); |
| 309 | + |
| 310 | + context.node_stack().Push(node_id, deref_base_id); |
308 | 311 | return true;
|
309 | 312 | }
|
310 | 313 |
|
|
0 commit comments