xref: /aosp_15_r20/external/skia/src/sksl/ir/SkSLMethodReference.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2021 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #ifndef SKSL_METHODREFERENCE
9*c8dee2aaSAndroid Build Coastguard Worker #define SKSL_METHODREFERENCE
10*c8dee2aaSAndroid Build Coastguard Worker 
11*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLBuiltinTypes.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLContext.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/ir/SkSLExpression.h"
14*c8dee2aaSAndroid Build Coastguard Worker 
15*c8dee2aaSAndroid Build Coastguard Worker namespace SkSL {
16*c8dee2aaSAndroid Build Coastguard Worker 
17*c8dee2aaSAndroid Build Coastguard Worker class FunctionDeclaration;
18*c8dee2aaSAndroid Build Coastguard Worker 
19*c8dee2aaSAndroid Build Coastguard Worker /**
20*c8dee2aaSAndroid Build Coastguard Worker  * An identifier referring to a method name, along with an instance for the call.
21*c8dee2aaSAndroid Build Coastguard Worker  * This is an intermediate value: MethodReferences are always eventually replaced by FunctionCalls
22*c8dee2aaSAndroid Build Coastguard Worker  * in valid programs.
23*c8dee2aaSAndroid Build Coastguard Worker  *
24*c8dee2aaSAndroid Build Coastguard Worker  * Method calls are only supported on effect-child types, and they all resolve to intrinsics
25*c8dee2aaSAndroid Build Coastguard Worker  * prefixed with '$', and taking the 'self' object as the last parameter. For example:
26*c8dee2aaSAndroid Build Coastguard Worker  *
27*c8dee2aaSAndroid Build Coastguard Worker  *   uniform shader child;
28*c8dee2aaSAndroid Build Coastguard Worker  *   ...
29*c8dee2aaSAndroid Build Coastguard Worker  *   child.eval(xy)  -->  $eval(xy, child)
30*c8dee2aaSAndroid Build Coastguard Worker  */
31*c8dee2aaSAndroid Build Coastguard Worker class MethodReference final : public Expression {
32*c8dee2aaSAndroid Build Coastguard Worker public:
33*c8dee2aaSAndroid Build Coastguard Worker     inline static constexpr Kind kIRNodeKind = Kind::kMethodReference;
34*c8dee2aaSAndroid Build Coastguard Worker 
MethodReference(const Context & context,Position pos,std::unique_ptr<Expression> self,const FunctionDeclaration * overloadChain)35*c8dee2aaSAndroid Build Coastguard Worker     MethodReference(const Context& context,
36*c8dee2aaSAndroid Build Coastguard Worker                     Position pos,
37*c8dee2aaSAndroid Build Coastguard Worker                     std::unique_ptr<Expression> self,
38*c8dee2aaSAndroid Build Coastguard Worker                     const FunctionDeclaration* overloadChain)
39*c8dee2aaSAndroid Build Coastguard Worker             : INHERITED(pos, kIRNodeKind, context.fTypes.fInvalid.get())
40*c8dee2aaSAndroid Build Coastguard Worker             , fSelf(std::move(self))
41*c8dee2aaSAndroid Build Coastguard Worker             , fOverloadChain(overloadChain) {}
42*c8dee2aaSAndroid Build Coastguard Worker 
self()43*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Expression>& self() { return fSelf; }
self()44*c8dee2aaSAndroid Build Coastguard Worker     const std::unique_ptr<Expression>& self() const { return fSelf; }
45*c8dee2aaSAndroid Build Coastguard Worker 
overloadChain()46*c8dee2aaSAndroid Build Coastguard Worker     const FunctionDeclaration* overloadChain() const { return fOverloadChain; }
47*c8dee2aaSAndroid Build Coastguard Worker 
clone(Position pos)48*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Expression> clone(Position pos) const override {
49*c8dee2aaSAndroid Build Coastguard Worker         return std::unique_ptr<Expression>(new MethodReference(
50*c8dee2aaSAndroid Build Coastguard Worker                 pos, this->self()->clone(), this->overloadChain(), &this->type()));
51*c8dee2aaSAndroid Build Coastguard Worker     }
52*c8dee2aaSAndroid Build Coastguard Worker 
description(OperatorPrecedence)53*c8dee2aaSAndroid Build Coastguard Worker     std::string description(OperatorPrecedence) const override {
54*c8dee2aaSAndroid Build Coastguard Worker         return "<method>";
55*c8dee2aaSAndroid Build Coastguard Worker     }
56*c8dee2aaSAndroid Build Coastguard Worker 
57*c8dee2aaSAndroid Build Coastguard Worker private:
MethodReference(Position pos,std::unique_ptr<Expression> self,const FunctionDeclaration * overloadChain,const Type * type)58*c8dee2aaSAndroid Build Coastguard Worker     MethodReference(Position pos,
59*c8dee2aaSAndroid Build Coastguard Worker                     std::unique_ptr<Expression> self,
60*c8dee2aaSAndroid Build Coastguard Worker                     const FunctionDeclaration* overloadChain,
61*c8dee2aaSAndroid Build Coastguard Worker                     const Type* type)
62*c8dee2aaSAndroid Build Coastguard Worker             : INHERITED(pos, kIRNodeKind, type)
63*c8dee2aaSAndroid Build Coastguard Worker             , fSelf(std::move(self))
64*c8dee2aaSAndroid Build Coastguard Worker             , fOverloadChain(overloadChain) {}
65*c8dee2aaSAndroid Build Coastguard Worker 
66*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Expression> fSelf;
67*c8dee2aaSAndroid Build Coastguard Worker     const FunctionDeclaration* fOverloadChain;
68*c8dee2aaSAndroid Build Coastguard Worker 
69*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = Expression;
70*c8dee2aaSAndroid Build Coastguard Worker };
71*c8dee2aaSAndroid Build Coastguard Worker 
72*c8dee2aaSAndroid Build Coastguard Worker }  // namespace SkSL
73*c8dee2aaSAndroid Build Coastguard Worker 
74*c8dee2aaSAndroid Build Coastguard Worker #endif
75