示例#1
0
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"));
}
示例#2
0
文件: fst.c 项目: SnookEE/nvc
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)) : "");
}
示例#3
0
文件: vcd.c 项目: SnookEE/nvc
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);
}
示例#4
0
文件: lxt.c 项目: SnookEE/nvc
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;
}
示例#5
0
文件: fst.c 项目: SnookEE/nvc
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);
}
示例#6
0
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;
}