📄 symbol.c
字号:
break;
case sc_auto:
message (WARN_HIDE, nameof (sp));
break;
default:
break;
}
}
#endif /* SYNTAX_CORRECT */
}
#ifdef FACIST
#ifndef SYNTAX_CORRECT
} else {
switch (storageof (sp)) {
case sc_global:
message (WARN_PREVDECL, nameof (sp));
break;
default:
break;
}
#endif /* SYNTAX_CORRECT */
#endif /* FACIST */
}
insertsym (sp, hashtab);
addsym (sp, scope_tab);
}
void sym_append P1 (SYM **, ptr_sp)
{
append (ptr_sp, &scope.local->symbols, symbols);
}
void tag_append P1 (SYM **, ptr_sp)
{
append (ptr_sp, &scope.local->tags, tags);
}
void field_append P1 (SYM **, ptr_sp)
{
#ifndef SYNTAX_CORRECT
SYM *sp = sym_search (nameof (*ptr_sp));
if ((sp != NIL_SYM) && is_local_scope (sp) && is_member (sp)) {
message (ERR_REDECL, nameof (*ptr_sp));
return;
}
#endif /* SYNTAX_CORRECT */
sym_append (ptr_sp);
}
SYM *tag_search P1 (const CHAR *, na)
{
return findsym (na, tags);
}
SYM *sym_search P1 (const CHAR *, na)
{
return findsym (na, symbols);
}
/*---------------------------------------------------------------------------*/
static TABLE labsyms;
static SYM *get_label P1 (const CHAR *, na)
{
SYM *sp = search (na, &labsyms);
if (sp == NIL_SYM) {
sp = mk_sym (na, sc_label, NIL_TYP);
sp->value.l = nextlabel++;
addsym (sp, &labsyms);
}
return sp;
}
LABEL lab_search P1 (const CHAR *, na)
{
SYM *sp = get_label (na);
symbol_used (sp);
return sp->value.l;
}
LABEL lab_define P1 (const CHAR *, na)
{
SYM *sp = get_label (na);
#ifndef SYNTAX_CORRECT
if (is_symbol_defined (sp)) {
message (ERR_DUPLABEL, na);
}
#endif /* SYNTAX_CORRECT */
symbol_defined (sp);
return sp->value.l;
}
void check_labels P0 (void)
{
#ifndef SYNTAX_CORRECT
const SYM *sp;
for (sp = labsyms.head; sp != NIL_SYM; sp = nextsym (sp)) {
if (!is_symbol_defined (sp)) {
message (ERR_UNDEFLAB, nameof (sp));
} else if (!is_symbol_used (sp)) {
message (WARN_LABNOTUSED, nameof (sp));
}
}
#endif /* SYNTAX_CORRECT */
labsyms.head = labsyms.tail = NIL_SYM;
}
/*---------------------------------------------------------------------------*/
BLOCK *mk_block P0 (void)
{
BLOCK *block;
block = (BLOCK *) xalloc (sizeof (BLOCK));
*block = init_block;
return block;
}
void beginblock P0 (void)
{
BLOCK *sb;
sb = mk_block ();
sb->prev = scope.local;
sb->offset = lc_auto;
scope.local = sb;
if (scope.global == NIL_BLOCK) {
scope.global = sb;
}
scope_level++;
}
void endblock P0 (void)
{
SYM *sp;
BLOCK *block = scope.local;
if (lc_auto > lc_auto_max) {
lc_auto_max = lc_auto;
}
#if 0
/*
* This will allow nested compound statements to start their definitions
* at the same offset. However there is currently a problem with this in
* the global optimiser when an integer is at the same offset as a float -
* the float is incorrectly optimised into a register! So until a solution
* is found just let the offsets be additive.
*/
lc_auto = block->offset;
#endif
for (sp = symbolsof (block); sp != NIL_SYM; sp = nextsym (sp)) {
TYP *tp = typeof (sp);
switch (storageof (sp)) {
case sc_global:
if (scope_level == GLOBAL_SCOPE) {
if (!(sp->status & (SYM_DEFINED | SYM_OUTPUT))) {
if (is_array_type (tp) && is_unknown_size (tp)) {
tp->size = referenced_type (tp)->size;
}
#ifndef SYNTAX_CORRECT
check_complete (tp);
#endif /* SYNTAX_CORRECT */
#ifdef CPU_DEFINED
put_storage (sp); /* tentative definition */
put_reference (sp);
#endif /* CPU_DEFINED */
}
}
break;
case sc_external:
if (scope_level == GLOBAL_SCOPE) {
#ifdef CPU_DEFINED
if (sp->status & (SYM_USED | SYM_DEFINED)) {
put_reference (sp);
}
#endif /* CPU_DEFINED */
} else {
SYM *sp1;
sp1 = global_search (sp);
if (sp1) {
sp1->status |= (STATUS) (sp->status & (STATUS)
~((unsigned) SYM_OUTPUT));
} else {
/* add this entry to the global table */
global_flag++;
sp1 = copy_sym (sp);
set_type (sp1, copy_type (tp));
sp1->status =
(STATUS) ((sp1->status | SYM_OUTSCOPE) & (STATUS)
~((unsigned) SYM_OUTPUT));
set_level (sp1, GLOBAL_SCOPE);
addsym (sp1, &scope.global->symbols);
rinsertsym (sp1, symbols);
global_flag--;
}
}
break;
case sc_static:
if (!is_symbol_defined (sp)) {
if (is_object_type (tp)) {
if (is_array_type (tp) && is_incomplete_type (tp)) {
tp->size = referenced_type (tp)->size;
}
#ifndef SYNTAX_CORRECT
check_complete (tp);
#endif /* SYNTAX_CORRECT */
#ifdef CPU_DEFINED
if (!is_symbol_output (sp)) {
put_storage (sp); /* tentative definition */
symbol_output (sp);
}
#endif /* CPU_DEFINED */
#ifndef SYNTAX_CORRECT
} else {
if (scope_level == GLOBAL_SCOPE) {
if (is_symbol_used (sp)) {
message (ERR_STATIC, nameof (sp));
} else {
message (WARN_STATIC, nameof (sp));
}
}
#endif /* SYNTAX_CORRECT */
}
}
/*lint -fallthrough */
case sc_auto:
case sc_register:
case sc_parms:
#ifndef SYNTAX_CORRECT
if (tp) {
switch (tp->type) {
case bt_void: /* func(void) definitions */
case bt_ellipsis: /* func(...) definitions */
break;
default:
if (!is_symbol_used (sp)) {
message (WARN_NOTUSED, nameof (sp));
}
}
}
#endif /* SYNTAX_CORRECT */
break;
case sc_typedef:
case sc_tag:
case sc_label:
case sc_member:
case sc_const:
break;
default:
CANNOT_REACH_HERE ();
break;
}
}
#ifdef LIST
summary (block, scope_level);
#endif /* LIST */
VOIDCAST endparamblock ();
}
void beginparamblock P0 (void)
{
beginblock ();
}
BLOCK *endparamblock P0 (void)
{
SYM *sp;
BLOCK *block = scope.local;;
for (sp = symbolsof (block); sp != NIL_SYM; sp = nextsym (sp)) {
deletesym (sp, symbols);
}
for (sp = block->tags.head; sp != NIL_SYM; sp = nextsym (sp)) {
deletesym (sp, tags);
}
scope.local = block->prev;
scope_level--;
return block;
}
void beginfuncblock P1 (const BLOCK *, block)
{
SYM *sp, *sp2;
assert (block != NULL);
beginblock ();
for (sp = symbolsof (block); sp != NIL_SYM; sp = nextsym (sp)) {
sp2 = copy_sym (sp);
addsym (sp2, &scope.local->symbols);
insertsym (sp2, symbols);
}
for (sp = block->tags.head; sp != NIL_SYM; sp = nextsym (sp)) {
sp2 = copy_sym (sp);
addsym (sp2, &scope.local->tags);
insertsym (sp2, tags);
}
}
void endfuncblock P0 (void)
{
endblock ();
}
/*
* There is only one tag table at any scoping level ... therefore although
* structures have a new symbol table for members they share the same tag
* table.
*/
void beginstructblock P1 (BLOCK *, block)
{
if (block) {
block->prev = scope.local;
block->offset = lc_auto;
scope.local = block;
if (scope.global == NIL_BLOCK) {
scope.global = block;
}
scope_level++;
} else {
beginblock ();
}
scope.local->tags = scope.local->prev->tags;
}
BLOCK *endstructblock P0 (void)
{
SYM *sp;
BLOCK *block = scope.local;
for (sp = symbolsof (block); sp != NIL_SYM; sp = nextsym (sp)) {
deletesym (sp, symbols);
}
scope.local = block->prev;
scope.local->tags = block->tags;
scope_level--;
for (sp = symbolsof (block); sp != NIL_SYM; sp = nextsym (sp)) {
if (is_const (sp)) {
SYM *sp2 = copy_sym (sp);
set_level (sp2, scope_level);
sym_append (&sp2);
}
}
block->tags.head = block->tags.tail = NIL_SYM;
for (sp = scope.local->tags.head; sp != NIL_SYM; sp = nextsym (sp)) {
set_level (sp, scope_level);
}
return block;
}
/*
* declare an internal symbol "name" of type "tp".
*/
SYM *internal_symbol P2 (const CHAR *, name, TYP *, tp)
{
SYM *sp = sym_search (name);
if (sp == NIL_SYM) {
tp = mk_type (tp_func, tp);
sp = mk_sym (name, sc_external, tp);
sym_append (&sp);
symbol_used (sp);
}
return sp;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -