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