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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [tree-browser.c] - Blame information for rev 826

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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