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_SYMBOL 9 #define SKSL_SYMBOL 10 11 #include "include/private/SkSLIRNode.h" 12 #include "include/private/SkSLProgramElement.h" 13 14 namespace SkSL { 15 16 /** 17 * Represents a symboltable entry. 18 */ 19 class Symbol : public IRNode { 20 public: 21 enum class Kind { 22 kExternal = (int) ProgramElement::Kind::kLast + 1, 23 kField, 24 kFunctionDeclaration, 25 kSymbolAlias, 26 kType, 27 kUnresolvedFunction, 28 kVariable, 29 30 kFirst = kExternal, 31 kLast = kVariable 32 }; 33 34 Symbol(int offset, Kind kind, StringFragment name, const Type* type = nullptr) 35 : INHERITED(offset, (int) kind) 36 , fName(name) 37 , fType(type) { 38 SkASSERT(kind >= Kind::kFirst && kind <= Kind::kLast); 39 } 40 ~Symbol()41 ~Symbol() override {} 42 type()43 const Type& type() const { 44 SkASSERT(fType); 45 return *fType; 46 } 47 kind()48 Kind kind() const { 49 return (Kind) fKind; 50 } 51 name()52 StringFragment name() const { 53 return fName; 54 } 55 56 /** 57 * Use is<T> to check the type of a symbol. 58 * e.g. replace `sym.kind() == Symbol::Kind::kVariable` with `sym.is<Variable>()`. 59 */ 60 template <typename T> is()61 bool is() const { 62 return this->kind() == T::kSymbolKind; 63 } 64 65 /** 66 * Use as<T> to downcast symbols. e.g. replace `(Variable&) sym` with `sym.as<Variable>()`. 67 */ 68 template <typename T> as()69 const T& as() const { 70 SkASSERT(this->is<T>()); 71 return static_cast<const T&>(*this); 72 } 73 74 template <typename T> as()75 T& as() { 76 SkASSERT(this->is<T>()); 77 return static_cast<T&>(*this); 78 } 79 80 private: 81 StringFragment fName; 82 const Type* fType; 83 84 using INHERITED = IRNode; 85 86 friend class Type; 87 }; 88 89 } // namespace SkSL 90 91 #endif 92