aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2018-05-31 10:56:59 -0400
committerAndrew Kelley <superjoe30@gmail.com>2018-05-31 17:28:07 -0400
commitfcbb7426faac5e693ef195defe2d8d2a2eddadb1 (patch)
treed34d161ccdbdacb0d0177b79aeb54605f9a49bd3 /src
parent717ac85a5acb5e6ae063c4d0eb3b8f1bd260776a (diff)
downloadzig-fcbb7426faac5e693ef195defe2d8d2a2eddadb1.tar.gz
zig-fcbb7426faac5e693ef195defe2d8d2a2eddadb1.zip
use * for pointer type instead of &
See #770 To help automatically translate code, see the zig-fmt-pointer-reform-2 branch. This will convert all & into *. Due to the syntax ambiguity (which is why we are making this change), even address-of & will turn into *, so you'll have to manually fix thes instances. You will be guaranteed to get compile errors for them - expected 'type', found 'foo'
Diffstat (limited to 'src')
-rw-r--r--src/all_types.hpp31
-rw-r--r--src/analyze.cpp8
-rw-r--r--src/ast_render.cpp31
-rw-r--r--src/codegen.cpp2
-rw-r--r--src/ir.cpp89
-rw-r--r--src/ir_print.cpp6
-rw-r--r--src/parser.cpp41
-rw-r--r--src/translate_c.cpp33
8 files changed, 130 insertions, 111 deletions
diff --git a/src/all_types.hpp b/src/all_types.hpp
index 9c156fb58b..b9199c2757 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -374,7 +374,7 @@ enum NodeType {
NodeTypeCharLiteral,
NodeTypeSymbol,
NodeTypePrefixOpExpr,
- NodeTypeAddrOfExpr,
+ NodeTypePointerType,
NodeTypeFnCallExpr,
NodeTypeArrayAccessExpr,
NodeTypeSliceExpr,
@@ -616,6 +616,7 @@ enum PrefixOp {
PrefixOpNegationWrap,
PrefixOpMaybe,
PrefixOpUnwrapMaybe,
+ PrefixOpAddrOf,
};
struct AstNodePrefixOpExpr {
@@ -623,7 +624,7 @@ struct AstNodePrefixOpExpr {
AstNode *primary_expr;
};
-struct AstNodeAddrOfExpr {
+struct AstNodePointerType {
AstNode *align_expr;
BigInt *bit_offset_start;
BigInt *bit_offset_end;
@@ -899,7 +900,7 @@ struct AstNode {
AstNodeBinOpExpr bin_op_expr;
AstNodeCatchExpr unwrap_err_expr;
AstNodePrefixOpExpr prefix_op_expr;
- AstNodeAddrOfExpr addr_of_expr;
+ AstNodePointerType pointer_type;
AstNodeFnCallExpr fn_call_expr;
AstNodeArrayAccessExpr array_access_expr;
AstNodeSliceExpr slice_expr;
@@ -2053,7 +2054,7 @@ enum IrInstructionId {
IrInstructionIdTypeInfo,
IrInstructionIdTypeId,
IrInstructionIdSetEvalBranchQuota,
- IrInstructionIdPtrTypeOf,
+ IrInstructionIdPtrType,
IrInstructionIdAlignCast,
IrInstructionIdOpaqueType,
IrInstructionIdSetAlignStack,
@@ -2412,6 +2413,17 @@ struct IrInstructionArrayType {
IrInstruction *child_type;
};
+struct IrInstructionPtrType {
+ IrInstruction base;
+
+ IrInstruction *align_value;
+ IrInstruction *child_type;
+ uint32_t bit_offset_start;
+ uint32_t bit_offset_end;
+ bool is_const;
+ bool is_volatile;
+};
+
struct IrInstructionPromiseType {
IrInstruction base;
@@ -2891,17 +2903,6 @@ struct IrInstructionSetEvalBranchQuota {
IrInstruction *new_quota;
};
-struct IrInstructionPtrTypeOf {
- IrInstruction base;
-
- IrInstruction *align_value;
- IrInstruction *child_type;
- uint32_t bit_offset_start;
- uint32_t bit_offset_end;
- bool is_const;
- bool is_volatile;
-};
-
struct IrInstructionAlignCast {
IrInstruction base;
diff --git a/src/analyze.cpp b/src/analyze.cpp
index b00e18a9a1..a5011035c5 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -418,12 +418,12 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type
const char *volatile_str = is_volatile ? "volatile " : "";
buf_resize(&entry->name, 0);
if (unaligned_bit_count == 0 && byte_alignment == abi_alignment) {
- buf_appendf(&entry->name, "&%s%s%s", const_str, volatile_str, buf_ptr(&child_type->name));
+ buf_appendf(&entry->name, "*%s%s%s", const_str, volatile_str, buf_ptr(&child_type->name));
} else if (unaligned_bit_count == 0) {
- buf_appendf(&entry->name, "&align(%" PRIu32 ") %s%s%s", byte_alignment,
+ buf_appendf(&entry->name, "*align(%" PRIu32 ") %s%s%s", byte_alignment,
const_str, volatile_str, buf_ptr(&child_type->name));
} else {
- buf_appendf(&entry->name, "&align(%" PRIu32 ":%" PRIu32 ":%" PRIu32 ") %s%s%s", byte_alignment,
+ buf_appendf(&entry->name, "*align(%" PRIu32 ":%" PRIu32 ":%" PRIu32 ") %s%s%s", byte_alignment,
bit_offset, bit_offset + unaligned_bit_count, const_str, volatile_str, buf_ptr(&child_type->name));
}
@@ -3270,7 +3270,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
case NodeTypeThisLiteral:
case NodeTypeSymbol:
case NodeTypePrefixOpExpr:
- case NodeTypeAddrOfExpr:
+ case NodeTypePointerType:
case NodeTypeIfBoolExpr:
case NodeTypeWhileExpr:
case NodeTypeForExpr:
diff --git a/src/ast_render.cpp b/src/ast_render.cpp
index 5a1e81b36d..f356f406b0 100644
--- a/src/ast_render.cpp
+++ b/src/ast_render.cpp
@@ -68,6 +68,7 @@ static const char *prefix_op_str(PrefixOp prefix_op) {
case PrefixOpBinNot: return "~";
case PrefixOpMaybe: return "?";
case PrefixOpUnwrapMaybe: return "??";
+ case PrefixOpAddrOf: return "&";
}
zig_unreachable();
}
@@ -185,8 +186,6 @@ static const char *node_type_str(NodeType node_type) {
return "Symbol";
case NodeTypePrefixOpExpr:
return "PrefixOpExpr";
- case NodeTypeAddrOfExpr:
- return "AddrOfExpr";
case NodeTypeUse:
return "Use";
case NodeTypeBoolLiteral:
@@ -251,6 +250,8 @@ static const char *node_type_str(NodeType node_type) {
return "Suspend";
case NodeTypePromiseType:
return "PromiseType";
+ case NodeTypePointerType:
+ return "PointerType";
}
zig_unreachable();
}
@@ -616,41 +617,41 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
fprintf(ar->f, "%s", prefix_op_str(op));
AstNode *child_node = node->data.prefix_op_expr.primary_expr;
- bool new_grouped = child_node->type == NodeTypePrefixOpExpr || child_node->type == NodeTypeAddrOfExpr;
+ bool new_grouped = child_node->type == NodeTypePrefixOpExpr || child_node->type == NodeTypePointerType;
render_node_extra(ar, child_node, new_grouped);
if (!grouped) fprintf(ar->f, ")");
break;
}
- case NodeTypeAddrOfExpr:
+ case NodeTypePointerType:
{
if (!grouped) fprintf(ar->f, "(");
- fprintf(ar->f, "&");
- if (node->data.addr_of_expr.align_expr != nullptr) {
+ fprintf(ar->f, "*");
+ if (node->data.pointer_type.align_expr != nullptr) {
fprintf(ar->f, "align(");
- render_node_grouped(ar, node->data.addr_of_expr.align_expr);
- if (node->data.addr_of_expr.bit_offset_start != nullptr) {
- assert(node->data.addr_of_expr.bit_offset_end != nullptr);
+ render_node_grouped(ar, node->data.pointer_type.align_expr);
+ if (node->data.pointer_type.bit_offset_start != nullptr) {
+ assert(node->data.pointer_type.bit_offset_end != nullptr);
Buf offset_start_buf = BUF_INIT;
buf_resize(&offset_start_buf, 0);
- bigint_append_buf(&offset_start_buf, node->data.addr_of_expr.bit_offset_start, 10);
+ bigint_append_buf(&offset_start_buf, node->data.pointer_type.bit_offset_start, 10);
Buf offset_end_buf = BUF_INIT;
buf_resize(&offset_end_buf, 0);
- bigint_append_buf(&offset_end_buf, node->data.addr_of_expr.bit_offset_end, 10);
+ bigint_append_buf(&offset_end_buf, node->data.pointer_type.bit_offset_end, 10);
fprintf(ar->f, ":%s:%s ", buf_ptr(&offset_start_buf), buf_ptr(&offset_end_buf));
}
fprintf(ar->f, ") ");
}
- if (node->data.addr_of_expr.is_const) {
+ if (node->data.pointer_type.is_const) {
fprintf(ar->f, "const ");
}
- if (node->data.addr_of_expr.is_volatile) {
+ if (node->data.pointer_type.is_volatile) {
fprintf(ar->f, "volatile ");
}
- render_node_ungrouped(ar, node->data.addr_of_expr.op_expr);
+ render_node_ungrouped(ar, node->data.pointer_type.op_expr);
if (!grouped) fprintf(ar->f, ")");
break;
}
@@ -669,7 +670,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
fprintf(ar->f, " ");
}
AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;
- bool grouped = (fn_ref_node->type != NodeTypePrefixOpExpr && fn_ref_node->type != NodeTypeAddrOfExpr);
+ bool grouped = (fn_ref_node->type != NodeTypePrefixOpExpr && fn_ref_node->type != NodeTypePointerType);
render_node_extra(ar, fn_ref_node, grouped);
fprintf(ar->f, "(");
for (size_t i = 0; i < node->data.fn_call_expr.params.length; i += 1) {
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 69542b3e67..d07d427729 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -4600,7 +4600,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
case IrInstructionIdTypeInfo:
case IrInstructionIdTypeId:
case IrInstructionIdSetEvalBranchQuota:
- case IrInstructionIdPtrTypeOf:
+ case IrInstructionIdPtrType:
case IrInstructionIdOpaqueType:
case IrInstructionIdSetAlignStack:
case IrInstructionIdArgType:
diff --git a/src/ir.cpp b/src/ir.cpp
index 6e944a8976..b1fac9f485 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -41,10 +41,6 @@ struct IrAnalyze {
static const LVal LVAL_NONE = { false, false, false };
static const LVal LVAL_PTR = { true, false, false };
-static LVal make_lval_addr(bool is_const, bool is_volatile) {
- return { true, is_const, is_volatile };
-}
-
enum ConstCastResultId {
ConstCastResultIdOk,
ConstCastResultIdErrSet,
@@ -629,8 +625,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSetEvalBranchQuo
return IrInstructionIdSetEvalBranchQuota;
}
-static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrTypeOf *) {
- return IrInstructionIdPtrTypeOf;
+static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrType *) {
+ return IrInstructionIdPtrType;
}
static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignCast *) {
@@ -1196,11 +1192,11 @@ static IrInstruction *ir_build_br_from(IrBuilder *irb, IrInstruction *old_instru
return new_instruction;
}
-static IrInstruction *ir_build_ptr_type_of(IrBuilder *irb, Scope *scope, AstNode *source_node,
+static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
IrInstruction *child_type, bool is_const, bool is_volatile, IrInstruction *align_value,
uint32_t bit_offset_start, uint32_t bit_offset_end)
{
- IrInstructionPtrTypeOf *ptr_type_of_instruction = ir_build_instruction<IrInstructionPtrTypeOf>(irb, scope, source_node);
+ IrInstructionPtrType *ptr_type_of_instruction = ir_build_instruction<IrInstructionPtrType>(irb, scope, source_node);
ptr_type_of_instruction->align_value = align_value;
ptr_type_of_instruction->child_type = child_type;
ptr_type_of_instruction->is_const = is_const;
@@ -4609,14 +4605,8 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode
}
static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) {
- AstNode *expr_node;
- if (node->type == NodeTypePrefixOpExpr) {
- expr_node = node->data.prefix_op_expr.primary_expr;
- } else if (node->type == NodeTypePtrDeref) {
- expr_node = node->data.ptr_deref_expr.target;
- } else {
- zig_unreachable();
- }
+ assert(node->type == NodeTypePrefixOpExpr);
+ AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval);
if (value == irb->codegen->invalid_instruction)
@@ -4640,16 +4630,12 @@ static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *
return ir_build_ref(irb, scope, value->source_node, value, lval.is_const, lval.is_volatile);
}
-static IrInstruction *ir_gen_address_of(IrBuilder *irb, Scope *scope, AstNode *node) {
- assert(node->type == NodeTypeAddrOfExpr);
- bool is_const = node->data.addr_of_expr.is_const;
- bool is_volatile = node->data.addr_of_expr.is_volatile;
- AstNode *expr_node = node->data.addr_of_expr.op_expr;
- AstNode *align_expr = node->data.addr_of_expr.align_expr;
-
- if (align_expr == nullptr && !is_const && !is_volatile) {
- return ir_gen_node_extra(irb, expr_node, scope, make_lval_addr(is_const, is_volatile));
- }
+static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode *node) {
+ assert(node->type == NodeTypePointerType);
+ bool is_const = node->data.pointer_type.is_const;
+ bool is_volatile = node->data.pointer_type.is_volatile;
+ AstNode *expr_node = node->data.pointer_type.op_expr;
+ AstNode *align_expr = node->data.pointer_type.align_expr;
IrInstruction *align_value;
if (align_expr != nullptr) {
@@ -4665,27 +4651,27 @@ static IrInstruction *ir_gen_address_of(IrBuilder *irb, Scope *scope, AstNode *n
return child_type;
uint32_t bit_offset_start = 0;
- if (node->data.addr_of_expr.bit_offset_start != nullptr) {
- if (!bigint_fits_in_bits(node->data.addr_of_expr.bit_offset_start, 32, false)) {
+ if (node->data.pointer_type.bit_offset_start != nullptr) {
+ if (!bigint_fits_in_bits(node->data.pointer_type.bit_offset_start, 32, false)) {
Buf *val_buf = buf_alloc();
- bigint_append_buf(val_buf, node->data.addr_of_expr.bit_offset_start, 10);
+ bigint_append_buf(val_buf, node->data.pointer_type.bit_offset_start, 10);
exec_add_error_node(irb->codegen, irb->exec, node,
buf_sprintf("value %s too large for u32 bit offset", buf_ptr(val_buf)));
return irb->codegen->invalid_instruction;
}
- bit_offset_start = bigint_as_unsigned(node->data.addr_of_expr.bit_offset_start);
+ bit_offset_start = bigint_as_unsigned(node->data.pointer_type.bit_offset_start);
}
uint32_t bit_offset_end = 0;
- if (node->data.addr_of_expr.bit_offset_end != nullptr) {
- if (!bigint_fits_in_bits(node->data.addr_of_expr.bit_offset_end, 32, false)) {
+ if (node->data.pointer_type.bit_offset_end != nullptr) {
+ if (!bigint_fits_in_bits(node->data.pointer_type.bit_offset_end, 32, false)) {
Buf *val_buf = buf_alloc();
- bigint_append_buf(val_buf, node->data.addr_of_expr.bit_offset_end, 10);
+ bigint_append_buf(val_buf, node->data.pointer_type.bit_offset_end, 10);
exec_add_error_node(irb->codegen, irb->exec, node,
buf_sprintf("value %s too large for u32 bit offset", buf_ptr(val_buf)));
return irb->codegen->invalid_instruction;
}
- bit_offset_end = bigint_as_unsigned(node->data.addr_of_expr.bit_offset_end);
+ bit_offset_end = bigint_as_unsigned(node->data.pointer_type.bit_offset_end);
}
if ((bit_offset_start != 0 || bit_offset_end != 0) && bit_offset_start >= bit_offset_end) {
@@ -4694,7 +4680,7 @@ static IrInstruction *ir_gen_address_of(IrBuilder *irb, Scope *scope, AstNode *n
return irb->codegen->invalid_instruction;
}
- return ir_build_ptr_type_of(irb, scope, node, child_type, is_const, is_volatile,
+ return ir_build_ptr_type(irb, scope, node, child_type, is_const, is_volatile,
align_value, bit_offset_start, bit_offset_end);
}
@@ -4761,6 +4747,10 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod
return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpMaybe), lval);
case PrefixOpUnwrapMaybe:
return ir_gen_maybe_assert_ok(irb, scope, node, lval);
+ case PrefixOpAddrOf: {
+ AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
+ return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LVAL_PTR), lval);
+ }
}
zig_unreachable();
}
@@ -6568,8 +6558,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
return ir_lval_wrap(irb, scope, ir_gen_if_bool_expr(irb, scope, node), lval);
case NodeTypePrefixOpExpr:
return ir_gen_prefix_op_expr(irb, scope, node, lval);
- case NodeTypeAddrOfExpr:
- return ir_lval_wrap(irb, scope, ir_gen_address_of(irb, scope, node), lval);
case NodeTypeContainerInitExpr:
return ir_lval_wrap(irb, scope, ir_gen_container_init_expr(irb, scope, node), lval);
case NodeTypeVariableDeclaration:
@@ -6592,14 +6580,23 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
return ir_build_load_ptr(irb, scope, node, ptr_instruction);
}
- case NodeTypePtrDeref:
- return ir_gen_prefix_op_id_lval(irb, scope, node, IrUnOpDereference, lval);
+ case NodeTypePtrDeref: {
+ assert(node->type == NodeTypePtrDeref);
+ AstNode *expr_node = node->data.ptr_deref_expr.target;
+ IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval);
+ if (value == irb->codegen->invalid_instruction)
+ return value;
+
+ return ir_build_un_op(irb, scope, node, IrUnOpDereference, value);
+ }
case NodeTypeThisLiteral:
return ir_lval_wrap(irb, scope, ir_gen_this_literal(irb, scope, node), lval);
case NodeTypeBoolLiteral:
return ir_lval_wrap(irb, scope, ir_gen_bool_literal(irb, scope, node), lval);
case NodeTypeArrayType:
return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval);
+ case NodeTypePointerType:
+ return ir_lval_wrap(irb, scope, ir_gen_pointer_type(irb, scope, node), lval);
case NodeTypePromiseType:
return ir_lval_wrap(irb, scope, ir_gen_promise_type(irb, scope, node), lval);
case NodeTypeStringLiteral:
@@ -8961,6 +8958,7 @@ static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instructio
ConstExprValue *pointee, TypeTableEntry *pointee_type,
ConstPtrMut ptr_mut, bool ptr_is_const, bool ptr_is_volatile, uint32_t ptr_align)
{
+ // TODO remove this special case for types
if (pointee_type->id == TypeTableEntryIdMetaType) {
TypeTableEntry *type_entry = pointee->data.x_type;
if (type_entry->id == TypeTableEntryIdUnreachable) {
@@ -18778,11 +18776,16 @@ static TypeTableEntry *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstr
return usize;
}
-static TypeTableEntry *ir_analyze_instruction_ptr_type_of(IrAnalyze *ira, IrInstructionPtrTypeOf *instruction) {
+static TypeTableEntry *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstructionPtrType *instruction) {
TypeTableEntry *child_type = ir_resolve_type(ira, instruction->child_type->other);
if (type_is_invalid(child_type))
return ira->codegen->builtin_types.entry_invalid;
+ if (child_type->id == TypeTableEntryIdUnreachable) {
+ ir_add_error(ira, &instruction->base, buf_sprintf("pointer to noreturn not allowed"));
+ return ira->codegen->builtin_types.entry_invalid;
+ }
+
uint32_t align_bytes;
if (instruction->align_value != nullptr) {
if (!ir_resolve_align(ira, instruction->align_value->other, &align_bytes))
@@ -19606,8 +19609,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
return ir_analyze_instruction_type_id(ira, (IrInstructionTypeId *)instruction);
case IrInstructionIdSetEvalBranchQuota:
return ir_analyze_instruction_set_eval_branch_quota(ira, (IrInstructionSetEvalBranchQuota *)instruction);
- case IrInstructionIdPtrTypeOf:
- return ir_analyze_instruction_ptr_type_of(ira, (IrInstructionPtrTypeOf *)instruction);
+ case IrInstructionIdPtrType:
+ return ir_analyze_instruction_ptr_type(ira, (IrInstructionPtrType *)instruction);
case IrInstructionIdAlignCast:
return ir_analyze_instruction_align_cast(ira, (IrInstructionAlignCast *)instruction);
case IrInstructionIdOpaqueType:
@@ -19783,7 +19786,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdCheckStatementIsVoid:
case IrInstructionIdPanic:
case IrInstructionIdSetEvalBranchQuota:
- case IrInstructionIdPtrTypeOf:
+ case IrInstructionIdPtrType:
case IrInstructionIdSetAlignStack:
case IrInstructionIdExport:
case IrInstructionIdCancel:
diff --git a/src/ir_print.cpp b/src/ir_print.cpp
index 9678120f1d..3c177a8bbf 100644
--- a/src/ir_print.cpp
+++ b/src/ir_print.cpp
@@ -921,7 +921,7 @@ static void ir_print_can_implicit_cast(IrPrint *irp, IrInstructionCanImplicitCas
fprintf(irp->f, ")");
}
-static void ir_print_ptr_type_of(IrPrint *irp, IrInstructionPtrTypeOf *instruction) {
+static void ir_print_ptr_type(IrPrint *irp, IrInstructionPtrType *instruction) {
fprintf(irp->f, "&");
if (instruction->align_value != nullptr) {
fprintf(irp->f, "align(");
@@ -1527,8 +1527,8 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdCanImplicitCast:
ir_print_can_implicit_cast(irp, (IrInstructionCanImplicitCast *)instruction);
break;
- case IrInstructionIdPtrTypeOf:
- ir_print_ptr_type_of(irp, (IrInstructionPtrTypeOf *)instruction);
+ case IrInstructionIdPtrType:
+ ir_print_ptr_type(irp, (IrInstructionPtrType *)instruction);
break;
case IrInstructionIdDeclRef:
ir_print_decl_ref(irp, (IrInstructionDeclRef *)instruction);
diff --git a/src/parser.cpp b/src/parser.cpp
index 4763d3b987..ef390a3a2e 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -1167,20 +1167,19 @@ static PrefixOp tok_to_prefix_op(Token *token) {
case TokenIdTilde: return PrefixOpBinNot;
case TokenIdMaybe: return PrefixOpMaybe;
case TokenIdDoubleQuestion: return PrefixOpUnwrapMaybe;
+ case TokenIdAmpersand: return PrefixOpAddrOf;
default: return PrefixOpInvalid;
}
}
-static AstNode *ast_parse_addr_of(ParseContext *pc, size_t *token_index) {
- Token *ampersand_tok = ast_eat_token(pc, token_index, TokenIdAmpersand);
-
- AstNode *node = ast_create_node(pc, NodeTypeAddrOfExpr, ampersand_tok);
+static AstNode *ast_parse_pointer_type(ParseContext *pc, size_t *token_index, Token *star_tok) {
+ AstNode *node = ast_create_node(pc, NodeTypePointerType, star_tok);
Token *token = &pc->tokens->at(*token_index);
if (token->id == TokenIdKeywordAlign) {
*token_index += 1;
ast_eat_token(pc, token_index, TokenIdLParen);
- node->data.addr_of_expr.align_expr = ast_parse_expression(pc, token_index, true);
+ node->data.pointer_type.align_expr = ast_parse_expression(pc, token_index, true);
token = &pc->tokens->at(*token_index);
if (token->id == TokenIdColon) {
@@ -1189,24 +1188,24 @@ static AstNode *ast_parse_addr_of(ParseContext *pc, size_t *token_index) {
ast_eat_token(pc, token_index, TokenIdColon);
Token *bit_offset_end_tok = ast_eat_token(pc, token_index, TokenIdIntLiteral);
- node->data.addr_of_expr.bit_offset_start = token_bigint(bit_offset_start_tok);
- node->data.addr_of_expr.bit_offset_end = token_bigint(bit_offset_end_tok);
+ node->data.pointer_type.bit_offset_start = token_bigint(bit_offset_start_tok);
+ node->data.pointer_type.bit_offset_end = token_bigint(bit_offset_end_tok);
}
ast_eat_token(pc, token_index, TokenIdRParen);
token = &pc->tokens->at(*token_index);
}
if (token->id == TokenIdKeywordConst) {
*token_index += 1;
- node->data.addr_of_expr.is_const = true;
+ node->data.pointer_type.is_const = true;
token = &pc->tokens->at(*token_index);
}
if (token->id == TokenIdKeywordVolatile) {
*token_index += 1;
- node->data.addr_of_expr.is_volatile = true;
+ node->data.pointer_type.is_volatile = true;
}
- node->data.addr_of_expr.op_expr = ast_parse_prefix_op_expr(pc, token_index, true);
+ node->data.pointer_type.op_expr = ast_parse_prefix_op_expr(pc, token_index, true);
return node;
}
@@ -1216,8 +1215,17 @@ PrefixOp = "!" | "-" | "~" | ("*" option("align" "(" Expression option(":" Integ
*/
static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
Token *token = &pc->tokens->at(*token_index);
- if (token->id == TokenIdAmpersand) {
- return ast_parse_addr_of(pc, token_index);
+ if (token->id == TokenIdStar) {
+ *token_index += 1;
+ return ast_parse_pointer_type(pc, token_index, token);
+ }
+ if (token->id == TokenIdStarStar) {
+ *token_index += 1;
+ AstNode *child_node = ast_parse_pointer_type(pc, token_index, token);
+ child_node->column += 1;
+ AstNode *parent_node = ast_create_node(pc, NodeTypePointerType, token);
+ parent_node->data.pointer_type.op_expr = child_node;
+ return parent_node;
}
if (token->id == TokenIdKeywordTry) {
return ast_parse_try_expr(pc, token_index);
@@ -1234,13 +1242,12 @@ static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index,
AstNode *node = ast_create_node(pc, NodeTypePrefixOpExpr, token);
- AstNode *parent_node = node;
AstNode *prefix_op_expr = ast_parse_error_set_expr(pc, token_index, true);
node->data.prefix_op_expr.primary_expr = prefix_op_expr;
node->data.prefix_op_expr.prefix_op = prefix_op;
- return parent_node;
+ return node;
}
@@ -3121,9 +3128,9 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
case NodeTypeErrorType:
// none
break;
- case NodeTypeAddrOfExpr:
- visit_field(&node->data.addr_of_expr.align_expr, visit, context);
- visit_field(&node->data.addr_of_expr.op_expr, visit, context);
+ case NodeTypePointerType:
+ visit_field(&node->data.pointer_type.align_expr, visit, context);
+ visit_field(&node->data.pointer_type.op_expr, visit, context);
break;
case NodeTypeErrorSetDecl:
visit_node_list(&node->data.err_set_decl.decls, visit, context);
diff --git a/src/translate_c.cpp b/src/translate_c.cpp
index 50ff073008..db541d34f3 100644
--- a/src/translate_c.cpp
+++ b/src/translate_c.cpp
@@ -276,11 +276,18 @@ static AstNode *maybe_suppress_result(Context *c, ResultUsed result_used, AstNod
node);
}
-static AstNode *trans_create_node_addr_of(Context *c, bool is_const, bool is_volatile, AstNode *child_node) {
- AstNode *node = trans_create_node(c, NodeTypeAddrOfExpr);
- node->data.addr_of_expr.is_const = is_const;
- node->data.addr_of_expr.is_volatile = is_volatile;
- node->data.addr_of_expr.op_expr = child_node;
+static AstNode *trans_create_node_ptr_type(Context *c, bool is_const, bool is_volatile, AstNode *child_node) {
+ AstNode *node = trans_create_node(c, NodeTypePointerType);
+ node->data.pointer_type.is_const = is_const;
+ node->data.pointer_type.is_volatile = is_volatile;
+ node->data.pointer_type.op_expr = child_node;
+ return node;
+}
+
+static AstNode *trans_create_node_addr_of(Context *c, AstNode *child_node) {
+ AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);
+ node->data.prefix_op_expr.prefix_op = PrefixOpAddrOf;
+ node->data.prefix_op_expr.primary_expr = child_node;
return node;
}
@@ -848,7 +855,7 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou
return trans_create_node_prefix_op(c, PrefixOpMaybe, child_node);
}
- AstNode *pointer_node = trans_create_node_addr_of(c, child_qt.isConstQualified(),
+ AstNode *pointer_node = trans_create_node_ptr_type(c, child_qt.isConstQualified(),
child_qt.isVolatileQualified(), child_node);
return trans_create_node_prefix_op(c, PrefixOpMaybe, pointer_node);
}
@@ -1033,7 +1040,7 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou
emit_warning(c, source_loc, "unresolved array element type");
return nullptr;
}
- AstNode *pointer_node = trans_create_node_addr_of(c, child_qt.isConstQualified(),
+ AstNode *pointer_node = trans_create_node_ptr_type(c, child_qt.isConstQualified(),
child_qt.isVolatileQualified(), child_type_node);
return pointer_node;
}
@@ -1402,7 +1409,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result
// const _ref = &lhs;
AstNode *lhs = trans_expr(c, ResultUsedYes, &child_scope->base, stmt->getLHS(), TransLValue);
if (lhs == nullptr) return nullptr;
- AstNode *addr_of_lhs = trans_create_node_addr_of(c, false, false, lhs);
+ AstNode *addr_of_lhs = trans_create_node_addr_of(c, lhs);
// TODO: avoid name collisions with generated variable names
Buf* tmp_var_name = buf_create_from_str("_ref");
AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr, addr_of_lhs);
@@ -1476,7 +1483,7 @@ static AstNode *trans_create_compound_assign(Context *c, ResultUsed result_used,
// const _ref = &lhs;
AstNode *lhs = trans_expr(c, ResultUsedYes, &child_scope->base, stmt->getLHS(), TransLValue);
if (lhs == nullptr) return nullptr;
- AstNode *addr_of_lhs = trans_create_node_addr_of(c, false, false, lhs);
+ AstNode *addr_of_lhs = trans_create_node_addr_of(c, lhs);
// TODO: avoid name collisions with generated variable names
Buf* tmp_var_name = buf_create_from_str("_ref");
AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr, addr_of_lhs);
@@ -1813,7 +1820,7 @@ static AstNode *trans_create_post_crement(Context *c, ResultUsed result_used, Tr
// const _ref = &expr;
AstNode *expr = trans_expr(c, ResultUsedYes, &child_scope->base, op_expr, TransLValue);
if (expr == nullptr) return nullptr;
- AstNode *addr_of_expr = trans_create_node_addr_of(c, false, false, expr);
+ AstNode *addr_of_expr = trans_create_node_addr_of(c, expr);
// TODO: avoid name collisions with generated variable names
Buf* ref_var_name = buf_create_from_str("_ref");
AstNode *ref_var_decl = trans_create_node_var_decl_local(c, true, ref_var_name, nullptr, addr_of_expr);
@@ -1868,7 +1875,7 @@ static AstNode *trans_create_pre_crement(Context *c, ResultUsed result_used, Tra
// const _ref = &expr;
AstNode *expr = trans_expr(c, ResultUsedYes, &child_scope->base, op_expr, TransLValue);
if (expr == nullptr) return nullptr;
- AstNode *addr_of_expr = trans_create_node_addr_of(c, false, false, expr);
+ AstNode *addr_of_expr = trans_create_node_addr_of(c, expr);
// TODO: avoid name collisions with generated variable names
Buf* ref_var_name = buf_create_from_str("_ref");
AstNode *ref_var_decl = trans_create_node_var_decl_local(c, true, ref_var_name, nullptr, addr_of_expr);
@@ -1917,7 +1924,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc
AstNode *value_node = trans_expr(c, result_used, scope, stmt->getSubExpr(), TransLValue);
if (value_node == nullptr)
return value_node;
- return trans_create_node_addr_of(c, false, false, value_node);
+ return trans_create_node_addr_of(c, value_node);
}
case UO_Deref:
{
@@ -4441,7 +4448,7 @@ static AstNode *parse_ctok_suffix_op_expr(Context *c, CTokenize *ctok, size_t *t
} else if (first_tok->id == CTokIdAsterisk) {
*tok_i += 1;
- node = trans_create_node_addr_of(c, false, false, node);
+ node = trans_create_node_ptr_type(c, false, false, node);
} else {
return node;
}