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-2026 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 14952 : static void BreakWhenSymBooked (unsigned int sym)
159 : {
160 14952 : 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 754313 : static tree Mod2GccWithoutGCCPoison (unsigned int sym)
184 : {
185 754313 : NameKey_Name n;
186 754313 : tree tr;
187 :
188 754313 : if (Indexing_InBounds (mod2gcc, sym))
189 : {
190 754313 : tr = (tree) (Indexing_GetIndice (mod2gcc, sym));
191 754313 : 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 14952 : static void Init (void)
214 : {
215 14952 : 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 14952 : 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 14952 : mod2gcc = Indexing_InitIndexTuned (1, (1024*1024) / 16, 16);
228 14952 : Storage_ALLOCATE (&PoisonedSymbol, 1);
229 14952 : }
230 :
231 :
232 : /*
233 : Mod2Gcc - given a modula-2 symbol, sym, return the gcc equivalent.
234 : */
235 :
236 52175619 : extern "C" tree SymbolConversion_Mod2Gcc (unsigned int sym)
237 : {
238 52175619 : NameKey_Name n;
239 52175619 : SymbolConversion_PtrToCardinal t;
240 52175619 : tree tr;
241 :
242 52175619 : if (USEPOISON)
243 : {
244 52175619 : if (Indexing_InBounds (mod2gcc, sym))
245 : {
246 51953619 : t = (SymbolConversion_PtrToCardinal) (Indexing_GetIndice (mod2gcc, sym));
247 51953619 : if ((t != NULL) && ((*t) == GGCPOISON))
248 : {
249 0 : M2Error_InternalError ((const char *) "gcc symbol has been poisoned", 28);
250 : }
251 : }
252 : }
253 52175619 : if (Indexing_InBounds (mod2gcc, sym))
254 : {
255 51953619 : tr = (tree) (Indexing_GetIndice (mod2gcc, sym));
256 51953619 : 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 16338866 : extern "C" void SymbolConversion_AddModGcc (unsigned int sym, tree gcc)
304 : {
305 16338866 : tree old;
306 16338866 : SymbolConversion_PtrToCardinal t;
307 :
308 16338866 : CheckBook (sym);
309 16338866 : if (gcc == (m2block_GetErrorNode ()))
310 : {
311 0 : M2Error_InternalError ((const char *) "error node generated during symbol conversion", 45);
312 : }
313 16338866 : if (USEPOISON)
314 : {
315 16338866 : t = (SymbolConversion_PtrToCardinal) (gcc);
316 16338866 : if ((gcc != ((tree) (NULL))) && ((*t) == GGCPOISON))
317 : {
318 0 : M2Error_InternalError ((const char *) "gcc symbol has been poisoned", 28);
319 : }
320 : }
321 16338866 : old = SymbolConversion_Mod2Gcc (sym);
322 16338866 : if (old == ((tree) (NULL)))
323 : {
324 : /* absent - add it */
325 15852151 : Indexing_PutIndice (mod2gcc, sym, gcc);
326 15852151 : if ((Indexing_GetIndice (mod2gcc, sym)) != gcc)
327 : {
328 0 : M2Error_InternalError ((const char *) "failed to add gcc <-> mod2 symbol", 33);
329 : }
330 15852151 : gcc = m2block_RememberConstant (gcc);
331 : }
332 : /* do nothing, as it is already stored */
333 486715 : 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 16338866 : if ((SymbolTable_IsConst (sym)) && (! (SymbolTable_IsValueSolved (sym))))
348 : {
349 460517 : M2ALU_PushTypeOfTree (sym, gcc);
350 460517 : SymbolTable_PopValue (sym);
351 : }
352 16338866 : }
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 49910507 : extern "C" bool SymbolConversion_GccKnowsAbout (unsigned int sym)
370 : {
371 49910507 : 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 787446 : extern "C" void SymbolConversion_Poison (unsigned int sym)
410 : {
411 787446 : void * a;
412 :
413 787446 : if (! (SymbolTable_IsConst (sym)))
414 : {
415 754313 : a = Mod2GccWithoutGCCPoison (sym);
416 754313 : if (a != NULL)
417 : {
418 748425 : Indexing_PutIndice (mod2gcc, sym, PoisonedSymbol);
419 : }
420 : }
421 787446 : }
422 :
423 14952 : extern "C" void _M2_SymbolConversion_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
424 : {
425 14952 : Init ();
426 14952 : }
427 :
428 0 : extern "C" void _M2_SymbolConversion_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
429 : {
430 0 : }
|