]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/m2/mc-boot/Gkeyc.c
Merge modula-2 front end onto gcc.
[thirdparty/gcc.git] / gcc / m2 / mc-boot / Gkeyc.c
1 /* do not edit automatically generated by mc from keyc. */
2 /* keyc maintains the C name scope and avoids C/C++ name conflicts.
3 Copyright (C) 2016-2022 Free Software Foundation, Inc.
4
5 This file is part of GNU Modula-2.
6
7 GNU Modula-2 is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11
12 GNU Modula-2 is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with gm2; see the file COPYING. If not, write to the Free Software
19 Foundation, 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
21
22 #include "config.h"
23 #include "system.h"
24 # if !defined (PROC_D)
25 # define PROC_D
26 typedef void (*PROC_t) (void);
27 typedef struct { PROC_t proc; } PROC;
28 # endif
29
30 # if !defined (TRUE)
31 # define TRUE (1==1)
32 # endif
33
34 # if !defined (FALSE)
35 # define FALSE (1==0)
36 # endif
37
38 # include "GStorage.h"
39 # include "Gmcrts.h"
40 #if defined(__cplusplus)
41 # undef NULL
42 # define NULL 0
43 #endif
44 #define _keyc_H
45 #define _keyc_C
46
47 # include "GmcPretty.h"
48 # include "GStorage.h"
49 # include "GDynamicStrings.h"
50 # include "GsymbolKey.h"
51 # include "GnameKey.h"
52 # include "GmcOptions.h"
53 # include "GM2RTS.h"
54
55 #if !defined (decl_node_D)
56 # define decl_node_D
57 typedef void *decl_node;
58 #endif
59
60 typedef struct keyc__T1_r keyc__T1;
61
62 typedef keyc__T1 *keyc_scope;
63
64 struct keyc__T1_r {
65 decl_node scoped;
66 symbolKey_symbolTree symbols;
67 keyc_scope next;
68 };
69
70 static keyc_scope stack;
71 static keyc_scope freeList;
72 static symbolKey_symbolTree keywords;
73 static symbolKey_symbolTree macros;
74 static unsigned int initializedCP;
75 static unsigned int initializedGCC;
76 static unsigned int seenIntMin;
77 static unsigned int seenUIntMin;
78 static unsigned int seenLongMin;
79 static unsigned int seenULongMin;
80 static unsigned int seenCharMin;
81 static unsigned int seenUCharMin;
82 static unsigned int seenIntMax;
83 static unsigned int seenUIntMax;
84 static unsigned int seenLongMax;
85 static unsigned int seenULongMax;
86 static unsigned int seenCharMax;
87 static unsigned int seenUCharMax;
88 static unsigned int seenLabs;
89 static unsigned int seenAbs;
90 static unsigned int seenFabs;
91 static unsigned int seenFabsl;
92 static unsigned int seenSize_t;
93 static unsigned int seenSSize_t;
94 static unsigned int seenUnistd;
95 static unsigned int seenSysTypes;
96 static unsigned int seenThrow;
97 static unsigned int seenFree;
98 static unsigned int seenMalloc;
99 static unsigned int seenStorage;
100 static unsigned int seenProc;
101 static unsigned int seenTrue;
102 static unsigned int seenFalse;
103 static unsigned int seenNull;
104 static unsigned int seenMemcpy;
105 static unsigned int seenException;
106 static unsigned int seenComplex;
107 static unsigned int seenM2RTS;
108 static unsigned int seenStrlen;
109 static unsigned int seenCtype;
110
111 /*
112 useUnistd - need to use unistd.h call using open/close/read/write require this header.
113 */
114
115 extern "C" void keyc_useUnistd (void);
116
117 /*
118 useThrow - use the throw function.
119 */
120
121 extern "C" void keyc_useThrow (void);
122
123 /*
124 useStorage - indicate we have used storage.
125 */
126
127 extern "C" void keyc_useStorage (void);
128
129 /*
130 useFree - indicate we have used free.
131 */
132
133 extern "C" void keyc_useFree (void);
134
135 /*
136 useMalloc - indicate we have used malloc.
137 */
138
139 extern "C" void keyc_useMalloc (void);
140
141 /*
142 useProc - indicate we have used proc.
143 */
144
145 extern "C" void keyc_useProc (void);
146
147 /*
148 useTrue - indicate we have used TRUE.
149 */
150
151 extern "C" void keyc_useTrue (void);
152
153 /*
154 useFalse - indicate we have used FALSE.
155 */
156
157 extern "C" void keyc_useFalse (void);
158
159 /*
160 useNull - indicate we have used NULL.
161 */
162
163 extern "C" void keyc_useNull (void);
164
165 /*
166 useMemcpy - indicate we have used memcpy.
167 */
168
169 extern "C" void keyc_useMemcpy (void);
170
171 /*
172 useIntMin - indicate we have used INT_MIN.
173 */
174
175 extern "C" void keyc_useIntMin (void);
176
177 /*
178 useUIntMin - indicate we have used UINT_MIN.
179 */
180
181 extern "C" void keyc_useUIntMin (void);
182
183 /*
184 useLongMin - indicate we have used LONG_MIN.
185 */
186
187 extern "C" void keyc_useLongMin (void);
188
189 /*
190 useULongMin - indicate we have used ULONG_MIN.
191 */
192
193 extern "C" void keyc_useULongMin (void);
194
195 /*
196 useCharMin - indicate we have used CHAR_MIN.
197 */
198
199 extern "C" void keyc_useCharMin (void);
200
201 /*
202 useUCharMin - indicate we have used UCHAR_MIN.
203 */
204
205 extern "C" void keyc_useUCharMin (void);
206
207 /*
208 useIntMax - indicate we have used INT_MAX.
209 */
210
211 extern "C" void keyc_useIntMax (void);
212
213 /*
214 useUIntMax - indicate we have used UINT_MAX.
215 */
216
217 extern "C" void keyc_useUIntMax (void);
218
219 /*
220 useLongMax - indicate we have used LONG_MAX.
221 */
222
223 extern "C" void keyc_useLongMax (void);
224
225 /*
226 useULongMax - indicate we have used ULONG_MAX.
227 */
228
229 extern "C" void keyc_useULongMax (void);
230
231 /*
232 useCharMax - indicate we have used CHAR_MAX.
233 */
234
235 extern "C" void keyc_useCharMax (void);
236
237 /*
238 useUCharMax - indicate we have used UChar_MAX.
239 */
240
241 extern "C" void keyc_useUCharMax (void);
242
243 /*
244 useSize_t - indicate we have used size_t.
245 */
246
247 extern "C" void keyc_useSize_t (void);
248
249 /*
250 useSSize_t - indicate we have used ssize_t.
251 */
252
253 extern "C" void keyc_useSSize_t (void);
254
255 /*
256 useLabs - indicate we have used labs.
257 */
258
259 extern "C" void keyc_useLabs (void);
260
261 /*
262 useAbs - indicate we have used abs.
263 */
264
265 extern "C" void keyc_useAbs (void);
266
267 /*
268 useFabs - indicate we have used fabs.
269 */
270
271 extern "C" void keyc_useFabs (void);
272
273 /*
274 useFabsl - indicate we have used fabsl.
275 */
276
277 extern "C" void keyc_useFabsl (void);
278
279 /*
280 useException - use the exceptions module, mcrts.
281 */
282
283 extern "C" void keyc_useException (void);
284
285 /*
286 useComplex - use the complex data type.
287 */
288
289 extern "C" void keyc_useComplex (void);
290
291 /*
292 useM2RTS - indicate we have used M2RTS in the converted code.
293 */
294
295 extern "C" void keyc_useM2RTS (void);
296
297 /*
298 useStrlen - indicate we have used strlen in the converted code.
299 */
300
301 extern "C" void keyc_useStrlen (void);
302
303 /*
304 useCtype - indicate we have used the toupper function.
305 */
306
307 extern "C" void keyc_useCtype (void);
308
309 /*
310 genDefs - generate definitions or includes for all
311 macros and prototypes used.
312 */
313
314 extern "C" void keyc_genDefs (mcPretty_pretty p);
315
316 /*
317 genConfigSystem - generate include files for config.h and system.h
318 within the GCC framework.
319 */
320
321 extern "C" void keyc_genConfigSystem (mcPretty_pretty p);
322
323 /*
324 enterScope - enter a scope defined by, n.
325 */
326
327 extern "C" void keyc_enterScope (decl_node n);
328
329 /*
330 leaveScope - leave the scope defined by, n.
331 */
332
333 extern "C" void keyc_leaveScope (decl_node n);
334
335 /*
336 cname - attempts to declare a symbol with name, n, in the
337 current scope. If there is no conflict with the
338 target language then NIL is returned, otherwise
339 a mangled name is returned as a String.
340 If scopes is FALSE then only the keywords and
341 macros are detected for a clash (all scoping
342 is ignored).
343 */
344
345 extern "C" DynamicStrings_String keyc_cname (nameKey_Name n, unsigned int scopes);
346
347 /*
348 cnamen - attempts to declare a symbol with name, n, in the
349 current scope. If there is no conflict with the
350 target language then NIL is returned, otherwise
351 a mangled name is returned as a Name
352 If scopes is FALSE then only the keywords and
353 macros are detected for a clash (all scoping
354 is ignored).
355 */
356
357 extern "C" nameKey_Name keyc_cnamen (nameKey_Name n, unsigned int scopes);
358
359 /*
360 cp - include C++ keywords and standard declarations to avoid.
361 */
362
363 extern "C" void keyc_cp (void);
364
365 /*
366 checkGccConfigSystem - issues the GCC include config.h, include system.h
367 instead of the standard host include.
368 */
369
370 static void checkGccConfigSystem (mcPretty_pretty p);
371
372 /*
373 checkCtype -
374 */
375
376 static void checkCtype (mcPretty_pretty p);
377
378 /*
379 checkAbs - check to see if the abs family, size_t or ssize_t have been used.
380 */
381
382 static void checkAbs (mcPretty_pretty p);
383
384 /*
385 checkLimits -
386 */
387
388 static void checkLimits (mcPretty_pretty p);
389
390 /*
391 checkFreeMalloc -
392 */
393
394 static void checkFreeMalloc (mcPretty_pretty p);
395
396 /*
397 checkStorage -
398 */
399
400 static void checkStorage (mcPretty_pretty p);
401
402 /*
403 checkProc -
404 */
405
406 static void checkProc (mcPretty_pretty p);
407
408 /*
409 checkTrue -
410 */
411
412 static void checkTrue (mcPretty_pretty p);
413
414 /*
415 checkFalse -
416 */
417
418 static void checkFalse (mcPretty_pretty p);
419
420 /*
421 checkNull -
422 */
423
424 static void checkNull (mcPretty_pretty p);
425
426 /*
427 checkMemcpy -
428 */
429
430 static void checkMemcpy (mcPretty_pretty p);
431
432 /*
433 checkM2RTS -
434 */
435
436 static void checkM2RTS (mcPretty_pretty p);
437
438 /*
439 checkException - check to see if exceptions were used.
440 */
441
442 static void checkException (mcPretty_pretty p);
443
444 /*
445 checkThrow - check to see if the throw function is used.
446 */
447
448 static void checkThrow (mcPretty_pretty p);
449
450 /*
451 checkUnistd - check to see if the unistd.h header file is required.
452 */
453
454 static void checkUnistd (mcPretty_pretty p);
455
456 /*
457 checkComplex - check to see if the type complex was used.
458 */
459
460 static void checkComplex (mcPretty_pretty p);
461
462 /*
463 checkSysTypes - emit header for sys/types.h if necessary.
464 */
465
466 static void checkSysTypes (mcPretty_pretty p);
467
468 /*
469 fixNullPointerConst - fixup for NULL on some C++11 systems.
470 */
471
472 static void fixNullPointerConst (mcPretty_pretty p);
473
474 /*
475 new -
476 */
477
478 static keyc_scope new_ (decl_node n);
479
480 /*
481 mangle1 - returns TRUE if name is unique if we add _
482 to its end.
483 */
484
485 static unsigned int mangle1 (nameKey_Name n, DynamicStrings_String *m, unsigned int scopes);
486
487 /*
488 mangle2 - returns TRUE if name is unique if we prepend _
489 to, n.
490 */
491
492 static unsigned int mangle2 (nameKey_Name n, DynamicStrings_String *m, unsigned int scopes);
493
494 /*
495 mangleN - keep adding '_' to the end of n until it
496 no longer clashes.
497 */
498
499 static unsigned int mangleN (nameKey_Name n, DynamicStrings_String *m, unsigned int scopes);
500
501 /*
502 clash - returns TRUE if there is a clash with name, n,
503 in the current scope or C keywords or C macros.
504 */
505
506 static unsigned int clash (nameKey_Name n, unsigned int scopes);
507
508 /*
509 initCP - add the extra keywords and standard definitions used by C++.
510 */
511
512 static void initCP (void);
513
514 /*
515 add -
516 */
517
518 static void add (symbolKey_symbolTree s, const char *a_, unsigned int _a_high);
519
520 /*
521 initMacros - macros and library function names to avoid.
522 */
523
524 static void initMacros (void);
525
526 /*
527 initKeywords - keywords to avoid.
528 */
529
530 static void initKeywords (void);
531
532 /*
533 init -
534 */
535
536 static void init (void);
537
538
539 /*
540 checkGccConfigSystem - issues the GCC include config.h, include system.h
541 instead of the standard host include.
542 */
543
544 static void checkGccConfigSystem (mcPretty_pretty p)
545 {
546 if (mcOptions_getGccConfigSystem ())
547 {
548 if (! initializedGCC)
549 {
550 initializedGCC = TRUE;
551 mcPretty_print (p, (const char *) "#include \"config.h\"\\n", 21);
552 mcPretty_print (p, (const char *) "#include \"system.h\"\\n", 21);
553 }
554 }
555 }
556
557
558 /*
559 checkCtype -
560 */
561
562 static void checkCtype (mcPretty_pretty p)
563 {
564 if (seenCtype)
565 {
566 checkGccConfigSystem (p);
567 if (mcOptions_getGccConfigSystem ())
568 {
569 /* GCC header files use a safe variant. */
570 mcPretty_print (p, (const char *) "#include <safe-ctype.h>\\n", 25);
571 }
572 else
573 {
574 mcPretty_print (p, (const char *) "#include <ctype.h>\\n", 20);
575 }
576 }
577 }
578
579
580 /*
581 checkAbs - check to see if the abs family, size_t or ssize_t have been used.
582 */
583
584 static void checkAbs (mcPretty_pretty p)
585 {
586 if (((((seenLabs || seenAbs) || seenFabs) || seenFabsl) || seenSize_t) || seenSSize_t)
587 {
588 checkGccConfigSystem (p);
589 if (! (mcOptions_getGccConfigSystem ()))
590 {
591 mcPretty_print (p, (const char *) "#include <stdlib.h>\\n", 21);
592 }
593 }
594 }
595
596
597 /*
598 checkLimits -
599 */
600
601 static void checkLimits (mcPretty_pretty p)
602 {
603 if ((((((((((((((seenMemcpy || seenIntMin) || seenUIntMin) || seenLongMin) || seenULongMin) || seenCharMin) || seenUCharMin) || seenUIntMin) || seenIntMax) || seenUIntMax) || seenLongMax) || seenULongMax) || seenCharMax) || seenUCharMax) || seenUIntMax)
604 {
605 checkGccConfigSystem (p);
606 if (! (mcOptions_getGccConfigSystem ()))
607 {
608 mcPretty_print (p, (const char *) "#include <limits.h>\\n", 21);
609 }
610 }
611 }
612
613
614 /*
615 checkFreeMalloc -
616 */
617
618 static void checkFreeMalloc (mcPretty_pretty p)
619 {
620 if (seenFree || seenMalloc)
621 {
622 checkGccConfigSystem (p);
623 if (! (mcOptions_getGccConfigSystem ()))
624 {
625 mcPretty_print (p, (const char *) "#include <stdlib.h>\\n", 21);
626 }
627 }
628 }
629
630
631 /*
632 checkStorage -
633 */
634
635 static void checkStorage (mcPretty_pretty p)
636 {
637 if (seenStorage)
638 {
639 mcPretty_print (p, (const char *) "# include \"", 13);
640 mcPretty_prints (p, mcOptions_getHPrefix ());
641 mcPretty_print (p, (const char *) "Storage.h\"\\n", 12);
642 }
643 }
644
645
646 /*
647 checkProc -
648 */
649
650 static void checkProc (mcPretty_pretty p)
651 {
652 if (seenProc)
653 {
654 mcPretty_print (p, (const char *) "# if !defined (PROC_D)\\n", 26);
655 mcPretty_print (p, (const char *) "# define PROC_D\\n", 22);
656 mcPretty_print (p, (const char *) " typedef void (*PROC_t) (void);\\n", 39);
657 mcPretty_print (p, (const char *) " typedef struct { PROC_t proc; } PROC;\\n", 46);
658 mcPretty_print (p, (const char *) "# endif\\n\\n", 13);
659 }
660 }
661
662
663 /*
664 checkTrue -
665 */
666
667 static void checkTrue (mcPretty_pretty p)
668 {
669 if (seenTrue)
670 {
671 mcPretty_print (p, (const char *) "# if !defined (TRUE)\\n", 24);
672 mcPretty_print (p, (const char *) "# define TRUE (1==1)\\n", 27);
673 mcPretty_print (p, (const char *) "# endif\\n\\n", 13);
674 }
675 }
676
677
678 /*
679 checkFalse -
680 */
681
682 static void checkFalse (mcPretty_pretty p)
683 {
684 if (seenFalse)
685 {
686 mcPretty_print (p, (const char *) "# if !defined (FALSE)\\n", 25);
687 mcPretty_print (p, (const char *) "# define FALSE (1==0)\\n", 28);
688 mcPretty_print (p, (const char *) "# endif\\n\\n", 13);
689 }
690 }
691
692
693 /*
694 checkNull -
695 */
696
697 static void checkNull (mcPretty_pretty p)
698 {
699 if (seenNull)
700 {
701 checkGccConfigSystem (p);
702 if (! (mcOptions_getGccConfigSystem ()))
703 {
704 mcPretty_print (p, (const char *) "#include <stddef.h>\\n", 21);
705 }
706 }
707 }
708
709
710 /*
711 checkMemcpy -
712 */
713
714 static void checkMemcpy (mcPretty_pretty p)
715 {
716 if (seenMemcpy || seenStrlen)
717 {
718 checkGccConfigSystem (p);
719 if (! (mcOptions_getGccConfigSystem ()))
720 {
721 mcPretty_print (p, (const char *) "#include <string.h>\\n", 21);
722 }
723 }
724 }
725
726
727 /*
728 checkM2RTS -
729 */
730
731 static void checkM2RTS (mcPretty_pretty p)
732 {
733 if (seenM2RTS)
734 {
735 mcPretty_print (p, (const char *) "# include \"", 13);
736 mcPretty_prints (p, mcOptions_getHPrefix ());
737 mcPretty_print (p, (const char *) "M2RTS.h\"\\n", 10);
738 }
739 }
740
741
742 /*
743 checkException - check to see if exceptions were used.
744 */
745
746 static void checkException (mcPretty_pretty p)
747 {
748 if (seenException)
749 {
750 mcPretty_print (p, (const char *) "# include \"Gmcrts.h\"\\n", 24);
751 }
752 }
753
754
755 /*
756 checkThrow - check to see if the throw function is used.
757 */
758
759 static void checkThrow (mcPretty_pretty p)
760 {
761 if (seenThrow)
762 {
763 /* print (p, '# include "sys/cdefs.h"
764 ') ; */
765 mcPretty_print (p, (const char *) "#ifndef __cplusplus\\n", 21);
766 mcPretty_print (p, (const char *) "extern void throw (unsigned int);\\n", 35);
767 mcPretty_print (p, (const char *) "#endif\\n", 8);
768 }
769 }
770
771
772 /*
773 checkUnistd - check to see if the unistd.h header file is required.
774 */
775
776 static void checkUnistd (mcPretty_pretty p)
777 {
778 if (seenUnistd)
779 {
780 checkGccConfigSystem (p);
781 if (! (mcOptions_getGccConfigSystem ()))
782 {
783 mcPretty_print (p, (const char *) "#include <unistd.h>\\n", 21);
784 }
785 }
786 }
787
788
789 /*
790 checkComplex - check to see if the type complex was used.
791 */
792
793 static void checkComplex (mcPretty_pretty p)
794 {
795 if (seenComplex)
796 {
797 checkGccConfigSystem (p);
798 if (! (mcOptions_getGccConfigSystem ()))
799 {
800 mcPretty_print (p, (const char *) "# include <complex.h>\\n", 25);
801 }
802 }
803 }
804
805
806 /*
807 checkSysTypes - emit header for sys/types.h if necessary.
808 */
809
810 static void checkSysTypes (mcPretty_pretty p)
811 {
812 if (seenSysTypes)
813 {
814 checkGccConfigSystem (p);
815 if (! (mcOptions_getGccConfigSystem ()))
816 {
817 mcPretty_print (p, (const char *) "# include <sys/types.h>\\n", 27);
818 }
819 }
820 }
821
822
823 /*
824 fixNullPointerConst - fixup for NULL on some C++11 systems.
825 */
826
827 static void fixNullPointerConst (mcPretty_pretty p)
828 {
829 if (seenNull)
830 {
831 mcPretty_print (p, (const char *) "#if defined(__cplusplus)\\n", 26);
832 mcPretty_print (p, (const char *) "# undef NULL\\n", 16);
833 mcPretty_print (p, (const char *) "# define NULL 0\\n", 19);
834 mcPretty_print (p, (const char *) "#endif\\n", 8);
835 }
836 }
837
838
839 /*
840 new -
841 */
842
843 static keyc_scope new_ (decl_node n)
844 {
845 keyc_scope s;
846
847 if (freeList == NULL)
848 {
849 Storage_ALLOCATE ((void **) &s, sizeof (keyc__T1));
850 }
851 else
852 {
853 s = freeList;
854 freeList = freeList->next;
855 }
856 return s;
857 /* static analysis guarentees a RETURN statement will be used before here. */
858 __builtin_unreachable ();
859 }
860
861
862 /*
863 mangle1 - returns TRUE if name is unique if we add _
864 to its end.
865 */
866
867 static unsigned int mangle1 (nameKey_Name n, DynamicStrings_String *m, unsigned int scopes)
868 {
869 (*m) = DynamicStrings_KillString ((*m));
870 (*m) = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (n));
871 (*m) = DynamicStrings_ConCatChar ((*m), '_');
872 return ! (clash (nameKey_makekey (DynamicStrings_string ((*m))), scopes));
873 /* static analysis guarentees a RETURN statement will be used before here. */
874 __builtin_unreachable ();
875 }
876
877
878 /*
879 mangle2 - returns TRUE if name is unique if we prepend _
880 to, n.
881 */
882
883 static unsigned int mangle2 (nameKey_Name n, DynamicStrings_String *m, unsigned int scopes)
884 {
885 (*m) = DynamicStrings_KillString ((*m));
886 (*m) = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (n));
887 (*m) = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "_", 1), DynamicStrings_Mark ((*m)));
888 return ! (clash (nameKey_makekey (DynamicStrings_string ((*m))), scopes));
889 /* static analysis guarentees a RETURN statement will be used before here. */
890 __builtin_unreachable ();
891 }
892
893
894 /*
895 mangleN - keep adding '_' to the end of n until it
896 no longer clashes.
897 */
898
899 static unsigned int mangleN (nameKey_Name n, DynamicStrings_String *m, unsigned int scopes)
900 {
901 (*m) = DynamicStrings_KillString ((*m));
902 (*m) = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (n));
903 for (;;)
904 {
905 (*m) = DynamicStrings_ConCatChar ((*m), '_');
906 if (! (clash (nameKey_makekey (DynamicStrings_string ((*m))), scopes)))
907 {
908 return TRUE;
909 }
910 }
911 ReturnException ("../../gcc-git-devel-modula2/gcc/m2/mc/keyc.def", 20, 1);
912 __builtin_unreachable ();
913 }
914
915
916 /*
917 clash - returns TRUE if there is a clash with name, n,
918 in the current scope or C keywords or C macros.
919 */
920
921 static unsigned int clash (nameKey_Name n, unsigned int scopes)
922 {
923 if (((symbolKey_getSymKey (macros, n)) != NULL) || ((symbolKey_getSymKey (keywords, n)) != NULL))
924 {
925 return TRUE;
926 }
927 return scopes && ((symbolKey_getSymKey (stack->symbols, n)) != NULL);
928 /* static analysis guarentees a RETURN statement will be used before here. */
929 __builtin_unreachable ();
930 }
931
932
933 /*
934 initCP - add the extra keywords and standard definitions used by C++.
935 */
936
937 static void initCP (void)
938 {
939 add (keywords, (const char *) "delete", 6);
940 add (keywords, (const char *) "try", 3);
941 add (keywords, (const char *) "catch", 5);
942 add (keywords, (const char *) "operator", 8);
943 add (keywords, (const char *) "complex", 7);
944 add (keywords, (const char *) "export", 6);
945 add (keywords, (const char *) "public", 6);
946 }
947
948
949 /*
950 add -
951 */
952
953 static void add (symbolKey_symbolTree s, const char *a_, unsigned int _a_high)
954 {
955 char a[_a_high+1];
956
957 /* make a local copy of each unbounded array. */
958 memcpy (a, a_, _a_high+1);
959
960 symbolKey_putSymKey (s, nameKey_makeKey ((const char *) a, _a_high), reinterpret_cast<void *> (DynamicStrings_InitString ((const char *) a, _a_high)));
961 }
962
963
964 /*
965 initMacros - macros and library function names to avoid.
966 */
967
968 static void initMacros (void)
969 {
970 macros = symbolKey_initTree ();
971 add (macros, (const char *) "FILE", 4);
972 add (macros, (const char *) "EOF", 3);
973 add (macros, (const char *) "stdio", 5);
974 add (macros, (const char *) "stdout", 6);
975 add (macros, (const char *) "stderr", 6);
976 add (macros, (const char *) "write", 5);
977 add (macros, (const char *) "read", 4);
978 add (macros, (const char *) "exit", 4);
979 add (macros, (const char *) "abs", 3);
980 add (macros, (const char *) "optarg", 6);
981 add (macros, (const char *) "div", 3);
982 add (macros, (const char *) "sin", 3);
983 add (macros, (const char *) "cos", 3);
984 add (macros, (const char *) "tan", 3);
985 add (macros, (const char *) "log10", 5);
986 add (macros, (const char *) "trunc", 5);
987 add (macros, (const char *) "I", 1);
988 add (macros, (const char *) "csqrt", 5);
989 add (macros, (const char *) "strlen", 6);
990 add (macros, (const char *) "strcpy", 6);
991 add (macros, (const char *) "free", 4);
992 add (macros, (const char *) "malloc", 6);
993 add (macros, (const char *) "time", 4);
994 add (macros, (const char *) "main", 4);
995 add (macros, (const char *) "true", 4);
996 add (macros, (const char *) "false", 5);
997 add (macros, (const char *) "sigfpe", 6);
998 }
999
1000
1001 /*
1002 initKeywords - keywords to avoid.
1003 */
1004
1005 static void initKeywords (void)
1006 {
1007 keywords = symbolKey_initTree ();
1008 add (keywords, (const char *) "auto", 4);
1009 add (keywords, (const char *) "break", 5);
1010 add (keywords, (const char *) "case", 4);
1011 add (keywords, (const char *) "char", 4);
1012 add (keywords, (const char *) "const", 5);
1013 add (keywords, (const char *) "continue", 8);
1014 add (keywords, (const char *) "default", 7);
1015 add (keywords, (const char *) "do", 2);
1016 add (keywords, (const char *) "double", 6);
1017 add (keywords, (const char *) "else", 4);
1018 add (keywords, (const char *) "enum", 4);
1019 add (keywords, (const char *) "extern", 6);
1020 add (keywords, (const char *) "float", 5);
1021 add (keywords, (const char *) "for", 3);
1022 add (keywords, (const char *) "goto", 4);
1023 add (keywords, (const char *) "if", 2);
1024 add (keywords, (const char *) "int", 3);
1025 add (keywords, (const char *) "long", 4);
1026 add (keywords, (const char *) "register", 8);
1027 add (keywords, (const char *) "return", 6);
1028 add (keywords, (const char *) "short", 5);
1029 add (keywords, (const char *) "signed", 6);
1030 add (keywords, (const char *) "sizeof", 6);
1031 add (keywords, (const char *) "static", 6);
1032 add (keywords, (const char *) "struct", 6);
1033 add (keywords, (const char *) "switch", 6);
1034 add (keywords, (const char *) "typedef", 7);
1035 add (keywords, (const char *) "union", 5);
1036 add (keywords, (const char *) "unsigned", 8);
1037 add (keywords, (const char *) "void", 4);
1038 add (keywords, (const char *) "volatile", 8);
1039 add (keywords, (const char *) "while", 5);
1040 add (keywords, (const char *) "and", 3);
1041 add (keywords, (const char *) "or", 2);
1042 add (keywords, (const char *) "not", 3);
1043 add (keywords, (const char *) "throw", 5);
1044 add (keywords, (const char *) "new", 3);
1045 }
1046
1047
1048 /*
1049 init -
1050 */
1051
1052 static void init (void)
1053 {
1054 seenUnistd = FALSE;
1055 seenThrow = FALSE;
1056 seenFree = FALSE;
1057 seenMalloc = FALSE;
1058 seenStorage = FALSE;
1059 seenProc = FALSE;
1060 seenTrue = FALSE;
1061 seenFalse = FALSE;
1062 seenNull = FALSE;
1063 seenMemcpy = FALSE;
1064 seenIntMin = FALSE;
1065 seenUIntMin = FALSE;
1066 seenLongMin = FALSE;
1067 seenULongMin = FALSE;
1068 seenCharMin = FALSE;
1069 seenUCharMin = FALSE;
1070 seenUIntMin = FALSE;
1071 seenIntMax = FALSE;
1072 seenUIntMax = FALSE;
1073 seenLongMax = FALSE;
1074 seenULongMax = FALSE;
1075 seenCharMax = FALSE;
1076 seenUCharMax = FALSE;
1077 seenUIntMax = FALSE;
1078 seenLabs = FALSE;
1079 seenAbs = FALSE;
1080 seenFabs = FALSE;
1081 seenFabsl = FALSE;
1082 seenException = FALSE;
1083 seenComplex = FALSE;
1084 seenM2RTS = FALSE;
1085 seenStrlen = FALSE;
1086 seenCtype = FALSE;
1087 seenSize_t = FALSE;
1088 seenSSize_t = FALSE;
1089 seenSysTypes = FALSE;
1090 initializedCP = FALSE;
1091 initializedGCC = FALSE;
1092 stack = NULL;
1093 freeList = NULL;
1094 initKeywords ();
1095 initMacros ();
1096 }
1097
1098
1099 /*
1100 useUnistd - need to use unistd.h call using open/close/read/write require this header.
1101 */
1102
1103 extern "C" void keyc_useUnistd (void)
1104 {
1105 seenUnistd = TRUE;
1106 }
1107
1108
1109 /*
1110 useThrow - use the throw function.
1111 */
1112
1113 extern "C" void keyc_useThrow (void)
1114 {
1115 seenThrow = TRUE;
1116 }
1117
1118
1119 /*
1120 useStorage - indicate we have used storage.
1121 */
1122
1123 extern "C" void keyc_useStorage (void)
1124 {
1125 seenStorage = TRUE;
1126 }
1127
1128
1129 /*
1130 useFree - indicate we have used free.
1131 */
1132
1133 extern "C" void keyc_useFree (void)
1134 {
1135 seenFree = TRUE;
1136 }
1137
1138
1139 /*
1140 useMalloc - indicate we have used malloc.
1141 */
1142
1143 extern "C" void keyc_useMalloc (void)
1144 {
1145 seenMalloc = TRUE;
1146 }
1147
1148
1149 /*
1150 useProc - indicate we have used proc.
1151 */
1152
1153 extern "C" void keyc_useProc (void)
1154 {
1155 seenProc = TRUE;
1156 }
1157
1158
1159 /*
1160 useTrue - indicate we have used TRUE.
1161 */
1162
1163 extern "C" void keyc_useTrue (void)
1164 {
1165 seenTrue = TRUE;
1166 }
1167
1168
1169 /*
1170 useFalse - indicate we have used FALSE.
1171 */
1172
1173 extern "C" void keyc_useFalse (void)
1174 {
1175 seenFalse = TRUE;
1176 }
1177
1178
1179 /*
1180 useNull - indicate we have used NULL.
1181 */
1182
1183 extern "C" void keyc_useNull (void)
1184 {
1185 seenNull = TRUE;
1186 }
1187
1188
1189 /*
1190 useMemcpy - indicate we have used memcpy.
1191 */
1192
1193 extern "C" void keyc_useMemcpy (void)
1194 {
1195 seenMemcpy = TRUE;
1196 }
1197
1198
1199 /*
1200 useIntMin - indicate we have used INT_MIN.
1201 */
1202
1203 extern "C" void keyc_useIntMin (void)
1204 {
1205 seenIntMin = TRUE;
1206 }
1207
1208
1209 /*
1210 useUIntMin - indicate we have used UINT_MIN.
1211 */
1212
1213 extern "C" void keyc_useUIntMin (void)
1214 {
1215 seenUIntMin = TRUE;
1216 }
1217
1218
1219 /*
1220 useLongMin - indicate we have used LONG_MIN.
1221 */
1222
1223 extern "C" void keyc_useLongMin (void)
1224 {
1225 seenLongMin = TRUE;
1226 }
1227
1228
1229 /*
1230 useULongMin - indicate we have used ULONG_MIN.
1231 */
1232
1233 extern "C" void keyc_useULongMin (void)
1234 {
1235 seenULongMin = TRUE;
1236 }
1237
1238
1239 /*
1240 useCharMin - indicate we have used CHAR_MIN.
1241 */
1242
1243 extern "C" void keyc_useCharMin (void)
1244 {
1245 seenCharMin = TRUE;
1246 }
1247
1248
1249 /*
1250 useUCharMin - indicate we have used UCHAR_MIN.
1251 */
1252
1253 extern "C" void keyc_useUCharMin (void)
1254 {
1255 seenUCharMin = TRUE;
1256 }
1257
1258
1259 /*
1260 useIntMax - indicate we have used INT_MAX.
1261 */
1262
1263 extern "C" void keyc_useIntMax (void)
1264 {
1265 seenIntMax = TRUE;
1266 }
1267
1268
1269 /*
1270 useUIntMax - indicate we have used UINT_MAX.
1271 */
1272
1273 extern "C" void keyc_useUIntMax (void)
1274 {
1275 seenUIntMax = TRUE;
1276 }
1277
1278
1279 /*
1280 useLongMax - indicate we have used LONG_MAX.
1281 */
1282
1283 extern "C" void keyc_useLongMax (void)
1284 {
1285 seenLongMax = TRUE;
1286 }
1287
1288
1289 /*
1290 useULongMax - indicate we have used ULONG_MAX.
1291 */
1292
1293 extern "C" void keyc_useULongMax (void)
1294 {
1295 seenULongMax = TRUE;
1296 }
1297
1298
1299 /*
1300 useCharMax - indicate we have used CHAR_MAX.
1301 */
1302
1303 extern "C" void keyc_useCharMax (void)
1304 {
1305 seenCharMax = TRUE;
1306 }
1307
1308
1309 /*
1310 useUCharMax - indicate we have used UChar_MAX.
1311 */
1312
1313 extern "C" void keyc_useUCharMax (void)
1314 {
1315 seenUCharMax = TRUE;
1316 }
1317
1318
1319 /*
1320 useSize_t - indicate we have used size_t.
1321 */
1322
1323 extern "C" void keyc_useSize_t (void)
1324 {
1325 seenSize_t = TRUE;
1326 }
1327
1328
1329 /*
1330 useSSize_t - indicate we have used ssize_t.
1331 */
1332
1333 extern "C" void keyc_useSSize_t (void)
1334 {
1335 seenSSize_t = TRUE;
1336 seenSysTypes = TRUE;
1337 }
1338
1339
1340 /*
1341 useLabs - indicate we have used labs.
1342 */
1343
1344 extern "C" void keyc_useLabs (void)
1345 {
1346 seenLabs = TRUE;
1347 }
1348
1349
1350 /*
1351 useAbs - indicate we have used abs.
1352 */
1353
1354 extern "C" void keyc_useAbs (void)
1355 {
1356 seenAbs = TRUE;
1357 }
1358
1359
1360 /*
1361 useFabs - indicate we have used fabs.
1362 */
1363
1364 extern "C" void keyc_useFabs (void)
1365 {
1366 seenFabs = TRUE;
1367 }
1368
1369
1370 /*
1371 useFabsl - indicate we have used fabsl.
1372 */
1373
1374 extern "C" void keyc_useFabsl (void)
1375 {
1376 seenFabsl = TRUE;
1377 }
1378
1379
1380 /*
1381 useException - use the exceptions module, mcrts.
1382 */
1383
1384 extern "C" void keyc_useException (void)
1385 {
1386 seenException = TRUE;
1387 }
1388
1389
1390 /*
1391 useComplex - use the complex data type.
1392 */
1393
1394 extern "C" void keyc_useComplex (void)
1395 {
1396 seenComplex = TRUE;
1397 }
1398
1399
1400 /*
1401 useM2RTS - indicate we have used M2RTS in the converted code.
1402 */
1403
1404 extern "C" void keyc_useM2RTS (void)
1405 {
1406 seenM2RTS = TRUE;
1407 }
1408
1409
1410 /*
1411 useStrlen - indicate we have used strlen in the converted code.
1412 */
1413
1414 extern "C" void keyc_useStrlen (void)
1415 {
1416 seenStrlen = TRUE;
1417 }
1418
1419
1420 /*
1421 useCtype - indicate we have used the toupper function.
1422 */
1423
1424 extern "C" void keyc_useCtype (void)
1425 {
1426 seenCtype = TRUE;
1427 }
1428
1429
1430 /*
1431 genDefs - generate definitions or includes for all
1432 macros and prototypes used.
1433 */
1434
1435 extern "C" void keyc_genDefs (mcPretty_pretty p)
1436 {
1437 checkFreeMalloc (p);
1438 checkProc (p);
1439 checkTrue (p);
1440 checkFalse (p);
1441 checkNull (p);
1442 checkMemcpy (p);
1443 checkLimits (p);
1444 checkAbs (p);
1445 checkStorage (p);
1446 checkException (p);
1447 checkComplex (p);
1448 checkCtype (p);
1449 checkUnistd (p);
1450 checkSysTypes (p);
1451 checkM2RTS (p);
1452 checkThrow (p);
1453 fixNullPointerConst (p);
1454 }
1455
1456
1457 /*
1458 genConfigSystem - generate include files for config.h and system.h
1459 within the GCC framework.
1460 */
1461
1462 extern "C" void keyc_genConfigSystem (mcPretty_pretty p)
1463 {
1464 checkGccConfigSystem (p);
1465 }
1466
1467
1468 /*
1469 enterScope - enter a scope defined by, n.
1470 */
1471
1472 extern "C" void keyc_enterScope (decl_node n)
1473 {
1474 keyc_scope s;
1475
1476 s = new_ (n);
1477 s->scoped = n;
1478 s->symbols = symbolKey_initTree ();
1479 s->next = stack;
1480 stack = s;
1481 }
1482
1483
1484 /*
1485 leaveScope - leave the scope defined by, n.
1486 */
1487
1488 extern "C" void keyc_leaveScope (decl_node n)
1489 {
1490 keyc_scope s;
1491
1492 if (n == stack->scoped)
1493 {
1494 s = stack;
1495 stack = stack->next;
1496 s->scoped = static_cast<decl_node> (NULL);
1497 symbolKey_killTree (&s->symbols);
1498 s->next = NULL;
1499 }
1500 else
1501 {
1502 M2RTS_HALT (-1);
1503 __builtin_unreachable ();
1504 }
1505 }
1506
1507
1508 /*
1509 cname - attempts to declare a symbol with name, n, in the
1510 current scope. If there is no conflict with the
1511 target language then NIL is returned, otherwise
1512 a mangled name is returned as a String.
1513 If scopes is FALSE then only the keywords and
1514 macros are detected for a clash (all scoping
1515 is ignored).
1516 */
1517
1518 extern "C" DynamicStrings_String keyc_cname (nameKey_Name n, unsigned int scopes)
1519 {
1520 DynamicStrings_String m;
1521
1522 m = static_cast<DynamicStrings_String> (NULL);
1523 if (clash (n, scopes))
1524 {
1525 if (((mangle1 (n, &m, scopes)) || (mangle2 (n, &m, scopes))) || (mangleN (n, &m, scopes)))
1526 {
1527 /* avoid dangling else. */
1528 if (scopes)
1529 {
1530 /* no longer a clash with, m, so add it to the current scope. */
1531 n = nameKey_makekey (DynamicStrings_string (m));
1532 symbolKey_putSymKey (stack->symbols, n, reinterpret_cast<void *> (m));
1533 }
1534 }
1535 else
1536 {
1537 /* mangleN must always succeed. */
1538 M2RTS_HALT (-1);
1539 __builtin_unreachable ();
1540 }
1541 }
1542 else if (scopes)
1543 {
1544 /* avoid dangling else. */
1545 /* no clash, add it to the current scope. */
1546 symbolKey_putSymKey (stack->symbols, n, reinterpret_cast<void *> (DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (n))));
1547 }
1548 return m;
1549 /* static analysis guarentees a RETURN statement will be used before here. */
1550 __builtin_unreachable ();
1551 }
1552
1553
1554 /*
1555 cnamen - attempts to declare a symbol with name, n, in the
1556 current scope. If there is no conflict with the
1557 target language then NIL is returned, otherwise
1558 a mangled name is returned as a Name
1559 If scopes is FALSE then only the keywords and
1560 macros are detected for a clash (all scoping
1561 is ignored).
1562 */
1563
1564 extern "C" nameKey_Name keyc_cnamen (nameKey_Name n, unsigned int scopes)
1565 {
1566 DynamicStrings_String m;
1567
1568 m = static_cast<DynamicStrings_String> (NULL);
1569 if (clash (n, scopes))
1570 {
1571 if (((mangle1 (n, &m, scopes)) || (mangle2 (n, &m, scopes))) || (mangleN (n, &m, scopes)))
1572 {
1573 /* avoid dangling else. */
1574 n = nameKey_makekey (DynamicStrings_string (m));
1575 if (scopes)
1576 {
1577 /* no longer a clash with, m, so add it to the current scope. */
1578 symbolKey_putSymKey (stack->symbols, n, reinterpret_cast<void *> (m));
1579 }
1580 }
1581 else
1582 {
1583 /* mangleN must always succeed. */
1584 M2RTS_HALT (-1);
1585 __builtin_unreachable ();
1586 }
1587 }
1588 else if (scopes)
1589 {
1590 /* avoid dangling else. */
1591 /* no clash, add it to the current scope. */
1592 symbolKey_putSymKey (stack->symbols, n, reinterpret_cast<void *> (DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (n))));
1593 }
1594 m = DynamicStrings_KillString (m);
1595 return n;
1596 /* static analysis guarentees a RETURN statement will be used before here. */
1597 __builtin_unreachable ();
1598 }
1599
1600
1601 /*
1602 cp - include C++ keywords and standard declarations to avoid.
1603 */
1604
1605 extern "C" void keyc_cp (void)
1606 {
1607 if (! initializedCP)
1608 {
1609 initializedCP = TRUE;
1610 initCP ();
1611 }
1612 }
1613
1614 extern "C" void _M2_keyc_init (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
1615 {
1616 init ();
1617 }
1618
1619 extern "C" void _M2_keyc_finish (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
1620 {
1621 }