/* 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; }
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); }
/* 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; }
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; }