blob: 4a1af1e2c38df2b5f5c6e1486f73d84da58fa436 [file] [log] [blame]
Ryan Harrisondbc13af2022-02-21 15:19:07 +00001// Copyright 2020 The Tint Authors. //
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14#ifndef SRC_TINT_SCOPE_STACK_H_
15#define SRC_TINT_SCOPE_STACK_H_
16
Ryan Harrisondbc13af2022-02-21 15:19:07 +000017#include <utility>
Ryan Harrisondbc13af2022-02-21 15:19:07 +000018
19#include "src/tint/symbol.h"
Ben Clayton94181522022-11-09 20:55:33 +000020#include "src/tint/utils/hashmap.h"
21#include "src/tint/utils/vector.h"
Ryan Harrisondbc13af2022-02-21 15:19:07 +000022
23namespace tint {
24
25/// Used to store a stack of scope information.
26/// The stack starts with a global scope which can not be popped.
James Price2cf32b12022-05-11 13:50:33 +000027template <class K, class V>
Ryan Harrisondbc13af2022-02-21 15:19:07 +000028class ScopeStack {
dan sinclair41e4d9a2022-05-01 14:40:55 +000029 public:
dan sinclair41e4d9a2022-05-01 14:40:55 +000030 /// Push a new scope on to the stack
Ben Clayton94181522022-11-09 20:55:33 +000031 void Push() { stack_.Push({}); }
Ryan Harrisondbc13af2022-02-21 15:19:07 +000032
dan sinclair41e4d9a2022-05-01 14:40:55 +000033 /// Pop the scope off the top of the stack
34 void Pop() {
Ben Clayton94181522022-11-09 20:55:33 +000035 if (stack_.Length() > 1) {
36 stack_.Pop();
dan sinclair41e4d9a2022-05-01 14:40:55 +000037 }
Ryan Harrisondbc13af2022-02-21 15:19:07 +000038 }
39
dan sinclair41e4d9a2022-05-01 14:40:55 +000040 /// Assigns the value into the top most scope of the stack.
James Price2cf32b12022-05-11 13:50:33 +000041 /// @param key the key of the value
dan sinclair41e4d9a2022-05-01 14:40:55 +000042 /// @param val the value
James Price2cf32b12022-05-11 13:50:33 +000043 /// @returns the old value if there was an existing key at the top of the
dan sinclair41e4d9a2022-05-01 14:40:55 +000044 /// stack, otherwise the zero initializer for type T.
James Price2cf32b12022-05-11 13:50:33 +000045 V Set(const K& key, V val) {
Ben Clayton94181522022-11-09 20:55:33 +000046 auto& back = stack_.Back();
Ben Clayton7c6e2292022-11-23 21:04:25 +000047 if (auto el = back.Find(key)) {
Ben Clayton94181522022-11-09 20:55:33 +000048 std::swap(val, *el);
49 return val;
50 }
51 back.Add(key, val);
52 return {};
dan sinclair41e4d9a2022-05-01 14:40:55 +000053 }
Ryan Harrisondbc13af2022-02-21 15:19:07 +000054
dan sinclair41e4d9a2022-05-01 14:40:55 +000055 /// Retrieves a value from the stack
James Price2cf32b12022-05-11 13:50:33 +000056 /// @param key the key to look for
dan sinclair41e4d9a2022-05-01 14:40:55 +000057 /// @returns the value, or the zero initializer if the value was not found
James Price2cf32b12022-05-11 13:50:33 +000058 V Get(const K& key) const {
dan sinclair41e4d9a2022-05-01 14:40:55 +000059 for (auto iter = stack_.rbegin(); iter != stack_.rend(); ++iter) {
Ben Clayton7c6e2292022-11-23 21:04:25 +000060 if (auto val = iter->Find(key)) {
Ben Clayton94181522022-11-09 20:55:33 +000061 return *val;
dan sinclair41e4d9a2022-05-01 14:40:55 +000062 }
63 }
64
James Price2cf32b12022-05-11 13:50:33 +000065 return V{};
dan sinclair41e4d9a2022-05-01 14:40:55 +000066 }
67
James Pricebe656f72022-05-11 22:05:15 +000068 /// Return the top scope of the stack.
69 /// @returns the top scope of the stack
Ben Clayton91d39a72023-01-12 20:31:33 +000070 const utils::Hashmap<K, V, 4>& Top() const { return stack_.Back(); }
James Pricebe656f72022-05-11 22:05:15 +000071
72 /// Clear the scope stack.
73 void Clear() {
Ben Clayton94181522022-11-09 20:55:33 +000074 stack_.Clear();
75 stack_.Push({});
James Pricebe656f72022-05-11 22:05:15 +000076 }
77
dan sinclair41e4d9a2022-05-01 14:40:55 +000078 private:
Ben Clayton91d39a72023-01-12 20:31:33 +000079 utils::Vector<utils::Hashmap<K, V, 4>, 8> stack_ = {{}};
Ryan Harrisondbc13af2022-02-21 15:19:07 +000080};
81
82} // namespace tint
83
84#endif // SRC_TINT_SCOPE_STACK_H_