]>
Commit | Line | Data |
---|---|---|
99dee823 | 1 | # Copyright (C) 2013-2021 Free Software Foundation, Inc. |
a167b052 DM |
2 | # |
3 | # This program is free software; you can redistribute it and/or modify it | |
4 | # under the terms of the GNU General Public License as published by the | |
5 | # Free Software Foundation; either version 3, or (at your option) any | |
6 | # later version. | |
7 | # | |
8 | # This program is distributed in the hope that it will be useful, | |
9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | # GNU General Public License for more details. | |
12 | # | |
13 | # You should have received a copy of the GNU General Public License | |
14 | # along with this program; see the file COPYING3. If not see | |
15 | # <http://www.gnu.org/licenses/>. | |
16 | ||
17 | # This Awk script takes passes.def and writes pass-instances.def, | |
18 | # counting the instances of each kind of pass, adding an instance number | |
19 | # to everywhere that NEXT_PASS is used. | |
478167be JJ |
20 | # Also handle INSERT_PASS_AFTER, INSERT_PASS_BEFORE and REPLACE_PASS |
21 | # directives. | |
a167b052 DM |
22 | # |
23 | # For example, the single-instanced pass: | |
24 | # NEXT_PASS (pass_warn_unused_result); | |
25 | # becomes this in the output: | |
26 | # NEXT_PASS (pass_warn_unused_result, 1); | |
27 | # | |
28 | # The various instances of | |
29 | # NEXT_PASS (pass_copy_prop); | |
30 | # become: | |
31 | # NEXT_PASS (pass_copy_prop, 1); | |
32 | # through: | |
33 | # NEXT_PASS (pass_copy_prop, 8); | |
34 | # (currently there are 8 instances of that pass) | |
478167be JJ |
35 | # |
36 | # INSERT_PASS_AFTER (pass_copy_prop, 1, pass_stv); | |
37 | # will insert | |
38 | # NEXT_PASS (pass_stv, 1); | |
39 | # immediately after the NEXT_PASS (pass_copy_prop, 1) line, | |
40 | # similarly INSERT_PASS_BEFORE inserts immediately before that line. | |
41 | # REPLACE_PASS (pass_copy_prop, 1, pass_stv, true); | |
42 | # will replace NEXT_PASS (pass_copy_prop, 1) line with | |
43 | # NEXT_PASS (pass_stv, 1, true); | |
44 | # line and renumber all higher pass_copy_prop instances if any. | |
a167b052 DM |
45 | |
46 | # Usage: awk -f gen-pass-instances.awk passes.def | |
47 | ||
48 | BEGIN { | |
478167be JJ |
49 | print "/* This file is auto-generated by gen-pass-instances.awk"; |
50 | print " from passes.def. */"; | |
51 | lineno = 1; | |
a167b052 DM |
52 | } |
53 | ||
478167be JJ |
54 | function parse_line(line, fnname, len_of_call, len_of_start, |
55 | len_of_open, len_of_close, | |
56 | len_of_args, args_start_at, | |
57 | args_str, len_of_prefix, | |
58 | call_starts_at, | |
59 | postfix_starts_at) | |
a167b052 | 60 | { |
478167be JJ |
61 | # Find call expression. |
62 | call_starts_at = match(line, fnname " \\(.+\\)"); | |
63 | if (call_starts_at == 0) | |
64 | return 0; | |
65 | ||
66 | # Length of the call expression. | |
67 | len_of_call = RLENGTH; | |
68 | ||
69 | len_of_start = length(fnname " ("); | |
70 | len_of_open = length("("); | |
71 | len_of_close = length(")"); | |
72 | ||
73 | # Find arguments | |
74 | len_of_args = len_of_call - (len_of_start + len_of_close); | |
75 | args_start_at = call_starts_at + len_of_start; | |
76 | args_str = substr(line, args_start_at, len_of_args); | |
77 | split(args_str, args, ","); | |
78 | ||
79 | # Find call expression prefix | |
80 | len_of_prefix = call_starts_at - 1; | |
81 | prefix = substr(line, 1, len_of_prefix); | |
82 | ||
83 | # Find call expression postfix | |
84 | postfix_starts_at = call_starts_at + len_of_call; | |
85 | postfix = substr(line, postfix_starts_at); | |
86 | return 1; | |
87 | } | |
d2616f3d | 88 | |
478167be JJ |
89 | function adjust_linenos(above, increment, p, i) |
90 | { | |
91 | for (p in pass_lines) | |
92 | if (pass_lines[p] >= above) | |
984fa0ea | 93 | pass_lines[p] += increment; |
478167be JJ |
94 | if (increment > 0) |
95 | for (i = lineno - 1; i >= above; i--) | |
96 | lines[i + increment] = lines[i]; | |
97 | else | |
98 | for (i = above; i < lineno; i++) | |
99 | lines[i + increment] = lines[i]; | |
100 | lineno += increment; | |
101 | } | |
0f73e667 | 102 | |
984fa0ea | 103 | function insert_remove_pass(line, fnname, arg3) |
478167be JJ |
104 | { |
105 | parse_line($0, fnname); | |
106 | pass_name = args[1]; | |
107 | if (pass_name == "PASS") | |
108 | return 1; | |
109 | pass_num = args[2] + 0; | |
984fa0ea JJ |
110 | arg3 = args[3]; |
111 | sub(/^[ \t]*/, "", arg3); | |
112 | new_line = prefix "NEXT_PASS (" arg3; | |
478167be | 113 | if (args[4]) |
984fa0ea | 114 | new_line = new_line "," args[4]; |
478167be JJ |
115 | new_line = new_line ")" postfix; |
116 | if (!pass_lines[pass_name, pass_num]) | |
117 | { | |
118 | print "ERROR: Can't locate instance of the pass mentioned in " fnname; | |
119 | return 1; | |
120 | } | |
121 | return 0; | |
122 | } | |
7d3e64f7 | 123 | |
478167be JJ |
124 | function insert_pass(line, fnname, after, num) |
125 | { | |
126 | if (insert_remove_pass(line, fnname)) | |
127 | return; | |
128 | num = pass_lines[pass_name, pass_num]; | |
129 | adjust_linenos(num + after, 1); | |
130 | pass_name = args[3]; | |
131 | # Set pass_counts | |
132 | if (args[3] in pass_counts) | |
133 | pass_counts[pass_name]++; | |
134 | else | |
135 | pass_counts[pass_name] = 1; | |
136 | ||
137 | pass_lines[pass_name, pass_counts[pass_name]] = num + after; | |
138 | lines[num + after] = new_line; | |
139 | } | |
6275791a | 140 | |
478167be JJ |
141 | function replace_pass(line, fnname, num, i) |
142 | { | |
143 | if (insert_remove_pass(line, "REPLACE_PASS")) | |
144 | return; | |
145 | num = pass_lines[pass_name, pass_num]; | |
146 | for (i = pass_counts[pass_name]; i > pass_num; i--) | |
147 | pass_lines[pass_name, i - 1] = pass_lines[pass_name, i]; | |
148 | delete pass_lines[pass_name, pass_counts[pass_name]]; | |
149 | if (pass_counts[pass_name] == 1) | |
150 | delete pass_counts[pass_name]; | |
151 | else | |
152 | pass_counts[pass_name]--; | |
153 | ||
154 | pass_name = args[3]; | |
155 | # Set pass_counts | |
156 | if (args[3] in pass_counts) | |
157 | pass_counts[pass_name]++; | |
158 | else | |
159 | pass_counts[pass_name] = 1; | |
160 | ||
161 | pass_lines[pass_name, pass_counts[pass_name]] = num; | |
162 | lines[num] = new_line; | |
163 | } | |
9fa1a402 | 164 | |
478167be JJ |
165 | /INSERT_PASS_AFTER \(.+\)/ { |
166 | insert_pass($0, "INSERT_PASS_AFTER", 1); | |
167 | next; | |
168 | } | |
504943f4 | 169 | |
478167be JJ |
170 | /INSERT_PASS_BEFORE \(.+\)/ { |
171 | insert_pass($0, "INSERT_PASS_BEFORE", 0); | |
172 | next; | |
173 | } | |
504943f4 | 174 | |
478167be JJ |
175 | /REPLACE_PASS \(.+\)/ { |
176 | replace_pass($0, "REPLACE_PASS"); | |
177 | next; | |
178 | } | |
9fa1a402 | 179 | |
478167be JJ |
180 | { |
181 | ret = parse_line($0, "NEXT_PASS"); | |
182 | if (ret) | |
183 | { | |
184 | pass_name = args[1]; | |
185 | ||
186 | # Set pass_counts | |
187 | if (pass_name in pass_counts) | |
188 | pass_counts[pass_name]++; | |
189 | else | |
190 | pass_counts[pass_name] = 1; | |
191 | ||
192 | pass_lines[pass_name, pass_counts[pass_name]] = lineno; | |
193 | } | |
194 | lines[lineno++] = $0; | |
195 | } | |
504943f4 | 196 | |
478167be | 197 | END { |
478167be JJ |
198 | for (i = 1; i < lineno; i++) |
199 | { | |
200 | ret = parse_line(lines[i], "NEXT_PASS"); | |
201 | if (ret) | |
b0c77505 | 202 | { |
478167be JJ |
203 | # Set pass_name argument, an optional with_arg argument |
204 | pass_name = args[1]; | |
205 | with_arg = args[2]; | |
206 | ||
772ebeb5 EB |
207 | # Set pass_final_counts |
208 | if (pass_name in pass_final_counts) | |
209 | pass_final_counts[pass_name]++; | |
478167be | 210 | else |
772ebeb5 | 211 | pass_final_counts[pass_name] = 1; |
478167be | 212 | |
772ebeb5 | 213 | pass_num = pass_final_counts[pass_name]; |
478167be JJ |
214 | |
215 | # Print call expression with extra pass_num argument | |
216 | printf "%s", prefix; | |
217 | if (with_arg) | |
218 | printf "NEXT_PASS_WITH_ARG"; | |
219 | else | |
220 | printf "NEXT_PASS"; | |
221 | printf " (%s, %s", pass_name, pass_num; | |
222 | if (with_arg) | |
984fa0ea | 223 | printf ",%s", with_arg; |
478167be | 224 | printf ")%s\n", postfix; |
b0c77505 | 225 | } |
478167be JJ |
226 | else |
227 | print lines[i]; | |
228 | } | |
a167b052 DM |
229 | } |
230 | ||
a3a5ff42 TV |
231 | # Local Variables: |
232 | # mode:awk | |
233 | # c-basic-offset:8 | |
234 | # End: |