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 kType, 26 kUnresolvedFunction, 27 kVariable, 28 29 kFirst = kExternal, 30 kLast = kVariable 31 }; 32 33 Symbol(int offset, Kind kind, std::string_view name, const Type* type = nullptr) 34 : INHERITED(offset, (int) kind) 35 , fName(name) 36 , fType(type) { 37 SkASSERT(kind >= Kind::kFirst && kind <= Kind::kLast); 38 } 39 ~Symbol()40 ~Symbol() override {} 41 type()42 const Type& type() const { 43 SkASSERT(fType); 44 return *fType; 45 } 46 kind()47 Kind kind() const { 48 return (Kind) fKind; 49 } 50 name()51 std::string_view name() const { 52 return fName; 53 } 54 55 /** 56 * Use is<T> to check the type of a symbol. 57 * e.g. replace `sym.kind() == Symbol::Kind::kVariable` with `sym.is<Variable>()`. 58 */ 59 template <typename T> is()60 bool is() const { 61 return this->kind() == T::kSymbolKind; 62 } 63 64 /** 65 * Use as<T> to downcast symbols. e.g. replace `(Variable&) sym` with `sym.as<Variable>()`. 66 */ 67 template <typename T> as()68 const T& as() const { 69 SkASSERT(this->is<T>()); 70 return static_cast<const T&>(*this); 71 } 72 73 template <typename T> as()74 T& as() { 75 SkASSERT(this->is<T>()); 76 return static_cast<T&>(*this); 77 } 78 79 private: 80 std::string_view fName; 81 const Type* fType; 82 83 using INHERITED = IRNode; 84 85 friend class Type; 86 }; 87 88 } // namespace SkSL 89 90 #endif 91