📄 decl.cc
字号:
p->sclass = sclass; p->src = *pos; p->type = ty; if (ty != NULL) p->defined = 1; if (t == '=') { error("illegal initialization for parameter `%s'\n", id); t = gettok(); genop ignored = expr1(0); ignored.deallocate(); } return p; }/* dclr - declarator */static type_node *dclr(type_node *basety, char **id, int lev) { type_node *ty = dclr1(id, lev); while (ty != voidtype) { assert(ty != NULL); switch (ty->op()) { case TYPE_PTR: { ptr_type *the_ptr_type = (ptr_type *)ty; assert(the_ptr_type->parent() == NULL); ty = the_ptr_type->ref_type(); the_ptr_type->set_ref_type(basety); basety = basety->parent()->install_type(the_ptr_type); break; } case TYPE_FUNC: { func_type *the_func_type = (func_type *)ty; assert(the_func_type->parent() == NULL); ty = the_func_type->return_type(); the_func_type->set_return_type(basety); base_symtab *target_symtab = basety->parent(); unsigned num_args = the_func_type->num_args(); for (unsigned arg_num = 0; arg_num < num_args; ++arg_num) { base_symtab *this_scope = the_func_type->arg_type(arg_num)->parent(); target_symtab = joint_symtab(target_symtab, this_scope); assert(target_symtab != NULL); } basety = target_symtab->install_type(the_func_type); break; } case TYPE_ARRAY: { array_type *the_array_type = (array_type *)ty; assert(the_array_type->parent() == NULL); ty = the_array_type->elem_type(); the_array_type->set_elem_type(basety); basety = basety->parent()->install_type(the_array_type); break; } case TYPE_CONST: case TYPE_VOLATILE: { modifier_type *the_mod_type = (modifier_type *)ty; assert(the_mod_type->parent() == NULL); ty = the_mod_type->base(); the_mod_type->set_base(basety); basety = basety->parent()->install_type(the_mod_type); break; } default: assert(FALSE); } } if ((Aflag >= 2) && (basety->size() > 32767)) warning("more than 32767 bytes in `%t'\n", basety); return basety; }/* dclr1 - ( id | * ( const | volatile )* | '(' dclr1 ')' ) ( (...) | [...] )**/static type_node *dclr1(char **id, int lev) { type_node *ty = voidtype; switch (t) { case ID: if (id != NULL) *id = token; else error("extraneous identifier `%s'\n", token); t = gettok(); break; case '*': t = gettok(); if ((t == CONST) || (t == VOLATILE)) { modifier_type *ty1; if (t == CONST) ty1 = new modifier_type(TYPE_CONST, voidtype); else ty1 = new modifier_type(TYPE_VOLATILE, voidtype); ty = ty1; while (((t = gettok()) == CONST) || (t == VOLATILE)) { if (t == CONST) ty = new modifier_type(TYPE_CONST, ty); else ty = new modifier_type(TYPE_VOLATILE, ty); } ty1->set_base(dclr1(id, lev)); } else { ty = dclr1(id, lev); } ty = new ptr_type(ty); break; case '(': t = gettok(); if ((kind[t] == CHAR) || ((t == ID) && (tsym != NULL) && (tsym->sclass == TYPEDEF))) { type_node **params = parameters(lev); ty = create_function_type(ty, params); foreach(identifiers, level, checkparam, NULL); exitscope(); } else { ty = dclr1(id, lev); expect(')'); if ((ty == voidtype) && (id == NULL)) return create_function_type(ty, NULL); } break; case '[': break; default: return ty; } while ((t == '(') || (t == '[')) { if (t == '(') { t = gettok(); type_node **params = parameters(lev); ty = create_function_type(ty, params); if ((lev == 0) && (!funcdclr)) { funcdclr = TRUE; } else { foreach(identifiers, level, checkparam, NULL); exitscope(); } } else { t = gettok(); array_type *the_array = new array_type(ty, array_bound(0)); if (kind[t] == ID) { i_integer n = intexpr(']', 1); if (n <= 0) { error("`%D' is an illegal array size\n", &n); n = 1; } n -= 1; if (!n.is_c_int()) { n += 1; error("`%D' is too big an array size\n", &n); n = 0; } the_array->set_upper_bound(array_bound(n.c_int())); } else { expect(']'); the_array->set_upper_bound(unknown_bound); } ty = the_array; } } return ty; }/* decl - type [ dclr ( , dclr )* ] ; */static void decl(Symbol (*dcl)(int, char *, type_node *, Coordinate *), boolean eflag) { int sclass; char *id = NULL; type_node *ty1; Coordinate pt; static char follow[] = { CHAR, STATIC, ID, 0 }; pt = src; type_node *ty = parse_type(level, &sclass); if ((t == ID) || (t == '*') || (t == '(') || (t == '[')) { Coordinate pos; pos = src; funcdclr = FALSE; if (level == GLOBAL) { ty1 = dclr(ty, &id, 0); if (funcdclr && (id != NULL) && isfunc(ty1) && ((t == '{') || (kind[t] == CHAR) || ((kind[t] == STATIC) && (t != TYPEDEF)) || ((t == ID) && (tsym != NULL) && (tsym->sclass == TYPEDEF)))) { if (sclass == TYPEDEF) { error("invalid use of `typedef'\n"); sclass = EXTERN; } fname = id; funcdecl(sclass, fname, (func_type *)ty1, pt); fname = NULL; return; } else if (funcdclr) { foreach(identifiers, level, checkparam, NULL); exitscope(); } } else { ty1 = dclr(ty, &id, 1); } for (;;) { if ((Aflag >= 1) && !hasproto(ty1)) warning("missing prototype\n"); if (id == NULL) error("missing identifier\n"); else if (sclass == TYPEDEF) (void)deftype(id, ty1, &pos); else (*dcl)(sclass, id, ty1, &pos); if (t != ',') break; t = gettok(); id = NULL; pos = src; ty1 = dclr(ty, &id, 1); } } else if ((ty != NULL) && eflag) { error("empty declaration\n"); } else if ((ty != NULL) && (sclass || (!isstruct_or_union(ty) && !isenum(ty)))) { warning("empty declaration\n"); } test(';', follow); }/* doextern - import external declared in a block, if necessary, propagate flags */static void doextern(Symbol p, Generic) { Symbol q = lookup(p->name, identifiers); if (q != NULL) q->ref += p->ref; else defsymbol(p); }/* doglobal - finalize tentative definitions, check for imported symbols */static void doglobal(Symbol p, Generic) { if ((p->sclass == TYPEDEF) || (p->sclass == ENUM) || p->defined) { /* re-define symbols to catch types that have been completed */ if ((p->sclass == AUTO) || (p->sclass == STATIC)) defsymbol(p); if (Pflag && !isfunc(p->type)) printdecl(p, p->type); return; } if ((p->sclass != EXTERN) && !isfunc(p->type)) { if (p->type->size() > 0) (void)defglobal(p); else error("undefined size for `%t %s'\n", p->type, p->name); p->defined = 1; if (Pflag) printdecl(p, p->type); } }/* enumdecl - enum [ id ] [ { id [ = cexpr ] ( , id [ = cexpr ] )* } ] */static enum_type *enumdecl(void) { char *tag; enum_type *result; Symbol p; Coordinate pos; t = gettok(); if (t == ID) { tag = token; pos = src; t = gettok(); } else { tag = string(""); } if (t == '{') { static char follow[] = { IF, 0 }; int n = 0, min, max, k = -1; boolean found_one = FALSE; Symbol enum_sym = newstruct(ENUM, tag); assert(enum_sym->type->is_enum()); result = (enum_type *)(enum_sym->type); t = gettok(); if (t != ID) error("expecting an enumerator identifier\n"); while (t == ID) { char *id = token; Coordinate s; if ((tsym != NULL) && (tsym->scope == level)) { error("redeclaration of `%s' previously declared at %w\n", token, &tsym->src); } s = src; t = gettok(); if (t == '=') { t = gettok(); i_integer ii_k = intexpr(0, 0); if (!ii_k.is_c_int()) { error("`%D' is too big for an enumeration constant" " value\n", &ii_k); ii_k = 0; } k = ii_k.c_int(); } else { if (k == INT_MAX) { error("overflow in value for enumeration constant `%s'\n", p->name); } k++; } if (found_one) { if (k < min) min = k; if (k > max) max = k; } else { min = max = k; found_one = TRUE; } p = install(id, &identifiers, level < LOCAL); p->src = s; p->type = result; p->sclass = ENUM; p->u.enum_value = k; result->set_num_values(n + 1); result->set_value(n, k); result->set_member(n, id); n++; if ((Aflag >= 2) && (n == 128)) { warning("more than 127 enumeration constants in `%t'\n", result); } if (t != ',') break; t = gettok(); if (t == '}') warning("non-ANSI trailing comma in enumerator list\n"); } test('}', follow); if (option_force_enum_is_int) { result->set_signed(TRUE); result->set_size(inttype->size()); } else if (immed_fits(immed(min), unsignedchar) && immed_fits(immed(max), unsignedchar)) { result->set_signed(FALSE); result->set_size(unsignedchar->size()); } else if (immed_fits(immed(min), signedchar) && immed_fits(immed(max), signedchar)) { result->set_signed(TRUE); result->set_size(signedchar->size()); } else if (immed_fits(immed(min), unsignedshort) && immed_fits(immed(max), unsignedshort)) { result->set_signed(FALSE); result->set_size(unsignedshort->size()); } else if (immed_fits(immed(min), shorttype) && immed_fits(immed(max), shorttype)) { result->set_signed(TRUE); result->set_size(shorttype->size()); } else { result->set_signed(TRUE); result->set_size(inttype->size()); } enum_sym->defined = 1; } else if ((p = lookup(tag, types)) && (p->type->op() == TYPE_ENUM)) { if ((*tag != 0) && xref) use(p, pos); assert(p->type->is_enum()); result = (enum_type *)(p->type); } else { error("unknown enumeration `%s'\n", tag); Symbol enum_sym = newstruct(ENUM, tag); assert(enum_sym->type->is_enum()); result = (enum_type *)(enum_sym->type); result->set_signed(TRUE); result->set_size(inttype->size()); } return result; }/* fields - ( type dclr ( , dclr )* ; )* */static void fields(struct_type *to_fill) { int n = 0, bits, off, overflow = 0; Field p; struct field *field_list = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -