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