1 /* 2 * Symbol scoping. 3 * 4 * This is pretty trivial. 5 * 6 * Copyright (C) 2003 Transmeta Corp. 7 * 2003-2004 Linus Torvalds 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a copy 10 * of this software and associated documentation files (the "Software"), to deal 11 * in the Software without restriction, including without limitation the rights 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 * copies of the Software, and to permit persons to whom the Software is 14 * furnished to do so, subject to the following conditions: 15 * 16 * The above copyright notice and this permission notice shall be included in 17 * all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 * THE SOFTWARE. 26 */ 27 #include <stdlib.h> 28 #include <string.h> 29 #include <stdio.h> 30 31 #include "lib.h" 32 #include "allocate.h" 33 #include "symbol.h" 34 #include "scope.h" 35 36 static struct scope builtin_scope = { .next = &builtin_scope }; 37 38 struct scope *block_scope = &builtin_scope, // regular automatic variables etc 39 *function_scope = &builtin_scope, // labels, arguments etc 40 *file_scope = &builtin_scope, // static 41 *global_scope = &builtin_scope; // externally visible 42 43 void bind_scope(struct symbol *sym, struct scope *scope) 44 { 45 sym->scope = scope; 46 add_symbol(&scope->symbols, sym); 47 } 48 49 void rebind_scope(struct symbol *sym, struct scope *new) 50 { 51 struct scope *old = sym->scope; 52 53 if (old == new) 54 return; 55 56 if (old) 57 delete_ptr_list_entry((struct ptr_list**) &old->symbols, sym, 1); 58 59 bind_scope(sym, new); 60 } 61 62 static void start_scope(struct scope **s, struct position pos) 63 { 64 struct scope *scope = __alloc_scope(0); 65 memset(scope, 0, sizeof(*scope)); 66 scope->token = __alloc_token(0); 67 scope->token->pos = pos; 68 scope->next = *s; 69 *s = scope; 70 } 71 72 void start_file_scope(void) 73 { 74 struct scope *scope = __alloc_scope(0); 75 76 memset(scope, 0, sizeof(*scope)); 77 scope->next = &builtin_scope; 78 file_scope = scope; 79 80 /* top-level stuff defaults to file scope, "extern" etc will choose global scope */ 81 function_scope = scope; 82 block_scope = scope; 83 } 84 85 void start_symbol_scope(struct position pos) 86 { 87 start_scope(&block_scope, pos); 88 } 89 90 void start_function_scope(struct position pos) 91 { 92 start_scope(&function_scope, pos); 93 start_scope(&block_scope, pos); 94 } 95 96 static void remove_symbol_scope(struct symbol *sym) 97 { 98 struct symbol **ptr = &sym->ident->symbols; 99 100 while (*ptr != sym) 101 ptr = &(*ptr)->next_id; 102 *ptr = sym->next_id; 103 } 104 105 static void end_scope(struct scope **s) 106 { 107 struct scope *scope = *s; 108 struct symbol_list *symbols = scope->symbols; 109 struct symbol *sym; 110 111 *s = scope->next; 112 scope->symbols = NULL; 113 FOR_EACH_PTR(symbols, sym) { 114 remove_symbol_scope(sym); 115 } END_FOR_EACH_PTR(sym); 116 } 117 118 void end_file_scope(void) 119 { 120 end_scope(&file_scope); 121 } 122 123 void new_file_scope(void) 124 { 125 if (file_scope != &builtin_scope) 126 end_file_scope(); 127 start_file_scope(); 128 } 129 130 void end_symbol_scope(void) 131 { 132 end_scope(&block_scope); 133 } 134 135 void end_function_scope(void) 136 { 137 end_scope(&block_scope); 138 end_scope(&function_scope); 139 } 140 141 int is_outer_scope(struct scope *scope) 142 { 143 if (scope == block_scope) 144 return 0; 145 if (scope == &builtin_scope && block_scope->next == &builtin_scope) 146 return 0; 147 return 1; 148 } 149 150