⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 symbol.c

📁 一款拥有一定历史的C语言编译器
💻 C
📖 第 1 页 / 共 2 页
字号:

/*
 * C compiler
 * ==========
 *
 * Copyright 1989, 1990, 1991 Christoph van Wuellen.
 * Credits to Matthew Brandt.
 * All commercial rights reserved.
 *
 * This compiler may be redistributed as long there is no
 * commercial interest. The compiler must not be redistributed
 * without its full sources. This notice must stay intact.
 *
 * History:
 *
 * 1989   starting an 68000 C compiler, starting with material
 *        originally by M. Brandt
 * 1990   68000 C compiler further bug fixes
 *        started i386 port (December)
 * 1991   i386 port finished (January)
 *        further corrections in the front end and in the 68000
 *        code generator.
 *        The next port will be a SPARC port
 */

/*****************************************************************************/

#include "chdr.h"
#include "expr.h"
#include "cglbdec.h"
#include "proto.h"
#include "outproto.h"

/********************************************************* Macro Definitions */

#define SMAXKEY	((unsigned)631)

/********************************************************** Type Definitions */

typedef unsigned int KEY;	/* type for hash key */

/********************************************************** Static Variables */

static LEVEL scope_level = (LEVEL) 0;
static struct scopetbl scope;
static SYM *symbols[SMAXKEY];
static SYM *tags[SMAXKEY];

/*********************************************** Static Function Definitions */

static SYM *copy_sym P_ ((const SYM *));
static SYM *findsym P_ ((const CHAR *, SYM *const *));
static SYM *get_label P_ ((const CHAR *));
static SYM *global_search P_ ((SYM *));
static KEY skey P_ ((register const CHAR *));
static void addsym P_ ((SYM *, TABLE *));
static void append P_ ((SYM **, TABLE *, SYM **));
static void check_same P_ ((const SYM *, const SYM *));
static void deletesym P_ ((const SYM *, SYM **));
static void insertsym P_ ((SYM *, SYM **));

/*****************************************************************************/

static void check_same P2 (const SYM *, sp1, const SYM *, sp2)
{
    if ((is_member (sp1) && !is_member (sp2)) || (!is_member (sp1) && is_member (sp2))) {
		return;
    }
#ifndef SYNTAX_CORRECT
    if (!is_equal_type (typeof (sp1), typeof (sp2))) {
		message (ERR_REDECL, nameof (sp1));
    }
#endif /* SYNTAX_CORRECT */
}

SYM    *mk_sym P3 (const CHAR *, name, STORAGE, storage, TYP *, tp)
{
    SYM    *sp;

    sp = (SYM *) xalloc (sizeof (SYM));

    set_nextsym (sp, NIL_SYM);
    set_name (sp, name);
    set_type (sp, tp);
    sp->value.i = 0L;
    set_storage (sp, storage);
    sp->status = (STATUS) 0;
    sp->function_specifier = fs_none;
#ifdef SEQUENCE
    sp->sequence = (SEQNUM) 0;
#endif
    return sp;
}

static SYM *copy_sym P1 (const SYM *, sp)
{
    SYM    *sp2;

    sp2 = (SYM *) xalloc (sizeof (SYM));

    *sp2 = *sp;
    sp2->hnext = NIL_SYM;
    set_nextsym (sp2, NIL_SYM);
    return sp2;
}

static void addsym P2 (SYM *, sp, TABLE *, table)
{
    assert (sp != NIL_SYM);
    if (table->head == NIL_SYM) {
		/* The table is empty so far... */
		table->head = sp;
    } else {
		set_nextsym (table->tail, sp);
    }
    table->tail = sp;
    set_nextsym (sp, NIL_SYM);
}

/* calculate the key for the hash function */
static KEY skey P1 (register const CHAR *, p)
{
    register KEY sum;

    for (sum = (KEY) 0; *p;) {
		sum += (sum << 5) + (KEY) * p++;
    }
    return (sum % SMAXKEY);
}

