From: Wolfgang Bumiller Date: Sat, 12 Jan 2013 10:03:17 +0000 (+0100) Subject: Declaration of type-restricted varargs X-Git-Tag: before-library~299 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=ca947d782c52864c7f7c0ddb9c4be657d359a071;p=xonotic%2Fgmqcc.git Declaration of type-restricted varargs --- diff --git a/ast.c b/ast.c index 995ba09..ee41347 100644 --- a/ast.c +++ b/ast.c @@ -75,6 +75,7 @@ static void ast_expression_init(ast_expression *self, self->expression.params = NULL; self->expression.count = 0; self->expression.flags = 0; + self->expression.varparam = NULL; } static void ast_expression_delete(ast_expression *self) diff --git a/ast.h b/ast.h index 37bbf02..b93de57 100644 --- a/ast.h +++ b/ast.h @@ -132,6 +132,10 @@ typedef struct size_t count; ast_value* *params; uint32_t flags; + /* void foo(string...) gets varparam set as a restriction + * for variadic parameters + */ + ast_expression *varparam; /* The codegen functions should store their output values * so we can call it multiple times without re-evaluating. * Store lvalue and rvalue seperately though. So that @@ -146,6 +150,7 @@ typedef struct #define AST_FLAG_INITIALIZED (1<<3) #define AST_FLAG_DEPRECATED (1<<4) #define AST_FLAG_INCLUDE_DEF (1<<5) +#define AST_FLAG_VARARG_COUNT (1<<6) #define AST_FLAG_TYPE_MASK (AST_FLAG_VARIADIC | AST_FLAG_NORETURN) /* Value diff --git a/parser.c b/parser.c index 2e16853..819c1e9 100644 --- a/parser.c +++ b/parser.c @@ -4291,6 +4291,7 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var) ast_value *fval; bool first = true; bool variadic = false; + ast_value *varparam = NULL; ctx = parser_ctx(parser); @@ -4320,11 +4321,7 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var) if (parser->tok == TOKEN_DOTS) { /* '...' indicates a varargs function */ variadic = true; - if (!parser_next(parser)) { - parseerror(parser, "expected parameter"); - return NULL; - } - if (parser->tok != ')') { + if (!parser_next(parser) || parser->tok != ')') { parseerror(parser, "`...` must be the last parameter of a variadic function declaration"); goto on_error; } @@ -4342,6 +4339,16 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var) parseerror(parser, "type not supported as part of a parameter list: %s", tname); goto on_error; } + /* type-restricted varargs */ + if (parser->tok == TOKEN_DOTS) { + variadic = true; + varparam = vec_last(params); + vec_pop(params); + if (!parser_next(parser) || parser->tok != ')') { + parseerror(parser, "`...` must be the last parameter of a variadic function declaration"); + goto on_error; + } + } } } @@ -4365,7 +4372,8 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var) fval->expression.flags |= AST_FLAG_VARIADIC; var = fval; - var->expression.params = params; + var->expression.params = params; + var->expression.varparam = (ast_expression*)varparam; params = NULL; return var;