/* * Symbol scoping. * * This is pretty trivial. * * Copyright (C) 2003 Transmeta Corp. * 2003-2004 Linus Torvalds * * Licensed under the Open Software License version 1.1 */ #include #include #include #include "lib.h" #include "allocate.h" #include "symbol.h" #include "scope.h" static struct scope builtin_scope = { .next = &builtin_scope }; struct scope *block_scope = &builtin_scope, // regular automatic variables etc *function_scope = &builtin_scope, // labels, arguments etc *file_scope = &builtin_scope, // static *global_scope = &builtin_scope; // externally visible void bind_scope(struct symbol *sym, struct scope *scope) { sym->scope = scope; add_symbol(&scope->symbols, sym); } static void start_scope(struct scope **s) { struct scope *scope = __alloc_scope(0); memset(scope, 0, sizeof(*scope)); scope->next = *s; *s = scope; } void start_file_scope(void) { struct scope *scope = __alloc_scope(0); memset(scope, 0, sizeof(*scope)); scope->next = &builtin_scope; file_scope = scope; /* top-level stuff defaults to file scope, "extern" etc will choose global scope */ function_scope = scope; block_scope = scope; } void start_symbol_scope(void) { start_scope(&block_scope); } void start_function_scope(void) { start_scope(&function_scope); start_scope(&block_scope); } static void remove_symbol_scope(struct symbol *sym) { struct symbol **ptr = &sym->ident->symbols; while (*ptr != sym) ptr = &(*ptr)->next_id; *ptr = sym->next_id; } static void end_scope(struct scope **s) { struct scope *scope = *s; struct symbol_list *symbols = scope->symbols; struct symbol *sym; *s = scope->next; scope->symbols = NULL; FOR_EACH_PTR(symbols, sym) { remove_symbol_scope(sym); } END_FOR_EACH_PTR(sym); } void end_file_scope(void) { end_scope(&file_scope); } void new_file_scope(void) { if (file_scope != &builtin_scope) end_file_scope(); start_file_scope(); } void end_symbol_scope(void) { end_scope(&block_scope); } void end_function_scope(void) { end_scope(&block_scope); end_scope(&function_scope); } int is_outer_scope(struct scope *scope) { if (scope == block_scope) return 0; if (scope == &builtin_scope && block_scope->next == &builtin_scope) return 0; return 1; }