/* insert a symbol into the specified hash table */
static void insertsym P2 (SYM *, sp, SYM **, hashtab)
{
    KEY     keyno = skey (nameof (sp));

    sp->hnext = hashtab[keyno];
    set_level (sp, scope_level);
    hashtab[keyno] = sp;
}

/* insert a symbol into the specified hash table, at the reverse end */
static void rinsertsym P2 (SYM *, sp, SYM **, hashtab)
{
    KEY     keyno = skey (nameof (sp));
    SYM   **spp = &hashtab[keyno];

    if (*spp) {
		while ((*spp)->hnext) {
			spp = &(*spp)->hnext;
		}
		(*spp)->hnext = sp;
    } else {
		hashtab[keyno] = sp;
    }
}

/* find a symbol in the specified hash table */
static SYM *findsym P2 (const CHAR *, p, SYM *const *, hashtab)
{
    register SYM *sp;

    for (sp = hashtab[skey (p)]; sp; sp = sp->hnext) {
		if (p == nameof (sp)) {
			break;
		}
    }
    return sp;
}

/* delete a symbol from the specified hash table */
static void deletesym P2 (const SYM *, sp, SYM **, hashtab)
{
    SYM   **hsp;

    for (hsp = &hashtab[skey (nameof (sp))]; *hsp; hsp = &(*hsp)->hnext) {
		if (*hsp == sp) {
			*hsp = (*hsp)->hnext;
			return;
		}
    }
}

/* returns true is the symbol is in the current scope, otherwise return false */
BOOL is_local_scope P1 (const SYM *, sp)
{
    return (levelof (sp) >= scope_level);
}

/* searches the current scope/table for the specified symbol */
SYM    *search P2 (const CHAR *, na, const TABLE *, table)
{
    register SYM *sp;

    for (sp = table->head; sp != NIL_SYM; sp = nextsym (sp)) {
		if (nameof (sp) == na) {
			break;
		}
    }
    return sp;
}

/* looks to see if a symbol of this name can be found in the global scope */
static SYM *global_search P1 (SYM *, sp)
{
    SYM    *sp1;

    for (sp1 = sp; sp1 != NIL_SYM; sp1 = sp1->hnext) {
		if ((nameof (sp1) == nameof (sp)) && is_global_scope (sp1)) {
			break;
		}
    }
    return sp1;
}

