1 /* 2 * Copyright 2016 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SKSL_FUNCTIONDECLARATION 9 #define SKSL_FUNCTIONDECLARATION 10 11 #include "SkSLExpression.h" 12 #include "SkSLModifiers.h" 13 #include "SkSLSymbol.h" 14 #include "SkSLSymbolTable.h" 15 #include "SkSLType.h" 16 #include "SkSLVariable.h" 17 18 namespace SkSL { 19 20 /** 21 * A function declaration (not a definition -- does not contain a body). 22 */ 23 struct FunctionDeclaration : public Symbol { FunctionDeclarationFunctionDeclaration24 FunctionDeclaration(Position position, SkString name, 25 std::vector<const Variable*> parameters, const Type& returnType) 26 : INHERITED(position, kFunctionDeclaration_Kind, std::move(name)) 27 , fDefined(false) 28 , fBuiltin(false) 29 , fParameters(std::move(parameters)) 30 , fReturnType(returnType) {} 31 descriptionFunctionDeclaration32 SkString description() const override { 33 SkString result = fReturnType.description() + " " + fName + "("; 34 SkString separator; 35 for (auto p : fParameters) { 36 result += separator; 37 separator = ", "; 38 result += p->description(); 39 } 40 result += ")"; 41 return result; 42 } 43 matchesFunctionDeclaration44 bool matches(const FunctionDeclaration& f) const { 45 if (fName != f.fName) { 46 return false; 47 } 48 if (fParameters.size() != f.fParameters.size()) { 49 return false; 50 } 51 for (size_t i = 0; i < fParameters.size(); i++) { 52 if (fParameters[i]->fType != f.fParameters[i]->fType) { 53 return false; 54 } 55 } 56 return true; 57 } 58 59 /** 60 * Determine the effective types of this function's parameters and return value when called with 61 * the given arguments. This is relevant for functions with generic parameter types, where this 62 * will collapse the generic types down into specific concrete types. 63 * 64 * Returns true if it was able to select a concrete set of types for the generic function, false 65 * if there is no possible way this can match the argument types. Note that even a true return 66 * does not guarantee that the function can be successfully called with those arguments, merely 67 * indicates that an attempt should be made. If false is returned, the state of 68 * outParameterTypes and outReturnType are undefined. 69 */ determineFinalTypesFunctionDeclaration70 bool determineFinalTypes(const std::vector<std::unique_ptr<Expression>>& arguments, 71 std::vector<const Type*>* outParameterTypes, 72 const Type** outReturnType) const { 73 assert(arguments.size() == fParameters.size()); 74 int genericIndex = -1; 75 for (size_t i = 0; i < arguments.size(); i++) { 76 if (fParameters[i]->fType.kind() == Type::kGeneric_Kind) { 77 std::vector<const Type*> types = fParameters[i]->fType.coercibleTypes(); 78 if (genericIndex == -1) { 79 for (size_t j = 0; j < types.size(); j++) { 80 if (arguments[i]->fType.canCoerceTo(*types[j])) { 81 genericIndex = j; 82 break; 83 } 84 } 85 if (genericIndex == -1) { 86 return false; 87 } 88 } 89 outParameterTypes->push_back(types[genericIndex]); 90 } else { 91 outParameterTypes->push_back(&fParameters[i]->fType); 92 } 93 } 94 if (fReturnType.kind() == Type::kGeneric_Kind) { 95 assert(genericIndex != -1); 96 *outReturnType = fReturnType.coercibleTypes()[genericIndex]; 97 } else { 98 *outReturnType = &fReturnType; 99 } 100 return true; 101 } 102 103 mutable bool fDefined; 104 bool fBuiltin; 105 const std::vector<const Variable*> fParameters; 106 const Type& fReturnType; 107 108 typedef Symbol INHERITED; 109 }; 110 111 } // namespace 112 113 #endif 114