Pristine Ack-5.5
[Ack-5.5.git] / lang / pc / comp / def.c
1 /* D E F I N I T I O N   M E C H A N I S M */
2
3 #include        "debug.h"
4
5 #include        <alloc.h>
6 #include        <assert.h>
7 #include        <em_arith.h>
8 #include        <em_label.h>
9
10 #include        "LLlex.h"
11 #include        "def.h"
12 #include        "idf.h"
13 #include        "main.h"
14 #include        "misc.h"
15 #include        "node.h"
16 #include        "scope.h"
17 #include        "type.h"
18
19 struct def *
20 MkDef(id, scope, kind)
21         register struct idf *id;
22         register struct scope *scope;
23         long kind;
24 {
25         /*      Create a new definition structure in scope "scope", with
26          *      id "id" and kind "kind".
27          */
28         register struct def *df = new_def();
29
30         df->df_idf = id;
31         df->df_scope = scope;
32         df->df_kind = kind;
33         df->df_type = error_type;
34         df->df_next = id->id_def;
35         id->id_def = df;
36
37         /* enter the definition in the list of definitions in this scope
38         */
39         df->df_nextinscope = scope->sc_def;
40         scope->sc_def = df;
41         return df;
42 }
43
44 struct def *
45 define(id, scope, kind)
46         register struct idf *id;
47         register struct scope *scope;
48         long kind;
49 {
50         /*      Declare an identifier in a scope, but first check if it
51                 already has been defined.
52                 If so, then check for the cases in which this is legal,
53                 and otherwise give an error message.
54         */
55         register struct def *df;
56
57         if( df = lookup(id, scope, 0L) )        {
58                 if (df->df_kind == D_INUSE) {
59                         if( kind != D_INUSE ) {
60                             error("\"%s\" already used in this block",
61                                                         id->id_text);
62                         }
63                         return MkDef(id, scope, kind);
64                 }
65                 if (df->df_kind == D_ERROR ) {
66                         /* used in forward references */
67                         df->df_kind = kind;
68                         return df;
69                 }
70                 /* other cases fit in an int (assume at least 2 bytes) */
71                 switch((int) df->df_kind )      {
72
73                     case D_LABEL :
74                         /* generate error message somewhere else */
75                         return NULLDEF;
76
77                     case D_PARAMETER :
78                         if( kind == D_VARIABLE )
79                         /* program parameter declared as variable */
80                                 return df;
81                         break;
82
83                     case D_FORWTYPE :
84                         if( kind == D_FORWTYPE ) return df;
85                         if( kind == D_TYPE )    {
86                         /* forward reference resolved */
87                                 df->df_kind = D_FTYPE;
88                                 return df;
89                         }
90                         else
91                                 error("identifier \"%s\" must be a type",
92                                                         id->id_text);
93                         return NULLDEF;
94
95                     case D_FWPROCEDURE :
96                         if( kind == D_PROCEDURE ) return df;
97                         error("procedure identification \"%s\" expected",
98                                                                 id->id_text);
99                         return NULLDEF;
100
101                     case D_FWFUNCTION :
102                         if( kind == D_FUNCTION ) return df;
103                         error("function identification \"%s\" expected",
104                                                                 id->id_text);
105                         return NULLDEF;
106
107                 }
108                 if( kind != D_ERROR )
109                         /* avoid spurious error messages */
110                         error("identifier \"%s\" already declared",id->id_text);
111
112                 return NULLDEF;
113         }
114
115         return MkDef(id, scope, kind);
116 }
117
118 DoDirective(directive, nd, tp, scl, function)
119         struct idf *directive;
120         struct node *nd;
121         struct type *tp;
122         struct scopelist *scl;
123 {
124         long kind;                      /* kind of directive */
125         int inp;                        /* internal or external name */
126         int ext = 0;            /* directive = EXTERN */
127         struct def *df = lookup(directive, PervasiveScope, D_INUSE);
128
129         if( !df )       {
130                 if( !is_anon_idf(directive) )
131                         node_error(nd, "\"%s\" unknown directive",
132                                                         directive->id_text);
133                 return;
134         }
135
136         if (df->df_kind == D_FORWARD) {
137                 kind = function ? D_FWFUNCTION : D_FWPROCEDURE;
138                 inp = (proclevel > 1);
139         }
140         else if (df->df_kind == D_EXTERN) {
141                 kind = function ? D_FUNCTION : D_PROCEDURE;
142                 inp = 0;
143                 ext = 1;
144         }
145         else {
146                 node_error(nd, "\"%s\" unknown directive",
147                                                 directive->id_text);
148                 return;
149         }
150
151         if( df = define(nd->nd_IDF, CurrentScope, kind) )       {
152                 if( df->df_kind != kind )       {
153                         /* identifier already forward declared */
154                         node_error(nd, "\"%s\" already forward declared",
155                                                         nd->nd_IDF->id_text);
156                         return;
157                 }
158
159                 df->df_type = tp;
160                 df->prc_vis = scl;
161                 df->prc_name = gen_proc_name(nd->nd_IDF, inp);
162                 if( ext ) {
163                         if (!(df->df_flags & D_EXTERNAL) && proclevel > 1)
164                                 tp->prc_nbpar -= pointer_size;
165                         /* was added for static link which is not needed now.
166                            But make sure this is done only once (look at the
167                            D_EXTERNAL flag).
168                         */
169                         df->df_flags |= D_EXTERNAL;
170                 }
171                 df->df_flags |= D_SET;
172         }
173 }
174
175 struct def *
176 DeclProc(nd, tp, scl)
177         register struct node *nd;
178         struct type *tp;
179         register struct scopelist *scl;
180 {
181         register struct def *df;
182
183         if( df = define(nd->nd_IDF, CurrentScope, D_PROCEDURE) )        {
184                 df->df_flags |= D_SET;
185                 if( df->df_kind == D_FWPROCEDURE )      {
186                         df->df_kind = D_PROCEDURE;      /* identification */
187
188                         /* Simulate a call to open_scope(), which has already
189                          * been performed in the forward declaration.
190                          */
191                         CurrVis = df->prc_vis;
192
193                         if( tp->prc_params )
194                                 node_error(nd,
195                                   "\"%s\" already declared",
196                                                         nd->nd_IDF->id_text);
197                 }
198                 else    {       /* normal declaration */
199                         df->df_type = tp;
200                         df->prc_name = gen_proc_name(nd->nd_IDF, (proclevel>1));
201                         /* simulate open_scope() */
202                         CurrVis = df->prc_vis = scl;
203                 }
204                 routine_label(df);
205         }
206         else CurrVis = scl;             /* simulate open_scope() */
207
208         return df;
209 }
210
211 struct def *
212 DeclFunc(nd, tp, scl)
213         register struct node *nd;
214         struct type *tp;
215         register struct scopelist *scl;
216 {
217         register struct def *df;
218
219         if( df = define(nd->nd_IDF, CurrentScope, D_FUNCTION) ) {
220             df->df_flags &= ~D_SET;
221             if( df->df_kind == D_FUNCTION )     {       /* declaration */
222                 if( !tp )       {
223                         node_error(nd, "\"%s\" illegal function declaration",
224                                                         nd->nd_IDF->id_text);
225                         tp = construct_type(T_FUNCTION, error_type);
226                 }
227                 /* simulate open_scope() */
228                 CurrVis = df->prc_vis = scl;
229                 df->df_type = tp;
230                 df->prc_name = gen_proc_name(nd->nd_IDF, (proclevel > 1));
231             }
232             else        {                       /* identification */
233                 assert(df->df_kind == D_FWFUNCTION);
234
235                 df->df_kind = D_FUNCTION;
236                 CurrVis = df->prc_vis;
237
238                 if( tp )
239                         node_error(nd,
240                                    "\"%s\" already declared",
241                                    nd->nd_IDF->id_text);
242
243             }
244             routine_label(df);
245         }
246         else CurrVis = scl;                     /* simulate open_scope() */
247
248         return df;
249 }
250
251 EndFunc(df)
252         register struct def *df;
253 {
254         /* assignment to functionname is illegal outside the functionblock */
255         df->prc_res = 0;
256
257         /* Give the error about assignment as soon as possible. The
258          * |= assignment inhibits a warning in the main procedure.
259          */
260         if( !(df->df_flags & D_SET) ) {
261                 error("function \"%s\" not assigned",df->df_idf->id_text);
262                 df->df_flags |= D_SET;
263         }
264 }
265
266 EndBlock(block_df)
267         register struct def *block_df;
268 {
269         register struct def *tmp_def = CurrentScope->sc_def;
270         register struct def *df;
271
272         while( tmp_def ) {
273             df = tmp_def;
274                 /* The length of a usd_def chain is at most 1.
275                  * The while is just defensive programming.
276                  */
277             while( df->df_kind & D_INUSE )
278                 df = df->usd_def;
279
280             if( !is_anon_idf(df->df_idf)
281                     && (df->df_scope == CurrentScope) ) {
282                 if( !(df->df_kind & (D_ENUM|D_LABEL|D_ERROR)) ) {
283                     if( !(df->df_flags & D_USED) ) {
284                         if( !(df->df_flags & D_SET) ) {
285                             warning("\"%s\" neither set nor used in \"%s\"",
286                                 df->df_idf->id_text, block_df->df_idf->id_text);
287                         }
288                         else {
289                             warning("\"%s\" unused in \"%s\"",
290                                 df->df_idf->id_text, block_df->df_idf->id_text);
291                         }
292                     }
293                     else if( !(df->df_flags & D_SET) ) {
294                         if( !(df->df_flags & D_LOOPVAR) )
295                             warning("\"%s\" not set in \"%s\"",
296                                 df->df_idf->id_text, block_df->df_idf->id_text);
297                     }
298                 }
299
300             }
301             tmp_def = tmp_def->df_nextinscope;
302         }
303 }