@@ -30,24 +30,35 @@ class ForeignAsyncConvention {
3030 // / The index of the completion handler parameters.
3131 unsigned CompletionHandlerParamIndex;
3232
33- // / When non-zero, indicates which parameter to the completion handler is
34- // / the Error? parameter (minus one) that makes this async function also
33+ // / When non-zero, subtracting one indicates which parameter to the completion handler is
34+ // / the Error? parameter that makes this async function also
3535 // / throwing.
3636 unsigned CompletionHandlerErrorParamIndexPlusOneOrZero;
3737
38+ // / When non-zero, indicates that the presence of an error is determined by
39+ // / an integral argument to the completion handler being zero or nonzero.
40+ unsigned CompletionHandlerFlagParamIndexPlusOneWithPolarityOrZero;
41+
3842 public:
3943 Info ()
4044 : CompletionHandlerParamIndex(0 ),
4145 CompletionHandlerErrorParamIndexPlusOneOrZero (0 ) { }
4246
4347 Info (
4448 unsigned completionHandlerParamIndex,
45- Optional<unsigned > completionHandlerErrorParamIndex)
49+ Optional<unsigned > completionHandlerErrorParamIndex,
50+ Optional<unsigned > completionHandlerFlagParamIndex,
51+ bool completionHandlerFlagIsErrorOnZero)
4652 : CompletionHandlerParamIndex(completionHandlerParamIndex),
4753 CompletionHandlerErrorParamIndexPlusOneOrZero(
4854 completionHandlerErrorParamIndex
4955 ? *completionHandlerErrorParamIndex + 1
50- : 0 ) {}
56+ : 0 ),
57+ CompletionHandlerFlagParamIndexPlusOneWithPolarityOrZero(
58+ completionHandlerFlagParamIndex
59+ ? (*completionHandlerFlagParamIndex | ((unsigned )completionHandlerFlagIsErrorOnZero << 31)) + 1
60+ : 0)
61+ {}
5162
5263 // / Retrieve the index of the completion handler argument in the method's
5364 // / parameter list.
@@ -56,15 +67,46 @@ class ForeignAsyncConvention {
5667 }
5768
5869 // / Retrieve the index of the \c Error? parameter in the completion handler's
59- // / parameter list. When argument passed to this parameter is non-null, the
60- // / provided error will be thrown by the async function.
70+ // / parameter list.
71+ // /
72+ // / Typically, when argument passed to this parameter is non-null, the
73+ // / provided error will be thrown by the async function. If a
74+ // / \c completionHandlerFlagParamIndex is also specified, the
75+ // / value of that flag instead indicates whether an error should be raised.
6176 Optional<unsigned > completionHandlerErrorParamIndex () const {
6277 if (CompletionHandlerErrorParamIndexPlusOneOrZero == 0 )
6378 return None;
6479
6580 return CompletionHandlerErrorParamIndexPlusOneOrZero - 1 ;
6681 }
6782
83+ // / Retrieve the index of the error flag parameter in the completion handler's
84+ // / parameter list, if any.
85+ // /
86+ // / If present, the boolean value of this argument will indicate whether the
87+ // / operation completed with an error. The \c completionHandlerFlagIsErrorOnZero
88+ // / value indicates whether this argument being zero indicates an error, or
89+ // / whether being nonzero indicates an error.
90+ Optional<unsigned > completionHandlerFlagParamIndex () const {
91+ if (CompletionHandlerFlagParamIndexPlusOneWithPolarityOrZero == 0 )
92+ return None;
93+
94+ return (CompletionHandlerFlagParamIndexPlusOneWithPolarityOrZero - 1 )
95+ & 0x7FFFFFFFu ;
96+ }
97+
98+ // / Indicates the polarity of the error flag parameter to the completion handler.
99+ // /
100+ // / It is only valid to call this if \c completionHandlerFlagParamIndex returns
101+ // / a non-\c None value; if there is no flag parameter to the completion handler, the value
102+ // / of this property is meaningless. Otherwise, if true is returned, then a zero flag value
103+ // / indicates an error, and nonzero indicates success. If false, then a zero flag value
104+ // / indicates success, and nonzero indicates an error.
105+ bool completionHandlerFlagIsErrorOnZero () const {
106+ return (CompletionHandlerFlagParamIndexPlusOneWithPolarityOrZero - 1 )
107+ & 0x80000000u ;
108+ }
109+
68110 // / Whether the async function is throwing due to the completion handler
69111 // / having an \c Error? parameter.
70112 // /
@@ -86,9 +128,13 @@ class ForeignAsyncConvention {
86128
87129 ForeignAsyncConvention (CanType completionHandlerType,
88130 unsigned completionHandlerParamIndex,
89- Optional<unsigned > completionHandlerErrorParamIndex)
131+ Optional<unsigned > completionHandlerErrorParamIndex,
132+ Optional<unsigned > completionHandlerFlagParamIndex,
133+ bool completionHandlerFlagIsErrorOnZero)
90134 : CompletionHandlerType(completionHandlerType),
91- TheInfo(completionHandlerParamIndex, completionHandlerErrorParamIndex)
135+ TheInfo(completionHandlerParamIndex, completionHandlerErrorParamIndex,
136+ completionHandlerFlagParamIndex,
137+ completionHandlerFlagIsErrorOnZero)
92138 { }
93139
94140 // / Retrieve the type of the completion handler parameter.
@@ -101,11 +147,36 @@ class ForeignAsyncConvention {
101147 }
102148
103149 // / Retrieve the index of the \c Error? parameter in the completion handler's
104- // / parameter list. When argument passed to this parameter is non-null, the
105- // / provided error will be thrown by the async function.
150+ // / parameter list.
151+ // /
152+ // / Typically, when argument passed to this parameter is non-null, the
153+ // / provided error will be thrown by the async function. If a
154+ // / \c completionHandlerFlagParamIndex is also specified, the
155+ // / value of that flag instead indicates whether an error should be raised.
106156 Optional<unsigned > completionHandlerErrorParamIndex () const {
107157 return TheInfo.completionHandlerErrorParamIndex ();
108158 }
159+
160+ // / Retrieve the index of the error flag parameter in the completion handler's
161+ // / parameter list, if any.
162+ // /
163+ // / If present, the boolean value of this argument will indicate whether the
164+ // / operation completed with an error. The \c completionHandlerFlagIsErrorOnZero
165+ // / value indicates whether this argument being zero indicates an error, or
166+ // / whether being nonzero indicates an error.
167+ Optional<unsigned > completionHandlerFlagParamIndex () const {
168+ return TheInfo.completionHandlerFlagParamIndex ();
169+ }
170+
171+ // / Indicates the polarity of the error flag parameter to the completion handler.
172+ // /
173+ // / It is only valid to call this if \c completionHandlerFlagParamIndex returns
174+ // / a non-\c None value. If true is returned, then a zero flag value indicates an error,
175+ // / and nonzero indicates success. If false, then a zero flag value indicates success,
176+ // / and nonzero indicates an error.
177+ bool completionHandlerFlagIsErrorOnZero () const {
178+ return TheInfo.completionHandlerFlagIsErrorOnZero ();
179+ }
109180
110181 // / Whether the async function is throwing due to the completion handler
111182 // / having an \c Error? parameter.
0 commit comments