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/private/SkSLModifiers.h"
12 #include "include/private/SkSLProgramKind.h"
13 #include "include/private/SkSLSymbol.h"
14 #include "include/private/SkTArray.h"
15 #include "src/sksl/SkSLIntrinsicList.h"
16 #include "src/sksl/ir/SkSLExpression.h"
17 #include "src/sksl/ir/SkSLSymbolTable.h"
18 #include "src/sksl/ir/SkSLType.h"
19 #include "src/sksl/ir/SkSLVariable.h"
20 
21 namespace SkSL {
22 
23 class FunctionDefinition;
24 
25 // This enum holds every intrinsic supported by SkSL.
26 #define SKSL_INTRINSIC(name) k_##name##_IntrinsicKind,
27 enum IntrinsicKind {
28     kNotIntrinsic = -1,
29     SKSL_INTRINSIC_LIST
30 };
31 #undef SKSL_INTRINSIC
32 
33 /**
34  * A function declaration (not a definition -- does not contain a body).
35  */
36 class FunctionDeclaration final : public Symbol {
37 public:
38     static constexpr Kind kSymbolKind = Kind::kFunctionDeclaration;
39 
40     FunctionDeclaration(int offset,
41                         const Modifiers* modifiers,
42                         StringFragment name,
43                         std::vector<const Variable*> parameters,
44                         const Type* returnType,
45                         bool builtin);
46 
47     static const FunctionDeclaration* Convert(const Context& context,
48                                               SymbolTable& symbols,
49                                               int offset,
50                                               const Modifiers* modifiers,
51                                               StringFragment name,
52                                               std::vector<std::unique_ptr<Variable>> parameters,
53                                               const Type* returnType,
54                                               bool isBuiltin);
55 
modifiers()56     const Modifiers& modifiers() const {
57         return *fModifiers;
58     }
59 
definition()60     const FunctionDefinition* definition() const {
61         return fDefinition;
62     }
63 
setDefinition(const FunctionDefinition * definition)64     void setDefinition(const FunctionDefinition* definition) const {
65         fDefinition = definition;
66     }
67 
parameters()68     const std::vector<const Variable*>& parameters() const {
69         return fParameters;
70     }
71 
returnType()72     const Type& returnType() const {
73         return *fReturnType;
74     }
75 
isBuiltin()76     bool isBuiltin() const {
77         return fBuiltin;
78     }
79 
isMain()80     bool isMain() const {
81         return fIsMain;
82     }
83 
intrinsicKind()84     IntrinsicKind intrinsicKind() const {
85         return fIntrinsicKind;
86     }
87 
isIntrinsic()88     bool isIntrinsic() const {
89         return this->intrinsicKind() != kNotIntrinsic;
90     }
91 
92     String mangledName() const;
93 
94     String description() const override;
95 
96     bool matches(const FunctionDeclaration& f) const;
97 
98     /**
99      * Determine the effective types of this function's parameters and return value when called with
100      * the given arguments. This is relevant for functions with generic parameter types, where this
101      * will collapse the generic types down into specific concrete types.
102      *
103      * Returns true if it was able to select a concrete set of types for the generic function, false
104      * if there is no possible way this can match the argument types. Note that even a true return
105      * does not guarantee that the function can be successfully called with those arguments, merely
106      * indicates that an attempt should be made. If false is returned, the state of
107      * outParameterTypes and outReturnType are undefined.
108      *
109      * This always assumes narrowing conversions are *allowed*. The calling code needs to verify
110      * that each argument can actually be coerced to the final parameter type, respecting the
111      * narrowing-conversions flag. This is handled in callCost(), or in convertCall() (via coerce).
112      */
113     using ParamTypes = SkSTArray<8, const Type*>;
114     bool determineFinalTypes(const ExpressionArray& arguments,
115                              ParamTypes* outParameterTypes,
116                              const Type** outReturnType) const;
117 
118 private:
119     mutable const FunctionDefinition* fDefinition;
120     const Modifiers* fModifiers;
121     std::vector<const Variable*> fParameters;
122     const Type* fReturnType;
123     bool fBuiltin;
124     bool fIsMain;
125     IntrinsicKind fIntrinsicKind = kNotIntrinsic;
126 
127     friend class SkSL::dsl::DSLFunction;
128 
129     using INHERITED = Symbol;
130 };
131 
132 }  // namespace SkSL
133 
134 #endif
135