OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [tree-browser.c] - Blame information for rev 20

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 jlechner
/* Tree browser.
2
   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
3
   Contributed by Sebastian Pop <s.pop@laposte.net>
4
 
5
This file is part of GCC.
6
 
7
GCC 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 2, or (at your option) any later
10
version.
11
 
12
GCC 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
18
along with GCC; see the file COPYING.  If not, write to the Free
19
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20
02110-1301, USA.  */
21
 
22
#include "config.h"
23
#include "system.h"
24
#include "coretypes.h"
25
#include "tm.h"
26
#include "tree.h"
27
#include "tree-inline.h"
28
#include "diagnostic.h"
29
#include "hashtab.h"
30
 
31
 
32
#define TB_OUT_FILE stdout
33
#define TB_IN_FILE stdin
34
#define TB_NIY fprintf (TB_OUT_FILE, "Sorry this command is not yet implemented.\n")
35
#define TB_WF fprintf (TB_OUT_FILE, "Warning, this command failed.\n")
36
 
37
 
38
/* Structures for handling Tree Browser's commands.  */
39
#define DEFTBCODE(COMMAND, STRING, HELP)   COMMAND,
40
enum TB_Comm_code {
41
#include "tree-browser.def"
42
  TB_UNUSED_COMMAND
43
};
44
#undef DEFTBCODE
45
typedef enum TB_Comm_code TB_CODE;
46
 
47
struct tb_command {
48
  const char *help_msg;
49
  const char *comm_text;
50
  size_t comm_len;
51
  TB_CODE comm_code;
52
};
53
 
54
#define DEFTBCODE(code, str, help) { help, str, sizeof(str) - 1, code },
55
static const struct tb_command tb_commands[] =
56
{
57
#include "tree-browser.def"
58
};
59
#undef DEFTBCODE
60
 
61
#define TB_COMMAND_LEN(N) (tb_commands[N].comm_len)
62
#define TB_COMMAND_TEXT(N) (tb_commands[N].comm_text)
63
#define TB_COMMAND_CODE(N) (tb_commands[N].comm_code)
64
#define TB_COMMAND_HELP(N) (tb_commands[N].help_msg)
65
 
66
 
67
/* Next structure is for parsing TREE_CODEs.  */
68
struct tb_tree_code {
69
  enum tree_code code;
70
  const char *code_string;
71
  size_t code_string_len;
72
};
73
 
74
#define DEFTREECODE(SYM, STRING, TYPE, NARGS) { SYM, STRING, sizeof (STRING) - 1 },
75
static const struct tb_tree_code tb_tree_codes[] =
76
{
77
#include "tree.def"
78
};
79
#undef DEFTREECODE
80
 
81
#define TB_TREE_CODE(N) (tb_tree_codes[N].code)
82
#define TB_TREE_CODE_TEXT(N) (tb_tree_codes[N].code_string)
83
#define TB_TREE_CODE_LEN(N) (tb_tree_codes[N].code_string_len)
84
 
85
 
86
/* Function declarations.  */
87
 
88
static long TB_getline (char **, long *, FILE *);
89
static TB_CODE TB_get_command (char *);
90
static enum tree_code TB_get_tree_code (char *);
91
static tree find_node_with_code (tree *, int *, void *);
92
static tree store_child_info (tree *, int *, void *);
93
static void TB_update_up (tree);
94
static tree TB_current_chain_node (tree);
95
static tree TB_prev_expr (tree);
96
static tree TB_next_expr (tree);
97
static tree TB_up_expr (tree);
98
static tree TB_first_in_bind (tree);
99
static tree TB_last_in_bind (tree);
100
static int  TB_parent_eq (const void *, const void *);
101
static tree TB_history_prev (void);
102
 
103
/* FIXME: To be declared in a .h file.  */
104
void browse_tree (tree);
105
 
106
/* Static variables.  */
107
static htab_t TB_up_ht;
108
static tree TB_history_stack = NULL_TREE;
109
static int TB_verbose = 1;
110
 
111
 
112
/* Entry point in the Tree Browser.  */
113
 
