Merge commit '0b12e027a3628e26a765126d9937a2366b638ff3' into zig0-0.15.1
This commit is contained in:
112
stage0/astgen.c
112
stage0/astgen.c
@@ -1089,6 +1089,54 @@ static void strLitAsString(AstGenCtx* ag, uint32_t str_lit_token,
|
|||||||
ag->string_bytes[ag->string_bytes_len++] = val;
|
ag->string_bytes[ag->string_bytes_len++] = val;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'u': {
|
||||||
|
// \u{NNNNNN} unicode escape (string_literal.zig:194-231).
|
||||||
|
// Skip past '{'.
|
||||||
|
i++;
|
||||||
|
// Parse hex digits until '}'.
|
||||||
|
uint32_t codepoint = 0;
|
||||||
|
while (i + 1 < raw_end) {
|
||||||
|
i++;
|
||||||
|
char c = source[i];
|
||||||
|
if (c >= '0' && c <= '9') {
|
||||||
|
codepoint = codepoint * 16 + (uint32_t)(c - '0');
|
||||||
|
} else if (c >= 'a' && c <= 'f') {
|
||||||
|
codepoint = codepoint * 16 + 10 + (uint32_t)(c - 'a');
|
||||||
|
} else if (c >= 'A' && c <= 'F') {
|
||||||
|
codepoint = codepoint * 16 + 10 + (uint32_t)(c - 'A');
|
||||||
|
} else {
|
||||||
|
// Must be '}', done.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Encode codepoint as UTF-8 (unicode.zig:53-82).
|
||||||
|
if (codepoint <= 0x7F) {
|
||||||
|
ag->string_bytes[ag->string_bytes_len++]
|
||||||
|
= (uint8_t)codepoint;
|
||||||
|
} else if (codepoint <= 0x7FF) {
|
||||||
|
ag->string_bytes[ag->string_bytes_len++]
|
||||||
|
= (uint8_t)(0xC0 | (codepoint >> 6));
|
||||||
|
ag->string_bytes[ag->string_bytes_len++]
|
||||||
|
= (uint8_t)(0x80 | (codepoint & 0x3F));
|
||||||
|
} else if (codepoint <= 0xFFFF) {
|
||||||
|
ag->string_bytes[ag->string_bytes_len++]
|
||||||
|
= (uint8_t)(0xE0 | (codepoint >> 12));
|
||||||
|
ag->string_bytes[ag->string_bytes_len++]
|
||||||
|
= (uint8_t)(0x80 | ((codepoint >> 6) & 0x3F));
|
||||||
|
ag->string_bytes[ag->string_bytes_len++]
|
||||||
|
= (uint8_t)(0x80 | (codepoint & 0x3F));
|
||||||
|
} else {
|
||||||
|
ag->string_bytes[ag->string_bytes_len++]
|
||||||
|
= (uint8_t)(0xF0 | (codepoint >> 18));
|
||||||
|
ag->string_bytes[ag->string_bytes_len++]
|
||||||
|
= (uint8_t)(0x80 | ((codepoint >> 12) & 0x3F));
|
||||||
|
ag->string_bytes[ag->string_bytes_len++]
|
||||||
|
= (uint8_t)(0x80 | ((codepoint >> 6) & 0x3F));
|
||||||
|
ag->string_bytes[ag->string_bytes_len++]
|
||||||
|
= (uint8_t)(0x80 | (codepoint & 0x3F));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
ag->string_bytes[ag->string_bytes_len++] = (uint8_t)source[i];
|
ag->string_bytes[ag->string_bytes_len++] = (uint8_t)source[i];
|
||||||
break;
|
break;
|
||||||
@@ -4251,6 +4299,26 @@ static uint32_t exprRl(GenZir* gz, Scope* scope, ResultLoc rl, uint32_t node) {
|
|||||||
char_val = val;
|
char_val = val;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'u': {
|
||||||
|
// \u{NNNNNN} unicode escape (string_literal.zig:194-231).
|
||||||
|
// Skip past '{'.
|
||||||
|
ci++;
|
||||||
|
uint32_t codepoint = 0;
|
||||||
|
while (true) {
|
||||||
|
ci++;
|
||||||
|
char c = src[ci];
|
||||||
|
if (c >= '0' && c <= '9')
|
||||||
|
codepoint = codepoint * 16 + (uint32_t)(c - '0');
|
||||||
|
else if (c >= 'a' && c <= 'f')
|
||||||
|
codepoint = codepoint * 16 + 10 + (uint32_t)(c - 'a');
|
||||||
|
else if (c >= 'A' && c <= 'F')
|
||||||
|
codepoint = codepoint * 16 + 10 + (uint32_t)(c - 'A');
|
||||||
|
else
|
||||||
|
break; // Must be '}'.
|
||||||
|
}
|
||||||
|
char_val = codepoint;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
char_val = (uint8_t)src[ci];
|
char_val = (uint8_t)src[ci];
|
||||||
break;
|
break;
|
||||||
@@ -4762,7 +4830,7 @@ static uint32_t blockExprExpr(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Labeled block (AstGen.zig:2466-2536).
|
// Labeled block (AstGen.zig:2466-2536).
|
||||||
bool force_comptime = gz->is_comptime;
|
// Note: upstream blockExpr always passes force_comptime=false.
|
||||||
uint32_t label_token = lbrace - 2;
|
uint32_t label_token = lbrace - 2;
|
||||||
|
|
||||||
// Compute break result info (AstGen.zig:2484-2492).
|
// Compute break result info (AstGen.zig:2484-2492).
|
||||||
@@ -4771,15 +4839,10 @@ static uint32_t blockExprExpr(
|
|||||||
bool need_result_rvalue = (break_ri.tag != rl.tag);
|
bool need_result_rvalue = (break_ri.tag != rl.tag);
|
||||||
|
|
||||||
// Reserve the block instruction (AstGen.zig:2500-2501).
|
// Reserve the block instruction (AstGen.zig:2500-2501).
|
||||||
ZirInstTag block_tag
|
uint32_t block_inst = makeBlockInst(ag, ZIR_INST_BLOCK, gz, node);
|
||||||
= force_comptime ? ZIR_INST_BLOCK_COMPTIME : ZIR_INST_BLOCK;
|
|
||||||
uint32_t block_inst = makeBlockInst(ag, block_tag, gz, node);
|
|
||||||
gzAppendInstruction(gz, block_inst);
|
gzAppendInstruction(gz, block_inst);
|
||||||
|
|
||||||
GenZir block_scope = makeSubBlock(gz, scope);
|
GenZir block_scope = makeSubBlock(gz, scope);
|
||||||
block_scope.is_inline = force_comptime; // AstGen.zig:2503
|
|
||||||
if (force_comptime)
|
|
||||||
block_scope.is_comptime = true;
|
|
||||||
// Set label on block_scope (AstGen.zig:2504-2508).
|
// Set label on block_scope (AstGen.zig:2504-2508).
|
||||||
block_scope.label_token = label_token;
|
block_scope.label_token = label_token;
|
||||||
block_scope.label_block_inst = block_inst;
|
block_scope.label_block_inst = block_inst;
|
||||||
@@ -4790,29 +4853,19 @@ static uint32_t blockExprExpr(
|
|||||||
|
|
||||||
if (!endsWithNoReturn(&block_scope)) {
|
if (!endsWithNoReturn(&block_scope)) {
|
||||||
// Emit restore_err_ret_index (AstGen.zig:2515).
|
// Emit restore_err_ret_index (AstGen.zig:2515).
|
||||||
if (!force_comptime) {
|
|
||||||
ZirInstData rdata;
|
ZirInstData rdata;
|
||||||
rdata.un_node.operand = block_inst + ZIR_REF_START_INDEX;
|
rdata.un_node.operand = block_inst + ZIR_REF_START_INDEX;
|
||||||
rdata.un_node.src_node
|
rdata.un_node.src_node = (int32_t)node - (int32_t)gz->decl_node_index;
|
||||||
= (int32_t)node - (int32_t)gz->decl_node_index;
|
|
||||||
addInstruction(
|
addInstruction(
|
||||||
gz, ZIR_INST_RESTORE_ERR_RET_INDEX_UNCONDITIONAL, rdata);
|
gz, ZIR_INST_RESTORE_ERR_RET_INDEX_UNCONDITIONAL, rdata);
|
||||||
}
|
|
||||||
// rvalue + break (AstGen.zig:2516-2518).
|
// rvalue + break (AstGen.zig:2516-2518).
|
||||||
uint32_t result = rvalue(
|
uint32_t result = rvalue(
|
||||||
gz, block_scope.break_result_info, ZIR_REF_VOID_VALUE, node);
|
gz, block_scope.break_result_info, ZIR_REF_VOID_VALUE, node);
|
||||||
ZirInstTag break_tag
|
addBreak(&block_scope, ZIR_INST_BREAK, block_inst, result,
|
||||||
= force_comptime ? ZIR_INST_BREAK_INLINE : ZIR_INST_BREAK;
|
AST_NODE_OFFSET_NONE);
|
||||||
addBreak(
|
|
||||||
&block_scope, break_tag, block_inst, result, AST_NODE_OFFSET_NONE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (force_comptime) {
|
|
||||||
setBlockComptimeBody(
|
|
||||||
ag, &block_scope, block_inst, COMPTIME_REASON_COMPTIME_KEYWORD);
|
|
||||||
} else {
|
|
||||||
setBlockBody(ag, &block_scope, block_inst);
|
setBlockBody(ag, &block_scope, block_inst);
|
||||||
}
|
|
||||||
|
|
||||||
// AstGen.zig:2531-2534.
|
// AstGen.zig:2531-2534.
|
||||||
if (need_result_rvalue)
|
if (need_result_rvalue)
|
||||||
@@ -6575,17 +6628,23 @@ static bool addEnsureResult(
|
|||||||
uint32_t inst = maybe_unused_result - ZIR_REF_START_INDEX;
|
uint32_t inst = maybe_unused_result - ZIR_REF_START_INDEX;
|
||||||
ZirInstTag tag = ag->inst_tags[inst];
|
ZirInstTag tag = ag->inst_tags[inst];
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
// For call/field_call/builtin_call: set ensure_result_used flag
|
// For call/field_call: set ensure_result_used flag
|
||||||
// (bit 3 of flags at offset 0). Flags *must* be at offset 0 in all
|
// (bit 3 of flags at offset 0). Flags *must* be at offset 0
|
||||||
// three structs (AstGen.zig:2658-2665, Zir.zig:3022).
|
// (AstGen.zig:2658-2665, Zir.zig:3022).
|
||||||
case ZIR_INST_CALL:
|
case ZIR_INST_CALL:
|
||||||
case ZIR_INST_FIELD_CALL:
|
case ZIR_INST_FIELD_CALL: {
|
||||||
case ZIR_INST_BUILTIN_CALL: {
|
|
||||||
uint32_t pi = ag->inst_datas[inst].pl_node.payload_index;
|
uint32_t pi = ag->inst_datas[inst].pl_node.payload_index;
|
||||||
ag->extra[pi] |= (1u << 3); // ensure_result_used
|
ag->extra[pi] |= (1u << 3); // ensure_result_used
|
||||||
elide_check = true;
|
elide_check = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// For builtin_call: ensure_result_used is at bit 1, not bit 3.
|
||||||
|
case ZIR_INST_BUILTIN_CALL: {
|
||||||
|
uint32_t pi = ag->inst_datas[inst].pl_node.payload_index;
|
||||||
|
ag->extra[pi] |= (1u << 1); // ensure_result_used
|
||||||
|
elide_check = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
// Always noreturn → elide (AstGen.zig:2909).
|
// Always noreturn → elide (AstGen.zig:2909).
|
||||||
case ZIR_INST_BREAK:
|
case ZIR_INST_BREAK:
|
||||||
case ZIR_INST_BREAK_INLINE:
|
case ZIR_INST_BREAK_INLINE:
|
||||||
@@ -6602,6 +6661,7 @@ static bool addEnsureResult(
|
|||||||
case ZIR_INST_TRAP:
|
case ZIR_INST_TRAP:
|
||||||
case ZIR_INST_CHECK_COMPTIME_CONTROL_FLOW:
|
case ZIR_INST_CHECK_COMPTIME_CONTROL_FLOW:
|
||||||
case ZIR_INST_SWITCH_CONTINUE:
|
case ZIR_INST_SWITCH_CONTINUE:
|
||||||
|
case ZIR_INST_COMPILE_ERROR:
|
||||||
is_noreturn = true;
|
is_noreturn = true;
|
||||||
elide_check = true;
|
elide_check = true;
|
||||||
break;
|
break;
|
||||||
@@ -9577,7 +9637,7 @@ static bool rlExpr(
|
|||||||
|
|
||||||
// defer (AstRlAnnotate.zig:148-151).
|
// defer (AstRlAnnotate.zig:148-151).
|
||||||
case AST_NODE_DEFER:
|
case AST_NODE_DEFER:
|
||||||
(void)rlExpr(ag, nd.rhs, block, RL_RI_NONE);
|
(void)rlExpr(ag, nd.lhs, block, RL_RI_NONE);
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// container_field (AstRlAnnotate.zig:153-167).
|
// container_field (AstRlAnnotate.zig:153-167).
|
||||||
|
|||||||
@@ -711,7 +711,7 @@ static AstNodeIndex expectStatement(Parser* p, bool allow_defer_var) {
|
|||||||
const AstTokenIndex comptime_token = eatToken(p, TOKEN_KEYWORD_COMPTIME);
|
const AstTokenIndex comptime_token = eatToken(p, TOKEN_KEYWORD_COMPTIME);
|
||||||
if (comptime_token != null_token) {
|
if (comptime_token != null_token) {
|
||||||
// comptime followed by block => comptime block statement
|
// comptime followed by block => comptime block statement
|
||||||
const AstNodeIndex block = parseBlock(p);
|
const AstNodeIndex block = parseBlockExpr(p);
|
||||||
if (block != 0) {
|
if (block != 0) {
|
||||||
return addNode(&p->nodes,
|
return addNode(&p->nodes,
|
||||||
(AstNodeItem) {
|
(AstNodeItem) {
|
||||||
@@ -1728,8 +1728,7 @@ static AstNodeIndex parseTypeExpr(Parser* p) {
|
|||||||
const AstNodeIndex condition = expectExpr(p);
|
const AstNodeIndex condition = expectExpr(p);
|
||||||
expectToken(p, TOKEN_R_PAREN);
|
expectToken(p, TOKEN_R_PAREN);
|
||||||
parsePtrPayload(p);
|
parsePtrPayload(p);
|
||||||
const AstNodeIndex cont_expr
|
const AstNodeIndex cont_expr = parseWhileContinueExpr(p);
|
||||||
= eatToken(p, TOKEN_COLON) != null_token ? expectExpr(p) : 0;
|
|
||||||
const AstNodeIndex body = parseTypeExpr(p);
|
const AstNodeIndex body = parseTypeExpr(p);
|
||||||
if (eatToken(p, TOKEN_KEYWORD_ELSE) != null_token) {
|
if (eatToken(p, TOKEN_KEYWORD_ELSE) != null_token) {
|
||||||
parsePayload(p);
|
parsePayload(p);
|
||||||
|
|||||||
Reference in New Issue
Block a user