F diff --git a/.gitignore b/.gitignore
--- a/.gitignore
+++ b/.gitignore
cmake_install.cmake
Makefile
build
+ tags
F diff --git a/.term.swp b/.term.swp
new file mode 100644
B Binary files /dev/null and b/.term.swp differ
F diff --git a/CMakeLists.txt b/CMakeLists.txt
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
semantics/scope.c
semantics/semantics.c
semantics/gcc_error.c
+ semantics/linkage.c
code_generation/js/transpile_to_js.c
)
F diff --git a/code_generation/js/transpile_to_js.c b/code_generation/js/transpile_to_js.c
--- a/code_generation/js/transpile_to_js.c
+++ b/code_generation/js/transpile_to_js.c
{
fprintf(out,"\n/*EXTERNS START*/\n");
Map_Map_Extended(
- &((struct Normal_Scope*)program->externs)->ordinary
+ &program->external_linkage->ids
,_to_js_print_externs
,command_arguments);
fprintf(out,"\n/*EXTERNS END*/\n");
{
Map_Map_Extended(
- &((struct Normal_Scope*)translation_unit->scope)->ordinary
+ &((struct Normal_Scope*)translation_unit->file_scope)->ordinary
,_to_js_print_statics
,command_arguments);
}
break;
case ST_OBJECT_DECLARATION:
to_js_print_object_declaration_tree(out,((struct AST_Object_Declaration*)tree),program);
- if(((struct AST_Object_Declaration*)tree)->initializer!=NULL)
+ if(((struct AST_Object_Declaration*)tree)->object->initializer!=NULL)
{
fprintf(out,"=");
- to_js_print_ast(out,((struct AST_Object_Declaration*)tree)->initializer,program);
+ to_js_print_ast(out,((struct AST_Object_Declaration*)tree)->object->initializer,program);
}
break;
case ST_FUNCTION_DECLARATION:
}
void to_js_print_object_declaration_tree(FILE* out,struct AST_Object_Declaration *object_declaration,struct Program *program)
{
- if(object_declaration->object->object->storage_class!=SC_EXTERN)
+ if(object_declaration->object->object->storage_class!=SCS_EXTERN)
{
fprintf(out,"let ");
print_token(out,object_declaration->object->id);
cache_type=(struct Type_Function*)function_definition->function->type;
- if((struct Type_Function*)function_definition->function->storage_class==SC_EXTERN)
+ if((struct Type_Function*)function_definition->function->linkage==LINKAGE_EXTERNAL)
{
// fprintf(out,"var ");
print_token(out,function_definition->function->id);
F diff --git a/lex/preprocessing.c b/lex/preprocessing.c
--- a/lex/preprocessing.c
+++ b/lex/preprocessing.c
struct token *hold_token;
int result;
- null_scope=get_normal_scope(NULL,EXTERN_SCOPE);
+ null_scope=get_normal_scope(NULL,FILE_SCOPE);
tokens=lex_line(src,translation_data,1);
F diff --git a/misc/map.c b/misc/map.c
--- a/misc/map.c
+++ b/misc/map.c
tree->is_final=1;
return NULL;
}
+ /*requires that the map has no loops. does not free the root node*/
+ /*TODO*/
+ void Map_Delete_Map(struct Map *tree)
+ {
+
+ }
#endif //#ifndef GMAP
F diff --git a/misc/map.h b/misc/map.h
--- a/misc/map.h
+++ b/misc/map.h
void Map_Remove(Map *tree, void *str,size_t size);
void Map_Map(Map *tree,void (*map)(void*));
void Map_Map_Extended(Map *tree,void (*map)(void*,void*),void* pass_data);
+
void Map_Destroy(Map *tree);
+ void Map_Delete_Map(struct Map *tree);
struct Condensed_Map* Map_Condense(Map* tree);
struct Map* Map_Push_And_Get(struct Map* tree,void *str,size_t size,void *id);
F diff --git a/misc/print.c b/misc/print.c
--- a/misc/print.c
+++ b/misc/print.c
}
ret=0;
- hold_translation_data=get_translation_data(NULL);
+ hold_translation_data=get_translation_data(NULL,get_linkage(),get_linkage());
do
{
base_file=get_source_file(*base_source_names,this_directory);
case DT_Label:
fprintf(out,"label ");return;
case DT_Object:
- switch(((struct Denoted_Object*)denoted)->object->storage_class)
+ switch(((struct Denoted_Object*)denoted)->linkage)
{
- case SC_EXTERN:
- fprintf(out,"extern ");
+ case LINKAGE_INTERNAL:
+ fprintf(out,"internally linked ");
+ break;
+ case LINKAGE_EXTERNAL:
+ fprintf(out,"externally linked ");
break;
- case SC_STATIC:
- fprintf(out,"static ");
+ case LINKAGE_NONE:
break;
+ default:
+ assert(0);
}
fprintf(out,"denoted object ");
print_token(out,((struct Denoted_Object*)denoted)->id);
+ switch(((struct Denoted_Object*)denoted)->object->storage_class)
+ {
+ case SCS_NONE:
+ fprintf(out," with automatic storage duration");
+ break;
+ case SCS_STATIC:
+ fprintf(out," static storage duration");
+ break;
+ assert(0);
+ }
fprintf(out," is a ");
print_type(out,((struct Denoted_Object*)denoted)->object->type,1);
print_type(out,((struct Denoted_Typedef*)denoted)->type,0);
return;
case DT_Function:
- switch(((struct Denoted_Function*)denoted)->storage_class)
+ print_token(out,((struct Denoted_Function*)denoted)->id);
+ fprintf(out," is ");
+ switch(((struct Denoted_Function*)denoted)->linkage)
{
- case SC_EXTERN:
- fprintf(out,"extern ");
+ case LINKAGE_EXTERNAL:
+ fprintf(out," an externally linked ");
break;
- case SC_STATIC:
- fprintf(out,"static ");
+ case LINKAGE_INTERNAL:
+ fprintf(out," an internally linked ");
break;
+ default:
+ assert(0);
}
- print_token(out,((struct Denoted_Function*)denoted)->id);
- fprintf(out," is ");
print_type(out,((struct Denoted_Function*)denoted)->type,1);
return;
case DT_Enum:
case ST_OBJECT_DECLARATION:
print_denoted(out,(struct Denoted*)((struct AST_Object_Declaration*)tree)->object);
fprintf(out,"=");
- print_ast(out,((struct AST_Object_Declaration*)tree)->initializer);
+ print_ast(out,((struct AST_Object_Declaration*)tree)->object->initializer);
break;
case ST_TYPE_DEFINITION:
print_denoted(out,(struct Denoted*)((struct AST_Type_Definition*)tree)->definition);
void print_function_definition(FILE *out,struct Denoted_Function *function)
{
print_token(out,function->id);
- fprintf(out," is a ");
+ fprintf(out," is");
+ switch(function->linkage)
+ {
+ case LINKAGE_EXTERNAL:
+ fprintf(out," an externally linked ");
+ break;
+ case LINKAGE_INTERNAL:
+ fprintf(out," an internally linked ");
+ break;
+ default:
+ assert(0);
+ }
print_type(out,function->type,1);
print_ast(out,(struct AST*)function->body);
}
F diff --git a/parse/parse_declaration.c b/parse/parse_declaration.c
--- a/parse/parse_declaration.c
+++ b/parse/parse_declaration.c
struct Denoted *hold;
prototype=parse_declaration_specifiers(translation_data,scope);
- while(1)
+ while(!get_and_check(translation_data,KW_SEMI_COLUMN))
{
- if(get_and_check(translation_data,KW_SEMI_COLUMN))
- goto finish;
-
hold=parse_declarator(translation_data,scope,prototype);
-
-
- if(hold->denotation==DT_Function && parse_function_definitions==1)
+ if(hold->denotation==DT_Function)
{
- if(get_and_check(translation_data,KW_OPEN_CURLY))
+ /*check if this is a function definition*/
+ if(parse_function_definitions && get_and_check(translation_data,KW_OPEN_CURLY))
{
- ((struct Denoted_Function*)hold)->body=(struct AST_Compound_Statement*)parse_finish_compound_statement(translation_data,scope);
-
+ ((struct Denoted_Function*)hold) ->body=
+ (struct AST_Compound_Statement*)parse_finish_compound_statement(translation_data,scope);
Queue_Push(where_to_push,get_function_definition_tree(scope,(struct Denoted_Function*)hold));
Scope_Push(scope,hold,translation_data);
- goto finish;
+ break;
}
-
+ /*this is a function declaration*/
Queue_Push(where_to_push,get_function_declaration_tree(scope,(struct Denoted_Function*)hold));
}else if(hold->denotation==DT_Typedef)
{
Queue_Push(where_to_push,get_type_definition_tree((struct Denoted_Typedef*)hold));
}else if(hold->denotation==DT_Object)
{
- struct AST_Object_Declaration *od;
- od=get_object_declaration_tree((struct Denoted_Object*)hold,NULL);
- Queue_Push(where_to_push,od);
+ Queue_Push(where_to_push,get_object_declaration_tree((struct Denoted_Object*)hold));
if(get_and_check(translation_data,KW_EQ))
- {
- od->initializer=parse_initializer(translation_data,scope,od->object);
- }
+ ((struct Denoted_Object*)hold)->initializer=parse_initializer(translation_data,scope,(struct Denoted_Object*)hold);
}else
{
/*TODO error*/
Queue_Push(where_to_push,get_declaration_error_tree(hold));
push_translation_error("declaration expected",translation_data);
+
/*search for end of erronous declaration*/
- while(!get_and_check(translation_data,KW_SEMI_COLUMN))
- {
- free(Queue_Pop(translation_data->tokens));
- }
- goto finish;
+ break;
}
Scope_Push(scope,hold,translation_data);
parse_function_definitions=0;
- if(!get_and_check(translation_data,KW_COMMA))
+ if(!get_and_check(translation_data,KW_COMMA) && !check(translation_data,KW_SEMI_COLUMN,0))
{
- if(get_and_check(translation_data,KW_SEMI_COLUMN))
- {
- goto finish;
- }else
- {
- /*TODO error*/
- Queue_Push(where_to_push,get_declaration_error_tree(NULL));
- push_translation_error("semi column expected",translation_data);
- goto finish;
- }
+ /*TODO error*/
+ Queue_Push(where_to_push,get_declaration_error_tree(NULL));
+ push_translation_error("semi column expected",translation_data);
+ break;
}
}
- finish:
free(prototype);
}
if(!parse_storage_class)
goto exit;
chomp(translation_data);
- if(ret->storage_class!=SC_NONE)
+ if(ret->storage_class!=SCS_NONE)
{
switch(ret->storage_class)
{
- case SC_EXTERN:
+ case SCS_EXTERN:
push_translation_error("only one extern allowed >:|",translation_data);
break;
- case SC_TYPEDEF:
- case SC_STATIC:
+ case SCS_TYPEDEF:
+ case SCS_STATIC:
push_translation_error("only one storage class allowed >:|",translation_data);
break;
default:
return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);
}
- ret->storage_class=SC_EXTERN;
+ ret->storage_class=SCS_EXTERN;
break;
case KW_STATIC:
if(!parse_storage_class)
goto exit;
chomp(translation_data);
- if(ret->storage_class!=SC_NONE)
+ if(ret->storage_class!=SCS_NONE)
{
switch(ret->storage_class)
{
- case SC_STATIC:
+ case SCS_STATIC:
push_translation_error("only one static allowed >:|",translation_data);
break;
- case SC_EXTERN:
- case SC_TYPEDEF:
+ case SCS_EXTERN:
+ case SCS_TYPEDEF:
push_translation_error("only one storage class allowed >:|",translation_data);
break;
default:
}
return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);
}
- ret->storage_class=SC_STATIC;
+ ret->storage_class=SCS_STATIC;
break;
case KW_TYPEDEF:
if(!parse_storage_class)
goto exit;
chomp(translation_data);
- if(ret->storage_class!=SC_NONE)
+ if(ret->storage_class!=SCS_NONE)
{
switch(ret->storage_class)
{
- case SC_STATIC:
- case SC_EXTERN:
- case SC_TYPEDEF:
+ case SCS_STATIC:
+ case SCS_EXTERN:
+ case SCS_TYPEDEF:
push_translation_error("only one storage class allowed >:|",translation_data);
break;
default:
}
return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);
}
- ret->storage_class=SC_TYPEDEF;
+ ret->storage_class=SCS_TYPEDEF;
break;
case KW_STRUCT:
ret->specifier=TS_STRUCT;
{
base->is_finished=1;
while(parse_struct_declaration(translation_data,(struct Scope*)base->inner_namespace,base->members))
- {
-
if(get_and_check(translation_data,KW_CLOSE_CURLY))
- {
return ;
- }
- }
-
/*TODO error*/
push_translation_error("expected closing curly bracket from struct declaration",translation_data);
- return ;
-
-
- }else
- {
- /*if this isnt a struct definition return an incomplete struct-union*/
- return ;
-
+ return;
}
-
}
/*
struct-declaration:
struct Denotation_Prototype *prototype;
struct Denoted *hold;
prototype=parse_specifier_qualifier_list(translation_data,struct_scope);
- while(1)
+ while(!get_and_check(translation_data,KW_SEMI_COLUMN))
{
hold=parse_struct_declarator(translation_data,struct_scope,prototype);
if(hold!=NULL && hold->denotation!=DT_Error)
}else
{
free(prototype);
- /*todo error*/
push_translation_error("there is a problem with the declarator",translation_data);
return 0;
}
- if(!get_and_check(translation_data,KW_COMMA))
+
+ if(!get_and_check(translation_data,KW_COMMA) && !check(translation_data,KW_SEMI_COLUMN,0))
{
- if(get_and_check(translation_data,KW_SEMI_COLUMN))
- {
- break;
- }else
- {
- free(prototype);
- push_translation_error("semi column expected in struct declaration",translation_data);
- /*todo error*/
- return 0;
- }
+ free(prototype);
+ push_translation_error("semi column expected in struct declaration",translation_data);
+ return 0;
}
}
free(prototype);
if(get_and_check(translation_data,KW_COLUMN))
{
/*unnamed bitfields are possible*/
- hold=get_denoted_object(NULL,SC_NONE,prototype->type);
+ hold=get_denoted_object(NULL,SCS_NONE,prototype->type,NULL);
}else
{
hold=parse_declarator(translation_data,scope,prototype);
if(get_and_check(translation_data,KW_COLUMN))
{
- /*TODO move error detection in get_type_bitfield*/
+ /*TODO move error detection in get_type_bitfield*/
((struct Denoted_Object*)hold)->object->type=(struct Type*)get_type_bitfield(prototype->type,parse_expression(translation_data,scope));
}
}
*/
struct AST* parse_initializer(struct Translation_Data *translation_data,struct Scope *scope,struct Denoted_Object *base)
{
+ /*TODO add compound initialiser*/
return parse_assignment_expression(translation_data,scope);
}
F diff --git a/parse/parse_declaration.h b/parse/parse_declaration.h
--- a/parse/parse_declaration.h
+++ b/parse/parse_declaration.h
#include <map.h>
#include <lexer.h>
#include <assert.h>
+ #include <linkage.h>
F diff --git a/parse/parse_statement.c b/parse/parse_statement.c
--- a/parse/parse_statement.c
+++ b/parse/parse_statement.c
{
struct AST_Compound_Statement *hold;
hold=get_compound_statement_tree(scope);
- while(!get_and_check(translation_data,KW_CLOSE_CURLY))
+ while(!get_and_check(translation_data,KW_CLOSE_CURLY) && !has_no_tokens(translation_data))
{
if(is_type(translation_data,hold->scope))
{
void chase_next_semicolumn(struct Translation_Data *translation_data)
{
/*chase ; and start parsing next declaration*/
- while(!get_and_check(translation_data,KW_SEMI_COLUMN) &&
+ while(!get_and_check(translation_data,KW_SEMI_COLUMN) && !check(translation_data,KW_CLOSE_CURLY,0) &&
translation_data->tokens->size>0)
{
chomp(translation_data);
F diff --git a/parse/parse_translation_unit.c b/parse/parse_translation_unit.c
--- a/parse/parse_translation_unit.c
+++ b/parse/parse_translation_unit.c
declaration [ translation-unit ]
function-definition [ translation-unit ]
*/
- struct AST* parse_translation_unit(struct Translation_Data *translation_data,struct Scope *externs)
+ struct AST* parse_translation_unit(struct Translation_Data *translation_data)
{
+ size_t loop_preventer;
struct AST_Translation_Unit *hold;
- hold=get_translation_unit_tree(externs);
- while(translation_data->tokens->size>0)
+ hold=get_translation_unit_tree();
+
+ loop_preventer=0;
+ while(translation_data->tokens->size>0 && loop_preventer!=translation_data->tokens->size)
{
- if(is_type(translation_data,hold->scope) || kw_get(translation_data)==KW_ID)
+ loop_preventer=translation_data->tokens->size;
+
+ if(is_type(translation_data,hold->file_scope) || kw_get(translation_data)==KW_ID)
{
- parse_declaration(translation_data,hold->scope,&hold->components,1);
+ parse_declaration(translation_data,hold->file_scope,&hold->components,1);
if(has_new_errors(translation_data))
{
chase_next_semicolumn(translation_data);
F diff --git a/parse/parse_translation_unit.h b/parse/parse_translation_unit.h
--- a/parse/parse_translation_unit.h
+++ b/parse/parse_translation_unit.h
#include <parse_statement.h>
#include <error.h>
- struct AST* parse_translation_unit(struct Translation_Data *translation_data,struct Scope *externs);
+ struct AST* parse_translation_unit(struct Translation_Data *translation_data);
#endif
F diff --git a/semantics/ast.c b/semantics/ast.c
--- a/semantics/ast.c
+++ b/semantics/ast.c
return ret;
}
- struct AST_Object_Declaration* get_object_declaration_tree(struct Denoted_Object *object,struct AST *initializer)
+ struct AST_Object_Declaration* get_object_declaration_tree(struct Denoted_Object *object)
{
struct AST_Object_Declaration *ret;
ret=malloc(sizeof(struct AST_Object_Declaration));
ret->type=ST_OBJECT_DECLARATION;
ret->object=object;
- ret->initializer=initializer;
-
return ret;
}
ret->function=function;
return ret;
}
- struct AST_Translation_Unit* get_translation_unit_tree(struct Scope* parent_scope)
+ struct AST_Translation_Unit* get_translation_unit_tree()
{
struct AST_Translation_Unit *ret;
ret=malloc(sizeof(struct AST_Translation_Unit));
- ret->type=TRANSLATION_UNIT;
+
+ ret->internal_linkage=get_linkage();
+ ret->file_scope=get_normal_scope(NULL,FILE_SCOPE);
+
+
+
Queue_Init(&ret->components);
- ret->scope=get_normal_scope(parent_scope,FILE_SCOPE);
+ Queue_Init(&ret->static_objects);
+ ret->type=TRANSLATION_UNIT;
+
return ret;
}
}
void delete_ast_object_declaration(struct AST_Object_Declaration *object_declaration)
{
- if(object_declaration->initializer!=NULL)
- delete_ast(object_declaration->initializer);
free(object_declaration);
}
{
while(translation_unit->components.size>0)
delete_ast((struct AST*)Queue_Pop(&translation_unit->components));
- if(translation_unit->scope!=NULL)
- delete_scope(translation_unit->scope);
+ if(translation_unit->file_scope!=NULL)
+ delete_scope(translation_unit->file_scope);
+ delete_linkage(translation_unit->internal_linkage);
free(translation_unit);
}
F diff --git a/semantics/ast.h b/semantics/ast.h
--- a/semantics/ast.h
+++ b/semantics/ast.h
#include <scope.h>
#include <parse_declaration.h>
#include <denoted.h>
+ #include <linkage.h>
{
enum AST_Type type;
struct Denoted_Object *object;
- struct AST *initializer;
};
struct AST_Function_Definition
{
{
enum AST_Type type;
struct Queue components;
- struct Scope *scope;
+
+ struct Scope *file_scope;
+ struct Linkage *internal_linkage;
+ struct Queue static_objects;
};
struct AST_Goto_Statement* get_goto_statement_tree(struct token *label,struct Scope *scope);
struct AST* get_nop_tree();
struct AST_Type_Definition* get_type_definition_tree(struct Denoted_Typedef *definition);
- struct AST_Object_Declaration* get_object_declaration_tree(struct Denoted_Object *object,struct AST *initializer);
+ struct AST_Object_Declaration* get_object_declaration_tree(struct Denoted_Object *object);
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);
+ struct AST_Translation_Unit* get_translation_unit_tree();
F diff --git a/semantics/denoted.c b/semantics/denoted.c
--- a/semantics/denoted.c
+++ b/semantics/denoted.c
struct Denoted_Function *ret;
ret=malloc(sizeof(struct Denoted_Function));
ret->denotation=DT_Function;
+ ret->linkage=LINKAGE_NONE;
ret->id=id;
ret->type=return_type;
ret->function_specifier=fs;
ret->body=NULL;
- ret->storage_class=SC_NONE;
return (struct Denoted*)ret;
}
- struct Denoted* get_denoted_object(struct token *id, enum Storage_Class sc,struct Type *type)
+ struct Denoted* get_denoted_object(struct token *id, enum Storage_Class_Specifier sc,struct Type *type,struct AST *initializer)
{
struct Denoted_Object *ret;
ret=malloc(sizeof(struct Denoted_Object));
ret->denotation=DT_Object;
+ ret->linkage=LINKAGE_NONE;
ret->id=id;
ret->object=malloc(sizeof(struct Object));
ret->object->location=NULL;
ret->object->storage_class=sc;
+ ret->initializer=initializer;
+
return (struct Denoted*)ret;
}
ret->denotation=DT_Prototype;
ret->type=NULL;
ret->node=types;
- ret->storage_class=SC_NONE;
+ ret->storage_class=SCS_NONE;
ret->specifier=TS_NONE;
ret->constraint=TC_NONE;
ret->sign=TSIGN_NONE;
if(base->type->specifier==TS_FUNC)
{
if(base->id==NULL && !allow_abstract)
- {
+ {
return get_denoted_error(get_denoted_function(NULL,((struct Type_Function*)base->type)->return_type,prototype->function_specifier));
}else
{
- return get_denoted_function(base->id,base->type,prototype->function_specifier);
+ struct Denoted_Function *hold_denoted_function;
+ hold_denoted_function=(struct Denoted_Function*)get_denoted_function(base->id,base->type,prototype->function_specifier);
+ /*hack*/
+ switch(prototype->storage_class)
+ {
+ case SCS_NONE:
+ hold_denoted_function->linkage=LINKAGE_NONE;
+ break;
+ case SCS_EXTERN:
+ hold_denoted_function->linkage=LINKAGE_EXTERNAL;
+ break;
+ case SCS_STATIC:
+ hold_denoted_function->linkage=LINKAGE_INTERNAL;
+ break;
+
+ }
+ return (struct Denoted*)hold_denoted_function;
}
- }else if(prototype->storage_class==SC_TYPEDEF)
+ }else if(prototype->storage_class==SCS_TYPEDEF)
{
if(base->id==NULL && !allow_abstract)
{
{
if(base->id==NULL && !allow_abstract)
{
- return get_denoted_error(get_denoted_object(base->id,prototype->storage_class,base->type));
+ return get_denoted_error(get_denoted_object(base->id,prototype->storage_class,base->type,NULL));
}else
{
- return get_denoted_object(base->id,prototype->storage_class,base->type);
+ return get_denoted_object(base->id,prototype->storage_class,base->type,NULL);
}
}
}
free(object->id);
if(object->object!=NULL)
delete_object(object->object);
+ if(object->initializer!=NULL)
+ delete_ast(object->initializer);
free(object);
}
void delete_denoted_typedef(struct Denoted_Typedef *typedefed)
{
delete_denoted(denoted);
}
-
+ void delete_denoted_with_no_linkage_wrapper(void *denoted)
+ {
+ if( ((struct Denoted*)denoted)->denotation == DT_Object )
+ {
+ if( AS_DENOTED_OBJECT_PTR(denoted)->linkage!=LINKAGE_NONE )
+ return;
+ }
+ delete_denoted(denoted);
+ }
F diff --git a/semantics/denoted.h b/semantics/denoted.h
--- a/semantics/denoted.h
+++ b/semantics/denoted.h
#include <type.h>
#include <scope.h>
#include <semantics.h>
+ #include <linkage.h>
enum Denotation_Type;
enum Function_Specifier;
- enum Storage_Class;
+ enum Storage_Class_Specifier;
struct Denoted
struct Denoted_Function
{
enum Denotation_Type denotation;
+ enum Linkage_Type linkage;
struct token *id;
struct Type *type;
enum Function_Specifier function_specifier;
- enum Storage_Class storage_class;
-
struct AST_Compound_Statement *body;
};
struct Denoted_Object
{
enum Denotation_Type denotation;
- struct token *id;
+ enum Linkage_Type linkage;
+ struct token *id;
struct Object *object;
+ struct AST *initializer;
};
struct Denoted_Typedef
{
struct Map *node;
- enum Storage_Class storage_class;
+ enum Storage_Class_Specifier storage_class;
enum Type_Specifier specifier;
enum Type_Constraint constraint;
enum Type_Signedness sign;
{
struct Type *type;
struct Location *location;
- enum Storage_Class storage_class;
+ enum Storage_Class_Specifier storage_class;
};
-
+ struct Static_Object;
+ struct Automatic_Object;
struct Denoted_Base* get_denoted_base(struct Denotation_Prototype *prototype);
struct Denoted* get_denoted_error(struct Denoted *error);
struct Denoted* get_denoted_function(struct token *id,struct Type *return_type,enum Function_Specifier fs);
- struct Denoted* get_denoted_object(struct token *id, enum Storage_Class sc,struct Type *type);
+ struct Denoted* get_denoted_object(struct token *id, enum Storage_Class_Specifier sc,struct Type *type,struct AST *initializer);
struct Denoted* get_denoted_typedef(struct Denoted_Base *base);
struct Denoted* get_denoted_enum_const_expr(struct token *id,struct Enum *parent,struct AST* expression);
struct Denoted* get_denoted_enum_const_num(struct token *id,struct Enum *parent,int value);
void delete_denoted_wrapper(void *denoted);
+ void delete_denoted_with_no_linkage_wrapper(void *denoted);
void delete_denoted(struct Denoted *denoted);
void delete_denoted_error(struct Denoted_Error *error);
void delete_denoted_function(struct Denoted_Function *function);
void delete_denoted_base(struct Denoted_Base *base);
- enum Storage_Class get_denoted_function_storage_class(struct Denoted_Function *function);
+ enum Storage_Class_Specifier get_denoted_function_storage_class(struct Denoted_Function *function);
#endif
F diff --git a/semantics/denoted.hh b/semantics/denoted.hh
--- a/semantics/denoted.hh
+++ b/semantics/denoted.hh
#define GCC_DENOTED_HH GCC_DENOTED_HH
#define AS_DENOTED_OBJECT_PTR(x) ((struct Denoted_Object*)x)
- #define AS_DENOTED_FUNCTION(x) ((struct Denoted_Object*)x)
- #define AS_DENOTED_TYPEDEF(x) ((struct Denoted_Object*)x)
- #define AS_DENOTED_ENUM(x) ((struct Denoted_Object*)x)
- #define AS_DENOTED_ENUM_CONST(x) ((struct Denoted_Object*)x)
- #define AS_DENOTED_STRUCT_UNION(x) ((struct denoted_object*)x)
+ #define AS_DENOTED_FUNCTION(x) ((struct Denoted_Function*)x)
+ #define AS_DENOTED_TYPEDEF(x) ((struct Denoted_Typedef*)x)
+ #define AS_DENOTED_ENUM(x) ((struct Denoted_Enum*)x)
+ #define AS_DENOTED_ENUM_CONST(x) ((struct Denoted_Enum_Const*)x)
+ #define AS_DENOTED_STRUCT_UNION(x) ((struct Denoted_Struct_Union*)x)
enum Denotation_Type
{
FS_Inline,
FS_None
};
- enum Storage_Class
+ enum Storage_Class_Specifier
{
- SC_EXTERN,
- SC_STATIC,
- SC_TYPEDEF,
- SC_NONE
+ SCS_EXTERN,
+ SCS_STATIC,
+ SCS_TYPEDEF,
+ SCS_REGISTER,
+ SCS_NONE
+
};
struct Denoted;
F diff --git a/semantics/linkage.c b/semantics/linkage.c
new file mode 100644
--- /dev/null
+++ b/semantics/linkage.c
+ #ifndef GCC_LINKAGE_C
+ #define GCC_LINKAGE_C GCC_LINKAGE_C
+ #include<linkage.h>
+
+
+
+
+
+ struct Linkage* get_linkage()
+ {
+ struct Linkage *ret;
+ ret=malloc(sizeof(struct Linkage));
+ Map_Init(&ret->ids);
+
+ return ret;
+ }
+
+ /*denoted things are deleted here and left alone when deleting scopes*/
+ void delete_linkage(struct Linkage *linkage)
+ {
+ Map_Map(&linkage->ids,delete_denoted_wrapper);
+ Map_Destroy(&linkage->ids);
+ free(linkage);
+ }
+
+
+ /*TODO optimise when you know what should happen here*/
+
+ void account_for_upper_linkage_on_object(struct Scope *scope,struct Translation_Data *translation_data,struct Denoted_Object *denoted_object)
+ {
+ struct Denoted_Object *hold_object;
+ hold_object=check_ordinary(scope,denoted_object->id);
+ if(hold_object!=NULL && hold_object->denotation==DT_Object && types_are_identical(denoted_object->object->type,hold_object->object->type))
+ {
+ if(hold_object->linkage!=LINKAGE_NONE)
+ {
+ denoted_object->linkage=hold_object->linkage;
+ denoted_object->object->storage_class=SCS_STATIC;
+ }else
+ {
+ denoted_object->linkage=LINKAGE_EXTERNAL;
+ denoted_object->object->storage_class=SCS_STATIC;
+ }
+ }else
+ {
+ denoted_object->linkage=LINKAGE_EXTERNAL;
+ denoted_object->object->storage_class=SCS_STATIC;
+ }
+ }
+ void account_for_upper_linkage_on_function(struct Scope *scope,struct Translation_Data *translation_data,struct Denoted_Function *denoted_function)
+ {
+ struct Denoted_Function *hold_function;
+ hold_function=check_ordinary(scope,denoted_function->id);
+ if(hold_function!=NULL)
+ {
+ if(hold_function->denotation==DT_Function && types_are_identical(denoted_function->type,hold_function->type))
+ {
+ denoted_function->linkage=( (hold_function->linkage==LINKAGE_NONE) ? LINKAGE_EXTERNAL : hold_function->linkage);
+ }else
+ {
+ push_translation_error("linking mismatching things",translation_data);
+ return;
+ }
+ }else
+ {
+ denoted_function->linkage=LINKAGE_EXTERNAL;
+ }
+ }
+ void resolve_object_linkage(struct Scope *scope,struct Translation_Data *translation_data,struct Denoted_Object *denoted_object)
+ {
+ if(scope->type==FILE_SCOPE)
+ {
+ if(denoted_object->object->storage_class==SCS_NONE || denoted_object->object->storage_class==SCS_EXTERN)
+ {
+ denoted_object->linkage=LINKAGE_EXTERNAL;
+ denoted_object->object->storage_class=SCS_STATIC;
+ account_for_upper_linkage_on_object(scope,translation_data,denoted_object);
+
+ }else if(denoted_object->object->storage_class==SCS_STATIC)
+ {
+ denoted_object->linkage=LINKAGE_INTERNAL;
+ denoted_object->object->storage_class=SCS_STATIC;
+ }else
+ {
+ assert(0);
+ }
+ }else if(scope->type==FUNCTION_PROTOTYPE_SCOPE)
+ {
+ denoted_object->linkage=LINKAGE_NONE;
+ denoted_object->object->storage_class=SCS_NONE;
+ if(denoted_object->object->storage_class!=SCS_NONE && denoted_object->object->storage_class!=SCS_REGISTER)
+ {
+ push_translation_error("storage class specifier other than register in function prototype scope",translation_data);
+ return ;
+ }
+ }else if(scope->type==BLOCK_SCOPE)
+ {
+ denoted_object->linkage=LINKAGE_NONE;
+ /*here comes the spooky part*/
+ if(denoted_object->object->storage_class==SCS_EXTERN)
+ account_for_upper_linkage_on_object(scope,translation_data,denoted_object);
+ }else
+ {
+ assert(0);
+ }
+
+ /*check if id is linked oppositely*/
+ if(denoted_object->linkage==LINKAGE_EXTERNAL &&
+ Map_Check(&translation_data->internal_linkage->ids,denoted_object->id->data,denoted_object->id->data_size)!=NULL)
+ {
+ push_translation_error("linking id both internally and externally",translation_data);
+ }else if(denoted_object->linkage==LINKAGE_INTERNAL &&
+ Map_Check(&translation_data->external_linkage->ids,denoted_object->id->data,denoted_object->id->data_size)!=NULL)
+ {
+ push_translation_error("linking id both internally and externally",translation_data);
+ }
+ }
+ void resolve_function_linkage(struct Scope *scope,struct Translation_Data *translation_data,struct Denoted_Function *denoted_function)
+ {
+ if(scope->type==BLOCK_SCOPE)
+ {
+ if(denoted_function->linkage==LINKAGE_INTERNAL)
+ {
+ push_translation_error("static storage class specifier on function declaration in block scope",translation_data);
+ return;
+ }else
+ {
+ denoted_function->linkage=LINKAGE_EXTERNAL;
+ account_for_upper_linkage_on_function(scope,translation_data,denoted_function);
+
+ }
+ }else if(scope->type==FILE_SCOPE)
+ {
+ if(denoted_function->linkage==LINKAGE_NONE)
+ denoted_function->linkage=LINKAGE_EXTERNAL;
+ /*falltrough*/
+
+ if(denoted_function->linkage==LINKAGE_EXTERNAL)
+ account_for_upper_linkage_on_function(scope,translation_data,denoted_function);
+
+ }else
+ {
+ assert(0);
+ }
+
+ /*check if id is linked oppositely*/
+ if(denoted_function->linkage==LINKAGE_EXTERNAL &&
+ Map_Check(&translation_data->internal_linkage->ids,denoted_function->id->data,denoted_function->id->data_size)!=NULL)
+ {
+ push_translation_error("linking id both internally and externally",translation_data);
+ }else if(denoted_function->linkage==LINKAGE_INTERNAL &&
+ Map_Check(&translation_data->external_linkage->ids,denoted_function->id->data,denoted_function->id->data_size)!=NULL)
+ {
+ push_translation_error("linking id both internally and externally",translation_data);
+ }
+
+ }
+
+ #endif
F diff --git a/semantics/linkage.h b/semantics/linkage.h
new file mode 100644
--- /dev/null
+++ b/semantics/linkage.h
+ #ifndef GCC_LINKAGE_H
+ #define GCC_LINKAGE_H GCC_LINKAGE_H
+ #include <linkage.hh>
+ #include <map.h>
+ #include <denoted.h>
+
+ enum Linkage_Type;
+
+ /*this can be external or internal depending on which structure it is located*/
+ struct Linkage
+ {
+ struct Map ids;
+ };
+
+
+ struct Linkage* get_linkage();
+ void delete_linkage();
+
+ /*these don't push the object into the linkage map*/
+ void resolve_object_linkage(struct Scope *scope,struct Translation_Data *translation_data,struct Denoted_Object *denoted_object);
+ void resolve_function_linkage(struct Scope *scope,struct Translation_Data *translation_data,struct Denoted_Function *denoted_function);
+ #endif
F diff --git a/semantics/linkage.hh b/semantics/linkage.hh
new file mode 100644
--- /dev/null
+++ b/semantics/linkage.hh
+ #ifndef GCC_LINKAGE_HH
+ #define GCC_LINKAGE_HH GCC_LINKAGE_HH
+
+
+ enum Linkage_Type
+ {
+ LINKAGE_EXTERNAL,
+ LINKAGE_INTERNAL,
+ LINKAGE_NONE
+ };
+
+ struct Linkage;
+
+
+
+ #endif
F diff --git a/semantics/program.c b/semantics/program.c
--- a/semantics/program.c
+++ b/semantics/program.c
ret->source_files=malloc(sizeof(struct Queue));
ret->errors=malloc(sizeof(struct Queue));
ret->types=malloc(sizeof(struct Map));
+ ret->external_linkage=malloc(sizeof(struct Linkage));
Queue_Init(ret->translation_units);
Queue_Init(ret->source_files);
Queue_Init(ret->errors);
- /*this isn't really a scope,
- TODO rework*/
- ret->externs=get_normal_scope(NULL,EXTERN_SCOPE);
+
+
Map_Init(ret->types);
fclose(in);
return src;
}
- struct Translation_Data* get_translation_data(struct Map *types)
+ struct Translation_Data* get_translation_data(struct Map *types,struct Linkage *internal_linkage,struct Linkage *external_linkage)
{
struct Translation_Data *ret;
ret=malloc(sizeof(struct Translation_Data));
ret->number_of_errors_when_last_checked=0;
+ ret->external_linkage=external_linkage;
+ ret->internal_linkage=internal_linkage;
+
return ret;
}
struct Source_Name* get_source_name(char *filename,char *base)
}
program=get_program();
- hold_translation_data=get_translation_data(program->types);
+ hold_translation_data=get_translation_data(program->types,get_linkage(),program->external_linkage);
do
{
base_file=get_source_file(*base_source_names,this_directory);
lex(base_file,hold_translation_data);
if(!has_new_errors(hold_translation_data))
{
- Queue_Push(program->translation_units,parse_translation_unit(hold_translation_data,program->externs));
+ Queue_Push(program->translation_units,parse_translation_unit(hold_translation_data));
}else
{
flush_tokens(hold_translation_data->tokens);
free(program->errors);
- delete_scope(program->externs);
+ delete_linkage(program->external_linkage);
/*BEWARE*/
Map_Map(program->types,delete_type);
}
+ char has_no_tokens(struct Translation_Data *translation_data)
+ {
+ return (translation_data->tokens->size)==0;
+ }
#endif
F diff --git a/semantics/program.h b/semantics/program.h
--- a/semantics/program.h
+++ b/semantics/program.h
struct Queue *translation_units;
struct Queue *source_files;
struct Queue *errors;
- struct Scope *externs;
/*
we the type node structures from
all the translation units are stored here
*/
struct Map *types;
+
+ struct Linkage *external_linkage;
};
struct Translation_Data
{
/*passed from program struct*/
struct Map *types;
+ struct Linkage *external_linkage;
+ struct Linkage *internal_linkage;
+ /*end of passed from program struct*/
};
struct Program* get_program();
struct Source_File* get_source_file(char *filename,char **where_to_search);
void normalise_source_name(struct Source_Name *name);
- struct Translation_Data* get_translation_data(struct Map *types);
+ struct Translation_Data* get_translation_data(struct Map *types,struct Linkage *internal_linkage,struct Linkage *external_linkage);
struct Program* parse_program(char **base_source_names);
char has_new_errors(struct Translation_Data *translation_data);
+ char has_no_tokens(struct Translation_Data *translation_data);
void delete_program(struct Program *program);
void delete_translation_data(struct Translation_Data *translation_data);
F diff --git a/semantics/scope.c b/semantics/scope.c
--- a/semantics/scope.c
+++ b/semantics/scope.c
struct Scope* get_normal_scope(struct Scope *parent,enum Scope_Type type)
{
struct Normal_Scope *ret;
- assert(type==BLOCK_SCOPE || type==EXTERN_SCOPE || type==FILE_SCOPE || type==FUNCTION_PROTOTYPE_SCOPE);
+ assert(type==BLOCK_SCOPE || type==FILE_SCOPE || type==FUNCTION_PROTOTYPE_SCOPE);
ret=malloc(sizeof(struct Normal_Scope));
ret->type=type;
- assert((type!=EXTERN_SCOPE) || parent==NULL);
- assert((type!=FILE_SCOPE) || parent->type==EXTERN_SCOPE);
+ assert((type!=FILE_SCOPE) || parent==NULL);
ret->parent=parent;
Map_Init(&ret->tags);
{
Map_Map(&scope->tags,delete_denoted_wrapper);
Map_Destroy(&scope->tags);
- Map_Map(&scope->ordinary,delete_denoted_wrapper);
+ Map_Map(&scope->ordinary,delete_denoted_with_no_linkage_wrapper);
Map_Destroy(&scope->ordinary);
free(scope);
}
{
case BLOCK_SCOPE:
case FILE_SCOPE:
- case EXTERN_SCOPE:
case FUNCTION_PROTOTYPE_SCOPE:
delete_normal_scope((struct Normal_Scope*)scope);
break;
void Scope_Push(struct Scope *scope,struct Denoted *declarator,struct Translation_Data *translation_data)
{
- /*TODO remove this macro */
- #define CHECK_IF_ID_IS_TAKEN_THEN_PUSH(type,namespace) \
- if(check_##namespace(scope,((type*)declarator)->id))\
- { push_translation_error("redeclaration of id",translation_data);delete_denoted(declarator); return;}\
- else { push_##namespace(scope,((type*)declarator)->id,declarator); }
-
switch(declarator->denotation)
{
/*perhaps lables should be denoted*/
assert(0);
case DT_Function:
- CHECK_IF_ID_IS_TAKEN_THEN_PUSH(struct Denoted_Function,ordinary);
+ push_function(scope,translation_data,AS_DENOTED_FUNCTION(declarator));
break;
case DT_Object:
- CHECK_IF_ID_IS_TAKEN_THEN_PUSH(struct Denoted_Object,ordinary);
+ push_object(scope,translation_data,AS_DENOTED_OBJECT_PTR(declarator));
break;
case DT_Typedef:
- CHECK_IF_ID_IS_TAKEN_THEN_PUSH(struct Denoted_Typedef,ordinary);
+ push_typedef(scope,translation_data,AS_DENOTED_TYPEDEF(declarator));
break;
case DT_Enum_Constant:
- CHECK_IF_ID_IS_TAKEN_THEN_PUSH(struct Denoted_Enum_Const,ordinary);
+ push_denoted_enum_constant(scope,translation_data,AS_DENOTED_ENUM_CONST(declarator));
break;
case DT_Struct_Union_Member:
- CHECK_IF_ID_IS_TAKEN_THEN_PUSH(struct Denoted_Object,ordinary);
+ assert(0);
break;
case DT_Enum:
- CHECK_IF_ID_IS_TAKEN_THEN_PUSH(struct Denoted_Enum,tag);
+ push_denoted_enum_tag(scope,translation_data,AS_DENOTED_ENUM(declarator));
break;
case DT_Struct_Union_Tag:
- CHECK_IF_ID_IS_TAKEN_THEN_PUSH(struct Denoted_Struct_Union,tag);
+ push_denoted_struct_union_tag(scope,translation_data,AS_DENOTED_STRUCT_UNION(declarator));
break;
}
- #undef CHECK_IF_ID_IS_TAKEN_THEN_PUSH
}
char check_if_typedefed(struct Scope* scope,struct token *id)
{
return 1;
}
- void push_tag(struct Scope *current,struct token *id,struct Denoted *denot)
+ #define CHECK_AND_PUSH(thing,scope) Map_Check_And_Push(scope,thing->id->data,thing->id->data_size,thing)
+
+ void push_object(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Object *denoted_object)
+ {
+ #define PO_ERROR(msg) delete_denoted_object(denoted_object);push_translation_error(msg,translation_data);return;
+
+ struct Denoted_Object *hold_object;
+ struct Linkage *linkage;
+ resolve_object_linkage(current,translation_data,denoted_object);
+ if(has_new_errors(translation_data))
+ {PO_ERROR("in declaration");}
+
+ hold_object=CHECK_AND_PUSH(denoted_object,&AS_NORMAL_SCOPE(current)->ordinary);
+ if(hold_object!=NULL && hold_object->linkage==LINKAGE_NONE)
+ {PO_ERROR("redeclaration of identifier");}
+
+ if(denoted_object->linkage==LINKAGE_NONE)
+ {
+ if(hold_object!=NULL)
+ {PO_ERROR("redeclaration of identifier");}
+ }else if(denoted_object->linkage==LINKAGE_EXTERNAL || denoted_object->linkage==LINKAGE_INTERNAL)
+ {
+ linkage=(denoted_object->linkage==LINKAGE_EXTERNAL?translation_data->external_linkage:translation_data->internal_linkage);
+ hold_object=CHECK_AND_PUSH(denoted_object,&linkage->ids);
+ if(hold_object!=NULL)
+ {
+ if(hold_object->denotation!=DT_Object)
+ {PO_ERROR("linking an object to a function");}
+ if(!types_are_identical(hold_object->object->type,denoted_object->object->type))
+ {PO_ERROR("linking an objects with mismatching types");}
+ if(denoted_object->initializer!=NULL)
+ {
+ if(hold_object->initializer==NULL)
+ hold_object->initializer=denoted_object->initializer;
+ else
+ {PO_ERROR("two initialisers for static storage duration object");}
+ //delete_denoted_object(denoted_object);
+ }
+ }
+ }else
+ {
+ assert(0);
+ }
+
+ #undef PO_ERROR
+ }
+ void push_function(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Function *denoted_function)
+ {
+ #define PF_ERROR(msg) delete_denoted_function(denoted_function);push_translation_error(msg,translation_data);return;
+
+ struct Denoted_Function *hold_function;
+ struct Linkage *linkage;
+ resolve_function_linkage(current,translation_data,denoted_function);
+ if(has_new_errors(translation_data))
+ {PF_ERROR("in declaration");}
+
+ if(denoted_function->linkage==LINKAGE_NONE)
+ {
+ hold_function=CHECK_AND_PUSH(denoted_function,&AS_NORMAL_SCOPE(current)->ordinary);
+ if(hold_function!=NULL)
+ {PF_ERROR("id with function type without linkage");}
+ }else if(denoted_function->linkage==LINKAGE_EXTERNAL || denoted_function->linkage==LINKAGE_INTERNAL)
+ {
+ linkage=(denoted_function->linkage==LINKAGE_EXTERNAL?translation_data->external_linkage:translation_data->internal_linkage);
+ hold_function=CHECK_AND_PUSH(denoted_function,&linkage->ids);
+ if(hold_function!=NULL)
+ {
+ if(hold_function->denotation!=DT_Function)
+ {PF_ERROR("linking an function to a object");}
+ if(!types_are_identical(hold_function->type,denoted_function->type))
+ {PF_ERROR("linking functions with mismatching types");}
+ if(hold_function->body!=NULL && denoted_function->body!=NULL)
+ {PF_ERROR("redefinition of a function");}
+ if(denoted_function->body!=NULL)
+ {
+ hold_function->body=denoted_function->body;
+ denoted_function->body=NULL;
+ // delete_denoted_function(denoted_function);
+ }
+ }
+ }else
+ {
+ assert(0);
+ }
+
+ #undef PF_ERROR
+ }
+ void push_typedef(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Typedef *denoted_typedef)
{
- /*TODO fix this shit*/
- assert(current->type!=FUNCTION_SCOPE);
- assert(denot!=NULL);
- Map_Push(&((struct Normal_Scope*)current)->tags,id->data,id->data_size,denot);
+ struct Denoted *hold_denotated;
+ hold_denotated=CHECK_AND_PUSH(denoted_typedef,&AS_NORMAL_SCOPE(current)->ordinary);
+ if(hold_denotated)
+ {
+ delete_denoted_typedef(denoted_typedef);
+ push_translation_error("redefinition of identifier",translation_data);
+ }
}
- void push_ordinary(struct Scope *current,struct token *id,struct Denoted *denot)
+ void push_denoted_enum_tag(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Enum *denoted_enum)
{
- assert(current->type!=FUNCTION_SCOPE);
- assert(denot!=NULL);
- Map_Push(&((struct Normal_Scope*)current)->ordinary,id->data,id->data_size,denot);
+ struct Denoted *hold_denotated;
+ hold_denotated=CHECK_AND_PUSH(denoted_enum,&AS_NORMAL_SCOPE(current)->tags);
+ if(hold_denotated)
+ {
+ delete_denoted_enum(denoted_enum);
+ push_translation_error("redefinition of tag",translation_data);
+ }
+ }
+ void push_denoted_enum_constant(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Enum_Const *denoted_enum_constant)
+ {
+ struct Denoted *hold_denotated;
+ hold_denotated=CHECK_AND_PUSH(denoted_enum_constant,&AS_NORMAL_SCOPE(current)->ordinary);
+ if(hold_denotated)
+ {
+ delete_denoted_enum_constant(denoted_enum_constant);
+ push_translation_error("redefinition of identifier",translation_data);
+ }
+ }
+ void push_denoted_struct_union_tag(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Struct_Union *denoted_struct_union)
+ {
+ struct Denoted *hold_denotated;
+ hold_denotated=CHECK_AND_PUSH(denoted_struct_union,&AS_NORMAL_SCOPE(current)->tags);
+ if(hold_denotated)
+ {
+ delete_denoted_struct_union(denoted_struct_union);
+ push_translation_error("redefinition of tag",translation_data);
+ }
}
+ #undef CHECK_AND_PUSH
#endif
F diff --git a/semantics/scope.h b/semantics/scope.h
--- a/semantics/scope.h
+++ b/semantics/scope.h
struct Scope* get_function_scope(struct Scope *parent);
void* check_label(struct Scope *current,struct token *id);
- void push_label(struct Scope *current,struct token *id);/*TODO*/
-
struct Denoted* check_tag(struct Scope *current,struct token *id);
- void push_tag(struct Scope *current,struct token *id,struct Denoted *denot);
-
void* check_ordinary(struct Scope *current,struct token *id);
- void push_ordinary(struct Scope *current,struct token *id,struct Denoted *denot);
-
- void Scope_Push(struct Scope *scope,struct Denoted *declarator,struct Translation_Data *translation_data);
-
- char check_if_typedefed(struct Scope* scope,struct token *id);
+ void push_label(struct Scope *current,struct token *id);/*TODO*/
+ void push_object(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Object *denoted_object);
+ void push_function(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Function *denoted_function);
+ void push_typedef(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Typedef *denoted_typedef);
+ void push_denoted_enum_tag(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Enum *denoted_enum);
+ void push_denoted_enum_constant(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Enum_Const *denoted_enum_constant);
+ void push_denoted_struct_union_tag(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Struct_Union *denoted_struct_union);
+ void Scope_Push(struct Scope *scope,struct Denoted *declarator,struct Translation_Data *translation_data);
void delete_scope(struct Scope *scope);
void delete_normal_scope(struct Normal_Scope *scope);
void delete_function_scope(struct Function_Scope *scope);
+
+
+
+
+ char check_if_typedefed(struct Scope* scope,struct token *id);
#endif
F diff --git a/semantics/scope.hh b/semantics/scope.hh
--- a/semantics/scope.hh
+++ b/semantics/scope.hh
#ifndef GCC_SCOPE_HH
#define GCC_SCOPE_HH GCC_SCOPE_HH
+ #define AS_NORMAL_SCOPE(x) ((struct Normal_Scope*)x)
+ #define AS_FUNCTION_SCOPE(x) ((struct Function_Scope*)x)
enum Scope_Type{
- EXTERN_SCOPE,
FILE_SCOPE,
BLOCK_SCOPE,
FUNCTION_PROTOTYPE_SCOPE,
F diff --git a/semantics/type.c b/semantics/type.c
--- a/semantics/type.c
+++ b/semantics/type.c
free(type);
}
}
+ char types_are_identical(struct Type *a,struct Type *b)
+ {
+ return 1;
+ }
#endif
F diff --git a/semantics/type.h b/semantics/type.h
--- a/semantics/type.h
+++ b/semantics/type.h
char is_type(struct Translation_Data *translation_data,struct Scope *scope);
size_t get_type_size(struct Type *type);
+ char types_are_identical(struct Type *a,struct Type *b);
F diff --git a/tests/test2.c b/tests/test2.c
--- a/tests/test2.c
+++ b/tests/test2.c
+ extern int err;
struct A
{
int x;
int y;
int kak:1;
- };
+ }zeh;
int main()
{
- int a;
- struct A b;
+ int * const * volatile a[3][2][1];
+ struct A kek;
return 0;
}
F diff --git a/tests/test4.c b/tests/test4.c
--- a/tests/test4.c
+++ b/tests/test4.c
-
- #include <limits.h>
-
-
+ extern int a=10;
+ extern int a;
int main()
{
- printf("asdf\n");
- return 0;
+ {
+ extern int a;
+ }
}
F diff --git a/tests/test5.c b/tests/test5.c
new file mode 100644
--- /dev/null
+++ b/tests/test5.c
+ extern int a;