Branch data Line data Source code
1 : : /* do not edit automatically generated by mc from M2LangDump. */
2 : : /* M2LangDump.mod provides support routines for the -flang-dump.
3 : :
4 : : Copyright (C) 2024 Free Software Foundation, Inc.
5 : : Contributed by Gaius Mulley <gaiusmod2@gmail.com>.
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 <stdbool.h>
26 : : # if !defined (PROC_D)
27 : : # define PROC_D
28 : : typedef void (*PROC_t) (void);
29 : : typedef struct { PROC_t proc; } PROC;
30 : : # endif
31 : :
32 : : # if !defined (TRUE)
33 : : # define TRUE (1==1)
34 : : # endif
35 : :
36 : : # if !defined (FALSE)
37 : : # define FALSE (1==0)
38 : : # endif
39 : :
40 : : #if defined(__cplusplus)
41 : : # undef NULL
42 : : # define NULL 0
43 : : #endif
44 : : #define _M2LangDump_H
45 : : #define _M2LangDump_C
46 : :
47 : : # include "GSYSTEM.h"
48 : : # include "GDynamicStrings.h"
49 : : # include "GSymbolTable.h"
50 : : # include "GM2Options.h"
51 : : # include "GM2GCCDeclare.h"
52 : : # include "GFormatStrings.h"
53 : : # include "GNameKey.h"
54 : : # include "GSymbolConversion.h"
55 : : # include "GM2AsmUtil.h"
56 : : # include "GM2LexBuf.h"
57 : : # include "GM2Printf.h"
58 : : # include "GM2Error.h"
59 : : # include "GM2Batch.h"
60 : : # include "GStrLib.h"
61 : : # include "Glibc.h"
62 : : # include "GFIO.h"
63 : : # include "GSFIO.h"
64 : : # include "GStdIO.h"
65 : :
66 : : # define Debugging false
67 : : static FIO_File outputFile;
68 : : static bool declActive;
69 : : static bool quadActive;
70 : : static bool mustClose;
71 : : static unsigned int NoOfQuadDumps;
72 : : static unsigned int NoOfDeclDumps;
73 : :
74 : : /*
75 : : IsDumpRequiredTree - return TRUE if the gcc tree should be dumped.
76 : : */
77 : :
78 : : extern "C" bool M2LangDump_IsDumpRequiredTree (m2tree_Tree tree, bool default_);
79 : :
80 : : /*
81 : : IsDumpRequired - return TRUE if symbol sym should be dumped
82 : : according to the rules of the filter.
83 : : No filter specified will always return default.
84 : : The filter is a comma separated list. Each element
85 : : of the list can specify a symbol three ways.
86 : : Firstly by DECL name for example: m2pim_NumberIO_HexToStr
87 : : Secondly by qualified scope: [pathname.]NumberIO.HexToStr
88 : : Thirdly by filename and scope: NumberIO.mod:HexToStr
89 : : */
90 : :
91 : : extern "C" bool M2LangDump_IsDumpRequired (unsigned int sym, bool default_);
92 : :
93 : : /*
94 : : MakeQuadTemplate - return a template for the quad dump file.
95 : : */
96 : :
97 : : extern "C" DynamicStrings_String M2LangDump_MakeQuadTemplate (void);
98 : :
99 : : /*
100 : : MakeGimpleTemplate - return a template for the gimple dump file and assign
101 : : len to the max number of characters required to complete
102 : : a template (including a nul terminator).
103 : : */
104 : :
105 : : extern "C" DynamicStrings_String M2LangDump_MakeGimpleTemplate (unsigned int *len);
106 : :
107 : : /*
108 : : GetDumpFile - return the dump output file.
109 : : */
110 : :
111 : : extern "C" FIO_File M2LangDump_GetDumpFile (void);
112 : :
113 : : /*
114 : : CreateDumpQuad - create the dump file for a quad dump.
115 : : */
116 : :
117 : : extern "C" void M2LangDump_CreateDumpQuad (const char *title_, unsigned int _title_high);
118 : :
119 : : /*
120 : : CloseDumpQuad - close the dump output file.
121 : : */
122 : :
123 : : extern "C" void M2LangDump_CloseDumpQuad (void);
124 : :
125 : : /*
126 : : CreateDumpDecl - create the dump file for a decl dump.
127 : : */
128 : :
129 : : extern "C" void M2LangDump_CreateDumpDecl (const char *title_, unsigned int _title_high);
130 : :
131 : : /*
132 : : CloseDumpDecl - close the dump output file.
133 : : */
134 : :
135 : : extern "C" void M2LangDump_CloseDumpDecl (void);
136 : :
137 : : /*
138 : : Assert - call InternalError is NOT value.
139 : : */
140 : :
141 : : static void Assert (bool value);
142 : :
143 : : /*
144 : : DumpWrite - writes a single ch to the dump output.
145 : : */
146 : :
147 : : static void DumpWrite (char ch);
148 : :
149 : : /*
150 : : CloseDump - close the dump file and pop the default write procedure.
151 : : */
152 : :
153 : : static void CloseDump (void);
154 : :
155 : : /*
156 : : OpenDump - open filename as a dump file. The filename '-' is treated as stdout.
157 : : It pushes a write procedure to StdIO.
158 : : */
159 : :
160 : : static void OpenDump (DynamicStrings_String filename, unsigned int no);
161 : :
162 : : /*
163 : : AddRuleTextDump -
164 : : */
165 : :
166 : : static void AddRuleTextDump (DynamicStrings_String rule);
167 : :
168 : : /*
169 : : AddRuleScopeQualidentDump -
170 : : */
171 : :
172 : : static void AddRuleScopeQualidentDump (DynamicStrings_String rule, int dot, unsigned int modsym);
173 : :
174 : : /*
175 : : AddRuleScopeDump -
176 : : */
177 : :
178 : : static void AddRuleScopeDump (DynamicStrings_String rule);
179 : :
180 : : /*
181 : : AddRuleFilenameDump -
182 : : */
183 : :
184 : : static void AddRuleFilenameDump (DynamicStrings_String rule);
185 : :
186 : : /*
187 : : AddRuleSymToDump -
188 : : */
189 : :
190 : : static void AddRuleSymToDump (DynamicStrings_String rule);
191 : :
192 : : /*
193 : : AddFilterListToDumpWatch -
194 : : */
195 : :
196 : : static void AddFilterListToDumpWatch (void * filter);
197 : :
198 : : /*
199 : : CreateDumpTitle - creates the underlined title.
200 : : */
201 : :
202 : : static void CreateDumpTitle (const char *title_, unsigned int _title_high);
203 : :
204 : : /*
205 : : Match - return TRUE if sym matches any of the filter rules.
206 : : */
207 : :
208 : : static bool Match (void * filter, unsigned int sym);
209 : :
210 : : /*
211 : : MatchRule - return TRUE if rule matches sym.
212 : : */
213 : :
214 : : static bool MatchRule (DynamicStrings_String rule, unsigned int sym);
215 : :
216 : : /*
217 : : MatchRuleFilenameScope - returns TRUE if rule contains filename.ext:qualident
218 : : and it matches sym.
219 : : */
220 : :
221 : : static bool MatchRuleFilenameScope (DynamicStrings_String rule, unsigned int sym);
222 : :
223 : : /*
224 : : MatchRuleScope - returns TRUE if rule contains a [libname.]qualified.ident
225 : : and it matches sym.
226 : : */
227 : :
228 : : static bool MatchRuleScope (DynamicStrings_String rule, unsigned int sym);
229 : :
230 : : /*
231 : : MatchRuleQualident - returns TRUE if rule matches qualified sym.
232 : : PostCondition: subrule will be deallocated upon exit.
233 : : TRUE is returned if rule matches qualified sym.
234 : : */
235 : :
236 : : static bool MatchRuleQualident (DynamicStrings_String rule, DynamicStrings_String subrule, int i, unsigned int sym);
237 : :
238 : : /*
239 : : QualifiedScope - PostCondition: true is returned is rule matches a qualified sym.
240 : : i is -1 if no more qualifications or libname is found.
241 : : scope will be the set to the last outer scope seen.
242 : : */
243 : :
244 : : static bool QualifiedScope (DynamicStrings_String rule, unsigned int sym, int *i, unsigned int *scope);
245 : :
246 : : /*
247 : : OptionalLibname - returns TRUE if rule[0..dot] matches syms libname or
248 : : if there is no libname the scope is a module or defimp
249 : : symbol.
250 : : */
251 : :
252 : : static bool OptionalLibname (DynamicStrings_String rule, unsigned int sym, int dot, unsigned int scope);
253 : :
254 : : /*
255 : : MatchRuleIdent - return TRUE if ident sym matches rule.
256 : : The ident must be in a module or defimp scope.
257 : : */
258 : :
259 : : static bool MatchRuleIdent (DynamicStrings_String rule, unsigned int sym);
260 : :
261 : : /*
262 : : MatchRuleText - returns TRUE if rule matches sym.
263 : : */
264 : :
265 : : static bool MatchRuleText (DynamicStrings_String rule, unsigned int sym);
266 : :
267 : : /*
268 : : TextCompareName - return TRUE if rule matches name.
269 : : */
270 : :
271 : : static bool TextCompareName (DynamicStrings_String rule, NameKey_Name name);
272 : :
273 : : /*
274 : : TextMatch - returns TRUE if rule matches text. Currently this
275 : : is a simple string compare, but could be extended
276 : : to implement regexp (seen in the rule).
277 : : */
278 : :
279 : : static bool TextMatch (DynamicStrings_String rule, DynamicStrings_String text);
280 : :
281 : : /*
282 : : CreateTemplate - create and return a template filename with extension.
283 : : If the user has specified "-" then "-" is returned otherwise
284 : : a template is formed from "dumpdir + filename + .%03dl.extension".
285 : : */
286 : :
287 : : static DynamicStrings_String CreateTemplate (DynamicStrings_String filename, DynamicStrings_String extension);
288 : :
289 : : /*
290 : : MakeDeclTemplate - return a template for the decl dump file.
291 : : */
292 : :
293 : : static DynamicStrings_String MakeDeclTemplate (void);
294 : :
295 : : /*
296 : : Init - initialize the module global variables.
297 : : */
298 : :
299 : : static void Init (void);
300 : :
301 : :
302 : : /*
303 : : Assert - call InternalError is NOT value.
304 : : */
305 : :
306 : 0 : static void Assert (bool value)
307 : : {
308 : 0 : if (! value)
309 : : {
310 : 0 : M2Error_InternalError ((const char *) "assert failed in M2LangDump", 27);
311 : : }
312 : 0 : }
313 : :
314 : :
315 : : /*
316 : : DumpWrite - writes a single ch to the dump output.
317 : : */
318 : :
319 : 0 : static void DumpWrite (char ch)
320 : : {
321 : 0 : FIO_WriteChar (outputFile, ch);
322 : 0 : }
323 : :
324 : :
325 : : /*
326 : : CloseDump - close the dump file and pop the default write procedure.
327 : : */
328 : :
329 : 0 : static void CloseDump (void)
330 : : {
331 : 0 : if (mustClose)
332 : : {
333 : 0 : FIO_Close (outputFile);
334 : 0 : mustClose = false;
335 : : }
336 : : else
337 : : {
338 : 0 : FIO_FlushBuffer (outputFile);
339 : : }
340 : 0 : StdIO_PopOutput ();
341 : 0 : outputFile = FIO_StdOut;
342 : 0 : }
343 : :
344 : :
345 : : /*
346 : : OpenDump - open filename as a dump file. The filename '-' is treated as stdout.
347 : : It pushes a write procedure to StdIO.
348 : : */
349 : :
350 : 0 : static void OpenDump (DynamicStrings_String filename, unsigned int no)
351 : : {
352 : 0 : if (DynamicStrings_EqualArray (filename, (const char *) "-", 1))
353 : : {
354 : 0 : mustClose = false;
355 : 0 : outputFile = FIO_StdOut;
356 : : }
357 : : else
358 : : {
359 : 0 : filename = FormatStrings_Sprintf1 (filename, (const unsigned char *) &no, (sizeof (no)-1));
360 : 0 : outputFile = SFIO_OpenToWrite (filename);
361 : 0 : mustClose = FIO_IsNoError (outputFile);
362 : : }
363 : 0 : filename = DynamicStrings_KillString (filename);
364 : 0 : StdIO_PushOutput ((StdIO_ProcWrite) {(StdIO_ProcWrite_t) DumpWrite});
365 : 0 : }
366 : :
367 : :
368 : : /*
369 : : AddRuleTextDump -
370 : : */
371 : :
372 : 0 : static void AddRuleTextDump (DynamicStrings_String rule)
373 : : {
374 : 0 : }
375 : :
376 : :
377 : : /*
378 : : AddRuleScopeQualidentDump -
379 : : */
380 : :
381 : 0 : static void AddRuleScopeQualidentDump (DynamicStrings_String rule, int dot, unsigned int modsym)
382 : : {
383 : 0 : DynamicStrings_String modstr;
384 : 0 : DynamicStrings_String idstr;
385 : 0 : int start;
386 : 0 : unsigned int sym;
387 : :
388 : 0 : start = dot+1;
389 : 0 : dot = DynamicStrings_Index (rule, '.', static_cast<unsigned int> (start));
390 : 0 : while (dot > 0)
391 : : {
392 : 0 : modstr = DynamicStrings_Slice (rule, start, dot);
393 : 0 : modsym = SymbolTable_GetLocalSym (modsym, NameKey_makekey (DynamicStrings_string (modstr)));
394 : 0 : if ((modsym != SymbolTable_NulSym) && (SymbolTable_IsModule (modsym)))
395 : : {
396 : 0 : start = dot+1;
397 : 0 : dot = DynamicStrings_Index (rule, '.', static_cast<unsigned int> (start));
398 : : }
399 : : else
400 : : {
401 : 0 : modstr = DynamicStrings_KillString (modstr);
402 : 0 : return ;
403 : : }
404 : : }
405 : 0 : idstr = DynamicStrings_Slice (rule, start, 0);
406 : 0 : sym = SymbolTable_GetLocalSym (modsym, NameKey_makekey (DynamicStrings_string (idstr)));
407 : 0 : if (sym != SymbolTable_NulSym)
408 : : {
409 : 0 : M2GCCDeclare_IncludeDumpSymbol (sym);
410 : : }
411 : : }
412 : :
413 : :
414 : : /*
415 : : AddRuleScopeDump -
416 : : */
417 : :
418 : 0 : static void AddRuleScopeDump (DynamicStrings_String rule)
419 : : {
420 : 0 : unsigned int modsym;
421 : 0 : DynamicStrings_String libstr;
422 : 0 : DynamicStrings_String modstr;
423 : 0 : int start;
424 : 0 : int dot;
425 : :
426 : 0 : dot = DynamicStrings_Index (rule, '.', 0);
427 : 0 : Assert (dot != -1);
428 : 0 : libstr = static_cast<DynamicStrings_String> (NULL);
429 : 0 : modstr = DynamicStrings_Slice (rule, 0, dot);
430 : 0 : modsym = M2Batch_Get (NameKey_makekey (DynamicStrings_string (modstr)));
431 : 0 : if (modsym == SymbolTable_NulSym)
432 : : {
433 : : /* avoid dangling else. */
434 : 0 : libstr = modstr;
435 : 0 : start = dot+1;
436 : 0 : dot = DynamicStrings_Index (rule, '.', static_cast<unsigned int> (start));
437 : 0 : if (dot > 0)
438 : : {
439 : 0 : modstr = DynamicStrings_Slice (rule, start, dot);
440 : 0 : modsym = M2Batch_Get (NameKey_makekey (DynamicStrings_string (modstr)));
441 : 0 : if ((modsym != SymbolTable_NulSym) && ((NameKey_makekey (DynamicStrings_string (libstr))) == (SymbolTable_GetLibName (modsym))))
442 : : {
443 : 0 : AddRuleScopeQualidentDump (rule, dot, modsym);
444 : : }
445 : : }
446 : : }
447 : : else
448 : : {
449 : 0 : AddRuleScopeQualidentDump (rule, dot, modsym);
450 : : }
451 : 0 : }
452 : :
453 : :
454 : : /*
455 : : AddRuleFilenameDump -
456 : : */
457 : :
458 : 0 : static void AddRuleFilenameDump (DynamicStrings_String rule)
459 : : {
460 : 0 : }
461 : :
462 : :
463 : : /*
464 : : AddRuleSymToDump -
465 : : */
466 : :
467 : 0 : static void AddRuleSymToDump (DynamicStrings_String rule)
468 : : {
469 : 0 : if ((DynamicStrings_Index (rule, ':', 0)) != -1)
470 : : {
471 : : /* Filename and scope rule. */
472 : : AddRuleFilenameDump (rule);
473 : : }
474 : 0 : else if ((DynamicStrings_Index (rule, '.', 0)) != -1)
475 : : {
476 : : /* avoid dangling else. */
477 : : /* Modula-2 scoping tests. */
478 : 0 : AddRuleScopeDump (rule);
479 : : }
480 : : else
481 : : {
482 : : /* avoid dangling else. */
483 : : /* Text decl tests. */
484 : : AddRuleTextDump (rule);
485 : : }
486 : 0 : }
487 : :
488 : :
489 : : /*
490 : : AddFilterListToDumpWatch -
491 : : */
492 : :
493 : 0 : static void AddFilterListToDumpWatch (void * filter)
494 : : {
495 : 0 : DynamicStrings_String rule;
496 : 0 : DynamicStrings_String full;
497 : 0 : int start;
498 : 0 : int i;
499 : :
500 : 0 : full = DynamicStrings_InitStringCharStar (filter);
501 : 0 : start = 0;
502 : 0 : do {
503 : 0 : i = DynamicStrings_Index (full, ',', static_cast<unsigned int> (start));
504 : 0 : if (i == -1)
505 : : {
506 : 0 : rule = DynamicStrings_Slice (full, start, 0);
507 : : }
508 : : else
509 : : {
510 : 0 : rule = DynamicStrings_Slice (full, start, i);
511 : : }
512 : 0 : AddRuleSymToDump (rule);
513 : 0 : rule = DynamicStrings_KillString (rule);
514 : 0 : start = i+1;
515 : 0 : } while (! (i == -1));
516 : 0 : full = DynamicStrings_KillString (full);
517 : 0 : }
518 : :
519 : :
520 : : /*
521 : : CreateDumpTitle - creates the underlined title.
522 : : */
523 : :
524 : 0 : static void CreateDumpTitle (const char *title_, unsigned int _title_high)
525 : : {
526 : 0 : unsigned int len;
527 : 0 : unsigned int text;
528 : 0 : unsigned int i;
529 : 0 : DynamicStrings_String s;
530 : 0 : char title[_title_high+1];
531 : :
532 : : /* make a local copy of each unbounded array. */
533 : 0 : memcpy (title, title_, _title_high+1);
534 : :
535 : 0 : s = FormatStrings_Sprintf0 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) title, _title_high)));
536 : 0 : s = DynamicStrings_KillString (SFIO_WriteS (M2LangDump_GetDumpFile (), s));
537 : 0 : len = StrLib_StrLen ((const char *) title, _title_high);
538 : 0 : i = 0;
539 : 0 : text = 0;
540 : 0 : while (i < len)
541 : : {
542 : 0 : if (title[i] == '\\')
543 : : {
544 : 0 : i += 2;
545 : : }
546 : : else
547 : : {
548 : 0 : i += 1;
549 : 0 : text += 1;
550 : : }
551 : : }
552 : 0 : s = DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "=", 1)), text);
553 : 0 : s = DynamicStrings_KillString (SFIO_WriteS (M2LangDump_GetDumpFile (), s));
554 : 0 : M2Printf_fprintf0 (M2LangDump_GetDumpFile (), (const char *) "\\n", 2);
555 : 0 : }
556 : :
557 : :
558 : : /*
559 : : Match - return TRUE if sym matches any of the filter rules.
560 : : */
561 : :
562 : 0 : static bool Match (void * filter, unsigned int sym)
563 : : {
564 : 0 : bool result;
565 : 0 : DynamicStrings_String rule;
566 : 0 : DynamicStrings_String full;
567 : 0 : int start;
568 : 0 : int i;
569 : :
570 : 0 : full = DynamicStrings_InitStringCharStar (filter);
571 : 0 : start = 0;
572 : 0 : do {
573 : 0 : i = DynamicStrings_Index (full, ',', static_cast<unsigned int> (start));
574 : 0 : if (i == -1)
575 : : {
576 : 0 : rule = DynamicStrings_Slice (full, start, 0);
577 : : }
578 : : else
579 : : {
580 : 0 : rule = DynamicStrings_Slice (full, start, i);
581 : : }
582 : 0 : result = MatchRule (rule, sym);
583 : 0 : rule = DynamicStrings_KillString (rule);
584 : 0 : if (result)
585 : : {
586 : 0 : full = DynamicStrings_KillString (full);
587 : 0 : return true;
588 : : }
589 : 0 : start = i+1;
590 : 0 : } while (! (i == -1));
591 : 0 : full = DynamicStrings_KillString (full);
592 : 0 : return false;
593 : : /* static analysis guarentees a RETURN statement will be used before here. */
594 : : __builtin_unreachable ();
595 : : }
596 : :
597 : :
598 : : /*
599 : : MatchRule - return TRUE if rule matches sym.
600 : : */
601 : :
602 : 0 : static bool MatchRule (DynamicStrings_String rule, unsigned int sym)
603 : : {
604 : 0 : if ((DynamicStrings_Index (rule, ':', 0)) != -1)
605 : : {
606 : : /* Filename and scope qualification tests. */
607 : 0 : return MatchRuleFilenameScope (rule, sym);
608 : : }
609 : 0 : else if ((DynamicStrings_Index (rule, '.', 0)) != -1)
610 : : {
611 : : /* avoid dangling else. */
612 : : /* Modula-2 scoping tests. */
613 : 0 : return MatchRuleScope (rule, sym);
614 : : }
615 : : else
616 : : {
617 : : /* avoid dangling else. */
618 : : /* Text decl tests. */
619 : 0 : return MatchRuleText (rule, sym);
620 : : }
621 : : /* static analysis guarentees a RETURN statement will be used before here. */
622 : : __builtin_unreachable ();
623 : : }
624 : :
625 : :
626 : : /*
627 : : MatchRuleFilenameScope - returns TRUE if rule contains filename.ext:qualident
628 : : and it matches sym.
629 : : */
630 : :
631 : 0 : static bool MatchRuleFilenameScope (DynamicStrings_String rule, unsigned int sym)
632 : : {
633 : 0 : DynamicStrings_String rulefile;
634 : 0 : DynamicStrings_String symfile;
635 : 0 : DynamicStrings_String subrule;
636 : :
637 : 0 : rulefile = DynamicStrings_Slice (rule, 0, DynamicStrings_Index (rule, ':', 0));
638 : : /* Do not deallocate symfile. */
639 : 0 : symfile = M2LexBuf_FindFileNameFromToken (SymbolTable_GetDeclaredMod (sym), 0);
640 : 0 : if (TextMatch (rulefile, symfile))
641 : : {
642 : 0 : subrule = DynamicStrings_Slice (rule, (DynamicStrings_Index (rule, ':', 0))+1, 0);
643 : 0 : if (MatchRuleScope (subrule, sym))
644 : : {
645 : 0 : subrule = DynamicStrings_KillString (subrule);
646 : 0 : return true;
647 : : }
648 : : }
649 : 0 : rulefile = DynamicStrings_KillString (rulefile);
650 : 0 : return false;
651 : : /* static analysis guarentees a RETURN statement will be used before here. */
652 : : __builtin_unreachable ();
653 : : }
654 : :
655 : :
656 : : /*
657 : : MatchRuleScope - returns TRUE if rule contains a [libname.]qualified.ident
658 : : and it matches sym.
659 : : */
660 : :
661 : 0 : static bool MatchRuleScope (DynamicStrings_String rule, unsigned int sym)
662 : : {
663 : 0 : int i;
664 : 0 : NameKey_Name name;
665 : :
666 : 0 : if (Debugging)
667 : : {
668 : : name = SymbolTable_GetSymName (sym);
669 : : M2Printf_printf2 ((const char *) "MatchRuleScope (%s, %a)\\n", 25, (const unsigned char *) &rule, (sizeof (rule)-1), (const unsigned char *) &name, (sizeof (name)-1));
670 : : }
671 : : /* Compare qualident right to left. */
672 : 0 : i = DynamicStrings_RIndex (rule, '.', 0);
673 : 0 : if (i == -1)
674 : : {
675 : : /* No qualification, just the ident. */
676 : 0 : return MatchRuleIdent (rule, sym);
677 : : }
678 : : else
679 : : {
680 : 0 : return MatchRuleQualident (rule, DynamicStrings_Slice (rule, i+1, 0), i, sym);
681 : : }
682 : : /* static analysis guarentees a RETURN statement will be used before here. */
683 : : __builtin_unreachable ();
684 : : }
685 : :
686 : :
687 : : /*
688 : : MatchRuleQualident - returns TRUE if rule matches qualified sym.
689 : : PostCondition: subrule will be deallocated upon exit.
690 : : TRUE is returned if rule matches qualified sym.
691 : : */
692 : :
693 : 0 : static bool MatchRuleQualident (DynamicStrings_String rule, DynamicStrings_String subrule, int i, unsigned int sym)
694 : : {
695 : 0 : unsigned int scope;
696 : :
697 : 0 : if (TextCompareName (subrule, SymbolTable_GetSymName (sym)))
698 : : {
699 : 0 : if (! (QualifiedScope (rule, sym, &i, &scope)))
700 : : {
701 : : return false;
702 : : }
703 : 0 : if (OptionalLibname (rule, sym, i, scope))
704 : : {
705 : : return true;
706 : : }
707 : : }
708 : 0 : subrule = DynamicStrings_KillString (subrule);
709 : 0 : if (Debugging)
710 : : {
711 : : M2Printf_printf0 ((const char *) "MatchRuleQualident FALSE\\n", 26);
712 : : }
713 : 0 : return false;
714 : : /* static analysis guarentees a RETURN statement will be used before here. */
715 : : __builtin_unreachable ();
716 : : }
717 : :
718 : :
719 : : /*
720 : : QualifiedScope - PostCondition: true is returned is rule matches a qualified sym.
721 : : i is -1 if no more qualifications or libname is found.
722 : : scope will be the set to the last outer scope seen.
723 : : */
724 : :
725 : 0 : static bool QualifiedScope (DynamicStrings_String rule, unsigned int sym, int *i, unsigned int *scope)
726 : : {
727 : 0 : DynamicStrings_String subrule;
728 : 0 : int j;
729 : 0 : NameKey_Name name;
730 : :
731 : 0 : if (Debugging)
732 : : {
733 : : name = SymbolTable_GetSymName (sym);
734 : : M2Printf_printf2 ((const char *) "seen ident name, QualifiedScope (rule = %s, %a)\\n", 49, (const unsigned char *) &rule, (sizeof (rule)-1), (const unsigned char *) &name, (sizeof (name)-1));
735 : : }
736 : 0 : (*scope) = sym;
737 : 0 : subrule = static_cast<DynamicStrings_String> (NULL);
738 : 0 : do {
739 : 0 : j = (*i);
740 : 0 : (*scope) = SymbolTable_GetScope ((*scope));
741 : 0 : (*i) = DynamicStrings_ReverseIndex (rule, '.', j-1);
742 : 0 : if (Debugging)
743 : : {
744 : : M2Printf_printf2 ((const char *) " reverseindex (rule = %s, '.', j = %d)\\n", 40, (const unsigned char *) &rule, (sizeof (rule)-1), (const unsigned char *) &j, (sizeof (j)-1));
745 : : M2Printf_printf1 ((const char *) " returns i = %d\\n", 20, (const unsigned char *) &(*i), (sizeof ((*i))-1));
746 : : }
747 : 0 : if ((*scope) != SymbolTable_NulSym)
748 : : {
749 : 0 : subrule = DynamicStrings_KillString (subrule);
750 : 0 : subrule = DynamicStrings_Slice (rule, (*i)+1, j);
751 : 0 : if (Debugging)
752 : : {
753 : : name = SymbolTable_GetSymName ((*scope));
754 : : M2Printf_printf2 ((const char *) "QualifiedScope (subrule = %s, %a)\\n", 35, (const unsigned char *) &subrule, (sizeof (subrule)-1), (const unsigned char *) &name, (sizeof (name)-1));
755 : : }
756 : 0 : if (! (TextCompareName (subrule, SymbolTable_GetSymName ((*scope)))))
757 : : {
758 : 0 : subrule = DynamicStrings_KillString (subrule);
759 : 0 : if (Debugging)
760 : : {
761 : : M2Printf_printf0 ((const char *) "QualifiedScope FALSE\\n", 22);
762 : : }
763 : 0 : return false;
764 : : }
765 : : }
766 : 0 : } while (! ((((*i) <= 0) || (SymbolTable_IsDefImp ((*scope)))) || (SymbolTable_IsModule ((*scope)))));
767 : 0 : subrule = DynamicStrings_KillString (subrule);
768 : 0 : return true;
769 : : /* static analysis guarentees a RETURN statement will be used before here. */
770 : : __builtin_unreachable ();
771 : : }
772 : :
773 : :
774 : : /*
775 : : OptionalLibname - returns TRUE if rule[0..dot] matches syms libname or
776 : : if there is no libname the scope is a module or defimp
777 : : symbol.
778 : : */
779 : :
780 : 0 : static bool OptionalLibname (DynamicStrings_String rule, unsigned int sym, int dot, unsigned int scope)
781 : : {
782 : 0 : DynamicStrings_String subrule;
783 : :
784 : 0 : if (dot > 0)
785 : : {
786 : : /* Check for optional libname. */
787 : 0 : subrule = DynamicStrings_Slice (rule, 0, dot);
788 : 0 : if (Debugging)
789 : : {
790 : : M2Printf_printf2 ((const char *) "checking for optional libname (subrule = %s, '.', dot = %d)\\n", 61, (const unsigned char *) &rule, (sizeof (rule)-1), (const unsigned char *) &dot, (sizeof (dot)-1));
791 : : }
792 : 0 : if (TextCompareName (subrule, SymbolTable_GetLibName (SymbolTable_GetModuleScope (sym))))
793 : : {
794 : 0 : subrule = DynamicStrings_KillString (subrule);
795 : 0 : if (Debugging)
796 : : {
797 : : M2Printf_printf0 ((const char *) "OptionalLibname TRUE\\n", 22);
798 : : }
799 : 0 : return true;
800 : : }
801 : 0 : subrule = DynamicStrings_KillString (subrule);
802 : : }
803 : 0 : else if ((scope != SymbolTable_NulSym) && ((SymbolTable_IsModule (scope)) || (SymbolTable_IsDefImp (scope))))
804 : : {
805 : : /* avoid dangling else. */
806 : 0 : if (Debugging)
807 : : {
808 : : M2Printf_printf0 ((const char *) "OptionalLibname TRUE\\n", 22);
809 : : }
810 : 0 : return true;
811 : : }
812 : : return false;
813 : : /* static analysis guarentees a RETURN statement will be used before here. */
814 : : __builtin_unreachable ();
815 : : }
816 : :
817 : :
818 : : /*
819 : : MatchRuleIdent - return TRUE if ident sym matches rule.
820 : : The ident must be in a module or defimp scope.
821 : : */
822 : :
823 : 0 : static bool MatchRuleIdent (DynamicStrings_String rule, unsigned int sym)
824 : : {
825 : 0 : unsigned int scope;
826 : :
827 : 0 : if (TextCompareName (rule, SymbolTable_GetSymName (sym)))
828 : : {
829 : 0 : scope = SymbolTable_GetScope (sym);
830 : 0 : return (SymbolTable_IsModule (scope)) || (SymbolTable_IsDefImp (scope));
831 : : }
832 : : return false;
833 : : /* static analysis guarentees a RETURN statement will be used before here. */
834 : : __builtin_unreachable ();
835 : : }
836 : :
837 : :
838 : : /*
839 : : MatchRuleText - returns TRUE if rule matches sym.
840 : : */
841 : :
842 : 0 : static bool MatchRuleText (DynamicStrings_String rule, unsigned int sym)
843 : : {
844 : 0 : return TextCompareName (rule, M2AsmUtil_GetFullScopeAsmName (sym));
845 : : /* static analysis guarentees a RETURN statement will be used before here. */
846 : : __builtin_unreachable ();
847 : : }
848 : :
849 : :
850 : : /*
851 : : TextCompareName - return TRUE if rule matches name.
852 : : */
853 : :
854 : 0 : static bool TextCompareName (DynamicStrings_String rule, NameKey_Name name)
855 : : {
856 : 0 : bool result;
857 : 0 : DynamicStrings_String text;
858 : :
859 : 0 : text = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (name));
860 : 0 : result = TextMatch (rule, text);
861 : 0 : text = DynamicStrings_KillString (text);
862 : 0 : return result;
863 : : /* static analysis guarentees a RETURN statement will be used before here. */
864 : : __builtin_unreachable ();
865 : : }
866 : :
867 : :
868 : : /*
869 : : TextMatch - returns TRUE if rule matches text. Currently this
870 : : is a simple string compare, but could be extended
871 : : to implement regexp (seen in the rule).
872 : : */
873 : :
874 : 0 : static bool TextMatch (DynamicStrings_String rule, DynamicStrings_String text)
875 : : {
876 : 0 : if (Debugging)
877 : : {
878 : : M2Printf_printf2 ((const char *) "TextMatch (%s, %s)\\n", 20, (const unsigned char *) &rule, (sizeof (rule)-1), (const unsigned char *) &text, (sizeof (text)-1));
879 : : }
880 : 0 : return DynamicStrings_Equal (rule, text);
881 : : /* static analysis guarentees a RETURN statement will be used before here. */
882 : : __builtin_unreachable ();
883 : : }
884 : :
885 : :
886 : : /*
887 : : CreateTemplate - create and return a template filename with extension.
888 : : If the user has specified "-" then "-" is returned otherwise
889 : : a template is formed from "dumpdir + filename + .%03dl.extension".
890 : : */
891 : :
892 : 0 : static DynamicStrings_String CreateTemplate (DynamicStrings_String filename, DynamicStrings_String extension)
893 : : {
894 : 0 : if (filename == NULL)
895 : : {
896 : : /* User has not specified a file. */
897 : 0 : if ((M2Options_GetDumpDir ()) == NULL)
898 : : {
899 : 0 : filename = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (SymbolTable_GetMainModule ())));
900 : : }
901 : : else
902 : : {
903 : 0 : filename = DynamicStrings_Dup (M2Options_GetDumpDir ());
904 : 0 : filename = DynamicStrings_ConCat (filename, DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (SymbolTable_GetMainModule ())))));
905 : : }
906 : 0 : filename = DynamicStrings_ConCat (filename, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) ".mod", 4)));
907 : : }
908 : : else
909 : : {
910 : : /* We need to duplicate the filename to create a new string before ConCat
911 : : is used later on. */
912 : 0 : filename = DynamicStrings_Dup (filename);
913 : : }
914 : 0 : if (! (DynamicStrings_EqualArray (filename, (const char *) "-", 1)))
915 : : {
916 : 0 : filename = DynamicStrings_ConCat (DynamicStrings_ConCat (filename, DynamicStrings_InitString ((const char *) ".%03dl.", 7)), extension);
917 : : }
918 : 0 : return filename;
919 : : /* static analysis guarentees a RETURN statement will be used before here. */
920 : : __builtin_unreachable ();
921 : : }
922 : :
923 : :
924 : : /*
925 : : MakeDeclTemplate - return a template for the decl dump file.
926 : : */
927 : :
928 : 0 : static DynamicStrings_String MakeDeclTemplate (void)
929 : : {
930 : 0 : return CreateTemplate (M2Options_GetDumpDeclFilename (), DynamicStrings_InitString ((const char *) "decl", 4));
931 : : /* static analysis guarentees a RETURN statement will be used before here. */
932 : : __builtin_unreachable ();
933 : : }
934 : :
935 : :
936 : : /*
937 : : Init - initialize the module global variables.
938 : : */
939 : :
940 : 16645 : static void Init (void)
941 : : {
942 : 16645 : NoOfQuadDumps = 0;
943 : 16645 : NoOfDeclDumps = 0;
944 : 16645 : declActive = false;
945 : 16645 : quadActive = false;
946 : 16645 : mustClose = false;
947 : 16645 : outputFile = FIO_StdOut;
948 : 0 : }
949 : :
950 : :
951 : : /*
952 : : IsDumpRequiredTree - return TRUE if the gcc tree should be dumped.
953 : : */
954 : :
955 : 0 : extern "C" bool M2LangDump_IsDumpRequiredTree (m2tree_Tree tree, bool default_)
956 : : {
957 : 0 : unsigned int sym;
958 : :
959 : 0 : sym = SymbolConversion_Gcc2Mod (tree);
960 : 0 : if (sym == SymbolTable_NulSym)
961 : : {
962 : : return default_;
963 : : }
964 : : else
965 : : {
966 : 0 : return M2LangDump_IsDumpRequired (sym, default_);
967 : : }
968 : : /* static analysis guarentees a RETURN statement will be used before here. */
969 : : __builtin_unreachable ();
970 : : }
971 : :
972 : :
973 : : /*
974 : : IsDumpRequired - return TRUE if symbol sym should be dumped
975 : : according to the rules of the filter.
976 : : No filter specified will always return default.
977 : : The filter is a comma separated list. Each element
978 : : of the list can specify a symbol three ways.
979 : : Firstly by DECL name for example: m2pim_NumberIO_HexToStr
980 : : Secondly by qualified scope: [pathname.]NumberIO.HexToStr
981 : : Thirdly by filename and scope: NumberIO.mod:HexToStr
982 : : */
983 : :
984 : 0 : extern "C" bool M2LangDump_IsDumpRequired (unsigned int sym, bool default_)
985 : : {
986 : 0 : DynamicStrings_String filter;
987 : :
988 : 0 : filter = static_cast<DynamicStrings_String> (M2Options_GetM2DumpFilter ());
989 : 0 : if (filter == NULL)
990 : : {
991 : : return default_;
992 : : }
993 : : else
994 : : {
995 : 0 : return Match (reinterpret_cast<void *> (filter), sym);
996 : : }
997 : : /* static analysis guarentees a RETURN statement will be used before here. */
998 : : __builtin_unreachable ();
999 : : }
1000 : :
1001 : :
1002 : : /*
1003 : : MakeQuadTemplate - return a template for the quad dump file.
1004 : : */
1005 : :
1006 : 0 : extern "C" DynamicStrings_String M2LangDump_MakeQuadTemplate (void)
1007 : : {
1008 : 0 : return CreateTemplate (M2Options_GetDumpQuadFilename (), DynamicStrings_InitString ((const char *) "quad", 4));
1009 : : /* static analysis guarentees a RETURN statement will be used before here. */
1010 : : __builtin_unreachable ();
1011 : : }
1012 : :
1013 : :
1014 : : /*
1015 : : MakeGimpleTemplate - return a template for the gimple dump file and assign
1016 : : len to the max number of characters required to complete
1017 : : a template (including a nul terminator).
1018 : : */
1019 : :
1020 : 0 : extern "C" DynamicStrings_String M2LangDump_MakeGimpleTemplate (unsigned int *len)
1021 : : {
1022 : 0 : DynamicStrings_String filename;
1023 : :
1024 : 0 : filename = CreateTemplate (M2Options_GetDumpGimpleFilename (), DynamicStrings_InitString ((const char *) "gimple", 6));
1025 : 0 : (*len) = DynamicStrings_Length (filename); /* This is a short cut based on '%03d' format
1026 : : specifier used above. */
1027 : 0 : return filename; /* This is a short cut based on '%03d' format
1028 : : specifier used above. */
1029 : : /* static analysis guarentees a RETURN statement will be used before here. */
1030 : : __builtin_unreachable ();
1031 : : }
1032 : :
1033 : :
1034 : : /*
1035 : : GetDumpFile - return the dump output file.
1036 : : */
1037 : :
1038 : 0 : extern "C" FIO_File M2LangDump_GetDumpFile (void)
1039 : : {
1040 : 0 : return outputFile;
1041 : : /* static analysis guarentees a RETURN statement will be used before here. */
1042 : : __builtin_unreachable ();
1043 : : }
1044 : :
1045 : :
1046 : : /*
1047 : : CreateDumpQuad - create the dump file for a quad dump.
1048 : : */
1049 : :
1050 : 0 : extern "C" void M2LangDump_CreateDumpQuad (const char *title_, unsigned int _title_high)
1051 : : {
1052 : 0 : char title[_title_high+1];
1053 : :
1054 : : /* make a local copy of each unbounded array. */
1055 : 0 : memcpy (title, title_, _title_high+1);
1056 : :
1057 : 0 : Assert (! declActive);
1058 : 0 : Assert (! quadActive);
1059 : 0 : quadActive = true;
1060 : 0 : NoOfQuadDumps += 1;
1061 : 0 : OpenDump (M2LangDump_MakeQuadTemplate (), NoOfQuadDumps);
1062 : 0 : CreateDumpTitle ((const char *) title, _title_high);
1063 : 0 : }
1064 : :
1065 : :
1066 : : /*
1067 : : CloseDumpQuad - close the dump output file.
1068 : : */
1069 : :
1070 : 0 : extern "C" void M2LangDump_CloseDumpQuad (void)
1071 : : {
1072 : 0 : CloseDump ();
1073 : 0 : quadActive = false;
1074 : 0 : }
1075 : :
1076 : :
1077 : : /*
1078 : : CreateDumpDecl - create the dump file for a decl dump.
1079 : : */
1080 : :
1081 : 0 : extern "C" void M2LangDump_CreateDumpDecl (const char *title_, unsigned int _title_high)
1082 : : {
1083 : 0 : char title[_title_high+1];
1084 : :
1085 : : /* make a local copy of each unbounded array. */
1086 : 0 : memcpy (title, title_, _title_high+1);
1087 : :
1088 : 0 : if ((M2Options_GetM2DumpFilter ()) != NULL)
1089 : : {
1090 : 0 : Assert (! declActive);
1091 : 0 : Assert (! quadActive);
1092 : 0 : declActive = true;
1093 : 0 : NoOfDeclDumps += 1;
1094 : 0 : OpenDump (MakeDeclTemplate (), NoOfDeclDumps);
1095 : 0 : CreateDumpTitle ((const char *) title, _title_high);
1096 : 0 : AddFilterListToDumpWatch (M2Options_GetM2DumpFilter ());
1097 : : }
1098 : 0 : }
1099 : :
1100 : :
1101 : : /*
1102 : : CloseDumpDecl - close the dump output file.
1103 : : */
1104 : :
1105 : 0 : extern "C" void M2LangDump_CloseDumpDecl (void)
1106 : : {
1107 : 0 : if (declActive)
1108 : : {
1109 : 0 : CloseDump ();
1110 : 0 : declActive = false;
1111 : : }
1112 : 0 : }
1113 : :
1114 : 16645 : extern "C" void _M2_M2LangDump_init (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
1115 : : {
1116 : 16645 : Init ();
1117 : 16645 : }
1118 : :
1119 : 0 : extern "C" void _M2_M2LangDump_fini (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
1120 : : {
1121 : 0 : }
|