Chromium Code Reviews| 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])) { |
|
dogben
2016/10/25 13:56:50
Is it always the case that a generic type's coerci
|
| + genericIndex = j; |
| + break; |
| + } |
| + } |
| + if (genericIndex == -1) { |
| + return false; |
| + } |
| + } |
|
dogben
2016/10/25 13:56:50
Do we need a range check here? i.e.
...
} else {
|
| + 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; |