114
void
115
browse_tree (tree begin)
116
{
117
  tree head;
118
  TB_CODE tbc = TB_UNUSED_COMMAND;
119
  ssize_t rd;
120
  char *input = NULL;
121
  long input_size = 0;
122
 
123
  fprintf (TB_OUT_FILE, "\nTree Browser\n");
124
 
125
#define TB_SET_HEAD(N) do {                                           \
126
  TB_history_stack = tree_cons (NULL_TREE, (N), TB_history_stack);    \
127
  head = N;                                                           \
128
  if (TB_verbose)                                                     \
129
    if (head)                                                         \
130
      {                                                               \
131
        print_generic_expr (TB_OUT_FILE, head, 0);                    \
132
        fprintf (TB_OUT_FILE, "\n");                                  \
133
      }                                                               \
134
} while (0)
135
 
136
  TB_SET_HEAD (begin);
137
 
138
  /* Store in a hashtable information about previous and upper statements.  */
139
  {
140
    TB_up_ht = htab_create (1023, htab_hash_pointer, &TB_parent_eq, NULL);
141
    TB_update_up (head);
142
  }
143
 
144
  while (24)
145
    {
146
      fprintf (TB_OUT_FILE, "TB> ");
147
      rd = TB_getline (&input, &input_size, TB_IN_FILE);
148
 
149
      if (rd == -1)
150
        /* EOF.  */
151
        goto ret;
152
 
153
      if (rd != 1)
154
        /* Get a new command.  Otherwise the user just pressed enter, and thus
155
           she expects the last command to be reexecuted.  */
156
        tbc = TB_get_command (input);
157
 
158
      switch (tbc)
159
        {
160
        case TB_UPDATE_UP:
161
          TB_update_up (head);
162
          break;
163
 
164
        case TB_MAX:
165
          if (head && (INTEGRAL_TYPE_P (head)
166
                       || TREE_CODE (head) == REAL_TYPE))
167
            TB_SET_HEAD (TYPE_MAX_VALUE (head));
168
          else
169
            TB_WF;
170
          break;
171
 
172
        case TB_MIN:
173
          if (head && (INTEGRAL_TYPE_P (head)
174
                       || TREE_CODE (head) == REAL_TYPE))
175
            TB_SET_HEAD (TYPE_MIN_VALUE (head));
176
          else
177
            TB_WF;
178
          break;
179
 
180
        case TB_ELT:
181
          if (head && TREE_CODE (head) == TREE_VEC)
182
            {
183
              /* This command takes another argument: the element number:
184
                 for example "elt 1".  */
185
              TB_NIY;
186
            }
187
          else if (head && TREE_CODE (head) == VECTOR_CST)
188
            {
189
              /* This command takes another argument: the element number:
190
                 for example "elt 1".  */
191
              TB_NIY;
192
            }
193
          else
194
            TB_WF;
195
          break;
196
 
197
        case TB_VALUE:
198
          if (head && TREE_CODE (head) == TREE_LIST)
199
            TB_SET_HEAD (TREE_VALUE (head));
200
          else
201
            TB_WF;
202
          break;
203
 
204
        case TB_PURPOSE:
205
          if (head && TREE_CODE (head) == TREE_LIST)
206
            TB_SET_HEAD (TREE_PURPOSE (head));
207
          else
208
            TB_WF;
209
          break;
210
 
211
        case TB_IMAG:
212
          if (head && TREE_CODE (head) == COMPLEX_CST)
213
            TB_SET_HEAD (TREE_IMAGPART (head));
214
          else
215
            TB_WF;
216
          break;
217
 
218
        case TB_REAL:
219
          if (head && TREE_CODE (head) == COMPLEX_CST)
220
            TB_SET_HEAD (TREE_REALPART (head));
221
          else
222
            TB_WF;
223
          break;
224
 
225
        case TB_BLOCK:
226
          if (head && TREE_CODE (head) == BIND_EXPR)
227
            TB_SET_HEAD (TREE_OPERAND (head, 2));
228
          else
229
            TB_WF;
230
          break;
231
 
232
        case TB_SUBBLOCKS:
233
          if (head && TREE_CODE (head) == BLOCK)
234
            TB_SET_HEAD (BLOCK_SUBBLOCKS (head));
235
          else
236
            TB_WF;
237
          break;
238
 
239
        case TB_SUPERCONTEXT:
240
          if (head && TREE_CODE (head) == BLOCK)
241
            TB_SET_HEAD (BLOCK_SUPERCONTEXT (head));
242
          else
243
            TB_WF;
244
          break;
245
 
246
        case TB_VARS:
247
          if (head && TREE_CODE (head) == BLOCK)
248
            TB_SET_HEAD (BLOCK_VARS (head));
249
          else if (head && TREE_CODE (head) == BIND_EXPR)
250
            TB_SET_HEAD (TREE_OPERAND (head, 0));
251
          else
252
            TB_WF;
253
          break;
254
 
255
        case TB_REFERENCE_TO_THIS:
256
          if (head && TYPE_P (head))
257
            TB_SET_HEAD (TYPE_REFERENCE_TO (head));
258
          else
259
            TB_WF;
260
          break;
261
 
262
        case TB_POINTER_TO_THIS:
263
          if (head && TYPE_P (head))
264
            TB_SET_HEAD (TYPE_POINTER_TO (head));
265
          else
266
            TB_WF;
267
          break;
268
 
269
        case TB_BASETYPE:
270
          if (head && TREE_CODE (head) == OFFSET_TYPE)
271
            TB_SET_HEAD (TYPE_OFFSET_BASETYPE (head));
272
          else
273
            TB_WF;
274
          break;
275
 
276
        case TB_ARG_TYPES:
277
          if (head && (TREE_CODE (head) == FUNCTION_TYPE
278
                       || TREE_CODE (head) == METHOD_TYPE))
279
            TB_SET_HEAD (TYPE_ARG_TYPES (head));
280
          else
281
            TB_WF;
282
          break;
283
 
284
        case TB_METHOD_BASE_TYPE:
285
          if (head && (TREE_CODE (head) == FUNCTION_TYPE
286
                       || TREE_CODE (head) == METHOD_TYPE)
287
              && TYPE_METHOD_BASETYPE (head))
288
            TB_SET_HEAD (TYPE_METHOD_BASETYPE (head));
289
          else
290
            TB_WF;
291
          break;
292
 
293
        case TB_FIELDS:
294
          if (head && (TREE_CODE (head) == RECORD_TYPE
295
                       || TREE_CODE (head) == UNION_TYPE
296
                       || TREE_CODE (head) == QUAL_UNION_TYPE))
297
            TB_SET_HEAD (TYPE_FIELDS (head));
298
          else
299
            TB_WF;
300
          break;
301
 
302
        case TB_DOMAIN:
303
          if (head && TREE_CODE (head) == ARRAY_TYPE)
304
            TB_SET_HEAD (TYPE_DOMAIN (head));
305
          else
306
            TB_WF;
307
          break;
308
 
309
        case TB_VALUES:
310
          if (head && TREE_CODE (head) == ENUMERAL_TYPE)
311
            TB_SET_HEAD (TYPE_VALUES (head));
312
          else
313
            TB_WF;
314
          break;
315
 
316
        case TB_ARG_TYPE:
317
          if (head && TREE_CODE (head) == PARM_DECL)
318
            TB_SET_HEAD (DECL_ARG_TYPE (head));
319
          else
320
            TB_WF;
321
          break;
322
 
323
        case TB_INITIAL:
324
          if (head && DECL_P (head))
325
            TB_SET_HEAD (DECL_INITIAL (head));
326
          else
327
            TB_WF;
328
          break;
329
 
330
        case TB_RESULT:
331
          if (head && DECL_P (head))
332
            TB_SET_HEAD (DECL_RESULT_FLD (head));
333
          else
334
            TB_WF;
335
          break;
336
 
337
        case TB_ARGUMENTS:
338
          if (head && DECL_P (head))
339
            TB_SET_HEAD (DECL_ARGUMENTS (head));
340
          else
341
            TB_WF;
342
          break;
343
 
344
        case TB_ABSTRACT_ORIGIN:
345
          if (head && DECL_P (head))
346
            TB_SET_HEAD (DECL_ABSTRACT_ORIGIN (head));
347
          else if (head && TREE_CODE (head) == BLOCK)
348
            TB_SET_HEAD (BLOCK_ABSTRACT_ORIGIN (head));
349
          else
350
            TB_WF;
351
          break;
352
 
353
        case TB_ATTRIBUTES:
354
          if (head && DECL_P (head))
355
            TB_SET_HEAD (DECL_ATTRIBUTES (head));
356
          else if (head && TYPE_P (head))
357
            TB_SET_HEAD (TYPE_ATTRIBUTES (head));
358
          else
359
            TB_WF;
360
          break;
361
 
362
        case TB_CONTEXT:
363
          if (head && DECL_P (head))
364
            TB_SET_HEAD (DECL_CONTEXT (head));
365
          else if (head && TYPE_P (head)
366
                   && TYPE_CONTEXT (head))
367
            TB_SET_HEAD (TYPE_CONTEXT (head));
368
          else
369
            TB_WF;
370
          break;
371
 
372
        case TB_OFFSET:
373
          if (head && TREE_CODE (head) == FIELD_DECL)
374
            TB_SET_HEAD (DECL_FIELD_OFFSET (head));
375
          else
376
            TB_WF;
377
          break;
378
 
379
        case TB_BIT_OFFSET:
380
          if (head && TREE_CODE (head) == FIELD_DECL)
381
            TB_SET_HEAD (DECL_FIELD_BIT_OFFSET (head));
382
          else
383
            TB_WF;
384
          break;
385
 
386
        case TB_UNIT_SIZE:
387
          if (head && DECL_P (head))
388
            TB_SET_HEAD (DECL_SIZE_UNIT (head));
389
          else if (head && TYPE_P (head))
390
            TB_SET_HEAD (TYPE_SIZE_UNIT (head));
391
          else
392
            TB_WF;
393
          break;
394
 
395
        case TB_SIZE:
396
          if (head && DECL_P (head))
397
            TB_SET_HEAD (DECL_SIZE (head));
398
          else if (head && TYPE_P (head))
399
            TB_SET_HEAD (TYPE_SIZE (head));
400
          else
401
            TB_WF;
402
          break;
403
 
404
        case TB_TYPE:
405
          if (head && TREE_TYPE (head))
406
            TB_SET_HEAD (TREE_TYPE (head));
407
          else
408
            TB_WF;
409
          break;
410
 
411
        case TB_DECL_SAVED_TREE:
412
          if (head && TREE_CODE (head) == FUNCTION_DECL
413
              && DECL_SAVED_TREE (head))
414
            TB_SET_HEAD (DECL_SAVED_TREE (head));
415
          else
416
            TB_WF;
417
          break;
418
 
419
        case TB_BODY:
420
          if (head && TREE_CODE (head) == BIND_EXPR)
421
            TB_SET_HEAD (TREE_OPERAND (head, 1));
422
          else
423
            TB_WF;
424
          break;
425
 
426
        case TB_CHILD_0:
427
          if (head && EXPR_P (head) && TREE_OPERAND (head, 0))
428
            TB_SET_HEAD (TREE_OPERAND (head, 0));
429
          else
430
            TB_WF;
431
          break;
432
 
433
        case TB_CHILD_1:
434
          if (head && EXPR_P (head) && TREE_OPERAND (head, 1))
435
            TB_SET_HEAD (TREE_OPERAND (head, 1));
436
          else
437
            TB_WF;
438
          break;
439
 
440
        case TB_CHILD_2:
441
          if (head && EXPR_P (head) && TREE_OPERAND (head, 2))
442
            TB_SET_HEAD (TREE_OPERAND (head, 2));
443
          else
444
            TB_WF;
445
          break;
446
 
447
        case TB_CHILD_3:
448
          if (head && EXPR_P (head) && TREE_OPERAND (head, 3))
449
            TB_SET_HEAD (TREE_OPERAND (head, 3));
450
          else
451
            TB_WF;
452
          break;
453
 
454
        case TB_PRINT:
455
          if (head)
456
            debug_tree (head);
457
          else
458
            TB_WF;
459
          break;
460
 
461
        case TB_PRETTY_PRINT:
462
          if (head)
463
            {
464
              print_generic_stmt (TB_OUT_FILE, head, 0);
465
              fprintf (TB_OUT_FILE, "\n");
466
            }
467
          else
468
            TB_WF;
469
          break;
470
 
471
        case TB_SEARCH_NAME:
472
 
473
          break;
474
 
475
        case TB_SEARCH_CODE:
476
          {
477
            enum tree_code code;
478
            char *arg_text;
479
 
480
            arg_text = strchr (input, ' ');
481
            if (arg_text == NULL)
482
              {
483
                fprintf (TB_OUT_FILE, "First argument is missing.  This isn't a valid search command.  \n");
484
                break;
485
              }
486
            code = TB_get_tree_code (arg_text + 1);
487
 
488
            /* Search in the subtree a node with the given code.  */
489
            {
490
              tree res;
491
 
492
              res = walk_tree (&head, find_node_with_code, &code, NULL);
493
              if (res == NULL_TREE)
494
                {
495
                  fprintf (TB_OUT_FILE, "There's no node with this code (reachable via the walk_tree function from this node).\n");
496
                }
497
              else
498
                {
499
                  fprintf (TB_OUT_FILE, "Achoo!  I got this node in the tree.\n");
500
                  TB_SET_HEAD (res);
501
                }
502
            }
503
            break;
504
          }
505
 
506
#define TB_MOVE_HEAD(FCT) do {       \
507
  if (head)                          \
508
    {                                \
509
      tree t;                        \
510
      t = FCT (head);                \
511
      if (t)                         \
512
        TB_SET_HEAD (t);             \
513
      else                           \
514
        TB_WF;                       \
515
    }                                \
516
  else                               \
517
    TB_WF;                           \
518
} while (0)
519
 
520
        case TB_FIRST:
521
          TB_MOVE_HEAD (TB_first_in_bind);
522
          break;
523
 
524
        case TB_LAST:
525
          TB_MOVE_HEAD (TB_last_in_bind);
526
          break;
527
 
528
        case TB_UP:
529
          TB_MOVE_HEAD (TB_up_expr);
530
          break;
531
 
532
        case TB_PREV:
533
          TB_MOVE_HEAD (TB_prev_expr);
534
          break;
535
 
536
        case TB_NEXT:
537
          TB_MOVE_HEAD (TB_next_expr);
538
          break;
539
 
540
        case TB_HPREV:
541
          /* This command is a little bit special, since it deals with history
542
             stack.  For this reason it should keep the "head = ..." statement
543
             and not use TB_MOVE_HEAD.  */
544
          if (head)
545
            {
546
              tree t;
547
              t = TB_history_prev ();
548
              if (t)
549
                {
550
                  head = t;
551
                  if (TB_verbose)
552
                    {
553
                      print_generic_expr (TB_OUT_FILE, head, 0);
554
                      fprintf (TB_OUT_FILE, "\n");
555
                    }
556
                }
557
              else
558
                TB_WF;
559
            }
560
          else
561
            TB_WF;
562
          break;
563
 
564
        case TB_CHAIN:
565
          /* Don't go further if it's the last node in this chain.  */
566
          if (head && TREE_CODE (head) == BLOCK)
567
            TB_SET_HEAD (BLOCK_CHAIN (head));
568
          else if (head && TREE_CHAIN (head))
569
            TB_SET_HEAD (TREE_CHAIN (head));
570
          else
571
            TB_WF;
572
          break;
573
 
574
        case TB_FUN:
575
          /* Go up to the current function declaration.  */
576
          TB_SET_HEAD (current_function_decl);
577
          fprintf (TB_OUT_FILE, "Current function declaration.\n");
578
          break;
579
 
580
        case TB_HELP:
581
          /* Display a help message.  */
582
          {
583
            int i;
584
            fprintf (TB_OUT_FILE, "Possible commands are:\n\n");
585
            for (i = 0; i < TB_UNUSED_COMMAND; i++)
586
              {
587
                fprintf (TB_OUT_FILE, "%20s  -  %s\n", TB_COMMAND_TEXT (i), TB_COMMAND_HELP (i));
588
              }
589
          }
590
          break;
591
 
592
        case TB_VERBOSE:
593
          if (TB_verbose == 0)
594
            {
595
              TB_verbose = 1;
596
              fprintf (TB_OUT_FILE, "Verbose on.\n");
597
            }
598
          else
599
            {
600
              TB_verbose = 0;
601
              fprintf (TB_OUT_FILE, "Verbose off.\n");
602
            }
603
          break;
604
 
605
        case TB_EXIT:
606
        case TB_QUIT:
607
          /* Just exit from this function.  */
608
          goto ret;
609
 
610
        default:
611
          TB_NIY;
612
        }
