F diff --git a/src/environment/error/gcc_error.c b/src/environment/error/gcc_error.c --- a/src/environment/error/gcc_error.c +++ b/src/environment/error/gcc_error.cchar *filename=NULL;size_t filename_size=0;+ struct wonky_stream s;struct Wonky_Message *hold;if(ptr->context)hold=get_wonky_message_vargs(WONKY_MESSAGE_TYPE_ERROR,WONKY_MESSAGE_SOURCE_TRANSLATION,line,column,filename,filename_size,err_fmt,args);+ s=wonky_string_stream(hold->message);+ wonky_fseek(&s,0,SEEK_END);+ wonky_fprintf(&s,"\n\t> %WPl%WIC",ptr,ptr);Queue_Push(ptr->program->errors,hold);+ wonky_string_stream_delete(&s);}void push_translation_error(const char *fmt,struct Translation_Data *translation_data,...){F diff --git a/src/frontend/lex/lex_preprocessing_directive.c b/src/frontend/lex/lex_preprocessing_directive.c --- a/src/frontend/lex/lex_preprocessing_directive.c +++ b/src/frontend/lex/lex_preprocessing_directive.c}return (struct token*)ret;}- struct token* preprocessing_lex_hastag_unary_operator(struct Lexer_Data *lexer_data,struct Source_Location *where,struct functionlike_define_directive *directive)+ struct token* preprocessing_lex_hastag_unary_operator(struct Lexer_Data *lexer_data,struct Source_Location *where){struct token_hashtag_unary_operator *ret;struct token *hold_token;ret->type=PKW_HASHTAG_UNARY_OP;ret->location=where;+ wonky_assert(lexer_data);+ wonky_assert(preprocessing_get_current_functionlike_define_directive(lexer_data));+if(!preprocessing_eol(lexer_data))- hold_token=preprocessing_get_token_for_functionlike_macro_substitution_list(lexer_data,where,directive);+ hold_token=preprocessing_get_token_for_functionlike_macro_substitution_list(lexer_data,where);if(hold_token==NULL || hold_token->type!=PKW_MACRO_ARGUMENT){push_generic_error(lexer_data->program,"Expected macro argument after #");return (struct token*)ret;}- struct token* preprocessing_lex_hastag_hashtag_operator_in_functionlike_macro(struct Lexer_Data *lexer_data,struct Source_Location *where,struct functionlike_define_directive *directive,struct token *previous_token)+ struct token* preprocessing_lex_hastag_hashtag_operator_in_functionlike_macro(struct Lexer_Data *lexer_data,struct Source_Location *where,struct token *previous_token){struct token *hold_token;struct Queue *ret_q;/*the first '##' has been eaten by the caller*/do{/*first pass is not eol*/- hold_token=preprocessing_get_token_for_functionlike_macro_substitution_list(lexer_data,where,directive);+ hold_token=preprocessing_get_token_for_functionlike_macro_substitution_list(lexer_data,where);Queue_Push(ret_q,hold_token);}while(preprocessing_get_and_check_token(lexer_data,KW_HASHTAG_HASHTAG) && !preprocessing_eol(lexer_data));if(!preprocessing_eol(lexer_data))return ret;}else{+ #warning make __VA_ARGS__ be not usable in normal #define directivesret=preprocessing_lex_normal_define_directive(lexer_data,where,hold_id,hold_hold_token);delete_token((struct token*)hold_token);delete_token(hold_hold_token);struct token_functionlike_define_directive *ret;ret=(struct token_functionlike_define_directive*)get_functionlike_define_directive_token(where,id);++ lex_set_currently_parsed_functionlike_define(lexer_data,ret);- preprocessing_parse_functionlike_macro_id_list(lexer_data,ret);+ preprocessing_parse_functionlike_macro_id_list(lexer_data);lexer_data->automata_view=AUTOMATA_VIEW_PREPROCESSING_DIRECTIVE;- preprocessing_push_functionlike_macro_substitution_tokens(lexer_data,where,ret->define);+ preprocessing_push_functionlike_macro_substitution_tokens(lexer_data,where);lexer_data->automata_view=AUTOMATA_VIEW_NORMAL;++ lex_unset_currently_parsed_functionlike_define(lexer_data);return (struct token*)ret;}Queue_Push(queue,preprocessing_extract_next_token(lexer_data));}/*You must not call this when eol*/- struct token* preprocessing_get_token_for_functionlike_macro_substitution_list(struct Lexer_Data *lexer_data,struct Source_Location *where,struct functionlike_define_directive *directive)+ struct token* preprocessing_get_token_for_functionlike_macro_substitution_list(struct Lexer_Data *lexer_data,struct Source_Location *where){struct token *hold_token;+ struct token_functionlike_define_directive *directive=preprocessing_get_current_functionlike_define_directive(lexer_data);/*returns NULL on eol*/hold_token=preprocessing_extract_next_token(lexer_data);if(hold_token->type==KW_ID && ((struct token_identifier*)hold_token)->id->hold_functionlike_define_directive==directive){- return get_functionlike_define_directive_argument_token(- where,- ((struct token_identifier*)hold_token)->id->hold_functionlike_define_directive_argument);+ return get_functionlike_define_directive_argument_token(+ where,+ ((struct token_identifier*)hold_token)->id->hold_functionlike_define_directive_argument);}else if(token_is_keyword(hold_token) && ((struct token_keyword*)hold_token)->id->hold_functionlike_define_directive==directive){- return get_functionlike_define_directive_argument_token(- where,- ((struct token_keyword*)hold_token)->id->hold_functionlike_define_directive_argument);+ return get_functionlike_define_directive_argument_token(+ where,+ ((struct token_keyword*)hold_token)->id->hold_functionlike_define_directive_argument);}else if(hold_token->type==KW_HASHTAG){- return preprocessing_lex_hastag_unary_operator(lexer_data,where,directive);+ return preprocessing_lex_hastag_unary_operator(lexer_data,where);+ }else if(hold_token->type==PKW_VA_ARGS)+ {+ if(directive->define->variadic_argument!=NULL)+ return get_functionlike_define_directive_argument_token(+ where,+ directive->define->variadic_argument+ );+ else+ push_generic_error(lexer_data->program,"Encountered a __VA_ARGS__ in a functionlike macro that is not variadic");}else{return hold_token;}- void preprocessing_push_functionlike_macro_substitution_tokens(struct Lexer_Data *lexer_data,struct Source_Location *where,struct functionlike_define_directive *directive)+ void preprocessing_push_functionlike_macro_substitution_tokens(struct Lexer_Data *lexer_data,struct Source_Location *where){struct token *hold_token;+ wonky_assert(lexer_data);+ struct token_functionlike_define_directive *directive=preprocessing_get_current_functionlike_define_directive(lexer_data);+ wonky_assert(directive);while(!preprocessing_eol(lexer_data)){- hold_token=preprocessing_get_token_for_functionlike_macro_substitution_list(lexer_data,where,directive);+ hold_token=preprocessing_get_token_for_functionlike_macro_substitution_list(lexer_data,where);if(preprocessing_get_and_check_token(lexer_data,KW_HASHTAG_HASHTAG)){if(preprocessing_eol(lexer_data))return;}else{- hold_token=preprocessing_lex_hastag_hashtag_operator_in_functionlike_macro(lexer_data,where,directive,hold_token);+ hold_token=preprocessing_lex_hastag_hashtag_operator_in_functionlike_macro(lexer_data,where,hold_token);}}- Queue_Push(directive->replacement_tokens,hold_token);+ Queue_Push(directive->define->replacement_tokens,hold_token);}}- void preprocessing_parse_functionlike_macro_id_list(struct Lexer_Data *lexer_data,struct token_functionlike_define_directive *directive)+ void preprocessing_parse_functionlike_macro_id_list(struct Lexer_Data *lexer_data){struct token *hold_token;+ wonky_assert(lexer_data);+ struct token_functionlike_define_directive *directive=preprocessing_get_current_functionlike_define_directive(lexer_data);+ wonky_assert(directive);+while(!preprocessing_eol(lexer_data)){hold_token=preprocessing_extract_next_token(lexer_data);if(hold_token->type==KW_ELIPSIS){- directive->define->is_variadic=1;+ directive->define->variadic_argument=get_functionlike_define_directive_argument(directive);delete_token(hold_token);- hold_token=preprocessing_extract_next_token(lexer_data);- if(hold_token->type==KW_CLOSE_NORMAL)+ if(preprocessing_get_and_check_token(lexer_data,KW_CLOSE_NORMAL)){- delete_token(hold_token);break;}else{Queue_Push(directive->define->arguments,hold_argument);- ((struct token_identifier*)hold_token)->id->hold_functionlike_define_directive=directive->define;+ ((struct token_identifier*)hold_token)->id->hold_functionlike_define_directive=directive;((struct token_identifier*)hold_token)->id->hold_functionlike_define_directive_argument=hold_argument;delete_token(hold_token);++ if(preprocessing_get_and_check_token(lexer_data,KW_ELIPSIS))+ {+ directive->define->variadic_argument=hold_argument;+ if(preprocessing_get_and_check_token(lexer_data,KW_CLOSE_NORMAL))+ {+ break;+ }else+ {+ push_generic_error_located(lexer_data->program,"Expected ')' after '...' in functionlike macro",hold_token->location);+ break;+ }+ }}else if(token_is_keyword(hold_token)){#warning make it check for duplicate ids hereendif.location=where;return (struct token*)&endif;}+ _Bool preprocessing_is_in_functionlike_define_directive(struct Lexer_Data *lexer_data)+ {+ return lexer_data->currently_parsed_functionlike_define!=NULL;+ }+ struct token_functionlike_define_directive* preprocessing_get_current_functionlike_define_directive(struct Lexer_Data *lexer_data)+ {+ return lexer_data->currently_parsed_functionlike_define;+ }#endifF diff --git a/src/frontend/lex/lex_preprocessing_directive.h b/src/frontend/lex/lex_preprocessing_directive.h --- a/src/frontend/lex/lex_preprocessing_directive.h +++ b/src/frontend/lex/lex_preprocessing_directive.hstruct token* preprocessing_lex_pragma_directive(struct Lexer_Data *lexer_data,struct Source_Location *where);struct token* preprocessing_lex_defined_unary_operator(struct Lexer_Data *lexer_data,struct Source_Location *where);- struct token* preprocessing_lex_hastag_unary_operator(struct Lexer_Data *lexer_data,struct Source_Location *where,struct functionlike_define_directive *directive);- struct token* preprocessing_lex_hastag_hashtag_operator_in_functionlike_macro(struct Lexer_Data *lexer_data,struct Source_Location *where,struct functionlike_define_directive *directive,struct token *previous_token);+ struct token* preprocessing_lex_hastag_unary_operator(struct Lexer_Data *lexer_data,struct Source_Location *where);+ struct token* preprocessing_lex_hastag_hashtag_operator_in_functionlike_macro(struct Lexer_Data *lexer_data,struct Source_Location *where,struct token *previous_token);struct token* preprocessing_return_else_token(struct Lexer_Data *lexer_data,struct Source_Location *where);struct token* preprocessing_return_endif_token(struct Lexer_Data *lexer_data,struct Source_Location *where);void preprocessing_push_tokens_into_queue_until_eol(struct Lexer_Data *lexer_data,struct Queue *queue);- struct token* preprocessing_get_token_for_functionlike_macro_substitution_list(struct Lexer_Data *lexer_data,struct Source_Location *where,struct functionlike_define_directive *directive);- void preprocessing_push_functionlike_macro_substitution_tokens(struct Lexer_Data *lexer_data,struct Source_Location *where,struct functionlike_define_directive *directive);+ struct token* preprocessing_get_token_for_functionlike_macro_substitution_list(struct Lexer_Data *lexer_data,struct Source_Location *where);+ void preprocessing_push_functionlike_macro_substitution_tokens(struct Lexer_Data *lexer_data,struct Source_Location *where);void preprocessing_goto_end_of_line(struct Lexer_Data *lexer_data);struct token* preprocessing_extract_next_token(struct Lexer_Data *lexer_data);_Bool preprocessing_eol(struct Lexer_Data *lexer_data);struct token *preprocessing_make_token_finishing_on_node(struct Lexer_Data *lexer_data,struct Automata_Node *finishing_node,size_t start_position,_Bool create_directive,_Bool create_defined_statement);- void preprocessing_parse_functionlike_macro_id_list(struct Lexer_Data *lexer_data,struct token_functionlike_define_directive *directive);+ void preprocessing_parse_functionlike_macro_id_list(struct Lexer_Data *lexer_data);- _Bool preprocessing_has_hit_hashtag(struct Lexer_Data *lexer_data);+ _Bool preprocessing_is_in_functionlike_define_directive(struct Lexer_Data *lexer_data);+ struct token_functionlike_define_directive* preprocessing_get_current_functionlike_define_directive(struct Lexer_Data *lexer_data);#endifF diff --git a/src/frontend/lex/lexer.c b/src/frontend/lex/lexer.c --- a/src/frontend/lex/lexer.c +++ b/src/frontend/lex/lexer.cret->src=src;ret->program=program;ret->buffer_token=NULL;+ ret->currently_parsed_functionlike_define=NULL;return ret;}+ void lex_set_currently_parsed_functionlike_define(struct Lexer_Data *lexer_data,struct token_functionlike_define_directive *define)+ {+ wonky_assert(lexer_data);+ wonky_assert(define);+ lexer_data->currently_parsed_functionlike_define=define;+ }+ void lex_unset_currently_parsed_functionlike_define(struct Lexer_Data *lexer_data)+ {+ wonky_assert(lexer_data);+ lexer_data->currently_parsed_functionlike_define=NULL;+ }struct token* lex_token_from_string(char *str,size_t string_length){finishing_node->data=id;}return get_id_token(finishing_node->data,token_location);- break;+ case PKW_VA_ARGS:+ if(lexer_data->automata_view==AUTOMATA_VIEW_PREPROCESSING_DIRECTIVE && preprocessing_is_in_functionlike_define_directive(lexer_data))+ return get_va_args_token(token_location,preprocessing_get_current_functionlike_define_directive(lexer_data));+ else+ return get_error_token("__VA_ARGS__ can only be used in a function-like #define directive",token_location,lexer_data->program);+ wonky_assert(SHOULD_NOT_REACH_HERE);case PKW_DEFINED:if(lexer_data->automata_view==AUTOMATA_VIEW_PREPROCESSING_DIRECTIVE){F diff --git a/src/frontend/lex/lexer.h b/src/frontend/lex/lexer.h --- a/src/frontend/lex/lexer.h +++ b/src/frontend/lex/lexer.hstruct Lexer_Data{-size_t where_in_src;size_t which_column;size_t which_row;struct Program *program;struct token *buffer_token;+ struct token_functionlike_define_directive *currently_parsed_functionlike_define;};struct Preprocessing_Translation_Unit* lex_inner(struct Lexer_Data *lexer_data);struct Lexer_Data* get_lexer_data(struct Source_File *src,struct Program *program);+ void lex_set_currently_parsed_functionlike_define(struct Lexer_Data *lexer_data,struct token_functionlike_define_directive *define);+ void lex_unset_currently_parsed_functionlike_define(struct Lexer_Data *lexer_data);+struct token* lex_token_from_string(char *str,size_t string_length);void lexer_skip_white_space(struct Lexer_Data *lexer_data);F diff --git a/src/frontend/parse/parse_declaration.c b/src/frontend/parse/parse_declaration.c --- a/src/frontend/parse/parse_declaration.c +++ b/src/frontend/parse/parse_declaration.c{/*TODO error*/Queue_Push(where_to_push_objects,get_declaration_error_tree(hold));- push_translation_error("declaration expected",translation_data,translation_data->token_pointer);+ push_translation_error("Declaration expected",translation_data);/*search for end of erronous declaration*/break;F diff --git a/src/misc/print.c b/src/misc/print.c --- a/src/misc/print.c +++ b/src/misc/print.ccase LT_ERROR:wonky_fprintf(out,"LT_ERROR");break;+ case PKW_VA_ARGS:+ wonky_fprintf(out,"PKW_VA_ARGS");+ break;default:wonky_fprintf(out,"KW_ERROR");}F diff --git a/src/misc/wonky_stream.c b/src/misc/wonky_stream.c --- a/src/misc/wonky_stream.c +++ b/src/misc/wonky_stream.c{struct functionlike_define_directive *arg=va_arg(args,struct functionlike_define_directive*);wonky_assert(arg);- wonky_fprintf(s,"\n\"%WI\" : {\n\tis_variadic=%d",arg->id,(int)arg->is_variadic);+ wonky_fprintf(s,"\n\"%WI\" : {\n\tis_variadic=%d",arg->id,(int)is_functionlike_define_directive_variadic(arg));for(struct Queue_Node *it=arg->arguments->first;it;it=it->prev)wonky_fprintf(s,"\n\t%WMA",it->data);wonky_fprintf(s,"\n}\n");F diff --git a/src/semantics/program/translation_unit.c b/src/semantics/program/translation_unit.c --- a/src/semantics/program/translation_unit.c +++ b/src/semantics/program/translation_unit.cstruct Queue_Node *hold_leading_token_node;struct functionlike_define_directive_argument *hold_arg;+ _Bool loading_variadic_argument=0;+hold_token=token_ptr_get_token_under_pointer(ptr);if(open_bracket_count)++number_of_tokens_in_argument;}- else if(hold_token->type==KW_COMMA && open_bracket_count==1) /*if we are at the top level ()*/+ else if(hold_token->type==KW_COMMA && open_bracket_count==1 && !loading_variadic_argument) /*if we are at the top level ()*/{- if(hold_argument_node==NULL)+ if(hold_argument_node==NULL && !loading_variadic_argument){push_token_pointer_error(ptr,"Too many arguments given to functionlike macro");return;push_token_pointer_error(ptr,"No tokens in functionlike macro");return;}- hold_arg=(struct functionlike_define_directive_argument*)hold_argument_node->data;- hold_arg->first_in_argument_substitution_tokens=hold_leading_token_node;- hold_arg->number_of_substitution_tokens=number_of_tokens_in_argument;-- number_of_tokens_in_argument=0;- hold_argument_node=hold_argument_node->prev;- hold_leading_token_node=token_ptr_get_current_queue_node(ptr);+ if(!loading_variadic_argument)+ {+ hold_arg=(struct functionlike_define_directive_argument*)hold_argument_node->data;+ hold_arg->first_in_argument_substitution_tokens=hold_leading_token_node;+ hold_arg->number_of_substitution_tokens=number_of_tokens_in_argument;++ number_of_tokens_in_argument=0;+ hold_argument_node=hold_argument_node->prev;+ hold_leading_token_node=token_ptr_get_current_queue_node(ptr);+ if(hold_argument_node==NULL && macro->variadic_argument!=NULL)+ {+ //number_of_tokens_in_argument=1;/*counting the ',' that we read on the way here*/+ loading_variadic_argument=1;+ }+ }}else{++number_of_tokens_in_argument;}}- if(hold_argument_node==NULL || hold_argument_node->prev!=NULL)+ if((hold_argument_node==NULL && !loading_variadic_argument) && number_of_tokens_in_argument!=0)+ {+ push_token_pointer_error(ptr,"Too many arguments given to functionlike macro");+ return;+ }+ if(hold_argument_node!=NULL && number_of_tokens_in_argument==0){push_token_pointer_error(ptr,"Too few arguments given to functionlike macro");return;}- hold_arg=(struct functionlike_define_directive_argument*)hold_argument_node->data;++ if(hold_argument_node!=NULL)+ {+ wonky_assert(macro->variadic_argument==NULL);+ hold_arg=(struct functionlike_define_directive_argument*)hold_argument_node->data;+ }else+ {+ wonky_assert(macro->variadic_argument!=NULL);+ hold_arg=macro->variadic_argument;+ }+hold_arg->first_in_argument_substitution_tokens=hold_leading_token_node;hold_arg->number_of_substitution_tokens=number_of_tokens_in_argument;case LT_ERROR:/*erronous token*/token_ptr_assume_location_of_token(token_pointer,token);- push_message_struct(token_pointer->program,((struct token_error*)token)->error);+ push_token_pointer_error(token_pointer,((struct token_error*)token)->error->cs);token_ptr_goto_next_token(token_pointer);return 1;+ case PKW_VA_ARGS:+ {+ token_ptr_assume_location_of_token(token_pointer,token);+ wonky_assert(token_pointer->context->executed_macro_id!=NULL);+ return 0;+ }case KW_ID:{struct token_identifier *hold_id_token;F diff --git a/src/syntax/automatas/automata.hh b/src/syntax/automatas/automata.hh --- a/src/syntax/automatas/automata.hh +++ b/src/syntax/automatas/automata.hhPKW_STDC_HOSTED_MACRO,PKW_STDC_VERSION_MACRO,PKW_TIME_MACRO,+ PKW_VA_ARGS,PKW_ANGULAR_BRACKET_INCLUDE_NAME,PKW_CONSTANT,PKW_ID,F diff --git a/src/syntax/automatas/generator/keyword_list.c b/src/syntax/automatas/generator/keyword_list.c --- a/src/syntax/automatas/generator/keyword_list.c +++ b/src/syntax/automatas/generator/keyword_list.c.action_string="AUTOMATA_ACTION_DISPENSE_TOKEN",.data_string="NULL"},+ {+ .keyword="__VA_ARGS__",+ .preprocessing_kw_string="PKW_VA_ARGS",+ .kw_string="PKW_VA_ARGS",+ .action_string="AUTOMATA_ACTION_DISPENSE_TOKEN",+ .data_string="NULL"+ },};F diff --git a/src/syntax/macro.c b/src/syntax/macro.c --- a/src/syntax/macro.c +++ b/src/syntax/macro.cQueue_Init(ret->arguments);ret->replacement_tokens=wonky_malloc(sizeof(struct Queue));Queue_Init(ret->replacement_tokens);- ret->is_variadic=0;+ ret->variadic_argument=NULL;return ret;}struct functionlike_define_directive_argument* get_functionlike_define_directive_argument(struct token_functionlike_define_directive *belongs_to)return ret;}+ _Bool is_functionlike_define_directive_variadic(struct functionlike_define_directive *directive)+ {+ wonky_assert(directive != NULL);+ return directive->variadic_argument != NULL;+ }#warning there is no check for duplicate ids in function like macro id list#warning functionlike macro '(' after the name of the macro should be glued to id, because otherwise we cant differentiate between '(' in the macro and the begining of the argument list. Currently this is not parsed correctly!#endifF diff --git a/src/syntax/macro.h b/src/syntax/macro.h --- a/src/syntax/macro.h +++ b/src/syntax/macro.hstruct identifier *id;struct Queue *arguments;struct Queue *replacement_tokens;- _Bool is_variadic;+ struct functionlike_define_directive_argument *variadic_argument;};struct functionlike_define_directive_argument{struct normal_define_directive* get_normal_define_directive(struct identifier *id);struct functionlike_define_directive* get_functionlike_define_directive(struct identifier *id);struct functionlike_define_directive_argument* get_functionlike_define_directive_argument(struct token_functionlike_define_directive *belongs_to);+ _Bool is_functionlike_define_directive_variadic(struct functionlike_define_directive *directive);F diff --git a/src/syntax/token/token.c b/src/syntax/token/token.c --- a/src/syntax/token/token.c +++ b/src/syntax/token/token.c{struct token_error *ret;va_list args;- struct wonky_str hold_err;+ struct wonky_str *hold_err;- hold_err=wonky_string_make();+ hold_err=wonky_malloc(sizeof(struct wonky_str));+ *hold_err=wonky_string_make();va_start(args,program);wonky_string_vprintf(&hold_err,msg,args);ret=wonky_malloc(sizeof(struct token_error));ret->type=LT_ERROR;ret->location=current_location;- ret->error=get_wonky_message(WONKY_MESSAGE_TYPE_ERROR,WONKY_MESSAGE_SOURCE_PREPROCESSING,current_location->line,current_location->column,current_location->src->src_name->name,current_location->src->src_name->name_size,"%s",hold_err.cs);+ ret->error=hold_err;return (struct token*)ret;}return (struct token*)get_string_token(KW_STRING,current_location,"Time could not be determined",sizeof("Time could not be determined"));}+ struct token* get_va_args_token(struct Source_Location *current_location,struct token_functionlike_define_directive *define)+ {+ struct token_va_args *ret;+ ret=wonky_malloc(sizeof(struct token_va_args));+ ret->type=PKW_VA_ARGS;+ ret->location=current_location;+ ret->directive=define;++ return (struct token*)ret;+ }char* get_string_from_token(struct token* token,size_t *size){char *ret;F diff --git a/src/syntax/token/token.h b/src/syntax/token/token.h --- a/src/syntax/token/token.h +++ b/src/syntax/token/token.h#include <constant.h>#include <wonky_malloc.h>#include <wonky_assert.h>+ #include <wonky_string.h>#include <source_file.h>#include <macro.h>struct Source_Location *location;struct functionlike_define_directive_argument *argument;};+ struct token_va_args+ {+ enum LEXER_TYPE type;+ struct Source_Location *location;+ struct token_functionlike_define_directive *directive;+ };struct token_undef_directive{enum LEXER_TYPE type;{enum LEXER_TYPE type;struct Source_Location *location;- struct Wonky_Message *error;+ struct wonky_str *error;};/*struct token* get_stdc_hosted_macro_token(struct Source_Location *current_location);struct token* get_stdc_version_macro_token(struct Source_Location *current_location);struct token* get_time_macro_token(struct Source_Location *current_location);+ struct token* get_va_args_token(struct Source_Location *current_location,struct token_functionlike_define_directive *define);char* get_string_from_token(struct token* token,size_t *size);_Bool token_is_keyword(struct token *token);