F diff --git a/ast.c b/ast.c --- a/ast.c +++ b/ast.cret->error=error;return ret;}+ struct AST_Declaration_Error* get_declaration_error_tree(struct Denoted *error)+ {++ struct AST_Error *ret;+ ret=malloc(sizeof(struct AST_Error));+ ret->type=ERROR_DECLARATION;+ ret->error=error;+ return ret;+ }+struct AST_Binary_Expression* get_binary_expression_tree(struct AST *left,struct AST *right,enum AST_Type type){struct AST_Binary_Expression *ret;- struct AST_Declaration* get_declaration_tree(struct Scope* scope)+ struct AST_Type_Definition* get_type_definition_tree(struct Denoted_Typedef *definition,struct Scope *scope);{- struct AST_Declaration *ret;- ret=malloc(sizeof(struct AST_Declaration));- ret->type=ST_DECLARATION;- ret->base_type=malloc(sizeof(struct Type_Node));- Queue_Init(&ret->declarators);+ struct AST_Type_Definition *ret;+ ret=malloc(sizeof(struct AST_Type_Definition));+ ret->type=ST_TYPE_DEFINITION;+ ret->definition=definition;ret->scope=scope;return ret;+}- struct AST_Function_Definition* get_function_definition_tree(struct Scope *scope)+ struct AST_Object_Declaration* get_object_declaration_tree(struct Denoted_Object *object,struct AST *initializer,struct Scope *scope)+ {+ struct AST_Object_Declaration *ret;+ ret=malloc(sizeof(struct AST_Object_Declaration));+ ret->type=ST_OBJECT_DECLARATION;+ ret->object=object;+ ret->scope=scope;++ return ret;+ }++ struct AST_Function_Definition* get_function_definition_tree(struct Scope *scope,struct Denoted_Function *function){struct AST_Function_Definition *ret;ret=malloc(sizeof(struct AST_Function_Definition));ret->type=ST_FUNCTION_DEFINITION;+ ret->function=function;+ ret->scope=scope;return ret;}+ struct AST_Function_Declaration* get_function_declaration_tree(struct Scope *scope,struct Denoted_Function *function)+ {+ struct AST_Function_Definition *ret;+ ret=malloc(sizeof(struct AST_Function_Definition));+ ret->type=ST_FUNCTION_DECLARATION;+ ret->function=function;+ ret->scope=scope;+ return ret;+ }struct AST_Translation_Unit* get_translation_unit_tree(struct Scope* parent_scope){struct AST_Translation_Unit *ret;F diff --git a/ast.h b/ast.h --- a/ast.h +++ b/ast.h#define GCC_AST_H GCC_AST_H#include "scope.h"#include "parse_declaration.h"+ #include "denoted.h"+++ struct Denoted;enum AST_Type{OP_COMMA,OP_LVALUE,OP_RVALUE,ST_COMPOUND,ST_EXPRESSION,ST_SWITCH,ST_IF,ST_WHILE,ST_DO_WHILE,ST_GOTO,ST_LABEL,ST_CASE,ST_DEFAULT,ST_CONTINUE,ST_BREAK,ST_RETURN,ST_FOR- ,ST_DECLARATION,ST_FUNCTION_DEFINITION+ ,ST_OBJECT_DECLARATION,ST_TYPE_DEFINITION,ST_FUNCTION_DEFINITION+ ,ST_FUNCTION_DECLARATION,TRANSLATION_UNIT- ,ERROR+ ,ERROR,ERROR_DECLARATION};enum AST_Type type;struct AST *error;};+ struct AST_Declaration_Error+ {+ enum AST_Type type;+ struct Denotation *error;+ };struct AST_Binary_Expression{enum AST_Type type;struct AST* return_expression;};- struct AST_Declaration+++ struct AST_Type_Definition+ {+ enum AST_Type type;+ struct Denoted_Typedef *definition;+ struct Scope *scope;+ };+ struct AST_Object_Declaration{enum AST_Type type;- struct Type_Node* base_type;- struct Queue declarators;+ struct Denoted_Object *object;+ struct AST *initializer;struct Scope *scope;};struct AST_Function_Definition{enum AST_Type type;- struct Type_Node *base_type;- struct Declarator *declarator;- struct AST *body_statement;+ struct Denoted_Function *function;+ struct Scope *scope;+ };+ struct AST_Function_Declaration+ {+ enum AST_Type type;+ struct Denoted_Function *function;struct Scope *scope;};struct AST_Translation_Unitstruct AST_Error* get_error_tree(struct AST *error);+ struct AST_Declaration_Error* get_declaration_error_tree(struct Denoted *error);struct AST_Binary_Expression* get_binary_expression_tree(struct AST *left,struct AST *right,enum AST_Type type);struct AST_Conditional_Expression* get_conditional_expression_tree(struct AST *left,struct AST *center,struct AST *right);struct AST_Function_Expression* get_function_expression_tree(struct AST* id,struct Scope *scope);struct AST_Return_Statement* get_return_statement_tree(struct AST* return_expression);struct AST_Goto_Statement* get_goto_statement_tree(struct token *label,struct Scope *scope);struct AST* get_nop_tree();- struct AST_Declaration* get_declaration_tree(struct Scope* scope);- struct AST_Function_Definition* get_function_definition_tree(struct Scope *scope);+ struct AST_Type_Definition* get_type_definition_tree(struct Denoted_Typedef *definition,struct Scope *scope);+ struct AST_Object_Declaration* get_object_declaration_tree(struct Denoted_Object *object,struct AST *initializer,struct Scope *scope);+ struct AST_Function_Declaration* get_function_declaration_tree(struct Scope *scope,struct Denoted_Function *function);+ struct AST_Function_Definition* get_function_definition_tree(struct Scope *scope,struct Denoted_Function *function);struct AST_Translation_Unit* get_translation_unit_tree(struct Scope* parent_scope);F diff --git a/denoted.c b/denoted.c --- a/denoted.c +++ b/denoted.c#ifndef GCC_DENOTED_C#define GCC_DENOTED_C GCC_DENOTED_C+ #include "denoted.h"- struct Denoted_Error* get_denoted_error(struct Denoted *error)+ struct Denoted* get_denoted_error(struct Denoted *error){struct Denoted_Error *ret;ret=malloc(sizeof(struct Denoted_Error));return (struct Denoted*)ret;}- struct Denoted_Function* get_denoted_function(struct Type *type)+ struct Denoted* get_denoted_function(struct Denotation_Prototype *prototype){struct Denoted_Function *ret;ret=malloc(sizeof(struct Denoted_Function));ret->denotation=DT_Function;- ret->type=type;+ ret->type=prototype->type;+ ret->function_specifier=prototype->function_specifier;ret->body=NULL;return (struct Denoted*)ret;}- struct Denoted_Object* get_denoted_object(struct Type *type)+ struct Denoted* get_denoted_object(struct token *id, struct Object *object){struct Denoted_Object *ret;ret=malloc(sizeof(struct Denoted_Object));ret->denotation=DT_Object;- ret->type=type;- ret->location=NULL;+ ret->id=id;+ ret->object=object;return (struct Denoted*)ret;}- struct Denoted_Typedef* get_denoted_typedef(struct token* id,struct Type *typedefed)+ struct Denoted* get_denoted_typedef(struct Denotation_Prototype *prototype){struct Denoted_Typedef *ret;ret=malloc(sizeof(struct Denoted_Typedef));ret->denotation=DT_Typedef;- ret->type=typedefed;- ret->id=id;+ ret->type=prototype->type;+ ret->id=prototype->id;return (struct Denoted*)ret;}- struct Denoted_Enum_Const* get_denoted_enum_const(struct token *id,struct Type_Enum *parent,int value)+ struct Denoted* get_denoted_enum_const(struct token *id,struct Type_Enum *parent,int value){struct Denoted_Enum_Const *ret;ret=malloc(sizeof(struct Denoted_Enum_Const));return (struct Denoted*)ret;}- struct Denoted_Struct_Union_Member* get_denoted_struct_union_member(struct token *id,struct Type *type,size_t offset)+ struct Denoted* get_denoted_enum(struct token *id,struct Enum *enumerator){- struct Denoted_Struct_Union_Member *ret;- ret=malloc(sizeof(struct Denoted_Struct_Union_Member));- ret->denotation=DT_Struct_Union_Member;+ struct Denoted_Enum *ret;+ ret=malloc(sizeof(struct Denoted_Enum));+ ret->denotation=DT_Enum;ret->id=id;- ret->type=type;- ret->offset=offset;+ ret->enumeration=enumerator;return (struct Denoted*)ret;}return (struct Denoted*)ret;}+ struct Denoted* get_denotation_prototype()+ {+ struct Denotation_Prototype *ret;+ ret=malloc(sizeof(struct Denotation_Prototype));+ ret->denotation=DT_Prototype;+ ret->specifier=TS_NONE;+ ret->storage_class=SC_NONE;+ ret->constraint=TC_NONE;+ ret->sign=TSIGN_NONE;+ ret->function_specifier=FS_None;+ ret->size=0;+ ret->is_const=ret->is_volatile=0;++ return (struct Denoted*)ret;+ }#endifF diff --git a/denoted.h b/denoted.h --- a/denoted.h +++ b/denoted.hDT_Object,DT_Typedef,DT_Function,+ DT_Enum,DT_Enum_Constant,DT_Struct_Union_Member,DT_Struct_Union_Tag,- DT_Error+ DT_Error,+ DT_Prototype};enum Function_Specifier{- TFS_Inline,- TFS_None+ FS_Inline,+ FS_None};enum Storage_Class{- TSC_EXTERN,- TSC_STATIC,- TSC_NONE+ SC_EXTERN,+ SC_STATIC,+ SC_TYPEDEF,+ SC_NONE};struct Denoted{enum Function_Specifier function_specifier;struct Type *type;+ struct token *id;struct AST_Compound_Statement *body;};struct Denoted_Objectstruct token *id;struct Type *type;};- struct Denoted_Enum_Const+ struct Denoted_Enum{enum Denotation_Type denotation;struct token *id;- struct Type_Enum *parent;- int value;+ struct Enum *enumeration;};-- struct Denoted_Struct_Union_Member+ struct Denoted_Enum_Const{enum Denotation_Type denotation;- struct Type *type;- size_t offset;struct token *id;+ struct Type_Enum *parent;+ int value;};+struct Denoted_Struct_Union{enum Denotation_Type denotation;struct Denotation_Prototype{+ enum Denotation_Type denotation;enum Storage_Class storage_class;+ enum Type_Specifier specifier;enum Type_Constraint constraint;enum Type_Signedness sign;+ enum Function_Specifier function_specifier;++ struct Type *type;++ struct token *id;++ struct Struct_Union *struct_union;+ struct Enum *enumerator;+size_t size;char is_const:1;char is_volatile:1;};struct Denoted* get_denoted_error(struct Denoted *error);- struct Denoted* get_denoted_function(struct Type *type);- struct Denoted* get_denoted_object(struct Type *type);+ struct Denoted* get_denoted_function(struct Denotation_Prototype *prototype);+ struct Denoted* get_denoted_object(struct token *id, struct Object *object);struct Denoted* get_denoted_typedef(struct token* id,struct Type *typedefed);struct Denoted* get_denoted_enum_const(struct token *id,struct Type_Enum *parent,int value);- struct Denoted* get_denoted_struct_union_member(struct token *id,struct Type *type,size_t offset);+ struct Denoted* get_denoted_enum(struct token *id,struct Enum *enumerator);struct Denoted* get_denoted_struct_union(struct token *id,struct Struct_Union *struct_union);- struct Object_Prototype* get_denotation_prototype();+ struct Denoted* get_denotation_prototype();#endifF diff --git a/parse_declaration.c b/parse_declaration.c --- a/parse_declaration.c +++ b/parse_declaration.c#define GCC_PARSE_DECLARATION_C GCC_PARSE_DECLARATION_C#include"parse_declaration.h"+ /*declaration-specifiers init-declarator (,init-declarator)* ;*/+ /* init-declarator: declarator [ = initializer ] */+ void parse_declaration(struct Queue *tokens,struct Scope *scope,struct Queue *where_to_push,char parse_function_definitions)+ {+ struct Type *hold_type;+ struct Denotation_Prototype *prototype;+ struct Denoted *hold;+ prototype=(struct Denotation_Prototype*)parse_declaration_specifiers(tokens,scope);+ if(((struct Denoted*)prototype)->denotation==DT_Error)+ {+ /*TODO error*/+ Queue_Push(where_to_push,get_error_tree(get_declaration_error_tree(prototype)));+ return ;+ }+ if(prototype->specifiers==TS_ENUM)+ {+ prototype->type=get_enum_type(prototype);+ }else if(prototype->specifiers==TS_STRUCT || prototype->specifiers==TS_UNION)+ {+ prototype->type=get_struct_union_type(prototype);+ }else+ {+ prototype->type=get_basic_type(prototype);+ }+- /*- declaration-specifiers:- storage-class-specifier [ declaration-specifiers ]- type-specifier [ declaration-specifiers ]- type-qualifier [ declaration-specifiers ]- function-spedifier [ declaration-specifiers ]- alignment-specifier [ declaration-specifiers ]-- */- struct Denoted* parse_declaration_specifiers(struct Queue *tokens,struct Scope *scope)+ do{+ hold=parse_declarator(tokens,scope,prototype);+ if(hold->denotation!=DT_Error)+ {+ if(hold->denotation==DT_Typedef)+ {+ Queue_Push(where_to_push,(struct AST*)get_type_definition_tree((struct Denoted_Typedef*)hold,scope));+ }else if(hold->denotation==DT_Object)+ {+ Queue_Push(where_to_push,(struct AST*),get_object_declaration_tree((struct Denoted_Object*)hold,parse_initializer(tokens,scope,(struct Denoted_Object*)hold),scope));+ }else if(hold->denotation==DT_Function)+ {+ if(parse_function_definitions==1 && get_and_check(tokens,KW_OPEN_CURLY))+ {+ ((struct Denoted_Function*)hold)->body=parse_finish_compound_statement(tokens,scope);++ Queue_Push(where_to_push,(struct AST*)get_function_definition_tree(scope,(struct Denoted_Function*)hold));+ return ;+ }+ Queue_Push(where_to_push,(struct AST*)get_function_declaration(scope,(struct Denoted_Function*)hold));+ }else+ {+ /*todo error*/+ /*shouldnt be able to reach here*/+ Queue_Push(where_to_push,(struct AST*)get_error_tree((struct AST*)get_declaration_error_tree(hold)));+ return ;+ }++ Scope_Push(scope,hold);+ }else+ {+ /*todo error*/+ Queue_Push(where_to_push,get_error_tree(get_denoted_error(hold)));+ return ;+ }++ parse_function_definitions=0;++ }while(get_and_check(tokens,KW_COMMA));+ if(!get_and_check(tokens,KW_SEMI_COLUMN))+ {+ /*TODO error*/+ Queue_Push(where_to_push,get_error_tree(NULL));+ }++ }++++ /*declaration-specifiers:+ ( storage-class-specifier type-specifier type-qualifier function-specifier)* */+ struct Denotation* parse_declaration_specifiers(struct Queue *tokens,struct Scope *scope){- struct Object_Prototype *hold;- enum KEYWORDS kw;- hold=(struct Object_Prototype*)get_object_prototype();+ enum KEYWORDS hold_kw;+ struct Denotation_Prototype *ret;+ ret=get_denotation_prototype();- for(kw=kw_get(tokens);tokens->size>0;chomp(tokens),kw=kw_get(tokens))+ while(1){- switch(kw)+ hold_kw=kw_get(tokens);+ switch(hold_kw){- case KW_CONST:- hold->is_const=1;+ case KW_CONST:+ chomp(tokens);+ ret->is_const=1;break;case KW_VOLATILE:- hold->is_volatile=1;+ chomp(tokens);+ ret->is_volatile=1;break;- case KW_STATIC:- if(hold->storage_class==TSC_NONE)+ case KW_INT:+ chomp(tokens);+ if(ret->specifier!=TS_NONE){- hold->storage_class=TSC_STATIC;- }else+ return get_denotation_prototype((struct Denoted*)ret);+ }+ ret->specifier=TS_INT;+ break;+ case KW_VOID:+ chomp(tokens);+ if(ret->specifier!=TS_NONE){- return get_denoted_error(get_denoted_object((struct Type*)hold));+ return get_denotation_prototype((struct Denoted*)ret);}+ ret->specifier=TS_VOID;break;- case KW_EXTERN:- if(hold->storage_class==TSC_NONE)+ case KW_CHAR:+ chomp(tokens);+ if(ret->specifier!=TS_NONE){- hold->storage_class=TSC_EXTERN;- }else+ return get_denotation_prototype((struct Denoted*)ret);+ }+ ret->specifier=TS_CHAR;+ break;+ case KW_DOUBLE:+ chomp(tokens);+ if(ret->specifier!=TS_NONE){- return get_denoted_error(get_denoted_object((struct Type*)hold));+ return get_denotation_prototype((struct Denoted*)ret);}+ ret->specifier=TS_DOUBLE;break;- case KW_INT:- if(hold->specifier!=TS_NONE)+ case KW_FLOAT:+ chomp(tokens);+ if(ret->specifier!=TS_NONE){- return get_denoted_error(get_denoted_object((struct Type*)hold));+ return get_denotation_prototype((struct Denoted*)ret);}- hold->specifier=TS_INT;+ ret->specifier=TS_FLOAT;break;- case KW_CHAR:- if(hold->specifier!=TS_NONE)+ case KW_LONG:+ chomp(tokens);+ if(ret->constraint!=TC_NONE){- return get_denoted_error(get_denoted_object((struct Type*)hold));+ return get_denotation_prototype((struct Denoted*)ret);}- hold->specifier=TS_CHAR;+ ret->constraint=TC_LONG;break;- case KW_VOID:- if(hold->specifier!=TS_NONE)+ case KW_SHORT:+ chomp(tokens);+ if(ret->constraint!=TC_NONE){- return get_denoted_error(get_denoted_object((struct Type*)hold));+ return get_denotation_prototype((struct Denoted*)ret);}- hold->specifier=TS_VOID;+ ret->constraint=TC_SHORT;break;- case KW_DOUBLE:- if(hold->specifier!=TS_NONE)+ case KW_EXTERN:+ chomp(tokens);+ if(ret->storage_class!=SC_NONE){- return get_denoted_error(get_denoted_object((struct Type*)hold));+ return get_denotation_prototype((struct Denoted*)ret);}- hold->specifier=TS_DOUBLE;+ ret->storage_class=SC_EXTERN;break;- case KW_FLOAT:- if(hold->specifier!=TS_NONE)+ case KW_STATIC:+ chomp(tokens);+ if(ret->storage_class!=SC_NONE){- return get_denoted_error(get_denoted_object((struct Type*)hold));+ return get_denotation_prototype((struct Denoted*)ret);}- hold->specifier=TS_FLOAT;+ ret->storage_class=SC_STATIC;+ break;+ case KW_TYPEDEF:+ chomp(tokens);+ if(ret->storage_class!=SC_NONE)+ {+ return get_denotation_prototype((struct Denoted*)ret);+ }+ ret->storage_class=SC_TYPEDEF;break;- case KW_UNION:case KW_STRUCT:- if(check(tokens,KW_ID,1) )+ ret->specifier=TS_STRUCT;+ goto hack;+ case KW_UNION:+ ret->specifier=TS_UNION;+ hack:+ chomp(tokens);+ if(check(tokens,KW_ID)){- /*this struct might already have been defined*/- struct Denoted_Struct_Union *hold_su;- struct token *tag=tokens->first->prev->data;- hold_su=check_tag(scope,tag);+ struct token *id;+ struct Denoted_Struct_Union *tag;+ id=Queue_Pop(tokens);+ tag=check_tag(scope,id);- if(hold_su==NULL)+ if(tag==NULL){- /*this tag isn't taken*/- /*denote an incomplete struct/union type*/- hold_su=get_denoted_struct_union(tag,get_struct_union());-+ struct Struct_Union *body;+ body=parse_struct_union_specifier_finish(tokens,scope);+ tag=get_denoted_struct_union(id,body);+ Scope_Push(scope,(struct Denoted*)tag);+ ret->struct_union=body;+ }else+ {+ ret->struct_union=tag->struct_union;+ if(ret->struct_union->specifier!=ret->specifier)+ {+ return get_denotation_prototype((struct Denoted*)ret);+ }}- /*consume struct/union tag*/- chomp(tokens);- return get_denoted_object(get_struct_union_type(hold,hold_su->struct_union));- }else if(check(tokens,KW_OPEN_CURLY,1))- {- /*this is a definition of an anonymous struct/union*/- return get_denoted_struct_union(NULL,parse_struct_union_specifier(tokens,scope))}else{- return get_denoted_error(get_denoted_object((struct Type*)hold));+ ret->struct_union=parse_struct_union_specifier_finish(tokens,scope);}- case KW_TYPEDEF:- hold->is_typedef=1;break;- case KW_ID:- if(hold->specifier==TS_NONE && check_if_typedefed(scope,tokens->first->data))+ case KW_ENUM:+ chomp(tokens);+ ret->specifier=TS_ENUM;+ if(check(tokens,KW_ID)){- hold->type_def=check_ordinary(scope,tokens->first->data);- merge_type_nodes(base,check_base_type_component(hold->type_def));- break;+ struct token *id;+ struct Denoted_Enum *enumerator;+ id=Queue_Pop(tokens);+ enumerator=check_tag(scope,id);+ if(enumerator==NULL)+ {+ struct Enum body;+ body=parse_enum_specifier_finish(tokens,scope);+ enumerator=get_denoted_enum(id,body);+ Scope_Push(scope,(struct Denoted*)enumerator);+ ret->enumerator=body;+ }else+ {+ ret->enumerator=enumerator->enumeration;+ if(enumeration->enumeration->specifier!=TS_ENUM)+ {+ return get_denotation_prototype((struct Denoted*)ret);+ }+ }+}else{- return base;+ ret->enumeration=parse_enum_specifier_finish(tokens,scope);}+ break;default:- return base;+ return ret;}}}- /*- pointer:- * type-qualifier-list<opt>- * type-qualifier-list<opt> pointer- */- void parse_pointer(struct Queue *tokens,struct Declarator *upper,struct Scope *scope)- {- struct Type_Node *temp;- while(get_and_check(tokens,KW_STAR))- {- temp=parse_declaration_specifiers(tokens,scope);- Queue_Push_Front(&(upper->type->components),temp);- if(temp->type_specifier!=TS_NONE || temp->is_extern!=0 || temp->is_static!=0 || temp->is_signed!=0)- {- /*TODO error*/- temp->error=1;- upper->initialiser=(struct AST*)get_error_tree(NULL);- return;- }else- {- temp->type_specifier=TS_POINTER;- }- }- }- /*- paramenter-list:- parameter-declaration- parameter-list, prameter-declaration- */- void parse_parameter_list(struct Queue *tokens,struct Type_Node *function_base,struct Scope *scope)- {- assert(function_base->type_specifier==TS_FUNC);- do- {- parse_parameter_declaration(tokens,function_base,scope);- }while(get_and_check(tokens,KW_COMMA));- }/*- ?- parameter-type-list- parameter-list , ...- */- void parse_parameter_type_list(struct Queue *tokens,struct Type_Node *function_base,struct Scope *scope)- {- parse_parameter_list(tokens,function_base,scope);- }- struct AST* parse_initialiser(struct Queue *tokens,struct Scope *scope)+ declarator:+ ( pointer ( type-qualifier )* )* direct-declarator+ */+ struct Denoted* parse_declarator(struct Queue *tokens,struct Scope *scope,struct Denotation_Prototype *prototype){- return parse_assignment_expression(tokens,scope);- }- /*- init-declarator:- declarator = initialiser- */- struct Declarator* parse_init_declarator(struct Queue *tokens,struct Type_Node *base,struct Scope *scope)- {- struct Declarator *ret;- ret=get_declarator(base);- parse_declarator(tokens,ret,scope);- if(get_and_check(tokens,KW_EQ))+ enum KEYWORDS hold;+ struct Denotation_Prototype copy;++ copy=*prototype;+ parse_declarator_inner(tokens,scope,©);+ if(copy.type->specifier==TS_FUNC){- ret->initialiser=parse_initialiser(tokens,scope);- }- return ret;- }- /*- declarator:- pointer- [ pointer ] direct-declarator- */- void parse_declarator(struct Queue *tokens,struct Declarator *base,struct Scope *scope)- {- parse_pointer(tokens,base,scope);- parse_direct_declarator(tokens,base,scope);- }+ return get_denoted_function(prototype);+ }else if(copy.type->specifier==TS_TYPEDEF- /*- direct-declarator-finish:- ( direct-declarator-finish-step )*- */- void parse_direct_declarator_finish(struct Queue *tokens,struct Type *upper,struct Scope *scope)- {- while(parse_direct_declarator_finish_step(tokens,upper,scope));- upper->size=size_of(upper);+ return ;}- /*- direct-declarator-finish-step:- \[ constant-expression \]- \[ \]- \[ * \]- \( parameter-type-list \)- */- char parse_direct_declarator_finish_step(struct Queue *tokens,struct Type *upper,struct Scope *scope)+ void parse_declarator_inner(struct Queue *tokens,struct Scope *scope,struct Denotation_Prototype *copy){- struct Type_Node *temp;- if(get_and_check(tokens,KW_OPEN_SQUARE))- {- temp=get_node();- temp->type_specifier=TS_ARRAY;- temp->type_constraints=TC_NONE;- temp->specifics.arr.number_of_elements_expr=NULL;-- if(get_and_check(tokens,KW_CLOSE_SQUARE))- {- Queue_Push_Front(&upper->components,temp);- return 1;- }- if(check(tokens,KW_STAR,0) && check(tokens,KW_CLOSE_SQUARE,1))- {- chomp(tokens);- chomp(tokens);- Queue_Push_Front(&upper->components,temp);- return 1;- }- temp->specifics.arr.number_of_elements=evaluate_const_expression_integer(- temp->specifics.arr.number_of_elements_expr=parse_const_expression(tokens,scope)- );-- if(!get_and_check(tokens,KW_CLOSE_SQUARE) || temp->specifics.arr.number_of_elements_expr<=0)- {- temp->error=1;- Queue_Push_Front(&upper->components,temp);- return 0;- }- Queue_Push_Front(&upper->components,temp);- return 1;- }else if(get_and_check(tokens,KW_OPEN_NORMAL))++ while(get_and_check(tokens,KW_STAR)){- temp=get_node();- temp->type_specifier=TS_FUNC;- temp->type_constraints=TC_NONE;- Queue_Init(&temp->specifics.arg_types);-- parse_parameter_list(tokens,temp,scope);--- if(!get_and_check(tokens,KW_CLOSE_NORMAL))+ base=get_pointer_type(base);+ hold=kw_get(tokens);+ while(1){- temp->error=1;- Queue_Push_Front(&upper->components,temp);- return 0;+ if(hold==KW_CONST)+ {+ base->is_const=1;+ }else if(hold==KW_VOLATILE)+ {+ base->is_volatile=1;+ }else+ {+ break;+ }}- Queue_Push_Front(&upper->components,temp);- return 1;- }else- {- return 0;}- }-+ }/*direct-declarator:id direct-declarator-finish( declarator ) direct-declarator-finish*/- void parse_direct_declarator(struct Queue *tokens,struct Declarator *upper,struct Scope *scope)+ void parse_direct_declarator(struct Queue *tokens,struct Scope *scope,struct Denotation_Prototype *prototype){- struct Type_Node *temp;- struct Type *hold_type;- struct Type *swap_type;-- if(check(tokens,KW_ID,0))+ struct Denoted *hold;+ if(check(tokens,KW_ID)){- upper->id=Queue_Pop(tokens);- parse_direct_declarator_finish(tokens,upper->type,scope);+ struct token *id;+ id=Queue_Pop(tokens);+ base=parse_direct_declarator_finish(tokens,scope,base);+ switch(base->specifier)+ {+ case VOID:+ case :+ case VOID:+ case VOID:+ case VOID:+ };+}else if(get_and_check(tokens,KW_OPEN_NORMAL)){-- hold_type=upper->type;-- upper->type=malloc(sizeof(struct Type));- Queue_Init(&(upper->type->components));- parse_declarator(tokens,upper,scope);-- swap_type=hold_type;- hold_type=upper->type;- upper->type=swap_type;-- if(get_and_check(tokens,KW_CLOSE_NORMAL))- {- parse_direct_declarator_finish(tokens,upper->type,scope);- Queue_Append(&hold_type->components,&upper->type->components);-- free(upper->type);-- upper->type=hold_type;- }else- {- /*error*/- temp=malloc(sizeof(struct Type_Node));- temp->type_specifier=TS_ERROR;- temp->error=1;- Queue_Push_Front(&hold_type->components,temp);-- Queue_Append(&hold_type->components,&upper->type->components);-- free(upper->type);-- upper->type=hold_type;- }}else{- temp=malloc(sizeof(struct Type_Node));- temp->type_specifier=TS_ERROR;- temp->error=1;- Queue_Push_Front(&upper->type->components,temp);+ /*TODO error*/}}-/*- delcaration:- declaration-specifiers [ init-declarator-list ] ;+ direct-declarator-finish:+ ( [ constant-expression ] | (parameter-list) | ( [id-list] ) )**/-- struct AST* parse_declaration(struct Queue *tokens,struct Scope *scope)+ void parse_direct_declarator_finish(struct Queue *tokens,struct Scope *scope,struct Denotation_Prototype *prototype){- struct AST_Declaration *ret;- struct Declarator *hold;- ret=get_declaration_tree(scope);- ret->base_type=parse_declaration_specifiers(tokens,scope);-- if(get_and_check(tokens,KW_SEMI_COLUMN))- {- return (struct AST*)ret;- }- do- {- hold=parse_init_declarator(tokens,ret->base_type,scope);- Queue_Push(&ret->declarators,hold);- if(hold->id==NULL || !Scope_Push(scope,hold))- return (struct AST*)get_error_tree((struct AST*)ret);-- }while(get_and_check(tokens,KW_COMMA));- if(get_and_check(tokens,KW_SEMI_COLUMN))- {- return (struct AST*)ret;- }else- {- return (struct AST*)get_error_tree((struct AST*)ret);- }+ }- }/*- abstract-declarator:- pointer- [ pointer ] direct-abstract-declarator- */- void parse_abstract_declarator(struct Queue *tokens,struct Declarator *base,struct Scope *scope)+ struct-union-specifier-finish:+ { ( struct-declaration )* }+ */+ struct Struct_Union* parse_struct_union_specifier_finish(struct Queue *tokens,struct Scope *scope){- parse_pointer(tokens,base,scope);- parse_direct_abstract_declarator(tokens,base,scope);+}/*-- direct-abstract-declarator:- direct-declarator-finish- ( abstract-declarator ) direct-declarator-finish+ struct-declaration:+ specifier-qualifier-list ( struct-declarator )* ;*/- void parse_direct_abstract_declarator(struct Queue *tokens,struct Declarator *upper,struct Scope *scope)+ void parse_struct_declaration(struct Queue *tokens,struct Scope *struct_scope,struct Queue* members){- struct Type_Node *temp;- struct Type *hold_type;- struct Type *swap_type;-- if(get_and_check(tokens,KW_OPEN_NORMAL))- {-- hold_type=upper->type;-- upper->type=malloc(sizeof(struct Type));- Queue_Init(&(upper->type->components));- parse_abstract_declarator(tokens,upper,scope);-- swap_type=hold_type;- hold_type=upper->type;- upper->type=swap_type;-- if(get_and_check(tokens,KW_CLOSE_NORMAL))- {- parse_direct_declarator_finish(tokens,upper->type,scope);- Queue_Append(&hold_type->components,&upper->type->components);-- free(upper->type);-- upper->type=hold_type;- }else- {- /*error*/- temp=malloc(sizeof(struct Type_Node));- temp->type_specifier=TS_ERROR;- temp->error=1;- Queue_Push_Front(&hold_type->components,temp);-- Queue_Append(&hold_type->components,&upper->type->components);-- free(upper->type);- upper->type=hold_type;- }- }else- {- parse_direct_declarator_finish(tokens,upper->type,scope);- }}/*- declaration-specifiers declarator- declaration-specifiers [ abstract declaration ]- */- void parse_parameter_declaration(struct Queue *tokens,struct Type_Node *function_base,struct Scope *scope)- {- struct Type_Node *base;- struct Declarator *hold;- assert(function_base->type_specifier==TS_FUNC);- base=parse_declaration_specifiers(tokens,scope);- hold=get_declarator(base);- parse_declarator(tokens,hold,scope);- Queue_Push(&function_base->specifics.arg_types,hold);- }- struct Type_Node* parse_specifier_qualifier_list(struct Queue *tokens,struct Scope *scope)+ struct-declarator:+ declarator+ [ declarator ] : constant-expression+ */+ struct Denoted* parse_struct_declarator(struct Queue *tokens,struct Scope *struct_scope,struct Denoted *origin){- struct Type_Node *ret;- ret=parse_declaration_specifiers(tokens,scope);- if(ret->type_specifier==TS_NONE || ret->is_extern==1 || ret->is_static==1 || ret->is_signed==1)- {- ret->error=1;- }- return ret;+}/*- type-name:- specifier-qualifier-list abstract-declarator;-+ enum-specifier-finish+ { ( enumeration-constant [ = constant-expression ] )* }*/- struct Type* parse_type_name(struct Queue *tokens,struct Scope *scope)+ struct Enum* parse_enum_specifier_finish(struct Queue *tokens,struct Scope *scope){- struct Declarator *declarator;- struct Type *ret;- struct Type_Node *base;-- declarator=malloc(sizeof(struct Declarator));- declarator->type=malloc(sizeof(struct Type));- declarator->id=NULL;- Queue_Init(&declarator->type->components);-- base=parse_specifier_qualifier_list(tokens,scope);- Queue_Push(&declarator->type->components,base);- if(base->error)- {- ret=declarator->type;- free(declarator);- return ret;- }- parse_abstract_declarator(tokens,declarator,scope);-- if(declarator->id!=NULL)- {- base->error=1;- }- ret=declarator->type;- free(declarator);- return ret;}/*- struct-declarator:- declarator- [ declarator ] : constant-expression-- */- void parse_struct_declarator(struct Queue *tokens,struct Declarator *base,struct Scope *scope)+ parameter-list:+ (declaratoion-specifiers (declarator | abstract-declarator),)++ */+ void parse_paramenter_list(struct Queue *tokens,struct Scope *scope,struct Queue *parameters){- struct Type_Node *hold;- if(get_and_check(tokens,KW_COLUMN))- {- hold=get_node();- hold->is_bit_field=1;- hold->specifics.bit_field_length=parse_const_expression(tokens,scope);- Queue_Push(&base->type->components,hold);- }else- {- parse_declarator(tokens,base,scope);- if(get_and_check(tokens,KW_COLUMN))- {- hold=get_node();- hold->is_bit_field=1;- hold->specifics.bit_field_length=parse_const_expression(tokens,scope);- Queue_Push(&base->type->components,hold);- }- }+}/*- struct-declarator-list:- struct-declarator (,struct-declarator)*- */- void parse_struct_declarator_list(struct Queue *tokens,struct Queue *declarators,struct Type_Node *base_type,struct Scope *scope)+ id-list:+ id,...+ */+ void parse_id_list(struct Queue *tokens,struct Scope *scope,struct Queue *ids){- struct Declarator *struct_declaration;- do- {- struct_declaration=get_declarator(base_type);- parse_struct_declarator(tokens,struct_declaration,scope);- Queue_Push(declarators,struct_declaration);- }while(get_and_check(tokens,KW_COMMA));+}/*- struct-declaration:- spedifier-qualifier-list [ struct-declarator-list ] ;+ type-name:+ specifier-qualifier-list [abstract-declarator]*/- void parse_struct_declaration(struct Queue *tokens,struct Type_Node *struct_union_base,struct Scope *scope)+ struct Type* parse_type_name(struct Queue *tokens,struct Scope *scope){- struct AST_Declaration *hold;- hold=get_declaration_tree(scope);- hold->base_type=parse_specifier_qualifier_list(tokens,scope);- parse_struct_declarator_list(tokens,&hold->declarators,hold->base_type,scope);-- Queue_Push(&struct_union_base->specifics.struct_union->declarations,hold);-- if(!get_and_check(tokens,KW_SEMI_COLUMN))- {- struct_union_base->error=1;- }-}- void parse_struct_declaration_list(struct Queue *tokens,struct Type_Node *struct_union_base,struct Scope *scope)+ /*+ abstract-declarator:+ ( pointer )* abstract-direct-declarator+ */+ struct Type* parse_abstract_declarator(struct Queue *tokens,struct Scope *scope,struct Type *base){- do- {- parse_struct_declaration(tokens,struct_union_base,scope);- }while(!( check(tokens,KW_CLOSE_CURLY,0) || struct_union_base->error));+}/*- struct-or-union-specifier:- struct-or-union [ identifier ] { struct-declaration-list }- struct-or-union identifier+ abstract-direct-declarator:+ ( abstract-declarator )+ abstract-declarator-finish*/- struct Type_Node* parse_struct_union_specifier(struct Queue *tokens,struct Scope *scope)+ struct Type* parse_abstract_direct_declarator(struct Queue *tokens,struct Scope *scope,struct Type *base){- struct Type_Node *hold;- hold=get_node();- if(get_and_check(tokens,KW_STRUCT))- {- hold->type_specifier=TS_STRUCT;- }else if(get_and_check(tokens,KW_UNION))- {- hold->type_specifier=TS_UNION;- }else- {- hold->type_specifier=TS_NONE;- hold->error=1;- return hold;- }-- hold->specifics.struct_union=get_struct_union();- if(check(tokens,KW_ID,0))- {- hold->specifics.struct_union->id=Queue_Pop(tokens);- }- if(get_and_check(tokens,KW_OPEN_CURLY))- {- parse_struct_declaration_list(tokens,hold,scope);- if(get_and_check(tokens,KW_CLOSE_CURLY))- {- return hold;- }else- {- hold->error=1;- return hold;- }- }else- {- hold->error=1;- return hold;- }}- struct Struct_Union* get_struct_union()++ /*+ abstract-declarator-finish:+ ( [ constant-expression] | ( parameter-type-list) )*+ */+ struct Type* parse_abstract_declarator_finish(struct Queue *tokens,struct Scope *scope,struct Type *base){- struct Struct_Union* ret;- ret=malloc(sizeof(struct Struct_Union));- Queue_Init(&ret->declarations);- Map_Init(&ret->inner_namespace);- ret->id=NULL;- return ret;+}- char is_type(struct Queue *tokens,struct Scope *scope)+ /*+ initializer:+ assignment-expression+ { initializer , ... [,] }+ */+ struct AST* parse_initializer(struct Queue *tokens,struct Scope *scope,struct Denoted_Object *base){-- enum KEYWORDS kw;- kw=kw_get(tokens);- switch(kw)- {- case KW_CONST:- case KW_VOLATILE:- case KW_STATIC:- case KW_TYPEDEF:- case KW_EXTERN:- case KW_INT:- case KW_CHAR:- case KW_VOID:- case KW_DOUBLE:- case KW_FLOAT:- case KW_UNION:- case KW_STRUCT:- case KW_ENUM:- return 1;- case KW_ID:- return check_if_typedefed(scope,tokens->first->data);- default:- return 0;- }- }- struct Declarator* get_declarator(struct Type_Node *base_type)- {- struct Declarator *ret;- ret=malloc(sizeof(struct Declarator));- ret->id=NULL;- ret->initialiser=NULL;- ret->type=malloc(sizeof(struct Type));- Queue_Init(&ret->type->components);- Queue_Push(&ret->type->components,base_type);- ret->location=NULL;-- return ret;}#endifF diff --git a/parse_declaration.h b/parse_declaration.h --- a/parse_declaration.h +++ b/parse_declaration.h#include "lexer.h"#include <assert.h>- struct Denoted;- struct AST;- struct Scope;-struct AST* parse_declaration(struct Queue *tokens,struct Scope *scope);- void parse_declarator(struct Queue *tokens,struct Denoted *base,struct Scope *scope);- void parse_direct_declarator(struct Queue *tokens,struct Denoted *upper,struct Scope *scope);- void parse_abstract_declarator(struct Queue *tokens,struct Denoted *base,struct Scope *scope);- void parse_direct_abstract_declarator(struct Queue *tokens,struct Denoted *upper,struct Scope *scope);- void parse_pointer(struct Queue *tokens,struct Denoted *upper,struct Scope *scope);- struct Denoted* parse_init_declarator(struct Queue *tokens,struct Type_Node *base,struct Scope *scope);- struct AST* parse_initialiser(struct Queue *tokens,struct Scope *scope);- struct Denoted* parse_declaration_specifiers(struct Queue *tokens,struct Scope *scope);- struct Type_Node* parse_specifier_qualifier_list(struct Queue *tokens,struct Scope *scope);- void parse_parameter_type_list(struct Queue *tokens,struct Type_Node *function_base,struct Scope *scope);- void parse_parameter_list(struct Queue *tokens,struct Type_Node *function_base,struct Scope *scope);- void parse_parameter_declaration(struct Queue *tokens,struct Type_Node *function_base,struct Scope *scope);- void parse_direct_declarator_finish(struct Queue *tokens,struct Type *upper,struct Scope *scope);- char parse_direct_declarator_finish_step(struct Queue *tokens,struct Type *upper,struct Scope *scope);- struct Type* parse_type_name(struct Queue *tokens,struct Scope *scope);--- void parse_struct_declarator(struct Queue *tokens,struct Denoted *base,struct Scope *scope);- void parse_struct_declarator_list(struct Queue *tokens,struct Queue *declarators,struct Type_Node *base_type,struct Scope *scope);- void parse_struct_declaration(struct Queue *tokens,struct Type_Node *struct_union_base,struct Scope *scope);- void parse_struct_declaration_list(struct Queue *tokens,struct Type_Node *struct_union_base,struct Scope *scope);- struct Struct_Union* parse_struct_union_specifier(struct Queue *tokens,struct Scope *scope);-- char is_type(struct Queue *tokens,struct Scope *scope);- struct Type_Node* get_node();- struct Type* get_type();- struct Denoted* get_declarator(struct Type_Node *base_type);#endifF diff --git a/scope.c b/scope.c --- a/scope.c +++ b/scope.creturn hold;}- char Scope_Push(struct Scope *scope,struct Declarator *declarator)+ char Scope_Push(struct Scope *scope,struct Denoted *declarator){- struct Type_Node *hold;- hold=declarator->type->components.last->data;- if(hold->is_typedef)- {-- if(Map_Check(&scope->ordinary,declarator->id->data,declarator->id->data_size))- {- return 0;- }else- {- Map_Push(&scope->ordinary,declarator->id->data,declarator->id->data_size,declarator->type);- return 1;- }- }-- hold=declarator->type->components.first->data;-- switch(hold->type_specifier)- {- case TS_INT:- case TS_CHAR:- case TS_FLOAT:- case TS_DOUBLE:- case TS_ARRAY:- case TS_POINTER:- if(Map_Check(&scope->ordinary,declarator->id->data,declarator->id->data_size))- {- return 0;- }else- {- Map_Push(&scope->ordinary,declarator->id->data,declarator->id->data_size,declarator->type);- return 1;- }- case TS_STRUCT:- case TS_UNION:- if(Map_Check(&scope->tags,declarator->id->data,declarator->id->data_size))- {- return 0;- }else- {- Map_Push(&scope->ordinary,declarator->id->data,declarator->id->data_size,declarator->type);- Map_Push(&scope->tags,kkkkkkk- return 1;- }- }- //shouldnt be able to go herereturn 0;}char check_if_typedefed(struct Scope* scope,struct token *id){- struct Type *hold;- hold=check_ordinary(scope,id);- if(hold)- {- return (((struct Type_Node*)(hold->components.last->data))->is_typedef);- }else- {- return 0;- }-}#endifF diff --git a/scope.h b/scope.h --- a/scope.h +++ b/scope.hstruct Scope* get_scope(struct Scope *parent);void* check_label(struct Scope *current,struct token *id);- void* check_tag(struct Scope *current,struct token *id);+ struct Denoted_Struct_Union* check_tag(struct Scope *current,struct token *id);void* check_ordinary(struct Scope *current,struct token *id);char Scope_Push(struct Scope *scope,struct Denoted* denoted);char check_if_typedefed(struct Scope* scope,struct token *id);F diff --git a/type.c b/type.c --- a/type.c +++ b/type.c- struct Type_Error* get_type_error(struct Type* error)+ struct Type* get_type_error(struct Type* error){struct Type_Error *ret;ret=malloc(sizeof(struct Type_Error));ret->specifier=TS_ERROR;ret->error=error;- return ret;- }- struct Object_Prototype* get_object_prototype()- {- struct Type_Prototype *ret;-- ret=malloc(sizeof(struct Type_Prototype));- ret->specifier=TS_NONE;- ret->size=0;- ret->is_const=ret->is_volatile=0;- ret->storage_class=TSC_NONE;- ret->constraint=TC_NONE;- ret->sign=TSIGN_NONE;-- return ret;+ return (struct Type*)ret;}/*could return error */- struct Type* get_struct_union_type(struct Denotation_Prototype *prototype,struct Struct_Union *base)+ struct Type* get_struct_union_type(struct Denotation_Prototype *prototype){struct Type_Struct_Union *ret;ret=malloc(sizeof(struct Type_Struct_Union));- ret->specifier=ts;- ret->size=prototype->size;-- ret->struct_union=base;+ ret->specifier=prototype->specifier;+ ret->struct_union=prototype->struct_union;- ret->inner_namespace=get_scope(NULL);- ret->id=id;ret->is_const=prototype->is_const;ret->is_volatile=prototype->is_volatile;- ret->storage_class=prototype->storage_class;- if(prototype->constraint!=TC_NONE || prototype->size!=TSIGN_NONE)+ if(prototype->constraint!=TC_NONE || prototype->size!=TSIGN_NONE || (prototype->specifier!=TS_ENUM && prototype->specifier!=TS_STRUCT)){- return (struct Type*)get_type_error(ret);+ return (struct Type*)get_type_error((struct Type*)ret);}else{return (struct Type*)ret;}}- struct Struct_Union* get_struct_union_base()+ struct Struct_Union* get_struct_union_base(enum Type_Specifier struct_or_union){struct Struct_Union *ret;ret=malloc(sizeof(struct Struct_Union));+ ret->specifier=struct_or_union;ret->number_of_members=0;ret->members=NULL;ret->inner_namespace=NULL;return ret;}+ struct Enum *get_enum_base()+ {+ struct Enum *ret;+ ret=malloc(sizeof(struct Enum));+ ret->specifier=TS_ENUM;+ ret->number_of_constants=0;+ ret->consts=NULL;++ return ret;+ }/*could return error*/struct Type* get_basic_type(struct Denotation_Prototype *prototype){ret->size=prototype->size;ret->is_const=prototype->is_const;ret->is_volatile=prototype->is_volatile;- ret->storage_class=prototype->storage_class;ret->constraint=prototype->constraint;ret->size=prototype->sign;|| prototype->constraint==TC_SHORT|| prototype->sign!=TSIGN_NONE){- return (struct Type*)get_type_error(ret);+ return (struct Type*)get_type_error((struct Type*)ret);}break;case TS_CHAR:if(prototype->constraint!=TC_NONE){- return (struct Type*)get_type_error(ret);+ return (struct Type*)get_type_error((struct Type*)ret);}break;default:if(prototype->constraint!=TC_NONE || prototype->sign!=TSIGN_NONE){- return (struct Type*)get_type_error(ret);+ return (struct Type*)get_type_error((struct Type*)ret);}}ret->size=PTR_SIZE;ret->points_to=points_to;ret->is_const=ret->is_volatile=0;- return ret;+ return (struct Type*)ret;}struct Type* get_array_type(struct Type *is_array_of)ret->size=0;ret->number_of_elements=0;- return ret;+ return (struct Type*)ret;}- struct Type* get_enum_type(struct token *id)+ struct Type* get_enum_type(struct Denotation_Prototype *prototype){struct Type_Enum *ret;ret=malloc(sizeof(struct Type_Enum));ret->specifier=TS_ENUM;- ret->number_of_constants=0;- ret->consts=NULL;- ret->id=id;-- return ret;+ ret->enumeration=prototype->enumerator;+ ret->is_const=prototype->is_const;+ ret->is_volatile=prototype->is_volatile;+ if(prototype->sign!=TSIGN_NONE || prototype->constraint!=TC_NONE)+ {+ return get_type_error((struct Type*)ret);+ }+ return (struct Type*)ret;+ }+ struct Type* get_type_bitfield(struct Type* base,size_t number_of_bits)+ {+ struct Type_Bit_Field *ret;+ ret=malloc(sizeof(struct Type_Bit_Field));+ ret->specifier=TS_BITFIELD;+ ret->number_of_bits=number_of_bits;+ ret->base=base;++ return (struct Type*)ret;}#endifF diff --git a/type.h b/type.h --- a/type.h +++ b/type.hstruct Denotation_Prototype;+ /*this isn't just type-specifier*/enum Type_Specifier{TS_VOID,TS_POINTER,TS_ARRAY,TS_FUNC,+ TS_BITFIELD,TS_NONE,- TS_ERROR,+ TS_ERROR};enum Type_Constraint{};struct Struct_Union{+ enum Type_Specifier specifier;size_t size;size_t number_of_members;struct Denoted_Struct_Union_Member **members;struct Scope *inner_namespace;};+ struct Type_Bit_Field+ {+ enum Type_Specifier specifier;+ size_t number_of_bits;+ struct Type *base;+ };struct Type_Basic{enum Type_Specifier specifier;struct Type_Enum{enum Type_Specifier specifier;+ struct Enum *enumeration;++ char is_const:1;+ char is_volatile:1;+ };+ struct Enum+ {+ enum Type_Specifier specifier;size_t number_of_constants;struct Denoted_Enum_Const **consts;- struct token *id;};struct Type* get_type_error(struct Type* error);- struct Type* get_struct_union_type(struct Denotation_Prototype *prototype,struct Struct_Union *base);+ struct Type* get_struct_union_type(struct Denotation_Prototype *prototype);struct Struct_Union* get_struct_union_base();+ struct Enum *get_enum_base();struct Type* get_basic_type(struct Denotation_Prototype *prototype);struct Type* get_pointer_type(struct Type* points_to);struct Type* get_array_type(struct Type *is_array_of);- struct Type* get_enum_type(struct token *id);+ struct Type* get_enum_type(struct Denotation_Prototype *prototype);+ struct Type* get_type_bitfield(struct Type* base,size_t number_of_bits);