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_INTLITERAL
9 #define SKSL_INTLITERAL
10 
11 #include "src/sksl/SkSLContext.h"
12 #include "src/sksl/ir/SkSLExpression.h"
13 
14 namespace SkSL {
15 
16 /**
17  * A literal integer. These are generally referred to as IntLiteral, but Literal<SKSL_INT> is
18  * also available for use with template code.
19  */
20 template <typename T> class Literal;
21 using IntLiteral = Literal<SKSL_INT>;
22 
23 template <>
24 class Literal<SKSL_INT> final : public Expression {
25 public:
26     static constexpr Kind kExpressionKind = Kind::kIntLiteral;
27 
28     // We will need to revisit this if we want full support for unsigned 64-bit integers,
29     // but for now an SKSL_INT (int64_t) will hold every value we care about.
Literal(int offset,SKSL_INT value,const Type * type)30     Literal(int offset, SKSL_INT value, const Type* type)
31         : INHERITED(offset, kExpressionKind, type)
32         , fValue(value) {}
33 
34     // Makes a literal of $intLiteral type.
Make(const Context & context,int offset,SKSL_INT value)35     static std::unique_ptr<IntLiteral> Make(const Context& context, int offset, SKSL_INT value) {
36         return std::make_unique<IntLiteral>(offset, value, context.fTypes.fIntLiteral.get());
37     }
38 
39     // Makes a literal of the specified integer type.
Make(int offset,SKSL_INT value,const Type * type)40     static std::unique_ptr<IntLiteral> Make(int offset, SKSL_INT value, const Type* type) {
41         SkASSERT(type->isInteger() || type->isEnum());
42         return std::make_unique<IntLiteral>(offset, value, type);
43     }
44 
value()45     SKSL_INT value() const {
46         return fValue;
47     }
48 
description()49     String description() const override {
50         return to_string(this->value());
51     }
52 
hasProperty(Property property)53     bool hasProperty(Property property) const override {
54         return false;
55     }
56 
isCompileTimeConstant()57     bool isCompileTimeConstant() const override {
58         return true;
59     }
60 
compareConstant(const Expression & other)61     ComparisonResult compareConstant(const Expression& other) const override {
62         if (!other.is<IntLiteral>()) {
63             return ComparisonResult::kUnknown;
64         }
65         return this->value() == other.as<IntLiteral>().value() ? ComparisonResult::kEqual
66                                                                : ComparisonResult::kNotEqual;
67     }
68 
coercionCost(const Type & target)69     CoercionCost coercionCost(const Type& target) const override {
70         if (target.isSigned() || target.isUnsigned() || target.isFloat() || target.isEnum()) {
71             return CoercionCost::Free();
72         }
73         return INHERITED::coercionCost(target);
74     }
75 
clone()76     std::unique_ptr<Expression> clone() const override {
77         return std::make_unique<IntLiteral>(fOffset, this->value(), &this->type());
78     }
79 
getConstantSubexpression(int n)80     const Expression* getConstantSubexpression(int n) const override {
81         SkASSERT(n == 0);
82         return this;
83     }
84 
85 private:
86     SKSL_INT fValue;
87 
88     using INHERITED = Expression;
89 };
90 
91 }  // namespace SkSL
92 
93 #endif
94