111
|
1 /* This plugin recursively dumps the source-code location ranges of
|
|
2 expressions, at the pre-gimplification tree stage. */
|
|
3 /* { dg-options "-O" } */
|
|
4
|
|
5 #include "gcc-plugin.h"
|
|
6 #include "config.h"
|
|
7 #include "system.h"
|
|
8 #include "coretypes.h"
|
|
9 #include "tm.h"
|
|
10 #include "tree.h"
|
|
11 #include "stringpool.h"
|
|
12 #include "toplev.h"
|
|
13 #include "basic-block.h"
|
|
14 #include "hash-table.h"
|
|
15 #include "vec.h"
|
|
16 #include "ggc.h"
|
|
17 #include "basic-block.h"
|
|
18 #include "tree-ssa-alias.h"
|
|
19 #include "internal-fn.h"
|
|
20 #include "gimple-fold.h"
|
|
21 #include "tree-eh.h"
|
|
22 #include "gimple-expr.h"
|
|
23 #include "is-a.h"
|
|
24 #include "gimple.h"
|
|
25 #include "gimple-iterator.h"
|
|
26 #include "tree.h"
|
|
27 #include "tree-pass.h"
|
|
28 #include "intl.h"
|
|
29 #include "plugin-version.h"
|
|
30 #include "diagnostic.h"
|
|
31 #include "context.h"
|
|
32 #include "gcc-rich-location.h"
|
|
33 #include "print-tree.h"
|
|
34
|
|
35 int plugin_is_GPL_compatible;
|
|
36
|
|
37 static void
|
|
38 show_tree (tree node)
|
|
39 {
|
|
40 if (!CAN_HAVE_RANGE_P (node))
|
|
41 return;
|
|
42
|
|
43 gcc_rich_location richloc (EXPR_LOCATION (node));
|
131
|
44 richloc.add_expr (node, NULL);
|
111
|
45
|
|
46 if (richloc.get_num_locations () < 2)
|
|
47 {
|
131
|
48 error_at (&richloc, "range not found");
|
111
|
49 return;
|
|
50 }
|
|
51
|
|
52 enum tree_code code = TREE_CODE (node);
|
|
53
|
|
54 location_range *range = richloc.get_range (1);
|
131
|
55 inform (&richloc, "%s", get_tree_code_name (code));
|
111
|
56
|
|
57 /* Recurse. */
|
|
58 int min_idx = 0;
|
|
59 int max_idx = TREE_OPERAND_LENGTH (node);
|
|
60 switch (code)
|
|
61 {
|
|
62 case CALL_EXPR:
|
|
63 min_idx = 3;
|
|
64 break;
|
|
65
|
|
66 default:
|
|
67 break;
|
|
68 }
|
|
69
|
|
70 for (int i = min_idx; i < max_idx; i++)
|
|
71 show_tree (TREE_OPERAND (node, i));
|
|
72 }
|
|
73
|
|
74 tree
|
|
75 cb_walk_tree_fn (tree * tp, int * walk_subtrees,
|
|
76 void * data ATTRIBUTE_UNUSED)
|
|
77 {
|
|
78 if (TREE_CODE (*tp) != CALL_EXPR)
|
|
79 return NULL_TREE;
|
|
80
|
|
81 tree call_expr = *tp;
|
|
82 tree fn = CALL_EXPR_FN (call_expr);
|
|
83 if (TREE_CODE (fn) != ADDR_EXPR)
|
|
84 return NULL_TREE;
|
|
85 fn = TREE_OPERAND (fn, 0);
|
|
86 if (TREE_CODE (fn) != FUNCTION_DECL)
|
|
87 return NULL_TREE;
|
|
88 if (strcmp (IDENTIFIER_POINTER (DECL_NAME (fn)), "__show_tree"))
|
|
89 return NULL_TREE;
|
|
90
|
|
91 /* Get arg 1; print it! */
|
|
92 tree arg = CALL_EXPR_ARG (call_expr, 1);
|
|
93
|
|
94 show_tree (arg);
|
|
95
|
|
96 return NULL_TREE;
|
|
97 }
|
|
98
|
|
99 static void
|
|
100 callback (void *gcc_data, void *user_data)
|
|
101 {
|
|
102 tree fndecl = (tree)gcc_data;
|
|
103 walk_tree (&DECL_SAVED_TREE (fndecl), cb_walk_tree_fn, NULL, NULL);
|
|
104 }
|
|
105
|
|
106 int
|
|
107 plugin_init (struct plugin_name_args *plugin_info,
|
|
108 struct plugin_gcc_version *version)
|
|
109 {
|
|
110 struct register_pass_info pass_info;
|
|
111 const char *plugin_name = plugin_info->base_name;
|
|
112 int argc = plugin_info->argc;
|
|
113 struct plugin_argument *argv = plugin_info->argv;
|
|
114
|
|
115 if (!plugin_default_version_check (version, &gcc_version))
|
|
116 return 1;
|
|
117
|
|
118 register_callback (plugin_name,
|
|
119 PLUGIN_PRE_GENERICIZE,
|
|
120 callback,
|
|
121 NULL);
|
|
122
|
|
123 return 0;
|
|
124 }
|