613
    }
614
 
615
 ret:;
616
  htab_delete (TB_up_ht);
617
  return;
618
}
619
 
620
 
621
/* Search the first node in this BIND_EXPR.  */
622
 
623
static tree
624
TB_first_in_bind (tree node)
625
{
626
  tree t;
627
 
628
  if (node == NULL_TREE)
629
    return NULL_TREE;
630
 
631
  while ((t = TB_prev_expr (node)))
632
    node = t;
633
 
634
  return node;
635
}
636
 
637
/* Search the last node in this BIND_EXPR.  */
638
 
639
static tree
640
TB_last_in_bind (tree node)
641
{
642
  tree t;
643
 
644
  if (node == NULL_TREE)
645
    return NULL_TREE;
646
 
647
  while ((t = TB_next_expr (node)))
648
    node = t;
649
 
650
  return node;
651
}
652
 
653
/* Search the parent expression for this node.  */
654
 
655
static tree
656
TB_up_expr (tree node)
657
{
658
  tree res;
659
  if (node == NULL_TREE)
660
    return NULL_TREE;
661
 
662
  res = (tree) htab_find (TB_up_ht, node);
663
  return res;
664
}
665
 
666
/* Search the previous expression in this BIND_EXPR.  */
667
 
668
static tree
669
TB_prev_expr (tree node)
670
{
671
  node = TB_current_chain_node (node);
672
 
673
  if (node == NULL_TREE)
674
    return NULL_TREE;
675
 
676
  node = TB_up_expr (node);
677
  if (node && TREE_CODE (node) == COMPOUND_EXPR)
678
    return node;
679
  else
680
    return NULL_TREE;
681
}
682
 
