annotate gcc/opt-problem.h @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1 /* Rich information on why an optimization wasn't possible.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 2018-2020 Free Software Foundation, Inc.
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
5 This file is part of GCC.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
6
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
7 GCC is free software; you can redistribute it and/or modify it under
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
8 the terms of the GNU General Public License as published by the Free
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
9 Software Foundation; either version 3, or (at your option) any later
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
10 version.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
11
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
15 for more details.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
16
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
18 along with GCC; see the file COPYING3. If not see
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
19 <http://www.gnu.org/licenses/>. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
20
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
21 #ifndef GCC_OPT_PROBLEM_H
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
22 #define GCC_OPT_PROBLEM_H
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
23
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
24 #include "diagnostic-core.h" /* for ATTRIBUTE_GCC_DIAG. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
25 #include "optinfo.h" /* for optinfo. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
26
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
27 /* This header declares a family of wrapper classes for tracking a
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
28 success/failure value, while optionally supporting propagating an
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
29 opt_problem * describing any failure back up the call stack.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
30
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
31 For instance, at the deepest point of the callstack where the failure
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
32 happens, rather than:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
33
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
34 if (!check_something ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
35 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
36 if (dump_enabled_p ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
37 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
38 "foo is unsupported.\n");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
39 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
40 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
41 // [...more checks...]
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
42
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
43 // All checks passed:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
44 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
45
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
46 we can capture the cause of the failure via:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
47
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
48 if (!check_something ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
49 return opt_result::failure_at (stmt, "foo is unsupported");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
50 // [...more checks...]
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
51
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
52 // All checks passed:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
53 return opt_result::success ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
54
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
55 which effectively returns true or false, whilst recording any problem.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
56
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
57 opt_result::success and opt_result::failure return opt_result values
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
58 which "looks like" true/false respectively, via operator bool().
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
59 If dump_enabled_p, then opt_result::failure also creates an opt_problem *,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
60 capturing the pertinent data (here, "foo is unsupported " and "stmt").
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
61 If dumps are disabled, then opt_problem instances aren't
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
62 created, and it's equivalent to just returning a bool.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
63
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
64 The opt_problem can be propagated via opt_result values back up
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
65 the call stack to where it makes most sense to the user.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
66 For instance, rather than:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
67
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
68 bool ok = try_something_that_might_fail ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
69 if (!ok)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
70 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
71 if (dump_enabled_p ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
72 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
73 "some message.\n");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
74 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
75 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
76
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
77 we can replace the bool with an opt_result, so if dump_enabled_p, we
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
78 assume that if try_something_that_might_fail, an opt_problem * will be
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
79 created, and we can propagate it up the call chain:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
80
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
81 opt_result ok = try_something_that_might_fail ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
82 if (!ok)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
83 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
84 if (dump_enabled_p ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
85 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
86 "some message.\n");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
87 return ok; // propagating the opt_result
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
88 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
89
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
90 opt_result is an opt_wrapper<bool>, where opt_wrapper<T> is a base
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
91 class for wrapping a T, optionally propagating an opt_problem in
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
92 case of failure_at (when dumps are enabled). Similarly,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
93 opt_pointer_wrapper<T> can be used to wrap pointer types (where non-NULL
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
94 signifies success, NULL signifies failure).
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
95
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
96 In all cases, opt_wrapper<T> acts as if the opt_problem were one of its
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
97 fields, but the opt_problem is actually stored in a global, so that when
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
98 compiled, an opt_wrapper<T> is effectively just a T, so that we're
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
99 still just passing e.g. a bool around; the opt_wrapper<T> classes
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
100 simply provide type-checking and an API to ensure that we provide
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
101 error-messages deep in the callstack at the places where problems
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
102 occur, and that we propagate them. This also avoids having
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
103 to manage the ownership of the opt_problem instances.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
104
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
105 Using opt_result and opt_wrapper<T> documents the intent of the code
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
106 for the places where we represent success values, and allows the C++ type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
107 system to track where the deepest points in the callstack are where we
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
108 need to emit the failure messages from. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
109
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
110 /* A bundle of information about why an optimization failed (e.g.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
111 vectorization), and the location in both the user's code and
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
112 in GCC itself where the problem occurred.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
113
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
114 Instances are created by static member functions in opt_wrapper
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
115 subclasses, such as opt_result::failure.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
116
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
117 Instances are only created when dump_enabled_p (). */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
118
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
119 class opt_problem
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
120 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
121 public:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
122 static opt_problem *get_singleton () { return s_the_problem; }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
123
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
124 opt_problem (const dump_location_t &loc,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
125 const char *fmt, va_list *ap)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
126 ATTRIBUTE_GCC_DUMP_PRINTF (3, 0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
127
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
128 const dump_location_t &
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
129 get_dump_location () const { return m_optinfo.get_dump_location (); }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
130
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
131 const optinfo & get_optinfo () const { return m_optinfo; }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
132
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
133 void emit_and_clear ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
134
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
135 private:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
136 optinfo m_optinfo;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
137
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
138 static opt_problem *s_the_problem;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
139 };
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
140
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
141 /* A base class for wrapper classes that track a success/failure value, while
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
142 optionally supporting propagating an opt_problem * describing any
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
143 failure back up the call stack. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
144
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
145 template <typename T>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
146 class opt_wrapper
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
147 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
148 public:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
149 typedef T wrapped_t;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
150
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
151 /* Be accessible as the wrapped type. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
152 operator wrapped_t () const { return m_result; }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
153
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
154 /* No public ctor. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
155
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
156 wrapped_t get_result () const { return m_result; }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
157 opt_problem *get_problem () const { return opt_problem::get_singleton (); }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
158
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
159 protected:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
160 opt_wrapper (wrapped_t result, opt_problem */*problem*/)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
161 : m_result (result)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
162 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
163 /* "problem" is ignored: although it looks like a field, we
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
164 actually just use the opt_problem singleton, so that
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
165 opt_wrapper<T> in memory is just a T. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
166 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
167
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
168 private:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
169 wrapped_t m_result;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
170 };
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
171
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
172 /* Subclass of opt_wrapper<T> for bool, where
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
173 - true signifies "success", and
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
174 - false signifies "failure"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
175 whilst effectively propagating an opt_problem * describing any failure
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
176 back up the call stack. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
177
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
178 class opt_result : public opt_wrapper <bool>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
179 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
180 public:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
181 /* Generate a "success" value: a wrapper around "true". */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
182
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
183 static opt_result success () { return opt_result (true, NULL); }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
184
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
185 /* Generate a "failure" value: a wrapper around "false", and,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
186 if dump_enabled_p, an opt_problem. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
187
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
188 static opt_result failure_at (const dump_location_t &loc,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
189 const char *fmt, ...)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
190 ATTRIBUTE_GCC_DUMP_PRINTF (2, 3)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
191 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
192 opt_problem *problem = NULL;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
193 if (dump_enabled_p ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
194 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
195 va_list ap;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
196 va_start (ap, fmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
197 problem = new opt_problem (loc, fmt, &ap);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
198 va_end (ap);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
199 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
200 return opt_result (false, problem);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
201 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
202
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
203 /* Given a failure wrapper of some other kind, make an opt_result failure
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
204 object, for propagating the opt_problem up the call stack. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
205
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
206 template <typename S>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
207 static opt_result
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
208 propagate_failure (opt_wrapper <S> other)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
209 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
210 return opt_result (false, other.get_problem ());
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
211 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
212
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
213 private:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
214 /* Private ctor. Instances should be created by the success and failure
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
215 static member functions. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
216 opt_result (wrapped_t result, opt_problem *problem)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
217 : opt_wrapper <bool> (result, problem)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
218 {}
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
219 };
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
220
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
221 /* Subclass of opt_wrapper<T> where T is a pointer type, for tracking
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
222 success/failure, where:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
223 - a non-NULL value signifies "success", and
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
224 - a NULL value signifies "failure",
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
225 whilst effectively propagating an opt_problem * describing any failure
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
226 back up the call stack. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
227
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
228 template <typename PtrType_t>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
229 class opt_pointer_wrapper : public opt_wrapper <PtrType_t>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
230 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
231 public:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
232 typedef PtrType_t wrapped_pointer_t;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
233
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
234 /* Given a non-NULL pointer, make a success object wrapping it. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
235
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
236 static opt_pointer_wrapper <wrapped_pointer_t>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
237 success (wrapped_pointer_t ptr)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
238 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
239 return opt_pointer_wrapper <wrapped_pointer_t> (ptr, NULL);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
240 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
241
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
242 /* Make a NULL pointer failure object, with the given message
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
243 (if dump_enabled_p). */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
244
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
245 static opt_pointer_wrapper <wrapped_pointer_t>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
246 failure_at (const dump_location_t &loc,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
247 const char *fmt, ...)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
248 ATTRIBUTE_GCC_DUMP_PRINTF (2, 3)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
249 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
250 opt_problem *problem = NULL;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
251 if (dump_enabled_p ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
252 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
253 va_list ap;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
254 va_start (ap, fmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
255 problem = new opt_problem (loc, fmt, &ap);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
256 va_end (ap);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
257 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
258 return opt_pointer_wrapper <wrapped_pointer_t> (NULL, problem);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
259 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
260
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
261 /* Given a failure wrapper of some other kind, make a NULL pointer
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
262 failure object, propagating the problem. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
263
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
264 template <typename S>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
265 static opt_pointer_wrapper <wrapped_pointer_t>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
266 propagate_failure (opt_wrapper <S> other)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
267 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
268 return opt_pointer_wrapper <wrapped_pointer_t> (NULL,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
269 other.get_problem ());
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
270 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
271
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
272 /* Support accessing the underlying pointer via ->. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
273
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
274 wrapped_pointer_t operator-> () const { return this->get_result (); }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
275
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
276 private:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
277 /* Private ctor. Instances should be built using the static member
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
278 functions "success" and "failure". */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
279 opt_pointer_wrapper (wrapped_pointer_t result, opt_problem *problem)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
280 : opt_wrapper<PtrType_t> (result, problem)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
281 {}
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
282 };
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
283
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
284 /* A typedef for wrapping "tree" so that NULL_TREE can carry an
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
285 opt_problem describing the failure (if dump_enabled_p). */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
286
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
287 typedef opt_pointer_wrapper<tree> opt_tree;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
288
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
289 #endif /* #ifndef GCC_OPT_PROBLEM_H */