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