Branch data Line data Source code
1 : : /* do not edit automatically generated by mc from SymbolConversion. */
2 : : /* SymbolConversion.mod mapping between m2 symbols and gcc symbols.
3 : :
4 : : Copyright (C) 2001-2025 Free Software Foundation, Inc.
5 : : Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
6 : :
7 : : This file is part of GNU Modula-2.
8 : :
9 : : GNU Modula-2 is free software; you can redistribute it and/or modify
10 : : it under the terms of the GNU General Public License as published by
11 : : the Free Software Foundation; either version 3, or (at your option)
12 : : any later version.
13 : :
14 : : GNU Modula-2 is distributed in the hope that it will be useful, but
15 : : WITHOUT ANY WARRANTY; without even the implied warranty of
16 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : : General Public License for more details.
18 : :
19 : : You should have received a copy of the GNU General Public License
20 : : along with GNU Modula-2; see the file COPYING3. If not see
21 : : <http://www.gnu.org/licenses/>. */
22 : :
23 : : #include "config.h"
24 : : #include "system.h"
25 : : #include "gcc-consolidation.h"
26 : :
27 : : #include <stdbool.h>
28 : : # if !defined (PROC_D)
29 : : # define PROC_D
30 : : typedef void (*PROC_t) (void);
31 : : typedef struct { PROC_t proc; } PROC;
32 : : # endif
33 : :
34 : : # if !defined (TRUE)
35 : : # define TRUE (1==1)
36 : : # endif
37 : :
38 : : #if defined(__cplusplus)
39 : : # undef NULL
40 : : # define NULL 0
41 : : #endif
42 : : #define _SymbolConversion_C
43 : :
44 : : #include "GSymbolConversion.h"
45 : : # include "GNameKey.h"
46 : : # include "GIndexing.h"
47 : : # include "GSymbolTable.h"
48 : : # include "GM2Error.h"
49 : : # include "GM2ALU.h"
50 : : # include "Gm2block.h"
51 : : # include "Ggcctypes.h"
52 : : # include "GM2Printf.h"
53 : : # include "GStorage.h"
54 : : # include "GSYSTEM.h"
55 : :
56 : : # define USEPOISON true
57 : : # define GGCPOISON 0x0A5A5A5A5
58 : : typedef unsigned int *SymbolConversion_PtrToCardinal;
59 : :
60 : : static Indexing_Index mod2gcc;
61 : : static void * PoisonedSymbol;
62 : : static unsigned int BookSym;
63 : :
64 : : /*
65 : : Mod2Gcc - given a modula-2 symbol, sym, return the gcc equivalent.
66 : : */
67 : :
68 : : extern "C" tree SymbolConversion_Mod2Gcc (unsigned int sym);
69 : :
70 : : /*
71 : : Gcc2Mod - given a gcc tree return the modula-2 symbol.
72 : : */
73 : :
74 : : extern "C" unsigned int SymbolConversion_Gcc2Mod (tree tree);
75 : :
76 : : /*
77 : : AddModGcc - adds the tuple [ sym, gcc ] into the database.
78 : : */
79 : :
80 : : extern "C" void SymbolConversion_AddModGcc (unsigned int sym, tree gcc);
81 : :
82 : : /*
83 : : RemoveMod2Gcc - removes the gcc symbol from the lookup table.
84 : : */
85 : :
86 : : extern "C" void SymbolConversion_RemoveMod2Gcc (unsigned int sym);
87 : :
88 : : /*
89 : : GccKnowsAbout - returns TRUE if gcc knows about the symbol, sym.
90 : : */
91 : :
92 : : extern "C" bool SymbolConversion_GccKnowsAbout (unsigned int sym);
93 : :
94 : : /*
95 : : AddTemporaryKnown - adds a temporary gcc symbol against the modula-2 sym.
96 : : */
97 : :
98 : : extern "C" void SymbolConversion_AddTemporaryKnown (unsigned int sym);
99 : :
100 : : /*
101 : : RemoveTemporaryKnown - removes the temporary symbol.
102 : : */
103 : :
104 : : extern "C" void SymbolConversion_RemoveTemporaryKnown (unsigned int sym);
105 : :
106 : : /*
107 : : Poison - poisons a symbol.
108 : : */
109 : :
110 : : extern "C" void SymbolConversion_Poison (unsigned int sym);
111 : :
112 : : /*
113 : : gdbhook - a debugger convenience hook.
114 : : */
115 : :
116 : : static void gdbhook (void);
117 : :
118 : : /*
119 : : BreakWhenSymBooked - to be called interactively by gdb.
120 : : */
121 : :
122 : : static void BreakWhenSymBooked (unsigned int sym);
123 : :
124 : : /*
125 : : CheckBook - if sym = BookSym then call gdbhook.
126 : : */
127 : :
128 : : static void CheckBook (unsigned int sym);
129 : :
130 : : /*
131 : : Mod2GccWithoutGCCPoison - given a modula-2 symbol, sym, return
132 : : the gcc equivalent, it does not check to see
133 : : whether the gcc symbol has been poisoned.
134 : : */
135 : :
136 : : static tree Mod2GccWithoutGCCPoison (unsigned int sym);
137 : :
138 : : /*
139 : : Init - create both binary trees.
140 : : */
141 : :
142 : : static void Init (void);
143 : :
144 : :
145 : : /*
146 : : gdbhook - a debugger convenience hook.
147 : : */
148 : :
149 : 0 : static void gdbhook (void)
150 : : {
151 : 0 : }
152 : :
153 : :
154 : : /*
155 : : BreakWhenSymBooked - to be called interactively by gdb.
156 : : */
157 : :
158 : 15506 : static void BreakWhenSymBooked (unsigned int sym)
159 : : {
160 : 15506 : BookSym = sym;
161 : 0 : }
162 : :
163 : :
164 : : /*
165 : : CheckBook - if sym = BookSym then call gdbhook.
166 : : */
167 : :
168 : 0 : static void CheckBook (unsigned int sym)
169 : : {
170 : 0 : if (sym == BookSym)
171 : : {
172 : 0 : gdbhook ();
173 : : }
174 : 0 : }
175 : :
176 : :
177 : : /*
178 : : Mod2GccWithoutGCCPoison - given a modula-2 symbol, sym, return
179 : : the gcc equivalent, it does not check to see
180 : : whether the gcc symbol has been poisoned.
181 : : */
182 : :
183 : 774158 : static tree Mod2GccWithoutGCCPoison (unsigned int sym)
184 : : {
185 : 774158 : NameKey_Name n;
186 : 774158 : tree tr;
187 : :
188 : 774158 : if (Indexing_InBounds (mod2gcc, sym))
189 : : {
190 : 774158 : tr = (tree) (Indexing_GetIndice (mod2gcc, sym));
191 : 774158 : if (tr == PoisonedSymbol)
192 : : {
193 : 0 : n = SymbolTable_GetSymName (sym);
194 : : /* not poisoned by the garbage collector, but by the gm2 front end. */
195 : 0 : M2Printf_printf1 ((const char *) "the gm2 front end poisoned this symbol (%a)\\n", 45, (const unsigned char *) &n, (sizeof (n)-1));
196 : 0 : M2Error_InternalError ((const char *) "attempting to use a gcc symbol which is no longer in scope", 58);
197 : : }
198 : : return tr;
199 : : }
200 : : else
201 : : {
202 : : return NULL;
203 : : }
204 : : /* static analysis guarentees a RETURN statement will be used before here. */
205 : : __builtin_unreachable ();
206 : : }
207 : :
208 : :
209 : : /*
210 : : Init - create both binary trees.
211 : : */
212 : :
213 : 15506 : static void Init (void)
214 : : {
215 : 15506 : BreakWhenSymBooked (SymbolTable_NulSym); /* Disable the intereactive sym watch. */
216 : : /* To examine when a symbol is double booked run cc1gm2 from gdb
217 : : and set a break point on gdbhook.
218 : : (gdb) break gdbhook
219 : : (gdb) run
220 : : Now below interactively call BreakWhenSymBooked with the symbol
221 : : under investigation. */
222 : 15506 : gdbhook ();
223 : : /* Now is the time to interactively call gdb, for example:
224 : : (gdb) print BreakWhenSymBooked (1234)
225 : : (gdb) cont
226 : : and you will arrive at gdbhook when this symbol is booked. */
227 : 15506 : mod2gcc = Indexing_InitIndexTuned (1, (1024*1024) / 16, 16);
228 : 15506 : Storage_ALLOCATE (&PoisonedSymbol, 1);
229 : 15506 : }
230 : :
231 : :
232 : : /*
233 : : Mod2Gcc - given a modula-2 symbol, sym, return the gcc equivalent.
234 : : */
235 : :
236 : 53080556 : extern "C" tree SymbolConversion_Mod2Gcc (unsigned int sym)
237 : : {
238 : 53080556 : NameKey_Name n;
239 : 53080556 : SymbolConversion_PtrToCardinal t;
240 : 53080556 : tree tr;
241 : :
242 : 53080556 : if (USEPOISON)
243 : : {
244 : 53080556 : if (Indexing_InBounds (mod2gcc, sym))
245 : : {
246 : 52850212 : t = (SymbolConversion_PtrToCardinal) (Indexing_GetIndice (mod2gcc, sym));
247 : 52850212 : if ((t != NULL) && ((*t) == GGCPOISON))
248 : : {
249 : 0 : M2Error_InternalError ((const char *) "gcc symbol has been poisoned", 28);
250 : : }
251 : : }
252 : : }
253 : 53080556 : if (Indexing_InBounds (mod2gcc, sym))
254 : : {
255 : 52850212 : tr = (tree) (Indexing_GetIndice (mod2gcc, sym));
256 : 52850212 : if (tr == PoisonedSymbol)
257 : : {
258 : 0 : n = SymbolTable_GetSymName (sym);
259 : : /* not poisoned by the garbage collector, but by the gm2 front end */
260 : 0 : M2Printf_printf1 ((const char *) "the gm2 front end poisoned this symbol (%a)\\n", 45, (const unsigned char *) &n, (sizeof (n)-1));
261 : 0 : M2Error_InternalError ((const char *) "attempting to use a gcc symbol which is no longer in scope", 58);
262 : : }
263 : : return tr;
264 : : }
265 : : else
266 : : {
267 : : return NULL;
268 : : }
269 : : /* static analysis guarentees a RETURN statement will be used before here. */
270 : : __builtin_unreachable ();
271 : : }
272 : :
273 : :
274 : : /*
275 : : Gcc2Mod - given a gcc tree return the modula-2 symbol.
276 : : */
277 : :
278 : 0 : extern "C" unsigned int SymbolConversion_Gcc2Mod (tree tree)
279 : : {
280 : 0 : unsigned int high;
281 : 0 : unsigned int i;
282 : :
283 : 0 : i = 1;
284 : 0 : high = Indexing_HighIndice (mod2gcc);
285 : 0 : while (i <= high)
286 : : {
287 : 0 : if ((Indexing_GetIndice (mod2gcc, i)) == tree)
288 : : {
289 : : return i;
290 : : }
291 : 0 : i += 1;
292 : : }
293 : : return SymbolTable_NulSym;
294 : : /* static analysis guarentees a RETURN statement will be used before here. */
295 : : __builtin_unreachable ();
296 : : }
297 : :
298 : :
299 : : /*
300 : : AddModGcc - adds the tuple [ sym, gcc ] into the database.
301 : : */
302 : :
303 : 16621242 : extern "C" void SymbolConversion_AddModGcc (unsigned int sym, tree gcc)
304 : : {
305 : 16621242 : tree old;
306 : 16621242 : SymbolConversion_PtrToCardinal t;
307 : :
308 : 16621242 : CheckBook (sym);
309 : 16621242 : if (gcc == (m2block_GetErrorNode ()))
310 : : {
311 : 0 : M2Error_InternalError ((const char *) "error node generated during symbol conversion", 45);
312 : : }
313 : 16621242 : if (USEPOISON)
314 : : {
315 : 16621242 : t = (SymbolConversion_PtrToCardinal) (gcc);
316 : 16621242 : if ((gcc != ((tree) (NULL))) && ((*t) == GGCPOISON))
317 : : {
318 : 0 : M2Error_InternalError ((const char *) "gcc symbol has been poisoned", 28);
319 : : }
320 : : }
321 : 16621242 : old = SymbolConversion_Mod2Gcc (sym);
322 : 16621242 : if (old == ((tree) (NULL)))
323 : : {
324 : : /* absent - add it */
325 : 16129583 : Indexing_PutIndice (mod2gcc, sym, gcc);
326 : 16129583 : if ((Indexing_GetIndice (mod2gcc, sym)) != gcc)
327 : : {
328 : 0 : M2Error_InternalError ((const char *) "failed to add gcc <-> mod2 symbol", 33);
329 : : }
330 : 16129583 : gcc = m2block_RememberConstant (gcc);
331 : : }
332 : : /* do nothing, as it is already stored */
333 : 491659 : else if (old == gcc)
334 : : {
335 : : /* avoid dangling else. */
336 : : }
337 : 0 : else if (old == (m2block_GetErrorNode ()))
338 : : {
339 : : /* avoid dangling else. */
340 : 0 : M2Error_InternalError ((const char *) "replacing a temporary symbol (currently unexpected)", 51);
341 : : }
342 : : else
343 : : {
344 : : /* avoid dangling else. */
345 : 0 : M2Error_InternalError ((const char *) "should not be replacing a symbol", 32);
346 : : }
347 : 16621242 : if ((SymbolTable_IsConst (sym)) && (! (SymbolTable_IsValueSolved (sym))))
348 : : {
349 : 468113 : M2ALU_PushTypeOfTree (sym, gcc);
350 : 468113 : SymbolTable_PopValue (sym);
351 : : }
352 : 16621242 : }
353 : :
354 : :
355 : : /*
356 : : RemoveMod2Gcc - removes the gcc symbol from the lookup table.
357 : : */
358 : :
359 : 0 : extern "C" void SymbolConversion_RemoveMod2Gcc (unsigned int sym)
360 : : {
361 : 0 : Indexing_PutIndice (mod2gcc, sym, NULL);
362 : 0 : }
363 : :
364 : :
365 : : /*
366 : : GccKnowsAbout - returns TRUE if gcc knows about the symbol, sym.
367 : : */
368 : :
369 : 50489361 : extern "C" bool SymbolConversion_GccKnowsAbout (unsigned int sym)
370 : : {
371 : 50489361 : return (Indexing_InBounds (mod2gcc, sym)) && ((Indexing_GetIndice (mod2gcc, sym)) != NULL);
372 : : /* static analysis guarentees a RETURN statement will be used before here. */
373 : : __builtin_unreachable ();
374 : : }
375 : :
376 : :
377 : : /*
378 : : AddTemporaryKnown - adds a temporary gcc symbol against the modula-2 sym.
379 : : */
380 : :
381 : 0 : extern "C" void SymbolConversion_AddTemporaryKnown (unsigned int sym)
382 : : {
383 : : /* we add the error node against symbol, sym. We expect it to be retacted later. */
384 : 0 : Indexing_PutIndice (mod2gcc, sym, m2block_GetErrorNode ());
385 : 0 : }
386 : :
387 : :
388 : : /*
389 : : RemoveTemporaryKnown - removes the temporary symbol.
390 : : */
391 : :
392 : 0 : extern "C" void SymbolConversion_RemoveTemporaryKnown (unsigned int sym)
393 : : {
394 : 0 : if ((SymbolConversion_Mod2Gcc (sym)) == (m2block_GetErrorNode ()))
395 : : {
396 : 0 : Indexing_PutIndice (mod2gcc, sym, NULL);
397 : : }
398 : : else
399 : : {
400 : 0 : M2Error_InternalError ((const char *) "attempting to remove a symbol which is not present in the tree", 62);
401 : : }
402 : 0 : }
403 : :
404 : :
405 : : /*
406 : : Poison - poisons a symbol.
407 : : */
408 : :
409 : 807541 : extern "C" void SymbolConversion_Poison (unsigned int sym)
410 : : {
411 : 807541 : void * a;
412 : :
413 : 807541 : if (! (SymbolTable_IsConst (sym)))
414 : : {
415 : 774158 : a = Mod2GccWithoutGCCPoison (sym);
416 : 774158 : if (a != NULL)
417 : : {
418 : 768274 : Indexing_PutIndice (mod2gcc, sym, PoisonedSymbol);
419 : : }
420 : : }
421 : 807541 : }
422 : :
423 : 15506 : extern "C" void _M2_SymbolConversion_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
424 : : {
425 : 15506 : Init ();
426 : 15506 : }
427 : :
428 : 0 : extern "C" void _M2_SymbolConversion_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
429 : : {
430 : 0 : }
|