Files
swift-mirror/include/swift/AST/ForeignAsyncConvention.h
Ben Barham ef8825bfe6 Migrate llvm::Optional to std::optional
LLVM has removed llvm::Optional, move over to std::optional. Also
clang-format to fix up all the renamed #includes.
2024-02-21 11:20:06 -08:00

204 lines
8.3 KiB
C++

//===--- ForeignAsyncConvention.h - Async conventions -----------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines the ForeignAsyncConvention structure, which
// describes the rules for how to detect that a foreign API is asynchronous.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_FOREIGN_ASYNC_CONVENTION_H
#define SWIFT_FOREIGN_ASYNC_CONVENTION_H
#include "swift/AST/Type.h"
namespace swift {
/// A small structure describing the async convention of a foreign declaration.
class ForeignAsyncConvention {
public:
struct Info {
private:
/// The index of the completion handler parameters.
unsigned CompletionHandlerParamIndex;
/// When non-zero, subtracting one indicates which parameter to the completion handler is
/// the Error? parameter that makes this async function also
/// throwing.
unsigned CompletionHandlerErrorParamIndexPlusOneOrZero;
/// When non-zero, indicates that the presence of an error is determined by
/// an integral argument to the completion handler being zero or nonzero.
unsigned CompletionHandlerFlagParamIndexPlusOneWithPolarityOrZero;
public:
Info()
: CompletionHandlerParamIndex(0),
CompletionHandlerErrorParamIndexPlusOneOrZero(0) { }
Info(unsigned completionHandlerParamIndex,
std::optional<unsigned> completionHandlerErrorParamIndex,
std::optional<unsigned> completionHandlerFlagParamIndex,
bool completionHandlerFlagIsErrorOnZero)
: CompletionHandlerParamIndex(completionHandlerParamIndex),
CompletionHandlerErrorParamIndexPlusOneOrZero(
completionHandlerErrorParamIndex
? *completionHandlerErrorParamIndex + 1
: 0),
CompletionHandlerFlagParamIndexPlusOneWithPolarityOrZero(
completionHandlerFlagParamIndex
? (*completionHandlerFlagParamIndex |
((unsigned)completionHandlerFlagIsErrorOnZero << 31)) +
1
: 0) {}
/// Retrieve the index of the completion handler argument in the method's
/// parameter list.
unsigned completionHandlerParamIndex() const {
return CompletionHandlerParamIndex;
}
/// Retrieve the index of the \c Error? parameter in the completion handler's
/// parameter list.
///
/// Typically, when argument passed to this parameter is non-null, the
/// provided error will be thrown by the async function. If a
/// \c completionHandlerFlagParamIndex is also specified, the
/// value of that flag instead indicates whether an error should be raised.
std::optional<unsigned> completionHandlerErrorParamIndex() const {
if (CompletionHandlerErrorParamIndexPlusOneOrZero == 0)
return std::nullopt;
return CompletionHandlerErrorParamIndexPlusOneOrZero - 1;
}
/// Retrieve the index of the error flag parameter in the completion handler's
/// parameter list, if any.
///
/// If present, the boolean value of this argument will indicate whether the
/// operation completed with an error. The \c completionHandlerFlagIsErrorOnZero
/// value indicates whether this argument being zero indicates an error, or
/// whether being nonzero indicates an error.
std::optional<unsigned> completionHandlerFlagParamIndex() const {
if (CompletionHandlerFlagParamIndexPlusOneWithPolarityOrZero == 0)
return std::nullopt;
return (CompletionHandlerFlagParamIndexPlusOneWithPolarityOrZero - 1)
& 0x7FFFFFFFu;
}
/// Indicates the polarity of the error flag parameter to the completion handler.
///
/// It is only valid to call this if \c completionHandlerFlagParamIndex returns
/// a non-\c None value; if there is no flag parameter to the completion handler, the value
/// of this property is meaningless. Otherwise, if true is returned, then a zero flag value
/// indicates an error, and nonzero indicates success. If false, then a zero flag value
/// indicates success, and nonzero indicates an error.
bool completionHandlerFlagIsErrorOnZero() const {
return (CompletionHandlerFlagParamIndexPlusOneWithPolarityOrZero - 1)
& 0x80000000u;
}
/// Whether the async function is throwing due to the completion handler
/// having an \c Error? parameter.
///
/// Equivalent to \c static_cast<bool>(completionHandlerErrorParamIndex()).
bool isThrowing() const {
return CompletionHandlerErrorParamIndexPlusOneOrZero != 0;
}
};
/// The type of the completion handler parameter.
CanType CompletionHandlerType;
/// Information about the async convention that can be determined from an
/// Objective-C declaration by itself.
Info TheInfo;
public:
ForeignAsyncConvention() : TheInfo() { }
ForeignAsyncConvention(
CanType completionHandlerType, unsigned completionHandlerParamIndex,
std::optional<unsigned> completionHandlerErrorParamIndex,
std::optional<unsigned> completionHandlerFlagParamIndex,
bool completionHandlerFlagIsErrorOnZero)
: CompletionHandlerType(completionHandlerType),
TheInfo(completionHandlerParamIndex, completionHandlerErrorParamIndex,
completionHandlerFlagParamIndex,
completionHandlerFlagIsErrorOnZero) {}
/// Retrieve the type of the completion handler parameter.
CanType completionHandlerType() const { return CompletionHandlerType; }
/// Retrieve the index of the completion handler parameter, which will be
/// erased from the Swift signature of the imported async function.
unsigned completionHandlerParamIndex() const {
return TheInfo.completionHandlerParamIndex();
}
/// Retrieve the index of the \c Error? parameter in the completion handler's
/// parameter list.
///
/// Typically, when argument passed to this parameter is non-null, the
/// provided error will be thrown by the async function. If a
/// \c completionHandlerFlagParamIndex is also specified, the
/// value of that flag instead indicates whether an error should be raised.
std::optional<unsigned> completionHandlerErrorParamIndex() const {
return TheInfo.completionHandlerErrorParamIndex();
}
/// Retrieve the index of the error flag parameter in the completion handler's
/// parameter list, if any.
///
/// If present, the boolean value of this argument will indicate whether the
/// operation completed with an error. The \c completionHandlerFlagIsErrorOnZero
/// value indicates whether this argument being zero indicates an error, or
/// whether being nonzero indicates an error.
std::optional<unsigned> completionHandlerFlagParamIndex() const {
return TheInfo.completionHandlerFlagParamIndex();
}
/// Indicates the polarity of the error flag parameter to the completion handler.
///
/// It is only valid to call this if \c completionHandlerFlagParamIndex returns
/// a non-\c None value. If true is returned, then a zero flag value indicates an error,
/// and nonzero indicates success. If false, then a zero flag value indicates success,
/// and nonzero indicates an error.
bool completionHandlerFlagIsErrorOnZero() const {
return TheInfo.completionHandlerFlagIsErrorOnZero();
}
/// Whether the async function is throwing due to the completion handler
/// having an \c Error? parameter.
///
/// Equivalent to \c static_cast<bool>(completionHandlerErrorParamIndex()).
bool isThrowing() const {
return TheInfo.isThrowing();
}
bool operator==(ForeignAsyncConvention other) const {
return CompletionHandlerType == other.CompletionHandlerType
&& TheInfo.completionHandlerParamIndex()
== other.TheInfo.completionHandlerParamIndex()
&& TheInfo.completionHandlerErrorParamIndex()
== other.TheInfo.completionHandlerErrorParamIndex();
}
bool operator!=(ForeignAsyncConvention other) const {
return !(*this == other);
}
};
}
#endif