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 "include/core/SkSpan.h" 12 #include "include/core/SkTypes.h" 13 #include "include/private/base/SkTArray.h" 14 #include "src/sksl/SkSLIntrinsicList.h" 15 #include "src/sksl/ir/SkSLIRNode.h" 16 #include "src/sksl/ir/SkSLModifierFlags.h" 17 #include "src/sksl/ir/SkSLSymbol.h" 18 19 #include <memory> 20 #include <string> 21 #include <string_view> 22 23 namespace SkSL { 24 25 class Context; 26 class ExpressionArray; 27 class FunctionDefinition; 28 struct Modifiers; 29 class Position; 30 class Type; 31 class Variable; 32 33 /** 34 * A function declaration (not a definition -- does not contain a body). 35 */ 36 class FunctionDeclaration final : public Symbol { 37 public: 38 inline static constexpr Kind kIRNodeKind = Kind::kFunctionDeclaration; 39 40 FunctionDeclaration(const Context& context, 41 Position pos, 42 ModifierFlags modifierFlags, 43 std::string_view name, 44 skia_private::TArray<Variable*> parameters, 45 const Type* returnType, 46 IntrinsicKind intrinsicKind); 47 48 static FunctionDeclaration* Convert(const Context& context, 49 Position pos, 50 const Modifiers& modifiers, 51 std::string_view name, 52 skia_private::TArray<std::unique_ptr<Variable>> parameters, 53 Position returnTypePos, 54 const Type* returnType); 55 modifierFlags()56 ModifierFlags modifierFlags() const { 57 return fModifierFlags; 58 } 59 setModifierFlags(ModifierFlags m)60 void setModifierFlags(ModifierFlags m) { 61 fModifierFlags = m; 62 } 63 definition()64 const FunctionDefinition* definition() const { 65 return fDefinition; 66 } 67 setDefinition(const FunctionDefinition * definition)68 void setDefinition(const FunctionDefinition* definition) { 69 fDefinition = definition; 70 fIntrinsicKind = kNotIntrinsic; 71 } 72 setNextOverload(FunctionDeclaration * overload)73 void setNextOverload(FunctionDeclaration* overload) { 74 SkASSERT(!overload || overload->name() == this->name()); 75 fNextOverload = overload; 76 } 77 parameters()78 SkSpan<Variable* const> parameters() const { 79 return fParameters; 80 } 81 returnType()82 const Type& returnType() const { 83 return *fReturnType; 84 } 85 isBuiltin()86 bool isBuiltin() const { 87 return fBuiltin; 88 } 89 isMain()90 bool isMain() const { 91 return fIsMain; 92 } 93 intrinsicKind()94 IntrinsicKind intrinsicKind() const { 95 return fIntrinsicKind; 96 } 97 isIntrinsic()98 bool isIntrinsic() const { 99 return this->intrinsicKind() != kNotIntrinsic; 100 } 101 nextOverload()102 const FunctionDeclaration* nextOverload() const { 103 return fNextOverload; 104 } 105 mutableNextOverload()106 FunctionDeclaration* mutableNextOverload() const { 107 return fNextOverload; 108 } 109 110 std::string mangledName() const; 111 112 std::string description() const override; 113 114 bool matches(const FunctionDeclaration& f) const; 115 116 /** 117 * If this function is main(), and it has the requested parameter, returns that parameter. 118 * For instance, only a runtime-blend program will have a dest-color parameter, in parameter 1; 119 * `getMainDestColorParameter` will return that parameter if this is a runtime-blend main() 120 * function. Otherwise, null is returned. 121 */ getMainCoordsParameter()122 const Variable* getMainCoordsParameter() const { 123 return fHasMainCoordsParameter ? fParameters[0] : nullptr; 124 } getMainInputColorParameter()125 const Variable* getMainInputColorParameter() const { 126 return fHasMainInputColorParameter ? fParameters[0] : nullptr; 127 } getMainDestColorParameter()128 const Variable* getMainDestColorParameter() const { 129 return fHasMainDestColorParameter ? fParameters[1] : nullptr; 130 } 131 132 /** 133 * Determine the effective types of this function's parameters and return value when called with 134 * the given arguments. This is relevant for functions with generic parameter types, where this 135 * will collapse the generic types down into specific concrete types. 136 * 137 * Returns true if it was able to select a concrete set of types for the generic function, false 138 * if there is no possible way this can match the argument types. Note that even a true return 139 * does not guarantee that the function can be successfully called with those arguments, merely 140 * indicates that an attempt should be made. If false is returned, the state of 141 * outParameterTypes and outReturnType are undefined. 142 * 143 * This always assumes narrowing conversions are *allowed*. The calling code needs to verify 144 * that each argument can actually be coerced to the final parameter type, respecting the 145 * narrowing-conversions flag. This is handled in callCost(), or in convertCall() (via coerce). 146 */ 147 using ParamTypes = skia_private::STArray<8, const Type*>; 148 bool determineFinalTypes(const ExpressionArray& arguments, 149 ParamTypes* outParameterTypes, 150 const Type** outReturnType) const; 151 152 private: 153 const FunctionDefinition* fDefinition; 154 FunctionDeclaration* fNextOverload = nullptr; 155 skia_private::TArray<Variable*> fParameters; 156 const Type* fReturnType = nullptr; 157 ModifierFlags fModifierFlags; 158 mutable IntrinsicKind fIntrinsicKind = kNotIntrinsic; 159 bool fBuiltin = false; 160 bool fIsMain = false; 161 bool fHasMainCoordsParameter = false; 162 bool fHasMainInputColorParameter = false; 163 bool fHasMainDestColorParameter = false; 164 165 using INHERITED = Symbol; 166 }; 167 168 } // namespace SkSL 169 170 #endif 171