blob: b0434e68f41a5cc1694e26bc8a514ca1e72f7dcb [file] [log] [blame]
ethannicholasb3058bd2016-07-01 08:22:01 -07001/*
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 */
Ethan Nicholas0df1b042017-03-31 13:56:23 -04007
ethannicholasb3058bd2016-07-01 08:22:01 -07008#ifndef SKSL_SYMBOLTABLE
9#define SKSL_SYMBOLTABLE
10
Ethan Nicholasdaed2592021-03-04 14:30:25 -050011#include "include/private/SkSLString.h"
Ethan Nicholas24c17722021-03-09 13:10:59 -050012#include "include/private/SkSLSymbol.h"
John Stiles6bef6a72020-12-02 14:26:04 -050013#include "include/private/SkTArray.h"
John Stilesefe767d2020-10-09 12:48:04 -040014#include "include/private/SkTHash.h"
Ethan Nicholas4a5e22a2021-08-13 17:29:51 -040015#include "include/sksl/SkSLErrorReporter.h"
ethannicholasb3058bd2016-07-01 08:22:01 -070016
John Stilesbf9dff62021-04-21 09:55:09 -040017#include <forward_list>
John Stilesefe767d2020-10-09 12:48:04 -040018#include <memory>
19#include <vector>
20
ethannicholasb3058bd2016-07-01 08:22:01 -070021namespace SkSL {
22
Ethan Nicholased84b732020-10-08 11:45:44 -040023class FunctionDeclaration;
ethannicholasd598f792016-07-25 10:08:54 -070024
ethannicholasb3058bd2016-07-01 08:22:01 -070025/**
26 * Maps identifiers to symbols. Functions, in particular, are mapped to either FunctionDeclaration
27 * or UnresolvedFunction depending on whether they are overloaded or not.
28 */
29class SymbolTable {
30public:
Ethan Nicholasc7774a72021-08-27 15:34:05 -040031 SymbolTable(const Context& context, bool builtin)
John Stiles7c3515b2020-10-16 18:38:39 -040032 : fBuiltin(builtin)
Ethan Nicholasc7774a72021-08-27 15:34:05 -040033 , fContext(context) {}
ethannicholasb3058bd2016-07-01 08:22:01 -070034
John Stiles7c3515b2020-10-16 18:38:39 -040035 SymbolTable(std::shared_ptr<SymbolTable> parent, bool builtin)
ethannicholasb3058bd2016-07-01 08:22:01 -070036 : fParent(parent)
John Stiles7c3515b2020-10-16 18:38:39 -040037 , fBuiltin(builtin)
Ethan Nicholasc7774a72021-08-27 15:34:05 -040038 , fContext(parent->fContext) {}
ethannicholasb3058bd2016-07-01 08:22:01 -070039
John Stiles6a1a98c2021-01-14 18:35:34 -050040 /**
41 * If the input is a built-in symbol table, returns a new empty symbol table as a child of the
42 * input table. If the input is not a built-in symbol table, returns it as-is. Built-in symbol
43 * tables must not be mutated after creation, so they must be wrapped if mutation is necessary.
44 */
John Stiles82f373c2020-10-20 13:58:05 -040045 static std::shared_ptr<SymbolTable> WrapIfBuiltin(std::shared_ptr<SymbolTable> symbolTable) {
46 if (!symbolTable) {
47 return nullptr;
48 }
49 if (!symbolTable->isBuiltin()) {
50 return symbolTable;
51 }
52 return std::make_shared<SymbolTable>(std::move(symbolTable), /*builtin=*/false);
53 }
54
John Stiles2630ea32020-12-04 10:51:21 -050055 /**
56 * Looks up the requested symbol and returns it. If a function has overloads, an
57 * UnresolvedFunction symbol (pointing to all of the candidates) will be added to the symbol
58 * table and returned.
59 */
Ethan Nicholas962dec42021-06-10 13:06:39 -040060 const Symbol* operator[](skstd::string_view name);
ethannicholasb3058bd2016-07-01 08:22:01 -070061
John Stiles6a1a98c2021-01-14 18:35:34 -050062 /**
63 * Creates a new name for a symbol which already exists; does not take ownership of Symbol*.
64 */
Ethan Nicholas962dec42021-06-10 13:06:39 -040065 void addAlias(skstd::string_view name, const Symbol* symbol);
John Stiles6a1a98c2021-01-14 18:35:34 -050066
Brian Osman5bf3e202020-10-13 10:34:18 -040067 void addWithoutOwnership(const Symbol* symbol);
ethannicholasd598f792016-07-25 10:08:54 -070068
John Stiles3ae071e2020-08-05 15:29:29 -040069 template <typename T>
Brian Osman5bf3e202020-10-13 10:34:18 -040070 const T* add(std::unique_ptr<T> symbol) {
71 const T* ptr = symbol.get();
John Stilesb8cc6652020-10-08 09:12:07 -040072 this->addWithoutOwnership(ptr);
John Stiles311dd9d2020-08-13 17:09:29 -040073 this->takeOwnershipOfSymbol(std::move(symbol));
74 return ptr;
75 }
76
77 template <typename T>
Brian Osman5bf3e202020-10-13 10:34:18 -040078 const T* takeOwnershipOfSymbol(std::unique_ptr<T> symbol) {
79 const T* ptr = symbol.get();
John Stiles3ae071e2020-08-05 15:29:29 -040080 fOwnedSymbols.push_back(std::move(symbol));
81 return ptr;
82 }
ethannicholasb3058bd2016-07-01 08:22:01 -070083
John Stiles3ae071e2020-08-05 15:29:29 -040084 template <typename T>
Brian Osman5bf3e202020-10-13 10:34:18 -040085 const T* takeOwnershipOfIRNode(std::unique_ptr<T> node) {
86 const T* ptr = node.get();
John Stiles3ae071e2020-08-05 15:29:29 -040087 fOwnedNodes.push_back(std::move(node));
88 return ptr;
89 }
Ethan Nicholasaae47c82017-11-10 15:34:03 -050090
John Stiles6bef6a72020-12-02 14:26:04 -050091 /**
John Stilesa2179502020-12-03 14:37:57 -050092 * Given type = `float` and arraySize = 5, creates the array type `float[5]` in the symbol
Brian Osmanb42c3832021-08-27 15:19:03 -040093 * table. The created array type is returned. If zero is passed, the base type is returned
94 * unchanged.
John Stiles6bef6a72020-12-02 14:26:04 -050095 */
John Stilesa2179502020-12-03 14:37:57 -050096 const Type* addArrayDimension(const Type* type, int arraySize);
John Stiles6bef6a72020-12-02 14:26:04 -050097
John Stilesefe767d2020-10-09 12:48:04 -040098 // Call fn for every symbol in the table. You may not mutate anything.
99 template <typename Fn>
100 void foreach(Fn&& fn) const {
101 fSymbols.foreach(
102 [&fn](const SymbolKey& key, const Symbol* symbol) { fn(key.fName, symbol); });
103 }
104
105 size_t count() {
106 return fSymbols.count();
107 }
108
John Stiles2630ea32020-12-04 10:51:21 -0500109 /** Returns true if this is a built-in SymbolTable. */
John Stiles7c3515b2020-10-16 18:38:39 -0400110 bool isBuiltin() const {
111 return fBuiltin;
112 }
113
John Stilesd51c9792021-03-18 11:40:14 -0400114 const String* takeOwnershipOfString(String n);
Ethan Nicholas70728ef2020-05-28 07:09:00 -0400115
Brian Osman1313d1a2020-09-08 10:34:30 -0400116 std::shared_ptr<SymbolTable> fParent;
ethannicholasb3058bd2016-07-01 08:22:01 -0700117
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400118 std::vector<std::unique_ptr<const Symbol>> fOwnedSymbols;
119
ethannicholasb3058bd2016-07-01 08:22:01 -0700120private:
John Stilesefe767d2020-10-09 12:48:04 -0400121 struct SymbolKey {
Ethan Nicholas962dec42021-06-10 13:06:39 -0400122 skstd::string_view fName;
John Stilesefe767d2020-10-09 12:48:04 -0400123 uint32_t fHash;
124
125 bool operator==(const SymbolKey& that) const { return fName == that.fName; }
126 bool operator!=(const SymbolKey& that) const { return fName != that.fName; }
127 struct Hash {
128 uint32_t operator()(const SymbolKey& key) const { return key.fHash; }
129 };
130 };
131
Ethan Nicholas962dec42021-06-10 13:06:39 -0400132 static SymbolKey MakeSymbolKey(skstd::string_view name) {
John Stilesefe767d2020-10-09 12:48:04 -0400133 return SymbolKey{name, SkOpts::hash_fn(name.data(), name.size(), 0)};
134 }
135
John Stilesbcd1fc02020-10-16 18:39:13 -0400136 const Symbol* lookup(SymbolTable* writableSymbolTable, const SymbolKey& key);
John Stiles6a1a98c2021-01-14 18:35:34 -0500137
ethannicholasd598f792016-07-25 10:08:54 -0700138 static std::vector<const FunctionDeclaration*> GetFunctions(const Symbol& s);
ethannicholasb3058bd2016-07-01 08:22:01 -0700139
John Stiles7c3515b2020-10-16 18:38:39 -0400140 bool fBuiltin = false;
Ethan Nicholasaae47c82017-11-10 15:34:03 -0500141 std::vector<std::unique_ptr<IRNode>> fOwnedNodes;
John Stilesbf9dff62021-04-21 09:55:09 -0400142 std::forward_list<String> fOwnedStrings;
Brian Osman5bf3e202020-10-13 10:34:18 -0400143 SkTHashMap<SymbolKey, const Symbol*, SymbolKey::Hash> fSymbols;
Ethan Nicholasc7774a72021-08-27 15:34:05 -0400144 const Context& fContext;
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400145
146 friend class Dehydrator;
ethannicholasb3058bd2016-07-01 08:22:01 -0700147};
148
John Stilesa6841be2020-08-06 14:11:56 -0400149} // namespace SkSL
ethannicholasb3058bd2016-07-01 08:22:01 -0700150
151#endif