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

📄 decl.cc

📁 c到DHL的转换工具
💻 CC
📖 第 1 页 / 共 4 页
字号:
/* file "decl.cc" *//*  Copyright (c) 1994 Stanford University    All rights reserved.    This software is provided under the terms described in    the "suif_copyright.h" include file. */#include <suif_copyright.h>/* snoot declaration parsing */#include "c.h"Symbol cfunc = NULL;            /* current function */char *fname = NULL;             /* current function name */static boolean funcdclr;        /* declarator has parameters */static int nglobals;            /* number of external ids */static void checklab(Symbol p, Generic);static void checkparam(Symbol p, Generic);static void checkref(Symbol p, Generic);static Symbol dclglobal(int sclass, char *id, type_node *ty, Coordinate *pos);static Symbol dcllocal(int sclass, char *id, type_node *ty, Coordinate *pos);static Symbol dclparam(int sclass, char *id, type_node *ty, Coordinate *pos);static type_node *dclr(type_node *basety, char **id, int lev);static type_node *dclr1(char **id, int lev);static void decl(Symbol (*dcl)(int, char *, type_node *, Coordinate *),                 boolean eflag);static void doglobal(Symbol p, Generic);static void doextern(Symbol p, Generic);static enum_type *enumdecl(void);static void fields(struct_type *to_fill);static void funcdecl(int sclass, char *id, func_type *ftype, Coordinate pt);static func_type *newstyle(func_type *ty, type_node *caller_types[],                           Symbol callee[]);static void oldparam(Symbol p, Generic cl);static func_type *oldstyle(char *name, func_type *ty,                           type_node *caller_types[], Symbol callee[]);static type_node **parameters(int lev);static struct_type *structdcl(int op);static type_node *parse_type(int lev, int *sclass);static boolean control_reaches_list_end(tree_node_list *node_list);/* checklab - check for undefined labels; called at ends of functions */static void checklab(Symbol p, Generic)  {    if (!p->defined)        error("undefined label `%s'\n", p->name);    p->defined = 1;  }/* checkref - check for unreferenced variables; called at ends of blocks */static void checkref(Symbol p, Generic)  {    if ((Aflag >= 2) && p->defined && (p->ref == 0))      {        if (p->sclass == STATIC)            warning("static `%t %s' is not referenced\n", p->type, p->name);        else if (p->scope == PARAM)            warning("parameter `%t %s' is not referenced\n", p->type, p->name);        else if ((p->scope > PARAM) && (p->sclass != EXTERN))            warning("local `%t %s' is not referenced\n", p->type, p->name);      }    Symbol q;    if ((p->scope > PARAM) && (q = lookup(p->name, externals)))      {        q->ref += p->ref;      }    else if ((p->sclass == STATIC) && !p->defined)      {        if (p->ref > 0)          {            error("undefined static `%t %s'\n", p->type, p->name);          }        else if (isfunc(p->type))          {            warning("undefined static `%t %s'\n", p->type, p->name);            /*             *  In SUIF it is illegal to have a procedure in the file symbol             *  table without a body, so we must remove this symbol.             */            sym_node *the_symbol = p->suif_symbol;            assert(the_symbol != NULL);            the_symbol->parent()->remove_sym(the_symbol);            delete the_symbol;            p->suif_symbol = NULL;          }      }    if (xref)        annotate_with_refs(p);  }/* compound - { ( decl ; )* statement* } */void compound(label_sym *continue_lab, label_sym *break_lab,              struct swtch *swp, int lev)  {    enterscope();    ++bnumber;    stabblock('{');    expect('{');    while ((kind[t] == CHAR) || (kind[t] == STATIC) ||           ((t == ID) && (tsym != NULL) && (tsym->sclass == TYPEDEF) &&            ((level < LOCAL) || (getchr() != ':'))))      {        decl(dcllocal, FALSE);      }    while ((kind[t] == IF) || (kind[t] == ID))        statement(continue_lab, break_lab, swp, lev);    foreach(identifiers, level, checkref, NULL);    stabblock('}');    if (level > LOCAL)      {        exitscope();        expect('}');      }  }/* dclglobal - called from decl to declare a global */static Symbol dclglobal(int sclass, char *id, type_node *ty, Coordinate *pos)  {    if ((sclass == 0) || (sclass == REGISTER))        sclass = AUTO;    Symbol p = lookup(id, identifiers);    if ((p != NULL) && (p->scope == GLOBAL))      {        if ((p->sclass != TYPEDEF) && eqtype(ty, p->type, TRUE))          {            ty = composite(ty, p->type);          }        else          {            error("redeclaration of `%s' previously declared at %w\n",                  p->name, &p->src);          }        if (!isfunc(ty) && p->defined && (t == '='))          {            error("redefinition of `%s' previously defined at %w\n", p->name,                  &p->src);          }        if (((p->sclass == STATIC) && (sclass == AUTO)) ||            ((p->sclass != STATIC) && (sclass == STATIC)))          {            warning("inconsistent linkage for `%s' previously declared at"                    " %w\n", p->name, &p->src);          }      }    else if ((sclass == STATIC) && !isfunc(ty) && (ty->size() == 0) &&             (t != '='))      {        warning("undefined size for static `%t %s'\n", ty, id);      }    if ((p == NULL) || (p->scope != GLOBAL))        p = install(id, &globals, 1);    p->type = ty;    Symbol q = lookup(p->name, externals);    if (q != NULL)      {        p->ref += q->ref;        p->suif_symbol = q->suif_symbol;      }    if (p->suif_symbol != NULL)      {        if (isfunc(ty))          {            assert(p->suif_symbol->is_proc());            func_type *the_func_type = (func_type *)(ty->unqual());            proc_sym *the_proc = (proc_sym *)(p->suif_symbol);            boolean vis = the_proc->parent()->make_type_visible(the_func_type);            assert(vis);            the_proc->set_type(the_func_type);          }        else          {            assert(p->suif_symbol->is_var());            var_sym *the_var = (var_sym *)(p->suif_symbol);            boolean vis = the_var->parent()->make_type_visible(p->type);            assert(vis);            the_var->set_type(p->type);          }      }    if ((p->sclass == 0) || ((sclass != EXTERN) && (p->sclass != STATIC)))      {        p->sclass = sclass;      }    if (p->sclass != STATIC)      {        nglobals++;        if ((Aflag >= 2) && (nglobals == 512))            warning("more than 511 external identifiers\n");      }    p->src = *pos;    if ((!p->defined) && (p->suif_symbol == NULL))        defsymbol(p);    if (q != NULL)      {        if ((((p->sclass == AUTO) ? (unsigned char)EXTERN : p->sclass) !=             q->sclass) || !eqtype(p->type, q->type, TRUE))          {            warning("declaration of `%s' does not match previous declaration"                    " at %w\n", p->name, &q->src);          }      }    if (!isfunc(p->type))      {        initglobal(p, FALSE);      }    else if (t == '=')      {        error("illegal initialization for `%s'\n", p->name);        t = gettok();        initializer(NULL, p->type, 0);      }    return p;  }/* dcllocal - called from decl to declare a local */static Symbol dcllocal(int sclass, char *id, type_node *ty, Coordinate *pos)  {    if (isfunc(ty))      {        if ((sclass != 0) && (sclass != EXTERN))            error("invalid storage class `%k' for `%t %s'\n", sclass, ty, id);        sclass = EXTERN;      }    else if (sclass == 0)      {        sclass = AUTO;      }    if ((sclass == REGISTER) &&        (isvolatile(ty) || isstruct_or_union(ty) || isarray(ty)))      {        warning("register declaration ignored for `%t %s'\n", ty, id);        sclass = AUTO;      }    Symbol q = lookup(id, identifiers);    if ((q != NULL) &&        ((q->scope >= level) || ((q->scope == PARAM) && (level == PARAM+1))))      {        if ((sclass == EXTERN) && (q->sclass == EXTERN) &&            eqtype(q->type, ty, TRUE))          {            ty = composite(ty, q->type);          }        else          {            error("redeclaration of `%s' previously declared at %w\n",                  q->name, &q->src);          }      }    assert(level >= LOCAL);    Symbol p = install(id, &identifiers, 0);    p->type = ty;    p->sclass = sclass;    p->src = *pos;    switch (sclass)      {        case EXTERN:          {            if ((q != NULL) && (q->scope == GLOBAL) && (q->sclass == STATIC))              {                p->sclass = STATIC;                p->scope = level;              }            defsymbol(p);            Symbol r = lookup(id, externals);            if (r == NULL)              {                r = install(p->name, &externals, 1);                r->src = p->src;                r->type = p->type;                r->sclass = p->sclass;                r->suif_symbol = p->suif_symbol;                q = lookup(id, globals);                if ((q != NULL) && (q->sclass != TYPEDEF) &&                    (q->sclass != ENUM))                  {                    r = q;                  }              }            if ((r != NULL) &&                ((((r->sclass == AUTO) ? (unsigned char)EXTERN : r->sclass) !=                  p->sclass) || !eqtype(r->type, p->type, TRUE)))              {                warning("declaration of `%s' does not match previous "                        "declaration at %w\n", r->name, &r->src);              }            break;          }        case STATIC:            defsymbol(p);            initglobal(p, FALSE);            if (!p->defined)              {                if (p->type->size() > 0)                    (void)defglobal(p);                else                    error("undefined size for `%t %s'\n", p->type, p->name);              }            p->defined = 1;            break;        case REGISTER:        case AUTO:          {            var_sym *the_var_sym =                    get_current_symtab()->new_var(p->type, p->name);            if (sclass == REGISTER)                the_var_sym->append_annote(k_is_declared_reg, new immed_list);            the_var_sym->set_userdef();            p->suif_symbol = the_var_sym;            p->defined = 1;            break;          }        default:            assert(FALSE);      }    if (t == '=')      {        if (sclass == EXTERN)            error("illegal initialization of `extern %s'\n", id);        t = gettok();        definept(NULL);        genop e;        if (isscalar(p->type) || (isstruct_or_union(p->type) && (t != '{')))          {            if (t == '{')              {                t = gettok();                e = constexpr(0);                (void)genconst(NULL, e, FALSE);                expect('}');              }            else              {                e = expr1(0);              }            e = pointer(e);            type_node *new_type = assign(p->type, e);            if (new_type != NULL)              {                e = cast(e, new_type);              }            else              {                error("invalid initialization type; found `%t' expected "                      "`%t'\n", e.type(), p->type);              }          }        else          {            type_node *ty = p->type;            boolean constified = FALSE;            if (!isconst(ty) &&                (!isarray(ty) || !isconst(base_from_array(ty))))              {                ty = qual(CONST, ty);                constified = TRUE;              }            var_sym *new_var = gen_static_global(ty);            var_def *the_def = begin_initialization(new_var);            ty = initializer(the_def, new_var->type(), 0);            if (isarray(new_var->type()) && new_var->type()->size() == 0)                new_var->set_type(ty);            if (isarray(p->type) && (p->type->size() == 0) &&                (new_var->type()->size() > 0))              {                int new_size =                        new_var->type()->size() /                        base_from_array(new_var->type())->size();                assert(p->suif_symbol != NULL);                assert(p->suif_symbol->is_var());                var_sym *p_var = (var_sym *)(p->suif_symbol);                p_var->set_type(build_array(base_from_array(p->type),                                            new_size));                p->type = p_var->type();              }            /* If it's an array and we changed the type to be an array             * of constant elements, we can't do a simple copy because             * the types will conflict, so we do an explicit load in             * that case. */            if (isarray(ty) && constified)              {                operand address_op =                        operand(new in_ldc(ty->ptr_to(), operand(),                                           immed(new_var)));                operand convert_op =                        operand(new in_rrr(io_cvt, p->type->ptr_to(),                                           operand(), address_op));                in_rrr *new_load =                        new in_rrr(io_lod, p->type, operand(), convert_op);                e = genop(operand(new_load), new tree_node_list);              }            else              {                e = sym_node_to_genop(new_var);              }          }        e.clean_up_bit_field_refs();        tree_node_list *precomputation = e.precomputation();        operand r_op = e.suif_operand();        curr_list->append(precomputation);        delete precomputation;        assert(p->suif_symbol->is_var());        tree_node *new_assignment =                create_assignment(((var_sym *)p->suif_symbol), r_op);        curr_list->append(new_assignment);        p->initialized = 1;        p->ref = 0;      }    if (!isfunc(p->type) && p->defined && (p->type->size() <= 0))        error("undefined size for `%t %s'\n", p->type, id);    return p;  }/* dclparam - called from decl to declare a parameter */static Symbol dclparam(int sclass, char *id, type_node *ty, Coordinate *pos)  {    Symbol p = lookup(id, identifiers);    if ((p != NULL) && (p->scope == level) &&        (p->defined || ((p->type == NULL) && (ty == NULL))))      {        error("duplicate definition for `%s' previously declared at %w\n", id,              &p->src);      }    else if ((p == NULL) || (p->scope < level))      {        p = install(id, &identifiers, 0);      }    if ((ty != NULL) && isfunc(ty))        ty = ty->ptr_to();    else if ((ty != NULL) && isarray(ty))        ty = atop(ty);    if (sclass == 0)        sclass = AUTO;    if ((sclass == REGISTER) && (ty != NULL) &&        (isvolatile(ty) || isstruct_or_union(ty)))      {        warning("register declaration ignored for `%t%s\n", ty,                stringf(id ? (char *) " %s'" : (char *) "' parameter", id));        sclass = AUTO;      }

⌨️ 快捷键说明

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