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_PROGRAMELEMENT 9 #define SKSL_PROGRAMELEMENT 10 11 #include "include/private/SkSLIRNode.h" 12 13 #include <memory> 14 15 namespace SkSL { 16 17 /** 18 * Represents a top-level element (e.g. function or global variable) in a program. 19 */ 20 class ProgramElement : public IRNode { 21 public: 22 enum class Kind { 23 kEnum = 0, 24 kExtension, 25 kFunction, 26 kFunctionPrototype, 27 kGlobalVar, 28 kInterfaceBlock, 29 kModifiers, 30 kSection, 31 kStructDefinition, 32 33 kFirst = kEnum, 34 kLast = kStructDefinition 35 }; 36 ProgramElement(int offset,Kind kind)37 ProgramElement(int offset, Kind kind) 38 : INHERITED(offset, (int) kind) { 39 SkASSERT(kind >= Kind::kFirst && kind <= Kind::kLast); 40 } 41 kind()42 Kind kind() const { 43 return (Kind) fKind; 44 } 45 46 /** 47 * Use is<T> to check the type of a program element. 48 * e.g. replace `el.kind() == ProgramElement::Kind::kEnum` with `el.is<Enum>()`. 49 */ 50 template <typename T> is()51 bool is() const { 52 return this->kind() == T::kProgramElementKind; 53 } 54 55 /** 56 * Use as<T> to downcast program elements. e.g. replace `(Enum&) el` with `el.as<Enum>()`. 57 */ 58 template <typename T> as()59 const T& as() const { 60 SkASSERT(this->is<T>()); 61 return static_cast<const T&>(*this); 62 } 63 64 template <typename T> as()65 T& as() { 66 SkASSERT(this->is<T>()); 67 return static_cast<T&>(*this); 68 } 69 70 virtual std::unique_ptr<ProgramElement> clone() const = 0; 71 72 private: 73 using INHERITED = IRNode; 74 }; 75 76 } // namespace SkSL 77 78 #endif 79