home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1985-1992 New York University
- *
- * This file is part of the Ada/Ed-C system. See the Ada/Ed README file for
- * warranty (none) and distribution info and also the GNU General Public
- * License for more details.
-
- */
- #ifndef SEM
- #define SEM 1
- #endif
-
- #include "hdr.h"
- #include "vars.h"
- #include "attr.h"
- #include "dclmapprots.h"
- #include "errmsgprots.h"
- #include "sspansprots.h"
- #include "nodesprots.h"
- #include "setprots.h"
- #include "miscprots.h"
- #include "smiscprots.h"
- #include "chapprots.h"
-
- /*
- CHECK HANDLING OF NEW_NAME in newmod ds 30 jul
- Sort out is_identifier usage ds 26 nov 84
- Bring C version of find_simple_name in closer correspondence to SETL
- version. ds 7 aug 84
-
- Note that set imported in collect_imported names is built on every call.
- It is probably dead on return, but I am not copying it when I put in
- in all_imported_names. May be able to do set_free(imported) before
- return from collect_imported_names - look into this later. ds 2 aug
- */
-
- /*
- * The following global variable is used for error reporting when
- * several instances of an identifier end up hiding each other and
- * the identifier is seen as undeclared or ambiguous.
- */
- static Set all_imported_names; /*TBSL: initialize to (Set)0 */
-
-
- static Set collect_imported_names(char *);
- static void name_error(Node);
- static void find_simple_name(Node);
- static void array_or_call(Node);
- static int parameterless_callable(Symbol);
- static void index_or_slice(Node);
- static void find_selected_comp(Node);
- static void find_exp_name(Node, Symbol, char *);
- static void all_declarations(Node, Symbol, char *, Symbol);
- static int has_implicit_operator(Node, Symbol, char *);
- static void make_any_id_node(Node);
- static int is_appropriate_for_record(Symbol);
- static int is_appropriate_for_task(Symbol);
- static Symbol renamed(Node, Tuple, Symbol);
- static Symbol op_matches_spec(Symbol, Tuple, Symbol);
- static void check_modes(Tuple, Symbol);
- static void renamed_entry(Node, Tuple);
-
- void find_old(Node id_node) /*;find_old*/
- {
- /*
- * Establish unique name of identifier, or of syntactic category name.
- * Yield error in the case of undefined identifier.
- * In the case of long and short integers, indicate that they are
- * unimplemented rather than 'undefined'.
- */
- Symbol u_name;
- char *id;
- char *newn;
- int unsupported;
-
- if (cdebug2 > 3)
- TO_ERRFILE("AT PROC : find_old");
-
- check_old(id_node);
- if (N_KIND(id_node) != as_simple_name) return; /* added 7 jul */
- u_name = N_OVERLOADED(id_node) ? (Symbol) 0 : N_UNQ(id_node);
- id = N_VAL(id_node);
- if (u_name == symbol_undef) {
- if (streq(id, "LONG_INTEGER") || streq(id, "SHORT_INTEGER")) {
- unsupported = TRUE;
- u_name = symbol_integer; /* new type to use */
- }
- else if (streq(id, "SHORT_FLOAT") || streq(id, "LONG_FLOAT")) {
- unsupported = TRUE;
- u_name = symbol_float; /* new type to use */
- }
- else {
- unsupported = FALSE;
- }
-
- if (!unsupported) {
- /* The identifier is undefined, or not visible. This is an error.*/
- name_error(id_node);
- }
- else {
- /* The identifier names unsupported type. This is error, so
- * issue error message and then change type to avoid further
- * spurious error messages
- */
- #ifdef ERRNUM
- str_errmsgn(420, id, 10, id_node);
- #else
- errmsg_str("% is not supported in current implementation",
- id, "none", id_node);
- #endif
- N_UNQ(id_node) = u_name;
- return;
- }
- /* insert in current scope, and give it default type.*/
- if (dcl_get(DECLARED(scope_name), id) == (Symbol)0
- && set_size(all_imported_names) == 0) {
- newn = id;
- u_name = find_new(newn);
- NATURE(u_name) = na_obj; /* Could be more precise.*/
- N_UNQ(id_node) = u_name;
- }
- TYPE_OF(u_name) = symbol_any;
- ALIAS(u_name) = symbol_any;
- }
- }
-
- Symbol find_type(Node node) /*;find_type*/
- {
- Symbol type_mark;
-
- /* Resolve a name that must yield a type mark.*/
- find_old(node);
- type_mark = N_UNQ(node);
- if (N_OVERLOADED(node) || type_mark == (Symbol)0
- || !is_type(type_mark) && TYPE_OF(type_mark) != symbol_any) {
- #ifdef ERRNUM
- errmsgn(421, 10, node);
- #else
- errmsg("Invalid type mark ", "none", node);
- #endif
- N_UNQ(node) = type_mark = symbol_any;
- }
- return type_mark;
- }
-
- static void name_error(Node id_node) /*;name_error*/
- {
-
- char *id;
- char *names;
-
- if (cdebug2 > 3)
- TO_ERRFILE("AT PROC : name_error");
- /*
- * Name was not found in environment. This may be because it is undeclared,
- * or because several imported instances of the name hide each other.
- * The marker '?' is also returned when a type name is mentioned in
- * the middle of its own elaboration.
- */
- id = N_VAL(id_node);
- if (set_size(all_imported_names) == 0) {
- if (dcl_get(DECLARED(scope_name), id) == (Symbol)0) {
- #ifdef ERRNUM
- str_errmsgn(422, id, 207, id_node);
- #else
- errmsg_str("identifier undeclared or not visible %", id, "3.1", id_node);
- #endif
- }
- else {
- #ifdef ERRNUM
- str_errmsgn(423, id, 126, id_node);
- #else
- errmsg_str("Invalid reference to %", id , "3.3", id_node);
- #endif
- }
- }
- else {
- #ifdef TBSL
- names = +/[ original_name(scope_of(x)) + '.' + original_name(x)
- + ' ': x in all_imported_names ];
- #endif
- names = build_full_names(all_imported_names);
- #ifdef ERRNUM
- str_errmsgn(424, names, 390, id_node);
- #else
- errmsg_str("Ambiguous identifier. Could be one of: %",
- names, "8.3, 8.4", id_node);
- #endif
- }
- }
-
- void check_old(Node n_node) /*;check_old*/
- {
- Node node, attr, arg1, expn;
- int nk;
-
- if (cdebug2 > 3) {
- TO_ERRFILE("AT PROC : check_old");
- printf(" kind %s\n", kind_str(N_KIND(n_node))); /*DEBUG*/
- }
- /*
- * This procedure performs name resolution for several syntactic
- * instances of names. These include identifiers, selected components,
- * array indexing and slicing, function calls and attribute expressions.
- * If -name- is an identifier and is undeclared, this proc yields
- * the special marker '?' which is used by error routines.
- * If -name- is overloaded, the procedure returns the set of overloaded
- * names which correspond to -name-. This set is constructed by
- * scanning first the open scopes, and then examining visible packages.
- * To facilitate the collection of overloaded names, the procedure
- * chain_overload, which is called when a procedure specification, or
- * and enumeration type are processed, collects successive overloads of the
- * same id together, using the -overloads- field of the symbol table.
- */
-
- switch (nk = N_KIND(n_node)) {
- case as_simple_name:
- case as_character_literal:
- case as_package_stub:
- case as_task_stub:
- find_simple_name(n_node);
- break;
- case as_call_unresolved:
- array_or_call(n_node);
- break;
- case as_selector:
- find_selected_comp(n_node);
- break;
- case as_string:
- N_KIND(n_node) = as_simple_name; /* Treat as simple*/
- find_simple_name(n_node); /* name.*/
- break;
- case as_name:
- case as_range_expression:
- node = N_AST1(n_node);
- find_old(node);
- copy_attributes(node, n_node);
- break;
- case as_attribute:
- attr = N_AST1(n_node);
- arg1 = N_AST2(n_node);
- find_old(arg1);
- break;
- case as_all:
- expn = N_AST1(n_node);
- find_old(expn);
- break;
- }
- }
-
- static void find_simple_name(Node n_node) /*;find_simple_name*/
- {
- char *id;
- Symbol sc;
- int sc_num;
- Symbol u_name, o, n, u_n;
- Symbol found, foreign;
- Set names, names_add, found_set;
- Set imported;
- int i, exists, found_is_set;
- Forset fs1, fs2;
- Symbol sym;
-
- id = N_VAL(n_node);
-
- if (cdebug2 > 0) {
- TO_ERRFILE(" looking for id. " );
- printf(" kind %s %s\n", kind_str(N_KIND(n_node)), id); /*DEBUG*/
- }
-
- exists = FALSE;
- for (sc_num = 1; sc_num <= tup_size(open_scopes); sc_num++) {
- sc = (Symbol)open_scopes[sc_num];
- u_name = dcl_get(DECLARED(sc), id);
- if (u_name != (Symbol)0) {
- exists = TRUE;
- break;
- }
- }
- if (exists) {
- if (!can_overload(u_name)) {
- found_is_set = FALSE;
- found = u_name;
- TO_XREF(u_name);
- }
- else {
- names = set_copy(OVERLOADS(u_name));
-
- /* Scan open scopes for further overloadings.*/
- for (i = sc_num+1; i <= tup_size(open_scopes); i++) {
- u_n = dcl_get(DECLARED(((Symbol)open_scopes[i])), id);
- if (u_n == (Symbol)0) continue;
- else if (!can_overload(u_n)) {
- found_is_set = TRUE;
- found_set = names;
- }
- else {
- names_add = set_new(0);
- FORSET(o=(Symbol), OVERLOADS(u_n), fs1);
- exists = FALSE;
- FORSET(n=(Symbol), names, fs2);
- if (same_type(TYPE_OF(n), TYPE_OF(o)) &&
- same_signature(n, o)) {
- exists = TRUE;
- break;
- }
- ENDFORSET(fs2);
- if (!exists) names_add = set_with(names_add, (char *)o);
- ENDFORSET(fs1);
- FORSET(o=(Symbol), names_add, fs1);
- names = set_with(names, (char *)o);
- ENDFORSET(fs1);
- set_free(names_add);
- }
- }
- imported = collect_imported_names(id);
- /* Keep only the imported names which are not hidden
- * by visible names with the same signature.
- */
- if (set_size(imported)>1 ||
- (set_size(imported) == 1 &&
- can_overload((Symbol)set_arb(imported)))) {
- names_add = set_new(0);
- FORSET(foreign=(Symbol), imported, fs1);
- exists = FALSE;
- FORSET(n=(Symbol), names, fs2);
- if (same_type(TYPE_OF(n), TYPE_OF(foreign)) &&
- same_signature(n, foreign)) {
- exists = TRUE;
- break;
- }
- ENDFORSET(fs2);
- if (!exists)
- names_add = set_with(names_add, (char *)foreign);
- ENDFORSET(fs1);
- FORSET(n=(Symbol), names_add, fs1);
- names = set_with(names, (char *) n);
- ENDFORSET(fs1);
- set_free(names_add);
- }
- found_is_set = TRUE;
- found_set = names;
- }
- }
- else if ((imported = collect_imported_names(id) , set_size(imported)) != 0){
- if (set_size(imported)>1 || can_overload((Symbol)set_arb(imported))) {
- found_is_set = TRUE;
- found_set = imported;
- }
- else {
- found_is_set = FALSE;
- found = (Symbol) set_arb(imported);
- }
- }
- /* the syntactic error recovery routine sends a '' when it can
- * recover by token insertion. return it as is, to avoid
- * subsequent spurious messages.
- */
- /* #if DEAD */
- /* DEAD (as best we can tell 7 jul */
- else if (streq(id, "any_id")) {
- found_is_set = FALSE;
- found = symbol_any_id;
- }
- #ifdef DEAD
- else if (id == (Symbol)0) {
- found_is_set = FALSE;
- found = id;
- }
- #endif
- else {
- found_is_set = FALSE;
- found = symbol_undef; /* need to add symbol_undef '?' */
- }
- if (found_is_set) {
- N_OVERLOADED(n_node) = TRUE;
- N_NAMES(n_node) = found_set;
- }
- else {
- N_OVERLOADED(n_node) = FALSE;
- N_UNQ(n_node) = found;
- }
- if (cdebug2 == 0) return; /* rest is debugging trace only*/
-
- if (cdebug2 > 0) TO_ERRFILE ("found name(s): " );
- /* always print found names */
- if (found_is_set) {
- FORSET(sym=(Symbol), found_set, fs1)
- #ifdef IBM_PC
- printf("%p", sym);
- #else
- printf("%ld", sym);
- #endif
- if (sym!=(Symbol)0) printf("%s", ORIG_NAME(sym));
- printf("\n");
- ENDFORSET(fs1);
- }
- else {
- #ifdef IBM_PC
- printf("found name %p ", found);
- #else
- printf("found name %ld ", found);
- #endif
- /* symbol_undef should not need special handling ds 17 jul
- if (found == symbol_undef) printf("?\n");
- else
- */
- if (found!=(Symbol)0) printf("%s\n", ORIG_NAME(found));
- }
- }
-
- static Set collect_imported_names(char *id) /*;collect_imported_names*/
- {
- Set imported;
- Symbol used;
- Symbol s;
- Symbol foreign;
- Fortup ft1;
- Forset fs1;
-
- if (cdebug2 > 3) TO_ERRFILE("AT PROC : collect_imported_names");
- /*
- * This procedure collects the set of all imported names corresponding
- * to identifier -name-, which appear in currently visible package.
- * An imported identifier is visible if :
- * a) It is not an overloadable identifier, and it appears in only
- * one used package.
- * b) Or, all of its appearances in used modules are overloadable.
- */
- imported = set_new(0);
- /*
- * (forall used in used_mods | (f:= visible(used)) /= om
- * and (foreign := f(id)) /= om )
- */
- FORTUP(used=(Symbol), used_mods, ft1);
- if (DECLARED(used) == (Declaredmap)0) continue;
- foreign = dcl_get_vis(DECLARED(used), id);
- if (foreign !=(Symbol)0) {
- if (can_overload(foreign)){
- FORSET(s=(Symbol), OVERLOADS(foreign), fs1);
- imported = set_with(imported, (char *)s);
- ENDFORSET(fs1);
- }
- else {
- if (set_size(imported) != 0) {
- /* mutual hiding. Save all for error message.*/
- /* imported dead - no need to copy ds 2 aug */
- all_imported_names = imported;
- all_imported_names = set_with(all_imported_names,
- (char *) foreign);
- return set_new(0);
- }
- else {
- imported = set_new1((char *) foreign);
- }
- }
- }
- ENDFORTUP(ft1);
-
- if (cdebug2 > 1) TO_ERRFILE("Imported names:");
-
- /* Save imported names in global variable, for possible error message.*/
- all_imported_names = imported;
- return imported;
- #ifdef TBSL
- -- this code seems to be dead review this with Ed ds 12-dec-84
- exists = FALSE;
- FORSET(fgn=(Symbol), imported, fs1);
- if (!can_overload(fgn)) {
- exists = TRUE;
- break;
- }
- ENDFORSET(fs1);
- if (exists) {
- /* If it is the only name found, return it.*/
- if (set_size(imported) == 1) {
- /*set_free(imported);*/
- return set_new1(fgn);
- }
- else {
- /*set_free(imported);*/
- return set_new(0);
- /* various visible names hide each other.*/
- }
- }
- else {
- /* All occurrences are overloadable. Return only those which do*/
- if (cdebug2 > 1) {
- TO_ERRFILE("Names:");
- return imported;
- }
- }
- #endif
- }
-
- static void array_or_call(Node n_node) /*;array_or_call*/
- {
- /*
- * This procedure resolves the construct
- * name aggregate
- * The meaning of this construct is one of the following :
- * a) Indexed expression or slice.
- * b) function call.
- * d) Conversion.
- */
-
- Node prefix_node, agg_node, call_node, index_node, p_node;
- Tuple arg_list;
- Set f_names, npfs;
- Symbol f, t;
- Forset fs1;
-
- if (cdebug2 > 3)
- TO_ERRFILE("AT PROC : array_or_call");
-
- prefix_node = N_AST1(n_node);
- agg_node = N_AST2(n_node);
- arg_list = N_LIST(agg_node);
-
- /* Find unique name of object (procedure, array, etc).*/
- find_old(prefix_node);
- /* Need different error flag. */
- if (N_UNQ(prefix_node) == (Symbol)symbol_undef)
- /* error message emitted already by find_old.*/
- return;
-
- if (N_OVERLOADED(prefix_node)) {
- f_names = N_NAMES(prefix_node);
- /* function call.*/
- N_KIND(n_node) = as_call;
- /* The nature of at least one of the overloaded instances must be
- * callable. This is checked by the type resolution routines. An
- * unpleasant syntactic ambiguity appears if parameterless functions
- * that return an array type appear in obj_name. In this case the
- * expression must be reformatted as an indexing on the result of a
- * function call. If both parameterless and parametered functions
- * are present, then the tree itself is ambiguous, and both parsings
- * must be carried, to be resolved by the type resolution routines.
- */
- npfs = set_new(0);
- FORSET(f=(Symbol), f_names, fs1);
- t = TYPE_OF(f);
- if (parameterless_callable(f) && (is_array(t)
- || is_access(t) && is_array((Symbol)designated_type(t))))
- npfs = set_with(npfs, (char *)f);
- ENDFORSET(fs1);
- if (set_size(npfs) != 0) {
- index_or_slice(n_node);
-
- if (N_KIND(n_node) == as_slice) {
- /* no ambiguity: it must be a slice.*/
- ; }
- else {
- /* Construct subtrees with both parsings.*/
- call_node = copy_node(n_node);
- N_KIND(call_node) = as_call;
- index_node = copy_tree(n_node);
- p_node = N_AST1(index_node);
- N_NAMES(p_node) = npfs;
- N_OVERLOADED(p_node)= TRUE;
-
- N_KIND(n_node) = as_call_or_index;
- N_AST1(n_node) = call_node;
- N_AST2(n_node) = index_node;
- }
- }
- }
- else if (is_type(N_UNQ(prefix_node))) {
- /* Case of a conversion.*/
- N_KIND(n_node) = as_convert;
- if (tup_size(arg_list) == 1) {
- /* Conversion of a single expression. $$$ What about a choice?*/
- N_AST1(n_node) = prefix_node;
- N_AST2(n_node) = (Node)arg_list[1];
- }
- else {
- /* Conversion of an aggregate: label it as such.*/
- N_KIND(agg_node) = as_aggregate;
- }
- }
- else{
- index_or_slice(n_node);
- }
- }
-
- static int parameterless_callable(Symbol f) /*;parameterless_callable*/
- {
- /*
- * Assert that f is a parameterless function, or that default values
- * exist for all its parameters and it can be called without arguments.
- */
-
- Symbol formal;
- Fortup ft1;
-
- if (NATURE(f) !=na_function && NATURE(f)!=na_function_spec)
- return FALSE;
- FORTUP(formal=(Symbol), SIGNATURE(f), ft1);
- if ((Node)default_expr(formal) == OPT_NODE ) return FALSE;
- ENDFORTUP(ft1);
- return TRUE;
- }
-
- static void index_or_slice(Node n_node) /*;index_or_slice*/
- {
- /*
- * A slice is not always recognizable syntactically from an
- * indexing expression. v(arg) is a slice in 3 cases:
- * a) arg is a range : L..R
- * b) arg is of the form V'RANGE
- * c) arg is a type mark, possibly with a range constraint.
- */
- Node prefix_node, index_node, constraint;
- Tuple index_list;
- int index_kind;
- Node index;
-
- prefix_node = N_AST1(n_node);
- index_node = N_AST2(n_node);
- index_list = N_LIST(index_node);
- N_KIND(n_node) = as_index; /* most likely. */
-
- if (tup_size(index_list) == 1) {
- index = (Node)index_list[1];
- index_kind = N_KIND(index );
- if (index_kind == as_subtype)
- N_KIND(n_node) = as_slice;
- else if (index_kind == as_range) {
- /* Reformat it as subtype of unknown type.*/
- constraint = copy_node(index);
- N_KIND(index) = as_subtype;
- N_AST1(index) = OPT_NODE;
- N_AST2(index) = constraint;
- N_KIND(n_node) = as_slice;
- }
- else if (index_kind == as_name) {
- find_old(index);
- if (is_type(N_UNQ(index)) || (N_KIND(index) == as_attribute
- && ((int)attribute_kind(index) == ATTR_RANGE
- || (int)attribute_kind(index) == ATTR_O_RANGE
- || (int)attribute_kind(index) == ATTR_T_RANGE)))
- N_KIND(n_node) = as_slice;
- }
- }
- }
-
- static void find_selected_comp(Node n_node) /*;find_selected_comp*/
- {
- Node prefix_node, s_node;
- char *selector;
- Set objset;
- Symbol prefix, prefix_type, u_n;
- Forset fs1;
- int prefix_nat;
- Symbol subp;
- Span save_span;
-
- if (cdebug2 > 3)
- TO_ERRFILE("AT PROC : find_selected_comp");
-
- prefix_node = N_AST1(n_node);
- s_node = N_AST2(n_node);
- selector = N_VAL(s_node);
- save_span = get_left_span(n_node);
-
- find_old(prefix_node);
-
- if (NATURE(scope_name) == na_void && streq(ORIG_NAME(scope_name), selector))
- #ifdef ERRNUM
- str_errmsgn(425, selector, 50, s_node);
- #else
- errmsg_str("premature usage of %", selector, "8.3(16)", s_node);
- #endif
-
- if (N_KIND(prefix_node) == as_simple_name && !N_OVERLOADED(prefix_node)){
- prefix = N_UNQ(prefix_node);
- prefix_type = TYPE_OF(prefix);
- prefix_nat = NATURE(prefix);
- if (prefix_nat == na_package_spec || prefix_nat == na_package)
- find_exp_name(n_node, prefix, selector);
- else if (is_appropriate_for_record(prefix_type)) {
- /* Type checking will verify that the selector denotes a
- * discriminant or component of the corresponding record or value.
- */
- ;
- }
- else if (is_appropriate_for_task(prefix_type)
- /* if the selector is an entry name, return it as as selected
- * component. Context is an entry call or the prefix of the
- * attribute COUNT.
- */
- && (is_access(prefix_type)
- || (((u_n= dcl_get(DECLARED(prefix_type), selector))!= (Symbol)0)
- && (NATURE(u_n) == na_entry || NATURE(u_n) == na_entry_family)))) {
- ;
- }
- /* other forms of selected components are expanded names. */
-
- else if (in_open_scopes(prefix) && prefix_nat != na_void) {
- /* prefix denotes an enclosing loop, block, or task, i.e. an
- * enclosing construct that is not a subprogram or accept statement.
- */
- find_exp_name(n_node, prefix, selector);
- }
-
- else { /* various error cases. */
- if (prefix_type == symbol_any) {
- /* Object was undeclared, and error message emitted already.*/
- ;
- }
- else if (NATURE(prefix) == na_void) {
- #ifdef ERRNUM
- id_errmsgn(425, prefix, 50, n_node);
- #else
- errmsg_id("premature usage of %", prefix, "8.3(16)", n_node);
- #endif
- }
- else {
- #ifdef ERRNUM
- errmsgn(428, 429, n_node);
- #else
- errmsg("Invalid prefix in qualified name", "4.1.3", n_node);
- #endif
- }
- make_any_id_node(n_node);
- }
- return;
- }
- if (N_KIND(prefix_node) != as_simple_name) {
- /* if the prefix is not a simple name (overloaded or not) it must be
- * be an expression whose type is appropriate for a record or access
- * type. Its full resolution requires type resolution as well. Nothing
- * else is done here.
- */
- ;
- return;
- }
- objset= N_NAMES(prefix_node);
-
- /* At this point the prefix is an overloaded name. It can be an enclosing
- * subprogram or accept statement. It can also be a call to a parameterless
- * function that yields a record value.
- */
- FORSET(subp=(Symbol), objset, fs1);
- if (in_open_scopes(subp )) {
- /* TBSL: more than one visible such name. */
- find_exp_name(n_node, subp, selector);
- return;
- }
- ENDFORSET(fs1);
-
- /* if no interpretation as an expanded name is possible, it must be a
- * selected component of a record returned by a function call.
- */
- FORSET(subp=(Symbol), objset, fs1);
- if (parameterless_callable(subp))
- return;
- ENDFORSET(fs1);
- /* nothing found.*/
- make_any_id_node(n_node);
- #ifdef ERRNUM
- errmsgn(430, 429, n_node);
- #else
- errmsg("Ambiguous name in selected component", "4.1.3", n_node);
- #endif
- }
-
- static void find_exp_name(Node n_node, Symbol prefix, char *selector)
- /*;find_exp_name*/
- {
- /* resolve an expanded name whose prefix denotes a package or an enclosing
- * construct.
- */
-
- Symbol entity;
-
- if (in_open_scopes(prefix))
- entity = dcl_get(DECLARED(prefix), selector);
- else /* prefix is package. */
- entity = dcl_get_vis(DECLARED(prefix), selector);
- if (entity !=(Symbol)0)
- /* If the object is overloaded, collect its local occurences.*/
- all_declarations(n_node, prefix, selector, entity);
- else if (has_implicit_operator(n_node, prefix, selector)) {
- /* It can still be an implicitly defined operator obtained by derivation
- * of a predefined type within the given construct.
- */
- ;
- }
- else {
- make_any_id_node(n_node);
- #ifdef ERRNUM
- str_id_errmsgn(426, selector, prefix, 427, n_node);
- #else
- errmsg_str_id("% not declared in %" , selector,
- prefix, "4.1.3, 8.3", n_node);
- #endif
- }
- }
-
- static void all_declarations(Node n_node, Symbol prefix, char *selector,
- Symbol entity) /*;all_declarations*/
- {
- /* collect all declarations that overload an entity that is declared
- * in a given construct. If the entity is not overloadable it is returned
- * as is (a simple name). Otherwise the local overloading must also be
- * collected. This is made complicated by the possible presence of implicit
- * operators, which are created by the derivation of predefined types, but
- * are nto inserted explicitly into the symbol table of the declarative
- * part where they occur.
- */
-
- int forall, ii;
- Symbol predef_op, subp, f;
- Forset fs1;
- Tuple tup;
- Set nams;
- Span save_span;
-
- save_span = get_left_span(n_node);
- N_KIND(n_node) = as_simple_name; /* most likely case.*/
- N_OVERLOADED(n_node) = FALSE;
- if (can_overload(entity)) {
- nams = set_copy(OVERLOADS(entity));
- if( in_op_designators(selector) && prefix!=symbol_standard0 ){
- /* Include implicitly defined operators, if they are not hidden by
- * an explicit declaration in the scope. To determine whether it is
- * hidden, compare it with the signature of the user-defined
- *operator just as for the resolution of renamings.
- */
- predef_op = dcl_get(DECLARED(symbol_standard0), selector);
- forall = TRUE;
- FORSET(subp=(Symbol), nams, fs1);
- tup = tup_new(tup_size(SIGNATURE(subp)));
- for (ii = 1; ii <= tup_size(SIGNATURE(subp)); ii++) {
- f = (Symbol) ((SIGNATURE(subp))[ii]);
- tup[ii] = (char *)TYPE_OF(f);
- }
- if (!(op_matches_spec(predef_op, tup, TYPE_OF(subp))
- == (Symbol)0)) {
- forall = FALSE;
- #ifdef TUPFREE
- tup_free(tup);
- #endif
- break;
- }
- #ifdef TUPFREE
- tup_free(tup);
- #endif
- ENDFORSET(fs1);
- if (forall) {
- /* leave as qualified name, for resolution in
- * procedure result_types.
- */
- nams = set_with(nams, (char *)predef_op);
- N_KIND(n_node) = as_selector;
- }
- }
- /* in any case, entity is overloaded.*/
- N_OVERLOADED(n_node) = TRUE;
- N_NAMES(n_node) = nams;
- }
- if (N_KIND(n_node) == as_simple_name) {
- if (!N_OVERLOADED(n_node)) N_UNQ(n_node) = entity;
- N_AST2(n_node) = (Node)0;
- N_VAL(n_node) = selector;
- set_span(n_node, save_span);
- TO_XREF(entity);
- }
- }
-
- static int has_implicit_operator(Node n_node, Symbol scope, char *selector)
- /*;has_implicit_operator*/
- {
- Fordeclared fd1;
- Symbol root, typ;
- char *id;
-
- if (!in_op_designators(selector))
- return FALSE;
- FORDECLARED(id, typ, DECLARED(scope), fd1);
- if (!is_type(typ)) continue;
- root = root_type (typ);
-
- if ( !is_limited_type (typ)
- && (streq(selector, "=") || streq(selector, "/="))) {
- N_OVERLOADED(n_node) = TRUE;
- N_NAMES(n_node) =
- set_new1((char *)dcl_get(DECLARED(symbol_standard0), selector));
- return TRUE;
- }
- if (((root == symbol_boolean) || (is_array (typ) &&
- (root_type (component_type (typ)) == symbol_boolean))) &&
- (streq(selector, "not") || streq(selector, "and")
- || streq(selector, "or") || streq(selector, "xor"))) {
- N_OVERLOADED(n_node) = TRUE;
- N_NAMES(n_node) =
- set_new1((char *)dcl_get(DECLARED(symbol_standard0), selector));
- return TRUE;
- }
- if (is_scalar_type (typ) || (is_array (typ) &&
- is_discrete_type (component_type (typ))) &&
- (streq(selector, "<") || streq(selector, "<=")
- || streq(selector, ">") || streq(selector, ">="))) {
- N_OVERLOADED(n_node) = TRUE;
- N_NAMES(n_node) =
- set_new1((char *)dcl_get(DECLARED(symbol_standard0), selector));
- return TRUE;
- }
- if (is_numeric_type (typ) &&
- (streq(selector, "+") || streq(selector, "-") ||
- streq(selector, "*") || streq(selector, "/") ||
- streq(selector, "**") || streq(selector, "abs") ||
- streq(selector, "mod") || streq(selector, "rem"))) {
- N_OVERLOADED(n_node) = TRUE;
- N_NAMES(n_node) =
- set_new1((char *)dcl_get(DECLARED(symbol_standard0), selector));
- return TRUE;
- }
- if (is_array (typ) && streq (selector , "&")) {
- N_OVERLOADED(n_node) = TRUE;
- N_NAMES(n_node) =
- set_new1((char *)dcl_get(DECLARED(symbol_standard0), selector));
- return TRUE;
- }
- ENDFORDECLARED(fd1);
- return FALSE;
- }
-
- static void make_any_id_node(Node n_node) /*;make_any_id_node*/
- {
- Span save_span;
-
- save_span = get_left_span(n_node);
- N_KIND(n_node) = as_simple_name;
- N_AST2(n_node) = (Node)0;
- set_span(n_node, save_span);
- N_UNQ(n_node) = symbol_any_id;
- }
-
- static int is_appropriate_for_record(Symbol t) /*;is_appropriate_for_record*/
- {
- return (is_record(t)
- || is_access(t) && is_record(designated_type(t)));
- }
-
- static int is_appropriate_for_task(Symbol t) /*;is_appropriate_for_task*/
- {
- return (is_task_type(t)
- || is_access(t) && is_task_type(designated_type(t)));
- }
-
- Set find_agg_types() /*;find_agg_types*/
- {
- /*
- * The possible types of an aggregate are all the structured types that
- * are visible, even if not directly visible.
- */
-
- Symbol s, agg, p, fgn, ss;
- Set res;
- Fortup ft1;
- Forset fs1;
-
- /*
- * return {} +/[overloads(agg): s in open_scopes
- * |(agg := declared(s)('aggregate')) /= om]
- * +/[overloads(fgn) : p in vis_mods
- * |(fgn := visible(p)('aggregate')) /= om];
- */
- res = set_new(0);
- FORTUP(s=(Symbol), open_scopes, ft1);
- agg = dcl_get(DECLARED(s), "aggregate");
- if (agg!=(Symbol)0) {
- FORSET(ss=(Symbol), OVERLOADS(agg), fs1);
- res = set_with(res, (char *)ss);
- ENDFORSET(fs1);
- }
- ENDFORTUP(ft1);
- FORTUP(p=(Symbol), vis_mods, ft1);
- fgn = dcl_get_vis(DECLARED(p), "aggregate");
- if (fgn!=(Symbol)0) {
- FORSET(ss=(Symbol), OVERLOADS(fgn), fs1);
- res = set_with(res, (char *) ss);
- ENDFORSET(fs1);
- }
- ENDFORTUP(ft1);
- return res;
- }
-
- Set find_access_types() /*;find_access_types*/
- {
- /*
- * Similarly, the possible types of NULL, and of any allocator, are all
- * visible access types. To simplify their retrieval, they are treated
- * like aggregates, and attached to the marker 'access', whenever an
- * access type definition is processed.
- */
-
- Set a_types;
- Symbol s, fgn, ss, a;
- Fortup ft1;
- Forset fs1;
-
- /*
- * a_types =
- * {} +/[overloads(a): s in open_scopes
- * |(a := declared(s)('access')) /= om]
- * +/[overloads(fgn) : p in vis_mods
- * |(fgn := visible(p)('access')) /= om];
- */
- a_types = set_new(0);
- FORTUP(s = (Symbol), open_scopes, ft1);
- a = dcl_get(DECLARED(s), "access");
- if (a != (Symbol)0) {
- FORSET(ss=(Symbol), OVERLOADS(a), fs1);
- a_types = set_with(a_types, (char *) ss);
- ENDFORSET(fs1);
- }
- ENDFORTUP(ft1);
-
- FORTUP(fgn = (Symbol), vis_mods, ft1);
- fgn = dcl_get_vis(DECLARED(fgn), "access");
- if (fgn != (Symbol)0) {
- FORSET(ss=(Symbol), OVERLOADS(fgn), fs1);
- a_types = set_with(a_types, (char *) ss);
- ENDFORSET(fs1);
- }
- ENDFORTUP(ft1);
-
- if (set_size(a_types) == 0) {
- noop_error = TRUE;
- errmsg("No available access types for allocator", "3.8,4.8",
- current_node);
- }
- return a_types;
- }
-
- Symbol find_new(char *name) /*;find_new*/
- {
- Symbol unique_nam, old;
-
- if (cdebug2 > 3) TO_ERRFILE("AT PROC : find_new");
-
- /*
- * insert new name in symbol table of current scope. Check
- * against duplications.
- *
- * IF error token was seen ('') , return undeclared marker.
- */
-
- if (name == (char *)0 || strlen(name) == 0) return symbol_any_id;
-
- /* add new name to current scope declarations.
- * generate a unique identifier for it.
- */
-
- unique_nam = (Symbol) 0;
-
- /* Insert new name in DECLARED table for current scope */
- old = dcl_get(DECLARED(scope_name), name);
- if (old != (Symbol)0) {
- /* The name has been seen already. This is acceptable
- * if it was inserted after some previous error of
- * any sort. (in that case it has type 'any').
- */
- if (TYPE_OF(old) == symbol_any) return old;
- else {
- #ifdef ERRNUM
- str_errmsgn(431, name, 143, current_node);
- #else
- errmsg_str("duplicate identifier: %", name , "8.3", current_node);
- #endif
- }
- }
- else {
- unique_nam = sym_new(na_void);
- /* insert in declared map for scope, and make visible if scope
- * is a package specification. ES 9-21-86)
- */
- dcl_put_vis(DECLARED(scope_name), name, unique_nam ,
- (NATURE(scope_name) == na_package_spec));
- }
- /* Initialize symbol table entry.*/
- /* allocate new symbol if not yet allocated */
- if (unique_nam == (Symbol)0) unique_nam = sym_new(na_void);
- NATURE(unique_nam) = na_void;
- TYPE_OF(unique_nam) = symbol_none;
- SCOPE_OF(unique_nam) = scope_name;
- ORIG_NAME(unique_nam) = name;
- TO_XREF(unique_nam);
- return unique_nam;
- }
-
- void check_void(char *id) /*;check_void*/
- {
- /*
- * Verify that within a procedure specification no use is made of the
- * procedure identifier under any guise. This cannot be automatically
- * caught by the name resolution routines.
- */
- if (streq(original_name(scope_name), id) && NATURE(scope_name) == na_void){
- #ifdef ERRNUM
- str_errmsgn(425, id, 50, current_node);
- #else
- errmsg_str("premature usage of %", id, "8.3(16)", current_node);
- #endif
- }
- }
-
- /* new_agg_or_access becomes two procedures:
- new_agg_or_access_acc marker 'access' implied
- new_agg_or_access_agg marker 'aggregate' implied
- */
-
- void new_agg_or_access_acc(Symbol type_mark) /*;new_agg_or_access_acc*/
- {
- /*
- * The possible types of an aggregate are all composite types that are
- * currently visible. To simplify their use, an entry with the marker
- * 'aggregate' is created for each such type definition. Its overloads
- * set carries all such types defined in the current scope. This is
- * similar to what is done for other overloadable constructs.
- * The same is done for access types, using the marker 'access'.
- */
-
- Symbol scope, old_def, new_def, maybe_priv, pr;
- int nat;
- Private_declarations pd;
-
- if (cdebug2>3) TO_ERRFILE("AT PROC: new_agg_or_access_acc");
-
- scope = scope_name;
- nat = na_access ;
- new_def = sym_new(nat);
- #ifdef TBSN
- new_def = marker + str newat;
- #endif
- SCOPE_OF(new_def) = scope;
- TYPE_OF(new_def) = type_mark;
- old_def = dcl_get(DECLARED(scope), "access");
- if (old_def == (Symbol)0 ) { /* first in scope*/
- dcl_put(DECLARED(scope), "access", new_def );
- OVERLOADS(new_def) = set_new1((char *) type_mark);
- }
- else {
- dcl_put(DECLARED(scope), newat_str(), new_def);
- /* If the current scope is a private part, make sure the visible
- * declaration has been saved, before adding new entry to overloads
- * set for old_def.
- */
- pd = (Private_declarations) private_decls(scope);
- if (NATURE(scope_name) == na_private_part
- && private_decls_get(pd, old_def) == (Symbol)0)
- private_decls_put(pd, old_def);
- OVERLOADS(old_def) = set_with(OVERLOADS(old_def), (char *) type_mark);
- }
- /*
- * If the type has an incomplete private component, (a private ancestor)
- * list it in the set of private dependents of that ancestor.
- */
- maybe_priv = (Symbol) designated_type(type_mark);
- pr = private_ancestor(maybe_priv);
- if ((pr !=(Symbol)0 && in_open_scopes(SCOPE_OF(pr)))
- || (is_access(type_mark) && is_incomplete_type(pr = maybe_priv)))
- /* ie still incomplete.*/
- if (!private_dependents(pr))
- private_dependents(pr) = set_new1((char *) type_mark);
- else
- private_dependents(pr) =
- set_with(private_dependents(pr), (char *) type_mark);
- initialize_representation_info(type_mark,TAG_ACCESS);
- }
-
- void new_agg_or_access_agg(Symbol type_mark) /*;new_agg_or_access_agg*/
- {
- /*
- * The possible types of an aggregate are all composite types that are
- * currently visible. To simplify their use, an entry with the marker
- * 'aggregate' is created for each such type definition. Its overloads
- * set carries all such types defined in the current scope. This is
- * similar to what is done for other overloadable constructs.
- * The same is done for access types, using the marker 'access'.
- */
-
- Symbol scope, old_def, new_def, maybe_priv, pr;
- int nat;
- Private_declarations pd;
-
- scope = scope_name;
- nat = na_aggregate;
- new_def = sym_new(nat);
- #ifdef TBSN
- if (cdebug2>3) TO_ERRFILE("AT PROC: new_agg_or_access_agg");
- new_def = marker + str newat;
- #endif
- SCOPE_OF(new_def) = scope;
- TYPE_OF(new_def) = type_mark;
- old_def = dcl_get(DECLARED(scope), "aggregate");
- if (old_def == (Symbol)0 ) { /* first in scope*/
- dcl_put(DECLARED(scope), "aggregate", new_def );
- OVERLOADS(new_def) = set_new1((char *) type_mark);
- }
- else {
- dcl_put(DECLARED(scope), newat_str(), new_def);
- /* If the current scope is a private part, make sure the visible
- * declaration has been saved, before adding new entry to overloads
- * set for old_def.
- */
- pd = (Private_declarations) private_decls(scope);
- if (NATURE(scope_name) == na_private_part
- && private_decls_get(pd, old_def) == (Symbol)0)
- private_decls_put(pd, old_def);
- /*
- * Make a copy of the overloads set so that if the field is
- * changed it will not affect another copy of the symbol which
- * points to this set. This might be the case if we have compilation
- * units for a package spec and body in the same file. The Overloads
- * field pointed to by the "aggregate" symbol saved in the unitdecl
- * of the spec and restored when processing the body is mangled if
- * the body adds anything to this overloads field.
- */
- OVERLOADS(old_def) = set_copy(OVERLOADS(old_def));
- OVERLOADS(old_def) = set_with (OVERLOADS(old_def), (char *) type_mark);
- }
- /* If the type has an incomplete private component, (a private ancestor)
- * list it in the set of private dependents of that ancestor.
- */
- maybe_priv = type_mark;
- pr = private_ancestor(maybe_priv);
- if ((pr !=(Symbol)0 && in_open_scopes(SCOPE_OF(pr)))
- || (is_access(type_mark) && is_incomplete_type(pr = maybe_priv)))
- /* ie still incomplete.*/
- if (!private_dependents(pr))
- private_dependents(pr) = set_new1((char *) type_mark);
- else
- private_dependents(pr) =
- set_with(private_dependents(pr), (char *) type_mark);
- }
-
- char *original_name(Symbol unique_nam) /*;*original_name*/
- {
- /*
- * This procedure strips the prefix and suffix of a generated name, to
- * recover the original source name. Is is used when looking for a
- * compilation stub, and for error messages.
- */
- return ORIG_NAME(unique_nam);
- }
-
- /*
- * Process RENAMES clauses. If the renamed entity is an identifier, then
- * the renames clause simply creates a synonym : new id shares the symbol
- * table entry of the entity. If the entity is an expression, then the
- * interpreter will have to elaborate it, and a 'renames' statement is
- * emitted. In addition, a new symbol table entry is created for the new
- * id, with the the appropriate type and nature.
- */
- void rename_ex(Node node) /*;rename_ex*/
- {
- /* Rename an exception.*/
- Node id_node, name_node;
- char *new_id;
- Symbol old;
-
- id_node = N_AST1(node);
- name_node = N_AST2(node);
- new_id = N_VAL(id_node);
- adasem(name_node);
- find_old(name_node);
- old = N_UNQ(name_node);
- if (N_KIND(name_node) != as_simple_name) {
- #ifdef ERRNUM
- errmsgn(432, 433, name_node);
- #else
- errmsg("Expect identifier in renaming", "8.5", name_node);
- #endif
- }
- else if (N_OVERLOADED(name_node) || NATURE(old) != na_exception) {
- #ifdef ERRNUM
- errmsgn(434, 433, name_node);
- #else
- errmsg("not an exception", "8.5", name_node);
- #endif
- }
- else
- dcl_put(DECLARED(scope_name), new_id, old);
- }
-
- void rename_pack(Node node) /*;rename_pack*/
- {
- Node id_node, name_node;
- char *new_id;
- Symbol old;
-
- id_node = N_AST1(node);
- name_node = N_AST2(node);
- new_id = N_VAL(id_node);
- adasem(name_node);
- find_old(name_node);
- old = N_UNQ(name_node);
- if (N_KIND(name_node) != as_simple_name) {
- #ifdef ERRNUM
- errmsgn(432, 433, name_node);
- #else
- errmsg("Expect identifier in renaming", "8.5", name_node);
- #endif
- }
- else if (N_OVERLOADED(name_node)
- || (NATURE(old) != na_package
- && NATURE(old) != na_package_spec
- && NATURE(old) != na_generic_package
- && NATURE(old) != na_generic_package_spec)) {
- #ifdef ERRNUM
- errmsgn(435, 433, name_node);
- #else
- errmsg("not a package", "8.5", name_node);
- #endif
- }
- else
- dcl_put(DECLARED(scope_name), new_id, old);
- }
-
- void rename_subprogram(Node node) /*;rename_subprogram*/
- {
- /*
- * The subprogram specification is elaborated, and the declared subpro-
- * gram is inserted in the symbol table.
- */
- Symbol ret;
- Node spec_node, name_node, formal_list;
- int kind, s_kind, exists, i;
- Node id_node, ret_node;
- Tuple formals, ftup, old_types;
- Symbol old1;
- Set set;
- Symbol ne, new_subp, new_ne;
- Forset fs1;
- Fortup ft1;
- char *id;
-
- if (cdebug2 > 3) TO_ERRFILE("AT PROC : rename_subprogram");
-
- spec_node = N_AST1(node);
- name_node = N_AST2(node);
- adasem(spec_node);
- id_node = N_AST1(spec_node);
- formal_list = N_AST2(spec_node);
- ret_node = N_AST3(spec_node);
- id = N_VAL(id_node);
- formals = get_formals(formal_list, id);
-
- if (N_KIND(spec_node) == as_procedure ) {
- kind = na_procedure;
- s_kind = na_procedure_spec;
- ret = symbol_none;
- /* Transform into abbreviated as_rename_sub_tr node and reset
- * N_UNQ(node) in later code below. The spec part of the node
- * is dropped.
- */
- N_KIND(node) = as_rename_sub_tr;
- }
- else {
- kind = na_function;
- s_kind = na_function_spec;
- ret = N_UNQ(ret_node);
- N_KIND(node) = as_rename_sub_tr;
- /* reset N_UNQ(node) below */
- }
- adasem(name_node);
- find_old(name_node); /* Name of entity being renamed.*/
-
- current_node = node;
- old_types = find_renamed_entity(kind, formals, ret, name_node);
- if (tup_size(old_types) != 0) {
- /* the subtypes of the formals are unaffected by the renaming */
- ret = (Symbol) tup_frome(old_types);
- FORTUPI(ftup = (Tuple), formals, i, ft1);
- ftup[3] = (char *)old_types[i];
- ENDFORTUP(ft1);
- }
- else return; /* previous error. Is this ok ??? */
-
- if (N_KIND(name_node) == as_simple_name) {
- /* renaming of subprogram or operator. */
- old1 = N_UNQ(name_node);
- if (in_op_designators(id )) /* check format, if operator spec */
- check_new_op(id_node, formals, ret);
-
- new_subp = chain_overloads(id, s_kind, ret, formals, old1, OPT_NODE);
- N_UNQ(node) = new_subp;
- /* a renaming is both a specification and body */
- NATURE(new_subp) = kind;
- if (ALIAS(old1) != (Symbol)0)
- ALIAS(new_subp) = ALIAS(old1);
- else
- ALIAS(new_subp) = old1;
- if (streq(id , "=")) {
- if (!streq(original_name(old1) , "=")) {
- #ifdef ERRNUM
- errmsgn(436, 54, name_node);
- #else
- errmsg("renaming with = can only rename an equality operator",
- "6.7", name_node);
- #endif
- }
- else if (tup_size(formals) != 2 ) {
- ; /* error caught elsewhere*/
- }
- else {
- /* The implicitly defined inequality operator, just introduced,
- * renames another inequality. assert exists ne in
- * overloads(declared(scope_of(old1))('/=')) |
- * same_signature(old1, ne);
- */
- exists = FALSE;
- set = OVERLOADS(dcl_get(DECLARED(SCOPE_OF(old1)), "/="));
- FORSET(ne=(Symbol), set, fs1);
- if(same_signature(old1, ne)) {
- exists = TRUE;
- break;
- }
- ENDFORSET(fs1);
- if (!exists)
- chaos("assertion failed in rename_subprogram chapter 8");
- /* assert exists new_ne in
- * overloads(declared(scope_of(new_subp))('/=')) |
- * same_signature(new_subp, new_ne);
- */
- exists = FALSE;
- set = OVERLOADS(dcl_get(DECLARED(SCOPE_OF(new_subp)), "/="));
- FORSET(new_ne=(Symbol), set, fs1);
- if(same_signature(new_subp, new_ne)) {
- exists = TRUE;
- break;
- }
- ENDFORSET(fs1);
-
- if (!exists)
- chaos("assertion failed in rename_subprogram chapter 8");
-
- if (ALIAS(ne) != (Symbol) 0)
- ALIAS(new_ne) = ALIAS(ne);
- else
- ALIAS(new_ne) = ne;
- }
- }
- }
- else {
- /* renaming of entry or attribute. */
-
- new_subp= chain_overloads(id, s_kind, ret, formals, (Symbol)0,OPT_NODE);
- N_UNQ(node) = new_subp;
- }
- /* A renaming declaration provides the subprogram specification and the
- * body as well.
- */
- NATURE(new_subp) = kind;
- }
-
- Tuple find_renamed_entity(int kind, Tuple formals, Symbol ret, Node name_node)
- /*;find_renamed_entity*/
- {
- /* When a subprogram is renamed, the signature of the entity is that of
- * the renamed object, and not that of the given subprogram specification
- * (except if the renamed entity is an operator, in which case the base
- * types of the specification are used).
- * This procedure finds the renamed entity (subprogram, entry or attri-
- * bute, verifies that it matches the spec, and returns a tuple with the
- * types of the formals of the renamed object, together with its type.
- */
- Symbol old1, e_name, typ, typ2, res, ft, i;
- Set old_sub;
- Node e_node, attr_node, typ_node;
- int attr;
- Tuple tup, ftup;
- Fortup ft1;
- Span save_span;
-
- if (N_OVERLOADED(name_node)) {
- old_sub = N_NAMES(name_node); /* Most likely overloadable. */
- /* find the one that matches the new specification. */
- old1 = renamed(name_node, formals, ret);
- #ifdef TBSL
- -- check old1='' in next line
- #endif
- if (old1 == (Symbol) 0) return tup_new(0); /* No match found. */
- else {
- /* suprogram name renames subprogram name. Mark as simple */
- /* renaming. */
- save_span = get_left_span(name_node);
- ast_clear(name_node);
- N_KIND(name_node) = as_simple_name;
- set_span(name_node, save_span);
- N_UNQ(name_node) = old1;
- tup = tup_new(0);
- if (NATURE(old1) != na_op) {
- FORTUP(i=(Symbol), SIGNATURE(old1), ft1);
- tup = tup_with(tup, (char *) TYPE_OF(i));
- ENDFORTUP(ft1);
- tup = tup_with(tup, (char *) TYPE_OF(old1));
- }
- else {
- FORTUP(ftup=(Tuple), formals, ft1);
- tup = tup_with(tup, (char *) base_type((Symbol) ftup[3]));
- ENDFORTUP(ft1);
- tup = tup_with(tup, (char *) base_type(ret));
- }
- return tup;
- }
- }
- else if (kind == na_procedure &&
- (N_KIND(name_node) == as_selector || N_KIND(name_node)== as_index)) {
- /* Procedure renames a entry given by a qualified name. Find */
- /* the full entry (and task) name. */
- renamed_entry(name_node, formals);
- e_node = N_AST2(name_node);
- if (e_node != OPT_NODE) {
- e_name = N_UNQ(e_node);
- #ifdef TBSL
- return [type_of(i): i in signature(e_name)] with 'none';
- #endif
- tup = tup_new(0);
- FORTUP(i=(Symbol), SIGNATURE(e_name), ft1)
- tup = tup_with(tup, (char *) TYPE_OF(i));
- ENDFORTUP(ft1)
- tup = tup_with(tup, (char *) symbol_none);
- }
- else {
- return tup_new(0);
- }
- }
- else {
- /* The name can be an attribute, renaming a function. */
- /* Verify that signatures match. */
- if (kind != na_function || N_KIND(name_node) != as_attribute) {
- #ifdef ERRNUM
- errmsgn(437, 433, name_node);
- #else
- errmsg("invalid renaming", "8.5", name_node);
- #endif
- return tup_new(0);
- }
- else if (tup_size(formals) != 1) {
- #ifdef ERRNUM
- errmsgn(438, 439, current_node);
- #else
- errmsg("function spec. does not match attribute", "8.5,12.3.6",
- current_node);
- #endif
- return tup_new(0);
- }
-
- attr_node = N_AST1(name_node);
- typ_node = N_AST2(name_node);
- attr = (int) N_VAL(attr_node);
- typ = N_UNQ(typ_node);
- tup = (Tuple) formals[1]; /* verify that this is correct */
- ft = (Symbol)tup[3];
- /* Find type returned by the attribute, and the required type of its
- * second argument.
- */
-
- if (attr == ATTR_SUCC || attr == ATTR_PRED) {
- typ2 = base_type(typ);
- res = base_type(typ);
- }
- else if (attr == ATTR_IMAGE) {
- typ2 = base_type(typ);
- res = symbol_string;
- }
- else if (attr == ATTR_VALUE) {
- typ2 = symbol_string;
- res = base_type(typ);
- }
- else {
- #ifdef ERRNUM
- errmsgn(440, 439, attr_node);
- #else
- errmsg("attribute cannot be renamed as function", "8.5,12.3.6",
- attr_node);
- #endif
- return tup_new(0);
- }
- if (!compatible_types(ret, res) ||
- !compatible_types(typ2, ft)) {
- #ifdef ERRNUM
- errmsgn(438, 439, current_node);
- #else
- errmsg("function spec. does not match attribute", "8.5,12.3.6",
- current_node);
- #endif
- return tup_new(0);
- }
- else {
- tup = tup_new(2);
- tup[1] = (char *) typ2;
- tup[2] = (char *) res;
- return tup;
- }
- }
- }
-
- void rename_object(Node node) /*;rename_object*/
- {
- Node id_node, type_node, expr_node;
- char *new_id;
- Symbol typ, new_obj, obj_typ;
- Node old_expr = (Node) 0; /* see note below */
- int nat;
- Tuple tup;
-
- if (cdebug2 > 3)
- TO_ERRFILE("AT PROC : rename_object");
-
- id_node = N_AST1(node);
- type_node = N_AST2(node);
- expr_node = N_AST3(node);
- new_id = N_VAL(id_node);
- adasem(type_node);
- adasem(expr_node);
- find_old(expr_node);
- typ = find_type(type_node);
-
- out_context = TRUE; /* Subcomponents of out parameters*/
- check_type(typ, expr_node);
- out_context = FALSE; /* are certainly renamable.*/
-
- if (in_qualifiers(N_KIND(expr_node))) {
- /* Constraints implied by the type mark of the clause are ignored*/
- expr_node = N_AST1(expr_node);
- N_AST1(node) = id_node;
- N_AST2(node) = type_node;
- N_AST3(node) = expr_node;
- }
- /* It is tempting to say that if a simple object is being renamed, the
- * new one has the same unique name. This simple optimization must
- * however be delayed until after conformance checks have been done.
- */
- /* TBSL - old_expr is never initialized. However
- * is_discriminant_dependent(12) currently always returns FALSE, so we
- * just declare old_expr. ds 3 aug
- * old_expr is initialized to (Node) 0 to keep lint quite ds 23-feb-87
- */
- if (is_discriminant_dependent( old_expr )) {
- #ifdef ERRNUM
- str_errmsgn(441, new_id, 433, (Node)0);
- #else
- errmsg_str("existence of object % depends on a discriminant ", new_id,
- "8.5", (Node)0);
- #endif
- }
- else {
- new_obj = find_new(new_id);
- N_UNQ(id_node) = new_obj;
- tup = check_nat_type(expr_node);
- nat = (int) tup[1];
- obj_typ = (Symbol) tup[2];
- if (N_KIND(expr_node) == as_slice) {
- obj_typ = slice_type(node,1);
- }
- NATURE(new_obj) = nat;
- SIGNATURE(new_obj) = (Tuple)expr_node;
- TYPE_OF(new_obj) = typ;
- if (N_KIND(expr_node) != as_ivalue) {
- /* object sharing at run-time. The type is inherited from the
- * object (the declared type may be unconstrained).
- */
- TYPE_OF(new_obj) = obj_typ;
- /* In the C version constants are allocated and this is handled
- * during the code generation phase.
- */
- }
- }
- }
-
- static Symbol renamed(Node name_node, Tuple formals, Symbol ret) /*;renamed*/
- {
- Node arg_list_node, subp_node, arg, expn;
- Set sfound, types, nset, tset, subprogs;
- Symbol subp, n, t, found;
- Tuple arg_list, ftup;
- Fortup ft1;
- Forset fs1;
- int exists;
-
- if (cdebug2 > 3) TO_ERRFILE("AT PROC : renamed");
-
- /* Find the subprogram in the overloaded set -subprog- which matches
- * the specification given in a renames clause or in a generic instantia-
- * tion.
- * If subprogs includes operators, then the matching is analogous to the
- * type-checking of an expression. We construct a skeletal argument list
- * out of the formals, and use result-types(q.v) to find the specific
- * operator being renamed.
- */
- if (cdebug2 > 0) TO_ERRFILE("Renaming prog with signature " );
-
- subp_node = copy_tree(name_node);
- subprogs = set_new(0);
-
- /* The renamed subprogram and the given specification must have the same
- * parameter and result profile. This requires that signatures have the
- * same length, and that the types match. Type matching is verified by
- * constructing a call to the renamed entity. Length checking is done first.
- */
- FORSET(subp=(Symbol), N_NAMES(subp_node), fs1)
- if (NATURE(subp) == na_op
- || tup_size(SIGNATURE(subp)) == tup_size(formals))
- subprogs = set_with(subprogs, (char *)subp);
- ENDFORSET(fs1);
- N_NAMES(subp_node) = subprogs;
-
- arg_list_node = node_new(as_list);
- arg_list = tup_new(0);
- FORTUP(ftup=(Tuple), formals, ft1);
- t = (Symbol) ftup[3];
- arg = node_new(as_simple_name);
- N_PTYPES(arg) = set_new1((char *) t);
- arg_list = tup_with(arg_list, (char *) arg);
- ENDFORTUP(ft1);
- N_LIST(arg_list_node) = arg_list;
-
- /* Build call node with these arguments, and resolve. */
- expn = node_new(as_call);
- N_AST1(expn) = subp_node;
- N_AST2(expn) = arg_list_node;
- result_types(expn);
- types = N_PTYPES(expn);
- N_PTYPES(expn) = (Set) 0; /* clear */
- if (types == (Set)0) types = set_new(0);
- sfound = set_new(0);
- if (N_OVERLOADED(subp_node))
- nset = N_NAMES(subp_node);
- else
- nset = (Set) 0;
- if (nset!=(Set)0) {
- FORSET(n=(Symbol), nset, fs1);
- if (compatible_types(TYPE_OF(n), ret))
- sfound = set_with(sfound, (char *) n);
- ENDFORSET(fs1);
- }
- /* This may require a stronger test.*/
- if (set_size(sfound) > 1) {
- /* user-defined subprogram defined in enclosing scope hides predefined
- * operator, and is chosen first.
- */
- exists = FALSE;
- FORSET(subp=(Symbol), sfound, fs1);
- if (NATURE(subp) != na_op
- && tup_mem((char *) SCOPE_OF(subp) , open_scopes)) {
- exists = TRUE;
- break;
- }
- ENDFORSET(fs1);
- if (exists) {
- tset = set_new(0);
- FORSET(subp=(Symbol), sfound, fs1);
- if (NATURE(subp) != na_op)
- tset = set_with(tset, (char *) subp);
- ENDFORSET(fs1);
- set_free(sfound);
- sfound = tset;
- }
- else {
- FORSET(subp=(Symbol), sfound, fs1);
- if ( NATURE(subp) == na_op) {
- sfound = set_new1((char *) subp);
- break;
- }
- ENDFORSET(fs1);
- }
- }
- if (set_size(sfound) == 1 ) {
- found = (Symbol) set_arb( sfound);
- check_modes(formals, found);
-
- if (cdebug2 > 0) TO_ERRFILE("renaming successful with ...");
-
- return found;
- }
- else if (set_size(sfound) > 1 ) {
- #ifdef ERRNUM
- id_errmsgn(442, (Symbol)set_arb(subprogs), 439, current_node);
- #else
- errmsg_id("ambiguous subprogram name: %", (Symbol) set_arb(subprogs),
- "8.5,12.3.6", current_node);
- #endif
- }
- else {
- #ifdef ERRNUM
- errmsgn(443, 439, current_node);
- #else
- errmsg("No match for subprogam specification ", "8.5,12.3.6",
- current_node);
- #endif
- }
- return (Symbol)0;
- }
-
- static Symbol op_matches_spec(Symbol op_nam, Tuple f_types, Symbol ret)
- /*;op_matches_spec*/
- {
- /* Determine whether a predefined operator matches a given subprogram
- * specification. Called for renamings and for name resolution of
- * selected components whose selector is an operator designator.
- * The matching is analogous to the type-checking of an expression. We
- * construct a skeletal argument list out of the type of formals, and
- * use result-types(q.v) to find the specific operator being renamed.
- */
- Node op_node, arg_list_node, expn;
- Tuple arg_list;
- Symbol t;
- Fortup ft1;
- Forset fs1;
- Set ops, types;
- Node arg;
-
- if (cdebug2 > 3) TO_ERRFILE("AT PROC : op_matches_spec");
-
- if (tup_size(f_types) < 1 || tup_size(f_types)> 2 )
- return (Symbol)0;
- else {
- op_node = node_new(as_op);
- N_NAMES(op_node) = set_new1((char *) op_nam);
- N_OVERLOADED(op_node) = TRUE;
-
- arg_list_node = node_new(as_list);
- arg_list = tup_new(0);
- FORTUP(t=(Symbol), f_types, ft1);
- arg = node_new(as_simple_name);
- N_PTYPES(arg) = set_new1((char *) t);
- arg_list = tup_with(arg_list, (char *) arg);
- ENDFORTUP(ft1);
- N_LIST(arg_list_node) = arg_list;
-
- expn = node_new(as_call);
- N_AST1(expn) = op_node;
- N_AST2(expn) = arg_list_node;
- result_types(expn);
- ops = (N_OVERLOADED(op_node)) ? N_NAMES(op_node): (Set)0;
- types = N_PTYPES(expn);
- N_PTYPES(expn) = (Set)0; /* clear */
-
- if (ops == (Set)0) return (Symbol) 0;
- if (set_size(ops) != 1) return (Symbol) 0;
- FORSET(t=(Symbol), types, fs1);
- if (compatible_types(t, ret)) return (Symbol) set_arb(ops);
- ENDFORSET(fs1);
- return (Symbol) 0;
- }
- }
-
- static void check_modes(Tuple formals, Symbol subp) /*;check_modes*/
- {
- /* Verify that the modes of the formals in a renaming spec match the modes
- * of the renamed subprogram (operator, entry).
- */
-
- int i, md;
- Fortup ft1;
- Tuple tup, sig;
-
- sig = SIGNATURE(subp);
- FORTUPI(tup=(Tuple), formals, i, ft1);
- md = (int) tup[2];
- if ((NATURE(subp) == na_op && md == na_in)
- || md == NATURE((Symbol)sig[i]))
- ;
- else {
- #ifdef ERRNUM
- errmsgn(444, 445, current_node);
- #else
- errmsg("parameter modes do not match", "8.5(8)", current_node);
- #endif
- }
- ENDFORTUP(ft1);
- }
-
- static void renamed_entry(Node entry_expr, Tuple formals) /*;renamed_entry*/
- {
- /* A procedure is being renamed with an expression. This can only be the
- * renaming of an entry or a member of an entry family.
- */
-
- Symbol e, new_typ, i_type;
- Set entries, found ;
- Tuple tup;
- Symbol e_name;
- Node task_node, entry_node, index_node;
- Fortup ft1;
- Forset fs1;
- Tuple sig;
- int i, nk;
- Symbol f;
-
- if (cdebug2 > 3) TO_ERRFILE("AT PROC : renamed_entry");
-
- find_entry_name(entry_expr);
- task_node = N_AST1(entry_expr);
- entry_node = N_AST2(entry_expr);
-
- if (entry_node == OPT_NODE) /* Invalid entry name or expression*/
- return;
- else if (N_KIND(entry_expr) == as_entry_name) {
- /* possibly overloaded; disambiguate with signature. */
- entries = N_NAMES(entry_expr);
- N_AST3(entry_expr) = OPT_NODE; /* discard N_NAMES */
- }
- else { /* case of entry family member. Type check the index */
- e_name = N_UNQ(entry_node);
- entries = set_new1((char *) e_name);
- index_node = N_AST3(entry_expr);
- i_type = (Symbol) index_type(TYPE_OF(e_name));
- check_type(i_type, index_node);
- N_KIND(entry_expr) = as_entry_name; /* common processing after this*/
- }
- found = set_new(0);
-
- FORSET(e=(Symbol), entries, fs1);
- sig = SIGNATURE(e);
- if (tup_size( sig) != tup_size(formals)) continue;
-
- FORTUPI(f =(Symbol), sig, i, ft1);
- tup = (Tuple) formals[i];
- new_typ = (Symbol) tup[3];
- if (!same_type(TYPE_OF(f), new_typ)) goto continue_forall_e;
- ENDFORTUP(ft1);
-
- found = set_with(found, (char *) e);
- continue_forall_e:
- ;
- ENDFORSET(fs1);
-
-
- if (set_size(found) != 1 ) {
- #ifdef ERRNUM
- errmsgn(446, 433, current_node);
- #else
- errmsg("ambiguous or invalid entry name in renaming", "8.5", current_node);
- #endif
- N_AST1(entry_expr) = OPT_NODE;
- N_AST2(entry_expr) = OPT_NODE;
- N_AST3(entry_expr) = OPT_NODE;
- nk = N_KIND(entry_expr);
- if (N_AST4_DEFINED(nk)) N_AST4(entry_expr) = (Node)0;
- }
- else {
- /* use entry name to complete resolution of task name*/
- e_name = (Symbol) set_arb(found);
- N_UNQ(entry_node) = e_name;
- complete_task_name(task_node, TYPE_OF(SCOPE_OF(e_name)));
- check_modes(formals, e_name);
- }
- }
-
- Tuple check_nat_type(Node expr_node) /*;check_nat_type*/
- {
- /* Obtain the nature and the actual type of of a renamed expression,
- * and verify that it designates an object.
- */
-
- Symbol expn;
- int nat, nk;
- Symbol t, s;
- Node exp1, exp2;
- int nrec, nfield;
- Tuple tup;
-
- if (N_KIND(expr_node) == as_simple_name) {
- expn = N_UNQ(expr_node);
- nat = NATURE(expn);
- t = TYPE_OF(expn);
- if (nat !=na_constant
- && nat!= na_in
- && nat!= na_inout
- && nat!= na_out
- && nat!= na_obj) {
- #ifdef ERRNUM
- errmsgn(449, 433, expr_node);
- #else
- errmsg("Renamed entity must be an object", "8.5", expr_node);
- #endif
- }
- tup = tup_new(2);
- tup[1] = (char *) nat;
- tup[2] = (char *) t;
- return tup;
- }
- else {
- /* Predefined operation, or call.*/
- exp1 = N_AST1(expr_node);
- exp2 = N_AST2(expr_node);
-
- nk = N_KIND(expr_node);
-
- if (nk == as_index) {
- /* The nature of an indexed component is the same as the
- * nature of the array object itself.
- */
- tup = check_nat_type(exp1);
- t = (Symbol) tup[2];
- tup[2] = (char *) component_type(t);
- return tup;
- }
- else if (nk == as_slice) {
- /* The nature of the slice is that of the array object.*/
- return check_nat_type(exp1);
- }
- else if (nk == as_selector) {
- tup = check_nat_type(exp1);
- nrec = (int) tup[1];
- s = N_UNQ(exp2);
- nfield = NATURE(s);
- t = TYPE_OF(s); /* attrs. of selector */
- /* IF selector is a discriminant, the new entity must be
- * treated as such. Otherwise the nature of the record
- * object (constant, formal, etc.) determines that of the
- * new entity.
- */
- nat = (nfield == na_discriminant) ? na_constant : nrec;
- tup = tup_new(2);
- tup[1] = (char *) nat;
- tup[2] = (char *) t;
- return tup;
- }
- else if (nk == as_all) {
- /* A dereferenced pointer always yields an object.*/
- tup = check_nat_type(exp1);
- nat = (int) tup[1];
- t = (Symbol)tup[2];
- /*tup_free(tup); may be possible here */
- tup = tup_new(2);
- tup[1] = (char *)na_obj;
- tup[2] =(char *) designated_type(t);
- return tup;
- }
- else if (nk == as_call) {
- /* The function being called must yield an access type.*/
- t = N_TYPE(expr_node);
- if (!is_access(t)) {
- #ifdef ERRNUM
- errmsgn(449, 433, expr_node);
- #else
- errmsg("Renamed entity must be an object", "8.5", expr_node);
- #endif
- }
- tup = tup_new(2);
- tup[1] = (char *) na_obj;
- tup[2] = (char *) t;
- return tup;
- }
- else if (nk == as_ivalue) {
- tup = tup_new(2);
- tup[1] = (char *) na_constant;
- tup[2] = (char *) symbol_any;
- return tup;
- }
- else {
- /*error somewhere.*/
- tup = tup_new(2);
- tup[1] = (char *) na_obj;
- tup[2] = (char *) symbol_any;
- return tup;
- }
- }
- }
-
- void newscope(Symbol new_name) /*;newscope*/
- {
- Tuple tup;
- int old_size;
- int i;
-
- if (cdebug2 > 3) TO_ERRFILE("AT PROC : newscope");
- /*
- * This procedure is invoked when a new lexical scope is entered.
- * Lexical scopes include package specifications, package bodies ,
- * subprogram bodies and entry bodies (ACCEPT statements) . In addition
- * record and task declarations and private parts are treated as scopes.
- * In each case, the environment of the previous scope is stacked
- * and the symbol table for the new scope is initialized.
- */
- if (cdebug2 > 0)
- if (ORIG_NAME(new_name) != (char *) 0)
- printf("new scope %s\n", ORIG_NAME(new_name));
-
- tup = tup_new(4);
- tup[1] = (char *) scope_name;
- tup[2] = (char *) tup_copy(open_scopes);
- tup[3] = (char *) tup_copy(used_mods);
- tup[4] = (char *) tup_copy(vis_mods);
- scope_st = tup_with(scope_st, (char *) tup);
- scope_name = new_name;
-
- if (DECLARED(scope_name) == (Declaredmap)0)
- DECLARED(scope_name) = dcl_new(0);
-
- /* save scope_name if new scope ds 1 aug */
-
- /*open_scopes := [scope_name] + open_scopes;*/
- old_size = tup_size(open_scopes);
- open_scopes = tup_exp(open_scopes, (unsigned) old_size+1);
- for (i = old_size; i >= 1; i--)
- open_scopes[i+1] = (char *) open_scopes[i];
- open_scopes[1] = (char *) scope_name;
- #ifdef TBSN
- suffix :
- = str newat;
- $ For the formation of unique names
- #endif
- }
-
- void popscope() /*;popscope*/
- {
- Tuple tup;
-
- if (cdebug2 > 3)
- TO_ERRFILE("AT PROC : popscope");
- /*
- * Ths procedure is called on exit from a completed lexical scope.
- * Eventually , it should contain various housekeeping functions
- * relating to symbol table statistics and space recovery. For now
- * it simply restores the environment of the enclosing scope.
- *
- * As each scope is closed, a symbol table dump may be done, controled
- * by the value of cdebug2:
- *
- * cdebug2 = 2 : show entries for current scope without signature
- * cdebug2 > 2 : show entries for current scope with signature
- * cdebug2 > 6 : show entries for all user defined scopes
- * cdebug2 = 9 : show entries for all declared scopes
- */
- if (cdebug2 > 1) {
- #ifdef TBSLN
- loop forall scop in
- if cdebug2 = 9 then domain declared
- elseif cdebug2 > 6 then domain(declared) -
- ({
- 'STANDARD#0', 'UNMENTIONABLE#0', 'ASCII' }
- +
- {
- x(2) :
- x in PREDEF_UNITS }
- )
- else {
- scope_name}
- end
- do
- sig_flag :
- = (cdebug2 > 2) and
- exists [item, u_name] in DECLARED(scop) |
- SIGNATURE(u_name) /= om;
- errstr "--- Symbol table entries for declared("+scop+"):";
- TO_ERRFILE(errstr );
- errstr = rpad("Id", 15) + rpad("Unique name", 25) +
- rpad("Nature", 15) + rpad("Type", 24) +
- if sig_flag then " Signature" else "" end;
- TO_ERRFILE(errstr );
- (forall [item, u_name] in DECLARED(scop))
- line :
- = rpad(item ? "", 14);
- line := rpad(line + " " + u_name ? "", 39);
- line := rpad(line + " " + nature(u_name) ? "", 54);
- line := rpad(line + " " +
- if is_string(type_of(u_name)) then type_of(u_name)
- else str type_of(u_name) end, 79);
- if sig_flag and signature(u_name) /= om then
- line +:
- = " " + str signature(u_name);
- end if;
- TO_ERRFILE(line);
- line :
- = str (overloads(u_name)) + " "
- + str scope_of(u_name) + " "
- + str alias(u_name);
- TO_ERRFILE(line);
-
- end forall;
- end loop;
- #endif
- }
- tup = (Tuple) tup_frome(scope_st);
- scope_name = (Symbol) tup[1];
- open_scopes = (Tuple) tup[2];
- used_mods = (Tuple) tup[3];
- vis_mods = (Tuple) tup[4];
- if (cdebug2 > 0) TO_ERRFILE("return to scope: " );
- }
-
- void newmod(char *name) /*;newmod*/
- {
- Symbol new_name;
-
- if (cdebug2 > 3) TO_ERRFILE("AT PROC : newmod");
-
- /* Update this comment*/
-
- #ifdef SKIPTHIS
- -- I think all we need is find_new call
- if (IS_COMP_UNIT){
- /* TBSN- SETL has new_name := name. But in C, name is string, and
- new_name is symbol table pointer. Try replacing with find_new
- new_name = name;
- */
- new_name = find_new(name);
- /* Enter module name in STANDARD*/
- if (dcl_get(DECLARED(scope_name), name) == (Symbol)0) {
- dcl_put(DECLARED(scope_name), name, new_name);
- SCOPE_OF(new_name) = scope_name;
- TO_XREF(new_name);
- }
- else {
- #ifdef ERRNUM
- str_errmsgn(450, name, 143, current_node);
- #else
- errmsg_str("Duplicate declaration of %", name , "8.3", current_node);
- #endif
- }
- }
- else {
- new_name = find_new(name);
- }
- #endif
- new_name = find_new(name);
- ORIG_NAME(new_name) = strjoin(name, "");
- /* Initialize its symbol table and enter scope. */
- DECLARED(new_name) = dcl_new(0);
- /*declared(new_name) := visible(new_name) := {};*/
- newscope(new_name);
- /* and update prefix of names with current module name. */
- #ifdef TBSN
- prefix = prefix + name + '.';
- #endif
- }
-
- void use_clause(Node node) /*;use_clause*/
- {
- /* If the use clause appears within a package specification, it constitutes
- * a declarative item that is visible in the corresponding body, and must
- * be saved in the declared map of the package.
- */
-
- Node id_node;
- char *id;
- Symbol rnam, uds, un;
- Fortup ft1;
- Fordeclared fd;
- int nat;
-
- nat = NATURE(scope_name);
- if (nat == na_package_spec || nat == na_generic_package_spec
- || nat == na_private_part)
- /*use_declarations(scope_name) +:= used;*/
- uds = dcl_get(DECLARED(scope_name), "$used");
- else uds = (Symbol)0;
-
- FORTUP(id_node =(Node), N_LIST(node), ft1);
- id = N_VAL(id_node);
- check_old(id_node);
- rnam = N_UNQ(id_node);
- if (rnam == symbol_undef) {
- #ifdef ERRNUM
- str_errmsgn(451, id, 452, id_node);
- #else
- errmsg_str("undeclared package name %", id, "8.4, 10.1", id_node);
- #endif
- }
- else if (N_OVERLOADED(id_node) ||
- NATURE(rnam)!=na_package && NATURE(rnam) !=na_package_spec){
- #ifdef ERRNUM
- str_errmsgn(453, id, 454, id_node);
- #else
- errmsg_str("% is not the name of a USEable package", id,
- "8.4", id_node);
- #endif
- }
- else {
- if (!tup_mem((char *) rnam, used_mods))
- used_mods = tup_with(used_mods, (char *) rnam);
- /* inner packages defined in a 'used' package can now be used to
- * qualify their inner entities
- */
- if (DECLARED(rnam) != (Declaredmap)0) { /* in case of error */
- FORDECLARED(id, un, DECLARED(rnam), fd);
- if (IS_VISIBLE(fd) && (NATURE(un) == na_package
- || NATURE(un) == na_package_spec))
- vis_mods = tup_with(vis_mods, (char *) un);
- ENDFORDECLARED(fd);
- }
- if (uds != (Symbol)0)
- SIGNATURE(uds) = tup_with(SIGNATURE(uds), (char *)rnam);
- }
- ENDFORTUP(ft1);
- }
-