• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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