mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-08-27 14:05:44 +00:00
The dependency graph no longer errors if a symbol cannot be resolved, instead the ResolvedIdentifier now has an unresolved variant. This is required as the second resolve phase only has the full context of the identifier usage, to provide the hints. Also: Split Slice out of the utils/vector.h, so it can be used as a lightweight view over static data. Fixed: tint:1842 Change-Id: I31fa7697790be24c35b7e4fab5ca903c8a7afbba Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/121020 Commit-Queue: Ben Clayton <bclayton@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Ben Clayton <bclayton@google.com> Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
224 lines
8.0 KiB
C++
224 lines
8.0 KiB
C++
// Copyright 2021 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_TINT_RESOLVER_DEPENDENCY_GRAPH_H_
|
|
#define SRC_TINT_RESOLVER_DEPENDENCY_GRAPH_H_
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "src/tint/ast/module.h"
|
|
#include "src/tint/builtin/access.h"
|
|
#include "src/tint/builtin/builtin.h"
|
|
#include "src/tint/builtin/builtin_value.h"
|
|
#include "src/tint/builtin/interpolation_sampling.h"
|
|
#include "src/tint/builtin/interpolation_type.h"
|
|
#include "src/tint/builtin/texel_format.h"
|
|
#include "src/tint/diagnostic/diagnostic.h"
|
|
#include "src/tint/sem/builtin_type.h"
|
|
#include "src/tint/symbol_table.h"
|
|
#include "src/tint/utils/hashmap.h"
|
|
|
|
namespace tint::resolver {
|
|
|
|
/// UnresolvedIdentifier is the variant value used by ResolvedIdentifier
|
|
struct UnresolvedIdentifier {
|
|
/// Name of the unresolved identifier
|
|
std::string name;
|
|
};
|
|
|
|
/// ResolvedIdentifier holds the resolution of an ast::Identifier.
|
|
/// Can hold one of:
|
|
/// - UnresolvedIdentifier
|
|
/// - const ast::TypeDecl* (as const ast::Node*)
|
|
/// - const ast::Variable* (as const ast::Node*)
|
|
/// - const ast::Function* (as const ast::Node*)
|
|
/// - sem::BuiltinType
|
|
/// - builtin::Access
|
|
/// - builtin::AddressSpace
|
|
/// - builtin::Builtin
|
|
/// - builtin::BuiltinValue
|
|
/// - builtin::InterpolationSampling
|
|
/// - builtin::InterpolationType
|
|
/// - builtin::TexelFormat
|
|
class ResolvedIdentifier {
|
|
public:
|
|
/// Constructor
|
|
/// @param value the resolved identifier value
|
|
template <typename T>
|
|
ResolvedIdentifier(T value) : value_(value) {} // NOLINT(runtime/explicit)
|
|
|
|
/// @return the UnresolvedIdentifier if the identifier was not resolved
|
|
const UnresolvedIdentifier* Unresolved() const {
|
|
if (auto n = std::get_if<UnresolvedIdentifier>(&value_)) {
|
|
return n;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
/// @return the node pointer if the ResolvedIdentifier holds an AST node, otherwise nullptr
|
|
const ast::Node* Node() const {
|
|
if (auto n = std::get_if<const ast::Node*>(&value_)) {
|
|
return *n;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
/// @return the builtin function if the ResolvedIdentifier holds sem::BuiltinType, otherwise
|
|
/// sem::BuiltinType::kNone
|
|
sem::BuiltinType BuiltinFunction() const {
|
|
if (auto n = std::get_if<sem::BuiltinType>(&value_)) {
|
|
return *n;
|
|
}
|
|
return sem::BuiltinType::kNone;
|
|
}
|
|
|
|
/// @return the access if the ResolvedIdentifier holds builtin::Access, otherwise
|
|
/// builtin::Access::kUndefined
|
|
builtin::Access Access() const {
|
|
if (auto n = std::get_if<builtin::Access>(&value_)) {
|
|
return *n;
|
|
}
|
|
return builtin::Access::kUndefined;
|
|
}
|
|
|
|
/// @return the address space if the ResolvedIdentifier holds builtin::AddressSpace, otherwise
|
|
/// builtin::AddressSpace::kUndefined
|
|
builtin::AddressSpace AddressSpace() const {
|
|
if (auto n = std::get_if<builtin::AddressSpace>(&value_)) {
|
|
return *n;
|
|
}
|
|
return builtin::AddressSpace::kUndefined;
|
|
}
|
|
|
|
/// @return the builtin type if the ResolvedIdentifier holds builtin::Builtin, otherwise
|
|
/// builtin::Builtin::kUndefined
|
|
builtin::Builtin BuiltinType() const {
|
|
if (auto n = std::get_if<builtin::Builtin>(&value_)) {
|
|
return *n;
|
|
}
|
|
return builtin::Builtin::kUndefined;
|
|
}
|
|
|
|
/// @return the builtin value if the ResolvedIdentifier holds builtin::BuiltinValue, otherwise
|
|
/// builtin::BuiltinValue::kUndefined
|
|
builtin::BuiltinValue BuiltinValue() const {
|
|
if (auto n = std::get_if<builtin::BuiltinValue>(&value_)) {
|
|
return *n;
|
|
}
|
|
return builtin::BuiltinValue::kUndefined;
|
|
}
|
|
|
|
/// @return the texel format if the ResolvedIdentifier holds type::InterpolationSampling,
|
|
/// otherwise type::InterpolationSampling::kUndefined
|
|
builtin::InterpolationSampling InterpolationSampling() const {
|
|
if (auto n = std::get_if<builtin::InterpolationSampling>(&value_)) {
|
|
return *n;
|
|
}
|
|
return builtin::InterpolationSampling::kUndefined;
|
|
}
|
|
|
|
/// @return the texel format if the ResolvedIdentifier holds type::InterpolationType,
|
|
/// otherwise type::InterpolationType::kUndefined
|
|
builtin::InterpolationType InterpolationType() const {
|
|
if (auto n = std::get_if<builtin::InterpolationType>(&value_)) {
|
|
return *n;
|
|
}
|
|
return builtin::InterpolationType::kUndefined;
|
|
}
|
|
|
|
/// @return the texel format if the ResolvedIdentifier holds type::TexelFormat, otherwise
|
|
/// type::TexelFormat::kUndefined
|
|
builtin::TexelFormat TexelFormat() const {
|
|
if (auto n = std::get_if<builtin::TexelFormat>(&value_)) {
|
|
return *n;
|
|
}
|
|
return builtin::TexelFormat::kUndefined;
|
|
}
|
|
|
|
/// @param value the value to compare the ResolvedIdentifier to
|
|
/// @return true if the ResolvedIdentifier is equal to @p value
|
|
template <typename T>
|
|
bool operator==(const T& value) const {
|
|
if (auto n = std::get_if<T>(&value_)) {
|
|
return *n == value;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// @param other the other value to compare to this
|
|
/// @return true if this ResolvedIdentifier and @p other are not equal
|
|
template <typename T>
|
|
bool operator!=(const T& other) const {
|
|
return !(*this == other);
|
|
}
|
|
|
|
/// @param symbols the program's symbol table
|
|
/// @param diagnostics diagnostics used to report ICEs
|
|
/// @return a description of the resolved symbol
|
|
std::string String(const SymbolTable& symbols, diag::List& diagnostics) const;
|
|
|
|
private:
|
|
std::variant<UnresolvedIdentifier,
|
|
const ast::Node*,
|
|
sem::BuiltinType,
|
|
builtin::Access,
|
|
builtin::AddressSpace,
|
|
builtin::Builtin,
|
|
builtin::BuiltinValue,
|
|
builtin::InterpolationSampling,
|
|
builtin::InterpolationType,
|
|
builtin::TexelFormat>
|
|
value_;
|
|
};
|
|
|
|
/// DependencyGraph holds information about module-scope declaration dependency
|
|
/// analysis and symbol resolutions.
|
|
struct DependencyGraph {
|
|
/// Constructor
|
|
DependencyGraph();
|
|
/// Move-constructor
|
|
DependencyGraph(DependencyGraph&&);
|
|
/// Destructor
|
|
~DependencyGraph();
|
|
|
|
/// Build() performs symbol resolution and dependency analysis on `module`,
|
|
/// populating `output` with the resulting dependency graph.
|
|
/// @param module the AST module to analyse
|
|
/// @param symbols the symbol table
|
|
/// @param diagnostics the diagnostic list to populate with errors / warnings
|
|
/// @param output the resulting DependencyGraph
|
|
/// @returns true on success, false on error
|
|
static bool Build(const ast::Module& module,
|
|
const SymbolTable& symbols,
|
|
diag::List& diagnostics,
|
|
DependencyGraph& output);
|
|
|
|
/// All globals in dependency-sorted order.
|
|
utils::Vector<const ast::Node*, 32> ordered_globals;
|
|
|
|
/// Map of ast::Identifier to a ResolvedIdentifier
|
|
utils::Hashmap<const ast::Identifier*, ResolvedIdentifier, 64> resolved_identifiers;
|
|
|
|
/// Map of ast::Variable to a type, function, or variable that is shadowed by
|
|
/// the variable key. A declaration (X) shadows another (Y) if X and Y use
|
|
/// the same symbol, and X is declared in a sub-scope of the scope that
|
|
/// declares Y.
|
|
utils::Hashmap<const ast::Variable*, const ast::Node*, 16> shadows;
|
|
};
|
|
|
|
} // namespace tint::resolver
|
|
|
|
#endif // SRC_TINT_RESOLVER_DEPENDENCY_GRAPH_H_
|