Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Member Functions | Static Public Member Functions | Static Public Attributes | List of all members
SkSL::BinaryExpression Class Referencefinal

#include <SkSLBinaryExpression.h>

Inheritance diagram for SkSL::BinaryExpression:
SkSL::Expression SkSL::IRNode SkSL::Poolable

Public Member Functions

 BinaryExpression (Position pos, std::unique_ptr< Expression > left, Operator op, std::unique_ptr< Expression > right, const Type *type)
 
std::unique_ptr< Expression > & left ()
 
const std::unique_ptr< Expression > & left () const
 
std::unique_ptr< Expression > & right ()
 
const std::unique_ptr< Expression > & right () const
 
Operator getOperator () const
 
std::unique_ptr< Expressionclone (Position pos) const override
 
std::string description (OperatorPrecedence parentPrecedence) const override
 
VariableReferenceisAssignmentIntoVariable ()
 
- Public Member Functions inherited from SkSL::Expression
 Expression (Position pos, Kind kind, const Type *type)
 
Kind kind () const
 
virtual const Typetype () const
 
bool isAnyConstructor () const
 
bool isIntLiteral () const
 
bool isFloatLiteral () const
 
bool isBoolLiteral () const
 
AnyConstructorasAnyConstructor ()
 
const AnyConstructorasAnyConstructor () const
 
bool isIncomplete (const Context &context) const
 
virtual ComparisonResult compareConstant (const Expression &other) const
 
CoercionCost coercionCost (const Type &target) const
 
virtual bool supportsConstantValues () const
 
virtual std::optional< double > getConstantValue (int n) const
 
std::unique_ptr< Expressionclone () const
 
std::string description () const final
 
- Public Member Functions inherited from SkSL::IRNode
virtual ~IRNode ()
 
 IRNode (const IRNode &)=delete
 
IRNodeoperator= (const IRNode &)=delete
 
Position position () const
 
void setPosition (Position p)
 
template<typename T >
bool is () const
 
template<typename T >
const Tas () const
 
template<typename T >
Tas ()
 

Static Public Member Functions

static std::unique_ptr< ExpressionConvert (const Context &context, Position pos, std::unique_ptr< Expression > left, Operator op, std::unique_ptr< Expression > right)
 
static std::unique_ptr< ExpressionMake (const Context &context, Position pos, std::unique_ptr< Expression > left, Operator op, std::unique_ptr< Expression > right)
 
static std::unique_ptr< ExpressionMake (const Context &context, Position pos, std::unique_ptr< Expression > left, Operator op, std::unique_ptr< Expression > right, const Type *resultType)
 
- Static Public Member Functions inherited from SkSL::Poolable
static void * operator new (const size_t size)
 
static void operator delete (void *ptr)
 

Static Public Attributes

static constexpr Kind kIRNodeKind = Kind::kBinary
 

Additional Inherited Members

- Public Types inherited from SkSL::Expression
enum class  ComparisonResult { kUnknown = -1 , kNotEqual , kEqual }
 
using Kind = ExpressionKind
 
- Public Attributes inherited from SkSL::IRNode
Position fPosition
 
- Protected Member Functions inherited from SkSL::IRNode
 IRNode (Position position, int kind)
 
- Protected Attributes inherited from SkSL::IRNode
int fKind
 

Detailed Description

A binary operation.

Definition at line 30 of file SkSLBinaryExpression.h.

Constructor & Destructor Documentation

◆ BinaryExpression()

SkSL::BinaryExpression::BinaryExpression ( Position  pos,
std::unique_ptr< Expression left,
Operator  op,
std::unique_ptr< Expression right,
const Type type 
)
inline

Definition at line 34 of file SkSLBinaryExpression.h.

36 : INHERITED(pos, kIRNodeKind, type)
37 , fLeft(std::move(left))
38 , fOperator(op)
39 , fRight(std::move(right)) {
40 // If we are assigning to a VariableReference, ensure that it is set to Write or ReadWrite.
41 SkASSERT(!op.isAssignment() || CheckRef(*this->left()));
42 }
SkPoint pos
#define SkASSERT(cond)
Definition SkAssert.h:116
std::unique_ptr< Expression > & left()
std::unique_ptr< Expression > & right()
static constexpr Kind kIRNodeKind
virtual const Type & type() const

Member Function Documentation

◆ clone()

std::unique_ptr< Expression > SkSL::BinaryExpression::clone ( Position  pos) const
overridevirtual

Implements SkSL::Expression.

Definition at line 166 of file SkSLBinaryExpression.cpp.

