Пример #1
0
/* Declare a new temporary that can be assigned a value of type t.
   Place the declaration at the start of block. 
   Return it's declaration */
data_declaration add_temporary(region r, compound_stmt block, type t)
{
  const char *name = next_temporary();
  data_decl dd = build_declaration(r, NULL, t, name, NULL, NULL);
  struct data_declaration tempdecl;
  data_declaration ddecl;

  /* Add to the function's declarations */
  dd->next = CAST(node, block->decls);
  block->decls = CAST(declaration, dd);

#if 0
  /* Set parent pointers */
  AST_set_parents(CAST(node, dd));
  dd->parent = CAST(node, block);
  dd->parent_ptr = CASTSRPTR(node, &block->decls);
  if (dd->next)
    dd->next->parent_ptr = &dd->next;
#endif

  /* Declare the variable */
  init_data_declaration(&tempdecl, dd->decls, rstrdup(r, name), t);
  tempdecl.kind = decl_variable;
  tempdecl.vtype = variable_normal;
  tempdecl.islocal = TRUE;
  ddecl = declare(block->env, &tempdecl, FALSE);
  CAST(variable_decl, dd->decls)->ddecl = ddecl;

  return ddecl;
}
Пример #2
0
void declare_interface_ref(interface_ref iref, declaration gparms,
			   environment env, attribute attribs)
{
  const char *iname = (iref->word2 ? iref->word2 : iref->word1)->cstring.data;
  nesc_declaration idecl = 
    require(l_interface, iref->location, iref->word1->cstring.data);
  struct data_declaration tempdecl;
  data_declaration old_decl, ddecl;

  init_data_declaration(&tempdecl, CAST(declaration, iref), iname, void_type);
  tempdecl.kind = decl_interface_ref;
  tempdecl.type = NULL;
  tempdecl.itype = idecl;
  tempdecl.container = current.container;
  tempdecl.required = current.spec_section == spec_uses;
  tempdecl.gparms = gparms ? make_gparm_typelist(gparms) : NULL;

  handle_decl_attributes(attribs, &tempdecl);

  old_decl = env_lookup(env->id_env, iname, TRUE);
  if (old_decl)
    error("redefinition of `%s'", iname);
  ddecl = declare(env, &tempdecl, FALSE);
  iref->attributes = attribs;
  iref->ddecl = ddecl;

  if (idecl->abstract)
    {
      generic_used = TRUE;

      check_abstract_arguments("interface", ddecl,
			       idecl->parameters, iref->args);
      ddecl->itype = interface_copy(parse_region, iref,
				    current.container->abstract);
      ddecl->functions = ddecl->itype->env;
    }
  else
    {
      copy_interface_functions(parse_region, current.container, ddecl,
			       ddecl->itype->env);
      if (iref->args)
	error("unexpected type arguments");
    }

  /* We don't make the interface type generic. Instead, we push the generic
     type into each function in copy_interface_functions.  This is because
     the syntax for invoking or defining a function on a generic interface
     is interfacename.functionname[generic args](...) */
  if (gparms)
    set_interface_functions_gparms(ddecl->functions, ddecl->gparms);
  ddecl->type = make_interface_type(ddecl);
}
Пример #3
0
/* Declare a new temporary that can be assigned a value of type t.
   Place the declaration at the start of block. 
   XXX: See discussion in types.c:tag2ast about the (lack of) correctness of
   this approach.
   Return it's declaration */
