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 "include/private/SkSLIRNode.h" 12 #include "include/sksl/SkSLPosition.h" 13 #include "src/sksl/ir/SkSLExpression.h" 14 #include "src/sksl/ir/SkSLType.h" 15 16 #include <cstddef> 17 #include <cstdint> 18 #include <memory> 19 #include <string> 20 #include <string_view> 21 #include <utility> 22 #include <vector> 23 24 namespace SkSL { 25 26 class Context; 27 class SymbolTable; 28 enum class OperatorPrecedence : uint8_t; 29 30 enum class FieldAccessOwnerKind : int8_t { 31 kDefault, 32 // this field access is to a field of an anonymous interface block (and thus, the field name 33 // is actually in global scope, so only the field name needs to be written in GLSL) 34 kAnonymousInterfaceBlock 35 }; 36 37 /** 38 * An expression which extracts a field from a struct, as in 'foo.bar'. 39 */ 40 class FieldAccess final : public Expression { 41 public: 42 using OwnerKind = FieldAccessOwnerKind; 43 44 inline static constexpr Kind kIRNodeKind = Kind::kFieldAccess; 45 46 FieldAccess(Position pos, std::unique_ptr<Expression> base, int fieldIndex, 47 OwnerKind ownerKind = OwnerKind::kDefault) 48 : INHERITED(pos, kIRNodeKind, base->type().fields()[fieldIndex].fType) 49 , fFieldIndex(fieldIndex) 50 , fOwnerKind(ownerKind) 51 , fBase(std::move(base)) {} 52 53 // Returns a field-access expression; reports errors via the ErrorReporter. 54 static std::unique_ptr<Expression> Convert(const Context& context, 55 Position pos, 56 SymbolTable& symbolTable, 57 std::unique_ptr<Expression> base, 58 std::string_view field); 59 60 // Returns a field-access expression; reports errors via ASSERT. 61 static std::unique_ptr<Expression> Make(const Context& context, 62 Position pos, 63 std::unique_ptr<Expression> base, 64 int fieldIndex, 65 OwnerKind ownerKind = OwnerKind::kDefault); 66 base()67 std::unique_ptr<Expression>& base() { 68 return fBase; 69 } 70 base()71 const std::unique_ptr<Expression>& base() const { 72 return fBase; 73 } 74 fieldIndex()75 int fieldIndex() const { 76 return fFieldIndex; 77 } 78 ownerKind()79 OwnerKind ownerKind() const { 80 return fOwnerKind; 81 } 82 clone(Position pos)83 std::unique_ptr<Expression> clone(Position pos) const override { 84 return std::make_unique<FieldAccess>(pos, 85 this->base()->clone(), 86 this->fieldIndex(), 87 this->ownerKind()); 88 } 89 90 size_t initialSlot() const; 91 92 std::string description(OperatorPrecedence) const override; 93 94 private: 95 int fFieldIndex; 96 FieldAccessOwnerKind fOwnerKind; 97 std::unique_ptr<Expression> fBase; 98 99 using INHERITED = Expression; 100 }; 101 102 } // namespace SkSL 103 104 #endif 105