summaryrefslogtreecommitdiff
path: root/Meta
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2022-11-08 19:58:54 -0500
committerLinus Groh <mail@linusgroh.de>2022-11-09 14:15:59 +0000
commit357fd76e300cfd3f35d0cf9c528b9708ba82266c (patch)
treea5cfee198af4e50b3e30c355f52eab07bbb883d2 /Meta
parent3618abdd19bf2b7c4da9b37854c7ddf7c5a99440 (diff)
downloadserenity-357fd76e300cfd3f35d0cf9c528b9708ba82266c.zip
Meta: Generate a helper constructor for single-value IPC responses
When an IPC message returns a single value, we generate a class with a constructor that is something like: class MessageResponse { MessageResponse(SingleReturnType value) : m_value(move(value)) { } }; If that IPC message wants to return a value that SingleReturnType is constructible from, you have to wrap that return call with braces: return { value_that_could_construct_single_return_type }; That isn't really an issue except for when we want to mix TRY semantics with the return type. If SingleReturnType is constructible from an Error type (i.e. something similar to ErrorOr), the following doesn't work: TRY(fallible_function()); Because MessageResponse would not be constructible from Error. Instead, we must do some workaround with a custom TRY macro, as in 31bb792. This patch generates a constructor that makes TRY usable as-is without any custom macros. We perform a very similar trick in ThrowCompletionOr inside LibJS. This constructor will allow you to create MessageResponse from any type that SingleReturnType is constructible from.
Diffstat (limited to 'Meta')
-rw-r--r--Meta/Lagom/Tools/CodeGenerators/IPCCompiler/main.cpp18
1 files changed, 17 insertions, 1 deletions
diff --git a/Meta/Lagom/Tools/CodeGenerators/IPCCompiler/main.cpp b/Meta/Lagom/Tools/CodeGenerators/IPCCompiler/main.cpp
index 2ff1c19f35..9eebb2f916 100644
--- a/Meta/Lagom/Tools/CodeGenerators/IPCCompiler/main.cpp
+++ b/Meta/Lagom/Tools/CodeGenerators/IPCCompiler/main.cpp
@@ -303,7 +303,23 @@ public:)~~~");
@message.pascal_name@(@message.pascal_name@ const&) = default;
@message.pascal_name@(@message.pascal_name@&&) = default;
@message.pascal_name@& operator=(@message.pascal_name@ const&) = default;
- @message.constructor@
+ @message.constructor@)~~~");
+
+ if (parameters.size() == 1) {
+ auto const& parameter = parameters[0];
+ message_generator.set("parameter.type"sv, parameter.type);
+ message_generator.set("parameter.name"sv, parameter.name);
+
+ message_generator.appendln(R"~~~(
+ template <typename WrappedReturnType>
+ requires(!SameAs<WrappedReturnType, @parameter.type@>)
+ @message.pascal_name@(WrappedReturnType&& value)
+ : m_@parameter.name@(forward<WrappedReturnType>(value))
+ {
+ })~~~");
+ }
+
+ message_generator.appendln(R"~~~(
virtual ~@message.pascal_name@() override {}
virtual u32 endpoint_magic() const override { return @endpoint.magic@; }