void location_compute (location *loc, boundary *cur, char const *token, size_t size) { int line = cur->line; int column = cur->column; char const *p0 = token; char const *p = token; char const *lim = token + size; loc->start = *cur; for (p = token; p < lim; p++) switch (*p) { case '\n': line += line < INT_MAX; column = 1; p0 = p + 1; break; case '\t': column = add_column_width (column, p0, p - p0); column = add_column_width (column, NULL, 8 - ((column - 1) & 7)); p0 = p + 1; break; default: break; } cur->line = line; cur->column = column = add_column_width (column, p0, p - p0); loc->end = *cur; if (line == INT_MAX && loc->start.line != INT_MAX) warn_at (*loc, _("line number overflow")); if (column == INT_MAX && loc->start.column != INT_MAX) warn_at (*loc, _("column number overflow")); }
static void fst_process_hier(tree_t h) { const tree_kind_t scope_kind = tree_subkind(h); enum fstScopeType st; switch (scope_kind) { case T_ARCH: st = FST_ST_VHDL_ARCHITECTURE; break; case T_BLOCK: st = FST_ST_VHDL_BLOCK; break; case T_FOR_GENERATE: st = FST_ST_VHDL_FOR_GENERATE; break; case T_PACKAGE: st = FST_ST_VHDL_PACKAGE; break; default: st = FST_ST_VHDL_ARCHITECTURE; warn_at(tree_loc(h), "no FST scope type for %s", tree_kind_str(scope_kind)); break; } const loc_t *loc = tree_loc(h); fstWriterSetSourceStem(fst_ctx, loc->file, loc->first_line, 1); fstWriterSetScope(fst_ctx, st, istr(tree_ident(h)), tree_has_ident2(h) ? istr(tree_ident2(h)) : ""); }
static void vcd_process_signal(tree_t d, int *next_key) { type_t type = tree_type(d); type_t base = type_base_recur(type); vcd_data_t *data = xmalloc(sizeof(vcd_data_t)); memset(data, '\0', sizeof(vcd_data_t)); int msb = 0, lsb = 0; if (type_is_array(type)) { if (type_dims(type) > 1) { warn_at(tree_loc(d), "cannot represent multidimensional arrays " "in VCD format"); free(data); return; } range_t r = type_dim(type, 0); int64_t low, high; range_bounds(r, &low, &high); data->dir = r.kind; data->size = high - low + 1; msb = assume_int(r.left); lsb = assume_int(r.right); type_t elem = type_elem(type); if (!vcd_can_fmt_chars(elem, data)) { warn_at(tree_loc(d), "cannot represent arrays of type %s " "in VCD format", type_pp(elem)); free(data); return; } } else { switch (type_kind(base)) { case T_INTEGER: { int64_t low, high; range_bounds(type_dim(type, 0), &low, &high); data->size = ilog2(high - low + 1); data->fmt = vcd_fmt_int; } break; case T_ENUM: if (vcd_can_fmt_chars(type, data)) { data->size = 1; break; } // Fall-through default: warn_at(tree_loc(d), "cannot represent type %s in VCD format", type_pp(type)); free(data); return; } } const char *name_base = strrchr(istr(tree_ident(d)), ':') + 1; const size_t base_len = strlen(name_base); char name[base_len + 64]; strncpy(name, name_base, base_len + 64); if (type_is_array(type)) snprintf(name + base_len, 64, "[%d:%d]\n", msb, lsb); tree_add_attr_ptr(d, vcd_data_i, data); data->watch = rt_set_event_cb(d, vcd_event_cb, data, true); vcd_key_fmt(*next_key, data->key); fprintf(vcd_file, "$var reg %d %s %s $end\n", (int)data->size, data->key, name); ++(*next_key); }
void lxt_restart(void) { if (trace == NULL) return; lt_set_timescale(trace, -15); lt_symbol_bracket_stripping(trace, 0); lt_set_clock_compress(trace); const int ndecls = tree_decls(lxt_top); for (int i = 0; i < ndecls; i++) { tree_t d = tree_decl(lxt_top, i); if (tree_kind(d) != T_SIGNAL_DECL) continue; else if (!wave_should_dump(d)) continue; type_t type = tree_type(d); int rows, msb, lsb; if (type_is_array(type)) { rows = type_dims(type) - 1; if ((rows > 0) || type_is_array(type_elem(type))) { warn_at(tree_loc(d), "cannot emit arrays of greater than one " "dimension or arrays of arrays in LXT yet"); continue; } range_t r = type_dim(type, 0); msb = assume_int(r.left); lsb = assume_int(r.right); } else { rows = 0; msb = lsb = -1; } lxt_data_t *data = xmalloc(sizeof(lxt_data_t)); memset(data, '\0', sizeof(lxt_data_t)); int flags = 0; if (type_is_array(type)) { // Only arrays of CHARACTER, BIT, STD_ULOGIC are supported type_t elem = type_base_recur(type_elem(type)); if ((type_kind(elem) != T_ENUM) || !lxt_can_fmt_enum_chars(elem, data, &flags)) { warn_at(tree_loc(d), "cannot represent arrays of type %s " "in LXT format", type_pp(elem)); free(data); continue; } data->dir = type_dim(type, 0).kind; } else { type_t base = type_base_recur(type); switch (type_kind(base)) { case T_INTEGER: data->fmt = lxt_fmt_int; flags = LT_SYM_F_INTEGER; break; case T_ENUM: if (!lxt_can_fmt_enum_chars(base, data, &flags)) { data->fmt = lxt_fmt_enum; flags = LT_SYM_F_STRING; } break; default: warn_at(tree_loc(d), "cannot represent type %s in LXT format", type_pp(type)); free(data); continue; } } char *name = lxt_fmt_name(d); data->sym = lt_symbol_add(trace, name, rows, msb, lsb, flags); free(name); tree_add_attr_ptr(d, lxt_data_i, data); watch_t *w = rt_set_event_cb(d, lxt_event_cb, data, true); (*data->fmt)(d, w, data); } last_time = (lxttime_t)-1; }
static void fst_process_signal(tree_t d) { type_t type = tree_type(d); type_t base = type_base_recur(type); fst_data_t *data = xmalloc(sizeof(fst_data_t)); memset(data, '\0', sizeof(fst_data_t)); int msb = 0, lsb = 0; enum fstVarType vt; enum fstSupplementalDataType sdt; if (type_is_array(type)) { if (type_dims(type) > 1) { warn_at(tree_loc(d), "cannot represent multidimensional arrays " "in FST format"); free(data); return; } range_t r = type_dim(type, 0); int64_t low, high; range_bounds(r, &low, &high); data->dir = r.kind; data->size = high - low + 1; msb = assume_int(r.left); lsb = assume_int(r.right); type_t elem = type_elem(type); if (!fst_can_fmt_chars(elem, data, &vt, &sdt)) { warn_at(tree_loc(d), "cannot represent arrays of type %s " "in FST format", type_pp(elem)); free(data); return; } else { ident_t ident = type_ident(base); if (ident == unsigned_i) sdt = FST_SDT_VHDL_UNSIGNED; else if (ident == signed_i) sdt = FST_SDT_VHDL_SIGNED; } } else { switch (type_kind(base)) { case T_INTEGER: { ident_t ident = type_ident(type); if (ident == natural_i) sdt = FST_SDT_VHDL_NATURAL; else if (ident == positive_i) sdt = FST_SDT_VHDL_POSITIVE; else sdt = FST_SDT_VHDL_INTEGER; int64_t low, high; range_bounds(type_dim(type, 0), &low, &high); vt = FST_VT_VCD_INTEGER; data->size = ilog2(high - low + 1); data->fmt = fst_fmt_int; } break; case T_ENUM: if (!fst_can_fmt_chars(type, data, &vt, &sdt)) { ident_t ident = type_ident(base); if (ident == std_bool_i) sdt = FST_SDT_VHDL_BOOLEAN; else if (ident == std_char_i) sdt = FST_SDT_VHDL_CHARACTER; else sdt = FST_SDT_NONE; vt = FST_VT_GEN_STRING; data->size = 0; data->fmt = fst_fmt_enum; } else data->size = 1; break; case T_PHYSICAL: { sdt = FST_SDT_NONE; vt = FST_VT_GEN_STRING; data->size = 0; data->type.units = fst_make_unit_map(type); data->fmt = fst_fmt_physical; } break; default: warn_at(tree_loc(d), "cannot represent type %s in FST format", type_pp(type)); free(data); return; } } enum fstVarDir dir = FST_VD_IMPLICIT; switch (tree_attr_int(d, fst_dir_i, -1)) { case PORT_IN: dir = FST_VD_INPUT; break; case PORT_OUT: dir = FST_VD_OUTPUT; break; case PORT_INOUT: dir = FST_VD_INOUT; break; case PORT_BUFFER: dir = FST_VD_BUFFER; break; } const char *name_base = strrchr(istr(tree_ident(d)), ':') + 1; const size_t base_len = strlen(name_base); char name[base_len + 64]; strncpy(name, name_base, base_len + 64); if (type_is_array(type)) snprintf(name + base_len, 64, "[%d:%d]\n", msb, lsb); data->handle = fstWriterCreateVar2( fst_ctx, vt, dir, data->size, name, 0, type_pp(type), FST_SVT_VHDL_SIGNAL, sdt); tree_add_attr_ptr(d, fst_data_i, data); data->watch = rt_set_event_cb(d, fst_event_cb, data, true); }
void fold_expr_if(expr *e, symtable *stab) { consty konst; type *tt_l, *tt_r; FOLD_EXPR(e->expr, stab); const_fold(e->expr, &konst); fold_check_expr(e->expr, FOLD_CHK_NO_ST_UN, "if-expr"); if(e->lhs){ FOLD_EXPR(e->lhs, stab); fold_check_expr(e->lhs, FOLD_CHK_NO_ST_UN | FOLD_CHK_ALLOW_VOID, "if-lhs"); } FOLD_EXPR(e->rhs, stab); fold_check_expr(e->rhs, FOLD_CHK_NO_ST_UN | FOLD_CHK_ALLOW_VOID, "if-rhs"); /* Arithmetic Arithmetic Arithmetic type after usual arithmetic conversions // Structure or union type Compatible structure or union type Structure or union type with all the qualifiers on both operands void void void Pointer to compatible type Pointer to compatible type Pointer to type with all the qualifiers specified for the type Pointer to type NULL pointer (the constant 0) Pointer to type Pointer to object or incomplete type Pointer to void Pointer to void with all the qualifiers specified for the type GCC and Clang seem to relax the last rule: a) resolve if either is any pointer, not just (void *) b) resolve to a pointer to the incomplete-type */ tt_l = (e->lhs ? e->lhs : e->expr)->tree_type; tt_r = e->rhs->tree_type; if(type_is_integral(tt_l) && type_is_integral(tt_r)){ expr **middle_op = e->lhs ? &e->lhs : &e->expr; expr_check_sign("?:", *middle_op, e->rhs, &e->where); e->tree_type = op_promote_types( op_unknown, middle_op, &e->rhs, &e->where, stab); }else if(type_is_void(tt_l) || type_is_void(tt_r)){ e->tree_type = type_nav_btype(cc1_type_nav, type_void); }else if(type_cmp(tt_l, tt_r, 0) & TYPE_EQUAL_ANY){ /* pointer to 'compatible' type */ e->tree_type = type_qualify(tt_l, type_qual(tt_l) | type_qual(tt_r)); }else{ /* brace yourself. */ int l_ptr_null = expr_is_null_ptr( e->lhs ? e->lhs : e->expr, NULL_STRICT_VOID_PTR); int r_ptr_null = expr_is_null_ptr(e->rhs, NULL_STRICT_VOID_PTR); int l_complete = !l_ptr_null && type_is_complete(tt_l); int r_complete = !r_ptr_null && type_is_complete(tt_r); if((l_complete && r_ptr_null) || (r_complete && l_ptr_null)){ e->tree_type = l_ptr_null ? tt_r : tt_l; }else{ int l_ptr = l_ptr_null || type_is(tt_l, type_ptr); int r_ptr = r_ptr_null || type_is(tt_r, type_ptr); if(l_ptr || r_ptr){ fold_type_chk_warn( tt_l, tt_r, &e->where, "?: pointer type mismatch"); /* qualified void * */ e->tree_type = type_qualify( type_ptr_to(type_nav_btype(cc1_type_nav, type_void)), type_qual(tt_l) | type_qual(tt_r)); }else{ char buf[TYPE_STATIC_BUFSIZ]; warn_at(&e->where, "conditional type mismatch (%s vs %s)", type_to_str(tt_l), type_to_str_r(buf, tt_r)); e->tree_type = type_nav_btype(cc1_type_nav, type_void); } } } e->freestanding = (e->lhs ? e->lhs : e->expr)->freestanding || e->rhs->freestanding; }