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
21namespace SkSL {
22
23class FunctionDefinition;
24
25// This enum holds every intrinsic supported by SkSL.
26#define SKSL_INTRINSIC(name) k_##name##_IntrinsicKind,
27enum IntrinsicKind : int8_t {
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 */
36class FunctionDeclaration final : public Symbol {
37public:
38    inline static constexpr Kind kSymbolKind = Kind::kFunctionDeclaration;
39
40    FunctionDeclaration(int line,
41                        const Modifiers* modifiers,
42                        skstd::string_view 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 line,
50                                              const Modifiers* modifiers,
51                                              skstd::string_view name,
52                                              std::vector<std::unique_ptr<Variable>> parameters,
53                                              const Type* returnType);
54
55    const Modifiers& modifiers() const {
56        return *fModifiers;
57    }
58
59    const FunctionDefinition* definition() const {
60        return fDefinition;
61    }
62
63    void setDefinition(const FunctionDefinition* definition) const {
64        fDefinition = definition;
65        fIntrinsicKind = kNotIntrinsic;
66    }
67
68    const std::vector<const Variable*>& parameters() const {
69        return fParameters;
70    }
71
72    const Type& returnType() const {
73        return *fReturnType;
74    }
75
76    bool isBuiltin() const {
77        return fBuiltin;
78    }
79
80    bool isMain() const {
81        return fIsMain;
82    }
83
84    IntrinsicKind intrinsicKind() const {
85        return fIntrinsicKind;
86    }
87
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
118private:
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    mutable IntrinsicKind fIntrinsicKind = kNotIntrinsic;
126
127    using INHERITED = Symbol;
128};
129
130}  // namespace SkSL
131
132#endif
133