📄 decl.cc
字号:
while ((kind[t] == CHAR) || ((t == ID) && (tsym != NULL) && (tsym->sclass == TYPEDEF))) { static char follow[] = { IF, CHAR, '}', 0 }; type_node *ty1 = parse_type(0, NULL); do { char *id = NULL; type_node *fty; fty = dclr(ty1, &id, 1); if (fty == NULL) fty = ty1; if ((Aflag >= 1) && !hasproto(fty)) warning("missing prototype\n"); p = newfield(id, &field_list, fty, to_fill); if (t == ':') { fty = fty->unqual(); if (isenum(fty)) fty = base_from_enum(fty); if ((fty != inttype) && (fty != unsignedtype)) { error("`%t' is an illegal bit field type\n", p->type); p->type = inttype; } t = gettok(); i_integer p_to = intexpr(0, 0); if ((p_to > inttype->size()) || (p_to < 0)) { error("`%D' is an illegal bit field size\n", &p_to); p_to = inttype->size(); } else if ((p_to == 0) && (id != NULL)) { warning("extraneous 0-width bit field `%t %s' ignored\n", p->type, id); p->name = gen_internal_name(); } p->to = p_to.c_int() + 1; } else if ((id == NULL) && isstruct_or_union(p->type)) { error("unnamed substructure in `%t'\n", to_fill); p->name = NULL; break; } else { if (id == NULL) error("field name missing\n"); else if (p->type->size() == 0) error("undefined size for field `%t %s'\n", p->type, id); } n++; if ((Aflag >= 2) && (n == 128)) warning("more than 127 fields in `%t'\n", to_fill); } while ((t == ',') && (t = gettok())); test(';', follow); } short resulting_alignment = target.struct_align; off = bits = 0;#define add(x,n) (x > INT_MAX - (n) ? (overflow = 1, x) : x + n) struct field *deferred = NULL; for (p = field_list; p != NULL;) { int a = (get_alignment(p->type) ? get_alignment(p->type) : target.addressable_size); if (to_fill->op() == TYPE_UNION) { if (p->to) a = get_alignment(unsignedtype); bits = 0; } else if ((bits == 0) || (p->to <= 1) || (bits - 1 + p->to - 1 > unsignedtype->size())) { if (bits != 0) off = add(off, unsignedtype->size()); if (p->to) a = get_alignment(unsignedtype); add(off, a - 1); off = roundup(off, a); bits = 0; } if (a > resulting_alignment) resulting_alignment = a; p->offset = off; if (p->to) { if (bits == 0) bits = 1; p->from = bits - 1; p->to = p->from + p->to - 1; bits += p->to - p->from; if ((to_fill->op() == TYPE_UNION) && (((bits + target.addressable_size - 2) / target.addressable_size) * target.addressable_size > to_fill->size())) { to_fill->set_size(((bits + target.addressable_size - 2) / target.addressable_size) * target.addressable_size); } } else if (to_fill->op() == TYPE_STRUCT) { off = add(off, p->type->size()); } else if (p->type->size() > to_fill->size()) { to_fill->set_size(p->type->size()); } field_list = p->link; if ((deferred != NULL) && (p->from < deferred->to)) { immed_list *descriptor = new immed_list; short def_offset = deferred->offset; char *name = new char[1]; name[0] = 0; boolean has_constant = FALSE; boolean has_volatile = FALSE; while (deferred != p) { assert(deferred->offset == def_offset); if ((deferred->name == 0) || (*deferred->name > '9') || (*deferred->name < '0')) { if (deferred->type->is_volatile()) { has_volatile = TRUE; descriptor->append(immed("volatile")); } if (deferred->type->is_const()) { has_constant = TRUE; descriptor->append(immed("const")); } deferred->type = deferred->type->unqual(); if (deferred->type == inttype) descriptor->append(immed("int")); else if (deferred->type == unsignedtype) descriptor->append(immed("unsigned")); else assert(FALSE); descriptor->append(immed(deferred->name)); descriptor->append(immed(deferred->from)); descriptor->append(immed(deferred->to)); char *new_name = new char[strlen(name) + strlen(deferred->name) + 2]; strcpy(new_name, name); strcat(new_name, "_"); strcat(new_name, deferred->name); delete[] name; name = new_name; } struct field *next_field = deferred->link; delete deferred; deferred = next_field; } deferred = NULL; if (*name != 0) { type_node *field_type = unsignedtype->copy(); field_type->append_annote(k_bit_field_info, descriptor); field_type = to_fill->parent()->install_type(field_type); if (has_volatile) field_type = qual(VOLATILE, field_type); if (has_constant) field_type = qual(CONST, field_type); unsigned next_field = to_fill->num_fields(); to_fill->set_num_fields(next_field + 1); to_fill->set_field_type(next_field, field_type); to_fill->set_field_name(next_field, name); to_fill->set_offset(next_field, def_offset); } else { delete descriptor; } delete[] name; } if (p->to != 0) { if (deferred == NULL) deferred = p; assert(deferred->offset == p->offset); } else { assert(deferred == NULL); if ((p->name == 0) || (*p->name > '9') || (*p->name < '0')) { unsigned next_field = to_fill->num_fields(); to_fill->set_num_fields(next_field + 1); to_fill->set_field_type(next_field, p->type); to_fill->set_field_name(next_field, p->name); to_fill->set_offset(next_field, p->offset); } delete p; } p = field_list; } if (deferred != NULL) { immed_list *descriptor = new immed_list; short def_offset = deferred->offset; char *name = new char[1]; name[0] = 0; boolean has_constant = FALSE; boolean has_volatile = FALSE; while (deferred != NULL) { assert(deferred->offset == def_offset); if ((deferred->name == 0) || (*deferred->name > '9') || (*deferred->name < '0')) { if (deferred->type->is_volatile()) { has_volatile = TRUE; descriptor->append(immed("volatile")); } if (deferred->type->is_const()) { has_constant = TRUE; descriptor->append(immed("const")); } deferred->type = deferred->type->unqual(); if (deferred->type == inttype) descriptor->append(immed("int")); else if (deferred->type == unsignedtype) descriptor->append(immed("unsigned")); else assert(FALSE); descriptor->append(immed(deferred->name)); descriptor->append(immed(deferred->from)); descriptor->append(immed(deferred->to)); char *new_name = new char[strlen(name) + strlen(deferred->name) + 2]; strcpy(new_name, name); strcat(new_name, "_"); strcat(new_name, deferred->name); delete[] name; name = new_name; } struct field *next_field = deferred->link; delete deferred; deferred = next_field; } if (*name != 0) { type_node *field_type = unsignedtype->copy(); field_type->append_annote(k_bit_field_info, descriptor); field_type = to_fill->parent()->install_type(field_type); if (has_volatile) field_type = qual(VOLATILE, field_type); if (has_constant) field_type = qual(CONST, field_type); unsigned next_field = to_fill->num_fields(); to_fill->set_num_fields(next_field + 1); to_fill->set_field_type(next_field, field_type); to_fill->set_field_name(next_field, name); to_fill->set_offset(next_field, def_offset); } else { delete descriptor; } delete[] name; } if (bits) off = add(off, ((bits + target.addressable_size - 2) / target.addressable_size) * target.addressable_size); if (to_fill->op() == TYPE_STRUCT) to_fill->set_size(off); else if (off > to_fill->size()) to_fill->set_size(off); add(to_fill->size(), resulting_alignment - 1); to_fill->set_size(roundup(to_fill->size(), resulting_alignment)); if (overflow) { error("size of `%t' exceeds %d bytes\n", to_fill, INT_MAX); to_fill->set_size(INT_MAX & (~(resulting_alignment - 1))); } }/* finalize - finalize tentative definitions, constants, check unref'd statics */void finalize(void) { if (xref) { setuses(identifiers); foreach(types, level, fielduses, NULL); setuses(types); } foreach(identifiers, GLOBAL, doglobal, NULL); foreach(externals, GLOBAL, doextern, NULL); foreach(identifiers, GLOBAL, checkref, NULL); }static void fillcallees(Symbol p, Generic cl);static void fillcallees(Symbol p, Generic cl) { *(List *)cl = append(p, *(List *)cl); }/* funcdecl - ... ( ... ) decl* compound */static void funcdecl(int sclass, char *id, func_type *ftype, Coordinate pt) { int i, n; Symbol *callee, p; type_node **caller_types; List callee_list = NULL; if (isstruct_or_union(freturn(ftype)) && (freturn(ftype)->size() == 0)) error("illegal use of incomplete type `%t'\n", freturn(ftype)); callee_list = NULL; foreach(identifiers, PARAM, fillcallees, (Generic)&callee_list); n = length(callee_list); if ((Aflag >= 2) && (n > 31)) warning("more than 31 parameters in function `%s'\n", id); callee = (Symbol *)ltoa(callee_list, NULL); caller_types = new type_node *[n]; for (i = 0; (p = callee[i]) != NULL; i++) { if (*(p->name) >= '1' && *(p->name) <= '9') error("missing parameter name to function `%s'\n", id); } callee[i] = NULL; if (ftype->args_known()) ftype = newstyle(ftype, caller_types, callee); else ftype = oldstyle(id, ftype, caller_types, callee); if ((Aflag >= 1) && !hasproto(ftype)) warning("missing prototype\n"); for (i = 0; (p = callee[i]) != NULL; i++) { if (p->type->size() == 0) { error("undefined size for parameter `%t %s'\n", p->type, p->name); caller_types[i] = p->type = inttype; } } p = lookup(id, identifiers); if ((p != NULL) && isfunc(p->type)) { if (p->defined) { error("redefinition of `%s' previously defined at %w\n", p->name, &p->src); } if (xref) use(p, p->src); } cfunc = dclglobal(sclass, id, ftype, &pt); cfunc->u.f.pt[0] = pt; cfunc->u.f.null_return = NULL; cfunc->defined = 1; if (Pflag) printproto(cfunc, callee); labels[0] = table(NULL, LABELS); labels[1] = table(NULL, LABELS); refinc = 1000; bnumber = -1; cfunc->u.f.pt[2] = *(definept(NULL)); start_function(cfunc, callee, caller_types, n, &(cfunc->u.f.pt[2])); delete[] caller_types; compound(NULL, NULL, NULL, 0); assert(curr_proc != NULL); tree_block *current_block = curr_proc->block(); assert(current_block != NULL); if (control_reaches_list_end(current_block->body())) { definept(NULL); return_nothing(); } exitscope(); foreach(identifiers, level, checkref, NULL); function(); outflush(); cfunc->u.f.pt[1] = src; expect('}'); setuses(labels[0]); foreach(labels[0], LABELS, checklab, NULL); exitscope(); cfunc = NULL; }/* newstyle - process function arguments for new-style definition */static func_type *newstyle(func_type *ty, type_node *caller_types[], Symbol callee[]) { for (int i = 0; callee[i] != NULL; i++) caller_types[i] = callee[i]->type; return ty; }/* oldparam - check that p is an old-style parameter, and patch callee[i] */static void oldparam(Symbol p, Generic cl) { Symbol *callee = (Symbol *)cl; for (int i = 0; callee[i] != NULL; i++) { if (p->name == callee[i]->name) { callee[i] = p; return; } } error("declared parameter `%s' is missing\n", p->name); }/* oldstyle - process function arguments for old-style definition */static func_type *oldstyle(char *name, func_type *ty, type_node *caller_types[], Symbol callee[]) { unsigned i; Symbol p; while ((kind[t] == CHAR) || (kind[t] == STATIC) || ((t == ID) && (tsym != NULL) && (tsym->sclass == TYPEDEF))) { decl(&dclparam, TRUE); } foreach(identifiers, PARAM, oldparam, (Generic)callee); for (i = 0; (p = callee[i]) != NULL; i++) { if (p->type == NULL) { p->type = inttype; p->defined = 1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -