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 "src/sksl/ir/SkSLExpression.h" 12 #include "src/sksl/ir/SkSLModifiers.h" 13 #include "src/sksl/ir/SkSLSymbol.h" 14 #include "src/sksl/ir/SkSLSymbolTable.h" 15 #include "src/sksl/ir/SkSLType.h" 16 #include "src/sksl/ir/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(int offset, Modifiers modifiers, StringFragment name, 25 std::vector<const Variable*> parameters, const Type& returnType) 26 : INHERITED(offset, kFunctionDeclaration_Kind, std::move(name)) 27 , fDefined(false) 28 , fBuiltin(false) 29 , fModifiers(modifiers) 30 , fParameters(std::move(parameters)) 31 , fReturnType(returnType) {} 32 descriptionFunctionDeclaration33 String description() const override { 34 String result = fReturnType.description() + " " + fName + "("; 35 String separator; 36 for (auto p : fParameters) { 37 result += separator; 38 separator = ", "; 39 result += p->description(); 40 } 41 result += ")"; 42 return result; 43 } 44 matchesFunctionDeclaration45 bool matches(const FunctionDeclaration& f) const { 46 if (fName != f.fName) { 47 return false; 48 } 49 if (fParameters.size() != f.fParameters.size()) { 50 return false; 51 } 52 for (size_t i = 0; i < fParameters.size(); i++) { 53 if (fParameters[i]->fType != f.fParameters[i]->fType) { 54 return false; 55 } 56 } 57 return true; 58 } 59 60 /** 61 * Determine the effective types of this function's parameters and return value when called with 62 * the given arguments. This is relevant for functions with generic parameter types, where this 63 * will collapse the generic types down into specific concrete types. 64 * 65 * Returns true if it was able to select a concrete set of types for the generic function, false 66 * if there is no possible way this can match the argument types. Note that even a true return 67 * does not guarantee that the function can be successfully called with those arguments, merely 68 * indicates that an attempt should be made. If false is returned, the state of 69 * outParameterTypes and outReturnType are undefined. 70 */ determineFinalTypesFunctionDeclaration71 bool determineFinalTypes(const std::vector<std::unique_ptr<Expression>>& arguments, 72 std::vector<const Type*>* outParameterTypes, 73 const Type** outReturnType) const { 74 SkASSERT(arguments.size() == fParameters.size()); 75 int genericIndex = -1; 76 for (size_t i = 0; i < arguments.size(); i++) { 77 if (fParameters[i]->fType.kind() == Type::kGeneric_Kind) { 78 std::vector<const Type*> types = fParameters[i]->fType.coercibleTypes(); 79 if (genericIndex == -1) { 80 for (size_t j = 0; j < types.size(); j++) { 81 if (arguments[i]->fType.canCoerceTo(*types[j])) { 82 genericIndex = j; 83 break; 84 } 85 } 86 if (genericIndex == -1) { 87 return false; 88 } 89 } 90 outParameterTypes->push_back(types[genericIndex]); 91 } else { 92 outParameterTypes->push_back(&fParameters[i]->fType); 93 } 94 } 95 if (fReturnType.kind() == Type::kGeneric_Kind) { 96 SkASSERT(genericIndex != -1); 97 *outReturnType = fReturnType.coercibleTypes()[genericIndex]; 98 } else { 99 *outReturnType = &fReturnType; 100 } 101 return true; 102 } 103 104 mutable bool fDefined; 105 bool fBuiltin; 106 Modifiers fModifiers; 107 const std::vector<const Variable*> fParameters; 108 const Type& fReturnType; 109 110 typedef Symbol INHERITED; 111 }; 112 113 } // namespace 114 115 #endif 116