parent
a299de2265
commit
46b0b84b90
@ -31,7 +31,7 @@ Directive = "#" "Symbol" "(" Expression ")"
|
|||||||
|
|
||||||
VisibleMod = "pub" | "export"
|
VisibleMod = "pub" | "export"
|
||||||
|
|
||||||
FnDef = option("inline") FnProto Block
|
FnDef = option("inline" | "extern") FnProto Block
|
||||||
|
|
||||||
ParamDeclList = "(" list(ParamDecl, ",") ")"
|
ParamDeclList = "(" list(ParamDecl, ",") ")"
|
||||||
|
|
||||||
|
@ -994,9 +994,9 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t
|
|||||||
buf_sprintf("invalid function attribute: '%s'", buf_ptr(name)));
|
buf_sprintf("invalid function attribute: '%s'", buf_ptr(name)));
|
||||||
}
|
}
|
||||||
} else if (buf_eql_str(name, "debug_safety")) {
|
} else if (buf_eql_str(name, "debug_safety")) {
|
||||||
if (fn_table_entry->is_extern) {
|
if (!fn_table_entry->fn_def_node) {
|
||||||
add_node_error(g, directive_node,
|
add_node_error(g, directive_node,
|
||||||
buf_sprintf("#debug_safety invalid on extern functions"));
|
buf_sprintf("#debug_safety valid only on function definitions"));
|
||||||
} else {
|
} else {
|
||||||
bool enable;
|
bool enable;
|
||||||
bool ok = resolve_const_expr_bool(g, import, import->block_context,
|
bool ok = resolve_const_expr_bool(g, import, import->block_context,
|
||||||
@ -1018,9 +1018,9 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t
|
|||||||
buf_sprintf("#condition valid only on exported symbols"));
|
buf_sprintf("#condition valid only on exported symbols"));
|
||||||
}
|
}
|
||||||
} else if (buf_eql_str(name, "static_eval_enable")) {
|
} else if (buf_eql_str(name, "static_eval_enable")) {
|
||||||
if (fn_table_entry->is_extern) {
|
if (!fn_table_entry->fn_def_node) {
|
||||||
add_node_error(g, directive_node,
|
add_node_error(g, directive_node,
|
||||||
buf_sprintf("#static_val_enable invalid on extern functions"));
|
buf_sprintf("#static_val_enable valid only on function definitions"));
|
||||||
} else {
|
} else {
|
||||||
bool enable;
|
bool enable;
|
||||||
bool ok = resolve_const_expr_bool(g, import, import->block_context,
|
bool ok = resolve_const_expr_bool(g, import, import->block_context,
|
||||||
@ -1470,9 +1470,9 @@ static void preview_fn_proto_instance(CodeGen *g, ImportTableEntry *import, AstN
|
|||||||
|
|
||||||
assert(!is_extern || !is_generic_instance);
|
assert(!is_extern || !is_generic_instance);
|
||||||
|
|
||||||
if (!is_extern && proto_node->data.fn_proto.is_var_args) {
|
if (fn_def_node && proto_node->data.fn_proto.is_var_args) {
|
||||||
add_node_error(g, proto_node,
|
add_node_error(g, proto_node,
|
||||||
buf_sprintf("variadic arguments only allowed in extern functions"));
|
buf_sprintf("variadic arguments only allowed in extern function declarations"));
|
||||||
}
|
}
|
||||||
|
|
||||||
FnTableEntry *fn_table_entry = allocate<FnTableEntry>(1);
|
FnTableEntry *fn_table_entry = allocate<FnTableEntry>(1);
|
||||||
@ -1480,13 +1480,13 @@ static void preview_fn_proto_instance(CodeGen *g, ImportTableEntry *import, AstN
|
|||||||
fn_table_entry->proto_node = proto_node;
|
fn_table_entry->proto_node = proto_node;
|
||||||
fn_table_entry->fn_def_node = fn_def_node;
|
fn_table_entry->fn_def_node = fn_def_node;
|
||||||
fn_table_entry->is_extern = is_extern;
|
fn_table_entry->is_extern = is_extern;
|
||||||
fn_table_entry->is_pure = !is_extern;
|
fn_table_entry->is_pure = fn_def_node != nullptr;
|
||||||
|
|
||||||
get_fully_qualified_decl_name(&fn_table_entry->symbol_name, proto_node, '_');
|
get_fully_qualified_decl_name(&fn_table_entry->symbol_name, proto_node, '_');
|
||||||
|
|
||||||
g->fn_protos.append(fn_table_entry);
|
g->fn_protos.append(fn_table_entry);
|
||||||
|
|
||||||
if (!is_extern) {
|
if (fn_def_node) {
|
||||||
g->fn_defs.append(fn_table_entry);
|
g->fn_defs.append(fn_table_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2414,27 +2414,46 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, int *token_index, bool mand
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
FnDef = option("inline") FnProto Block
|
FnDef = option("inline" | "extern") FnProto Block
|
||||||
*/
|
*/
|
||||||
static AstNode *ast_parse_fn_def(ParseContext *pc, int *token_index, bool mandatory,
|
static AstNode *ast_parse_fn_def(ParseContext *pc, int *token_index, bool mandatory,
|
||||||
ZigList<AstNode*> *directives, VisibMod visib_mod)
|
ZigList<AstNode*> *directives, VisibMod visib_mod)
|
||||||
{
|
{
|
||||||
Token *first_token = &pc->tokens->at(*token_index);
|
Token *first_token = &pc->tokens->at(*token_index);
|
||||||
bool is_inline;
|
bool is_inline;
|
||||||
|
bool is_extern;
|
||||||
if (first_token->id == TokenIdKeywordInline) {
|
if (first_token->id == TokenIdKeywordInline) {
|
||||||
*token_index += 1;
|
*token_index += 1;
|
||||||
is_inline = true;
|
is_inline = true;
|
||||||
|
is_extern = false;
|
||||||
|
} else if (first_token->id == TokenIdKeywordExtern) {
|
||||||
|
*token_index += 1;
|
||||||
|
is_extern = true;
|
||||||
|
is_inline = false;
|
||||||
} else {
|
} else {
|
||||||
is_inline = false;
|
is_inline = false;
|
||||||
|
is_extern = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AstNode *fn_proto = ast_parse_fn_proto(pc, token_index, mandatory, directives, visib_mod);
|
AstNode *fn_proto = ast_parse_fn_proto(pc, token_index, mandatory, directives, visib_mod);
|
||||||
if (!fn_proto)
|
if (!fn_proto) {
|
||||||
|
if (is_inline || is_extern) {
|
||||||
|
*token_index -= 1;
|
||||||
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
AstNode *node = ast_create_node(pc, NodeTypeFnDef, first_token);
|
}
|
||||||
|
|
||||||
fn_proto->data.fn_proto.is_inline = is_inline;
|
fn_proto->data.fn_proto.is_inline = is_inline;
|
||||||
|
fn_proto->data.fn_proto.is_extern = is_extern;
|
||||||
|
|
||||||
|
Token *semi_token = &pc->tokens->at(*token_index);
|
||||||
|
if (semi_token->id == TokenIdSemicolon) {
|
||||||
|
*token_index += 1;
|
||||||
|
normalize_parent_ptrs(fn_proto);
|
||||||
|
return fn_proto;
|
||||||
|
}
|
||||||
|
|
||||||
|
AstNode *node = ast_create_node(pc, NodeTypeFnDef, first_token);
|
||||||
node->data.fn_def.fn_proto = fn_proto;
|
node->data.fn_def.fn_proto = fn_proto;
|
||||||
node->data.fn_def.body = ast_parse_block(pc, token_index, true);
|
node->data.fn_def.body = ast_parse_block(pc, token_index, true);
|
||||||
normalize_parent_ptrs(node);
|
normalize_parent_ptrs(node);
|
||||||
|
@ -819,7 +819,7 @@ fn f() {
|
|||||||
|
|
||||||
add_compile_fail_case("variadic functions only allowed in extern", R"SOURCE(
|
add_compile_fail_case("variadic functions only allowed in extern", R"SOURCE(
|
||||||
fn f(...) {}
|
fn f(...) {}
|
||||||
)SOURCE", 1, ".tmp_source.zig:2:1: error: variadic arguments only allowed in extern functions");
|
)SOURCE", 1, ".tmp_source.zig:2:1: error: variadic arguments only allowed in extern function declarations");
|
||||||
|
|
||||||
add_compile_fail_case("write to const global variable", R"SOURCE(
|
add_compile_fail_case("write to const global variable", R"SOURCE(
|
||||||
const x : i32 = 99;
|
const x : i32 = 99;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user