1 // Copyright 2020 The Tint Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "src/symbol_table.h"
16
17 #include "src/debug.h"
18
19 namespace tint {
20
SymbolTable(tint::ProgramID program_id)21 SymbolTable::SymbolTable(tint::ProgramID program_id)
22 : program_id_(program_id) {}
23
24 SymbolTable::SymbolTable(const SymbolTable&) = default;
25
26 SymbolTable::SymbolTable(SymbolTable&&) = default;
27
28 SymbolTable::~SymbolTable() = default;
29
30 SymbolTable& SymbolTable::operator=(const SymbolTable& other) = default;
31
32 SymbolTable& SymbolTable::operator=(SymbolTable&&) = default;
33
Register(const std::string & name)34 Symbol SymbolTable::Register(const std::string& name) {
35 TINT_ASSERT(Symbol, !name.empty());
36
37 auto it = name_to_symbol_.find(name);
38 if (it != name_to_symbol_.end())
39 return it->second;
40
41 #if TINT_SYMBOL_STORE_DEBUG_NAME
42 Symbol sym(next_symbol_, program_id_, name);
43 #else
44 Symbol sym(next_symbol_, program_id_);
45 #endif
46 ++next_symbol_;
47
48 name_to_symbol_[name] = sym;
49 symbol_to_name_[sym] = name;
50
51 return sym;
52 }
53
Get(const std::string & name) const54 Symbol SymbolTable::Get(const std::string& name) const {
55 auto it = name_to_symbol_.find(name);
56 return it != name_to_symbol_.end() ? it->second : Symbol();
57 }
58
NameFor(const Symbol symbol) const59 std::string SymbolTable::NameFor(const Symbol symbol) const {
60 TINT_ASSERT_PROGRAM_IDS_EQUAL(Symbol, program_id_, symbol);
61 auto it = symbol_to_name_.find(symbol);
62 if (it == symbol_to_name_.end()) {
63 return symbol.to_str();
64 }
65
66 return it->second;
67 }
68
New(std::string prefix)69 Symbol SymbolTable::New(std::string prefix /* = "" */) {
70 if (prefix.empty()) {
71 prefix = "tint_symbol";
72 }
73 auto it = name_to_symbol_.find(prefix);
74 if (it == name_to_symbol_.end()) {
75 return Register(prefix);
76 }
77 std::string name;
78 size_t i = 1;
79 do {
80 name = prefix + "_" + std::to_string(i++);
81 } while (name_to_symbol_.count(name));
82 return Register(name);
83 }
84
85 } // namespace tint
86