scope.cc 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /* $Id$ */
  2. /* Scope mechanism */
  3. #include <assert.h>
  4. #include <alloc.h>
  5. #include <out.h>
  6. #include "position.h"
  7. #include "file.h"
  8. #include "idf.h"
  9. #include "type.h"
  10. #include "symbol.h"
  11. #include "scope.h"
  12. #include "avl.h"
  13. p_scope PervasiveScope, CurrentScope, FileScope;
  14. /* STATICALLOCDEF "scope" 10 */
  15. static AVL_tree ScopeTree;
  16. static int
  17. cmp_starts(s1, s2)
  18. char *s1, *s2;
  19. {
  20. register p_scope c1 = (p_scope)s1, c2 = (p_scope)s2;
  21. return c1->sc_start < c2->sc_start
  22. ? -1
  23. : c1->sc_start == c2->sc_start
  24. ? 0
  25. : 1;
  26. }
  27. /*ARGSUSED*/
  28. open_scope(name, has_activation)
  29. p_symbol name;
  30. int has_activation;
  31. {
  32. register p_scope sc = new_scope();
  33. sc->sc_has_activation_record = has_activation;
  34. sc->sc_static_encl = CurrentScope;
  35. sc->sc_definedby = name;
  36. sc->sc_proclevel = CurrentScope->sc_proclevel;
  37. /* sc_proclevel possibly reset by caller */
  38. CurrentScope = sc;
  39. }
  40. init_scope()
  41. {
  42. register p_scope sc = new_scope();
  43. PervasiveScope = sc;
  44. CurrentScope = sc;
  45. open_scope((p_symbol) 0, 0); /* this one will be closed at the
  46. first N_SO
  47. */
  48. ScopeTree = create_avl_tree(cmp_starts);
  49. }
  50. close_scope()
  51. {
  52. register p_scope sc = CurrentScope;
  53. assert(sc != 0);
  54. CurrentScope = sc->sc_static_encl;
  55. }
  56. add_scope_addr(scope)
  57. p_scope scope;
  58. {
  59. add_to_avl_tree(ScopeTree, (char *)scope);
  60. }
  61. /* extern p_scope get_scope_from_addr(t_addr a);
  62. Returns the scope of the code at address 'a', or 0 if it could not be found.
  63. */
  64. p_scope
  65. get_scope_from_addr(a)
  66. t_addr a;
  67. {
  68. t_scope sc;
  69. sc.sc_start = a;
  70. return (p_scope) find_ngt(ScopeTree, (char *) &sc);
  71. }
  72. /* extern p_scope get_next_scope_from_addr(t_addr a);
  73. Returns the scope following the one of the code at address 'a',
  74. and that has an activation record,
  75. or 0 if it could not be found.
  76. */
  77. p_scope
  78. get_next_scope_from_addr(a)
  79. t_addr a;
  80. {
  81. t_scope sc;
  82. sc.sc_start = a;
  83. for (;;) {
  84. p_scope psc = (p_scope) find_nlt(ScopeTree, (char *) &sc);
  85. if (! psc || psc->sc_has_activation_record) return psc;
  86. sc.sc_start = psc->sc_start+1;
  87. }
  88. /*NOTREACHED*/
  89. }
  90. /* extern int has_static_link(p_scope sc);
  91. Returns 1 if the procedure of this scope takes a static link.
  92. */
  93. int
  94. has_static_link(sc)
  95. register p_scope sc;
  96. {
  97. return sc->sc_proclevel > 1;
  98. }
  99. /* extern p_scope base_scope(p_scope sc);
  100. Returns the closest enclosing scope of 'sc' that has an activation record.
  101. */
  102. p_scope
  103. base_scope(sc)
  104. register p_scope sc;
  105. {
  106. while (sc && ! sc->sc_has_activation_record) {
  107. sc = sc->sc_static_encl;
  108. }
  109. return sc;
  110. }
  111. /* extern int scope_encloses(p_scope scope, from_scope);
  112. Returns 1 if scope encloses from from_scope, 0 otherwise.
  113. */
  114. int
  115. scope_encloses(scope, from_scope)
  116. p_scope scope, from_scope;
  117. {
  118. register p_scope sc = from_scope;
  119. while (sc) {
  120. if (sc == scope) return 1;
  121. sc = sc->sc_static_encl;
  122. }
  123. return 0;
  124. }