683
/* Search the next expression in this BIND_EXPR.  */
684
 
685
static tree
686
TB_next_expr (tree node)
687
{
688
  node = TB_current_chain_node (node);
689
 
690
  if (node == NULL_TREE)
691
    return NULL_TREE;
692
 
693
  node = TREE_OPERAND (node, 1);
694
  return node;
695
}
696
 
697
static tree
698
TB_current_chain_node (tree node)
699
{
700
  if (node == NULL_TREE)
701
    return NULL_TREE;
702
 
703
  if (TREE_CODE (node) == COMPOUND_EXPR)
704
    return node;
705
 
706
  node = TB_up_expr (node);
707
  if (node)
708
    {
709
      if (TREE_CODE (node) == COMPOUND_EXPR)
710
        return node;
711
 
712
      node = TB_up_expr (node);
713
      if (TREE_CODE (node) == COMPOUND_EXPR)
714
        return node;
715
    }
716
 
717
  return NULL_TREE;
718
}
719
 
720
/* For each node store in its children nodes that the current node is their
721
   parent.  This function is used by walk_tree.  */
722
 
723
static tree
724
store_child_info (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
725
                  void *data ATTRIBUTE_UNUSED)
726
{
727
  tree node;
728
  void **slot;
729
 
730
  node = *tp;
731
 
732
  /* 'node' is the parent of 'TREE_OPERAND (node, *)'.  */
733
  if (EXPRESSION_CLASS_P (node))
734
    {
735
 
736
#define STORE_CHILD(N) do {                                                \
737
  tree op = TREE_OPERAND (node, N);                                        \
738
  slot = htab_find_slot (TB_up_ht, op, INSERT);                               \
739
  *slot = (void *) node;                                                   \
740
} while (0)
741
 
742
      switch (TREE_CODE_LENGTH (TREE_CODE (node)))
743
        {
744
        case 4:
745
          STORE_CHILD (0);
746
          STORE_CHILD (1);
747
          STORE_CHILD (2);
748
          STORE_CHILD (3);
749
          break;
750
 
751
        case 3:
752
          STORE_CHILD (0);
753
          STORE_CHILD (1);
754
          STORE_CHILD (2);
755
          break;
756
 
757
        case 2:
758
          STORE_CHILD (0);
759
          STORE_CHILD (1);
760
          break;
761
 
762
        case 1:
763
          STORE_CHILD (0);
764
          break;
765
 
766
        case 0:
767
        default:
768
          /* No children: nothing to do.  */
769
          break;
770
        }
771
#undef STORE_CHILD
772
    }
