aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/analyze.cpp21
-rw-r--r--src/parser.cpp43
2 files changed, 41 insertions, 23 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 3e3bf2b5f3..c3d66a26f8 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -457,6 +457,10 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t
assert(node->type == NodeTypeFnProto);
AstNodeFnProto *fn_proto = &node->data.fn_proto;
+ if (fn_proto->skip) {
+ return;
+ }
+
TypeTableEntry *fn_type = new_type_table_entry(TypeTableEntryIdFn);
fn_table_entry->type_entry = fn_type;
fn_type->data.fn.calling_convention = fn_table_entry->internal_linkage ? LLVMFastCallConv : LLVMCCallConv;
@@ -932,6 +936,9 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
static void preview_fn_proto(CodeGen *g, ImportTableEntry *import,
AstNode *proto_node)
{
+ if (proto_node->data.fn_proto.skip) {
+ return;
+ }
AstNode *fn_def_node = proto_node->data.fn_proto.fn_def_node;
AstNode *struct_node = proto_node->data.fn_proto.struct_node;
bool is_extern = proto_node->data.fn_proto.is_extern;
@@ -4307,6 +4314,10 @@ static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNo
buf_sprintf("byvalue struct parameters not yet supported on exported functions"));
}
+ if (buf_len(&param_decl->name) == 0) {
+ add_node_error(g, param_decl_node, buf_sprintf("missing parameter name"));
+ }
+
VariableTableEntry *var = add_local_var(g, param_decl_node, context, &param_decl->name, type, true);
var->src_arg_index = i;
param_decl_node->data.param_decl.variable = var;
@@ -4682,6 +4693,15 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
}
case NodeTypeFnProto:
{
+ // if the name is missing, we immediately announce an error
+ Buf *name = &node->data.fn_proto.name;
+ if (buf_len(name) == 0) {
+ node->data.fn_proto.skip = true;
+ add_node_error(g, node, buf_sprintf("missing function name"));
+ break;
+ }
+
+
// determine which other top level declarations this function prototype depends on.
TopLevelDecl *decl_node = &node->data.fn_proto.top_level_decl;
decl_node->deps.init(1);
@@ -4692,7 +4712,6 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
}
collect_expr_decl_deps(g, import, node->data.fn_proto.return_type, decl_node);
- Buf *name = &node->data.fn_proto.name;
decl_node->name = name;
decl_node->import = import;
if (decl_node->deps.size() > 0) {
diff --git a/src/parser.cpp b/src/parser.cpp
index 170d579956..e717a18941 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -569,35 +569,33 @@ static void ast_parse_directives(ParseContext *pc, int *token_index,
}
/*
-ParamDecl : option("noalias") "Symbol" ":" PrefixOpExpression | "..."
+ParamDecl = option("noalias") option("Symbol" ":") PrefixOpExpression | "..."
*/
static AstNode *ast_parse_param_decl(ParseContext *pc, int *token_index) {
- Token *first_token = &pc->tokens->at(*token_index);
+ Token *token = &pc->tokens->at(*token_index);
- if (first_token->id == TokenIdEllipsis) {
+ if (token->id == TokenIdEllipsis) {
*token_index += 1;
return nullptr;
}
- AstNode *node = ast_create_node(pc, NodeTypeParamDecl, first_token);
- Token *name_token;
+ AstNode *node = ast_create_node(pc, NodeTypeParamDecl, token);
- if (first_token->id == TokenIdKeywordNoAlias) {
+ if (token->id == TokenIdKeywordNoAlias) {
node->data.param_decl.is_noalias = true;
*token_index += 1;
- name_token = ast_eat_token(pc, token_index, TokenIdSymbol);
- } else if (first_token->id == TokenIdSymbol) {
- name_token = first_token;
- *token_index += 1;
- } else {
- ast_invalid_token_error(pc, first_token);
+ token = &pc->tokens->at(*token_index);
}
- ast_buf_from_token(pc, name_token, &node->data.param_decl.name);
+ buf_resize(&node->data.param_decl.name, 0);
- Token *colon = &pc->tokens->at(*token_index);
- *token_index += 1;
- ast_expect_token(pc, colon, TokenIdColon);
+ if (token->id == TokenIdSymbol) {
+ Token *next_token = &pc->tokens->at(*token_index + 1);
+ if (next_token->id == TokenIdColon) {
+ ast_buf_from_token(pc, token, &node->data.param_decl.name);
+ *token_index += 2;
+ }
+ }
node->data.param_decl.type = ast_parse_prefix_op_expr(pc, token_index, true);
@@ -2179,7 +2177,7 @@ static AstNode *ast_parse_block(ParseContext *pc, int *token_index, bool mandato
}
/*
-FnProto : "fn" "Symbol" ParamDeclList option("->" PrefixOpExpression)
+FnProto : "fn" option("Symbol") ParamDeclList option("->" PrefixOpExpression)
*/
static AstNode *ast_parse_fn_proto(ParseContext *pc, int *token_index, bool mandatory,
ZigList<AstNode*> *directives, VisibMod visib_mod)
@@ -2200,11 +2198,12 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, int *token_index, bool mand
node->data.fn_proto.directives = directives;
Token *fn_name = &pc->tokens->at(*token_index);
- *token_index += 1;
- ast_expect_token(pc, fn_name, TokenIdSymbol);
-
- ast_buf_from_token(pc, fn_name, &node->data.fn_proto.name);
-
+ if (fn_name->id == TokenIdSymbol) {
+ *token_index += 1;
+ ast_buf_from_token(pc, fn_name, &node->data.fn_proto.name);
+ } else {
+ buf_resize(&node->data.fn_proto.name, 0);
+ }
ast_parse_param_decl_list(pc, token_index, &node->data.fn_proto.params, &node->data.fn_proto.is_var_args);