1 /* ***********************************************************
 2    *                                                         *
 3    * Copyright, (C) Honeywell Information Systems Inc., 1982 *
 4    *                                                         *
 5    * Copyright (c) 1972 by Massachusetts Institute of        *
 6    * Technology and Honeywell Information Systems, Inc.      *
 7    *                                                         *
 8    *********************************************************** */
 9 
10 
11 /* this routine  is called to adjust the reference counts in a subtree.
12    If a given node in the tree has no reference count, no further
13    processing is necessary.  If it has a count, the count is reduced by one.
14    If that reduces it to zero, the node is freed and the routine is called to
15    process the subexpressions.  */
16 
17 adjust_count: proc(pt);
18 
19 dcl       (pt,t,s) ptr;
20 dcl       shared bit(1) aligned;
21 dcl       i fixed bin(15);
22 dcl       null builtin;
23 
24 %include nodes;
25 %include reference;
26 %include operator;
27 %include op_codes;
28 %include list;
29 %include language_utility;
30 
31 begin:
32           t = pt;
33           if t = null then return;
34           if t->node.type = reference_node
35                then do;
36                     if t->reference.shared then return;
37                     t->reference.ref_count = t->reference.ref_count-1;
38                     if t->reference.ref_count = 0
39                          then do;
40                               if t->reference.offset ^= null then call adjust_count((t->reference.offset));
41                               if t->reference.length ^= null then call adjust_count((t->reference.length));
42                               if t->reference.qualifier ^= null then call adjust_count((t->reference.qualifier));
43                               call free_node(t);
44                               end;
45                     return;
46                     end;
47           if t->node.type = operator_node
48                then if t->operator.number > 0
49                     then if t->operator.operand(1) ^= null
50                          then do;
51                               s = t->operator.operand(1);
52 
53                               shared = s->reference.shared;
54 
55                               if ^shared
56                               then do;
57                                    if t->operator.op_code = std_call
58                                         then i = 2;
59                                         else i = 1;
60                                    if s->reference.ref_count - i ^= 0
61                                    then do;
62                                         s->reference.ref_count = s->reference.ref_count - 1;
63                                         return;
64                                         end;
65                                    end;
66 
67                               if ^t->operator.optimized
68                               then do i = 1 to t->operator.number;
69                                    call adjust_count((t->operator.operand(i)));
70                                    end;
71 
72                               if ^shared
73                                    then call free_node(t);
74                                    else t -> operator.optimized = "1"b;
75                               return;
76                               end;
77           if t->node.type = list_node
78                then do i = 1 to t->list.number;
79                     call adjust_count((t->list.element(i)));
80                     end;
81           end; /* adjust_count */
82