166 {
167 return std::make_unique<BinaryExpression>(pos,
168 this->left()->clone(),
169 this->getOperator(),
170 this->right()->clone(),
171 &this->type());
172}
std::unique_ptr< Expression > clone() const

◆ Convert()

std::unique_ptr< Expression > SkSL::BinaryExpression::Convert ( const Context context,
Position  pos,
std::unique_ptr< Expression left,
Operator  op,
std::unique_ptr< Expression right 
)
static

Definition at line 24 of file SkSLBinaryExpression.cpp.

28 {
29 if (!left || !right) {
30 return nullptr;
31 }
32 const Type* rawLeftType = (left->isIntLiteral() && right->type().isInteger())
33 ? &right->type()
34 : &left->type();
35 const Type* rawRightType = (right->isIntLiteral() && left->type().isInteger())
36 ? &left->type()
37 : &right->type();
38
39 bool isAssignment = op.isAssignment();
40 if (isAssignment &&
42 op.kind() != Operator::Kind::EQ
43 ? VariableReference::RefKind::kReadWrite
44 : VariableReference::RefKind::kWrite,
45 context.fErrors)) {
46 return nullptr;
47 }
48
49 const Type* leftType;
50 const Type* rightType;
51 const Type* resultType;
52 if (!op.determineBinaryType(context, *rawLeftType, *rawRightType,
53 &leftType, &rightType, &resultType)) {
54 context.fErrors->error(pos, "type mismatch: '" + std::string(op.tightOperatorName()) +
55 "' cannot operate on '" + left->type().displayName() + "', '" +
56 right->type().displayName() + "'");
57 return nullptr;
58 }
59
60 if (isAssignment && (leftType->componentType().isOpaque() || leftType->isOrContainsAtomic())) {
61 context.fErrors->error(pos, "assignments to opaque type '" + left->type().displayName() +
62 "' are not permitted");
63 return nullptr;
64 }
65 if (context.fConfig->strictES2Mode() && !op.isAllowedInStrictES2Mode()) {
66 context.fErrors->error(pos, "operator '" + std::string(op.tightOperatorName()) +
67 "' is not allowed");
68 return nullptr;
69 }
70 if (context.fConfig->strictES2Mode() || op.kind() == OperatorKind::COMMA) {
71 // Most operators are already rejected on arrays, but GLSL ES 1.0 is very explicit that the
72 // *only* operator allowed on arrays is subscripting (and the rules against assignment,
73 // comparison, and even sequence apply to structs containing arrays as well).
74 // WebGL2 also restricts the usage of the sequence operator with arrays (section 5.26,
75 // "Disallowed variants of GLSL ES 3.00 operators"). Since there is very little practical
76 // application for sequenced array expressions, we disallow it in SkSL.
77 const Expression* arrayExpr = leftType->isOrContainsArray() ? left.get() :
78 rightType->isOrContainsArray() ? right.get() :
79 nullptr;
80 if (arrayExpr) {
81 context.fErrors->error(arrayExpr->position(),
82 "operator '" + std::string(op.tightOperatorName()) +
83 "' can not operate on arrays (or structs containing arrays)");
84 return nullptr;
85 }
86 }
87
88 left = leftType->coerceExpression(std::move(left), context);
89 right = rightType->coerceExpression(std::move(right), context);
90 if (!left || !right) {
91 return nullptr;
92 }
93
94 return BinaryExpression::Make(context, pos, std::move(left), op, std::move(right), resultType);
95}
static std::unique_ptr< Expression > Make(const Context &context, Position pos, std::unique_ptr< Expression > left, Operator op, std::unique_ptr< Expression > right)
Expression(Position pos, Kind kind, const Type *type)
bool UpdateVariableRefKind(Expression *expr, VariableRefKind kind, ErrorReporter *errors=nullptr)

◆ description()

std::string SkSL::BinaryExpression::description ( OperatorPrecedence  parentPrecedence) const
overridevirtual

Implements SkSL::Expression.

Definition at line 174 of file SkSLBinaryExpression.cpp.

174 {
175 OperatorPrecedence operatorPrecedence = this->getOperator().getBinaryPrecedence();
176 bool needsParens = (operatorPrecedence >= parentPrecedence);
177 return std::string(needsParens ? "(" : "") +
178 this->left()->description(operatorPrecedence) +
179 this->getOperator().operatorName() +
180 this->right()->description(operatorPrecedence) +
181 std::string(needsParens ? ")" : "");
182}
std::string description() const final
OperatorPrecedence getBinaryPrecedence() const
OperatorPrecedence
Definition ref_ptr.h:256