773
 
774
  /* Never stop walk_tree.  */
775
  return NULL_TREE;
776
}
777
 
778
/* Function used in TB_up_ht.  */
779
 
780
static int
781
TB_parent_eq (const void *p1, const void *p2)
782
{
783
  tree node, parent;
784
  node = (tree) p2;
785
  parent = (tree) p1;
786
 
787
  if (p1 == NULL || p2 == NULL)
788
    return 0;
789
 
790
  if (EXPRESSION_CLASS_P (parent))
791
    {
792
 
793
#define TEST_CHILD(N) do {               \
794
  if (node == TREE_OPERAND (parent, N))  \
795
    return 1;                            \
796
} while (0)
797
 
798
    switch (TREE_CODE_LENGTH (TREE_CODE (parent)))
799
      {
800
      case 4:
801
        TEST_CHILD (0);
802
        TEST_CHILD (1);
803
        TEST_CHILD (2);
804
        TEST_CHILD (3);
805
        break;
806
 
807
      case 3:
808
        TEST_CHILD (0);
809
        TEST_CHILD (1);
810
        TEST_CHILD (2);
811
        break;
812
 
813
      case 2:
814
        TEST_CHILD (0);
815
        TEST_CHILD (1);
816
        break;
817
 
818
      case 1:
819
        TEST_CHILD (0);
820
        break;
821
 
822
      case 0:
823
      default:
824
        /* No children: nothing to do.  */
825
        break;
826
      }
827
#undef TEST_CHILD
828
    }
829
 
830
  return 0;
831
}
832
 
833
/* Update information about upper expressions in the hash table.  */
834
 
835
static void
836
TB_update_up (tree node)
837
{
838
  while (node)
839
    {
840
      walk_tree (&node, store_child_info, NULL, NULL);
841
 
842
      /* Walk function's body.  */
843
      if (TREE_CODE (node) == FUNCTION_DECL)
844
        if (DECL_SAVED_TREE (node))
845
          walk_tree (&DECL_SAVED_TREE (node), store_child_info, NULL, NULL);
846
 
847
      /* Walk rest of the chain.  */
848
      node = TREE_CHAIN (node);
849
    }
850
  fprintf (TB_OUT_FILE, "Up/prev expressions updated.\n");
851
}
852
 
853
/* Parse the input string for determining the command the user asked for.  */
854
 
855
static TB_CODE
856
TB_get_command (char *input)
857
{
858
  unsigned int mn, size_tok;
859
  int comp;
860
  char *space;
861
 
862
  space = strchr (input, ' ');
863
  if (space != NULL)
864
    size_tok = strlen (input) - strlen (space);
865
  else
866
    size_tok = strlen (input) - 1;
867
 
868
  for (mn = 0; mn < TB_UNUSED_COMMAND; mn++)
869
    {
870
      if (size_tok != TB_COMMAND_LEN (mn))
871
        continue;
872
 
873
      comp = memcmp (input, TB_COMMAND_TEXT (mn), TB_COMMAND_LEN (mn));
874
      if (comp == 0)
875
        /* Here we just determined the command.  If this command takes
876
           an argument, then the argument is determined later.  */
877
        return TB_COMMAND_CODE (mn);
878
    }
879
 
880
  /* Not a valid command.  */
881
  return TB_UNUSED_COMMAND;
882
}
883
 
884
/* Parse the input string for determining the tree code.  */
885
 
886
static enum tree_code
887
TB_get_tree_code (char *input)
888
{
889
  unsigned int mn, size_tok;
890
  int comp;
891
  char *space;
892
 
893
  space = strchr (input, ' ');
894
  if (space != NULL)
895
    size_tok = strlen (input) - strlen (space);
896
  else
897
    size_tok = strlen (input) - 1;
898
 
899
  for (mn = 0; mn < LAST_AND_UNUSED_TREE_CODE; mn++)
900
    {
901
      if (size_tok != TB_TREE_CODE_LEN (mn))
902
        continue;
903
 
904
      comp = memcmp (input, TB_TREE_CODE_TEXT (mn), TB_TREE_CODE_LEN (mn));
905
      if (comp == 0)
906
        {
907
          fprintf (TB_OUT_FILE, "%s\n", TB_TREE_CODE_TEXT (mn));
908
          return TB_TREE_CODE (mn);
909
        }
910
    }
911
 
912
  /* This isn't a valid code.  */
913
  return LAST_AND_UNUSED_TREE_CODE;
914
}
915
 
916
/* Find a node with a given code.  This function is used as an argument to
917
   walk_tree.  */
918
 
919
static tree
920
find_node_with_code (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
921
                     void *data)
922
{
923
  enum tree_code *code;
924
  code = (enum tree_code *) data;
925
  if (*code == TREE_CODE (*tp))
926
    return *tp;
927
 
928
  return NULL_TREE;
929
}
930
 
931
/* Returns a pointer to the last visited node.  */
932
 
933
static tree
934
TB_history_prev (void)
935
{
936
  if (TB_history_stack)
937
    {
938
      TB_history_stack = TREE_CHAIN (TB_history_stack);
939
      if (TB_history_stack)
940
        return TREE_VALUE (TB_history_stack);
941
    }
942
  return NULL_TREE;
943
}
944
 
945
/* Read up to (and including) a '\n' from STREAM into *LINEPTR
946
   (and null-terminate it). *LINEPTR is a pointer returned from malloc
947
   (or NULL), pointing to *N characters of space.  It is realloc'd as
948
   necessary.  Returns the number of characters read (not including the
949
   null terminator), or -1 on error or EOF.
950
   This function comes from sed (and is supposed to be a portable version
951
   of getline).  */
952
 
953
static long
954
TB_getline (char **lineptr, long *n, FILE *stream)
955
{
956
  char *line, *p;
957
  long size, copy;
958
 
959
  if (lineptr == NULL || n == NULL)
960
    {
961
      errno = EINVAL;
962
      return -1;
963
    }
964
 
965
  if (ferror (stream))
966
    return -1;
967
 
968
  /* Make sure we have a line buffer to start with.  */
969
  if (*lineptr == NULL || *n < 2) /* !seen and no buf yet need 2 chars.  */
970
    {
971
#ifndef MAX_CANON
972
#define MAX_CANON       256
973
#endif
974
      line = (char *) xrealloc (*lineptr, MAX_CANON);
975
      if (line == NULL)
976
        return -1;
977
      *lineptr = line;
978
      *n = MAX_CANON;
979
    }
980
 
981
  line = *lineptr;
982
  size = *n;
983
 
984
  copy = size;
985
  p = line;
986
 
987
  while (1)
988
    {
989
      long len;
990
 
991
      while (--copy > 0)
992
        {
993
          register int c = getc (stream);
994
          if (c == EOF)
995
            goto lose;
996
          else if ((*p++ = c) == '\n')
997
            goto win;
998
        }
999
 
1000
      /* Need to enlarge the line buffer.  */
1001
      len = p - line;
1002
      size *= 2;
1003
      line = (char *) xrealloc (line, size);
1004
      if (line == NULL)
1005
        goto lose;
1006
      *lineptr = line;
1007
      *n = size;
1008
      p = line + len;
1009
      copy = size - len;
1010
    }
1011
 
1012
 lose:
1013
  if (p == *lineptr)
1014
    return -1;
1015
 
1016
  /* Return a partial line since we got an error in the middle.  */
1017
 win:
1018
#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) || defined(MSDOS)
1019
  if (p - 2 >= *lineptr && p[-2] == '\r')
1020
    p[-2] = p[-1], --p;
1021
#endif
1022
  *p = '\0';
1023
  return p - *lineptr;
1024
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.