dawn-cmake/src/scope_stack.h
Ben Clayton 4183051b54 resolver: Add dependency-graph analysis
Performs a module-scope (global) declaration dependency analysis, so
that out-of-order global declarations can be re-ordered into dependency
order for consumption by the resolver.

The WGSL working group are currently debating whether out-of-order
declarations should be included in WebGPU V1, so this implementation
currently errors if module-scope declarations are declared out-of-order,
and the resolver does not currently use this sorted global list.

The analysis does however provide significantly better error diagnostics
when cyclic dependencies are formed, and when globals are declared
out-of-order.

The DependencyGraph also correctly now detects symbol collisions between
functions and types (tint:1308).

With this change, validation is duplicated between the DependencyGraph
and the Resolver. The now-unreachable validation will be removed from
the Resolver with a followup change.

Fixed: tint:1308
Bug: tint:1266
Change-Id: I809c23a069a86cf429f5ec8ef3ad9a98246766ab
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/69381
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@chromium.org>
Reviewed-by: David Neto <dneto@google.com>
2021-11-22 11:44:57 +00:00

81 lines
2.2 KiB
C++

// Copyright 2020 The Tint Authors. //
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_SCOPE_STACK_H_
#define SRC_SCOPE_STACK_H_
#include <unordered_map>
#include <utility>
#include <vector>
#include "src/symbol.h"
namespace tint {
/// Used to store a stack of scope information.
/// The stack starts with a global scope which can not be popped.
template <class T>
class ScopeStack {
public:
/// Constructor
ScopeStack() {
// Push global bucket
stack_.push_back({});
}
/// Copy Constructor
ScopeStack(const ScopeStack&) = default;
~ScopeStack() = default;
/// Push a new scope on to the stack
void Push() { stack_.push_back({}); }
/// Pop the scope off the top of the stack
void Pop() {
if (stack_.size() > 1) {
stack_.pop_back();
}
}
/// Assigns the value into the top most scope of the stack.
/// @param symbol the symbol of the value
/// @param val the value
/// @returns the old value if there was an existing symbol at the top of the
/// stack, otherwise the zero initializer for type T.
T Set(const Symbol& symbol, T val) {
std::swap(val, stack_.back()[symbol]);
return val;
}
/// Retrieves a value from the stack
/// @param symbol the symbol to look for
/// @returns the value, or the zero initializer if the value was not found
T Get(const Symbol& symbol) const {
for (auto iter = stack_.rbegin(); iter != stack_.rend(); ++iter) {
auto& map = *iter;
auto val = map.find(symbol);
if (val != map.end()) {
return val->second;
}
}
return T{};
}
private:
std::vector<std::unordered_map<Symbol, T>> stack_;
};
} // namespace tint
#endif // SRC_SCOPE_STACK_H_