size_t align_all = 1;
size_t offset = 0;
size_t bit_offset = 0;
- declaration_t *entry = type->declaration->context.declarations;
+ declaration_t *entry = type->declaration->scope.declarations;
for( ; entry != NULL; entry = entry->next) {
if(entry->namespc != NAMESPACE_NORMAL)
continue;
int align_all = 1;
int size = 0;
- declaration_t *entry = declaration->context.declarations;
+ declaration_t *entry = declaration->scope.declarations;
for( ; entry != NULL; entry = entry->next) {
if(entry->namespc != NAMESPACE_NORMAL)
continue;
{
declaration_t *compound_declaration = type->declaration;
- declaration_t *compound_entry = compound_declaration->context.declarations;
+ declaration_t *compound_entry = compound_declaration->scope.declarations;
compound_graph_path_entry_t entry;
entry.type = COMPOUND_GRAPH_ENTRY_COMPOUND;
ir_node *result = NULL;
statement_t *statement = compound->statements;
for( ; statement != NULL; statement = statement->base.next) {
- //context2firm(&statement->context);
+ //context2firm(&statement->scope);
if(statement->base.next == NULL
&& statement->kind == STATEMENT_EXPRESSION) {
}
/* create declarations */
- declaration_t *declaration = statement->context.declarations;
+ declaration_t *declaration = statement->scope.declarations;
for( ; declaration != NULL; declaration = declaration->next) {
create_local_declaration(declaration);
}
case STATEMENT_FOR: {
const for_statement_t *const for_stmt = &stmt->fors;
- count += count_local_declarations(for_stmt->context.declarations, NULL);
+ count += count_local_declarations(for_stmt->scope.declarations, NULL);
count += count_decls_in_expression(for_stmt->initialisation);
count += count_decls_in_expression(for_stmt->condition);
count += count_decls_in_expression(for_stmt->step);
int count = 0;
/* count parameters */
- count += count_local_declarations(declaration->context.declarations, NULL);
+ count += count_local_declarations(declaration->scope.declarations, NULL);
/* count local variables declared in body */
count += count_decls_in_stmts(declaration->init.statement);
ir_type *function_irtype = get_ir_type(declaration->type);
int n = 0;
- declaration_t *parameter = declaration->context.declarations;
+ declaration_t *parameter = declaration->scope.declarations;
for( ; parameter != NULL; parameter = parameter->next, ++n) {
assert(parameter->declaration_kind == DECLARATION_KIND_UNKNOWN);
type_t *type = skip_typeref(parameter->type);
panic("Invalid storage class for global variable");
}
-static void context_to_firm(context_t *context)
+static void scope_to_firm(scope_t *scope)
{
/* first pass: create declarations */
- declaration_t *declaration = context->declarations;
+ declaration_t *declaration = scope->declarations;
for( ; declaration != NULL; declaration = declaration->next) {
if(declaration->namespc != NAMESPACE_NORMAL)
continue;
}
/* second pass: create code */
- declaration = context->declarations;
+ declaration = scope->declarations;
for( ; declaration != NULL; declaration = declaration->next) {
if(declaration->namespc != NAMESPACE_NORMAL)
continue;
break_label = NULL;
current_switch_cond = NULL;
- context_to_firm(&unit->context);
+ scope_to_firm(&unit->scope);
}
static int lookahead_bufpos;
static stack_entry_t *environment_stack = NULL;
static stack_entry_t *label_stack = NULL;
-static context_t *global_context = NULL;
-static context_t *context = NULL;
+static scope_t *global_scope = NULL;
+static scope_t *scope = NULL;
static declaration_t *last_declaration = NULL;
static declaration_t *current_function = NULL;
static switch_statement_t *current_switch = NULL;
} \
next_token();
-static void set_context(context_t *new_context)
+static void set_scope(scope_t *new_scope)
{
- context = new_context;
+ scope = new_scope;
- last_declaration = new_context->declarations;
+ last_declaration = new_scope->declarations;
if(last_declaration != NULL) {
while(last_declaration->next != NULL) {
last_declaration = last_declaration->next;
static void environment_push(declaration_t *declaration)
{
assert(declaration->source_position.input_name != NULL);
- assert(declaration->parent_context != NULL);
+ assert(declaration->parent_scope != NULL);
stack_push(&environment_stack, declaration);
}
static void label_push(declaration_t *declaration)
{
- declaration->parent_context = ¤t_function->context;
+ declaration->parent_scope = ¤t_function->scope;
stack_push(&label_stack, declaration);
}
}
} else {
assert(is_type_compound(type));
- context_t *const context = &type->compound.declaration->context;
+ scope_t *const scope = &type->compound.declaration->scope;
if(token.type == '[') {
errorf(HERE,
skip_designator();
}
- declaration_t *first = context->declarations;
+ declaration_t *first = scope->declarations;
if(first == NULL)
return NULL;
type_t *first_type = first->type;
(is_struct ? NAMESPACE_STRUCT : NAMESPACE_UNION);
declaration->source_position = token.source_position;
declaration->symbol = symbol;
- declaration->parent_context = context;
+ declaration->parent_scope = scope;
if (symbol != NULL) {
environment_push(declaration);
}
assert(symbol != NULL);
errorf(HERE, "multiple definition of '%s %Y'",
is_struct ? "struct" : "union", symbol);
- declaration->context.declarations = NULL;
+ declaration->scope.declarations = NULL;
}
declaration->init.is_defined = true;
- int top = environment_top();
- context_t *last_context = context;
- set_context(&declaration->context);
+ int top = environment_top();
+ scope_t *last_scope = scope;
+ set_scope(&declaration->scope);
parse_compound_type_entries();
parse_attributes();
- assert(context == &declaration->context);
- set_context(last_context);
+ assert(scope == &declaration->scope);
+ set_scope(last_scope);
environment_pop_to(top);
}
declaration->namespc = NAMESPACE_ENUM;
declaration->source_position = token.source_position;
declaration->symbol = symbol;
- declaration->parent_context = context;
+ declaration->parent_scope = scope;
}
type_t *const type = allocate_type_zero(TYPE_ENUM);
declaration_t *parameters = parse_parameters(&type->function);
if(declaration != NULL) {
- declaration->context.declarations = parameters;
+ declaration->scope.declarations = parameters;
}
construct_function_type_t *construct_function_type =
if (last_declaration != NULL) {
last_declaration->next = declaration;
} else {
- context->declarations = declaration;
+ scope->declarations = declaration;
}
last_declaration = declaration;
return declaration;
}
+/**
+ * Check if the declaration of main is suspicious. main should be a
+ * function with external linkage, returning int, taking either zero
+ * arguments, two, or three arguments of appropriate types, ie.
+ *
+ * int main([ int argc, char **argv [, char **env ] ]).
+ *
+ * @param decl the declaration to check
+ * @param type the function type of the declaration
+ */
static void check_type_of_main(const declaration_t *const decl, const function_type_t *const func_type)
{
+ if (decl->storage_class == STORAGE_CLASS_STATIC) {
+ warningf(decl->source_position, "'main' is normally a non-static function");
+ }
if (skip_typeref(func_type->return_type) != type_int) {
warningf(decl->source_position, "return type of 'main' should be 'int', but is '%T'", func_type->return_type);
}
}
parm = parm->next;
if (parm != NULL) {
- warningf(decl->source_position, "'main' takes only zero or two arguments");
+ type_t *const third_type = parm->type;
+ if (!types_compatible(skip_typeref(third_type), type_char_ptr_ptr)) {
+ warningf(decl->source_position, "third argument of 'main' should be 'char**', but is '%T'", third_type);
+ }
+ parm = parm->next;
+ if (parm != NULL) {
+ warningf(decl->source_position, "'main' takes only zero, two or three arguments");
+ }
}
} else {
- warningf(decl->source_position, "'main' takes only zero or two arguments");
+ warningf(decl->source_position, "'main' takes only zero, two or three arguments");
}
}
}
+/**
+ * Check if a symbol is the equal to "main".
+ */
static bool is_sym_main(const symbol_t *const sym)
{
return strcmp(sym->string, "main") == 0;
declaration_t *const previous_declaration = get_declaration(symbol, namespc);
assert(declaration != previous_declaration);
if (previous_declaration != NULL) {
- if (previous_declaration->parent_context == context) {
+ if (previous_declaration->parent_scope == scope) {
/* can happen for K&R style declarations */
if(previous_declaration->type == NULL) {
previous_declaration->type = declaration->type;
}
}
} else if (warning.missing_declarations &&
- context == global_context &&
+ scope == global_scope &&
!is_type_function(type) && (
declaration->storage_class == STORAGE_CLASS_NONE ||
declaration->storage_class == STORAGE_CLASS_THREAD
warningf(declaration->source_position, "no previous declaration for '%#T'", orig_type, symbol);
}
- assert(declaration->parent_context == NULL);
+ assert(declaration->parent_scope == NULL);
assert(declaration->symbol != NULL);
- assert(context != NULL);
+ assert(scope != NULL);
- declaration->parent_context = context;
+ declaration->parent_scope = scope;
environment_push(declaration);
return append_declaration(declaration);
declaration_t *previous_declaration = get_declaration(symbol, namespc);
if(previous_declaration == NULL ||
- previous_declaration->parent_context != context) {
+ previous_declaration->parent_scope != scope) {
errorf(HERE, "expected declaration of a function parameter, found '%Y'",
symbol);
return declaration;
if(previous_declaration->type == NULL) {
previous_declaration->type = declaration->type;
previous_declaration->storage_class = declaration->storage_class;
- previous_declaration->parent_context = context;
+ previous_declaration->parent_scope = scope;
return previous_declaration;
} else {
return record_declaration(declaration);
return;
/* push function parameters */
- int top = environment_top();
- context_t *last_context = context;
- set_context(&declaration->context);
+ int top = environment_top();
+ scope_t *last_scope = scope;
+ set_scope(&declaration->scope);
- declaration_t *parameter = declaration->context.declarations;
+ declaration_t *parameter = declaration->scope.declarations;
for( ; parameter != NULL; parameter = parameter->next) {
- assert(parameter->parent_context == NULL);
- parameter->parent_context = context;
+ assert(parameter->parent_scope == NULL);
+ parameter->parent_scope = scope;
environment_push(parameter);
}
}
/* pop function parameters */
- assert(context == &declaration->context);
- set_context(last_context);
+ assert(scope == &declaration->scope);
+ set_scope(last_scope);
environment_pop_to(top);
/* update function type */
function_parameter_t *parameters = NULL;
function_parameter_t *last_parameter = NULL;
- declaration_t *parameter_declaration = declaration->context.declarations;
+ declaration_t *parameter_declaration = declaration->scope.declarations;
for( ; parameter_declaration != NULL;
parameter_declaration = parameter_declaration->next) {
type_t *parameter_type = parameter_declaration->type;
declaration_t *const declaration = record_function_definition(ndeclaration);
if(ndeclaration != declaration) {
- declaration->context = ndeclaration->context;
+ declaration->scope = ndeclaration->scope;
}
type = skip_typeref(declaration->type);
- /* push function parameters and switch context */
- int top = environment_top();
- context_t *last_context = context;
- set_context(&declaration->context);
+ /* push function parameters and switch scope */
+ int top = environment_top();
+ scope_t *last_scope = scope;
+ set_scope(&declaration->scope);
- declaration_t *parameter = declaration->context.declarations;
+ declaration_t *parameter = declaration->scope.declarations;
for( ; parameter != NULL; parameter = parameter->next) {
- if(parameter->parent_context == &ndeclaration->context) {
- parameter->parent_context = context;
+ if(parameter->parent_scope == &ndeclaration->scope) {
+ parameter->parent_scope = scope;
}
- assert(parameter->parent_context == NULL
- || parameter->parent_context == context);
- parameter->parent_context = context;
+ assert(parameter->parent_scope == NULL
+ || parameter->parent_scope == scope);
+ parameter->parent_scope = scope;
environment_push(parameter);
}
}
end_of_parse_external_declaration:
- assert(context == &declaration->context);
- set_context(last_context);
+ assert(scope == &declaration->scope);
+ set_scope(last_scope);
environment_pop_to(top);
}
declaration->type = type;
declaration->symbol = symbol;
declaration->source_position = source_position;
- declaration->parent_context = global_context;
+ declaration->parent_scope = global_scope;
- context_t *old_context = context;
- set_context(global_context);
+ scope_t *old_scope = scope;
+ set_scope(global_scope);
environment_push(declaration);
- /* prepend the declaration to the global declarations list */
- declaration->next = context->declarations;
- context->declarations = declaration;
+ /* prepends the declaration to the global declarations list */
+ declaration->next = scope->declarations;
+ scope->declarations = declaration;
- assert(context == global_context);
- set_context(old_context);
+ assert(scope == global_scope);
+ set_scope(old_scope);
return declaration;
}
expression_t *const expr = parse_assignment_expression();
if (expr->kind == EXPR_REFERENCE) {
declaration_t *const decl = expr->reference.declaration;
- if (decl->parent_context == ¤t_function->context &&
+ if (decl->parent_scope == ¤t_function->scope &&
decl->next == NULL) {
expression->va_starte.parameter = decl;
expect(')');
return create_invalid_expression();
}
- declaration_t *iter = declaration->context.declarations;
+ declaration_t *iter = declaration->scope.declarations;
for( ; iter != NULL; iter = iter->next) {
if(iter->symbol == symbol) {
break;
for( ; parameter != NULL && argument != NULL;
parameter = parameter->next, argument = argument->next) {
type_t *expected_type = parameter->type;
- /* TODO report context in error messages */
+ /* TODO report scope in error messages */
expression_t *const arg_expr = argument->expression;
type_t *const res_type = semantic_assign(expected_type, arg_expr, "function call");
if (res_type == NULL) {
*/
static bool has_const_fields(const compound_type_t *type)
{
- const context_t *context = &type->declaration->context;
- const declaration_t *declaration = context->declarations;
+ const scope_t *scope = &type->declaration->scope;
+ const declaration_t *declaration = scope->declarations;
for (; declaration != NULL; declaration = declaration->next) {
if (declaration->namespc != NAMESPACE_NORMAL)
/* if we found a label in the same function, then we already created the
* declaration */
if(candidate != NULL
- && candidate->parent_context == ¤t_function->context) {
+ && candidate->parent_scope == ¤t_function->scope) {
return candidate;
}
expect('(');
- int top = environment_top();
- context_t *last_context = context;
- set_context(&statement->context);
+ int top = environment_top();
+ scope_t *last_scope = scope;
+ set_scope(&statement->scope);
if(token.type != ';') {
if(is_declaration_specifier(&token, false)) {
expect(')');
statement->body = parse_loop_body((statement_t*)statement);
- assert(context == &statement->context);
- set_context(last_context);
+ assert(scope == &statement->scope);
+ set_scope(last_scope);
environment_pop_to(top);
return (statement_t*) statement;
parse_declaration(record_declaration);
if(before == NULL) {
- statement->declaration.declarations_begin = context->declarations;
+ statement->declaration.declarations_begin = scope->declarations;
} else {
statement->declaration.declarations_begin = before->next;
}
eat('{');
- int top = environment_top();
- context_t *last_context = context;
- set_context(&compound_statement->context);
+ int top = environment_top();
+ scope_t *last_scope = scope;
+ set_scope(&compound_statement->scope);
statement_t *last_statement = NULL;
errorf(compound_statement->statement.source_position, "end of file while looking for closing '}'");
}
- assert(context == &compound_statement->context);
- set_context(last_context);
+ assert(scope == &compound_statement->scope);
+ set_scope(last_scope);
environment_pop_to(top);
return (statement_t*) compound_statement;
{
translation_unit_t *unit = allocate_ast_zero(sizeof(unit[0]));
- assert(global_context == NULL);
- global_context = &unit->context;
+ assert(global_scope == NULL);
+ global_scope = &unit->scope;
- assert(context == NULL);
- set_context(&unit->context);
+ assert(scope == NULL);
+ set_scope(&unit->scope);
initialize_builtin_types();
}
}
- assert(context == &unit->context);
- context = NULL;
+ assert(scope == &unit->scope);
+ scope = NULL;
last_declaration = NULL;
- assert(global_context == &unit->context);
- global_context = NULL;
+ assert(global_scope == &unit->scope);
+ global_scope = NULL;
return unit;
}
#include "type.h"
#include "adt/error.h"
-static const context_t *global_context;
-static FILE *out;
+static const scope_t *global_scope;
+static FILE *out;
static void write_type(const type_t *type);
static const char *get_atomic_type_string(const atomic_type_kind_t type)
{
switch(type) {
- case ATOMIC_TYPE_VOID: return "void";
- case ATOMIC_TYPE_CHAR: return "byte";
- case ATOMIC_TYPE_SCHAR: return "byte";
- case ATOMIC_TYPE_UCHAR: return "unsigned byte";
- case ATOMIC_TYPE_SHORT: return "short";
- case ATOMIC_TYPE_USHORT: return "unsigned short";
- case ATOMIC_TYPE_INT: return "int";
- case ATOMIC_TYPE_UINT: return "unsigned int";
- case ATOMIC_TYPE_LONG: return "int";
- case ATOMIC_TYPE_ULONG: return "unsigned int";
- case ATOMIC_TYPE_LONGLONG: return "long";
- case ATOMIC_TYPE_ULONGLONG: return "unsigned long";
- case ATOMIC_TYPE_FLOAT: return "float";
- case ATOMIC_TYPE_DOUBLE: return "double";
+ case ATOMIC_TYPE_VOID: return "void";
+ case ATOMIC_TYPE_CHAR: return "byte";
+ case ATOMIC_TYPE_SCHAR: return "byte";
+ case ATOMIC_TYPE_UCHAR: return "unsigned byte";
+ case ATOMIC_TYPE_SHORT: return "short";
+ case ATOMIC_TYPE_USHORT: return "unsigned short";
+ case ATOMIC_TYPE_INT: return "int";
+ case ATOMIC_TYPE_UINT: return "unsigned int";
+ case ATOMIC_TYPE_LONG: return "int";
+ case ATOMIC_TYPE_ULONG: return "unsigned int";
+ case ATOMIC_TYPE_LONGLONG: return "long";
+ case ATOMIC_TYPE_ULONGLONG: return "unsigned long";
+ case ATOMIC_TYPE_FLOAT: return "float";
+ case ATOMIC_TYPE_DOUBLE: return "double";
case ATOMIC_TYPE_LONG_DOUBLE: return "double";
- case ATOMIC_TYPE_BOOL: return "bool";
- default: panic("unsupported atomic type");
+ case ATOMIC_TYPE_BOOL: return "bool";
+ default: panic("unsupported atomic type");
}
}
static declaration_t *find_typedef(const type_t *type)
{
/* first: search for a matching typedef in the global type... */
- declaration_t *declaration = global_context->declarations;
+ declaration_t *declaration = global_scope->declarations;
while(declaration != NULL) {
if(! (declaration->storage_class == STORAGE_CLASS_TYPEDEF)) {
declaration = declaration->next;
{
fprintf(out, "struct %s:\n", symbol->string);
- const declaration_t *declaration = type->declaration->context.declarations;
+ const declaration_t *declaration = type->declaration->scope.declarations;
while(declaration != NULL) {
write_struct_entry(declaration);
declaration = declaration->next;
{
fprintf(out, "union %s:\n", symbol->string);
- const declaration_t *declaration = type->declaration->context.declarations;
+ const declaration_t *declaration = type->declaration->scope.declarations;
while(declaration != NULL) {
write_struct_entry(declaration);
declaration = declaration->next;
const function_type_t *function_type
= (const function_type_t*) declaration->type;
- declaration_t *parameter = declaration->context.declarations;
+ declaration_t *parameter = declaration->scope.declarations;
int first = 1;
for( ; parameter != NULL; parameter = parameter->next) {
if(!first) {
void write_fluffy_decls(FILE *output, const translation_unit_t *unit)
{
out = output;
- global_context = &unit->context;
+ global_scope = &unit->scope;
ast_set_output(out);
fprintf(out, "/* WARNING: Automatically generated file */\n");
/* write structs,unions + enums */
- declaration_t *declaration = unit->context.declarations;
+ declaration_t *declaration = unit->scope.declarations;
for( ; declaration != NULL; declaration = declaration->next) {
//fprintf(out, "// Decl: %s\n", declaration->symbol->string);
if(! (declaration->storage_class == STORAGE_CLASS_TYPEDEF)) {
}
/* write global variables */
- declaration = unit->context.declarations;
+ declaration = unit->scope.declarations;
for( ; declaration != NULL; declaration = declaration->next) {
if(declaration->namespc != NAMESPACE_NORMAL)
continue;
}
/* write functions */
- declaration = unit->context.declarations;
+ declaration = unit->scope.declarations;
for( ; declaration != NULL; declaration = declaration->next) {
if(declaration->namespc != NAMESPACE_NORMAL)
continue;