]> sourceware.org Git - systemtap.git/blame - elaborate.cxx
2005-06-03 Frank Ch. Eigler <fche@redhat.com>
[systemtap.git] / elaborate.cxx
CommitLineData
2b066ec1 1// elaboration functions
69c68955
FCE
2// Copyright (C) 2005 Red Hat Inc.
3//
4// This file is part of systemtap, and is free software. You can
5// redistribute it and/or modify it under the terms of the GNU General
6// Public License (GPL); either version 2, or (at your option) any
7// later version.
2b066ec1
FCE
8
9#include "config.h"
10#include "elaborate.h"
11#include "parse.h"
12
13extern "C" {
14#include <sys/utsname.h>
15}
16
17#include <fstream>
18#include <algorithm>
19
20#if 0
21#ifdef HAVE_ELFUTILS_LIBDW_H
22#include <elfutils/libdw.h>
23#else
24#error "need <elfutils/libdw.h>"
25#endif
26#endif
27
28using namespace std;
29
30
31// ------------------------------------------------------------------------
32
33
34derived_probe::derived_probe (probe *p):
35 base (p)
36{
37 this->locations = p->locations;
38 this->tok = p->tok;
39 this->body = p->body;
40 this->locals = p->locals;
41}
42
43
44derived_probe::derived_probe (probe *p, probe_point *l):
45 base (p)
46{
47 this->locations.push_back (l);
48 this->tok = p->tok;
49 this->body = p->body;
50 this->locals = p->locals;
51}
52
53
54// ------------------------------------------------------------------------
55
56
57static int semantic_pass_symbols (systemtap_session&);
58static int semantic_pass_types (systemtap_session&);
59
60
61
62// Link up symbols to their declarations. Set the session's
63// files/probes/functions/globals vectors from the transitively
64// reached set of stapfiles in s.library_files, starting from
65// s.user_file. Perform automatic tapset inclusion and XXX: probe
66// alias expansion.
67static int
68semantic_pass_symbols (systemtap_session& s)
69{
70 symresolution_info sym (s);
71
72 // NB: s.files can grow during this iteration, so size() can
73 // return gradually increasing numbers.
74 s.files.push_back (s.user_file);
75 for (unsigned i = 0; i < s.files.size(); i++)
76 {
77 stapfile* dome = s.files[i];
78
79 // Pass 1: add globals and functions to systemtap-session master list,
80 // so the find_* functions find them
81
82 for (unsigned i=0; i<dome->globals.size(); i++)
83 s.globals.push_back (dome->globals[i]);
84
85 for (unsigned i=0; i<dome->functions.size(); i++)
86 s.functions.push_back (dome->functions[i]);
87
88 // Pass 2: process functions
89
90 for (unsigned i=0; i<dome->functions.size(); i++)
91 {
92 functiondecl* fd = dome->functions[i];
93
94 try
95 {
96 sym.current_function = fd;
97 sym.current_probe = 0;
98 fd->body->visit (& sym);
99 }
100 catch (const semantic_error& e)
101 {
102 s.print_error (e);
103 }
104 }
105
106 // Pass 3: process probes
107
108 for (unsigned i=0; i<dome->probes.size(); i++)
109 {
110 probe* p = dome->probes [i];
111 vector<derived_probe*> dps;
112
113 try
114 {
115 // much magic happens here: probe alias expansion,
116 // provider identification
117 sym.derive_probes (p, dps);
118 }
119 catch (const semantic_error& e)
120 {
121 s.print_error (e);
122 // dps.erase (dps.begin(), dps.end());
123 }
124
125 for (unsigned j=0; j<dps.size(); j++)
126 {
127 derived_probe* dp = dps[j];
128 s.probes.push_back (dp);
129
130 try
131 {
132 sym.current_function = 0;
133 sym.current_probe = dp;
134 dp->body->visit (& sym);
135 }
136 catch (const semantic_error& e)
137 {
138 s.print_error (e);
139 }
140 }
141 }
142 }
143
144 return s.num_errors; // all those print_error calls
145}
146
147
148
149int
150semantic_pass (systemtap_session& s)
151{
152 int rc = semantic_pass_symbols (s);
153 if (rc == 0) rc = semantic_pass_types (s);
154 return rc;
155}
156
157
158// ------------------------------------------------------------------------
159
160
161systemtap_session::systemtap_session ():
162 user_file (0), op (0), up (0), num_errors (0)
163{
164}
165
166
167void
168systemtap_session::print_error (const semantic_error& e)
169{
170 cerr << "semantic error: " << e.what () << ": ";
171 if (e.tok1) cerr << *e.tok1;
172 cerr << e.msg2;
173 if (e.tok2) cerr << *e.tok2;
174 cerr << endl;
175 num_errors ++;
176}
177
178
179// ------------------------------------------------------------------------
180// semantic processing: symbol resolution
181
182
183symresolution_info::symresolution_info (systemtap_session& s):
184 session (s), current_function (0), current_probe (0)
185{
186}
187
188
189void
190symresolution_info::visit_block (block* e)
191{
192 for (unsigned i=0; i<e->statements.size(); i++)
193 {
194 try
195 {
196 e->statements[i]->visit (this);
197 }
198 catch (const semantic_error& e)
199 {
200 session.print_error (e);
201 }
202 }
203}
204
205
69c68955
FCE
206void
207symresolution_info::visit_foreach_loop (foreach_loop* e)
208{
209 for (unsigned i=0; i<e->indexes.size(); i++)
210 e->indexes[i]->visit (this);
211
212 if (e->base_referent)
213 return;
214
215 vardecl* d = find_array (e->base, e->indexes.size ());
216 if (d)
217 e->base_referent = d;
218 else
219 throw semantic_error ("unresolved global array " + e->base, e->tok);
220
221 e->block->visit (this);
222}
223
224
2b066ec1
FCE
225void
226symresolution_info::visit_symbol (symbol* e)
227{
228 if (e->referent)
229 return;
230
231 vardecl* d = find_scalar (e->name);
232 if (d)
233 e->referent = d;
234 else
235 {
236 // new local
237 vardecl* v = new vardecl;
238 v->name = e->name;
239 v->tok = e->tok;
240 if (current_function)
241 current_function->locals.push_back (v);
242 else if (current_probe)
243 current_probe->locals.push_back (v);
244 else
ce10591c
FCE
245 // must not happen
246 throw semantic_error ("no current probe/function", e->tok);
2b066ec1
FCE
247 e->referent = v;
248 }
249}
250
251
252void
253symresolution_info::visit_arrayindex (arrayindex* e)
254{
255 for (unsigned i=0; i<e->indexes.size(); i++)
256 e->indexes[i]->visit (this);
257
258 if (e->referent)
259 return;
260
261 vardecl* d = find_array (e->base, e->indexes.size ());
262 if (d)
263 e->referent = d;
264 else
265 throw semantic_error ("unresolved global array", e->tok);
266}
267
268
269void
270symresolution_info::visit_functioncall (functioncall* e)
271{
272 for (unsigned i=0; i<e->args.size(); i++)
273 e->args[i]->visit (this);
274
275 if (e->referent)
276 return;
277
278 functiondecl* d = find_function (e->function, e->args.size ());
279 if (d)
280 e->referent = d;
281 else
282 throw semantic_error ("unresolved function call", e->tok);
283}
284
285
286vardecl*
287symresolution_info::find_scalar (const string& name)
288{
289 // search locals
290 vector<vardecl*>& locals = (current_function ?
291 current_function->locals :
292 current_probe->locals);
293 for (unsigned i=0; i<locals.size(); i++)
294 if (locals[i]->name == name)
295 // NB: no need to check arity here: locals always scalar
296 return locals[i];
297
298 // search function formal parameters (if any)
299 if (current_function)
300 for (unsigned i=0; i<current_function->formal_args.size(); i++)
301 if (current_function->formal_args[i]->name == name)
302 // NB: no need to check arity here: formal args always scalar
303 return current_function->formal_args[i];
304
305 // search globals
306 for (unsigned i=0; i<session.globals.size(); i++)
307 if (session.globals[i]->name == name)
308 if (session.globals[i]->arity <= 0)
309 {
310 session.globals[i]->set_arity (0);
311 return session.globals[i];
312 }
313
314 // search library globals
315 for (unsigned i=0; i<session.library_files.size(); i++)
316 {
317 stapfile* f = session.library_files[i];
318 for (unsigned j=0; j<f->globals.size(); j++)
319 if (f->globals[j]->name == name &&
320 f->globals[j]->index_types.size() == 0)
321 {
322 // put library into the queue if not already there
323 if (0) // (session.verbose_resolution)
324 cerr << " scalar " << name << " "
325 << "is defined from " << f->name << endl;
326
327 if (find (session.files.begin(), session.files.end(), f)
328 == session.files.end())
329 session.files.push_back (f);
330 // else .. print different message?
331
332 return f->globals[j];
333 }
334 }
335
336 // search builtins that become locals
337 // XXX: need to invent a proper formalism for this
338 if (name == "$pid" || name == "$tid")
339 {
340 vardecl_builtin* vb = new vardecl_builtin;
341 vb->name = name;
342 vb->type = pe_long;
343
344 // XXX: need a better way to synthesize tokens
345 token* t = new token;
346 t->type = tok_identifier;
347 t->content = name;
348 t->location.file = "<builtin>";
349 vb->tok = t;
350
351 locals.push_back (vb);
352 return vb;
353 }
354
355 return 0;
356 // XXX: add checking for conflicting array or function
357}
358
359
360vardecl*
361symresolution_info::find_array (const string& name, unsigned arity)
362{
363 // search processed globals
364 for (unsigned i=0; i<session.globals.size(); i++)
365 if (session.globals[i]->name == name)
ce10591c 366 if ((arity > 0 && (session.globals[i]->arity == (int) arity)) ||
2b066ec1
FCE
367 session.globals[i]->arity < 0)
368 {
ce10591c
FCE
369 if (arity > 0)
370 session.globals[i]->set_arity (arity);
2b066ec1
FCE
371 return session.globals[i];
372 }
373
374 // search library globals
375 for (unsigned i=0; i<session.library_files.size(); i++)
376 {
377 stapfile* f = session.library_files[i];
378 for (unsigned j=0; j<f->globals.size(); j++)
bed7c0af 379 if (f->globals[j]->name == name)
ce10591c 380 if ((arity > 0 && (f->globals[j]->arity == (int) arity)) ||
bed7c0af 381 f->globals[j]->arity < 0)
2b066ec1 382 {
ce10591c
FCE
383 if (arity > 0)
384 f->globals[j]->set_arity (arity);
bed7c0af 385
2b066ec1
FCE
386 // put library into the queue if not already there
387 if (0) // (session.verbose_resolution)
388 cerr << " array " << name << " "
389 << "is defined from " << f->name << endl;
390
391 if (find (session.files.begin(), session.files.end(), f)
392 == session.files.end())
393 session.files.push_back (f);
394 // else .. print different message?
395
396 return f->globals[j];
397 }
398 }
399
400 return 0;
401 // XXX: add checking for conflicting scalar or function
402}
403
404
405functiondecl*
406symresolution_info::find_function (const string& name, unsigned arity)
407{
408 for (unsigned j = 0; j < session.functions.size(); j++)
409 {
410 functiondecl* fd = session.functions[j];
411 if (fd->name == name &&
412 fd->formal_args.size() == arity)
413 return fd;
414 }
415
416 // search library globals
417 for (unsigned i=0; i<session.library_files.size(); i++)
418 {
419 stapfile* f = session.library_files[i];
420 for (unsigned j=0; j<f->functions.size(); j++)
421 if (f->functions[j]->name == name &&
422 f->functions[j]->formal_args.size() == arity)
423 {
424 // put library into the queue if not already there
425 if (0) // session.verbose_resolution
426 cerr << " function " << name << " "
427 << "is defined from " << f->name << endl;
428
429 if (find (session.files.begin(), session.files.end(), f)
430 == session.files.end())
431 session.files.push_back (f);
432 // else .. print different message?
433
434 return f->functions[j];
435 }
436 }
437
438 return 0;
439 // XXX: add checking for conflicting variables
440}
441
442
443// ------------------------------------------------------------------------
444// type resolution
445
446
447static int
448semantic_pass_types (systemtap_session& s)
449{
450 int rc = 0;
451
452 // next pass: type inference
453 unsigned iterations = 0;
454 typeresolution_info ti (s);
455
456 ti.assert_resolvability = false;
457 // XXX: maybe convert to exception-based error signalling
458 while (1)
459 {
460 iterations ++;
461 // cerr << "Type resolution, iteration " << iterations << endl;
462 ti.num_newly_resolved = 0;
463 ti.num_still_unresolved = 0;
464
465 for (unsigned j=0; j<s.functions.size(); j++)
466 {
467 functiondecl* fn = s.functions[j];
468 ti.current_function = fn;
469 ti.t = pe_unknown;
470 fn->body->visit (& ti);
471 // NB: we don't have to assert a known type for
472 // functions here, to permit a "void" function.
473 // The translator phase will omit the "retvalue".
474 //
475 // if (fn->type == pe_unknown)
476 // ti.unresolved (fn->tok);
477 }
478
479 for (unsigned j=0; j<s.probes.size(); j++)
480 {
481 derived_probe* pn = s.probes[j];
482 ti.current_function = 0;
483 ti.t = pe_unknown;
484 pn->body->visit (& ti);
485 }
486
487 for (unsigned j=0; j<s.globals.size(); j++)
488 {
489 vardecl* gd = s.globals[j];
490 if (gd->type == pe_unknown)
491 ti.unresolved (gd->tok);
492 }
493
494 if (ti.num_newly_resolved == 0) // converged
495 if (ti.num_still_unresolved == 0)
496 break; // successfully
497 else if (! ti.assert_resolvability)
498 ti.assert_resolvability = true; // last pass, with error msgs
499 else
500 { // unsuccessful conclusion
501 rc ++;
502 break;
503 }
504 }
505
506 return rc + s.num_errors;
507}
508
509
510void
511typeresolution_info::visit_literal_number (literal_number* e)
512{
513 assert (e->type == pe_long);
514 if ((t == e->type) || (t == pe_unknown))
515 return;
516
517 mismatch (e->tok, e->type, t);
518}
519
520
521void
522typeresolution_info::visit_literal_string (literal_string* e)
523{
524 assert (e->type == pe_string);
525 if ((t == e->type) || (t == pe_unknown))
526 return;
527
528 mismatch (e->tok, e->type, t);
529}
530
531
532void
533typeresolution_info::visit_logical_or_expr (logical_or_expr *e)
534{
535 visit_binary_expression (e);
536}
537
538
539void
540typeresolution_info::visit_logical_and_expr (logical_and_expr *e)
541{
542 visit_binary_expression (e);
543}
544
545
546void
547typeresolution_info::visit_comparison (comparison *e)
548{
549 visit_binary_expression (e);
550}
551
552
553void
554typeresolution_info::visit_concatenation (concatenation *e)
555{
556 visit_binary_expression (e);
557}
558
559
560void
561typeresolution_info::visit_exponentiation (exponentiation *e)
562{
563 visit_binary_expression (e);
564}
565
566
567void
568typeresolution_info::visit_assignment (assignment *e)
569{
570 visit_binary_expression (e);
571}
572
573
574void
575typeresolution_info::visit_binary_expression (binary_expression* e)
576{
577 if (e->op == "<<<") // stats aggregation
578 {
579 exp_type t1 = t;
580 t = pe_stats;
581 e->left->visit (this);
582 t = pe_long;
583 e->right->visit (this);
584 if (t1 == pe_stats || t1 == pe_string)
585 invalid (e->tok, t1);
586 else if (e->type == pe_unknown)
587 {
588 e->type = pe_long;
589 resolved (e->tok, e->type);
590 }
591 }
592 else if (e->op == ".") // string concatenation
593 {
594 exp_type t1 = t;
595 t = pe_string;
596 e->left->visit (this);
597 t = pe_string;
598 e->right->visit (this);
599 if (t1 == pe_long || t1 == pe_stats)
600 mismatch (e->tok, t1, pe_string);
601 else if (e->type == pe_unknown)
602 {
603 e->type = pe_string;
604 resolved (e->tok, e->type);
605 }
606 }
607 else if (e->op == "=="
608 || false) // XXX: other comparison operators
609 {
610 exp_type t1 = t;
611 t = pe_unknown;
612 e->left->visit (this);
613 t = pe_unknown;
614 e->right->visit (this);
615 if (t1 == pe_string || t1 == pe_stats)
616 mismatch (e->tok, t1, pe_long);
617 else if (e->type == pe_unknown)
618 {
619 e->type = pe_long;
620 resolved (e->tok, e->type);
621 }
622 }
623 else // general arithmetic operators?
624 {
625 // propagate e->type downward
626 exp_type sub_type = t;
627 if ((sub_type == pe_unknown) && (e->type != pe_unknown))
628 sub_type = e->type;
629 t = sub_type;
630 e->left->visit (this);
631 t = sub_type;
632 e->right->visit (this);
633
634 if ((sub_type == pe_unknown) && (e->type != pe_unknown))
635 ; // already resolved
636 else if ((sub_type != pe_unknown) && (e->type == pe_unknown))
637 {
638 e->type = sub_type;
639 resolved (e->tok, e->type);
640 }
641 else if ((sub_type == pe_unknown) && (e->left->type != pe_unknown))
642 {
643 e->type = e->left->type;
644 resolved (e->tok, e->type);
645 }
646 else if ((sub_type == pe_unknown) && (e->right->type != pe_unknown))
647 {
648 e->type = e->right->type;
649 resolved (e->tok, e->type);
650 }
651 else if (e->type != sub_type)
652 mismatch (e->tok, sub_type, e->type);
653 }
654}
655
656
657void
658typeresolution_info::visit_pre_crement (pre_crement *e)
659{
660 visit_unary_expression (e);
661}
662
663
664void
665typeresolution_info::visit_post_crement (post_crement *e)
666{
667 visit_unary_expression (e);
668}
669
670
671void
672typeresolution_info::visit_unary_expression (unary_expression* e)
673{
674 // all unary operators only work on numerics
675 exp_type t1 = t;
676 t = pe_long;
677 e->operand->visit (this);
678
679 if (t1 == pe_unknown && e->type != pe_unknown)
680 ; // already resolved
681 else if (t1 == pe_string || t1 == pe_stats)
682 mismatch (e->tok, t1, pe_long);
683 else if (e->type == pe_unknown)
684 {
685 e->type = pe_long;
686 resolved (e->tok, e->type);
687 }
688}
689
690
691
692void
693typeresolution_info::visit_ternary_expression (ternary_expression* e)
694{
695 exp_type sub_type = t;
696
697 t = pe_long;
698 e->cond->visit (this);
699
700 // Match ordinary binary_expression type inference for the true/false
701 // arms of the ternary expression.
702
703 if (sub_type == pe_unknown && e->type != pe_unknown)
704 sub_type = e->type;
705 t = sub_type;
706 e->truevalue->visit (this);
707 t = sub_type;
708 e->falsevalue->visit (this);
709
710 if ((sub_type == pe_unknown) && (e->type != pe_unknown))
711 ; // already resolved
712 else if ((sub_type != pe_unknown) && (e->type == pe_unknown))
713 {
714 e->type = sub_type;
715 resolved (e->tok, e->type);
716 }
717 else if ((sub_type == pe_unknown) && (e->truevalue->type != pe_unknown))
718 {
719 e->type = e->truevalue->type;
720 resolved (e->tok, e->type);
721 }
722 else if ((sub_type == pe_unknown) && (e->falsevalue->type != pe_unknown))
723 {
724 e->type = e->falsevalue->type;
725 resolved (e->tok, e->type);
726 }
727 else if (e->type != sub_type)
728 mismatch (e->tok, sub_type, e->type);
729}
730
731
732template <class Referrer, class Referent>
733void resolve_2types (Referrer* referrer, Referent* referent,
734 typeresolution_info* r, exp_type t)
735{
736 exp_type& re_type = referrer->type;
737 const token* re_tok = referrer->tok;
738 exp_type& te_type = referent->type;
739 const token* te_tok = referent->tok;
740
741 if (t != pe_unknown && re_type == t && re_type == te_type)
742 ; // do nothing: all three e->types in agreement
743 else if (t == pe_unknown && re_type != pe_unknown && re_type == te_type)
744 ; // do nothing: two known e->types in agreement
745 else if (re_type != pe_unknown && te_type != pe_unknown && re_type != te_type)
746 r->mismatch (re_tok, re_type, te_type);
747 else if (re_type != pe_unknown && t != pe_unknown && re_type != t)
748 r->mismatch (re_tok, re_type, t);
749 else if (te_type != pe_unknown && t != pe_unknown && te_type != t)
750 r->mismatch (te_tok, te_type, t);
751 else if (re_type == pe_unknown && t != pe_unknown)
752 {
753 // propagate from upstream
754 re_type = t;
755 r->resolved (re_tok, re_type);
756 // catch re_type/te_type mismatch later
757 }
758 else if (re_type == pe_unknown && te_type != pe_unknown)
759 {
760 // propagate from referent
761 re_type = te_type;
762 r->resolved (re_tok, re_type);
763 // catch re_type/t mismatch later
764 }
765 else if (re_type != pe_unknown && te_type == pe_unknown)
766 {
767 // propagate to referent
768 te_type = re_type;
769 r->resolved (te_tok, te_type);
770 // catch re_type/t mismatch later
771 }
772 else
773 r->unresolved (re_tok);
774}
775
776
777void
778typeresolution_info::visit_symbol (symbol* e)
779{
780 assert (e->referent != 0);
781
782 if (e->referent->arity > 0)
783 unresolved (e->tok); // symbol resolution should not permit this
784 // XXX: but consider "delete <array>;" and similar constructs
785 else
786 resolve_2types (e, e->referent, this, t);
787}
788
789
790void
791typeresolution_info::visit_arrayindex (arrayindex* e)
792{
793 assert (e->referent != 0);
794
795 resolve_2types (e, e->referent, this, t);
796
797 // now resolve the array indexes
69c68955
FCE
798
799 // if (e->referent->index_types.size() == 0)
800 // // redesignate referent as array
801 // e->referent->set_arity (e->indexes.size ());
2b066ec1
FCE
802
803 if (e->indexes.size() != e->referent->index_types.size())
804 unresolved (e->tok); // symbol resolution should prevent this
805 else for (unsigned i=0; i<e->indexes.size(); i++)
806 {
807 expression* ee = e->indexes[i];
808 exp_type& ft = e->referent->index_types [i];
809 t = ft;
810 ee->visit (this);
811 exp_type at = ee->type;
812
813 if ((at == pe_string || at == pe_long) && ft == pe_unknown)
814 {
815 // propagate to formal type
816 ft = at;
817 resolved (e->referent->tok, ft);
818 // uses array decl as there is no token for "formal type"
819 }
820 if (at == pe_stats)
821 invalid (ee->tok, at);
822 if (ft == pe_stats)
823 invalid (ee->tok, ft);
824 if (at != pe_unknown && ft != pe_unknown && ft != at)
825 mismatch (e->tok, at, ft);
826 if (at == pe_unknown)
827 unresolved (ee->tok);
828 }
829}
830
831
832void
833typeresolution_info::visit_functioncall (functioncall* e)
834{
835 assert (e->referent != 0);
836
837 resolve_2types (e, e->referent, this, t);
838
839 if (e->type == pe_stats)
840 invalid (e->tok, e->type);
841
842 // XXX: but what about functions that return no value,
843 // and are used only as an expression-statement for side effects?
844
845 // now resolve the function parameters
846 if (e->args.size() != e->referent->formal_args.size())
847 unresolved (e->tok); // symbol resolution should prevent this
848 else for (unsigned i=0; i<e->args.size(); i++)
849 {
850 expression* ee = e->args[i];
851 exp_type& ft = e->referent->formal_args[i]->type;
852 const token* fe_tok = e->referent->formal_args[i]->tok;
853 t = ft;
854 ee->visit (this);
855 exp_type at = ee->type;
856
857 if (((at == pe_string) || (at == pe_long)) && ft == pe_unknown)
858 {
859 // propagate to formal arg
860 ft = at;
861 resolved (e->referent->formal_args[i]->tok, ft);
862 }
863 if (at == pe_stats)
864 invalid (e->tok, at);
865 if (ft == pe_stats)
866 invalid (fe_tok, ft);
867 if (at != pe_unknown && ft != pe_unknown && ft != at)
868 mismatch (e->tok, at, ft);
869 if (at == pe_unknown)
870 unresolved (e->tok);
871 }
872}
873
874
875void
876typeresolution_info::visit_block (block* e)
877{
878 for (unsigned i=0; i<e->statements.size(); i++)
879 {
880 try
881 {
882 t = pe_unknown;
883 e->statements[i]->visit (this);
884 }
885 catch (const semantic_error& e)
886 {
887 session.print_error (e);
888 }
889 }
890}
891
892
893void
894typeresolution_info::visit_if_statement (if_statement* e)
895{
896 t = pe_long;
897 e->condition->visit (this);
898
899 t = pe_unknown;
900 e->thenblock->visit (this);
901
902 if (e->elseblock)
903 {
904 t = pe_unknown;
905 e->elseblock->visit (this);
906 }
907}
908
909
910void
911typeresolution_info::visit_for_loop (for_loop* e)
912{
913 t = pe_unknown;
914 e->init->visit (this);
915 t = pe_long;
916 e->cond->visit (this);
917 t = pe_unknown;
918 e->incr->visit (this);
919 t = pe_unknown;
920 e->block->visit (this);
921}
922
923
69c68955
FCE
924void
925typeresolution_info::visit_foreach_loop (foreach_loop* e)
926{
927 // See also visit_arrayindex.
928 // This is different in that, being a statement, we can't assign
929 // a type to the outer array, only propagate to/from the indexes
930
931 // if (e->referent->index_types.size() == 0)
932 // // redesignate referent as array
933 // e->referent->set_arity (e->indexes.size ());
934
935 if (e->indexes.size() != e->base_referent->index_types.size())
936 unresolved (e->tok); // symbol resolution should prevent this
937 else for (unsigned i=0; i<e->indexes.size(); i++)
938 {
939 expression* ee = e->indexes[i];
940 exp_type& ft = e->base_referent->index_types [i];
941 t = ft;
942 ee->visit (this);
943 exp_type at = ee->type;
944
945 if ((at == pe_string || at == pe_long) && ft == pe_unknown)
946 {
947 // propagate to formal type
948 ft = at;
949 resolved (e->base_referent->tok, ft);
950 // uses array decl as there is no token for "formal type"
951 }
952 if (at == pe_stats)
953 invalid (ee->tok, at);
954 if (ft == pe_stats)
955 invalid (ee->tok, ft);
956 if (at != pe_unknown && ft != pe_unknown && ft != at)
957 mismatch (e->tok, at, ft);
958 if (at == pe_unknown)
959 unresolved (ee->tok);
960 }
961
962 t = pe_unknown;
963 e->block->visit (this);
964}
965
966
2b066ec1
FCE
967void
968typeresolution_info::visit_null_statement (null_statement* e)
969{
970}
971
972
973void
974typeresolution_info::visit_expr_statement (expr_statement* e)
975{
976 t = pe_unknown;
977 e->value->visit (this);
978}
979
980
981void
982typeresolution_info::visit_delete_statement (delete_statement* e)
983{
984 // XXX: not yet supported
985 unresolved (e->tok);
986}
987
988
989void
990typeresolution_info::visit_array_in (array_in* e)
991{
ce10591c
FCE
992 // all unary operators only work on numerics
993 exp_type t1 = t;
994 t = pe_unknown; // array value can be anything
995 e->operand->visit (this);
996
997 if (t1 == pe_unknown && e->type != pe_unknown)
998 ; // already resolved
999 else if (t1 == pe_string || t1 == pe_stats)
1000 mismatch (e->tok, t1, pe_long);
1001 else if (e->type == pe_unknown)
1002 {
1003 e->type = pe_long;
1004 resolved (e->tok, e->type);
1005 }
2b066ec1
FCE
1006}
1007
1008
1009void
1010typeresolution_info::visit_return_statement (return_statement* e)
1011{
1012 // This is like symbol, where the referent is
1013 // the return value of the function.
1014
1015 // XXX: need control flow semantic checking; until then:
1016 if (current_function == 0)
1017 {
1018 unresolved (e->tok);
1019 return;
1020 }
1021
1022 exp_type& e_type = current_function->type;
1023 t = current_function->type;
1024 e->value->visit (this);
1025
1026 if (e_type != pe_unknown && e->value->type != pe_unknown
1027 && e_type != e->value->type)
1028 mismatch (current_function->tok, e_type, e->value->type);
1029 if (e_type == pe_unknown &&
1030 (e->value->type == pe_long || e->value->type == pe_string))
1031 {
1032 // propagate non-statistics from value
1033 e_type = e->value->type;
1034 resolved (current_function->tok, e->value->type);
1035 }
1036 if (e->value->type == pe_stats)
1037 invalid (e->value->tok, e->value->type);
1038}
1039
1040
1041void
1042typeresolution_info::unresolved (const token* tok)
1043{
1044 num_still_unresolved ++;
1045
1046 if (assert_resolvability)
1047 {
1048 cerr << "error: unresolved type for ";
1049 if (tok)
1050 cerr << *tok;
1051 else
1052 cerr << "a token";
1053 cerr << endl;
1054 }
1055}
1056
1057
1058void
1059typeresolution_info::invalid (const token* tok, exp_type pe)
1060{
1061 num_still_unresolved ++;
1062
1063 if (assert_resolvability)
1064 {
1065 cerr << "error: invalid type " << pe << " for ";
1066 if (tok)
1067 cerr << *tok;
1068 else
1069 cerr << "a token";
1070 cerr << endl;
1071 }
1072}
1073
1074
1075void
1076typeresolution_info::mismatch (const token* tok, exp_type t1, exp_type t2)
1077{
1078 num_still_unresolved ++;
1079
1080 if (assert_resolvability)
1081 {
1082 cerr << "error: type mismatch for ";
1083 if (tok)
1084 cerr << *tok;
1085 else
1086 cerr << "a token";
1087 cerr << ": " << t1 << " vs. " << t2 << endl;
1088 }
1089}
1090
1091
1092void
1093typeresolution_info::resolved (const token* tok, exp_type t)
1094{
1095 num_newly_resolved ++;
1096 // cerr << "resolved " << *e->tok << " type " << t << endl;
1097}
1098
This page took 0.155578 seconds and 5 git commands to generate.