◆ getOperator()

Operator SkSL::BinaryExpression::getOperator ( ) const
inline

Definition at line 85 of file SkSLBinaryExpression.h.

85 {
86 return fOperator;
87 }

◆ isAssignmentIntoVariable()

VariableReference * SkSL::BinaryExpression::isAssignmentIntoVariable ( )

If the expression is an assignment like a = 1 or a += sin(b), returns the VariableReference that will be written to. For other types of expressions, returns null. Complex expressions that contain inner assignments, like (a = b) * 2, will return null.

Definition at line 184 of file SkSLBinaryExpression.cpp.

184 {
185 if (this->getOperator().isAssignment()) {
186 Analysis::AssignmentInfo assignmentInfo;
187 if (Analysis::IsAssignable(*this->left(), &assignmentInfo, /*errors=*/nullptr)) {
188 return assignmentInfo.fAssignedVar;
189 }
190 }
191 return nullptr;
192}
bool IsAssignable(Expression &expr, AssignmentInfo *info=nullptr, ErrorReporter *errors=nullptr)

◆ left() [1/2]

std::unique_ptr< Expression > & SkSL::BinaryExpression::left ( )
inline

Definition at line 69 of file SkSLBinaryExpression.h.

69 {
70 return fLeft;
71 }

◆ left() [2/2]

const std::unique_ptr< Expression > & SkSL::BinaryExpression::left ( ) const
inline

Definition at line 73 of file SkSLBinaryExpression.h.

73 {
74 return fLeft;
75 }

◆ Make() [1/2]

std::unique_ptr< Expression > SkSL::BinaryExpression::Make ( const Context context,
Position  pos,
std::unique_ptr< Expression left,
Operator  op,
std::unique_ptr< Expression right 
)
static

Definition at line 97 of file SkSLBinaryExpression.cpp.

101 {
102 // Determine the result type of the binary expression.
103 const Type* leftType;
104 const Type* rightType;
105 const Type* resultType;
106 SkAssertResult(op.determineBinaryType(context, left->type(), right->type(),
107 &leftType, &rightType, &resultType));
108
109 return BinaryExpression::Make(context, pos, std::move(left), op, std::move(right), resultType);
110}
#define SkAssertResult(cond)
Definition SkAssert.h:123

◆ Make() [2/2]

std::unique_ptr< Expression > SkSL::BinaryExpression::Make ( const Context context,
Position  pos,
std::unique_ptr< Expression left,
Operator  op,
std::unique_ptr< Expression right,
const Type resultType 
)
static

Definition at line 112 of file SkSLBinaryExpression.cpp.

117 {
118 // We should have detected non-ES2 compliant behavior in Convert.
119 SkASSERT(!context.fConfig->strictES2Mode() || op.isAllowedInStrictES2Mode());
120 SkASSERT(!context.fConfig->strictES2Mode() || !left->type().isOrContainsArray());
121
122 // We should have detected non-assignable assignment expressions in Convert.
123 SkASSERT(!op.isAssignment() || Analysis::IsAssignable(*left));
124 SkASSERT(!op.isAssignment() || !left->type().componentType().isOpaque());
125
126 // For simple assignments, detect and report out-of-range literal values.
127 if (op.kind() == Operator::Kind::EQ) {
128 left->type().checkForOutOfRangeLiteral(context, *right);
129 }
130
131 // Perform constant-folding on the expression.
132 if (std::unique_ptr<Expression> result = ConstantFolder::Simplify(context, pos, *left,
133 op, *right, *resultType)) {
134 return result;
135 }
136
137 return std::make_unique<BinaryExpression>(pos, std::move(left), op,
138 std::move(right), resultType);
139}
static std::unique_ptr< Expression > Simplify(const Context &context, Position pos, const Expression &left, Operator op, const Expression &right, const Type &resultType)
GAsyncResult * result

◆ right() [1/2]

std::unique_ptr< Expression > & SkSL::BinaryExpression::right ( )
inline

Definition at line 77 of file SkSLBinaryExpression.h.

77 {
78 return fRight;
79 }

◆ right() [2/2]

const std::unique_ptr< Expression > & SkSL::BinaryExpression::right ( ) const
inline

Definition at line 81 of file SkSLBinaryExpression.h.

81 {
82 return fRight;
83 }

Member Data Documentation

◆ kIRNodeKind

constexpr Kind SkSL::BinaryExpression::kIRNodeKind = Kind::kBinary
inlinestaticconstexpr

Definition at line 32 of file SkSLBinaryExpression.h.


The documentation for this class was generated from the following files: