blob: 2424a8037b3204bfaba3dff1c4b1d54c07a711f5 [file] [log] [blame]
/*
* Copyright (C) 2018 Apple Inc. All rights reserved.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
*/
#pragma once
#if ENABLE(WEBGPU)
#include "WHLSLUnnamedType.h"
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
#include <wtf/UniqueRef.h>
#include <wtf/Variant.h>
namespace WebCore {
namespace WHLSL {
namespace AST {
class ResolvableType;
}
// There are cases where the type of one AST node should match the type of another AST node.
// One example of this is the comma expression - the type of the comma expression should match the type of its last item.
// If this type happens to be a resolvable type, it will get resolved later. When that happens,
// both of the AST nodes have to be resolved to the result type. This class represents a
// reference counted wrapper around a resolvable type so both entries in the type map can point
// to the same resolvable type, so resolving it once resolves both the entries in the map.
// This class could probably be represented as
// "class ResolvableTypeReference : public std::reference_wrapper<AST::ResolvableType>, public RefCounted<ResolvableTypeReference {}"
// but I didn't want to be too clever.
class ResolvableTypeReference : public RefCounted<ResolvableTypeReference> {
public:
ResolvableTypeReference(AST::ResolvableType& resolvableType)
: m_resolvableType(&resolvableType)
{
}
ResolvableTypeReference(const ResolvableTypeReference&) = delete;
ResolvableTypeReference(ResolvableTypeReference&&) = delete;
ResolvableTypeReference& operator=(const ResolvableTypeReference&) = delete;
ResolvableTypeReference& operator=(ResolvableTypeReference&&) = delete;
AST::ResolvableType& resolvableType() { return *m_resolvableType; }
private:
AST::ResolvableType* m_resolvableType;
};
// This is a thin wrapper around a Variant.
// It exists so we can make sure that the default constructor does the right thing.
// FIXME: https://bugs.webkit.org/show_bug.cgi?id=198158 This wrapper might not be necessary.
class ResolvingType {
public:
ResolvingType()
: m_inner(RefPtr<ResolvableTypeReference>())
{
}
ResolvingType(UniqueRef<AST::UnnamedType>&& v)
: m_inner(WTFMove(v))
{
}
ResolvingType(RefPtr<ResolvableTypeReference>&& v)
: m_inner(WTFMove(v))
{
}
ResolvingType(const ResolvingType&) = delete;
ResolvingType(ResolvingType&& other)
: m_inner(WTFMove(other.m_inner))
{
}
ResolvingType& operator=(const ResolvingType&) = delete;
ResolvingType& operator=(ResolvingType&& other)
{
m_inner = WTFMove(other.m_inner);
return *this;
}
AST::UnnamedType* getUnnamedType()
{
if (WTF::holds_alternative<UniqueRef<AST::UnnamedType>>(m_inner))
return &WTF::get<UniqueRef<AST::UnnamedType>>(m_inner);
return nullptr;
}
template <typename Visitor> auto visit(const Visitor& visitor) -> decltype(WTF::visit(visitor, std::declval<Variant<UniqueRef<AST::UnnamedType>, RefPtr<ResolvableTypeReference>>&>()))
{
return WTF::visit(visitor, m_inner);
}
private:
Variant<UniqueRef<AST::UnnamedType>, RefPtr<ResolvableTypeReference>> m_inner;
};
}
}
#endif