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_FIELDACCESS
9 #define SKSL_FIELDACCESS
10 
11 #include "src/sksl/SkSLUtil.h"
12 #include "src/sksl/ir/SkSLExpression.h"
13 
14 namespace SkSL {
15 
16 enum class FieldAccessOwnerKind : int8_t {
17     kDefault,
18     // this field access is to a field of an anonymous interface block (and thus, the field name
19     // is actually in global scope, so only the field name needs to be written in GLSL)
20     kAnonymousInterfaceBlock
21 };
22 
23 /**
24  * An expression which extracts a field from a struct, as in 'foo.bar'.
25  */
26 class FieldAccess final : public Expression {
27 public:
28     using OwnerKind = FieldAccessOwnerKind;
29 
30     static constexpr Kind kExpressionKind = Kind::kFieldAccess;
31 
32     FieldAccess(std::unique_ptr<Expression> base, int fieldIndex,
33                 OwnerKind ownerKind = OwnerKind::kDefault)
34     : INHERITED(base->fOffset, kExpressionKind, base->type().fields()[fieldIndex].fType)
35     , fFieldIndex(fieldIndex)
36     , fOwnerKind(ownerKind)
37     , fBase(std::move(base)) {}
38 
base()39     std::unique_ptr<Expression>& base() {
40         return fBase;
41     }
42 
base()43     const std::unique_ptr<Expression>& base() const {
44         return fBase;
45     }
46 
fieldIndex()47     int fieldIndex() const {
48         return fFieldIndex;
49     }
50 
ownerKind()51     OwnerKind ownerKind() const {
52         return fOwnerKind;
53     }
54 
hasProperty(Property property)55     bool hasProperty(Property property) const override {
56         return this->base()->hasProperty(property);
57     }
58 
clone()59     std::unique_ptr<Expression> clone() const override {
60         return std::unique_ptr<Expression>(new FieldAccess(this->base()->clone(),
61                                                            this->fieldIndex(),
62                                                            this->ownerKind()));
63     }
64 
description()65     String description() const override {
66         return this->base()->description() + "." +
67                this->base()->type().fields()[this->fieldIndex()].fName;
68     }
69 
70 private:
71     int fFieldIndex;
72     FieldAccessOwnerKind fOwnerKind;
73     std::unique_ptr<Expression> fBase;
74 
75     using INHERITED = Expression;
76 };
77 
78 }  // namespace SkSL
79 
80 #endif
81