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

#include <SkSLTernaryExpression.h>

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

Public Member Functions

 TernaryExpression (Position pos, std::unique_ptr< Expression > test, std::unique_ptr< Expression > ifTrue, std::unique_ptr< Expression > ifFalse)
 
std::unique_ptr< Expression > & test ()
 
const std::unique_ptr< Expression > & test () const
 
std::unique_ptr< Expression > & ifTrue ()
 
const std::unique_ptr< Expression > & ifTrue () const
 
std::unique_ptr< Expression > & ifFalse ()
 
const std::unique_ptr< Expression > & ifFalse () const
 
std::unique_ptr< Expressionclone (Position pos) const override
 
std::string description (OperatorPrecedence parentPrecedence) const override
 
- 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 > test, std::unique_ptr< Expression > ifTrue, std::unique_ptr< Expression > ifFalse)
 
static std::unique_ptr< ExpressionMake (const Context &context, Position pos, std::unique_ptr< Expression > test, std::unique_ptr< Expression > ifTrue, std::unique_ptr< Expression > ifFalse)
 
- 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::kTernary
 

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 ternary expression (test ? ifTrue : ifFalse).

Definition at line 30 of file SkSLTernaryExpression.h.

Constructor & Destructor Documentation

◆ TernaryExpression()

SkSL::TernaryExpression::TernaryExpression ( Position  pos,
std::unique_ptr< Expression test,
std::unique_ptr< Expression ifTrue,
std::unique_ptr< Expression ifFalse 
)
inline

Definition at line 34 of file SkSLTernaryExpression.h.

36 : INHERITED(pos, kIRNodeKind, &ifTrue->type())
37 , fTest(std::move(test))
38 , fIfTrue(std::move(ifTrue))
39 , fIfFalse(std::move(ifFalse)) {
40 SkASSERT(this->ifTrue()->type().matches(this->ifFalse()->type()));
41 }
SkPoint pos
#define SkASSERT(cond)
Definition SkAssert.h:116
virtual const Type & type() const
std::unique_ptr< Expression > & ifTrue()
std::unique_ptr< Expression > & ifFalse()
static constexpr Kind kIRNodeKind

Member Function Documentation

◆ clone()

std::unique_ptr< Expression > SkSL::TernaryExpression::clone ( Position  pos) const
inlineoverridevirtual

Implements SkSL::Expression.

Definition at line 82 of file SkSLTernaryExpression.h.

82 {
83 return std::make_unique<TernaryExpression>(pos, this->test()->clone(),
84 this->ifTrue()->clone(),
85 this->ifFalse()->clone());
86 }
std::unique_ptr< Expression > clone() const
std::unique_ptr< Expression > & test()

◆ Convert()

std::unique_ptr< Expression > SkSL::TernaryExpression::Convert ( const Context context,
Position  pos,
std::unique_ptr< Expression test,
std::unique_ptr< Expression ifTrue,
std::unique_ptr< Expression ifFalse 
)
static

Definition at line 24 of file SkSLTernaryExpression.cpp.

28 {
29 test = context.fTypes.fBool->coerceExpression(std::move(test), context);
30 if (!test || !ifTrue || !ifFalse) {
31 return nullptr;
32 }
33 if (ifTrue->type().componentType().isOpaque()) {
34 context.fErrors->error(pos, "ternary expression of opaque type '" +
35 ifTrue->type().displayName() + "' is not allowed");
36 return nullptr;
37 }
38 const Type* trueType;
39 const Type* falseType;
40 const Type* resultType;
41 Operator equalityOp(Operator::Kind::EQEQ);
42 if (!equalityOp.determineBinaryType(context, ifTrue->type(), ifFalse->type(),
43 &trueType, &falseType, &resultType) ||
44 !trueType->matches(*falseType)) {
45 Position errorPos = ifTrue->fPosition.rangeThrough(ifFalse->fPosition);
46 if (ifTrue->type().isVoid()) {
47 context.fErrors->error(errorPos, "ternary expression of type 'void' is not allowed");
48 } else {
49 context.fErrors->error(errorPos, "ternary operator result mismatch: '" +
50 ifTrue->type().displayName() + "', '" +
51 ifFalse->type().displayName() + "'");
52 }
53 return nullptr;
54 }
55 if (trueType->isOrContainsArray()) {
56 context.fErrors->error(pos, "ternary operator result may not be an array (or struct "
57 "containing an array)");
58 return nullptr;
59 }
60 ifTrue = trueType->coerceExpression(std::move(ifTrue), context);
61 if (!ifTrue) {
62 return nullptr;
63 }
64 ifFalse = falseType->coerceExpression(std::move(ifFalse), context);
65 if (!ifFalse) {
66 return nullptr;
67 }
68 return TernaryExpression::Make(context, pos, std::move(test), std::move(ifTrue),
69 std::move(ifFalse));
70}
static std::unique_ptr< Expression > Make(const Context &context, Position pos, std::unique_ptr< Expression > test, std::unique_ptr< Expression > ifTrue, std::unique_ptr< Expression > ifFalse)

◆ description()

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

Implements SkSL::Expression.

Definition at line 139 of file SkSLTernaryExpression.cpp.

139 {
140 bool needsParens = (OperatorPrecedence::kTernary >= parentPrecedence);
141 return std::string(needsParens ? "(" : "") +
142 this->test()->description(OperatorPrecedence::kTernary) + " ? " +
143 this->ifTrue()->description(OperatorPrecedence::kTernary) + " : " +
145 std::string(needsParens ? ")" : "");
146}
std::string description() const final
OperatorPrecedence
Definition ref_ptr.h:256