static void append P3 (SYM **, ptr_sp, TABLE *, scope_tab, SYM **, hashtab)
{
    SYM    *sp1 = NIL_SYM;
    SYM    *sp = *ptr_sp;

    if ((nameof (sp)[0] != (CHAR) 0) && (sp1 = findsym (nameof (sp), hashtab)) != NIL_SYM) {
		if (is_extern (sp) && !is_local_scope (sp1) && !is_symbol_outscope (sp1)) {
			/*ANSI 3.1.2.2
			 * If the declarator of an identifier for an object or a function
			 * contains the storage-class specifier extern, the identifier
			 * has the same linkage as any visible declaration of the
			 * identifier with file scope.  If there is no visible declaration
			 * with file scope, the identifier has external linkage.
			 */
			sp1 = global_search (sp1);
			if (sp1 != NIL_SYM) {
				check_same (sp, sp1);
				set_type (sp, typeof (sp1));
				set_storage (sp, storageof (sp1));
				sp->value = sp1->value;
				sp->status |= sp1->status;
				if (is_static (sp1)) {
					symbol_output (sp);
				}
			}
		}
    }
    if (sp1 != NIL_SYM) {
		if (is_local_scope (sp1)) {
			if (scope_level == GLOBAL_SCOPE) {
				sp1->status &= (STATUS) ~((unsigned) SYM_OUTSCOPE);
			}
			check_same (sp, sp1);
			set_type (sp1, composite_type (typeof (sp1), typeof (sp)));
			if (is_func (typeof (sp))) {
				sp1->status |= sp->status;
				if (is_global (sp)) {
					typeof (sp1)->state &= (STATE) (~(unsigned) STATE_ANSI);
					if (is_ansi (typeof (sp))) {
						set_ansi (typeof (sp1));
					}
				}
			}
			/*
			 * The new storage class depends on the old and on the new one.
			 */
			if (storageof (sp) == storageof (sp1)) {
#ifndef SYNTAX_CORRECT
				switch (storageof (sp)) {
					case sc_const:
					case sc_auto:
						message (ERR_REDECL, nameof (sp));
						break;
					case sc_typedef:
						if (is_equal_type (typeof (sp), typeof (sp1))) {
							message (WARN_REDECL, nameof (sp));
						} else {
							message (ERR_REDECL, nameof (sp));
						}
						break;
#ifdef FACIST
					case sc_external:
						message (WARN_DUPDECL, nameof (sp));
						break;
#endif /* FACIST */
					default:
						break;
				}
#endif /* SYNTAX_CORRECT */
				if (!is_symbol_outscope (sp1)) {
					*ptr_sp = sp1;	/* caller uses old entry */
					return;
				}
			}
			switch (storageof (sp)) {
				case sc_const:
				case sc_typedef:
#ifndef SYNTAX_CORRECT
					message (ERR_REDECL, nameof (sp));
#endif /* SYNTAX_CORRECT */
					*ptr_sp = sp1;	/* caller uses old entry */
					return;

				case sc_external:
					if (scope_level == GLOBAL_SCOPE) {
						sp1->status &= (STATUS) ~((unsigned) SYM_OUTSCOPE);
					}
					if (!is_symbol_outscope (sp1)) {
						*ptr_sp = sp1;	/* caller uses old entry */
						return;
					}
					break;

				case sc_global:
#ifndef SYNTAX_CORRECT
					switch (storageof (sp1)) {
						case sc_typedef:
						case sc_const:
							message (ERR_REDECL, nameof (sp));
							return;
						case sc_static:
							if ((lang_option == LANG_KANDR) || !is_func (typeof (sp))) {
								message (ERR_REDECL, nameof (sp));
							} else if (is_func (typeof (sp))) {
								message (WARN_GLOBAL, nameof (sp));
							}
							break;
						default:
							break;
					}
#endif /* SYNTAX_CORRECT */
					set_storage (sp1, sc_global);
					*ptr_sp = sp1;	/* caller uses old entry */
					return;

				case sc_static:
#ifndef SYNTAX_CORRECT
					switch (storageof (sp1)) {
						case sc_typedef:
						case sc_const:
						case sc_global:
							message (ERR_REDECL, nameof (sp));
							return;
						case sc_external:
							if (is_object_type (typeof (sp))) {
								message (ERR_LINKAGE, nameof (sp));
							} else {
								message (WARN_EXTERN, nameof (sp));
							}
							break;
						default:
							break;
					}
#endif /* SYNTAX_CORRECT */
					set_storage (sp1, sc_static);
					*ptr_sp = sp1;	/* caller uses old entry */
					return;

				default:
#ifndef SYNTAX_CORRECT
					if (is_typedef (sp1)) {
						message (ERR_REDECL, nameof (sp));
					}
#endif /* SYNTAX_CORRECT */
					*ptr_sp = sp1;	/* caller uses old entry */
					return;
			}
#ifndef SYNTAX_CORRECT
		} else {
			if (!is_member (sp)) {
				switch (storageof (sp1)) {
					case sc_external:
					case sc_static:
						if (!is_extern (sp) && !is_static (sp)) {
							message (WARN_HIDE, nameof (sp));
						}
						break;
					case sc_global:
						if (!is_global (sp)) {
							if (!is_function_type (typeof (sp))) {
								message (WARN_HIDE, nameof (sp));
							}
						}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -