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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [tree-browser.c] - Blame information for rev 816

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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