On 8/13/25 11:45 AM, John Ericson wrote:
The old C-style was cumbersome make making one responsible for manually
create and pass a closure (separate function and *_info class for
closed-over variables).
I would have liked to redo this with C++ lambdas, so we could:
- derive environment types implicitly
- have fewer stray static functions
- make the return-type polymorphism type safe.
But I was advised on IRC that introducing template specializations in
the driver would a open compile time performance can of worms. It was
instead suggested I do it the old OOP way: this patch.
The old OOP way I don't really like, as it doesn't really reduce
boilerplate, but at least the environment accessing is well-typed now
(no `data` to `info` casts), and the `info->` boilerplate is also gone.
But I am happy to do as suggested. Also I have an idea for a follow-up
patch (after this one) that does allow the use of lambdas without
templating the original function, and so should be a "best of both
worlds" approach.
Thanks to Jason Merill for the idea of using an out-of-line definition
to avoid a large reindentating. That does make this much nicer.
gcc/ChangeLog:
* gcc.cc (for_each_path): Made method on class below.
(class find_within_paths): Class below has virtual method for
callback, instead of function and and data arguments.
(struct add_to_obstack_info): Renamed without trailing _info.
(struct add_to_obstack): Now inherits from find_within_paths.
(add_to_obstack): Became the callback on the above class which
inherited its name.
(build_search_list): Updated to use add_to_obstack.
(struct file_at_path_info): Renamed without trailing _info.
(struct file_at_path): Now inherits from find_within_paths.
(file_at_path): Became the callback on the above class which
inherited its name.
(find_a_file): Updated to use new file_at_path.
(struct spec_path_info): Renamed without trailing _info.
(struct spec_path): Now inherits from find_within_paths.
(spec_path): Became the callback on the above class which
inherited its name.
(do_spec_1): Updated to use new spec_path.
Signed-off-by: John Ericson <g...@johnericson.me>
---
gcc/gcc.cc | 126 +++++++++++++++++++++++++++++------------------------
1 file changed, 68 insertions(+), 58 deletions(-)
diff --git a/gcc/gcc.cc b/gcc/gcc.cc
index bfa588ee5f0..930060c2078 100644
--- a/gcc/gcc.cc
+++ b/gcc/gcc.cc
@@ -2774,12 +2774,23 @@ clear_failure_queue (void)
Returns the value returned by CALLBACK. */
-static void *
-for_each_path (const struct path_prefix *paths,
+class find_within_paths
+{
+protected:
+ virtual void *
+ callback (char *);
We don't need to split this declaration across lines. Also, building
xgcc fails for me with this patch because this function is not defined:
/usr/bin/ld: gcc.o: in function `find_within_paths::find_within_paths()':
/home/jason/gt/gcc/gcc.cc:2777:(.text._ZN17find_within_pathsC2Ev[_ZN17find_within_pathsC5Ev]+0x9):
undefined reference to `vtable for find_within_paths'
Doesn't it fail for you? Hmm, perhaps because you're building with
optimization and the reference gets optimized away.
It seems enough to add = 0 to define it as pure virtual.
@@ -2936,26 +2947,26 @@ for_each_path (const struct path_prefix *paths,
/* Callback for build_search_list. Adds path to obstack being built. */
-struct add_to_obstack_info {
+struct add_to_obstack : find_within_paths {
struct obstack *ob;
bool check_dir;
bool first_time;
+
+private:
+ void *callback (char *path) override;
};
-static void *
-add_to_obstack (char *path, void *data)
+void *add_to_obstack::callback (char *path)
...but here in the definition, the qualified-name should be at the
beginning of the line.
@@ -3026,34 +3037,35 @@ access_check (const char *name, int mode)
path. If the resulting file exists in the right mode, return the
full pathname to the file. */
-struct file_at_path_info {
+struct file_at_path : find_within_paths {
const char *name;
const char *suffix;
int name_len;
int suffix_len;
int mode;
+
+private:
+ void *callback (char *path) override;
};
-static void *
-file_at_path (char *path, void *data)
+void *file_at_path::callback (char *path)
Likewise.
@@ -6008,25 +6019,26 @@ do_self_spec (const char *spec)
/* Callback for processing %D and %I specs. */
-struct spec_path_info {
+struct spec_path : find_within_paths {
const char *option;
const char *append;
size_t append_len;
bool omit_relative;
bool separate_options;
bool realpaths;
+
+private:
+ void *callback (char *path) override;
};
-static void *
-spec_path (char *path, void *data)
+void *spec_path::callback (char *path)
Likewise.
Jason