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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [tree-browser.c] - Blame information for rev 688

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

Line No. Rev Author Line
1 684 jeremybenn
/* Tree browser.
2
   Copyright (C) 2002, 2003, 2004, 2007, 2008, 2010
3
   Free Software Foundation, Inc.
4
   Contributed by Sebastian Pop <s.pop@laposte.net>
5
 
6
This file is part of GCC.
7
 
8
GCC is free software; you can redistribute it and/or modify it under
9
the terms of the GNU General Public License as published by the Free
10
Software Foundation; either version 3, or (at your option) any later
11
version.
12
 
13
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14
WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16
for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with GCC; see the file COPYING3.  If not see
20
<http://www.gnu.org/licenses/>.  */
21
 
22
#include "config.h"
23
#include "system.h"
24
#include "coretypes.h"
25
#include "tree.h"
26
#include "tree-pretty-print.h"
27
 
28
#define TB_OUT_FILE stdout
29
#define TB_IN_FILE stdin
30
#define TB_NIY fprintf (TB_OUT_FILE, "Sorry this command is not yet implemented.\n")
31
#define TB_WF fprintf (TB_OUT_FILE, "Warning, this command failed.\n")
32
 
33
/* Structures for handling Tree Browser's commands.  */
34
#define DEFTBCODE(COMMAND, STRING, HELP)   COMMAND,
35
enum TB_Comm_code {
36
#include "tree-browser.def"
37
  TB_UNUSED_COMMAND
38
};
39
#undef DEFTBCODE
40
typedef enum TB_Comm_code TB_CODE;
41
 
42
struct tb_command {
43
  const char *help_msg;
44
  const char *comm_text;
45
  size_t comm_len;
46
  TB_CODE comm_code;
47
};
48
 
49
#define DEFTBCODE(code, str, help) { help, str, sizeof(str) - 1, code },
50
static const struct tb_command tb_commands[] =
51
{
52
#include "tree-browser.def"
53
};
54
#undef DEFTBCODE
55
 
56
#define TB_COMMAND_LEN(N) (tb_commands[N].comm_len)
57
#define TB_COMMAND_TEXT(N) (tb_commands[N].comm_text)
58
#define TB_COMMAND_CODE(N) (tb_commands[N].comm_code)
59
#define TB_COMMAND_HELP(N) (tb_commands[N].help_msg)
60
 
61
 
62
/* Next structure is for parsing TREE_CODEs.  */
63
struct tb_tree_code {
64
  enum tree_code code;
65
  const char *code_string;
66
  size_t code_string_len;
67
};
68
 
69
#define DEFTREECODE(SYM, STRING, TYPE, NARGS) { SYM, STRING, sizeof (STRING) - 1 },
70
#define END_OF_BASE_TREE_CODES \
71
  { LAST_AND_UNUSED_TREE_CODE, "@dummy", sizeof ("@dummy") - 1 },
72
static const struct tb_tree_code tb_tree_codes[] =
73
{
74
#include "all-tree.def"
75
};
76
#undef DEFTREECODE
77
#undef END_OF_BASE_TREE_CODES
78
 
79
#define TB_TREE_CODE(N) (tb_tree_codes[N].code)
80
#define TB_TREE_CODE_TEXT(N) (tb_tree_codes[N].code_string)
81
#define TB_TREE_CODE_LEN(N) (tb_tree_codes[N].code_string_len)
82
 
83
 
84
/* Function declarations.  */
85
 
86
static long TB_getline (char **, long *, FILE *);
87
static TB_CODE TB_get_command (char *);
88
static enum tree_code TB_get_tree_code (char *);
89
static tree find_node_with_code (tree *, int *, void *);
90
static tree store_child_info (tree *, int *, void *);
91
static void TB_update_up (tree);
92
static tree TB_current_chain_node (tree);
93
static tree TB_prev_expr (tree);
94
static tree TB_next_expr (tree);
95
static tree TB_up_expr (tree);
96
static tree TB_first_in_bind (tree);
97
static tree TB_last_in_bind (tree);
98
static int  TB_parent_eq (const void *, const void *);
99
static tree TB_history_prev (void);
100
 
101
/* FIXME: To be declared in a .h file.  */
102
void browse_tree (tree);
103
 
104
/* Static variables.  */
105
static htab_t TB_up_ht;
106
static VEC(tree,gc) *TB_history_stack;
107
static int TB_verbose = 1;
108
 
109
 
110
/* Entry point in the Tree Browser.  */
111
 