data_decl build_declaration(region r, struct environment *e,
			    type t, const char *name, expression init,
			    data_declaration *oddecl)
{
  struct data_declaration tempdecl;
  identifier_declarator id;
  variable_decl vd;
  data_decl dd;
  declarator tdeclarator;
  type_element tmodifiers;

  /* Compute real type, name */
  if (type_array(t))
    t = make_pointer_type(type_array_of(t));
  else if (type_function(t))
    t = make_pointer_type(t);
  /* Qualifiers must not be present on the temp (the qualifiers of t apply
     to the original location we are building a temp) */
  t = make_qualified_type(t, no_qualifiers);

  /* Build AST for the declaration */
  id = new_identifier_declarator(r, dummy_location, str2cstring(r, name));
  type2ast(r, dummy_location, t, CAST(declarator, id), &tdeclarator, &tmodifiers);
  vd = new_variable_decl(r, dummy_location, tdeclarator, NULL, init, NULL, NULL);
  vd->declared_type = t;
  dd = new_data_decl(r, dummy_location, tmodifiers, CAST(declaration, vd));

  if (e) /* Declare the variable */
    {
      init_data_declaration(&tempdecl, CAST(declaration, vd), id->cstring.data, t);
      tempdecl.kind = decl_variable;
      tempdecl.vtype = variable_normal;
      tempdecl.islocal = TRUE;
      *oddecl = vd->ddecl = declare(e, &tempdecl, FALSE);
    }

  return dd;
}
Пример #4
0
static expression build_taskid(module m, data_declaration taskdecl)
{
  /* Build a unique identifier for a task whose declaration is taskdecl,
     in module m.
     Method: we add enum { m$taskdecl = unique("task-unique-string") };
             to all_cdecls
	     and return an identifier-expression referring to m$taskdecl
  */

  location loc = taskdecl->ast->location;
  region r = parse_region;
  cstring idname;
  enumerator idast;
  struct data_declaration tempdecl;
  enum_ref idenum;
  tag_declaration enumdecl;
  data_decl iddecl;
  expression unique_id, unique_fn, unique_args, use_id;
  cstring silly_name;
  identifier_declarator silly_id;
  declarator silly_d;
  type_element silly_modifiers;
  rid silly_typedef;
  type silly_type;
  variable_decl silly_vd;
  data_decl silly_decl;

  /* Build unique("task-unique-string") */
  unique_fn = build_identifier(r, loc, magic_unique);
  unique_args = build_string(r, loc, scheduler_unique_name);
  default_conversion(unique_args);
  unique_id = build_function_call(r, loc, unique_fn, unique_args);

  /* Build, declare enumerator taskdecl */
  idname = str2cstring(r, taskdecl->name);
  idast = new_enumerator(r, loc, idname, unique_id, NULL);
  init_data_declaration(&tempdecl, CAST(declaration, idast), idname.data,
			int_type);
  tempdecl.kind = decl_constant;
  tempdecl.definition = tempdecl.ast;
  tempdecl.value = unique_id->cst;
  idast->ddecl = declare(m->ienv, &tempdecl, FALSE);

  /* Build the enum declaration */
  idenum = new_enum_ref(r, loc, NULL, NULL, NULL, TRUE);
  idenum->fields = CAST(declaration, idast);
  idenum->tdecl = enumdecl = declare_tag(idenum);
  layout_enum_start(enumdecl);
  enumdecl->definition = idenum;
  enumdecl->defined = TRUE;
  layout_enum_end(enumdecl);

  /* Build the expression we will use in the wiring. */
  use_id = build_identifier(r, loc, idast->ddecl);

  /* Hack: the use_id expression needs to be in the module's AST so
     that we do instantiation and constant folding on it. We build
     a silly typedef for that purpose:
       typedef int __nesc_sillytask_taskdecl[use_id]
  */
  silly_name = alloc_cstring(r, strlen(taskdecl->name) + 17);
  sprintf(silly_name.data, "__nesc_sillytask_%s", taskdecl->name);
  silly_id = new_identifier_declarator(r, loc, silly_name);
  silly_type = make_array_type(int_type, use_id);
  type2ast(r, loc, silly_type, CAST(declarator, silly_id), 
	   &silly_d, &silly_modifiers);

  silly_typedef = new_rid(r, loc, RID_TYPEDEF);

  silly_vd = new_variable_decl(r, loc, silly_d, NULL, NULL, NULL,
			       NULL/*ddecl*/);
  init_data_declaration(&tempdecl, CAST(declaration, silly_vd),
			silly_name.data, silly_type);
  tempdecl.kind = decl_typedef;
  tempdecl.definition = tempdecl.ast;
  silly_vd->ddecl = declare(m->ienv, &tempdecl, FALSE);
  silly_vd->declared_type = silly_type;
  silly_decl =
    new_data_decl(r, loc, type_element_chain(CAST(type_element, silly_typedef),
					     silly_modifiers),
		  CAST(declaration, silly_vd));
  m->decls = declaration_chain(CAST(declaration, silly_decl), m->decls);

  /* Build the declaration and add it to the module's decls */
  iddecl = new_data_decl(r, loc, CAST(type_element, idenum), NULL);
  m->decls = declaration_chain(CAST(declaration, iddecl), m->decls);

  return use_id;
}