◆ ifFalse() [1/2]

std::unique_ptr< Expression > & SkSL::TernaryExpression::ifFalse ( )
inline

Definition at line 74 of file SkSLTernaryExpression.h.

74 {
75 return fIfFalse;
76 }

◆ ifFalse() [2/2]

const std::unique_ptr< Expression > & SkSL::TernaryExpression::ifFalse ( ) const
inline

Definition at line 78 of file SkSLTernaryExpression.h.

78 {
79 return fIfFalse;
80 }

◆ ifTrue() [1/2]

std::unique_ptr< Expression > & SkSL::TernaryExpression::ifTrue ( )
inline

Definition at line 66 of file SkSLTernaryExpression.h.

66 {
67 return fIfTrue;
68 }

◆ ifTrue() [2/2]

const std::unique_ptr< Expression > & SkSL::TernaryExpression::ifTrue ( ) const
inline

Definition at line 70 of file SkSLTernaryExpression.h.

70 {
71 return fIfTrue;
72 }

◆ Make()

std::unique_ptr< Expression > SkSL::TernaryExpression::Make ( const Context context,
Position  pos,
std::unique_ptr< Expression test,
std::unique_ptr< Expression ifTrue,
std::unique_ptr< Expression ifFalse 
)
static

Definition at line 72 of file SkSLTernaryExpression.cpp.

76 {
77 SkASSERT(ifTrue->type().matches(ifFalse->type()));
78 SkASSERT(!ifTrue->type().componentType().isOpaque());
79 SkASSERT(!context.fConfig->strictES2Mode() || !ifTrue->type().isOrContainsArray());
80
82 if (testExpr->isBoolLiteral()) {
83 // static boolean test, just return one of the branches
84 if (testExpr->as<Literal>().boolValue()) {
85 ifTrue->fPosition = pos;
86 return ifTrue;
87 } else {
88 ifFalse->fPosition = pos;
89 return ifFalse;
90 }
91 }
92
93 if (context.fConfig->fSettings.fOptimize) {
96
97 // A ternary with matching true- and false-cases does not need to branch.
98 if (Analysis::IsSameExpressionTree(*ifTrueExpr, *ifFalseExpr)) {
99 // If `test` has no side-effects, we can eliminate it too, and just return `ifTrue`.
101 ifTrue->fPosition = pos;
102 return ifTrue;
103 }
104 // Return a comma-expression containing `(test, ifTrue)`.
105 return BinaryExpression::Make(context, pos, std::move(test),
106 Operator::Kind::COMMA, std::move(ifTrue));
107 }
108
109 // A ternary of the form `test ? expr : false` can be simplified to `test && expr`.
110 if (ifFalseExpr->isBoolLiteral() && !ifFalseExpr->as<Literal>().boolValue()) {
111 return BinaryExpression::Make(context, pos, std::move(test),
112 Operator::Kind::LOGICALAND, std::move(ifTrue));
113 }
114
115 // A ternary of the form `test ? true : expr` can be simplified to `test || expr`.
116 if (ifTrueExpr->isBoolLiteral() && ifTrueExpr->as<Literal>().boolValue()) {
117 return BinaryExpression::Make(context, pos, std::move(test),
118 Operator::Kind::LOGICALOR, std::move(ifFalse));
119 }
120
121 // A ternary of the form `test ? false : true` can be simplified to `!test`.
122 if (ifTrueExpr->isBoolLiteral() && !ifTrueExpr->as<Literal>().boolValue() &&
123 ifFalseExpr->isBoolLiteral() && ifFalseExpr->as<Literal>().boolValue()) {
124 return PrefixExpression::Make(context, pos, Operator::Kind::LOGICALNOT,
125 std::move(test));
126 }
127
128 // A ternary of the form `test ? 1 : 0` can be simplified to `cast(test)`.
129 if (ifTrueExpr->is<Literal>() && ifTrueExpr->as<Literal>().value() == 1.0 &&
130 ifFalseExpr->is<Literal>() && ifFalseExpr->as<Literal>().value() == 0.0) {
131 return ConstructorScalarCast::Make(context, pos, ifTrue->type(), std::move(test));
132 }
133 }
134
135 return std::make_unique<TernaryExpression>(pos, std::move(test), std::move(ifTrue),
136 std::move(ifFalse));
137}
static std::unique_ptr< Expression > Make(const Context &context, Position pos, std::unique_ptr< Expression > left, Operator op, std::unique_ptr< Expression > right)
static const Expression * GetConstantValueForVariable(const Expression &value)
static std::unique_ptr< Expression > Make(const Context &context, Position pos, const Type &type, std::unique_ptr< Expression > arg)
Expression(Position pos, Kind kind, const Type *type)
static std::unique_ptr< Expression > Make(const Context &context, Position pos, Operator op, std::unique_ptr< Expression > base)
bool IsSameExpressionTree(const Expression &left, const Expression &right)
bool HasSideEffects(const Expression &expr)

◆ test() [1/2]

std::unique_ptr< Expression > & SkSL::TernaryExpression::test ( )
inline

Definition at line 58 of file SkSLTernaryExpression.h.

58 {
59 return fTest;
60 }

◆ test() [2/2]

const std::unique_ptr< Expression > & SkSL::TernaryExpression::test ( ) const
inline

Definition at line 62 of file SkSLTernaryExpression.h.

62 {
63 return fTest;
64 }

Member Data Documentation

◆ kIRNodeKind

constexpr Kind SkSL::TernaryExpression::kIRNodeKind = Kind::kTernary
inlinestaticconstexpr

Definition at line 32 of file SkSLTernaryExpression.h.


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