chromium/third_party/dawn/src/tint/lang/wgsl/resolver/dependency_graph_test.cc

// Copyright 2021 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <string>
#include <tuple>
#include <utility>

#include "gmock/gmock.h"
#include "src/tint/lang/core/address_space.h"
#include "src/tint/lang/core/type/texture_dimension.h"
#include "src/tint/lang/wgsl/resolver/dependency_graph.h"
#include "src/tint/lang/wgsl/resolver/resolver_helper_test.h"
#include "src/tint/utils/containers/transform.h"

namespace tint::resolver {
namespace {

ElementsAre;
usingnamespacetint::core::fluent_types;     // NOLINT
usingnamespacetint::core::number_suffixes;  // NOLINT

template <typename T>
class ResolverDependencyGraphTestWithParam : public ResolverTestWithParam<T> {};

ResolverDependencyGraphTest;

////////////////////////////////////////////////////////////////////////////////
// Parameterized test helpers
////////////////////////////////////////////////////////////////////////////////

/// SymbolDeclKind is used by parameterized tests to enumerate the different
/// kinds of symbol declarations.
enum class SymbolDeclKind {};

static constexpr SymbolDeclKind kAllSymbolDeclKinds[] =;

static constexpr SymbolDeclKind kTypeDeclKinds[] =;

static constexpr SymbolDeclKind kValueDeclKinds[] =;

static constexpr SymbolDeclKind kGlobalDeclKinds[] =;

static constexpr SymbolDeclKind kLocalDeclKinds[] =;

static constexpr SymbolDeclKind kGlobalValueDeclKinds[] =;

static constexpr SymbolDeclKind kFuncDeclKinds[] =;

/// SymbolUseKind is used by parameterized tests to enumerate the different kinds of symbol uses.
enum class SymbolUseKind {};

static constexpr SymbolUseKind kAllUseKinds[] =;

static constexpr SymbolUseKind kTypeUseKinds[] =;

static constexpr SymbolUseKind kValueUseKinds[] =;

static constexpr SymbolUseKind kFuncUseKinds[] =;

/// @returns the description of the symbol declaration kind.
/// @note: This differs from the strings used in diagnostic messages.
std::ostream& operator<<(std::ostream& out, SymbolDeclKind kind) {}

/// @returns the description of the symbol use kind.
/// @note: This differs from the strings used in diagnostic messages.
std::ostream& operator<<(std::ostream& out, SymbolUseKind kind) {}

/// @returns the declaration scope depth for the symbol declaration kind.
///          Globals are at depth 0, parameters and locals are at depth 1,
///          nested locals are at depth 2.
int ScopeDepth(SymbolDeclKind kind) {}

/// @returns the use depth for the symbol use kind.
///          Globals are at depth 0, parameters and locals are at depth 1,
///          nested locals are at depth 2.
int ScopeDepth(SymbolUseKind kind) {}

/// A helper for building programs that exercise symbol declaration tests.
struct SymbolTestHelper {};

SymbolTestHelper::SymbolTestHelper(ProgramBuilder* b) :{}

SymbolTestHelper::~SymbolTestHelper() {}

const ast::Node* SymbolTestHelper::Add(SymbolDeclKind kind, Symbol symbol, Source source = {}

const ast::Identifier* SymbolTestHelper::Add(SymbolUseKind kind,
                                             Symbol symbol,
                                             Source source = {}

void SymbolTestHelper::Build() {}

////////////////////////////////////////////////////////////////////////////////
// Used-before-declared tests
////////////////////////////////////////////////////////////////////////////////
namespace used_before_decl_tests {

ResolverDependencyGraphUsedBeforeDeclTest;

TEST_F(ResolverDependencyGraphUsedBeforeDeclTest, FuncCall) {}

TEST_F(ResolverDependencyGraphUsedBeforeDeclTest, TypeConstructed) {}

TEST_F(ResolverDependencyGraphUsedBeforeDeclTest, TypeUsedByLocal) {}

TEST_F(ResolverDependencyGraphUsedBeforeDeclTest, TypeUsedByParam) {}

TEST_F(ResolverDependencyGraphUsedBeforeDeclTest, TypeUsedAsReturnType) {}

TEST_F(ResolverDependencyGraphUsedBeforeDeclTest, TypeByStructMember) {}

TEST_F(ResolverDependencyGraphUsedBeforeDeclTest, VarUsed) {}

}  // namespace used_before_decl_tests

////////////////////////////////////////////////////////////////////////////////
// Undeclared symbol tests
////////////////////////////////////////////////////////////////////////////////
namespace undeclared_tests {

ResolverDependencyGraphUndeclaredSymbolTest;

TEST_P(ResolverDependencyGraphUndeclaredSymbolTest, Test) {}

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

}  // namespace undeclared_tests

////////////////////////////////////////////////////////////////////////////////
// Self reference by decl
////////////////////////////////////////////////////////////////////////////////
namespace undeclared_tests {

ResolverDependencyGraphDeclSelfUse;

TEST_F(ResolverDependencyGraphDeclSelfUse, GlobalVar) {}

TEST_F(ResolverDependencyGraphDeclSelfUse, GlobalConst) {}

TEST_F(ResolverDependencyGraphDeclSelfUse, LocalVar) {}

TEST_F(ResolverDependencyGraphDeclSelfUse, LocalLet) {}

}  // namespace undeclared_tests

////////////////////////////////////////////////////////////////////////////////
// Recursive dependency tests
////////////////////////////////////////////////////////////////////////////////
namespace recursive_tests {

ResolverDependencyGraphCyclicRefTest;

TEST_F(ResolverDependencyGraphCyclicRefTest, DirectCall) {}

TEST_F(ResolverDependencyGraphCyclicRefTest, IndirectCall) {}

TEST_F(ResolverDependencyGraphCyclicRefTest, Alias_Direct) {}

TEST_F(ResolverDependencyGraphCyclicRefTest, Alias_Indirect) {}

TEST_F(ResolverDependencyGraphCyclicRefTest, Struct_Direct) {}

TEST_F(ResolverDependencyGraphCyclicRefTest, Struct_Indirect) {}

TEST_F(ResolverDependencyGraphCyclicRefTest, GlobalVar_Direct) {}

TEST_F(ResolverDependencyGraphCyclicRefTest, GlobalConst_Direct) {}

TEST_F(ResolverDependencyGraphCyclicRefTest, GlobalVar_Indirect) {}

TEST_F(ResolverDependencyGraphCyclicRefTest, GlobalConst_Indirect) {}

TEST_F(ResolverDependencyGraphCyclicRefTest, Mixed_RecursiveDependencies) {}

}  // namespace recursive_tests

////////////////////////////////////////////////////////////////////////////////
// Symbol Redeclaration tests
////////////////////////////////////////////////////////////////////////////////
namespace redeclaration_tests {

ResolverDependencyGraphRedeclarationTest;

TEST_P(ResolverDependencyGraphRedeclarationTest, Test) {}

INSTANTIATE_TEST_SUITE_P();

}  // namespace redeclaration_tests

////////////////////////////////////////////////////////////////////////////////
// Ordered global tests
////////////////////////////////////////////////////////////////////////////////
namespace ordered_globals {

ResolverDependencyGraphOrderedGlobalsTest;

TEST_P(ResolverDependencyGraphOrderedGlobalsTest, InOrder) {}

TEST_P(ResolverDependencyGraphOrderedGlobalsTest, OutOfOrder) {}

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

TEST_F(ResolverDependencyGraphOrderedGlobalsTest, DirectiveFirst) {}
}  // namespace ordered_globals

////////////////////////////////////////////////////////////////////////////////
// Resolve to user-declaration tests
////////////////////////////////////////////////////////////////////////////////
namespace resolve_to_user_decl {

ResolverDependencyGraphResolveToUserDeclTest;

TEST_P(ResolverDependencyGraphResolveToUserDeclTest, Test) {}

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

}  // namespace resolve_to_user_decl

////////////////////////////////////////////////////////////////////////////////
// Resolve to builtin func tests
////////////////////////////////////////////////////////////////////////////////
namespace resolve_to_builtin_func {

ResolverDependencyGraphResolveToBuiltinFn;

TEST_P(ResolverDependencyGraphResolveToBuiltinFn, Resolve) {}

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

}  // namespace resolve_to_builtin_func

////////////////////////////////////////////////////////////////////////////////
// Resolve to builtin type tests
////////////////////////////////////////////////////////////////////////////////
namespace resolve_to_builtin_type {

ResolverDependencyGraphResolveToBuiltinType;

TEST_P(ResolverDependencyGraphResolveToBuiltinType, Resolve) {}

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

}  // namespace resolve_to_builtin_type

////////////////////////////////////////////////////////////////////////////////
// Resolve to core::Access tests
////////////////////////////////////////////////////////////////////////////////
namespace resolve_to_access {

ResolverDependencyGraphResolveToAccess;

TEST_P(ResolverDependencyGraphResolveToAccess, Resolve) {}

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

}  // namespace resolve_to_access

////////////////////////////////////////////////////////////////////////////////
// Resolve to core::AddressSpace tests
////////////////////////////////////////////////////////////////////////////////
namespace resolve_to_address_space {

ResolverDependencyGraphResolveToAddressSpace;

TEST_P(ResolverDependencyGraphResolveToAddressSpace, Resolve) {}

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

}  // namespace resolve_to_address_space

////////////////////////////////////////////////////////////////////////////////
// Resolve to core::TexelFormat tests
////////////////////////////////////////////////////////////////////////////////
namespace resolve_to_texel_format {

ResolverDependencyGraphResolveToTexelFormat;

TEST_P(ResolverDependencyGraphResolveToTexelFormat, Resolve) {}

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

}  // namespace resolve_to_texel_format

////////////////////////////////////////////////////////////////////////////////
// Shadowing tests
////////////////////////////////////////////////////////////////////////////////
namespace shadowing {

ResolverDependencyGraphShadowScopeTest;

TEST_P(ResolverDependencyGraphShadowScopeTest, Test) {}

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

ResolverDependencyGraphShadowKindTest;

TEST_P(ResolverDependencyGraphShadowKindTest, ShadowedByGlobalVar) {}

TEST_P(ResolverDependencyGraphShadowKindTest, ShadowedByStruct) {}

TEST_P(ResolverDependencyGraphShadowKindTest, ShadowedByFunc) {}

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

}  // namespace shadowing

////////////////////////////////////////////////////////////////////////////////
// AST traversal tests
////////////////////////////////////////////////////////////////////////////////
namespace ast_traversal {

static const ast::Identifier* IdentifierOf(const ast::IdentifierExpression* expr) {}

static const ast::Identifier* IdentifierOf(const ast::Identifier* ident) {}

ResolverDependencyGraphTraversalTest;

TEST_F(ResolverDependencyGraphTraversalTest, SymbolsReached) {}

TEST_F(ResolverDependencyGraphTraversalTest, InferredType) {}

// Reproduces an unbalanced stack push / pop bug in
// DependencyAnalysis::SortGlobals(), found by clusterfuzz.
// See: crbug.com/chromium/1273451
TEST_F(ResolverDependencyGraphTraversalTest, chromium_1273451) {}

}  // namespace ast_traversal

}  // namespace
}  // namespace tint::resolver