]>
Commit | Line | Data |
---|---|---|
a96cefb2 | 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 | ||
a96cefb2 | 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)); | |
b7bb5264 | 44 | richloc.add_expr (node, NULL); |
a96cefb2 | 45 | |
46 | if (richloc.get_num_locations () < 2) | |
47 | { | |
3b6578b3 | 48 | error_at (&richloc, "range not found"); |
a96cefb2 | 49 | return; |
50 | } | |
51 | ||
52 | enum tree_code code = TREE_CODE (node); | |
53 | ||
54 | location_range *range = richloc.get_range (1); | |
3b6578b3 | 55 | inform (&richloc, "%s", get_tree_code_name (code)); |
a96cefb2 | 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 | } |