112
void
113
browse_tree (tree begin)
114
{
115
  tree head;
116
  TB_CODE tbc = TB_UNUSED_COMMAND;
117
  ssize_t rd;
118
  char *input = NULL;
119
  long input_size = 0;
120
 
121
  fprintf (TB_OUT_FILE, "\nTree Browser\n");
122
 
123
#define TB_SET_HEAD(N) do {                                           \
124
  VEC_safe_push (tree, gc, TB_history_stack, N);                      \
125
  head = N;                                                           \
126
  if (TB_verbose)                                                     \
127
    if (head)                                                         \
128
      {                                                               \
129
        print_generic_expr (TB_OUT_FILE, head, 0);                    \
130
        fprintf (TB_OUT_FILE, "\n");                                  \
131
      }                                                               \
132
} while (0)
133
 
134
  TB_SET_HEAD (begin);
135
 
136
  /* Store in a hashtable information about previous and upper statements.  */
137
  {
138
    TB_up_ht = htab_create (1023, htab_hash_pointer, &TB_parent_eq, NULL);
139
    TB_update_up (head);
140
  }
141
 
142
  while (24)
143
    {
144
      fprintf (TB_OUT_FILE, "TB> ");
145
      rd = TB_getline (&input, &input_size, TB_IN_FILE);
146
 
147
      if (rd == -1)
148
        /* EOF.  */
149
        goto ret;
150
 
151
      if (rd != 1)
152
        /* Get a new command.  Otherwise the user just pressed enter, and thus
153
           she expects the last command to be reexecuted.  */
154
        tbc = TB_get_command (input);
155
 
156
      switch (tbc)
157
        {
158
        case TB_UPDATE_UP:
159
          TB_update_up (head);
160
          break;
161
 
162
        case TB_MAX:
163
          if (head && (INTEGRAL_TYPE_P (head)
164
                       || TREE_CODE (head) == REAL_TYPE
165
                       || TREE_CODE (head) == FIXED_POINT_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
                       || TREE_CODE (head) == FIXED_POINT_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 (EXPR_P (node))
734
    {
735
      int n = TREE_OPERAND_LENGTH (node);
736
      int i;
737
      for (i = 0; i < n; i++)
738
        {
739
          tree op = TREE_OPERAND (node, i);
740
          slot = htab_find_slot (TB_up_ht, op, INSERT);
741
          *slot = (void *) node;
742
        }
743
    }
744
 
745
  /* Never stop walk_tree.  */
746
  return NULL_TREE;
747
}
748
 
749
/* Function used in TB_up_ht.  */
750
 
751
static int
752
TB_parent_eq (const void *p1, const void *p2)
753
{
754
  const_tree const node = (const_tree)p2;
755
  const_tree const parent = (const_tree) p1;
756
 
757
  if (p1 == NULL || p2 == NULL)
758
    return 0;
759
 
760
  if (EXPR_P (parent))
761
    {
762
      int n = TREE_OPERAND_LENGTH (parent);
763
      int i;
764
      for (i = 0; i < n; i++)
765
        if (node == TREE_OPERAND (parent, i))
766
          return 1;
767
    }
768
  return 0;
769
}
770
 
771
/* Update information about upper expressions in the hash table.  */
772
 
773
static void
774
TB_update_up (tree node)
775
{
776
  while (node)
777
    {
778
      walk_tree (&node, store_child_info, NULL, NULL);
779
 
780
      /* Walk function's body.  */
781
      if (TREE_CODE (node) == FUNCTION_DECL)
782
        if (DECL_SAVED_TREE (node))
783
          walk_tree (&DECL_SAVED_TREE (node), store_child_info, NULL, NULL);
784
 
785
      /* Walk rest of the chain.  */
786
      node = TREE_CHAIN (node);
787
    }
788
  fprintf (TB_OUT_FILE, "Up/prev expressions updated.\n");
789
}
790
 
791
/* Parse the input string for determining the command the user asked for.  */
792
 
793
static TB_CODE
794
TB_get_command (char *input)
795
{
796
  unsigned int mn, size_tok;
797
  int comp;
798
  char *space;
799
 
800
  space = strchr (input, ' ');
801
  if (space != NULL)
802
    size_tok = strlen (input) - strlen (space);
803
  else
804
    size_tok = strlen (input) - 1;
805
 
806
  for (mn = 0; mn < TB_UNUSED_COMMAND; mn++)
807
    {
808
      if (size_tok != TB_COMMAND_LEN (mn))
809
        continue;
810
 
811
      comp = memcmp (input, TB_COMMAND_TEXT (mn), TB_COMMAND_LEN (mn));
812
      if (comp == 0)
813
        /* Here we just determined the command.  If this command takes
814
           an argument, then the argument is determined later.  */
815
        return TB_COMMAND_CODE (mn);
816
    }
817
 
818
  /* Not a valid command.  */
819
  return TB_UNUSED_COMMAND;
820
}
821
 
822
/* Parse the input string for determining the tree code.  */
823
 
824
static enum tree_code
825
TB_get_tree_code (char *input)
826
{
827
  unsigned int mn, size_tok;
828
  int comp;
829
  char *space;
830
 
831
  space = strchr (input, ' ');
832
  if (space != NULL)
833
    size_tok = strlen (input) - strlen (space);
834
  else
835
    size_tok = strlen (input) - 1;
836
 
837
  for (mn = 0; mn < LAST_AND_UNUSED_TREE_CODE; mn++)
838
    {
839
      if (size_tok != TB_TREE_CODE_LEN (mn))
840
        continue;
841
 
842
      comp = memcmp (input, TB_TREE_CODE_TEXT (mn), TB_TREE_CODE_LEN (mn));
843
      if (comp == 0)
844
        {
845
          fprintf (TB_OUT_FILE, "%s\n", TB_TREE_CODE_TEXT (mn));
846
          return TB_TREE_CODE (mn);
847
        }
848
    }
849
 
850
  /* This isn't a valid code.  */
851
  return LAST_AND_UNUSED_TREE_CODE;
852
}
853
 
854
/* Find a node with a given code.  This function is used as an argument to
855
   walk_tree.  */
856
 
857
static tree
858
find_node_with_code (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
859
                     void *data)
860
{
861
  enum tree_code *code;
862
  code = (enum tree_code *) data;
863
  if (*code == TREE_CODE (*tp))
864
    return *tp;
865
 
866
  return NULL_TREE;
867
}
868
 
869
/* Returns a pointer to the last visited node.  */
870
 
871
static tree
872
TB_history_prev (void)
873
{
874
  if (!VEC_empty (tree, TB_history_stack))
875
    {
876
      tree last = VEC_last (tree, TB_history_stack);
877
      VEC_pop (tree, TB_history_stack);
878
      return last;
879
    }
880
  return NULL_TREE;
881
}
882
 
883
/* Read up to (and including) a '\n' from STREAM into *LINEPTR
884
   (and null-terminate it). *LINEPTR is a pointer returned from malloc
885
   (or NULL), pointing to *N characters of space.  It is realloc'd as
886
   necessary.  Returns the number of characters read (not including the
887
   null terminator), or -1 on error or EOF.
888
   This function comes from sed (and is supposed to be a portable version
889
   of getline).  */
890
 
891
static long
892
TB_getline (char **lineptr, long *n, FILE *stream)
893
{
894
  char *line, *p;
895
  long size, copy;
896
 
897
  if (lineptr == NULL || n == NULL)
898
    {
899
      errno = EINVAL;
900
      return -1;
901
    }
902
 
903
  if (ferror (stream))
904
    return -1;
905
 
906
  /* Make sure we have a line buffer to start with.  */
907
  if (*lineptr == NULL || *n < 2) /* !seen and no buf yet need 2 chars.  */
908
    {
909
#ifndef MAX_CANON
910
#define MAX_CANON       256
911
#endif
912
      line = (char *) xrealloc (*lineptr, MAX_CANON);
913
      if (line == NULL)
914
        return -1;
915
      *lineptr = line;
916
      *n = MAX_CANON;
917
    }
918
 
919
  line = *lineptr;
920
  size = *n;
921
 
922
  copy = size;
923
  p = line;
924
 
925
  while (1)
926
    {
927
      long len;
928
 
929
      while (--copy > 0)
930
        {
931
          register int c = getc (stream);
932
          if (c == EOF)
933
            goto lose;
934
          else if ((*p++ = c) == '\n')
935
            goto win;
936
        }
937
 
938
      /* Need to enlarge the line buffer.  */
939
      len = p - line;
940
      size *= 2;
941
      line = (char *) xrealloc (line, size);
942
      if (line == NULL)
943
        goto lose;
944
      *lineptr = line;
945
      *n = size;
946
      p = line + len;
947
      copy = size - len;
948
    }
949
 
950
 lose:
951
  if (p == *lineptr)
952
    return -1;
953
 
954
  /* Return a partial line since we got an error in the middle.  */
955
 win:
956
#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) || defined(MSDOS)
957
  if (p - 2 >= *lineptr && p[-2] == '\r')
958
    p[-2] = p[-1], --p;
959
#endif
960
  *p = '\0';
961
  return p - *lineptr;
962
}

powered by: WebSVN 2.1.0

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