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 "src/sksl/ir/SkSLIRNode.h"
12 #include "src/sksl/ir/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