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