| Index: src/sksl/ir/SkSLFunctionDeclaration.h
|
| diff --git a/src/sksl/ir/SkSLFunctionDeclaration.h b/src/sksl/ir/SkSLFunctionDeclaration.h
|
| index ffde0c66c130aedb069da390899b5011eb1cc1af..52a579a89b9e13dbb2f36e22feaf224d0b04fbe8 100644
|
| --- a/src/sksl/ir/SkSLFunctionDeclaration.h
|
| +++ b/src/sksl/ir/SkSLFunctionDeclaration.h
|
| @@ -8,6 +8,7 @@
|
| #ifndef SKSL_FUNCTIONDECLARATION
|
| #define SKSL_FUNCTIONDECLARATION
|
|
|
| +#include "SkSLExpression.h"
|
| #include "SkSLModifiers.h"
|
| #include "SkSLSymbol.h"
|
| #include "SkSLSymbolTable.h"
|
| @@ -55,6 +56,50 @@ struct FunctionDeclaration : public Symbol {
|
| return true;
|
| }
|
|
|
| + /**
|
| + * Determine the effective types of this function's parameters and return value when called with
|
| + * the given arguments. This is relevant for functions with generic parameter types, where this
|
| + * will collapse the generic types down into specific concrete types.
|
| + *
|
| + * Returns true if it was able to select a concrete set of types for the generic function, false
|
| + * if there is no possible way this can match the argument types. Note that even a true return
|
| + * does not guarantee that the function can be successfully called with those arguments, merely
|
| + * indicates that an attempt should be made. If false is returned, the state of
|
| + * outParameterTypes and outReturnType are undefined.
|
| + */
|
| + bool determineFinalTypes(const std::vector<std::unique_ptr<Expression>>& arguments,
|
| + std::vector<const Type*>* outParameterTypes,
|
| + const Type** outReturnType) const {
|
| + assert(arguments.size() == fParameters.size());
|
| + int genericIndex = -1;
|
| + for (size_t i = 0; i < arguments.size(); i++) {
|
| + if (fParameters[i]->fType.kind() == Type::kGeneric_Kind) {
|
| + std::vector<const Type*> types = fParameters[i]->fType.coercibleTypes();
|
| + if (genericIndex == -1) {
|
| + for (size_t j = 0; j < types.size(); j++) {
|
| + if (arguments[i]->fType.canCoerceTo(*types[j])) {
|
| + genericIndex = j;
|
| + break;
|
| + }
|
| + }
|
| + if (genericIndex == -1) {
|
| + return false;
|
| + }
|
| + }
|
| + outParameterTypes->push_back(types[genericIndex]);
|
| + } else {
|
| + outParameterTypes->push_back(&fParameters[i]->fType);
|
| + }
|
| + }
|
| + if (fReturnType.kind() == Type::kGeneric_Kind) {
|
| + assert(genericIndex != -1);
|
| + *outReturnType = fReturnType.coercibleTypes()[genericIndex];
|
| + } else {
|
| + *outReturnType = &fReturnType;
|
| + }
|
| + return true;
|
| + }
|
| +
|
| mutable bool fDefined;
|
| bool fBuiltin;
|
| const std::vector<const Variable*> fParameters;
|
|
|