WebKit Bugzilla
Attachment 358667 Details for
Bug 193080
: [WHLSL] Implement the Type Checker
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
WIP
patch.txt (text/plain), 488.77 KB, created by
Myles C. Maxfield
on 2019-01-08 20:53:01 PST
(
hide
)
Description:
WIP
Filename:
MIME Type:
Creator:
Myles C. Maxfield
Created:
2019-01-08 20:53:01 PST
Size:
488.77 KB
patch
obsolete
>diff --git a/Source/WTF/wtf/UniqueRef.h b/Source/WTF/wtf/UniqueRef.h >index 2039950d9d8..d2a37a284a5 100644 >--- a/Source/WTF/wtf/UniqueRef.h >+++ b/Source/WTF/wtf/UniqueRef.h >@@ -60,6 +60,8 @@ public: > operator T&() { ASSERT(m_ref); return *m_ref; } > operator const T&() const { ASSERT(m_ref); return *m_ref; } > >+ std::unique_ptr<T>&& takeUniquePtr() { return WTFMove(m_ref); } >+ > private: > template<class U, class... Args> friend UniqueRef<U> makeUniqueRef(Args&&...); > template<class U> friend class UniqueRef; >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLArrayReferenceType.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLArrayReferenceType.h >index 2d567f00e70..01d68f1276d 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLArrayReferenceType.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLArrayReferenceType.h >@@ -29,6 +29,7 @@ > > #include "WHLSLLexer.h" > #include "WHLSLReferenceType.h" >+#include <wtf/UniqueRef.h> > #include <wtf/text/WTFString.h> > > namespace WebCore { >@@ -39,8 +40,8 @@ namespace AST { > > class ArrayReferenceType : public ReferenceType { > public: >- ArrayReferenceType(Lexer::Token&& origin, String&& addressSpace, std::unique_ptr<Type>&& elementType) >- : ReferenceType(WTFMove(origin), WTFMove(addressSpace), WTFMove(elementType)) >+ ArrayReferenceType(Lexer::Token&& origin, AddressSpace addressSpace, UniqueRef<UnnamedType>&& elementType) >+ : ReferenceType(WTFMove(origin), addressSpace, WTFMove(elementType)) > { > } > >@@ -49,22 +50,22 @@ public: > ArrayReferenceType(const ArrayReferenceType&) = delete; > ArrayReferenceType(ArrayReferenceType&&) = default; > >- bool isArrayReferenceType() const override { return false; } >+ bool isArrayReferenceType() const override { return true; } > >- std::unique_ptr<Type> clone() const override >+ UniqueRef<UnnamedType> clone() const override > { >- return std::make_unique<ArrayReferenceType>(Lexer::Token(origin()), String(addressSpace()), elementType().clone()); >+ return makeUniqueRef<ArrayReferenceType>(Lexer::Token(origin()), addressSpace(), elementType().clone()); > } > > private: > }; > >-} >+} // namespace AST > > } > > } > >-SPECIALIZE_TYPE_TRAITS_WHLSL_TYPE(ArrayReferenceType, isArrayReferenceType()) >+SPECIALIZE_TYPE_TRAITS_WHLSL_UNNAMED_TYPE(ArrayReferenceType, isArrayReferenceType()) > > #endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLArrayType.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLArrayType.h >index 40b5f8df6fe..422fd3c713a 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLArrayType.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLArrayType.h >@@ -28,8 +28,9 @@ > #if ENABLE(WEBGPU) > > #include "WHLSLLexer.h" >-#include "WHLSLType.h" >+#include "WHLSLUnnamedType.h" > #include "WHLSLTypeArgument.h" >+#include <wtf/UniqueRef.h> > #include <wtf/text/WTFString.h> > > namespace WebCore { >@@ -38,10 +39,10 @@ namespace WHLSL { > > namespace AST { > >-class ArrayType : public Type { >+class ArrayType : public UnnamedType { > public: >- ArrayType(Lexer::Token&& origin, std::unique_ptr<Type>&& elementType, unsigned numElements) >- : m_origin(WTFMove(origin)) >+ ArrayType(Lexer::Token&& origin, UniqueRef<UnnamedType>&& elementType, unsigned numElements) >+ : UnnamedType(WTFMove(origin)) > , m_elementType(WTFMove(elementType)) > , m_numElements(numElements) > { >@@ -52,29 +53,28 @@ public: > ArrayType(const ArrayType&) = delete; > ArrayType(ArrayType&&) = default; > >- unsigned numElements() const { return m_numElements; } >- >- bool isArrayType() const override { return false; } >+ bool isArrayType() const override { return true; } > >- Type& type() { return *m_elementType; } >+ const UnnamedType& type() const { return static_cast<const UnnamedType&>(m_elementType); } >+ UnnamedType& type() { return static_cast<UnnamedType&>(m_elementType); } >+ unsigned numElements() const { return m_numElements; } > >- std::unique_ptr<Type> clone() const override >+ UniqueRef<UnnamedType> clone() const override > { >- return std::make_unique<ArrayType>(Lexer::Token(m_origin), m_elementType->clone(), m_numElements); >+ return makeUniqueRef<ArrayType>(Lexer::Token(origin()), m_elementType->clone(), m_numElements); > } > > private: >- Lexer::Token m_origin; >- std::unique_ptr<Type> m_elementType; >+ UniqueRef<UnnamedType> m_elementType; > unsigned m_numElements; > }; > >-} >+} // namespace AST > > } > > } > >-SPECIALIZE_TYPE_TRAITS_WHLSL_TYPE(ArrayType, isArrayType()) >+SPECIALIZE_TYPE_TRAITS_WHLSL_UNNAMED_TYPE(ArrayType, isArrayType()) > > #endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAssignmentExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAssignmentExpression.h >index eaa694f5985..9dd07f8c827 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAssignmentExpression.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAssignmentExpression.h >@@ -29,6 +29,7 @@ > > #include "WHLSLExpression.h" > #include "WHLSLLexer.h" >+#include <wtf/UniqueRef.h> > > namespace WebCore { > >@@ -38,7 +39,7 @@ namespace AST { > > class AssignmentExpression : public Expression { > public: >- AssignmentExpression(Lexer::Token&& origin, std::unique_ptr<Expression>&& left, std::unique_ptr<Expression>&& right) >+ AssignmentExpression(Lexer::Token&& origin, UniqueRef<Expression>&& left, UniqueRef<Expression>&& right) > : Expression(WTFMove(origin)) > , m_left(WTFMove(left)) > , m_right(WTFMove(right)) >@@ -52,15 +53,15 @@ public: > > bool isAssignmentExpression() const override { return true; } > >- Expression& left() { return *m_left; } >- Expression& right() { return *m_right; } >+ Expression& left() { return static_cast<Expression&>(m_left); } >+ Expression& right() { return static_cast<Expression&>(m_right); } > > private: >- std::unique_ptr<Expression> m_left; >- std::unique_ptr<Expression> m_right; >+ UniqueRef<Expression> m_left; >+ UniqueRef<Expression> m_right; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBaseFunctionAttribute.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBaseFunctionAttribute.h >index 5c244ca82a9..a6a0613b2e8 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBaseFunctionAttribute.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBaseFunctionAttribute.h >@@ -52,7 +52,7 @@ private: > Lexer::Token m_origin; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBaseSemantic.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBaseSemantic.h >index 6573372f137..932c46c7964 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBaseSemantic.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBaseSemantic.h >@@ -34,8 +34,13 @@ namespace WebCore { > > namespace WHLSL { > >+class Intrinsics; >+ > namespace AST { > >+class FunctionDefinition; >+class UnnamedType; >+ > class BaseSemantic : public Node { > public: > BaseSemantic(Lexer::Token&& origin) >@@ -48,11 +53,19 @@ public: > BaseSemantic(const BaseSemantic&) = delete; > BaseSemantic(BaseSemantic&&) = default; > >+ virtual bool isAcceptableType(const AST::UnnamedType&, const Intrinsics&) const = 0; >+ >+ enum class ShaderItemDirection : uint8_t { >+ Input, >+ Output >+ }; >+ virtual bool isAcceptableForShaderItemDirection(ShaderItemDirection, const FunctionDefinition&) const = 0; >+ > private: > Lexer::Token m_origin; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBlock.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBlock.h >index c4d129fede3..6c436cd074a 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBlock.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBlock.h >@@ -58,7 +58,7 @@ private: > Statements m_statements; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBooleanLiteral.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBooleanLiteral.h >index 200f364932b..3b25c8b5d7f 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBooleanLiteral.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBooleanLiteral.h >@@ -46,18 +46,26 @@ public: > > virtual ~BooleanLiteral() = default; > >- explicit BooleanLiteral(const BooleanLiteral&) = default; >+ BooleanLiteral(const BooleanLiteral&) = delete; > BooleanLiteral(BooleanLiteral&&) = default; > >+ BooleanLiteral& operator=(const BooleanLiteral&) = delete; >+ BooleanLiteral& operator=(BooleanLiteral&&) = default; >+ > bool value() const { return m_value; } > > bool isBooleanLiteral() const override { return true; } > >+ BooleanLiteral clone() const >+ { >+ return BooleanLiteral(Lexer::Token(origin()), m_value); >+ } >+ > private: > bool m_value; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBreak.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBreak.h >index 7475cc3f6fb..5fffe8698a5 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBreak.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBreak.h >@@ -53,7 +53,7 @@ public: > private: > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBuiltInSemantic.cpp b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBuiltInSemantic.cpp >new file mode 100644 >index 00000000000..8414ba3461b >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBuiltInSemantic.cpp >@@ -0,0 +1,144 @@ >+/* >+ * 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. >+ */ >+ >+#if ENABLE(WEBGPU) >+ >+#include "config.h" >+#include "WHLSLBuiltInSemantic.h" >+ >+#include "WHLSLFunctionDefinition.h" >+#include "WHLSLInferTypes.h" >+#include "WHLSLIntrinsics.h" >+#include "WHLSLTypeReference.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+bool BuiltInSemantic::isAcceptableType(const AST::UnnamedType& unnamedType, const Intrinsics& intrinsics) const >+{ >+ switch (m_variable) { >+ case Variable::SVInstanceID: >+ return matches(unnamedType, intrinsics.uintType()); >+ case Variable::SVVertexID: >+ return matches(unnamedType, intrinsics.uintType()); >+ case Variable::PSize: >+ return matches(unnamedType, intrinsics.floatType()); >+ case Variable::SVPosition: >+ return matches(unnamedType, intrinsics.float4Type()); >+ case Variable::SVIsFrontFace: >+ return matches(unnamedType, intrinsics.boolType()); >+ case Variable::SVSampleIndex: >+ return matches(unnamedType, intrinsics.uintType()); >+ case Variable::SVInnerCoverage: >+ return matches(unnamedType, intrinsics.uintType()); >+ case Variable::SVTarget: >+ return matches(unnamedType, intrinsics.float4Type()); >+ case Variable::SVDepth: >+ return matches(unnamedType, intrinsics.floatType()); >+ case Variable::SVCoverage: >+ return matches(unnamedType, intrinsics.uintType()); >+ case Variable::SVDispatchThreadID: >+ return matches(unnamedType, intrinsics.float3Type()); >+ case Variable::SVGroupID: >+ return matches(unnamedType, intrinsics.float3Type()); >+ case Variable::SVGroupIndex: >+ return matches(unnamedType, intrinsics.uintType()); >+ case Variable::SVGroupThreadID: >+ return matches(unnamedType, intrinsics.float3Type()); >+ } >+} >+ >+bool BuiltInSemantic::isAcceptableForShaderItemDirection(ShaderItemDirection direction, const FunctionDefinition& functionDefinition) const >+{ >+ switch (*functionDefinition.entryPointType()) { >+ case FunctionDeclaration::EntryPointType::Vertex: >+ switch (direction) { >+ case ShaderItemDirection::Input: >+ switch (m_variable) { >+ case Variable::SVInstanceID: >+ case Variable::SVVertexID: >+ return true; >+ default: >+ return false; >+ } >+ case ShaderItemDirection::Output: >+ switch (m_variable) { >+ case Variable::PSize: >+ case Variable::SVPosition: >+ return true; >+ default: >+ return false; >+ } >+ } >+ case FunctionDeclaration::EntryPointType::Fragment: >+ switch (direction) { >+ case ShaderItemDirection::Input: >+ switch (m_variable) { >+ case Variable::SVIsFrontFace: >+ case Variable::SVPosition: >+ case Variable::SVSampleIndex: >+ case Variable::SVInnerCoverage: >+ return true; >+ default: >+ return false; >+ } >+ case ShaderItemDirection::Output: >+ switch (m_variable) { >+ case Variable::SVTarget: >+ case Variable::SVDepth: >+ case Variable::SVCoverage: >+ return true; >+ default: >+ return false; >+ } >+ } >+ case FunctionDeclaration::EntryPointType::Compute: >+ switch (direction) { >+ case ShaderItemDirection::Input: >+ switch (m_variable) { >+ case Variable::SVDispatchThreadID: >+ case Variable::SVGroupID: >+ case Variable::SVGroupIndex: >+ case Variable::SVGroupThreadID: >+ return true; >+ default: >+ return false; >+ } >+ case ShaderItemDirection::Output: >+ return false; >+ } >+ } >+} >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBuiltInSemantic.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBuiltInSemantic.h >index 7046df32cfa..f2c274cf45c 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBuiltInSemantic.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBuiltInSemantic.h >@@ -39,7 +39,7 @@ namespace AST { > > class BuiltInSemantic : public BaseSemantic { > public: >- enum class Variable { >+ enum class Variable : uint8_t { > SVInstanceID, > SVVertexID, > PSize, >@@ -70,12 +70,25 @@ public: > > Variable variable() const { return m_variable; } > >+ bool operator==(const BuiltInSemantic& other) const >+ { >+ return m_variable == other.m_variable && m_targetIndex == other.m_targetIndex; >+ } >+ >+ bool operator!=(const BuiltInSemantic& other) const >+ { >+ return !(*this == other); >+ } >+ >+ bool isAcceptableType(const AST::UnnamedType&, const Intrinsics&) const override; >+ bool isAcceptableForShaderItemDirection(ShaderItemDirection, const FunctionDefinition&) const override; >+ > private: > Variable m_variable; > Optional<unsigned> m_targetIndex; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLCallExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLCallExpression.h >index 64af713299c..6f7a47c46d1 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLCallExpression.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLCallExpression.h >@@ -28,7 +28,9 @@ > #if ENABLE(WEBGPU) > > #include "WHLSLExpression.h" >+#include "WHLSLFunctionDeclaration.h" > #include "WHLSLLexer.h" >+#include <wtf/UniqueRef.h> > > namespace WebCore { > >@@ -36,9 +38,11 @@ namespace WHLSL { > > namespace AST { > >+class NamedType; >+ > class CallExpression : public Expression { > public: >- CallExpression(Lexer::Token&& origin, String&& name, Vector<std::unique_ptr<Expression>>&& arguments) >+ CallExpression(Lexer::Token&& origin, String&& name, Vector<UniqueRef<Expression>>&& arguments) > : Expression(WTFMove(origin)) > , m_name(WTFMove(name)) > , m_arguments(WTFMove(arguments)) >@@ -52,14 +56,40 @@ public: > > bool isCallExpression() const override { return true; } > >- Vector<std::unique_ptr<Expression>>& arguments() { return m_arguments; } >+ Vector<UniqueRef<Expression>>& arguments() { return m_arguments; } >+ >+ String& name() { return m_name; } >+ >+ void setCastData(AST::NamedType& namedType) >+ { >+ m_castReturnType = { namedType }; >+ } >+ >+ bool isCast() { return static_cast<bool>(m_castReturnType); } >+ Optional<std::reference_wrapper<AST::NamedType>>& castReturnType() { return m_castReturnType; } >+ bool hasOverloads() const { return static_cast<bool>(m_overloads); } >+ Optional<Vector<std::reference_wrapper<FunctionDeclaration>, 1>>& overloads() { return m_overloads; } >+ void setOverloads(const Vector<std::reference_wrapper<FunctionDeclaration>, 1>& overloads) >+ { >+ assert(!hasOverloads()); >+ m_overloads = overloads; >+ } >+ >+ void setFunction(FunctionDeclaration& functionDeclaration) >+ { >+ assert(!m_function); >+ m_function = &functionDeclaration; >+ } > > private: > String m_name; >- Vector<std::unique_ptr<Expression>> m_arguments; >+ Vector<UniqueRef<Expression>> m_arguments; >+ Optional<Vector<std::reference_wrapper<FunctionDeclaration>, 1>> m_overloads; >+ FunctionDeclaration* m_function { nullptr }; >+ Optional<std::reference_wrapper<AST::NamedType>> m_castReturnType { WTF::nullopt }; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLCommaExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLCommaExpression.h >index b8d2ba38dbc..e322f53e734 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLCommaExpression.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLCommaExpression.h >@@ -29,6 +29,7 @@ > > #include "WHLSLExpression.h" > #include "WHLSLLexer.h" >+#include <wtf/UniqueRef.h> > #include <wtf/Vector.h> > > namespace WebCore { >@@ -39,7 +40,7 @@ namespace AST { > > class CommaExpression : public Expression { > public: >- CommaExpression(Lexer::Token&& origin, Vector<std::unique_ptr<Expression>>&& list) >+ CommaExpression(Lexer::Token&& origin, Vector<UniqueRef<Expression>>&& list) > : Expression(WTFMove(origin)) > , m_list(WTFMove(list)) > { >@@ -52,13 +53,13 @@ public: > > bool isCommaExpression() const override { return true; } > >- Vector<std::unique_ptr<Expression>>& list() { return m_list; } >+ Vector<UniqueRef<Expression>>& list() { return m_list; } > > private: >- Vector<std::unique_ptr<Expression>> m_list; >+ Vector<UniqueRef<Expression>> m_list; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLConstantExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLConstantExpression.h >index a38b0d5b3a1..1d4fa7d9fe1 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLConstantExpression.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLConstantExpression.h >@@ -76,11 +76,92 @@ public: > { > } > >+ ConstantExpression(const ConstantExpression&) = delete; >+ ConstantExpression(ConstantExpression&&) = default; >+ >+ ConstantExpression& operator=(const ConstantExpression&) = delete; >+ ConstantExpression& operator=(ConstantExpression&&) = default; >+ >+ IntegerLiteral& integerLiteral() >+ { >+ ASSERT(WTF::holds_alternative<IntegerLiteral>(m_variant)); >+ return WTF::get<IntegerLiteral>(m_variant); >+ } >+ > template<typename T> void visit(T&& t) > { > WTF::visit(WTFMove(t), m_variant); > } > >+ template<typename T> void visit(T&& t) const >+ { >+ WTF::visit(WTFMove(t), m_variant); >+ } >+ >+ ConstantExpression clone() const >+ { >+ return WTF::visit(WTF::makeVisitor([&](const IntegerLiteral& integerLiteral) -> ConstantExpression { >+ return integerLiteral.clone(); >+ }, [&](const UnsignedIntegerLiteral& unsignedIntegerLiteral) -> ConstantExpression { >+ return unsignedIntegerLiteral.clone(); >+ }, [&](const FloatLiteral& floatLiteral) -> ConstantExpression { >+ return floatLiteral.clone(); >+ }, [&](const NullLiteral& nullLiteral) -> ConstantExpression { >+ return nullLiteral.clone(); >+ }, [&](const BooleanLiteral& booleanLiteral) -> ConstantExpression { >+ return booleanLiteral.clone(); >+ }, [&](const ConstantExpressionEnumerationMemberReference& constantExpressionEnumerationMemberReference) -> ConstantExpression { >+ return constantExpressionEnumerationMemberReference.clone(); >+ }), m_variant); >+ } >+ >+ bool matches(const ConstantExpression& other) const >+ { >+ Optional<bool> result; >+ double value; >+ visit(WTF::makeVisitor([&](const IntegerLiteral& integerLiteral) { >+ value = integerLiteral.value(); >+ }, [&](const UnsignedIntegerLiteral& unsignedIntegerLiteral) { >+ value = unsignedIntegerLiteral.value(); >+ }, [&](const FloatLiteral& floatLiteral) { >+ value = floatLiteral.value(); >+ }, [&](const NullLiteral&) { >+ result = WTF::holds_alternative<NullLiteral>(other.m_variant); >+ }, [&](const BooleanLiteral& booleanLiteral) { >+ if (WTF::holds_alternative<BooleanLiteral>(other.m_variant)) { >+ const auto& otherBooleanLiteral = WTF::get<BooleanLiteral>(other.m_variant); >+ result = booleanLiteral.value() == otherBooleanLiteral.value(); >+ } else >+ result = false; >+ }, [&](const ConstantExpressionEnumerationMemberReference& constantExpressionEnumerationMemberReference) { >+ if (WTF::holds_alternative<ConstantExpressionEnumerationMemberReference>(other.m_variant)) { >+ const auto& otherMemberReference = WTF::get<ConstantExpressionEnumerationMemberReference>(other.m_variant); >+ result = constantExpressionEnumerationMemberReference.enumerationMember() == otherMemberReference.enumerationMember(); >+ } else >+ result = false; >+ })); >+ >+ if (result) >+ return *result; >+ >+ other.visit(WTF::makeVisitor([&](const IntegerLiteral& integerLiteral) { >+ result = value == integerLiteral.value(); >+ }, [&](const UnsignedIntegerLiteral& unsignedIntegerLiteral) { >+ result = value == unsignedIntegerLiteral.value(); >+ }, [&](const FloatLiteral& floatLiteral) { >+ result = value == floatLiteral.value(); >+ }, [&](const NullLiteral&) { >+ result = false; >+ }, [&](const BooleanLiteral&) { >+ result = false; >+ }, [&](const ConstantExpressionEnumerationMemberReference&) { >+ result = false; >+ })); >+ >+ ASSERT(result); >+ return *result; >+ } >+ > private: > Variant< > IntegerLiteral, >@@ -92,7 +173,7 @@ private: > > m_variant; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLConstantExpressionEnumerationMemberReference.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLConstantExpressionEnumerationMemberReference.h >index 2c24a98b2ca..2c4ced1fa6d 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLConstantExpressionEnumerationMemberReference.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLConstantExpressionEnumerationMemberReference.h >@@ -36,10 +36,13 @@ namespace WHLSL { > > namespace AST { > >-class ConstantExpressionEnumerationMemberReference : public Node { >+class EnumerationDefinition; >+class EnumerationMember; >+ >+class ConstantExpressionEnumerationMemberReference : public Expression { > public: > ConstantExpressionEnumerationMemberReference(Lexer::Token&& origin, String&& left, String&& right) >- : m_origin(WTFMove(origin)) >+ : Expression(WTFMove(origin)) > , m_left(WTFMove(left)) > , m_right(WTFMove(right)) > { >@@ -50,13 +53,53 @@ public: > explicit ConstantExpressionEnumerationMemberReference(const ConstantExpressionEnumerationMemberReference&) = default; > ConstantExpressionEnumerationMemberReference(ConstantExpressionEnumerationMemberReference&&) = default; > >+ ConstantExpressionEnumerationMemberReference& operator=(const ConstantExpressionEnumerationMemberReference&) = delete; >+ ConstantExpressionEnumerationMemberReference& operator=(ConstantExpressionEnumerationMemberReference&&) = default; >+ >+ const String& left() const { return m_left; } >+ const String& right() const { return m_right; } >+ >+ ConstantExpressionEnumerationMemberReference clone() const >+ { >+ auto result = ConstantExpressionEnumerationMemberReference(Lexer::Token(origin()), String(m_left), String(m_right)); >+ result.m_enumerationMember = m_enumerationMember; >+ return result; >+ } >+ >+ AST::EnumerationDefinition* enumerationDefinition() >+ { >+ return m_enumerationDefinition; >+ } >+ >+ AST::EnumerationDefinition* enumerationDefinition() const >+ { >+ return m_enumerationDefinition; >+ } >+ >+ AST::EnumerationMember* enumerationMember() >+ { >+ return m_enumerationMember; >+ } >+ >+ AST::EnumerationMember* enumerationMember() const >+ { >+ return m_enumerationMember; >+ } >+ >+ void setEnumerationMember(AST::EnumerationDefinition& enumerationDefinition, AST::EnumerationMember& enumerationMember) >+ { >+ m_enumerationDefinition = &enumerationDefinition; >+ m_enumerationMember = &enumerationMember; >+ } >+ > private: >- Lexer::Token m_origin; > String m_left; > String m_right; >+ AST::EnumerationDefinition* m_enumerationDefinition { nullptr }; >+ AST::EnumerationMember* m_enumerationMember { nullptr }; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLContinue.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLContinue.h >index 3b06ec59d22..534ae22063d 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLContinue.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLContinue.h >@@ -53,7 +53,7 @@ public: > private: > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDereferenceExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDereferenceExpression.h >index 6c55de34a7f..afc3103188a 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDereferenceExpression.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDereferenceExpression.h >@@ -29,6 +29,7 @@ > > #include "WHLSLExpression.h" > #include "WHLSLLexer.h" >+#include <wtf/UniqueRef.h> > > namespace WebCore { > >@@ -38,7 +39,7 @@ namespace AST { > > class DereferenceExpression : public Expression { > public: >- DereferenceExpression(Lexer::Token&& origin, std::unique_ptr<Expression>&& pointer) >+ DereferenceExpression(Lexer::Token&& origin, UniqueRef<Expression>&& pointer) > : Expression(WTFMove(origin)) > , m_pointer(WTFMove(pointer)) > { >@@ -51,13 +52,13 @@ public: > > bool isDereferenceExpression() const override { return true; } > >- Expression& pointer() { return *m_pointer; } >+ Expression& pointer() { return static_cast<Expression&>(m_pointer); } > > private: >- std::unique_ptr<Expression> m_pointer; >+ UniqueRef<Expression> m_pointer; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDoWhileLoop.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDoWhileLoop.h >index d26edf922ce..fbf44872de2 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDoWhileLoop.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDoWhileLoop.h >@@ -30,6 +30,7 @@ > #include "WHLSLExpression.h" > #include "WHLSLLexer.h" > #include "WHLSLStatement.h" >+#include <wtf/UniqueRef.h> > > namespace WebCore { > >@@ -39,7 +40,7 @@ namespace AST { > > class DoWhileLoop : public Statement { > public: >- DoWhileLoop(Lexer::Token&& origin, std::unique_ptr<Statement>&& body, std::unique_ptr<Expression>&& conditional) >+ DoWhileLoop(Lexer::Token&& origin, UniqueRef<Statement>&& body, UniqueRef<Expression>&& conditional) > : Statement(WTFMove(origin)) > , m_body(WTFMove(body)) > , m_conditional(WTFMove(conditional)) >@@ -53,15 +54,15 @@ public: > > bool isDoWhileLoop() const override { return true; } > >- Statement& body() { return *m_body; } >- Expression& conditional() { return *m_conditional; } >+ Statement& body() { return static_cast<Statement&>(m_body); } >+ Expression& conditional() { return static_cast<Expression&>(m_conditional); } > > private: >- std::unique_ptr<Statement> m_body; >- std::unique_ptr<Expression> m_conditional; >+ UniqueRef<Statement> m_body; >+ UniqueRef<Expression> m_conditional; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDotExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDotExpression.h >index c43c69ee541..c1cf50e5627 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDotExpression.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDotExpression.h >@@ -29,6 +29,7 @@ > > #include "WHLSLLexer.h" > #include "WHLSLPropertyAccessExpression.h" >+#include <wtf/UniqueRef.h> > > namespace WebCore { > >@@ -38,7 +39,7 @@ namespace AST { > > class DotExpression : public PropertyAccessExpression { > public: >- DotExpression(Lexer::Token&& origin, std::unique_ptr<Expression>&& base, String&& fieldName) >+ DotExpression(Lexer::Token&& origin, UniqueRef<Expression>&& base, String&& fieldName) > : PropertyAccessExpression(WTFMove(origin), WTFMove(base)) > , m_fieldName(WTFMove(fieldName)) > { >@@ -49,14 +50,35 @@ public: > DotExpression(const DotExpression&) = delete; > DotExpression(DotExpression&&) = default; > >+ bool isDotExpression() const override { return true; } >+ >+ String getFunctionName() const override >+ { >+ return String::format("operator.%s", m_fieldName.utf8().data()); >+ } >+ >+ String setFunctionName() const override >+ { >+ return String::format("operator.%s=", m_fieldName.utf8().data()); >+ } >+ >+ String andFunctionName() const override >+ { >+ return String::format("operator&.%s", m_fieldName.utf8().data()); >+ } >+ >+ String& fieldName() { return m_fieldName; } >+ > private: > String m_fieldName; > }; > >-} >+} // namespace AST > > } > > } > >+SPECIALIZE_TYPE_TRAITS_WHLSL_EXPRESSION(DotExpression, isDotExpression()) >+ > #endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEffectfulExpressionStatement.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEffectfulExpressionStatement.h >index d9ca99ad8e0..33325f17824 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEffectfulExpressionStatement.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEffectfulExpressionStatement.h >@@ -30,6 +30,7 @@ > #include "WHLSLExpression.h" > #include "WHLSLLexer.h" > #include "WHLSLStatement.h" >+#include <wtf/UniqueRef.h> > > namespace WebCore { > >@@ -39,7 +40,7 @@ namespace AST { > > class EffectfulExpressionStatement : public Statement { > public: >- EffectfulExpressionStatement(std::unique_ptr<Expression>&& effectfulExpression) >+ EffectfulExpressionStatement(UniqueRef<Expression>&& effectfulExpression) > : Statement(Lexer::Token(effectfulExpression->origin())) > , m_effectfulExpression(WTFMove(effectfulExpression)) > { >@@ -52,13 +53,13 @@ public: > > bool isEffectfulExpressionStatement() const override { return true; } > >- Expression& effectfulExpression() { return *m_effectfulExpression; } >+ Expression& effectfulExpression() { return static_cast<Expression&>(m_effectfulExpression); } > > private: >- std::unique_ptr<Expression> m_effectfulExpression; >+ UniqueRef<Expression> m_effectfulExpression; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEnumerationDefinition.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEnumerationDefinition.h >index 7970b59e54a..c5723269886 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEnumerationDefinition.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEnumerationDefinition.h >@@ -29,8 +29,13 @@ > > #include "WHLSLEnumerationMember.h" > #include "WHLSLLexer.h" >-#include "WHLSLType.h" >+#include "WHLSLNamedType.h" >+#include "WHLSLUnnamedType.h" >+#include <memory> >+#include <wtf/HashMap.h> >+#include <wtf/UniqueRef.h> > #include <wtf/Vector.h> >+#include <wtf/text/StringHash.h> > #include <wtf/text/WTFString.h> > > namespace WebCore { >@@ -39,13 +44,11 @@ namespace WHLSL { > > namespace AST { > >-class EnumerationDefinition : public Node { >+class EnumerationDefinition : public NamedType { > public: >- EnumerationDefinition(Lexer::Token&& origin, String&& name, std::unique_ptr<Type>&& type, EnumerationMembers&& members) >- : m_origin(WTFMove(origin)) >- , m_name(WTFMove(name)) >+ EnumerationDefinition(Lexer::Token&& origin, String&& name, std::unique_ptr<UnnamedType>&& type) >+ : NamedType(WTFMove(origin), WTFMove(name)) > , m_type(WTFMove(type)) >- , m_members(WTFMove(members)) > { > } > >@@ -54,20 +57,43 @@ public: > EnumerationDefinition(const EnumerationDefinition&) = delete; > EnumerationDefinition(EnumerationDefinition&&) = default; > >- Type& type() { return *m_type; } >- EnumerationMembers& enumerationMembers() { return m_members; } >+ bool isEnumerationDefinition() const override { return true; } >+ >+ UnnamedType& type() { return *m_type; } >+ >+ bool add(EnumerationMember&& member) >+ { >+ auto result = m_members.add(member.name(), std::make_unique<EnumerationMember>(WTFMove(member))); >+ return !result.isNewEntry; >+ } >+ >+ EnumerationMember* memberByName(const String& name) >+ { >+ auto iterator = m_members.find(name); >+ if (iterator == m_members.end()) >+ return nullptr; >+ return iterator->value.get(); >+ } >+ >+ Vector<std::reference_wrapper<EnumerationMember>> enumerationMembers() >+ { >+ Vector<std::reference_wrapper<EnumerationMember>> result; >+ for (auto& pair : m_members) >+ result.append(*pair.value); >+ return result; >+ } > > private: >- Lexer::Token m_origin; >- String m_name; >- std::unique_ptr<Type> m_type; >- EnumerationMembers m_members; >+ std::unique_ptr<UnnamedType> m_type; >+ HashMap<String, std::unique_ptr<EnumerationMember>> m_members; > }; > >-} >+} // namespace AST > > } > > } > >+SPECIALIZE_TYPE_TRAITS_WHLSL_NAMED_TYPE(EnumerationDefinition, isEnumerationDefinition()) >+ > #endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEnumerationMember.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEnumerationMember.h >index 9d9d854883e..afeb18600e9 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEnumerationMember.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEnumerationMember.h >@@ -54,17 +54,25 @@ public: > EnumerationMember(const EnumerationMember&) = delete; > EnumerationMember(EnumerationMember&&) = default; > >+ const Lexer::Token& origin() const { return m_origin; } >+ String& name() { return m_name; } > Optional<ConstantExpression>& value() { return m_value; } > >+ void setValue(ConstantExpression&& value) >+ { >+ ASSERT(!m_value); >+ m_value = WTFMove(value); >+ } >+ > private: > Lexer::Token m_origin; > String m_name; > Optional<ConstantExpression> m_value; > }; > >-typedef Vector<EnumerationMember> EnumerationMembers; >+using EnumerationMembers = Vector<EnumerationMember>; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEnumerationMemberLiteral.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEnumerationMemberLiteral.h >new file mode 100644 >index 00000000000..4095af33f29 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEnumerationMemberLiteral.h >@@ -0,0 +1,69 @@ >+/* >+ * 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 "WHLSLEnumerationMember.h" >+#include "WHLSLExpression.h" >+#include "WHLSLLexer.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class EnumerationMemberLiteral : public Expression { >+public: >+ EnumerationMemberLiteral(Lexer::Token&& origin, EnumerationMember& enumerationMember) >+ : Expression(WTFMove(origin)) >+ , m_enumerationMember(enumerationMember) >+ { >+ } >+ >+ virtual ~EnumerationMemberLiteral() = default; >+ >+ EnumerationMemberLiteral(const EnumerationMemberLiteral&) = delete; >+ EnumerationMemberLiteral(EnumerationMemberLiteral&&) = default; >+ >+ bool isEnumerationMemberLiteral() const override { return true; } >+ >+ EnumerationMember& enumerationMember() { return m_enumerationMember; } >+ >+private: >+ EnumerationMember& m_enumerationMember; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_EXPRESSION(EnumerationMemberLiteral, isEnumerationMemberLiteral()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLExpression.h >index e368383646d..8fafa29fe67 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLExpression.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLExpression.h >@@ -48,14 +48,19 @@ public: > explicit Expression(const Expression&) = default; > Expression(Expression&&) = default; > >- Lexer::Token origin() const { return m_origin; } >+ Expression& operator=(const Expression&) = default; >+ Expression& operator=(Expression&&) = default; >+ >+ const Lexer::Token& origin() const { return m_origin; } > > virtual bool isAssignmentExpression() const { return false; } > virtual bool isBooleanLiteral() const { return false; } > virtual bool isCallExpression() const { return false; } > virtual bool isCommaExpression() const { return false; } > virtual bool isDereferenceExpression() const { return false; } >+ virtual bool isDotExpression() const { return false; } > virtual bool isFloatLiteral() const { return false; } >+ virtual bool isIndexExpression() const { return false; } > virtual bool isIntegerLiteral() const { return false; } > virtual bool isLogicalExpression() const { return false; } > virtual bool isLogicalNotExpression() const { return false; } >@@ -67,12 +72,13 @@ public: > virtual bool isTernaryExpression() const { return false; } > virtual bool isUnsignedIntegerLiteral() const { return false; } > virtual bool isVariableReference() const { return false; } >+ virtual bool isEnumerationMemberLiteral() const { return false; } > > private: > Lexer::Token m_origin; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFallthrough.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFallthrough.h >index 099157d4e6d..4e66c9a4f54 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFallthrough.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFallthrough.h >@@ -53,7 +53,7 @@ public: > private: > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteral.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteral.h >index cbf5469dbfa..2263b4a2043 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteral.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteral.h >@@ -28,6 +28,7 @@ > #if ENABLE(WEBGPU) > > #include "WHLSLExpression.h" >+#include "WHLSLFloatLiteralType.h" > #include "WHLSLLexer.h" > > namespace WebCore { >@@ -39,25 +40,39 @@ namespace AST { > class FloatLiteral : public Expression { > public: > FloatLiteral(Lexer::Token&& origin, float value) >- : Expression(WTFMove(origin)) >+ : Expression(Lexer::Token(origin)) >+ , m_type(WTFMove(origin), value) > , m_value(value) > { > } > > virtual ~FloatLiteral() = default; > >- explicit FloatLiteral(const FloatLiteral&) = default; >+ FloatLiteral(const FloatLiteral&) = delete; > FloatLiteral(FloatLiteral&&) = default; > >+ FloatLiteral& operator=(const FloatLiteral&) = delete; >+ FloatLiteral& operator=(FloatLiteral&&) = default; >+ >+ FloatLiteralType& type() { return m_type; } > float value() const { return m_value; } > > bool isFloatLiteral() const override { return true; } > >+ FloatLiteral clone() const >+ { >+ FloatLiteral result(Lexer::Token(origin()), m_value); >+ if (result.m_type.resolvedType()) >+ result.m_type.resolve(result.m_type.resolvedType()->clone()); >+ return result; >+ } >+ > private: >+ FloatLiteralType m_type; > float m_value; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteralType.cpp b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteralType.cpp >new file mode 100644 >index 00000000000..c8266b8b4a5 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteralType.cpp >@@ -0,0 +1,76 @@ >+/* >+ * 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. >+ */ >+ >+#if ENABLE(WEBGPU) >+ >+#include "config.h" >+#include "WHLSLFloatLiteralType.h" >+ >+#include "WHLSLInferTypes.h" >+#include "WHLSLTypeReference.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+FloatLiteralType::FloatLiteralType(Lexer::Token&& origin, float value) >+ : m_value(value) >+ , m_preferredType(makeUniqueRef<TypeReference>(WTFMove(origin), String("float", String::ConstructFromLiteral), TypeArguments())) >+{ >+} >+ >+FloatLiteralType::~FloatLiteralType() = default; >+ >+bool FloatLiteralType::canResolve(const Type& type) const >+{ >+ if (!is<NamedType>(type)) >+ return false; >+ auto& namedType = downcast<NamedType>(type); >+ if (!is<NativeTypeDeclaration>(namedType)) >+ return false; >+ auto& nativeTypeDeclaration = downcast<NativeTypeDeclaration>(namedType); >+ if (!nativeTypeDeclaration.isFloating()) >+ return false; >+ if (!nativeTypeDeclaration.canRepresentFloat()(m_value)) >+ return false; >+ return true; >+} >+ >+unsigned FloatLiteralType::conversionCost(const UnnamedType& unnamedType) const >+{ >+ if (matches(unnamedType, static_cast<const TypeReference&>(m_preferredType))) >+ return 0; >+ return 1; >+} >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteralType.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteralType.h >new file mode 100644 >index 00000000000..1aad2f47c65 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteralType.h >@@ -0,0 +1,76 @@ >+/* >+ * 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 "WHLSLResolvableType.h" >+#include <wtf/UniqueRef.h> >+#include <wtf/text/WTFString.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class TypeReference; >+ >+class FloatLiteralType : public ResolvableType { >+public: >+ FloatLiteralType(Lexer::Token&& origin, float value); >+ >+ virtual ~FloatLiteralType(); >+ >+ FloatLiteralType(const FloatLiteralType&) = delete; >+ FloatLiteralType(FloatLiteralType&&) = default; >+ >+ FloatLiteralType& operator=(const FloatLiteralType&) = delete; >+ FloatLiteralType& operator=(FloatLiteralType&&) = default; >+ >+ bool isFloatLiteralType() const override { return true; } >+ >+ TypeReference& preferredType() { return static_cast<TypeReference&>(m_preferredType); } >+ >+ bool canResolve(const Type&) const override; >+ unsigned conversionCost(const UnnamedType&) const override; >+ >+private: >+ float m_value; >+ // This is a unique_ptr to resolve a circular dependency between >+ // ConstantExpression -> LiteralType -> TypeReference -> TypeArguments -> ConstantExpression >+ UniqueRef<TypeReference> m_preferredType; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_RESOLVABLE_TYPE(FloatLiteralType, isFloatLiteralType()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLForLoop.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLForLoop.h >index 28fc1376dac..7639c68ccce 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLForLoop.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLForLoop.h >@@ -31,6 +31,8 @@ > #include "WHLSLLexer.h" > #include "WHLSLStatement.h" > #include "WHLSLVariableDeclarationsStatement.h" >+#include <memory> >+#include <wtf/UniqueRef.h> > #include <wtf/Variant.h> > #include <wtf/Vector.h> > >@@ -42,7 +44,7 @@ namespace AST { > > class ForLoop : public Statement { > public: >- ForLoop(Lexer::Token&& origin, Variant<VariableDeclarationsStatement, std::unique_ptr<Expression>>&& initialization, std::unique_ptr<Expression>&& condition, std::unique_ptr<Expression>&& increment, std::unique_ptr<Statement>&& body) >+ ForLoop(Lexer::Token&& origin, Variant<VariableDeclarationsStatement, UniqueRef<Expression>>&& initialization, std::unique_ptr<Expression>&& condition, std::unique_ptr<Expression>&& increment, UniqueRef<Statement>&& body) > : Statement(WTFMove(origin)) > , m_initialization(WTFMove(initialization)) > , m_condition(WTFMove(condition)) >@@ -60,19 +62,19 @@ public: > > bool isForLoop() const override { return true; } > >- Variant<VariableDeclarationsStatement, std::unique_ptr<Expression>>& initialization() { return m_initialization; } >+ Variant<VariableDeclarationsStatement, UniqueRef<Expression>>& initialization() { return m_initialization; } > Expression* condition() { return m_condition.get(); } > Expression* increment() { return m_increment.get(); } >- Statement& body() { return *m_body; } >+ Statement& body() { return static_cast<Statement&>(m_body); } > > private: >- Variant<VariableDeclarationsStatement, std::unique_ptr<Expression>> m_initialization; >- std::unique_ptr<Expression> m_condition; // nullable >- std::unique_ptr<Expression> m_increment; // nullable >- std::unique_ptr<Statement> m_body; >+ Variant<VariableDeclarationsStatement, UniqueRef<Expression>> m_initialization; >+ std::unique_ptr<Expression> m_condition; >+ std::unique_ptr<Expression> m_increment; >+ UniqueRef<Statement> m_body; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFunctionAttribute.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFunctionAttribute.h >index cbd72d4a90c..7749be6522f 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFunctionAttribute.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFunctionAttribute.h >@@ -37,10 +37,10 @@ namespace WHLSL { > > namespace AST { > >-typedef Variant<NumThreadsFunctionAttribute> FunctionAttribute; >-typedef Vector<FunctionAttribute> AttributeBlock; >+using FunctionAttribute = Variant<NumThreadsFunctionAttribute>; >+using AttributeBlock = Vector<FunctionAttribute>; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFunctionDeclaration.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFunctionDeclaration.h >index 7a7e0a0656c..cbbacaac47e 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFunctionDeclaration.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFunctionDeclaration.h >@@ -30,9 +30,10 @@ > #include "WHLSLFunctionAttribute.h" > #include "WHLSLLexer.h" > #include "WHLSLNode.h" >-#include "WHLSLParameter.h" > #include "WHLSLSemantic.h" >-#include "WHLSLType.h" >+#include "WHLSLUnnamedType.h" >+#include "WHLSLVariableDeclaration.h" >+#include <wtf/UniqueRef.h> > #include <wtf/text/WTFString.h> > > namespace WebCore { >@@ -43,13 +44,14 @@ namespace AST { > > class FunctionDeclaration : public Node { > public: >- enum class EntryPointType { >+ enum class EntryPointType : uint8_t { > Vertex, > Fragment, >- Compute >+ Compute, >+ // FIXME: Add an entry point type for testing > }; > >- FunctionDeclaration(Lexer::Token&& origin, AttributeBlock&& attributeBlock, Optional<EntryPointType> entryPointType, std::unique_ptr<AST::Type>&& type, String&& name, Parameters&& parameters, Optional<AST::Semantic>&& semantic) >+ FunctionDeclaration(Lexer::Token&& origin, AttributeBlock&& attributeBlock, Optional<EntryPointType> entryPointType, UniqueRef<AST::UnnamedType>&& type, String&& name, VariableDeclarations&& parameters, Optional<AST::Semantic>&& semantic, bool isOperator) > : m_origin(WTFMove(origin)) > , m_attributeBlock(WTFMove(attributeBlock)) > , m_entryPointType(entryPointType) >@@ -57,6 +59,7 @@ public: > , m_name(WTFMove(name)) > , m_parameters(WTFMove(parameters)) > , m_semantic(WTFMove(semantic)) >+ , m_isOperator(WTFMove(isOperator)) > { > } > >@@ -65,33 +68,40 @@ public: > FunctionDeclaration(const FunctionDeclaration&) = delete; > FunctionDeclaration(FunctionDeclaration&&) = default; > >+ virtual bool isFunctionDefinition() const { return false; } >+ virtual bool isNativeFunctionDeclaration() const { return false; } >+ > AttributeBlock& attributeBlock() { return m_attributeBlock; } >- AST::Type& type() { return *m_type; } >- Parameters& parameters() { return m_parameters; } >+ const Optional<EntryPointType>& entryPointType() const { return m_entryPointType; } >+ const AST::UnnamedType& type() const { return static_cast<const AST::UnnamedType&>(m_type); } >+ AST::UnnamedType& type() { return static_cast<AST::UnnamedType&>(m_type); } >+ const String& name() const { return m_name; } >+ bool isCast() const { return m_name == "operator cast"; } >+ const VariableDeclarations& parameters() const { return m_parameters; } >+ VariableDeclarations& parameters() { return m_parameters; } > Optional<AST::Semantic>& semantic() { return m_semantic; } >- >- Lexer::Token&& takeOrigin() { return WTFMove(m_origin); } >- AttributeBlock&& takeAttributeBlock() { return WTFMove(m_attributeBlock); } >- Optional<EntryPointType>&& takeEntryPointType() { return WTFMove(m_entryPointType); } >- std::unique_ptr<AST::Type>&& takeType() { return WTFMove(m_type); } >- String&& takeName() { return WTFMove(m_name); } >- Parameters&& takeParameters() { return WTFMove(m_parameters); } >- Optional<AST::Semantic>&& takeSemantic() { return WTFMove(m_semantic); } >+ bool isOperator() const { return m_isOperator; } > > private: > Lexer::Token m_origin; > AttributeBlock m_attributeBlock; > Optional<EntryPointType> m_entryPointType; >- std::unique_ptr<AST::Type> m_type; >+ UniqueRef<UnnamedType> m_type; > String m_name; >- Parameters m_parameters; >+ VariableDeclarations m_parameters; > Optional<AST::Semantic> m_semantic; >+ bool m_isOperator; > }; > >-} >+} // namespace AST > > } > > } > >+#define SPECIALIZE_TYPE_TRAITS_WHLSL_FUNCTION_DECLARATION(ToValueTypeName, predicate) \ >+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::WHLSL::AST::ToValueTypeName) \ >+ static bool isType(const WebCore::WHLSL::AST::FunctionDeclaration& type) { return type.predicate; } \ >+SPECIALIZE_TYPE_TRAITS_END() >+ > #endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFunctionDefinition.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFunctionDefinition.h >index a4907b0d298..2a4b9834750 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFunctionDefinition.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFunctionDefinition.h >@@ -50,6 +50,8 @@ public: > FunctionDefinition(const FunctionDefinition&) = delete; > FunctionDefinition(FunctionDefinition&&) = default; > >+ bool isFunctionDefinition() const override { return true; } >+ > Block& block() { return m_block; } > bool restricted() const { return m_restricted; } > >@@ -58,10 +60,12 @@ private: > bool m_restricted; > }; > >-} >+} // namespace AST > > } > > } > >+SPECIALIZE_TYPE_TRAITS_WHLSL_FUNCTION_DECLARATION(FunctionDefinition, isFunctionDefinition()) >+ > #endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIfStatement.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIfStatement.h >index 1ef10e2e71d..fc20d7613ad 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIfStatement.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIfStatement.h >@@ -30,6 +30,8 @@ > #include "WHLSLExpression.h" > #include "WHLSLLexer.h" > #include "WHLSLStatement.h" >+#include <memory> >+#include <wtf/UniqueRef.h> > > namespace WebCore { > >@@ -39,7 +41,7 @@ namespace AST { > > class IfStatement : public Statement { > public: >- IfStatement(Lexer::Token&& origin, std::unique_ptr<Expression>&& conditional, std::unique_ptr<Statement>&& body, std::unique_ptr<Statement>&& elseBody) >+ IfStatement(Lexer::Token&& origin, UniqueRef<Expression>&& conditional, UniqueRef<Statement>&& body, std::unique_ptr<Statement>&& elseBody) > : Statement(WTFMove(origin)) > , m_conditional(WTFMove(conditional)) > , m_body(WTFMove(body)) >@@ -54,17 +56,17 @@ public: > > bool isIfStatement() const override { return true; } > >- Expression& conditional() { return *m_conditional; } >- Statement& body() { return *m_body; } >+ Expression& conditional() { return static_cast<Expression&>(m_conditional); } >+ Statement& body() { return static_cast<Statement&>(m_body); } > Statement* elseBody() { return m_elseBody.get(); } > > private: >- std::unique_ptr<Expression> m_conditional; >- std::unique_ptr<Statement> m_body; >- std::unique_ptr<Statement> m_elseBody; // nullable >+ UniqueRef<Expression> m_conditional; >+ UniqueRef<Statement> m_body; >+ std::unique_ptr<Statement> m_elseBody; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIndexExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIndexExpression.h >index 6bb6a0f0dab..33901fca580 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIndexExpression.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIndexExpression.h >@@ -29,6 +29,7 @@ > > #include "WHLSLLexer.h" > #include "WHLSLPropertyAccessExpression.h" >+#include <wtf/UniqueRef.h> > > namespace WebCore { > >@@ -38,7 +39,7 @@ namespace AST { > > class IndexExpression : public PropertyAccessExpression { > public: >- IndexExpression(Lexer::Token&& origin, std::unique_ptr<Expression>&& base, std::unique_ptr<Expression>&& index) >+ IndexExpression(Lexer::Token&& origin, UniqueRef<Expression>&& base, UniqueRef<Expression>&& index) > : PropertyAccessExpression(WTFMove(origin), WTFMove(base)) > , m_index(WTFMove(index)) > { >@@ -49,14 +50,35 @@ public: > IndexExpression(const IndexExpression&) = delete; > IndexExpression(IndexExpression&&) = default; > >+ bool isIndexExpression() const override { return true; } >+ >+ String getFunctionName() const override >+ { >+ return String("operator[]", String::ConstructFromLiteral); >+ } >+ >+ String setFunctionName() const override >+ { >+ return String("operator&[]", String::ConstructFromLiteral); >+ } >+ >+ String andFunctionName() const override >+ { >+ return String("operator[]=", String::ConstructFromLiteral); >+ } >+ >+ Expression& indexExpression() { return static_cast<Expression&>(m_index); } >+ > private: >- std::unique_ptr<Expression> m_index; >+ UniqueRef<Expression> m_index; > }; > >-} >+} // namespace AST > > } > > } > >+SPECIALIZE_TYPE_TRAITS_WHLSL_EXPRESSION(IndexExpression, isIndexExpression()) >+ > #endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.cpp b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.cpp >new file mode 100644 >index 00000000000..7e4ffb30b01 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.cpp >@@ -0,0 +1,55 @@ >+/* >+ * 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. >+ */ >+ >+#if ENABLE(WEBGPU) >+ >+#include "config.h" >+#include "WHLSLIntegerLiteral.h" >+ >+#include "WHLSLNativeTypeDeclaration.h" >+#include "WHLSLTypeReference.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+int64_t IntegerLiteral::valueForSelectedType() const >+{ >+ ASSERT(m_type.resolvedType()); >+ auto& typeReference = downcast<TypeReference>(*m_type.resolvedType()); >+ ASSERT(typeReference.resolvedType()); >+ auto& nativeTypeDeclaration = downcast<NativeTypeDeclaration>(*typeReference.resolvedType()); >+ return nativeTypeDeclaration.formatValueFromInteger()(m_value); >+} >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.h >index 6854dd27f0c..cc9a0ed5846 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.h >@@ -28,6 +28,7 @@ > #if ENABLE(WEBGPU) > > #include "WHLSLExpression.h" >+#include "WHLSLIntegerLiteralType.h" > #include "WHLSLLexer.h" > > namespace WebCore { >@@ -39,25 +40,41 @@ namespace AST { > class IntegerLiteral : public Expression { > public: > IntegerLiteral(Lexer::Token&& origin, int value) >- : Expression(WTFMove(origin)) >+ : Expression(Lexer::Token(origin)) >+ , m_type(WTFMove(origin), value) > , m_value(value) > { > } > > virtual ~IntegerLiteral() = default; > >- explicit IntegerLiteral(const IntegerLiteral&) = default; >+ IntegerLiteral(const IntegerLiteral&) = delete; > IntegerLiteral(IntegerLiteral&&) = default; > >+ IntegerLiteral& operator=(const IntegerLiteral&) = delete; >+ IntegerLiteral& operator=(IntegerLiteral&&) = default; >+ >+ IntegerLiteralType& type() { return m_type; } > int value() const { return m_value; } > > bool isIntegerLiteral() const override { return true; } > >+ IntegerLiteral clone() const >+ { >+ IntegerLiteral result(Lexer::Token(origin()), m_value); >+ if (result.m_type.resolvedType()) >+ result.m_type.resolve(result.m_type.resolvedType()->clone()); >+ return result; >+ } >+ >+ int64_t valueForSelectedType() const; >+ > private: >+ IntegerLiteralType m_type; > int m_value; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteralType.cpp b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteralType.cpp >new file mode 100644 >index 00000000000..f80930b6182 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteralType.cpp >@@ -0,0 +1,75 @@ >+/* >+ * 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. >+ */ >+ >+#if ENABLE(WEBGPU) >+ >+#include "config.h" >+#include "WHLSLIntegerLiteralType.h" >+ >+#include "WHLSLInferTypes.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+IntegerLiteralType::IntegerLiteralType(Lexer::Token&& origin, int value) >+ : m_value(value) >+ , m_preferredType(makeUniqueRef<TypeReference>(WTFMove(origin), String("int", String::ConstructFromLiteral), TypeArguments())) >+{ >+} >+ >+IntegerLiteralType::~IntegerLiteralType() = default; >+ >+bool IntegerLiteralType::canResolve(const Type& type) const >+{ >+ if (!is<NamedType>(type)) >+ return false; >+ auto& namedType = downcast<NamedType>(type); >+ if (!is<NativeTypeDeclaration>(namedType)) >+ return false; >+ auto& nativeTypeDeclaration = downcast<NativeTypeDeclaration>(namedType); >+ if (!nativeTypeDeclaration.isNumber()) >+ return false; >+ if (!nativeTypeDeclaration.canRepresentInteger()(m_value)) >+ return false; >+ return true; >+} >+ >+unsigned IntegerLiteralType::conversionCost(const UnnamedType& unnamedType) const >+{ >+ if (matches(unnamedType, static_cast<const TypeReference&>(m_preferredType))) >+ return 0; >+ return 1; >+} >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteralType.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteralType.h >new file mode 100644 >index 00000000000..8acaf2e9f8c >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteralType.h >@@ -0,0 +1,76 @@ >+/* >+ * 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 "WHLSLResolvableType.h" >+#include <wtf/UniqueRef.h> >+#include <wtf/text/WTFString.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class TypeReference; >+ >+class IntegerLiteralType : public ResolvableType { >+public: >+ IntegerLiteralType(Lexer::Token&& origin, int value); >+ >+ virtual ~IntegerLiteralType(); >+ >+ IntegerLiteralType(const IntegerLiteralType&) = delete; >+ IntegerLiteralType(IntegerLiteralType&&) = default; >+ >+ IntegerLiteralType& operator=(const IntegerLiteralType&) = delete; >+ IntegerLiteralType& operator=(IntegerLiteralType&&) = default; >+ >+ bool isIntegerLiteralType() const override { return true; } >+ >+ TypeReference& preferredType() { return static_cast<TypeReference&>(m_preferredType); } >+ >+ bool canResolve(const Type&) const override; >+ unsigned conversionCost(const UnnamedType&) const override; >+ >+private: >+ int m_value; >+ // This is a unique_ptr to resolve a circular dependency between >+ // ConstantExpression -> LiteralType -> TypeReference -> TypeArguments -> ConstantExpression >+ UniqueRef<TypeReference> m_preferredType; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_RESOLVABLE_TYPE(IntegerLiteralType, isIntegerLiteralType()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLLogicalExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLLogicalExpression.h >index d996fa5f5d4..78718bdfa95 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLLogicalExpression.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLLogicalExpression.h >@@ -29,6 +29,7 @@ > > #include "WHLSLExpression.h" > #include "WHLSLLexer.h" >+#include <wtf/UniqueRef.h> > > namespace WebCore { > >@@ -38,12 +39,12 @@ namespace AST { > > class LogicalExpression : public Expression { > public: >- enum class Type { >+ enum class Type : uint8_t { > And, > Or > }; > >- LogicalExpression(Lexer::Token&& origin, Type type, std::unique_ptr<Expression>&& left, std::unique_ptr<Expression>&& right) >+ LogicalExpression(Lexer::Token&& origin, Type type, UniqueRef<Expression>&& left, UniqueRef<Expression>&& right) > : Expression(WTFMove(origin)) > , m_type(type) > , m_left(WTFMove(left)) >@@ -60,16 +61,16 @@ public: > > bool isLogicalExpression() const override { return true; } > >- Expression& left() { return *m_left; } >- Expression& right() { return *m_right; } >+ Expression& left() { return static_cast<Expression&>(m_left); } >+ Expression& right() { return static_cast<Expression&>(m_right); } > > private: > Type m_type; >- std::unique_ptr<Expression> m_left; >- std::unique_ptr<Expression> m_right; >+ UniqueRef<Expression> m_left; >+ UniqueRef<Expression> m_right; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLLogicalNotExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLLogicalNotExpression.h >index 2d4f0cb8619..decad35b526 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLLogicalNotExpression.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLLogicalNotExpression.h >@@ -29,6 +29,7 @@ > > #include "WHLSLExpression.h" > #include "WHLSLLexer.h" >+#include <wtf/UniqueRef.h> > > namespace WebCore { > >@@ -38,7 +39,7 @@ namespace AST { > > class LogicalNotExpression : public Expression { > public: >- LogicalNotExpression(Lexer::Token&& origin, std::unique_ptr<Expression>&& operand) >+ LogicalNotExpression(Lexer::Token&& origin, UniqueRef<Expression>&& operand) > : Expression(WTFMove(origin)) > , m_operand(WTFMove(operand)) > { >@@ -51,13 +52,13 @@ public: > > bool isLogicalNotExpression() const override { return true; } > >- Expression& operand() { return *m_operand; } >+ Expression& operand() { return static_cast<Expression&>(m_operand); } > > private: >- std::unique_ptr<Expression> m_operand; >+ UniqueRef<Expression> m_operand; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLMakeArrayReferenceExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLMakeArrayReferenceExpression.h >index 9ab79983eff..6688f87f396 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLMakeArrayReferenceExpression.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLMakeArrayReferenceExpression.h >@@ -29,6 +29,7 @@ > > #include "WHLSLExpression.h" > #include "WHLSLLexer.h" >+#include <wtf/UniqueRef.h> > > namespace WebCore { > >@@ -38,7 +39,7 @@ namespace AST { > > class MakeArrayReferenceExpression : public Expression { > public: >- MakeArrayReferenceExpression(Lexer::Token&& origin, std::unique_ptr<Expression>&& lValue) >+ MakeArrayReferenceExpression(Lexer::Token&& origin, UniqueRef<Expression>&& lValue) > : Expression(WTFMove(origin)) > , m_lValue(WTFMove(lValue)) > { >@@ -51,13 +52,13 @@ public: > > bool isMakeArrayReferenceExpression() const override { return true; } > >- Expression& lValue() { return *m_lValue; } >+ Expression& lValue() { return static_cast<Expression&>(m_lValue); } > > private: >- std::unique_ptr<Expression> m_lValue; >+ UniqueRef<Expression> m_lValue; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLMakePointerExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLMakePointerExpression.h >index 2a6b8510e31..0da4be589dc 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLMakePointerExpression.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLMakePointerExpression.h >@@ -29,6 +29,7 @@ > > #include "WHLSLExpression.h" > #include "WHLSLLexer.h" >+#include <wtf/UniqueRef.h> > > namespace WebCore { > >@@ -38,7 +39,7 @@ namespace AST { > > class MakePointerExpression : public Expression { > public: >- MakePointerExpression(Lexer::Token&& origin, std::unique_ptr<Expression>&& lValue) >+ MakePointerExpression(Lexer::Token&& origin, UniqueRef<Expression>&& lValue) > : Expression(WTFMove(origin)) > , m_lValue(WTFMove(lValue)) > { >@@ -51,13 +52,13 @@ public: > > bool isMakePointerExpression() const override { return true; } > >- Expression& lValue() { return *m_lValue; } >+ Expression& lValue() { return static_cast<Expression&>(m_lValue); } > > private: >- std::unique_ptr<Expression> m_lValue; >+ UniqueRef<Expression> m_lValue; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNamedType.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNamedType.h >new file mode 100644 >index 00000000000..f90dbef3cd8 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNamedType.h >@@ -0,0 +1,84 @@ >+/* >+ * 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 "WHLSLLexer.h" >+#include "WHLSLNode.h" >+#include "WHLSLType.h" >+#include <wtf/text/WTFString.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class NamedType : public Type { >+public: >+ NamedType(Lexer::Token&& origin, String&& name) >+ : m_origin(WTFMove(origin)) >+ , m_name(WTFMove(name)) >+ { >+ } >+ >+ virtual ~NamedType() = default; >+ >+ NamedType(const NamedType&) = delete; >+ NamedType(NamedType&&) = default; >+ >+ const Lexer::Token& origin() const { return m_origin; } >+ String& name() { return m_name; } >+ >+ bool isNamedType() const override { return true; } >+ virtual bool isTypeDefinition() const { return false; } >+ virtual bool isStructureDefinition() const { return false; } >+ virtual bool isEnumerationDefinition() const { return false; } >+ virtual bool isNativeTypeDeclaration() const { return false; } >+ >+ virtual const Type& unifyNode() const { return *this; } >+ virtual Type& unifyNode() { return *this; } >+ >+private: >+ Lexer::Token m_origin; >+ String m_name; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#define SPECIALIZE_TYPE_TRAITS_WHLSL_NAMED_TYPE(ToValueTypeName, predicate) \ >+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::WHLSL::AST::ToValueTypeName) \ >+ static bool isType(const WebCore::WHLSL::AST::NamedType& type) { return type.predicate; } \ >+SPECIALIZE_TYPE_TRAITS_END() >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_TYPE(NamedType, isNamedType()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNativeFunctionDeclaration.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNativeFunctionDeclaration.h >index 010e6eba700..06d8e36223e 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNativeFunctionDeclaration.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNativeFunctionDeclaration.h >@@ -37,8 +37,8 @@ namespace AST { > > class NativeFunctionDeclaration : public FunctionDeclaration { > public: >- NativeFunctionDeclaration(Lexer::Token&& origin, AttributeBlock&& attributeBlock, Optional<EntryPointType> entryPointType, std::unique_ptr<AST::Type>&& type, String&& name, Parameters&& parameters, Optional<AST::Semantic>&& semantic, bool restricted) >- : FunctionDeclaration(WTFMove(origin), WTFMove(attributeBlock), WTFMove(entryPointType), WTFMove(type), WTFMove(name), WTFMove(parameters), WTFMove(semantic)) >+ NativeFunctionDeclaration(FunctionDeclaration&& functionDeclaration, bool restricted) >+ : FunctionDeclaration(WTFMove(functionDeclaration)) > , m_restricted(restricted) > { > } >@@ -48,16 +48,20 @@ public: > NativeFunctionDeclaration(const NativeFunctionDeclaration&) = delete; > NativeFunctionDeclaration(NativeFunctionDeclaration&&) = default; > >+ bool isNativeFunctionDeclaration() const override { return true; } >+ > bool restricted() const { return m_restricted; } > > private: > bool m_restricted; > }; > >-} >+} // namespace AST > > } > > } > >+SPECIALIZE_TYPE_TRAITS_WHLSL_FUNCTION_DECLARATION(NativeFunctionDeclaration, isNativeFunctionDeclaration()) >+ > #endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNativeTypeDeclaration.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNativeTypeDeclaration.h >index 320abc3c475..e7980b4f40f 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNativeTypeDeclaration.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNativeTypeDeclaration.h >@@ -28,7 +28,7 @@ > #if ENABLE(WEBGPU) > > #include "WHLSLLexer.h" >-#include "WHLSLType.h" >+#include "WHLSLNamedType.h" > #include "WHLSLTypeArgument.h" > #include <wtf/text/WTFString.h> > >@@ -38,11 +38,10 @@ namespace WHLSL { > > namespace AST { > >-class NativeTypeDeclaration : public Type { >+class NativeTypeDeclaration : public NamedType { > public: > NativeTypeDeclaration(Lexer::Token&& origin, String&& name, TypeArguments&& typeArguments) >- : m_origin(WTFMove(origin)) >- , m_name(WTFMove(name)) >+ : NamedType(WTFMove(origin), WTFMove(name)) > , m_typeArguments(WTFMove(typeArguments)) > { > } >@@ -52,24 +51,67 @@ public: > NativeTypeDeclaration(const NativeTypeDeclaration&) = delete; > NativeTypeDeclaration(NativeTypeDeclaration&&) = default; > >+ bool isNativeTypeDeclaration() const override { return true; } >+ >+ const String& name() const { return m_name; } >+ String& name() { return m_name; } > TypeArguments& typeArguments() { return m_typeArguments; } > >- std::unique_ptr<Type> clone() const override >- { >- ASSERT_NOT_REACHED(); >- return nullptr; >- } >+ bool isInt() const { return m_isInt; } >+ bool isNumber() const { return m_isNumber; } >+ bool isFloating() const { return m_isFloating; } >+ bool isVector() const { return m_isVector; } >+ bool isMatrix() const { return m_isMatrix; } >+ bool isTexture() const { return m_isTexture; } >+ bool isSigned() const { return m_isSigned; } >+ const std::function<bool(int)>& canRepresentInteger() const { return m_canRepresentInteger; } >+ const std::function<bool(unsigned)>& canRepresentUnsignedInteger() const { return m_canRepresentUnsignedInteger; } >+ const std::function<bool(float)>& canRepresentFloat() const { return m_canRepresentFloat; } >+ const std::function<int64_t(int64_t)>& successor() const { return m_successor; } >+ const std::function<int64_t(int)>& formatValueFromInteger() const { return m_formatValueFromInteger; } >+ const std::function<int64_t(unsigned)>& formatValueFromUnsignedInteger() const { return m_formatValueFromUnsignedInteger; } >+ void iterateAllValues(const std::function<bool(int64_t)>& callback) { m_iterateAllValues(callback); } >+ >+ void setIsInt() { m_isInt = true; } >+ void setIsNumber() { m_isNumber = true; } >+ void setIsFloating() { m_isFloating = true; } >+ void setIsVector() { m_isVector = true; } >+ void setIsMatrix() { m_isMatrix = true; } >+ void setIsTexture() { m_isTexture = true; } >+ void setIsSigned() { m_isSigned = true; } >+ void setCanRepresentInteger(std::function<bool(int)>&& canRepresent) { m_canRepresentInteger = WTFMove(canRepresent); } >+ void setCanRepresentUnsignedInteger(std::function<bool(unsigned)>&& canRepresent) { m_canRepresentUnsignedInteger = WTFMove(canRepresent); } >+ void setCanRepresentFloat(std::function<bool(float)>&& canRepresent) { m_canRepresentFloat = WTFMove(canRepresent); } >+ void setSuccessor(std::function<int64_t(int64_t)>&& successor) { m_successor = WTFMove(successor); } >+ void setFormatValueFromInteger(std::function<int64_t(int)>&& formatValue) { m_formatValueFromInteger = WTFMove(formatValue); } >+ void setFormatValueFromUnsignedInteger(std::function<int64_t(unsigned)>&& formatValue) { m_formatValueFromUnsignedInteger = WTFMove(formatValue); } >+ void setIterateAllValues(std::function<void(const std::function<bool(int64_t)>&)>&& iterateAllValues) { m_iterateAllValues = WTFMove(iterateAllValues); } > > private: >- Lexer::Token m_origin; > String m_name; > TypeArguments m_typeArguments; >+ std::function<bool(int)> m_canRepresentInteger; >+ std::function<bool(unsigned)> m_canRepresentUnsignedInteger; >+ std::function<bool(float)> m_canRepresentFloat; >+ std::function<int64_t(int64_t)> m_successor; >+ std::function<int64_t(int)> m_formatValueFromInteger; >+ std::function<int64_t(unsigned)> m_formatValueFromUnsignedInteger; >+ std::function<void(const std::function<bool(int64_t)>&)> m_iterateAllValues; >+ bool m_isInt { false }; >+ bool m_isNumber { false }; >+ bool m_isFloating { false }; >+ bool m_isVector { false }; >+ bool m_isMatrix { false }; >+ bool m_isTexture { false }; >+ bool m_isSigned { false }; > }; > >-} >+} // namespace AST > > } > > } > >+SPECIALIZE_TYPE_TRAITS_WHLSL_NAMED_TYPE(NativeTypeDeclaration, isNativeTypeDeclaration()) >+ > #endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNode.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNode.h >index f6c4f0060c0..c1790b5e1ea 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNode.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNode.h >@@ -42,10 +42,13 @@ public: > explicit Node(const Node&) = default; > Node(Node&&) = default; > >+ Node& operator=(const Node&) = default; >+ Node& operator=(Node&&) = default; >+ > private: > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h >index ee647cf9d39..050272fe661 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h >@@ -29,6 +29,7 @@ > > #include "WHLSLExpression.h" > #include "WHLSLLexer.h" >+#include "WHLSLNullLiteralType.h" > > namespace WebCore { > >@@ -45,15 +46,29 @@ public: > > virtual ~NullLiteral() = default; > >- explicit NullLiteral(const NullLiteral&) = default; >+ NullLiteral(const NullLiteral&) = delete; > NullLiteral(NullLiteral&&) = default; > >+ NullLiteral& operator=(const NullLiteral&) = delete; >+ NullLiteral& operator=(NullLiteral&&) = default; >+ >+ NullLiteralType& type() { return m_type; } >+ > bool isNullLiteral() const override { return true; } > >+ NullLiteral clone() const >+ { >+ auto result = NullLiteral(Lexer::Token(origin())); >+ if (result.m_type.resolvedType()) >+ result.m_type.resolve(result.m_type.resolvedType()->clone()); >+ return result; >+ } >+ > private: >+ NullLiteralType m_type; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteralType.cpp b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteralType.cpp >new file mode 100644 >index 00000000000..39c11fd54e5 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteralType.cpp >@@ -0,0 +1,60 @@ >+/* >+ * 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. >+ */ >+ >+#if ENABLE(WEBGPU) >+ >+#include "config.h" >+#include "WHLSLNullLiteralType.h" >+ >+#include "WHLSLReferenceType.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+bool NullLiteralType::canResolve(const Type& type) const >+{ >+ if (!is<UnnamedType>(type)) >+ return false; >+ auto& unnamedType = downcast<UnnamedType>(type); >+ if (!is<ReferenceType>(unnamedType)) >+ return false; >+ return true; >+} >+ >+unsigned NullLiteralType::conversionCost(const UnnamedType&) const >+{ >+ return 0; >+} >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteralType.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteralType.h >new file mode 100644 >index 00000000000..660a77690dd >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteralType.h >@@ -0,0 +1,66 @@ >+/* >+ * 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 "WHLSLResolvableType.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class NullLiteralType : public ResolvableType { >+public: >+ NullLiteralType() = default; >+ >+ virtual ~NullLiteralType() = default; >+ >+ NullLiteralType(const NullLiteralType&) = delete; >+ NullLiteralType(NullLiteralType&&) = default; >+ >+ NullLiteralType& operator=(const NullLiteralType&) = delete; >+ NullLiteralType& operator=(NullLiteralType&&) = default; >+ >+ bool isNullLiteralType() const override { return true; } >+ >+ bool canResolve(const Type&) const override; >+ unsigned conversionCost(const UnnamedType&) const override; >+ >+private: >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_RESOLVABLE_TYPE(NullLiteralType, isNullLiteralType()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNumThreadsFunctionAttribute.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNumThreadsFunctionAttribute.h >index 837e8668e2c..8c88f2d7741 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNumThreadsFunctionAttribute.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNumThreadsFunctionAttribute.h >@@ -60,7 +60,7 @@ private: > unsigned m_depth; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPointerType.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPointerType.h >index 1529426a2ed..05e3be6569a 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPointerType.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPointerType.h >@@ -29,6 +29,7 @@ > > #include "WHLSLLexer.h" > #include "WHLSLReferenceType.h" >+#include <wtf/UniqueRef.h> > #include <wtf/text/WTFString.h> > > namespace WebCore { >@@ -39,8 +40,8 @@ namespace AST { > > class PointerType : public ReferenceType { > public: >- PointerType(Lexer::Token&& origin, String&& addressSpace, std::unique_ptr<Type> elementType) >- : ReferenceType(WTFMove(origin), WTFMove(addressSpace), WTFMove(elementType)) >+ PointerType(Lexer::Token&& origin, AddressSpace addressSpace, UniqueRef<UnnamedType> elementType) >+ : ReferenceType(WTFMove(origin), addressSpace, WTFMove(elementType)) > { > } > >@@ -49,22 +50,22 @@ public: > PointerType(const PointerType&) = delete; > PointerType(PointerType&&) = default; > >- bool isPointerType() const override { return false; } >+ bool isPointerType() const override { return true; } > >- std::unique_ptr<Type> clone() const override >+ UniqueRef<UnnamedType> clone() const override > { >- return std::make_unique<PointerType>(Lexer::Token(origin()), String(addressSpace()), elementType().clone()); >+ return makeUniqueRef<PointerType>(Lexer::Token(origin()), addressSpace(), elementType().clone()); > } > > private: > }; > >-} >+} // namespace AST > > } > > } > >-SPECIALIZE_TYPE_TRAITS_WHLSL_TYPE(PointerType, isPointerType()) >+SPECIALIZE_TYPE_TRAITS_WHLSL_UNNAMED_TYPE(PointerType, isPointerType()) > > #endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPropertyAccessExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPropertyAccessExpression.h >index ba38a5c01ea..ef745c4fdfe 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPropertyAccessExpression.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPropertyAccessExpression.h >@@ -29,6 +29,7 @@ > > #include "WHLSLExpression.h" > #include "WHLSLLexer.h" >+#include <wtf/UniqueRef.h> > > namespace WebCore { > >@@ -38,7 +39,7 @@ namespace AST { > > class PropertyAccessExpression : public Expression { > public: >- PropertyAccessExpression(Lexer::Token&& origin, std::unique_ptr<Expression>&& base) >+ PropertyAccessExpression(Lexer::Token&& origin, UniqueRef<Expression>&& base) > : Expression(WTFMove(origin)) > , m_base(WTFMove(base)) > { >@@ -51,13 +52,37 @@ public: > > bool isPropertyAccessExpression() const override { return true; } > >- Expression& base() { return *m_base; } >+ virtual String getFunctionName() const = 0; >+ virtual String setFunctionName() const = 0; >+ virtual String andFunctionName() const = 0; >+ >+ Vector<std::reference_wrapper<FunctionDeclaration>, 1>& possibleGetOverloads() { return m_possibleGetOverloads; } >+ Vector<std::reference_wrapper<FunctionDeclaration>, 1>& possibleSetOverloads() { return m_possibleSetOverloads; } >+ Vector<std::reference_wrapper<FunctionDeclaration>, 1>& possibleAndOverloads() { return m_possibleAndOverloads; } >+ >+ void setPossibleGetOverloads(const Vector<std::reference_wrapper<FunctionDeclaration>, 1>& overloads) >+ { >+ m_possibleGetOverloads = overloads; >+ } >+ void setPossibleSetOverloads(const Vector<std::reference_wrapper<FunctionDeclaration>, 1>& overloads) >+ { >+ m_possibleSetOverloads = overloads; >+ } >+ void setPossibleAndOverloads(const Vector<std::reference_wrapper<FunctionDeclaration>, 1>& overloads) >+ { >+ m_possibleAndOverloads = overloads; >+ } >+ >+ Expression& base() { return static_cast<Expression&>(m_base); } > > private: >- std::unique_ptr<Expression> m_base; >+ UniqueRef<Expression> m_base; >+ Vector<std::reference_wrapper<FunctionDeclaration>, 1> m_possibleGetOverloads; >+ Vector<std::reference_wrapper<FunctionDeclaration>, 1> m_possibleSetOverloads; >+ Vector<std::reference_wrapper<FunctionDeclaration>, 1> m_possibleAndOverloads; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLQualifier.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLQualifier.h >index 333f0522441..ff65cd0f93a 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLQualifier.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLQualifier.h >@@ -38,7 +38,7 @@ namespace WHLSL { > > namespace AST { > >-enum class Qualifier { >+enum class Qualifier : uint8_t { > Nointerpolation, > Noperspective, > Uniform, >@@ -46,9 +46,9 @@ enum class Qualifier { > Sample > }; > >-typedef Vector<Qualifier> Qualifiers; >+using Qualifiers = Vector<Qualifier>; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReadModifyWriteExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReadModifyWriteExpression.h >index a4c14ce1cf3..be212653f6a 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReadModifyWriteExpression.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReadModifyWriteExpression.h >@@ -27,10 +27,12 @@ > > #if ENABLE(WEBGPU) > >-#include "WHLSLAnonymousVariableDeclaration.h" >+#include "WHLSLVariableDeclaration.h" > #include "WHLSLExpression.h" > #include "WHLSLLexer.h" > #include "WHLSLVariableReference.h" >+#include <memory> >+#include <wtf/UniqueRef.h> > > namespace WebCore { > >@@ -49,12 +51,9 @@ namespace AST { > */ > class ReadModifyWriteExpression : public Expression { > public: >- ReadModifyWriteExpression(Lexer::Token&& origin, std::unique_ptr<Expression> lValue) >- : Expression(Lexer::Token(origin)) >- , m_lValue(WTFMove(lValue)) >- , m_oldValue(Lexer::Token(origin)) >- , m_newValue(WTFMove(origin)) >+ static UniqueRef<ReadModifyWriteExpression> create(Lexer::Token&& origin, UniqueRef<Expression> lValue) > { >+ return makeUniqueRef<ReadModifyWriteExpression>(WTFMove(origin), WTFMove(lValue)); > } > > virtual ~ReadModifyWriteExpression() = default; >@@ -62,45 +61,55 @@ public: > ReadModifyWriteExpression(const ReadModifyWriteExpression&) = delete; > ReadModifyWriteExpression(ReadModifyWriteExpression&&) = default; > >- void setNewValueExpression(std::unique_ptr<Expression>&& newValueExpression) >+ void setNewValueExpression(UniqueRef<Expression>&& newValueExpression) > { >- m_newValueExpression = WTFMove(newValueExpression); >+ m_newValueExpression = newValueExpression.takeUniquePtr(); > } > >- void setResultExpression(std::unique_ptr<Expression>&& resultExpression) >+ void setResultExpression(UniqueRef<Expression>&& resultExpression) > { >- m_resultExpression = WTFMove(resultExpression); >+ m_resultExpression = resultExpression.takeUniquePtr(); > } > >- std::unique_ptr<VariableReference> oldVariableReference() >+ UniqueRef<VariableReference> oldVariableReference() > { > // The only reason we don't get use-after-frees is the fact that every instance of ReadModifyWriteExpression is allocated on the heap. >- return std::make_unique<VariableReference>(VariableReference::wrap(m_oldValue)); >+ return makeUniqueRef<VariableReference>(VariableReference::wrap(m_oldValue)); > } > >- std::unique_ptr<VariableReference> newVariableReference() >+ UniqueRef<VariableReference> newVariableReference() > { > // The only reason we don't get use-after-frees is the fact that every instance of ReadModifyWriteExpression is allocated on the heap. >- return std::make_unique<VariableReference>(VariableReference::wrap(m_newValue)); >+ return makeUniqueRef<VariableReference>(VariableReference::wrap(m_newValue)); > } > > bool isReadModifyWriteExpression() const override { return true; } > >- Expression& lValue() { return *m_lValue; } >- AnonymousVariableDeclaration& oldValue() { return m_oldValue; } >- AnonymousVariableDeclaration& newValue() { return m_newValue; } >+ Expression& lValue() { return static_cast<Expression&>(m_lValue); } >+ VariableDeclaration& oldValue() { return m_oldValue; } >+ VariableDeclaration& newValue() { return m_newValue; } > Expression& newValueExpression() { return *m_newValueExpression; } > Expression& resultExpression() { return *m_resultExpression; } > > private: >- std::unique_ptr<Expression> m_lValue; >- AnonymousVariableDeclaration m_oldValue; >- AnonymousVariableDeclaration m_newValue; >+ template<class U, class... Args> friend UniqueRef<U> WTF::makeUniqueRef(Args&&...); >+ >+ ReadModifyWriteExpression(Lexer::Token&& origin, UniqueRef<Expression> lValue) >+ : Expression(Lexer::Token(origin)) >+ , m_lValue(WTFMove(lValue)) >+ , m_oldValue(Lexer::Token(origin), Qualifiers(), nullptr, String(), WTF::nullopt, nullptr) >+ , m_newValue(WTFMove(origin), Qualifiers(), nullptr, String(), WTF::nullopt, nullptr) >+ { >+ } >+ >+ UniqueRef<Expression> m_lValue; >+ VariableDeclaration m_oldValue; >+ VariableDeclaration m_newValue; > std::unique_ptr<Expression> m_newValueExpression; > std::unique_ptr<Expression> m_resultExpression; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReferenceType.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReferenceType.h >index 2257f9be240..f2ba1747c48 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReferenceType.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReferenceType.h >@@ -28,7 +28,8 @@ > #if ENABLE(WEBGPU) > > #include "WHLSLLexer.h" >-#include "WHLSLType.h" >+#include "WHLSLUnnamedType.h" >+#include <wtf/UniqueRef.h> > #include <wtf/text/WTFString.h> > > namespace WebCore { >@@ -37,11 +38,18 @@ namespace WHLSL { > > namespace AST { > >-class ReferenceType : public Type { >+class ReferenceType : public UnnamedType { > public: >- ReferenceType(Lexer::Token&& origin, String&& addressSpace, std::unique_ptr<Type>&& elementType) >- : m_origin(WTFMove(origin)) >- , m_addressSpace(WTFMove(addressSpace)) >+ enum class AddressSpace : uint8_t { >+ Constant, >+ Device, >+ Threadgroup, >+ Thread >+ }; >+ >+ ReferenceType(Lexer::Token&& origin, AddressSpace addressSpace, UniqueRef<UnnamedType>&& elementType) >+ : UnnamedType(WTFMove(origin)) >+ , m_addressSpace(addressSpace) > , m_elementType(WTFMove(elementType)) > { > } >@@ -50,24 +58,24 @@ public: > > ReferenceType(const ReferenceType&) = delete; > ReferenceType(ReferenceType&&) = default; >- >- Type& elementType() { return *m_elementType; } > >-protected: >- const Lexer::Token& origin() const { return m_origin; } >- const String& addressSpace() const { return m_addressSpace; } >- const Type& elementType() const { return *m_elementType; } >+ bool isReferenceType() const override { return false; } >+ >+ AddressSpace addressSpace() const { return m_addressSpace; } >+ const UnnamedType& elementType() const { return static_cast<const UnnamedType&>(m_elementType); } >+ UnnamedType& elementType() { return static_cast<UnnamedType&>(m_elementType); } > > private: >- Lexer::Token m_origin; >- String m_addressSpace; >- std::unique_ptr<Type> m_elementType; >+ AddressSpace m_addressSpace; >+ UniqueRef<UnnamedType> m_elementType; > }; > >-} >+} // namespace AST > > } > > } > >+SPECIALIZE_TYPE_TRAITS_WHLSL_UNNAMED_TYPE(ReferenceType, isReferenceType()) >+ > #endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResolvableType.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResolvableType.h >new file mode 100644 >index 00000000000..ecbcfc51968 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResolvableType.h >@@ -0,0 +1,86 @@ >+/* >+ * 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 "WHLSLType.h" >+#include "WHLSLUnnamedType.h" >+#include <memory> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class ResolvableType : public Type { >+public: >+ ResolvableType() = default; >+ >+ virtual ~ResolvableType() = default; >+ >+ ResolvableType(const ResolvableType&) = delete; >+ ResolvableType(ResolvableType&&) = default; >+ >+ ResolvableType& operator=(const ResolvableType&) = delete; >+ ResolvableType& operator=(ResolvableType&&) = default; >+ >+ bool isResolvableType() const override { return true; } >+ virtual bool isFloatLiteralType() const { return false; } >+ virtual bool isIntegerLiteralType() const { return false; } >+ virtual bool isNullLiteralType() const { return false; } >+ virtual bool isUnsignedIntegerLiteralType() const { return false; } >+ >+ virtual bool canResolve(const Type&) const = 0; >+ virtual unsigned conversionCost(const UnnamedType&) const = 0; >+ >+ UnnamedType* resolvedType() const { return m_resolvedType.get(); } >+ UnnamedType* resolvedType() { return m_resolvedType.get(); } >+ >+ void resolve(UniqueRef<UnnamedType>&& type) >+ { >+ m_resolvedType = type.takeUniquePtr(); >+ } >+ >+private: >+ std::unique_ptr<UnnamedType> m_resolvedType; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#define SPECIALIZE_TYPE_TRAITS_WHLSL_RESOLVABLE_TYPE(ToValueTypeName, predicate) \ >+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::WHLSL::AST::ToValueTypeName) \ >+ static bool isType(const WebCore::WHLSL::AST::ResolvableType& type) { return type.predicate; } \ >+SPECIALIZE_TYPE_TRAITS_END() >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_TYPE(ResolvableType, isResolvableType()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.cpp b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.cpp >new file mode 100644 >index 00000000000..adda5bf756e >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.cpp >@@ -0,0 +1,92 @@ >+/* >+ * 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. >+ */ >+ >+#if ENABLE(WEBGPU) >+ >+#include "config.h" >+#include "WHLSLResourceSemantic.h" >+ >+#include "WHLSLArrayType.h" >+#include "WHLSLInferTypes.h" >+#include "WHLSLIntrinsics.h" >+#include "WHLSLReferenceType.h" >+#include "WHLSLTypeReference.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+bool ResourceSemantic::isAcceptableType(const AST::UnnamedType& unnamedType, const Intrinsics& intrinsics) const >+{ >+ switch (m_mode) { >+ case Mode::UnorderedAccessView: >+ if (is<ReferenceType>(unnamedType)) { >+ auto& referenceType = downcast<ReferenceType>(unnamedType); >+ return referenceType.addressSpace() == ReferenceType::AddressSpace::Constant || referenceType.addressSpace() == ReferenceType::AddressSpace::Device; >+ } >+ if (is<ArrayType>(unnamedType)) >+ return true; >+ if (is<TypeReference>(unnamedType)) { >+ auto& typeReference = downcast<TypeReference>(unnamedType); >+ ASSERT(typeReference.resolvedType()); >+ if (is<NativeTypeDeclaration>(*typeReference.resolvedType())) >+ return downcast<NativeTypeDeclaration>(*typeReference.resolvedType()).isTexture(); >+ } >+ return false; >+ case Mode::Texture: >+ if (is<ReferenceType>(unnamedType)) >+ return downcast<ReferenceType>(unnamedType).addressSpace() == ReferenceType::AddressSpace::Constant; >+ if (is<ArrayType>(unnamedType)) >+ return true; >+ if (is<TypeReference>(unnamedType)) { >+ auto& typeReference = downcast<TypeReference>(unnamedType); >+ ASSERT(typeReference.resolvedType()); >+ if (is<NativeTypeDeclaration>(*typeReference.resolvedType())) >+ return downcast<NativeTypeDeclaration>(*typeReference.resolvedType()).isTexture(); >+ } >+ return false; >+ case Mode::Buffer: >+ if (is<ReferenceType>(unnamedType)) >+ return downcast<ReferenceType>(unnamedType).addressSpace() == ReferenceType::AddressSpace::Constant; >+ return is<ArrayType>(unnamedType); >+ case Mode::Sampler: >+ return matches(unnamedType, intrinsics.samplerType()); >+ } >+} >+ >+bool ResourceSemantic::isAcceptableForShaderItemDirection(ShaderItemDirection direction, const FunctionDefinition&) const >+{ >+ return direction == ShaderItemDirection::Input; >+} >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.h >index ab3b430f442..8960230ea49 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.h >@@ -38,7 +38,7 @@ namespace AST { > > class ResourceSemantic : public BaseSemantic { > public: >- enum class Mode { >+ enum class Mode : uint8_t { > UnorderedAccessView, > Texture, > Buffer, >@@ -62,13 +62,26 @@ public: > unsigned index() const { return m_index; } > unsigned space() const { return m_space; } > >+ bool operator==(const ResourceSemantic& other) const >+ { >+ return m_mode == other.m_mode && m_index == other.m_index && m_space == other.m_space; >+ } >+ >+ bool operator!=(const ResourceSemantic& other) const >+ { >+ return !(*this == other); >+ } >+ >+ bool isAcceptableType(const AST::UnnamedType&, const Intrinsics&) const override; >+ bool isAcceptableForShaderItemDirection(ShaderItemDirection, const FunctionDefinition&) const override; >+ > private: > Mode m_mode; > unsigned m_index; > unsigned m_space; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReturn.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReturn.h >index c5bfc9e4286..da79ba47807 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReturn.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReturn.h >@@ -30,6 +30,8 @@ > #include "WHLSLExpression.h" > #include "WHLSLLexer.h" > #include "WHLSLStatement.h" >+#include <memory> >+#include <wtf/UniqueRef.h> > > namespace WebCore { > >@@ -54,11 +56,15 @@ public: > > Expression* value() { return m_value.get(); } > >+ FunctionDefinition* function() { return m_function; } >+ void setFunction(FunctionDefinition* functionDefinition) { m_function = functionDefinition; } >+ > private: >- std::unique_ptr<Expression> m_value; // nullable >+ std::unique_ptr<Expression> m_value; >+ FunctionDefinition* m_function; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSemantic.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSemantic.h >index b052b92ea26..60564c916a5 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSemantic.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSemantic.h >@@ -39,9 +39,9 @@ namespace WHLSL { > > namespace AST { > >-typedef Variant<BuiltInSemantic, ResourceSemantic, SpecializationConstantSemantic, StageInOutSemantic> Semantic; >+using Semantic = Variant<BuiltInSemantic, ResourceSemantic, SpecializationConstantSemantic, StageInOutSemantic>; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSpecializationConstantSemantic.cpp b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSpecializationConstantSemantic.cpp >new file mode 100644 >index 00000000000..c2b4548a8ff >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSpecializationConstantSemantic.cpp >@@ -0,0 +1,63 @@ >+/* >+ * 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. >+ */ >+ >+#if ENABLE(WEBGPU) >+ >+#include "config.h" >+#include "WHLSLSpecializationConstantSemantic.h" >+ >+#include "WHLSLInferTypes.h" >+#include "WHLSLIntrinsics.h" >+#include "WHLSLTypeReference.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+bool SpecializationConstantSemantic::isAcceptableType(const AST::UnnamedType& unnamedType, const Intrinsics&) const >+{ >+ if (!is<TypeReference>(unnamedType)) >+ return false; >+ auto& typeReference = downcast<TypeReference>(unnamedType); >+ ASSERT(typeReference.resolvedType()); >+ if (!is<NativeTypeDeclaration>(*typeReference.resolvedType())) >+ return false; >+ return downcast<NativeTypeDeclaration>(*typeReference.resolvedType()).isNumber(); >+} >+ >+bool SpecializationConstantSemantic::isAcceptableForShaderItemDirection(ShaderItemDirection direction, const FunctionDefinition&) const >+{ >+ return direction == ShaderItemDirection::Input; >+} >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSpecializationConstantSemantic.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSpecializationConstantSemantic.h >index 9a7c53fd4b6..9069b82cf9c 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSpecializationConstantSemantic.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSpecializationConstantSemantic.h >@@ -48,10 +48,23 @@ public: > SpecializationConstantSemantic(const SpecializationConstantSemantic&) = delete; > SpecializationConstantSemantic(SpecializationConstantSemantic&&) = default; > >+ bool operator==(const SpecializationConstantSemantic&) const >+ { >+ return true; >+ } >+ >+ bool operator!=(const SpecializationConstantSemantic&) const >+ { >+ return false; >+ } >+ >+ bool isAcceptableType(const AST::UnnamedType&, const Intrinsics&) const override; >+ bool isAcceptableForShaderItemDirection(ShaderItemDirection, const FunctionDefinition&) const override; >+ > private: > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStageInOutSemantic.cpp b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStageInOutSemantic.cpp >new file mode 100644 >index 00000000000..065bf4b00b7 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStageInOutSemantic.cpp >@@ -0,0 +1,81 @@ >+/* >+ * 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. >+ */ >+ >+#if ENABLE(WEBGPU) >+ >+#include "config.h" >+#include "WHLSLStageInOutSemantic.h" >+ >+#include "WHLSLArrayType.h" >+#include "WHLSLEnumerationDefinition.h" >+#include "WHLSLFunctionDefinition.h" >+#include "WHLSLInferTypes.h" >+#include "WHLSLIntrinsics.h" >+#include "WHLSLTypeReference.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+bool StageInOutSemantic::isAcceptableType(const AST::UnnamedType& unnamedType, const Intrinsics&) const >+{ >+ if (is<ArrayType>(unnamedType)) >+ return true; >+ if (!is<TypeReference>(unnamedType)) >+ return false; >+ auto& typeReference = downcast<TypeReference>(unnamedType); >+ ASSERT(typeReference.resolvedType()); >+ auto& resolvedType = *typeReference.resolvedType(); >+ if (is<EnumerationDefinition>(resolvedType)) >+ return true; >+ if (!is<NativeTypeDeclaration>(resolvedType)) >+ return false; >+ auto& nativeTypeDeclaration = downcast<NativeTypeDeclaration>(*typeReference.resolvedType()); >+ return nativeTypeDeclaration.isNumber() >+ || nativeTypeDeclaration.isVector() >+ || nativeTypeDeclaration.isMatrix(); >+} >+ >+bool StageInOutSemantic::isAcceptableForShaderItemDirection(ShaderItemDirection direction, const FunctionDefinition& functionDefinition) const >+{ >+ switch (*functionDefinition.entryPointType()) { >+ case FunctionDeclaration::EntryPointType::Vertex: >+ return true; >+ case FunctionDeclaration::EntryPointType::Fragment: >+ return direction == ShaderItemDirection::Input; >+ case FunctionDeclaration::EntryPointType::Compute: >+ return false; >+ } >+} >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStageInOutSemantic.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStageInOutSemantic.h >index a3992781e3a..0c9e7252132 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStageInOutSemantic.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStageInOutSemantic.h >@@ -51,11 +51,24 @@ public: > > unsigned index() const { return m_index; } > >+ bool operator==(const StageInOutSemantic& other) const >+ { >+ return m_index == other.m_index; >+ } >+ >+ bool operator!=(const StageInOutSemantic& other) const >+ { >+ return !(*this == other); >+ } >+ >+ bool isAcceptableType(const AST::UnnamedType&, const Intrinsics&) const override; >+ bool isAcceptableForShaderItemDirection(ShaderItemDirection, const FunctionDefinition&) const override; >+ > private: > unsigned m_index; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStatement.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStatement.h >index 434d21a0432..c5e65918d28 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStatement.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStatement.h >@@ -29,6 +29,7 @@ > > #include "WHLSLLexer.h" > #include "WHLSLValue.h" >+#include <wtf/UniqueRef.h> > > namespace WebCore { > >@@ -67,9 +68,9 @@ private: > Lexer::Token m_origin; > }; > >-typedef Vector<std::unique_ptr<Statement>> Statements; >+using Statements = Vector<UniqueRef<Statement>>; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStructureDefinition.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStructureDefinition.h >index 87cc62f2356..6bb1487a600 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStructureDefinition.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStructureDefinition.h >@@ -29,7 +29,7 @@ > > #include "WHLSLLexer.h" > #include "WHLSLStructureElement.h" >-#include "WHLSLType.h" >+#include "WHLSLNamedType.h" > #include <wtf/Vector.h> > #include <wtf/text/WTFString.h> > >@@ -39,11 +39,10 @@ namespace WHLSL { > > namespace AST { > >-class StructureDefinition : public Type { >+class StructureDefinition : public NamedType { > public: > StructureDefinition(Lexer::Token&& origin, String&& name, StructureElements&& structureElements) >- : m_origin(WTFMove(origin)) >- , m_name(WTFMove(name)) >+ : NamedType(WTFMove(origin), WTFMove(name)) > , m_structureElements(WTFMove(structureElements)) > { > } >@@ -53,24 +52,20 @@ public: > StructureDefinition(const StructureDefinition&) = delete; > StructureDefinition(StructureDefinition&&) = default; > >- StructureElements& structureElements() { return m_structureElements; } >+ bool isStructureDefinition() const override { return true; } > >- std::unique_ptr<Type> clone() const override >- { >- ASSERT_NOT_REACHED(); >- return nullptr; >- } >+ StructureElements& structureElements() { return m_structureElements; } > > private: >- Lexer::Token m_origin; >- String m_name; > StructureElements m_structureElements; > }; > >-} >+} // namespace AST > > } > > } > >+SPECIALIZE_TYPE_TRAITS_WHLSL_NAMED_TYPE(StructureDefinition, isStructureDefinition()) >+ > #endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStructureElement.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStructureElement.h >index 14be41c7298..e4a76463ce9 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStructureElement.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStructureElement.h >@@ -32,6 +32,7 @@ > #include "WHLSLQualifier.h" > #include "WHLSLSemantic.h" > #include "WHLSLType.h" >+#include <wtf/UniqueRef.h> > > namespace WebCore { > >@@ -41,7 +42,7 @@ namespace AST { > > class StructureElement : public Node { > public: >- StructureElement(Lexer::Token&& origin, Qualifiers&& qualifiers, std::unique_ptr<Type>&& type, String&& name, Optional<Semantic> semantic) >+ StructureElement(Lexer::Token&& origin, Qualifiers&& qualifiers, UniqueRef<UnnamedType>&& type, String&& name, Optional<Semantic> semantic) > : m_origin(WTFMove(origin)) > , m_qualifiers(WTFMove(qualifiers)) > , m_type(WTFMove(type)) >@@ -55,20 +56,22 @@ public: > StructureElement(const StructureElement&) = delete; > StructureElement(StructureElement&&) = default; > >- Type& type() { return *m_type; } >+ const Lexer::Token& origin() const { return m_origin; } >+ UnnamedType& type() { return static_cast<UnnamedType&>(m_type); } >+ const String& name() { return m_name; } > Optional<Semantic>& semantic() { return m_semantic; } > > private: > Lexer::Token m_origin; > Qualifiers m_qualifiers; >- std::unique_ptr<Type> m_type; >+ UniqueRef<UnnamedType> m_type; > String m_name; > Optional<Semantic> m_semantic; > }; > >-typedef Vector<StructureElement> StructureElements; >+using StructureElements = Vector<StructureElement>; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSwitchCase.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSwitchCase.h >index 19905bd1789..15f09c26698 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSwitchCase.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSwitchCase.h >@@ -63,7 +63,7 @@ private: > Block m_block; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSwitchStatement.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSwitchStatement.h >index 46e676550dc..d9af69d7732 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSwitchStatement.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSwitchStatement.h >@@ -31,6 +31,7 @@ > #include "WHLSLLexer.h" > #include "WHLSLStatement.h" > #include "WHLSLSwitchCase.h" >+#include <wtf/UniqueRef.h> > > namespace WebCore { > >@@ -40,7 +41,7 @@ namespace AST { > > class SwitchStatement : public Statement { > public: >- SwitchStatement(Lexer::Token&& origin, std::unique_ptr<Expression>&& value, Vector<SwitchCase>&& switchCases) >+ SwitchStatement(Lexer::Token&& origin, UniqueRef<Expression>&& value, Vector<SwitchCase>&& switchCases) > : Statement(WTFMove(origin)) > , m_value(WTFMove(value)) > , m_switchCases(WTFMove(switchCases)) >@@ -54,15 +55,15 @@ public: > > bool isSwitchStatement() const override { return true; } > >- Expression& value() { return *m_value; } >+ Expression& value() { return static_cast<Expression&>(m_value); } > Vector<SwitchCase>& switchCases() { return m_switchCases; } > > private: >- std::unique_ptr<Expression> m_value; >+ UniqueRef<Expression> m_value; > Vector<SwitchCase> m_switchCases; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTernaryExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTernaryExpression.h >index 904cc4c489c..5d862ee4e5c 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTernaryExpression.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTernaryExpression.h >@@ -29,6 +29,7 @@ > > #include "WHLSLExpression.h" > #include "WHLSLLexer.h" >+#include <wtf/UniqueRef.h> > > namespace WebCore { > >@@ -38,7 +39,7 @@ namespace AST { > > class TernaryExpression : public Expression { > public: >- TernaryExpression(Lexer::Token&& origin, std::unique_ptr<Expression>&& predicate, std::unique_ptr<Expression>&& bodyExpression, std::unique_ptr<Expression>&& elseExpression) >+ TernaryExpression(Lexer::Token&& origin, UniqueRef<Expression>&& predicate, UniqueRef<Expression>&& bodyExpression, UniqueRef<Expression>&& elseExpression) > : Expression(WTFMove(origin)) > , m_predicate(WTFMove(predicate)) > , m_bodyExpression(WTFMove(bodyExpression)) >@@ -53,17 +54,17 @@ public: > > bool isTernaryExpression() const override { return true; } > >- Expression& predicate() { return *m_predicate; } >- Expression& bodyExpression() { return *m_bodyExpression; } >- Expression& elseExpression() { return *m_elseExpression; } >+ Expression& predicate() { return static_cast<Expression&>(m_predicate); } >+ Expression& bodyExpression() { return static_cast<Expression&>(m_bodyExpression); } >+ Expression& elseExpression() { return static_cast<Expression&>(m_elseExpression); } > > private: >- std::unique_ptr<Expression> m_predicate; >- std::unique_ptr<Expression> m_bodyExpression; >- std::unique_ptr<Expression> m_elseExpression; >+ UniqueRef<Expression> m_predicate; >+ UniqueRef<Expression> m_bodyExpression; >+ UniqueRef<Expression> m_elseExpression; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTrap.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTrap.h >index dba2f12f817..0a93b368f0b 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTrap.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTrap.h >@@ -53,7 +53,7 @@ public: > private: > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLType.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLType.h >index cf4cbc88790..db92ff5428b 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLType.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLType.h >@@ -42,20 +42,20 @@ public: > > virtual ~Type() = default; > >- Type(const Type&) = delete; >+ explicit Type(const Type&) = delete; > Type(Type&&) = default; > >- virtual bool isTypeReference() const { return false; } >- virtual bool isPointerType() const { return false; } >- virtual bool isArrayReferenceType() const { return false; } >- virtual bool isArrayType() const { return false; } >+ Type& operator=(const Type&) = delete; >+ Type& operator=(Type&&) = default; > >- virtual std::unique_ptr<Type> clone() const = 0; >+ virtual bool isNamedType() const { return false; } >+ virtual bool isUnnamedType() const { return false; } >+ virtual bool isResolvableType() const { return false; } > > private: > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeArgument.cpp b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeArgument.cpp >index 7e5801e3b56..8735065a1bb 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeArgument.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeArgument.cpp >@@ -23,14 +23,15 @@ > * THE POSSIBILITY OF SUCH DAMAGE. > */ > >-#pragma once >- > #if ENABLE(WEBGPU) > > #include "config.h" >-#include "WHLSLLexer.h" >+#include "WHLSLTypeArgument.h" > >-#include <wtf/Optional.h> >+#include "WHLSLConstantExpression.h" >+#include "WHLSLTypeReference.h" >+#include <wtf/UniqueRef.h> >+#include <wtf/Variant.h> > > namespace WebCore { > >@@ -49,13 +50,13 @@ TypeArguments clone(const TypeArguments& typeArguments) > TypeArgument clone(const TypeArgument& typeArgument) > { > return WTF::visit(WTF::makeVisitor([](const ConstantExpression& constantExpression) -> TypeArgument { >- return constantExpression; >- }, [](const std::unique_ptr<TypeReference>& typeReference) -> TypeArgument { >+ return constantExpression.clone(); >+ }, [](const UniqueRef<TypeReference>& typeReference) -> TypeArgument { > return typeReference->cloneTypeReference(); > }), typeArgument); > } > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeArgument.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeArgument.h >index e385d50d5ef..67383aa1dbb 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeArgument.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeArgument.h >@@ -29,6 +29,7 @@ > > #include "WHLSLConstantExpression.h" > #include "WHLSLLexer.h" >+#include <wtf/UniqueRef.h> > #include <wtf/Variant.h> > #include <wtf/Vector.h> > >@@ -40,13 +41,13 @@ namespace AST { > > class TypeReference; > >-typedef Variant<ConstantExpression, std::unique_ptr<TypeReference>> TypeArgument; >-typedef Vector<TypeArgument> TypeArguments; >+using TypeArgument = Variant<ConstantExpression, UniqueRef<TypeReference>>; >+using TypeArguments = Vector<TypeArgument>; > > TypeArgument clone(const TypeArgument&); > TypeArguments clone(const TypeArguments&); > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeDefinition.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeDefinition.h >index f73629e29b1..866a2772446 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeDefinition.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeDefinition.h >@@ -29,7 +29,9 @@ > > #include "WHLSLLexer.h" > #include "WHLSLNode.h" >-#include "WHLSLType.h" >+#include "WHLSLNamedType.h" >+#include "WHLSLUnnamedType.h" >+#include <wtf/UniqueRef.h> > #include <wtf/text/WTFString.h> > > namespace WebCore { >@@ -38,11 +40,10 @@ namespace WHLSL { > > namespace AST { > >-class TypeDefinition : public Type { >+class TypeDefinition : public NamedType { > public: >- TypeDefinition(Lexer::Token&& origin, String&& name, std::unique_ptr<AST::Type>&& type) >- : m_origin(WTFMove(origin)) >- , m_name(WTFMove(name)) >+ TypeDefinition(Lexer::Token&& origin, String&& name, UniqueRef<AST::UnnamedType>&& type) >+ : NamedType(WTFMove(origin), WTFMove(name)) > , m_type(WTFMove(type)) > { > } >@@ -52,24 +53,30 @@ public: > TypeDefinition(const TypeDefinition&) = delete; > TypeDefinition(TypeDefinition&&) = default; > >- AST::Type& type() { return *m_type; } >+ bool isTypeDefinition() const override { return true; } > >- std::unique_ptr<Type> clone() const override >+ AST::UnnamedType& type() { return static_cast<AST::UnnamedType&>(m_type); } >+ >+ const Type& unifyNode() const override >+ { >+ return m_type->unifyNode(); >+ } >+ >+ Type& unifyNode() override > { >- ASSERT_NOT_REACHED(); >- return nullptr; >+ return m_type->unifyNode(); > } > > private: >- Lexer::Token m_origin; >- String m_name; >- std::unique_ptr<AST::Type> m_type; >+ UniqueRef<AST::UnnamedType> m_type; > }; > >-} >+} // namespace AST > > } > > } > >+SPECIALIZE_TYPE_TRAITS_WHLSL_NAMED_TYPE(TypeDefinition, isTypeDefinition()) >+ > #endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeReference.cpp b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeReference.cpp >new file mode 100644 >index 00000000000..d0c99f12775 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeReference.cpp >@@ -0,0 +1,56 @@ >+/* >+ * 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. >+ */ >+ >+#if ENABLE(WEBGPU) >+ >+#include "config.h" >+#include "WHLSLTypeReference.h" >+ >+#include "WHLSLNativeTypeDeclaration.h" >+#include <wtf/UniqueRef.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+UniqueRef<TypeReference> TypeReference::wrap(Lexer::Token&& origin, NamedType& resolvedType) >+{ >+ TypeArguments typeArguments; >+ if (is<NativeTypeDeclaration>(resolvedType)) >+ typeArguments = AST::clone(downcast<NativeTypeDeclaration>(resolvedType).typeArguments()); >+ auto result = makeUniqueRef<TypeReference>(WTFMove(origin), String(resolvedType.name()), WTFMove(typeArguments)); >+ result->setResolvedType(resolvedType); >+ return result; >+} >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeReference.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeReference.h >index 49441d8b5c7..b8e4bf850b4 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeReference.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeReference.h >@@ -28,8 +28,9 @@ > #if ENABLE(WEBGPU) > > #include "WHLSLLexer.h" >-#include "WHLSLType.h" > #include "WHLSLTypeArgument.h" >+#include "WHLSLUnnamedType.h" >+#include <wtf/UniqueRef.h> > #include <wtf/text/WTFString.h> > > namespace WebCore { >@@ -38,10 +39,12 @@ namespace WHLSL { > > namespace AST { > >-class TypeReference : public Type { >+class NamedType; >+ >+class TypeReference : public UnnamedType { > public: > TypeReference(Lexer::Token&& origin, String&& name, TypeArguments&& typeArguments) >- : m_origin(WTFMove(origin)) >+ : UnnamedType(WTFMove(origin)) > , m_name(WTFMove(name)) > , m_typeArguments(WTFMove(typeArguments)) > { >@@ -52,32 +55,53 @@ public: > TypeReference(const TypeReference&) = delete; > TypeReference(TypeReference&&) = default; > >+ static UniqueRef<TypeReference> wrap(Lexer::Token&& origin, NamedType& resolvedType); >+ > bool isTypeReference() const override { return true; } > >+ String& name() { return m_name; } > TypeArguments& typeArguments() { return m_typeArguments; } >+ NamedType* resolvedType() const { return m_resolvedType; } > >- std::unique_ptr<TypeReference> cloneTypeReference() const >+ const Type& unifyNode() const override > { >- return std::make_unique<TypeReference>(Lexer::Token(m_origin), String(m_name), AST::clone(m_typeArguments)); >+ ASSERT(m_resolvedType); >+ return m_resolvedType->unifyNode(); > } > >- std::unique_ptr<Type> clone() const override >+ Type& unifyNode() override >+ { >+ ASSERT(m_resolvedType); >+ return m_resolvedType->unifyNode(); >+ } >+ >+ void setResolvedType(NamedType& resolvedType) >+ { >+ m_resolvedType = &resolvedType; >+ } >+ >+ UniqueRef<TypeReference> cloneTypeReference() const >+ { >+ return makeUniqueRef<TypeReference>(Lexer::Token(origin()), String(m_name), AST::clone(m_typeArguments)); >+ } >+ >+ UniqueRef<UnnamedType> clone() const override > { > return cloneTypeReference(); > } > > private: >- Lexer::Token m_origin; > String m_name; > TypeArguments m_typeArguments; >+ NamedType* m_resolvedType { nullptr }; > }; > >-} >+} // namespace AST > > } > > } > >-SPECIALIZE_TYPE_TRAITS_WHLSL_TYPE(TypeReference, isTypeReference()) >+SPECIALIZE_TYPE_TRAITS_WHLSL_UNNAMED_TYPE(TypeReference, isTypeReference()) > > #endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnnamedType.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnnamedType.h >new file mode 100644 >index 00000000000..862a26dcae5 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnnamedType.h >@@ -0,0 +1,85 @@ >+/* >+ * 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 "WHLSLLexer.h" >+#include "WHLSLNode.h" >+#include "WHLSLType.h" >+#include <wtf/UniqueRef.h> >+#include <wtf/text/WTFString.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class UnnamedType : public Type { >+public: >+ UnnamedType(Lexer::Token&& origin) >+ : m_origin(WTFMove(origin)) >+ { >+ } >+ >+ virtual ~UnnamedType() = default; >+ >+ UnnamedType(const UnnamedType&) = delete; >+ UnnamedType(UnnamedType&&) = default; >+ >+ bool isUnnamedType() const override { return true; } >+ virtual bool isTypeReference() const { return false; } >+ virtual bool isPointerType() const { return false; } >+ virtual bool isArrayReferenceType() const { return false; } >+ virtual bool isArrayType() const { return false; } >+ virtual bool isReferenceType() const { return false; } >+ >+ virtual const Type& unifyNode() const { return *this; } >+ virtual Type& unifyNode() { return *this; } >+ >+ virtual UniqueRef<UnnamedType> clone() const = 0; >+ >+ const Lexer::Token& origin() const { return m_origin; } >+ >+private: >+ Lexer::Token m_origin; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#define SPECIALIZE_TYPE_TRAITS_WHLSL_UNNAMED_TYPE(ToValueTypeName, predicate) \ >+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::WHLSL::AST::ToValueTypeName) \ >+ static bool isType(const WebCore::WHLSL::AST::UnnamedType& type) { return type.predicate; } \ >+SPECIALIZE_TYPE_TRAITS_END() >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_TYPE(UnnamedType, isUnnamedType()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.cpp b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.cpp >new file mode 100644 >index 00000000000..146e3b59f9c >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.cpp >@@ -0,0 +1,55 @@ >+/* >+ * 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. >+ */ >+ >+#if ENABLE(WEBGPU) >+ >+#include "config.h" >+#include "WHLSLUnsignedIntegerLiteral.h" >+ >+#include "WHLSLNativeTypeDeclaration.h" >+#include "WHLSLTypeReference.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+int64_t UnsignedIntegerLiteral::valueForSelectedType() const >+{ >+ ASSERT(m_type.resolvedType()); >+ auto& typeReference = downcast<TypeReference>(*m_type.resolvedType()); >+ ASSERT(typeReference.resolvedType()); >+ auto& nativeTypeDeclaration = downcast<NativeTypeDeclaration>(*typeReference.resolvedType()); >+ return nativeTypeDeclaration.formatValueFromUnsignedInteger()(m_value); >+} >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.h >index 58d6e23075e..b64c9868e3c 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.h >@@ -29,6 +29,7 @@ > > #include "WHLSLExpression.h" > #include "WHLSLLexer.h" >+#include "WHLSLUnsignedIntegerLiteralType.h" > > namespace WebCore { > >@@ -39,25 +40,41 @@ namespace AST { > class UnsignedIntegerLiteral : public Expression { > public: > UnsignedIntegerLiteral(Lexer::Token&& origin, unsigned value) >- : Expression(WTFMove(origin)) >+ : Expression(Lexer::Token(origin)) >+ , m_type(WTFMove(origin), value) > , m_value(value) > { > } > > virtual ~UnsignedIntegerLiteral() = default; > >- explicit UnsignedIntegerLiteral(const UnsignedIntegerLiteral&) = default; >+ UnsignedIntegerLiteral(const UnsignedIntegerLiteral&) = delete; > UnsignedIntegerLiteral(UnsignedIntegerLiteral&&) = default; > >+ UnsignedIntegerLiteral& operator=(const UnsignedIntegerLiteral&) = delete; >+ UnsignedIntegerLiteral& operator=(UnsignedIntegerLiteral&&) = default; >+ >+ UnsignedIntegerLiteralType& type() { return m_type; } > unsigned value() const { return m_value; } > > bool isUnsignedIntegerLiteral() const override { return true; } > >+ UnsignedIntegerLiteral clone() const >+ { >+ UnsignedIntegerLiteral result(Lexer::Token(origin()), m_value); >+ if (result.m_type.resolvedType()) >+ result.m_type.resolve(result.m_type.resolvedType()->clone()); >+ return result; >+ } >+ >+ int64_t valueForSelectedType() const; >+ > private: >+ UnsignedIntegerLiteralType m_type; > unsigned m_value; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteralType.cpp b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteralType.cpp >new file mode 100644 >index 00000000000..1dc5aa062fe >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteralType.cpp >@@ -0,0 +1,77 @@ >+/* >+ * 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. >+ */ >+ >+#if ENABLE(WEBGPU) >+ >+#include "config.h" >+#include "WHLSLUnsignedIntegerLiteralType.h" >+ >+#include "WHLSLInferTypes.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+UnsignedIntegerLiteralType::UnsignedIntegerLiteralType(Lexer::Token&& origin, unsigned value) >+ : m_value(value) >+ , m_preferredType(std::make_unique<TypeReference>(WTFMove(origin), String("uint", String::ConstructFromLiteral), TypeArguments())) >+{ >+} >+ >+UnsignedIntegerLiteralType::~UnsignedIntegerLiteralType() = default; >+ >+bool UnsignedIntegerLiteralType::canResolve(const Type& type) const >+{ >+ if (!is<NamedType>(type)) >+ return false; >+ auto& namedType = downcast<NamedType>(type); >+ if (!is<NativeTypeDeclaration>(namedType)) >+ return false; >+ auto& nativeTypeDeclaration = downcast<NativeTypeDeclaration>(namedType); >+ if (!nativeTypeDeclaration.isInt()) >+ return false; >+ if (!nativeTypeDeclaration.isSigned()) >+ return false; >+ if (!nativeTypeDeclaration.canRepresentUnsignedInteger()(m_value)) >+ return false; >+ return true; >+} >+ >+unsigned UnsignedIntegerLiteralType::conversionCost(const UnnamedType& unnamedType) const >+{ >+ if (matches(unnamedType, *m_preferredType)) >+ return 0; >+ return 1; >+} >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteralType.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteralType.h >new file mode 100644 >index 00000000000..1130df5055d >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteralType.h >@@ -0,0 +1,76 @@ >+/* >+ * 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 "WHLSLResolvableType.h" >+#include <wtf/UniqueRef.h> >+#include <wtf/text/WTFString.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class TypeReference; >+ >+class UnsignedIntegerLiteralType : public ResolvableType { >+public: >+ UnsignedIntegerLiteralType(Lexer::Token&& origin, unsigned value); >+ >+ virtual ~UnsignedIntegerLiteralType(); >+ >+ UnsignedIntegerLiteralType(const UnsignedIntegerLiteralType&) = delete; >+ UnsignedIntegerLiteralType(UnsignedIntegerLiteralType&&) = default; >+ >+ UnsignedIntegerLiteralType& operator=(const UnsignedIntegerLiteralType&) = delete; >+ UnsignedIntegerLiteralType& operator=(UnsignedIntegerLiteralType&&) = default; >+ >+ bool isUnsignedIntegerLiteralType() const override { return true; } >+ >+ TypeReference& preferredType() { return static_cast<TypeReference&>(m_preferredType); } >+ >+ bool canResolve(const Type&) const override; >+ unsigned conversionCost(const UnnamedType&) const override; >+ >+private: >+ unsigned m_value; >+ // This is a unique_ptr to resolve a circular dependency between >+ // ConstantExpression -> LiteralType -> TypeReference -> TypeArguments -> ConstantExpression >+ UniqueRef<TypeReference> m_preferredType; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_RESOLVABLE_TYPE(UnsignedIntegerLiteralType, isUnsignedIntegerLiteralType()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLValue.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLValue.h >index 6e0ea91fc1d..b912d0e4852 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLValue.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLValue.h >@@ -46,10 +46,13 @@ public: > explicit Value(const Value&) = default; > Value(Value&&) = default; > >+ Value& operator=(const Value&) = default; >+ Value& operator=(Value&&) = default; >+ > private: > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclaration.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclaration.h >index ff0368193bd..638ca367cb0 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclaration.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclaration.h >@@ -33,6 +33,8 @@ > #include "WHLSLSemantic.h" > #include "WHLSLType.h" > #include "WHLSLValue.h" >+#include <memory> >+#include <wtf/UniqueRef.h> > #include <wtf/Vector.h> > #include <wtf/text/WTFString.h> > >@@ -44,7 +46,7 @@ namespace AST { > > class VariableDeclaration : public Value { > public: >- VariableDeclaration(Lexer::Token&& origin, Qualifiers&& qualifiers, std::unique_ptr<AST::Type>&& type, String&& name, Optional<Semantic>&& semantic, std::unique_ptr<Expression>&& initializer) >+ VariableDeclaration(Lexer::Token&& origin, Qualifiers&& qualifiers, std::unique_ptr<AST::UnnamedType>&& type, String&& name, Optional<Semantic>&& semantic, std::unique_ptr<Expression>&& initializer) > : m_origin(WTFMove(origin)) > , m_qualifiers(WTFMove(qualifiers)) > , m_type(WTFMove(type)) >@@ -59,22 +61,26 @@ public: > VariableDeclaration(const VariableDeclaration&) = delete; > VariableDeclaration(VariableDeclaration&&) = default; > >- Lexer::Token origin() const { return m_origin; } >+ const Lexer::Token& origin() const { return m_origin; } >+ String& name() { return m_name; } > >- Type& type() { return *m_type; } >+ const UnnamedType* type() const { return m_type.get(); } // Anonymous variables inside ReadModifyWriteExpressions have their type set by the type checker. >+ UnnamedType* type() { return m_type.get(); } > Optional<Semantic>& semantic() { return m_semantic; } > Expression* initializer() { return m_initializer.get(); } > > private: > Lexer::Token m_origin; > Qualifiers m_qualifiers; >- std::unique_ptr<AST::Type> m_type; >+ std::unique_ptr<AST::UnnamedType> m_type; > String m_name; > Optional<Semantic> m_semantic; > std::unique_ptr<Expression> m_initializer; > }; > >-} >+using VariableDeclarations = Vector<VariableDeclaration>; >+ >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclarationsStatement.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclarationsStatement.h >index f8dafc251fb..5544b18363c 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclarationsStatement.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclarationsStatement.h >@@ -59,7 +59,7 @@ private: > Vector<VariableDeclaration> m_variableDeclarations; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableReference.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableReference.h >index 2ae828d5295..ef4fb55d19d 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableReference.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableReference.h >@@ -27,7 +27,7 @@ > > #if ENABLE(WEBGPU) > >-#include "WHLSLAnonymousVariableDeclaration.h" >+#include "WHLSLVariableDeclaration.h" > #include "WHLSLExpression.h" > #include "WHLSLLexer.h" > #include "WHLSLVariableDeclaration.h" >@@ -55,19 +55,21 @@ public: > static VariableReference wrap(VariableDeclaration& variableDeclaration) > { > VariableReference result(Lexer::Token(variableDeclaration.origin())); >- result.m_variable = { &variableDeclaration }; >+ result.m_variable = &variableDeclaration; > return result; > } > >- static VariableReference wrap(AnonymousVariableDeclaration& anonymousVariableDeclaration) >+ bool isVariableReference() const override { return true; } >+ >+ String& name() { return m_name; } >+ >+ VariableDeclaration* variable() { return m_variable; } >+ >+ void setVariable(VariableDeclaration& variableDeclaration) > { >- VariableReference result(Lexer::Token(anonymousVariableDeclaration.origin())); >- result.m_variable = { &anonymousVariableDeclaration }; >- return result; >+ m_variable = &variableDeclaration; > } > >- bool isVariableReference() const override { return true; } >- > private: > VariableReference(Lexer::Token&& origin) > : Expression(WTFMove(origin)) >@@ -75,10 +77,10 @@ private: > } > > String m_name; >- Optional<Variant<VariableDeclaration*, AnonymousVariableDeclaration*>> m_variable; >+ VariableDeclaration* m_variable; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLWhileLoop.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLWhileLoop.h >index 1d4ae759779..aec64caac30 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLWhileLoop.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLWhileLoop.h >@@ -30,6 +30,7 @@ > #include "WHLSLExpression.h" > #include "WHLSLLexer.h" > #include "WHLSLStatement.h" >+#include <wtf/UniqueRef.h> > > namespace WebCore { > >@@ -39,7 +40,7 @@ namespace AST { > > class WhileLoop : public Statement { > public: >- WhileLoop(Lexer::Token&& origin, std::unique_ptr<Expression>&& conditional, std::unique_ptr<Statement>&& body) >+ WhileLoop(Lexer::Token&& origin, UniqueRef<Expression>&& conditional, UniqueRef<Statement>&& body) > : Statement(WTFMove(origin)) > , m_conditional(WTFMove(conditional)) > , m_body(WTFMove(body)) >@@ -53,15 +54,15 @@ public: > > bool isWhileLoop() const override { return true; } > >- Expression& conditional() { return *m_conditional; } >- Statement& body() { return *m_body; } >+ Expression& conditional() { return static_cast<Expression&>(m_conditional); } >+ Statement& body() { return static_cast<Statement&>(m_body); } > > private: >- std::unique_ptr<Expression> m_conditional; >- std::unique_ptr<Statement> m_body; >+ UniqueRef<Expression> m_conditional; >+ UniqueRef<Statement> m_body; > }; > >-} >+} // namespace AST > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.cpp >new file mode 100644 >index 00000000000..2b67b3e1416 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.cpp >@@ -0,0 +1,122 @@ >+/* >+ * 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. >+ */ >+ >+#if ENABLE(WEBGPU) >+ >+#include "config.h" >+#include "WHLSLCheckDuplicateFunctions.h" >+ >+#include "WHLSLArrayReferenceType.h" >+#include "WHLSLArrayType.h" >+#include "WHLSLInferTypes.h" >+#include "WHLSLTypeReference.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+bool checkDuplicateFunctions(const Program& program) >+{ >+ Vector<std::reference_wrapper<AST::FunctionDeclaration>> functions; >+ for (auto& functionDefinition : program.functionDefinitions()) >+ functions.append(*functionDefinition); >+ for (auto& nativeFunctionDeclaration : program.nativeFunctionDeclarations()) >+ functions.append(*nativeFunctionDeclaration); >+ >+ std::sort(functions.begin(), functions.end(), [](const AST::FunctionDeclaration& a, const AST::FunctionDeclaration& b) -> bool { >+ for (unsigned i = 0; i < std::min(a.name().length(), b.name().length()); ++i) { >+ if (a.name()[i] < b.name()[i]) >+ return true; >+ if (a.name()[i] > b.name()[i]) >+ return false; >+ } >+ return a.name().length() < b.name().length(); >+ }); >+ for (size_t i = 0; i < functions.size(); ++i) { >+ for (size_t j = i + 1; j < functions.size(); ++i) { >+ if (functions[i].get().name() != functions[j].get().name()) >+ break; >+ if (is<AST::NativeFunctionDeclaration>(functions[i].get()) && is<AST::NativeFunctionDeclaration>(functions[j].get())) >+ continue; >+ if (functions[i].get().parameters().size() != functions[j].get().parameters().size()) >+ continue; >+ if (functions[i].get().isCast()) { >+ bool same = true; >+ if (!matches(functions[i].get().type(), functions[j].get().type())) >+ same = false; >+ else { >+ for (size_t k = 0; k < functions[i].get().parameters().size(); ++k) { >+ if (!matches(*functions[i].get().parameters()[k].type(), *functions[j].get().parameters()[k].type())) { >+ same = false; >+ break; >+ } >+ } >+ } >+ if (same) >+ return false; >+ } else { >+ bool same = true; >+ for (size_t k = 0; k < functions[i].get().parameters().size(); ++k) { >+ if (!matches(*functions[i].get().parameters()[k].type(), *functions[j].get().parameters()[k].type())) { >+ same = false; >+ break; >+ } >+ } >+ if (same) >+ return false; >+ } >+ } >+ >+ if (functions[i].get().name() == "operator&[]" && functions[i].get().parameters().size() == 2 >+ && is<AST::ArrayReferenceType>(functions[i].get().parameters()[0].type())) { >+ auto& type = *functions[i].get().parameters()[1].type(); >+ if (is<AST::TypeReference>(type)) { >+ if (auto* resolvedType = downcast<AST::TypeReference>(type).resolvedType()) { >+ if (is<AST::NativeTypeDeclaration>(*resolvedType)) { >+ auto& nativeTypeDeclaration = downcast<AST::NativeTypeDeclaration>(*resolvedType); >+ if (nativeTypeDeclaration.name() == "uint") >+ return false; >+ } >+ } >+ } >+ } else if (functions[i].get().name() == "operator.length" && functions[i].get().parameters().size() == 1 >+ && (is<AST::ArrayReferenceType>(functions[i].get().parameters()[0].type()) >+ || is<AST::ArrayType>(functions[i].get().parameters()[0].type()))) >+ return false; >+ else if (functions[i].get().name() == "operator==" >+ && functions[i].get().parameters().size() == 2 >+ && is<AST::ReferenceType>(functions[i].get().parameters()[0].type()) >+ && is<AST::ReferenceType>(functions[i].get().parameters()[1].type()) >+ && matches(*functions[i].get().parameters()[0].type(), *functions[i].get().parameters()[1].type())) >+ return false; >+ } >+ return true; >+} >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.h >new file mode 100644 >index 00000000000..7ecee782c5f >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.h >@@ -0,0 +1,43 @@ >+/* >+ * 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 "WHLSLProgram.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+bool checkDuplicateFunctions(const Program&); >+ >+} >+ >+} >+ >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp >new file mode 100644 >index 00000000000..b4b144ff870 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp >@@ -0,0 +1,1487 @@ >+/* >+ * 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. >+ */ >+ >+#if ENABLE(WEBGPU) >+ >+#include "config.h" >+#include "WHLSLChecker.h" >+ >+#include "WHLSLArrayReferenceType.h" >+#include "WHLSLArrayType.h" >+#include "WHLSLAssignmentExpression.h" >+#include "WHLSLCallExpression.h" >+#include "WHLSLCommaExpression.h" >+#include "WHLSLDereferenceExpression.h" >+#include "WHLSLDoWhileLoop.h" >+#include "WHLSLDotExpression.h" >+#include "WHLSLForLoop.h" >+#include "WHLSLGatherEntryPointItems.h" >+#include "WHLSLIfStatement.h" >+#include "WHLSLInferTypes.h" >+#include "WHLSLLogicalExpression.h" >+#include "WHLSLLogicalNotExpression.h" >+#include "WHLSLMakeArrayReferenceExpression.h" >+#include "WHLSLMakePointerExpression.h" >+#include "WHLSLPointerType.h" >+#include "WHLSLProgram.h" >+#include "WHLSLReadModifyWriteExpression.h" >+#include "WHLSLResolvableType.h" >+#include "WHLSLResolveOverloadImpl.h" >+#include "WHLSLResolvingType.h" >+#include "WHLSLReturn.h" >+#include "WHLSLSwitchStatement.h" >+#include "WHLSLTernaryExpression.h" >+#include "WHLSLVisitor.h" >+#include "WHLSLWhileLoop.h" >+#include <wtf/HashMap.h> >+#include <wtf/HashSet.h> >+#include <wtf/Ref.h> >+#include <wtf/Vector.h> >+#include <wtf/text/WTFString.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+class PODChecker : public Visitor { >+public: >+ PODChecker() = default; >+ >+ virtual ~PODChecker() = default; >+ >+ void visit(AST::EnumerationDefinition& enumerationDefinition) override >+ { >+ Visitor::visit(enumerationDefinition); >+ } >+ >+ void visit(AST::NativeTypeDeclaration& nativeTypeDeclaration) override >+ { >+ if (!nativeTypeDeclaration.isNumber() >+ && !nativeTypeDeclaration.isVector() >+ && !nativeTypeDeclaration.isMatrix()) >+ setError(); >+ } >+ >+ void visit(AST::StructureDefinition& structureDefinition) override >+ { >+ Visitor::visit(structureDefinition); >+ } >+ >+ void visit(AST::TypeDefinition& typeDefinition) override >+ { >+ Visitor::visit(typeDefinition); >+ } >+ >+ void visit(AST::ArrayType& arrayType) override >+ { >+ Visitor::visit(arrayType); >+ } >+ >+ void visit(AST::PointerType&) override >+ { >+ setError(); >+ } >+ >+ void visit(AST::ArrayReferenceType&) override >+ { >+ setError(); >+ } >+ >+ void visit(AST::TypeReference& typeReference) override >+ { >+ ASSERT(typeReference.resolvedType()); >+ checkErrorAndVisit(*typeReference.resolvedType()); >+ } >+}; >+ >+static Optional<AST::NativeFunctionDeclaration> resolveWithOperatorAnderIndexer(AST::CallExpression& callExpression, AST::ArrayReferenceType& firstArgument, const Intrinsics& intrinsics) >+{ >+ bool isRestricted = false; >+ bool isOperator = true; >+ auto returnType = makeUniqueRef<AST::PointerType>(Lexer::Token(callExpression.origin()), firstArgument.addressSpace(), firstArgument.elementType().clone()); >+ AST::VariableDeclarations parameters; >+ parameters.append(AST::VariableDeclaration(Lexer::Token(callExpression.origin()), AST::Qualifiers(), firstArgument.clone().takeUniquePtr(), String(), WTF::nullopt, nullptr)); >+ parameters.append(AST::VariableDeclaration(Lexer::Token(callExpression.origin()), AST::Qualifiers(), AST::TypeReference::wrap(Lexer::Token(callExpression.origin()), intrinsics.uintType()).takeUniquePtr(), String(), WTF::nullopt, nullptr)); >+ return AST::NativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(callExpression.origin()), AST::AttributeBlock(), WTF::nullopt, WTFMove(returnType), String("operator&[]", String::ConstructFromLiteral), WTFMove(parameters), WTF::nullopt, isOperator), isRestricted); >+} >+ >+static Optional<AST::NativeFunctionDeclaration> resolveWithOperatorLength(AST::CallExpression& callExpression, AST::UnnamedType& firstArgument, const Intrinsics& intrinsics) >+{ >+ bool isRestricted = false; >+ bool isOperator = true; >+ auto returnType = AST::TypeReference::wrap(Lexer::Token(callExpression.origin()), intrinsics.uintType()); >+ AST::VariableDeclarations parameters; >+ parameters.append(AST::VariableDeclaration(Lexer::Token(callExpression.origin()), AST::Qualifiers(), firstArgument.clone().takeUniquePtr(), String(), WTF::nullopt, nullptr)); >+ return AST::NativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(callExpression.origin()), AST::AttributeBlock(), WTF::nullopt, WTFMove(returnType), String("operator.length", String::ConstructFromLiteral), WTFMove(parameters), WTF::nullopt, isOperator), isRestricted); >+} >+ >+static Optional<AST::NativeFunctionDeclaration> resolveWithReferenceComparator(AST::CallExpression& callExpression, ResolvingType& firstArgument, ResolvingType& secondArgument, const Intrinsics& intrinsics) >+{ >+ bool isRestricted = false; >+ bool isOperator = true; >+ auto returnType = AST::TypeReference::wrap(Lexer::Token(callExpression.origin()), intrinsics.boolType()); >+ auto argumentType = WTF::visit(WTF::makeVisitor([](UniqueRef<AST::UnnamedType>& unnamedType) -> UniqueRef<AST::UnnamedType> { >+ return unnamedType->clone(); >+ }, [&](Ref<ResolvableTypeReference>&) -> UniqueRef<AST::UnnamedType> { >+ return WTF::visit(WTF::makeVisitor([](UniqueRef<AST::UnnamedType>& unnamedType) -> UniqueRef<AST::UnnamedType> { >+ return unnamedType->clone(); >+ }, [&](Ref<ResolvableTypeReference>&) -> UniqueRef<AST::UnnamedType> { >+ // We encountered "null == null". >+ // The type isn't observable, so we can pick whatever we want. >+ // FIXME: This can probably be generalized, using the "preferred type" infrastructure used by generic literals >+ return AST::TypeReference::wrap(Lexer::Token(callExpression.origin()), intrinsics.intType()); >+ }), secondArgument); >+ }), firstArgument); >+ AST::VariableDeclarations parameters; >+ parameters.append(AST::VariableDeclaration(Lexer::Token(callExpression.origin()), AST::Qualifiers(), argumentType->clone().takeUniquePtr(), String(), WTF::nullopt, nullptr)); >+ parameters.append(AST::VariableDeclaration(Lexer::Token(callExpression.origin()), AST::Qualifiers(), argumentType.takeUniquePtr(), String(), WTF::nullopt, nullptr)); >+ return AST::NativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(callExpression.origin()), AST::AttributeBlock(), WTF::nullopt, WTFMove(returnType), String("operator==", String::ConstructFromLiteral), WTFMove(parameters), WTF::nullopt, isOperator), isRestricted); >+} >+ >+static Optional<AST::NativeFunctionDeclaration> resolveByInstantiation(AST::CallExpression& callExpression, const Vector<std::reference_wrapper<ResolvingType>>& types, const Intrinsics& intrinsics) >+{ >+ if (callExpression.name() == "operator&[]" && types.size() == 2) { >+ auto* firstArgumentArrayRef = WTF::visit(WTF::makeVisitor([](UniqueRef<AST::UnnamedType>& unnamedType) -> AST::ArrayReferenceType* { >+ if (is<AST::ArrayReferenceType>(static_cast<AST::UnnamedType&>(unnamedType))) >+ return &downcast<AST::ArrayReferenceType>(static_cast<AST::UnnamedType&>(unnamedType)); >+ return nullptr; >+ }, [](Ref<ResolvableTypeReference>&) -> AST::ArrayReferenceType* { >+ return nullptr; >+ }), types[0].get()); >+ bool secondArgumentIsUint = WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& unnamedType) -> bool { >+ return matches(static_cast<AST::UnnamedType&>(unnamedType), intrinsics.uintType()); >+ }, [&](Ref<ResolvableTypeReference>& resolvableTypeReference) -> bool { >+ return resolvableTypeReference->resolvableType().canResolve(intrinsics.uintType()); >+ }), types[1].get()); >+ if (firstArgumentArrayRef && secondArgumentIsUint) >+ return resolveWithOperatorAnderIndexer(callExpression, *firstArgumentArrayRef, intrinsics); >+ } else if (callExpression.name() == "operator.length" && types.size() == 1) { >+ auto* firstArgumentReference = WTF::visit(WTF::makeVisitor([](UniqueRef<AST::UnnamedType>& unnamedType) -> AST::UnnamedType* { >+ if (is<AST::ArrayReferenceType>(static_cast<AST::UnnamedType&>(unnamedType)) || is<AST::ArrayType>(static_cast<AST::UnnamedType&>(unnamedType))) >+ return &static_cast<AST::UnnamedType&>(unnamedType); >+ return nullptr; >+ }, [](Ref<ResolvableTypeReference>&) -> AST::UnnamedType* { >+ return nullptr; >+ }), types[0].get()); >+ if (firstArgumentReference) >+ return resolveWithOperatorLength(callExpression, *firstArgumentReference, intrinsics); >+ } else if (callExpression.name() == "operator==" && types.size() == 2) { >+ auto isAcceptable = [](ResolvingType& resolvingType) -> bool { >+ return WTF::visit(WTF::makeVisitor([](UniqueRef<AST::UnnamedType>& unnamedType) -> bool { >+ return is<AST::ReferenceType>(static_cast<AST::UnnamedType&>(unnamedType)); >+ }, [](Ref<ResolvableTypeReference>& resolvableTypeReference) -> bool { >+ return is<AST::NullLiteralType>(resolvableTypeReference->resolvableType()); >+ }), resolvingType); >+ }; >+ if (isAcceptable(types[0].get()) && isAcceptable(types[1].get())) >+ return resolveWithReferenceComparator(callExpression, types[0].get(), types[1].get(), intrinsics); >+ } >+ return WTF::nullopt; >+} >+ >+class Checker : public Visitor { >+public: >+ Checker(const Intrinsics& intrinsics, Program& program) >+ : m_intrinsics(intrinsics) >+ , m_program(program) >+ { >+ } >+ >+ ~Checker() = default; >+ >+ void visit(Program& program) override >+ { >+ for (auto& typeDefinition : program.typeDefinitions()) >+ checkErrorAndVisit(*typeDefinition); >+ for (auto& structureDefinition : program.structureDefinitions()) >+ checkErrorAndVisit(*structureDefinition); >+ for (auto& enumerationDefinition : program.enumerationDefinitions()) >+ checkErrorAndVisit(*enumerationDefinition); >+ for (auto& nativeTypeDeclaration : program.nativeTypeDeclarations()) >+ checkErrorAndVisit(*nativeTypeDeclaration); >+ >+ for (auto& functionDefinition : program.functionDefinitions()) >+ checkErrorAndVisit(*functionDefinition); >+ for (auto& nativeFunctionDeclaration : program.nativeFunctionDeclarations()) >+ checkErrorAndVisit(*nativeFunctionDeclaration); >+ } >+ >+private: >+ bool checkShaderType(const AST::FunctionDefinition& functionDefinition) >+ { >+ switch (*functionDefinition.entryPointType()) { >+ case AST::FunctionDefinition::EntryPointType::Vertex: >+ return !m_vertexEntryPoints.add(functionDefinition.name()).isNewEntry; >+ case AST::FunctionDefinition::EntryPointType::Fragment: >+ return !m_fragmentEntryPoints.add(functionDefinition.name()).isNewEntry; >+ case AST::FunctionDefinition::EntryPointType::Compute: >+ return !m_computeEntryPoints.add(functionDefinition.name()).isNewEntry; >+ } >+ } >+ >+ bool checkSemantics(AST::FunctionDefinition& functionDefinition) >+ { >+ auto entryPointItems = gatherEntryPointItems(m_intrinsics, functionDefinition); >+ if (!entryPointItems) >+ return false; >+ auto inputItems = WTFMove(entryPointItems->inputs); >+ auto outputItems = WTFMove(entryPointItems->outputs); >+ >+ { >+ auto checkDuplicateSemantics = [&](const Vector<EntryPointItem>& items) -> bool { >+ // FIXME: Make this faster than O(n^2). >+ for (size_t i = 0; i < items.size(); ++i) { >+ for (size_t j = i + 1; j < items.size(); ++j) { >+ if (items[i].semantic == items[j].semantic) >+ return false; >+ } >+ } >+ return true; >+ }; >+ if (!checkDuplicateSemantics(inputItems)) >+ return false; >+ if (!checkDuplicateSemantics(outputItems)) >+ return false; >+ } >+ >+ { >+ auto checkSemanticTypes = [&](const Vector<EntryPointItem>& items) -> bool { >+ for (auto& item : items) { >+ auto acceptable = WTF::visit(WTF::makeVisitor([&](const AST::BaseSemantic& semantic) -> bool { >+ return semantic.isAcceptableType(item.unnamedType, m_intrinsics); >+ }), item.semantic); >+ if (!acceptable) >+ return false; >+ } >+ return true; >+ }; >+ if (!checkSemanticTypes(inputItems)) >+ return false; >+ if (!checkSemanticTypes(outputItems)) >+ return false; >+ } >+ >+ { >+ auto checkSemanticForShaderType = [&](const Vector<EntryPointItem>& items, AST::BaseSemantic::ShaderItemDirection direction) -> bool { >+ for (auto& item : items) { >+ auto acceptable = WTF::visit(WTF::makeVisitor([&](const AST::BaseSemantic& semantic) -> bool { >+ return semantic.isAcceptableForShaderItemDirection(direction, functionDefinition); >+ }), item.semantic); >+ if (!acceptable) >+ return false; >+ } >+ return true; >+ }; >+ if (!checkSemanticForShaderType(inputItems, AST::BaseSemantic::ShaderItemDirection::Input)) >+ return false; >+ if (!checkSemanticForShaderType(outputItems, AST::BaseSemantic::ShaderItemDirection::Output)) >+ return false; >+ } >+ >+ { >+ auto checkPODData = [&](const Vector<EntryPointItem>& items) -> bool { >+ for (auto& item : items) { >+ PODChecker podChecker; >+ if (is<AST::PointerType>(item.unnamedType)) >+ podChecker.checkErrorAndVisit(downcast<AST::PointerType>(item.unnamedType).elementType()); >+ else if (is<AST::ArrayReferenceType>(item.unnamedType)) >+ podChecker.checkErrorAndVisit(downcast<AST::ArrayReferenceType>(item.unnamedType).elementType()); >+ else if (is<AST::ArrayType>(item.unnamedType)) >+ podChecker.checkErrorAndVisit(downcast<AST::ArrayType>(item.unnamedType).type()); >+ else >+ continue; >+ if (podChecker.error()) >+ return false; >+ } >+ return true; >+ }; >+ if (!checkPODData(inputItems)) >+ return false; >+ if (!checkPODData(outputItems)) >+ return false; >+ } >+ >+ return true; >+ } >+ >+ bool checkOperatorOverload(const AST::FunctionDefinition& functionDefinition) >+ { >+ enum class CheckKind { >+ Index, >+ Dot >+ }; >+ >+ auto checkGetter = [&](CheckKind kind) -> bool { >+ size_t numExpectedParameters = kind == CheckKind::Index ? 2 : 1; >+ if (functionDefinition.parameters().size() != numExpectedParameters) >+ return false; >+ auto& unifyNode = functionDefinition.parameters()[0].type()->unifyNode(); >+ if (is<AST::UnnamedType>(unifyNode)) { >+ auto& unnamedType = downcast<AST::UnnamedType>(unifyNode); >+ if (is<AST::PointerType>(unnamedType)) >+ return false; >+ } >+ return true; >+ }; >+ >+ auto checkSetter = [&](CheckKind kind) -> bool { >+ size_t numExpectedParameters = kind == CheckKind::Index ? 3 : 2; >+ if (functionDefinition.parameters().size() != numExpectedParameters) >+ return false; >+ auto& firstArgumentUnifyNode = functionDefinition.parameters()[0].type()->unifyNode(); >+ if (is<AST::UnnamedType>(firstArgumentUnifyNode)) { >+ auto& unnamedType = downcast<AST::UnnamedType>(firstArgumentUnifyNode); >+ if (is<AST::PointerType>(unnamedType)) >+ return false; >+ } >+ if (!matches(functionDefinition.type(), *functionDefinition.parameters()[0].type())) >+ return false; >+ auto& valueType = *functionDefinition.parameters()[numExpectedParameters - 1].type(); >+ auto getterName = functionDefinition.name().substring(0, functionDefinition.name().length() - 1); >+ auto* getterFuncs = m_program.nameContext().getFunctions(getterName); >+ if (!getterFuncs) >+ return false; >+ Vector<ResolvingType> argumentTypes; >+ Vector<std::reference_wrapper<ResolvingType>> argumentTypeReferences; >+ for (size_t i = 0; i < numExpectedParameters - 1; ++i) >+ argumentTypes.append(functionDefinition.parameters()[i].type()->clone()); >+ for (auto& argumentType : argumentTypes) >+ argumentTypeReferences.append(argumentType); >+ Optional<std::reference_wrapper<AST::NamedType>> castReturnType = WTF::nullopt; >+ auto* overload = resolveFunctionOverloadImpl(*getterFuncs, argumentTypeReferences, castReturnType); >+ if (!overload) >+ return false; >+ auto& resultType = overload->type(); >+ if (!matches(resultType, valueType)) >+ return false; >+ return true; >+ }; >+ >+ auto checkAnder = [&](CheckKind kind) -> bool { >+ size_t numExpectedParameters = kind == CheckKind::Index ? 2 : 1; >+ if (functionDefinition.parameters().size() != numExpectedParameters) >+ return false; >+ { >+ auto& unifyNode = functionDefinition.type().unifyNode(); >+ if (!is<AST::UnnamedType>(unifyNode)) >+ return false; >+ auto& unnamedType = downcast<AST::UnnamedType>(unifyNode); >+ if (!is<AST::PointerType>(unnamedType)) >+ return false; >+ } >+ { >+ auto& unifyNode = functionDefinition.parameters()[0].type()->unifyNode(); >+ if (!is<AST::UnnamedType>(unifyNode)) >+ return false; >+ auto& unnamedType = downcast<AST::UnnamedType>(unifyNode); >+ if (!is<AST::PointerType>(unnamedType) && !is<AST::ArrayReferenceType>(unnamedType)) >+ return false; >+ } >+ >+ return true; >+ }; >+ >+ if (!functionDefinition.isOperator()) >+ return true; >+ if (functionDefinition.isCast()) >+ return true; >+ if (functionDefinition.name() == "operator++" >+ || functionDefinition.name() == "operator--") { >+ if (functionDefinition.parameters().size() != 1) >+ return false; >+ if (!matches(*functionDefinition.parameters()[0].type(), functionDefinition.type())) >+ return false; >+ return true; >+ } >+ if (functionDefinition.name() == "operator+" >+ || functionDefinition.name() == "operator-") { >+ if (functionDefinition.parameters().size() != 1 >+ && functionDefinition.parameters().size() != 2) >+ return false; >+ return true; >+ } >+ if (functionDefinition.name() == "operator*" >+ || functionDefinition.name() == "operator/" >+ || functionDefinition.name() == "operator%" >+ || functionDefinition.name() == "operator&" >+ || functionDefinition.name() == "operator|" >+ || functionDefinition.name() == "operator^" >+ || functionDefinition.name() == "operator<<" >+ || functionDefinition.name() == "opreator>>") { >+ if (functionDefinition.parameters().size() != 2) >+ return false; >+ return true; >+ } >+ if (functionDefinition.name() == "operator~") { >+ if (functionDefinition.parameters().size() != 1) >+ return false; >+ return true; >+ } >+ if (functionDefinition.name() == "operator==" >+ || functionDefinition.name() == "operator<" >+ || functionDefinition.name() == "operator<=" >+ || functionDefinition.name() == "operator>" >+ || functionDefinition.name() == "operator>=") { >+ if (functionDefinition.parameters().size() != 2) >+ return false; >+ if (!matches(functionDefinition.type(), m_intrinsics.boolType())) >+ return false; >+ return true; >+ } >+ if (functionDefinition.name() == "operator[]") { >+ if (!checkGetter(CheckKind::Index)) >+ return false; >+ return true; >+ } >+ if (functionDefinition.name() == "operator[]=") { >+ if (!checkSetter(CheckKind::Index)) >+ return false; >+ return true; >+ } >+ if (functionDefinition.name() == "operator&[]") { >+ if (!checkAnder(CheckKind::Index)) >+ return false; >+ return true; >+ } >+ if (functionDefinition.name().startsWith("operator.")) { >+ if (functionDefinition.name().endsWith("=")) { >+ if (!checkSetter(CheckKind::Dot)) >+ return false; >+ } else { >+ if (!checkGetter(CheckKind::Dot)) >+ return false; >+ } >+ return true; >+ } >+ if (functionDefinition.name().startsWith("operator&.")) { >+ if (!checkAnder(CheckKind::Dot)) >+ return false; >+ return true; >+ } >+ return false; >+ } >+ >+ void visit(AST::FunctionDefinition& functionDefinition) override >+ { >+ if (functionDefinition.entryPointType()) { >+ if (!checkShaderType(functionDefinition)) { >+ setError(); >+ return; >+ } >+ if (!checkSemantics(functionDefinition)) { >+ setError(); >+ return; >+ } >+ } >+ if (!checkOperatorOverload(functionDefinition)) { >+ setError(); >+ return; >+ } >+ >+ checkErrorAndVisit(functionDefinition); >+ } >+ >+ void visit(AST::EnumerationDefinition& enumerationDefinition) override >+ { >+ checkErrorAndVisit(enumerationDefinition.type()); >+ >+ auto& baseType = enumerationDefinition.type().unifyNode(); >+ >+ if (!is<AST::UnnamedType>(baseType)) { >+ setError(); >+ return; >+ } >+ auto& unnamedBase = downcast<AST::UnnamedType>(baseType); >+ if (!is<AST::TypeReference>(unnamedBase)) { >+ setError(); >+ return; >+ } >+ auto& typeReferenceBase = downcast<AST::TypeReference>(unnamedBase); >+ ASSERT(typeReferenceBase.resolvedType()); >+ if (!is<AST::NativeTypeDeclaration>(*typeReferenceBase.resolvedType())) { >+ setError(); >+ return; >+ } >+ auto& nativeTypeDeclaration = downcast<AST::NativeTypeDeclaration>(*typeReferenceBase.resolvedType()); >+ if (!nativeTypeDeclaration.isInt()) { >+ setError(); >+ return; >+ } >+ >+ auto enumerationMembers = enumerationDefinition.enumerationMembers(); >+ >+ for (auto& member : enumerationMembers) { >+ if (!member.get().value()) >+ continue; >+ >+ bool success; >+ member.get().value()->visit(WTF::makeVisitor([&](auto& value) { >+ checkErrorAndVisit(value); >+ auto iterator = m_typeMap.find(&value); >+ ASSERT(iterator != m_typeMap.end()); >+ success = WTF::visit(WTF::makeVisitor([&](std::unique_ptr<AST::UnnamedType>& unnamedType) -> bool { >+ return matches(*unnamedType, enumerationDefinition); >+ }, [&](ResolvableTypeReference& resolvableTypeReference) -> bool { >+ return static_cast<bool>(matchAndCommit(enumerationDefinition, resolvableTypeReference.resolvableType())); >+ }), iterator->value); >+ })); >+ if (!success) { >+ setError(); >+ return; >+ } >+ } >+ >+ int64_t nextValue = 0; >+ for (auto& member : enumerationMembers) { >+ if (member.get().value()) { >+ int64_t value; >+ member.get().value()->visit(WTF::makeVisitor([&](AST::IntegerLiteral& integerLiteral) { >+ value = integerLiteral.valueForSelectedType(); >+ }, [&](AST::UnsignedIntegerLiteral& unsignedIntegerLiteral) { >+ value = unsignedIntegerLiteral.valueForSelectedType(); >+ }, [&](AST::FloatLiteral&) { >+ ASSERT_NOT_REACHED(); >+ }, [&](AST::NullLiteral&) { >+ ASSERT_NOT_REACHED(); >+ }, [&](AST::BooleanLiteral&) { >+ ASSERT_NOT_REACHED(); >+ }, [&](AST::ConstantExpressionEnumerationMemberReference&) { >+ ASSERT_NOT_REACHED(); >+ })); >+ nextValue = nativeTypeDeclaration.successor()(value); >+ } else { >+ member.get().setValue(AST::ConstantExpression(AST::IntegerLiteral(Lexer::Token(member.get().origin()), nextValue))); >+ nextValue = nativeTypeDeclaration.successor()(nextValue); >+ } >+ } >+ >+ for (size_t i = 0; i < enumerationMembers.size(); ++i) { >+ auto& member = enumerationMembers[i].get(); >+ ASSERT(member.value()); >+ int64_t value; >+ member.value()->visit(WTF::makeVisitor([&](AST::IntegerLiteral& integerLiteral) { >+ value = integerLiteral.value(); >+ }, [&](AST::UnsignedIntegerLiteral& unsignedIntegerLiteral) { >+ value = unsignedIntegerLiteral.value(); >+ }, [&](AST::FloatLiteral&) { >+ ASSERT_NOT_REACHED(); >+ }, [&](AST::NullLiteral&) { >+ ASSERT_NOT_REACHED(); >+ }, [&](AST::BooleanLiteral&) { >+ ASSERT_NOT_REACHED(); >+ }, [&](AST::ConstantExpressionEnumerationMemberReference&) { >+ ASSERT_NOT_REACHED(); >+ })); >+ for (size_t j = i + 1; j < enumerationMembers.size(); ++j) { >+ auto& otherMember = enumerationMembers[j].get(); >+ ASSERT(otherMember.value()); >+ bool fail = false; >+ otherMember.value()->visit(WTF::makeVisitor([&](AST::IntegerLiteral& integerLiteral) { >+ fail = value == integerLiteral.value(); >+ }, [&](AST::UnsignedIntegerLiteral& unsignedIntegerLiteral) { >+ fail = value == unsignedIntegerLiteral.value(); >+ }, [&](AST::FloatLiteral&) { >+ ASSERT_NOT_REACHED(); >+ }, [&](AST::NullLiteral&) { >+ ASSERT_NOT_REACHED(); >+ }, [&](AST::BooleanLiteral&) { >+ ASSERT_NOT_REACHED(); >+ }, [&](AST::ConstantExpressionEnumerationMemberReference&) { >+ ASSERT_NOT_REACHED(); >+ })); >+ if (fail) { >+ setError(); >+ return; >+ } >+ } >+ } >+ >+ bool foundZero = false; >+ for (auto& member : enumerationMembers) { >+ ASSERT(member.get().value()); >+ member.get().value()->visit(WTF::makeVisitor([&](AST::IntegerLiteral& integerLiteral) { >+ if (integerLiteral.value() == 0) >+ foundZero = true; >+ }, [&](AST::UnsignedIntegerLiteral& unsignedIntegerLiteral) { >+ if (unsignedIntegerLiteral.value() == 0) >+ foundZero = true; >+ }, [&](AST::FloatLiteral&) { >+ ASSERT_NOT_REACHED(); >+ }, [&](AST::NullLiteral&) { >+ ASSERT_NOT_REACHED(); >+ }, [&](AST::BooleanLiteral&) { >+ ASSERT_NOT_REACHED(); >+ }, [&](AST::ConstantExpressionEnumerationMemberReference&) { >+ ASSERT_NOT_REACHED(); >+ })); >+ } >+ if (!foundZero) { >+ setError(); >+ return; >+ } >+ } >+ >+ void visit(AST::TypeReference& typeReference) override >+ { >+ ASSERT(typeReference.resolvedType()); >+ >+ checkErrorAndVisit(typeReference); >+ } >+ >+ void visit(AST::VariableDeclaration& variableDeclaration) override >+ { >+ checkErrorAndVisit(*variableDeclaration.type()); // FIXME: Make this work with anonymous variables which don't have types. >+ if (variableDeclaration.initializer()) { >+ auto& lhsType = *variableDeclaration.type(); >+ checkErrorAndVisit(*variableDeclaration.initializer()); >+ auto iterator = m_typeMap.find(variableDeclaration.initializer()); >+ ASSERT(iterator != m_typeMap.end()); >+ auto& rhs = iterator->value; >+ auto success = WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& unnamedType) -> bool { >+ return matches(lhsType, static_cast<AST::UnnamedType&>(unnamedType)); >+ }, [&](Ref<ResolvableTypeReference>& resolvableTypeReference) -> bool { >+ return static_cast<bool>(matchAndCommit(lhsType, resolvableTypeReference->resolvableType())); >+ }), rhs); >+ if (!success) { >+ setError(); >+ return; >+ } >+ } >+ } >+ >+ void visit(AST::AssignmentExpression& assignmentExpression) override >+ { >+ checkErrorAndVisit(assignmentExpression.left()); >+ auto leftIterator = m_typeMap.find(&assignmentExpression.left()); >+ ASSERT(leftIterator != m_typeMap.end()); >+ auto& lhsType = leftIterator->value; >+ // FIXME: How to do lvalue and address space analysis? >+ checkErrorAndVisit(assignmentExpression.right()); >+ auto rightIterator = m_typeMap.find(&assignmentExpression.right()); >+ ASSERT(rightIterator != m_typeMap.end()); >+ auto& rhsType = rightIterator->value; >+ auto resultType = WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& left) -> std::unique_ptr<AST::UnnamedType> { >+ return WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& right) -> std::unique_ptr<AST::UnnamedType> { >+ if (matches(static_cast<AST::UnnamedType&>(left), static_cast<AST::UnnamedType&>(right))) >+ return left->clone().takeUniquePtr(); >+ return nullptr; >+ }, [&](Ref<ResolvableTypeReference>& right) -> std::unique_ptr<AST::UnnamedType> { >+ return matchAndCommit(static_cast<AST::UnnamedType&>(left), right->resolvableType()); >+ }), rhsType); >+ }, [&](Ref<ResolvableTypeReference>& left) -> std::unique_ptr<AST::UnnamedType> { >+ return WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& right) -> std::unique_ptr<AST::UnnamedType> { >+ return matchAndCommit(static_cast<AST::UnnamedType&>(right), left->resolvableType()); >+ }, [&](Ref<ResolvableTypeReference>& right) -> std::unique_ptr<AST::UnnamedType> { >+ return matchAndCommit(left->resolvableType(), right->resolvableType()); >+ }), rhsType); >+ }), lhsType); >+ if (!resultType) { >+ setError(); >+ return; >+ } >+ auto addResult = m_typeMap.add(&assignmentExpression, WTFMove(resultType)); >+ ASSERT_UNUSED(addResult, addResult.isNewEntry); >+ } >+ >+ void visit(AST::ReadModifyWriteExpression& readModifyWriteExpression) override >+ { >+ checkErrorAndVisit(readModifyWriteExpression.lValue()); >+ auto lValueIterator = m_typeMap.find(&readModifyWriteExpression.lValue()); >+ ASSERT(lValueIterator != m_typeMap.end()); >+ auto& lhsType = lValueIterator->value; >+ // FIXME: How to do lvalue and address space analysis? >+ // FIXME: Figure out what to do with the ReadModifyWriteExpression's AnonymousVariables. >+ checkErrorAndVisit(readModifyWriteExpression.newValueExpression()); >+ auto newValueIterator = m_typeMap.find(&readModifyWriteExpression.newValueExpression()); >+ ASSERT(newValueIterator != m_typeMap.end()); >+ auto& newValueType = newValueIterator->value; >+ auto success = WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& left) -> bool { >+ return WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& right) -> bool { >+ return matches(static_cast<AST::UnnamedType&>(left), static_cast<AST::UnnamedType&>(right)); >+ }, [&](Ref<ResolvableTypeReference>& right) -> bool { >+ return static_cast<bool>(matchAndCommit(static_cast<AST::UnnamedType&>(left), right->resolvableType())); >+ }), newValueType); >+ }, [&](Ref<ResolvableTypeReference>& left) -> bool { >+ return WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& right) -> bool { >+ return static_cast<bool>(matchAndCommit(static_cast<AST::UnnamedType&>(right), left->resolvableType())); >+ }, [&](Ref<ResolvableTypeReference>& right) -> bool { >+ return static_cast<bool>(matchAndCommit(left->resolvableType(), right->resolvableType())); >+ }), newValueType); >+ }), lhsType); >+ if (!success) { >+ setError(); >+ return; >+ } >+ checkErrorAndVisit(readModifyWriteExpression.resultExpression()); >+ auto resultIterator = m_typeMap.find(&readModifyWriteExpression.resultExpression()); >+ ASSERT(resultIterator != m_typeMap.end()); >+ auto& resultType = resultIterator->value; >+ WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& result) { >+ auto addResult = m_typeMap.add(&readModifyWriteExpression, result->clone()); >+ ASSERT_UNUSED(addResult, addResult.isNewEntry); >+ }, [&](Ref<ResolvableTypeReference>& result) { >+ auto addResult = m_typeMap.add(&readModifyWriteExpression, result.copyRef()); >+ ASSERT_UNUSED(addResult, addResult.isNewEntry); >+ }), resultType); >+ } >+ >+ void visit(AST::DereferenceExpression& dereferenceExpression) override >+ { >+ checkErrorAndVisit(dereferenceExpression.pointer()); >+ auto pointerIterator = m_typeMap.find(&dereferenceExpression.pointer()); >+ ASSERT(pointerIterator != m_typeMap.end()); >+ auto& type = pointerIterator->value; >+ auto* pointerType = WTF::visit(WTF::makeVisitor([](UniqueRef<AST::UnnamedType>& type) -> AST::PointerType* { >+ auto& unifyNode = type->unifyNode(); >+ if (!is<AST::UnnamedType>(unifyNode)) >+ return nullptr; >+ auto& unnamedType = downcast<AST::UnnamedType>(unifyNode); >+ if (!is<AST::PointerType>(unnamedType)) >+ return nullptr; >+ return &downcast<AST::PointerType>(unnamedType); >+ }, [](Ref<ResolvableTypeReference>& type) -> AST::PointerType* { >+ auto* resolvedType = type->resolvableType().resolvedType(); >+ if (!resolvedType) >+ return nullptr; >+ auto& unifyNode = resolvedType->unifyNode(); >+ if (!is<AST::UnnamedType>(unifyNode)) >+ return nullptr; >+ auto& unnamedType = downcast<AST::UnnamedType>(unifyNode); >+ if (!is<AST::PointerType>(unnamedType)) >+ return nullptr; >+ return &downcast<AST::PointerType>(unnamedType); >+ }), type); >+ if (!pointerType) { >+ setError(); >+ return; >+ } >+ // FIXME: How to do lvalue and address space analysis? >+ auto addResult = m_typeMap.add(&dereferenceExpression, pointerType->clone()); >+ ASSERT_UNUSED(addResult, addResult.isNewEntry); >+ } >+ >+ void visit(AST::MakePointerExpression& makePointerExpression) override >+ { >+ checkErrorAndVisit(makePointerExpression.lValue()); >+ auto lValueIterator = m_typeMap.find(&makePointerExpression.lValue()); >+ ASSERT(lValueIterator != m_typeMap.end()); >+ auto& elementType = lValueIterator->value; >+ auto* lValueType = WTF::visit(WTF::makeVisitor([](UniqueRef<AST::UnnamedType>& type) -> AST::UnnamedType* { >+ return &static_cast<AST::UnnamedType&>(type); >+ }, [](Ref<ResolvableTypeReference>& type) -> AST::UnnamedType* { >+ return type->resolvableType().resolvedType(); >+ }), elementType); >+ if (!lValueType) { >+ setError(); >+ return; >+ } >+ // FIXME: How to do lvalue and address space analysis? >+ AST::ReferenceType::AddressSpace addressSpace = AST::ReferenceType::AddressSpace::Device; >+ auto addResult = m_typeMap.add(&makePointerExpression, std::make_unique<AST::PointerType>(Lexer::Token(makePointerExpression.origin()), addressSpace, lValueType->clone())); >+ ASSERT_UNUSED(addResult, addResult.isNewEntry); >+ } >+ >+ void visit(AST::MakeArrayReferenceExpression& makeArrayReferenceExpression) override >+ { >+ checkErrorAndVisit(makeArrayReferenceExpression.lValue()); >+ auto lValueIterator = m_typeMap.find(&makeArrayReferenceExpression.lValue()); >+ ASSERT(lValueIterator != m_typeMap.end()); >+ auto& elementType = lValueIterator->value; >+ auto* unnamedType = WTF::visit(WTF::makeVisitor([](UniqueRef<AST::UnnamedType>& type) -> AST::UnnamedType* { >+ return &static_cast<AST::UnnamedType&>(type); >+ }, [](Ref<ResolvableTypeReference>& type) -> AST::UnnamedType* { >+ return type->resolvableType().resolvedType(); >+ }), elementType); >+ if (!unnamedType) { >+ setError(); >+ return; >+ } >+ auto& unifyNode = unnamedType->unifyNode(); >+ if (is<AST::UnnamedType>(unifyNode)) { >+ auto& unnamedType = downcast<AST::UnnamedType>(unifyNode); >+ if (is<AST::PointerType>(unnamedType)) { >+ auto& pointerType = downcast<AST::PointerType>(unnamedType); >+ // FIXME: Become a ConvertPointerToArrayReferenceExpression >+ auto addResult = m_typeMap.add(&makeArrayReferenceExpression, std::make_unique<AST::ArrayReferenceType>(Lexer::Token(makeArrayReferenceExpression.origin()), pointerType.addressSpace(), pointerType.elementType().clone())); >+ ASSERT_UNUSED(addResult, addResult.isNewEntry); >+ return; >+ } >+ >+ // FIXME: How to do lvalue and address space analysis? >+ if (is<AST::ArrayType>(unnamedType)) { >+ auto& arrayType = downcast<AST::ArrayType>(unnamedType); >+ // FIXME: How to do lvalue and address space analysis? >+ AST::ReferenceType::AddressSpace addressSpace = AST::ReferenceType::AddressSpace::Device; >+ // FIXME: Save the number of elements. >+ auto addResult = m_typeMap.add(&makeArrayReferenceExpression, std::make_unique<AST::ArrayReferenceType>(Lexer::Token(makeArrayReferenceExpression.origin()), addressSpace, arrayType.type().clone())); >+ ASSERT_UNUSED(addResult, addResult.isNewEntry); >+ return; >+ } >+ } >+ >+ // FIXME: How to do lvalue and address space analysis? >+ AST::ReferenceType::AddressSpace addressSpace = AST::ReferenceType::AddressSpace::Device; >+ auto addResult = m_typeMap.add(&makeArrayReferenceExpression, std::make_unique<AST::ArrayReferenceType>(Lexer::Token(makeArrayReferenceExpression.origin()), addressSpace, unnamedType->clone())); >+ ASSERT_UNUSED(addResult, addResult.isNewEntry); >+ } >+ >+ void visit(AST::DotExpression& dotExpression) override >+ { >+ checkErrorAndVisit(dotExpression.base()); >+ auto baseIterator = m_typeMap.find(&dotExpression.base()); >+ ASSERT(baseIterator != m_typeMap.end()); >+ auto& baseType = baseIterator->value; >+ auto* baseUnifyNode = WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& baseType) -> AST::Type* { >+ return &baseType->unifyNode(); >+ }, [&](Ref<ResolvableTypeReference>& baseType) -> AST::Type* { >+ if (!baseType->resolvableType().resolvedType()) { >+ if (!static_cast<bool>(commit(baseType->resolvableType()))) >+ return nullptr; >+ } >+ return &baseType->resolvableType().resolvedType()->unifyNode(); >+ }), baseType); >+ if (!baseUnifyNode) { >+ setError(); >+ return; >+ } >+ auto wrappedBaseType = ([&]() -> UniqueRef<AST::UnnamedType> { >+ if (is<AST::UnnamedType>(*baseUnifyNode)) >+ return downcast<AST::UnnamedType>(*baseUnifyNode).clone(); >+ else { >+ ASSERT(is<AST::NamedType>(baseUnifyNode)); >+ return AST::TypeReference::wrap(Lexer::Token(dotExpression.origin()), downcast<AST::NamedType>(*baseUnifyNode)); >+ } >+ })(); >+ >+ Optional<std::reference_wrapper<AST::NamedType>> castReturnType; >+ >+ ResolvingType getArgumentType(wrappedBaseType->clone()); >+ Vector<std::reference_wrapper<ResolvingType>> getArgumentTypes; >+ getArgumentTypes.append(WTFMove(getArgumentType)); >+ auto* getFunction = resolveFunctionOverloadImpl(dotExpression.possibleGetOverloads(), getArgumentTypes, castReturnType); >+ AST::UnnamedType* getReturnType = nullptr; >+ if (getFunction) >+ getReturnType = &getFunction->type(); >+ >+ AST::FunctionDeclaration* andFunction = nullptr; >+ AST::UnnamedType* andReturnType = nullptr; >+ auto computeAndArgumentType = [&](AST::UnnamedType& unnamedType) -> Optional<ResolvingType> { >+ if (is<AST::ArrayReferenceType>(unnamedType)) >+ return { unnamedType.clone() }; >+ if (is<AST::ArrayType>(unnamedType)) >+ return { makeUniqueRef<AST::ArrayReferenceType>(Lexer::Token(dotExpression.origin()), AST::ReferenceType::AddressSpace::Thread, downcast<AST::ArrayType>(unnamedType).type().clone()) }; >+ if (is<AST::PointerType>(unnamedType)) >+ return WTF::nullopt; >+ return { makeUniqueRef<AST::PointerType>(Lexer::Token(dotExpression.origin()), AST::ReferenceType::AddressSpace::Thread, downcast<AST::ArrayType>(unnamedType).type().clone()) }; >+ }; >+ auto computeAndReturnType = [&](AST::UnnamedType& unnamedType) -> AST::UnnamedType* { >+ if (is<AST::PointerType>(unnamedType)) >+ return &downcast<AST::PointerType>(unnamedType).elementType(); >+ return nullptr; >+ }; >+ auto andArgumentType = computeAndArgumentType(static_cast<AST::UnnamedType&>(wrappedBaseType)); >+ if (andArgumentType) { >+ Vector<std::reference_wrapper<ResolvingType>> andArgumentTypes; >+ andArgumentTypes.append(WTFMove(*andArgumentType)); >+ andFunction = resolveFunctionOverloadImpl(dotExpression.possibleAndOverloads(), andArgumentTypes, castReturnType); >+ if (andFunction) >+ andReturnType = computeAndReturnType(andFunction->type()); >+ } >+ >+ if (!getReturnType && !andReturnType) { >+ setError(); >+ return; >+ } >+ >+ if (getReturnType && andReturnType && !matches(*getReturnType, *andReturnType)) { >+ setError(); >+ return; >+ } >+ >+ ResolvingType setArgument1Type(wrappedBaseType->clone()); >+ ResolvingType setArgument2Type(getReturnType ? getReturnType->clone() : andReturnType->clone()); >+ Vector<std::reference_wrapper<ResolvingType>> setArgumentTypes; >+ setArgumentTypes.append(WTFMove(setArgument1Type)); >+ setArgumentTypes.append(WTFMove(setArgument2Type)); >+ auto* setFunction = resolveFunctionOverloadImpl(dotExpression.possibleSetOverloads(), setArgumentTypes, castReturnType); >+ if (setFunction) { >+ if (!matches(setFunction->type(), static_cast<AST::UnnamedType&>(wrappedBaseType))) { >+ setError(); >+ return; >+ } >+ } >+ >+ // FIXME: How to do lvalue and address space analysis? >+ >+ // FIXME: Generate the call expressions >+ /*Vector<std::unique_ptr<AST::Expression>> getArguments; >+ getArguments.append(dotExpression.base()); // FIXME: This has to be the same base as dotExpression.base(). >+ auto callForGet = std::make_unique<AST::CallExpression>(Lexer::Token(dotExpression.origin()), dotExpression.getFunctionName(), WTFMove(getArguments)); >+ callForGet->setFunction(*getFunction); >+ auto getResultType = getFunction->type().clone();*/ >+ } >+ >+ void visit(AST::IndexExpression&) override >+ { >+ // FIXME: Implement me >+ } >+ >+ void visit(AST::VariableReference& variableReference) override >+ { >+ ASSERT(variableReference.variable()); >+ ASSERT(variableReference.variable()->type()); >+ auto addResult = m_typeMap.add(&variableReference, variableReference.variable()->type()->clone()); >+ ASSERT_UNUSED(addResult, addResult.isNewEntry); >+ } >+ >+ void visit(AST::Return& returnStatement) override >+ { >+ ASSERT(returnStatement.function()); >+ if (returnStatement.value()) { >+ checkErrorAndVisit(*returnStatement.value()); >+ auto valueIterator = m_typeMap.find(returnStatement.value()); >+ ASSERT(valueIterator != m_typeMap.end()); >+ auto& resultType = valueIterator->value; >+ auto success = WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& resultType) -> bool { >+ return matches(returnStatement.function()->type(), static_cast<AST::UnnamedType&>(resultType)); >+ }, [&](Ref<ResolvableTypeReference>& resultType) -> bool { >+ return static_cast<bool>(matchAndCommit(returnStatement.function()->type(), resultType->resolvableType())); >+ }), resultType); >+ if (!success) >+ setError(); >+ return; >+ } >+ >+ if (!matches(returnStatement.function()->type(), m_intrinsics.voidType())) >+ setError(); >+ } >+ >+ void visit(AST::PointerType&) override >+ { >+ // Following pointer types can cause infinite loops because of data structures >+ // like linked lists. >+ // FIXME: Make sure this function should be empty >+ } >+ >+ void visit(AST::ArrayReferenceType&) override >+ { >+ // Following array reference types can cause infinite loops because of data >+ // structures like linked lists. >+ // FIXME: Make sure this function should be empty >+ } >+ >+ void visit(AST::IntegerLiteral& integerLiteral) override >+ { >+ auto ref = adoptRef(*new ResolvableTypeReference(integerLiteral.type())); >+ auto addResult = m_typeMap.add(&integerLiteral, WTFMove(ref)); >+ ASSERT_UNUSED(addResult, addResult.isNewEntry); >+ } >+ >+ void visit(AST::UnsignedIntegerLiteral& unsignedIntegerLiteral) override >+ { >+ auto ref = adoptRef(*new ResolvableTypeReference(unsignedIntegerLiteral.type())); >+ auto addResult = m_typeMap.add(&unsignedIntegerLiteral, WTFMove(ref)); >+ ASSERT_UNUSED(addResult, addResult.isNewEntry); >+ } >+ >+ void visit(AST::FloatLiteral& floatLiteral) override >+ { >+ auto ref = adoptRef(*new ResolvableTypeReference(floatLiteral.type())); >+ auto addResult = m_typeMap.add(&floatLiteral, WTFMove(ref)); >+ ASSERT_UNUSED(addResult, addResult.isNewEntry); >+ } >+ >+ void visit(AST::NullLiteral& nullLiteral) override >+ { >+ auto ref = adoptRef(*new ResolvableTypeReference(nullLiteral.type())); >+ auto addResult = m_typeMap.add(&nullLiteral, WTFMove(ref)); >+ ASSERT_UNUSED(addResult, addResult.isNewEntry); >+ } >+ >+ void visit(AST::BooleanLiteral& booleanLiteral) override >+ { >+ auto addResult = m_typeMap.add(&booleanLiteral, AST::TypeReference::wrap(Lexer::Token(booleanLiteral.origin()), m_intrinsics.boolType())); >+ ASSERT_UNUSED(addResult, addResult.isNewEntry); >+ } >+ >+ void visit(AST::ConstantExpressionEnumerationMemberReference& constantExpressionEnumerationMemberReference) override >+ { >+ ASSERT(constantExpressionEnumerationMemberReference.enumerationDefinition()); >+ auto& enumerationDefinition = *constantExpressionEnumerationMemberReference.enumerationDefinition(); >+ auto addResult = m_typeMap.add(&constantExpressionEnumerationMemberReference, AST::TypeReference::wrap(Lexer::Token(constantExpressionEnumerationMemberReference.origin()), enumerationDefinition)); >+ ASSERT_UNUSED(addResult, addResult.isNewEntry); >+ } >+ >+ bool isBoolType(ResolvingType& resolvingType) >+ { >+ return WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& left) -> bool { >+ return matches(static_cast<AST::UnnamedType&>(left), m_intrinsics.boolType()); >+ }, [&](Ref<ResolvableTypeReference>& left) -> bool { >+ return static_cast<bool>(matchAndCommit(m_intrinsics.boolType(), left->resolvableType())); >+ }), resolvingType); >+ } >+ >+ void visit(AST::LogicalNotExpression& logicalNotExpression) override >+ { >+ checkErrorAndVisit(logicalNotExpression.operand()); >+ auto operandIterator = m_typeMap.find(&logicalNotExpression.operand()); >+ ASSERT(operandIterator != m_typeMap.end()); >+ auto& operandType = operandIterator->value; >+ if (!isBoolType(operandType)) { >+ setError(); >+ return; >+ } >+ auto addResult = m_typeMap.add(&logicalNotExpression, AST::TypeReference::wrap(Lexer::Token(logicalNotExpression.origin()), m_intrinsics.boolType())); >+ ASSERT_UNUSED(addResult, addResult.isNewEntry); >+ } >+ >+ void visit(AST::LogicalExpression& logicalExpression) override >+ { >+ checkErrorAndVisit(logicalExpression.left()); >+ auto leftIterator = m_typeMap.find(&logicalExpression.left()); >+ ASSERT(leftIterator != m_typeMap.end()); >+ auto& leftType = leftIterator->value; >+ >+ checkErrorAndVisit(logicalExpression.right()); >+ auto rightIterator = m_typeMap.find(&logicalExpression.right()); >+ ASSERT(rightIterator != m_typeMap.end()); >+ auto& rightType = rightIterator->value; >+ >+ if (!isBoolType(leftType) || !isBoolType(rightType)) { >+ setError(); >+ return; >+ } >+ auto addResult = m_typeMap.add(&logicalExpression, AST::TypeReference::wrap(Lexer::Token(logicalExpression.origin()), m_intrinsics.boolType())); >+ ASSERT_UNUSED(addResult, addResult.isNewEntry); >+ } >+ >+ void visit(AST::IfStatement& ifStatement) override >+ { >+ checkErrorAndVisit(ifStatement.conditional()); >+ auto conditionalIterator = m_typeMap.find(&ifStatement.conditional()); >+ ASSERT(conditionalIterator != m_typeMap.end()); >+ auto& conditionalType = conditionalIterator->value; >+ if (!isBoolType(conditionalType)) { >+ setError(); >+ return; >+ } >+ checkErrorAndVisit(ifStatement.body()); >+ if (ifStatement.elseBody()) >+ checkErrorAndVisit(*ifStatement.elseBody()); >+ } >+ >+ void visit(AST::WhileLoop& whileLoop) override >+ { >+ checkErrorAndVisit(whileLoop.conditional()); >+ auto conditionalIterator = m_typeMap.find(&whileLoop.conditional()); >+ ASSERT(conditionalIterator != m_typeMap.end()); >+ auto& conditionalType = conditionalIterator->value; >+ if (!isBoolType(conditionalType)) { >+ setError(); >+ return; >+ } >+ checkErrorAndVisit(whileLoop.body()); >+ } >+ >+ void visit(AST::DoWhileLoop& doWhileLoop) override >+ { >+ checkErrorAndVisit(doWhileLoop.body()); >+ checkErrorAndVisit(doWhileLoop.conditional()); >+ auto conditionalIterator = m_typeMap.find(&doWhileLoop.conditional()); >+ ASSERT(conditionalIterator != m_typeMap.end()); >+ auto& conditionalType = conditionalIterator->value; >+ if (!isBoolType(conditionalType)) { >+ setError(); >+ return; >+ } >+ } >+ >+ void visit(AST::ForLoop& forLoop) override >+ { >+ WTF::visit(WTF::makeVisitor([&](AST::VariableDeclarationsStatement& variableDeclarationsStatement) { >+ checkErrorAndVisit(variableDeclarationsStatement); >+ }, [&](std::unique_ptr<AST::Expression>& expression) { >+ checkErrorAndVisit(*expression); >+ }), forLoop.initialization()); >+ if (forLoop.condition()) { >+ checkErrorAndVisit(*forLoop.condition()); >+ auto conditionIterator = m_typeMap.find(forLoop.condition()); >+ ASSERT(conditionIterator != m_typeMap.end()); >+ auto& conditionType = conditionIterator->value; >+ if (!isBoolType(conditionType)) { >+ setError(); >+ return; >+ } >+ } >+ if (forLoop.increment()) >+ checkErrorAndVisit(*forLoop.increment()); >+ checkErrorAndVisit(forLoop.body()); >+ } >+ >+ void visit(AST::SwitchStatement& switchStatement) override >+ { >+ checkErrorAndVisit(switchStatement.value()); >+ auto valueIterator = m_typeMap.find(&switchStatement.value()); >+ ASSERT(valueIterator != m_typeMap.end()); >+ auto& valueType = valueIterator->value; >+ auto valueUnifyNode = WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& left) -> AST::Type* { >+ return &left->unifyNode(); >+ }, [&](Ref<ResolvableTypeReference>& left) -> AST::Type* { >+ if (!left->resolvableType().resolvedType()) { >+ if (!static_cast<bool>(commit(left->resolvableType()))) >+ return nullptr; >+ } >+ return &left->resolvableType().resolvedType()->unifyNode(); >+ }), valueType); >+ if (!is<AST::NamedType>(*valueUnifyNode)) { >+ setError(); >+ return; >+ } >+ auto& valueNamedUnifyNode = downcast<AST::NamedType>(*valueUnifyNode); >+ if (!(is<AST::NativeTypeDeclaration>(valueNamedUnifyNode) && downcast<AST::NativeTypeDeclaration>(valueNamedUnifyNode).isInt()) >+ && !is<AST::EnumerationDefinition>(valueNamedUnifyNode)) { >+ setError(); >+ return; >+ } >+ >+ bool hasDefault = false; >+ for (auto& switchCase : switchStatement.switchCases()) { >+ checkErrorAndVisit(switchCase.block()); >+ if (!switchCase.value()) { >+ hasDefault = true; >+ continue; >+ } >+ bool success; >+ switchCase.value()->visit(WTF::makeVisitor([&](AST::IntegerLiteral& integerLiteral) { >+ success = WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& valueType) -> bool { >+ return static_cast<bool>(matchAndCommit(static_cast<AST::UnnamedType&>(valueType), integerLiteral.type())); >+ }, [&](Ref<ResolvableTypeReference>& valueType) -> bool { >+ return static_cast<bool>(matchAndCommit(valueType->resolvableType(), integerLiteral.type())); >+ }), valueType); >+ }, [&](AST::UnsignedIntegerLiteral& unsignedIntegerLiteral) { >+ success = WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& valueType) -> bool { >+ return static_cast<bool>(matchAndCommit(static_cast<AST::UnnamedType&>(valueType), unsignedIntegerLiteral.type())); >+ }, [&](Ref<ResolvableTypeReference>& valueType) -> bool { >+ return static_cast<bool>(matchAndCommit(valueType->resolvableType(), unsignedIntegerLiteral.type())); >+ }), valueType); >+ }, [&](AST::FloatLiteral& floatLiteral) { >+ success = WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& valueType) -> bool { >+ return static_cast<bool>(matchAndCommit(static_cast<AST::UnnamedType&>(valueType), floatLiteral.type())); >+ }, [&](Ref<ResolvableTypeReference>& valueType) -> bool { >+ return static_cast<bool>(matchAndCommit(valueType->resolvableType(), floatLiteral.type())); >+ }), valueType); >+ }, [&](AST::NullLiteral& nullLiteral) { >+ success = WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& valueType) -> bool { >+ return static_cast<bool>(matchAndCommit(static_cast<AST::UnnamedType&>(valueType), nullLiteral.type())); >+ }, [&](Ref<ResolvableTypeReference>& valueType) -> bool { >+ return static_cast<bool>(matchAndCommit(valueType->resolvableType(), nullLiteral.type())); >+ }), valueType); >+ }, [&](AST::BooleanLiteral&) { >+ success = WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& valueType) -> bool { >+ return matches(static_cast<AST::UnnamedType&>(valueType), m_intrinsics.boolType()); >+ }, [&](Ref<ResolvableTypeReference>& valueType) -> bool { >+ return static_cast<bool>(matchAndCommit(m_intrinsics.boolType(), valueType->resolvableType())); >+ }), valueType); >+ }, [&](AST::ConstantExpressionEnumerationMemberReference& constantExpressionEnumerationMemberReference) { >+ ASSERT(constantExpressionEnumerationMemberReference.enumerationDefinition()); >+ success = WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& valueType) -> bool { >+ return matches(static_cast<AST::UnnamedType&>(valueType), *constantExpressionEnumerationMemberReference.enumerationDefinition()); >+ }, [&](Ref<ResolvableTypeReference>& valueType) -> bool { >+ return static_cast<bool>(matchAndCommit(*constantExpressionEnumerationMemberReference.enumerationDefinition(), valueType->resolvableType())); >+ }), valueType); >+ })); >+ if (!success) { >+ setError(); >+ return; >+ } >+ } >+ >+ for (size_t i = 0; i < switchStatement.switchCases().size(); ++i) { >+ auto& firstCase = switchStatement.switchCases()[i]; >+ for (size_t j = i + 1; j < switchStatement.switchCases().size(); ++j) { >+ auto& secondCase = switchStatement.switchCases()[j]; >+ >+ if (static_cast<bool>(firstCase.value()) != static_cast<bool>(secondCase.value())) >+ continue; >+ >+ if (!static_cast<bool>(firstCase.value())) { >+ setError(); >+ return; >+ } >+ >+ bool success = true; >+ firstCase.value()->visit(WTF::makeVisitor([&](AST::IntegerLiteral& firstIntegerLiteral) { >+ secondCase.value()->visit(WTF::makeVisitor([&](AST::IntegerLiteral& secondIntegerLiteral) { >+ success = firstIntegerLiteral.value() != secondIntegerLiteral.value(); >+ }, [&](AST::UnsignedIntegerLiteral& secondUnsignedIntegerLiteral) { >+ success = static_cast<int64_t>(firstIntegerLiteral.value()) != static_cast<int64_t>(secondUnsignedIntegerLiteral.value()); >+ }, [&](AST::FloatLiteral&) { >+ }, [&](AST::NullLiteral&) { >+ }, [&](AST::BooleanLiteral&) { >+ }, [&](AST::ConstantExpressionEnumerationMemberReference&) { >+ })); >+ }, [&](AST::UnsignedIntegerLiteral& firstUnsignedIntegerLiteral) { >+ secondCase.value()->visit(WTF::makeVisitor([&](AST::IntegerLiteral& secondIntegerLiteral) { >+ success = static_cast<int64_t>(firstUnsignedIntegerLiteral.value()) != static_cast<int64_t>(secondIntegerLiteral.value()); >+ }, [&](AST::UnsignedIntegerLiteral& secondUnsignedIntegerLiteral) { >+ success = firstUnsignedIntegerLiteral.value() != secondUnsignedIntegerLiteral.value(); >+ }, [&](AST::FloatLiteral&) { >+ }, [&](AST::NullLiteral&) { >+ }, [&](AST::BooleanLiteral&) { >+ }, [&](AST::ConstantExpressionEnumerationMemberReference&) { >+ })); >+ }, [&](AST::FloatLiteral&) { >+ }, [&](AST::NullLiteral&) { >+ }, [&](AST::BooleanLiteral&) { >+ }, [&](AST::ConstantExpressionEnumerationMemberReference& firstConstantExpressionEnumerationMemberReference) { >+ secondCase.value()->visit(WTF::makeVisitor([&](AST::IntegerLiteral&) { >+ }, [&](AST::UnsignedIntegerLiteral&) { >+ }, [&](AST::FloatLiteral&) { >+ }, [&](AST::NullLiteral&) { >+ }, [&](AST::BooleanLiteral&) { >+ }, [&](AST::ConstantExpressionEnumerationMemberReference& secondConstantExpressionEnumerationMemberReference) { >+ success = firstConstantExpressionEnumerationMemberReference.enumerationMember() != secondConstantExpressionEnumerationMemberReference.enumerationMember(); >+ })); >+ })); >+ } >+ } >+ >+ if (!hasDefault) { >+ if (is<AST::NativeTypeDeclaration>(valueNamedUnifyNode)) { >+ HashSet<int64_t> values; >+ bool zeroValueExists; >+ for (auto& switchCase : switchStatement.switchCases()) { >+ int64_t value; >+ switchCase.value()->visit(WTF::makeVisitor([&](AST::IntegerLiteral& integerLiteral) { >+ value = integerLiteral.valueForSelectedType(); >+ }, [&](AST::UnsignedIntegerLiteral& unsignedIntegerLiteral) { >+ value = unsignedIntegerLiteral.valueForSelectedType(); >+ }, [&](AST::FloatLiteral&) { >+ ASSERT_NOT_REACHED(); >+ }, [&](AST::NullLiteral&) { >+ ASSERT_NOT_REACHED(); >+ }, [&](AST::BooleanLiteral&) { >+ ASSERT_NOT_REACHED(); >+ }, [&](AST::ConstantExpressionEnumerationMemberReference&) { >+ ASSERT_NOT_REACHED(); >+ })); >+ if (!value) >+ zeroValueExists = true; >+ else >+ values.add(value); >+ } >+ bool success = true; >+ downcast<AST::NativeTypeDeclaration>(valueNamedUnifyNode).iterateAllValues([&](int64_t value) -> bool { >+ if (!value) { >+ if (!zeroValueExists) { >+ success = false; >+ return true; >+ } >+ return false; >+ } else { >+ if (!values.contains(value)) { >+ success = false; >+ return true; >+ } >+ return false; >+ } >+ }); >+ if (!success) { >+ setError(); >+ return; >+ } >+ } else { >+ ASSERT(is<AST::EnumerationDefinition>(valueNamedUnifyNode)); >+ HashSet<AST::EnumerationMember*> values; >+ for (auto& switchCase : switchStatement.switchCases()) { >+ switchCase.value()->visit(WTF::makeVisitor([&](AST::IntegerLiteral&) { >+ ASSERT_NOT_REACHED(); >+ }, [&](AST::UnsignedIntegerLiteral&) { >+ ASSERT_NOT_REACHED(); >+ }, [&](AST::FloatLiteral&) { >+ ASSERT_NOT_REACHED(); >+ }, [&](AST::NullLiteral&) { >+ ASSERT_NOT_REACHED(); >+ }, [&](AST::BooleanLiteral&) { >+ ASSERT_NOT_REACHED(); >+ }, [&](AST::ConstantExpressionEnumerationMemberReference& constantExpressionEnumerationMemberReference) { >+ ASSERT(constantExpressionEnumerationMemberReference.enumerationMember()); >+ values.add(constantExpressionEnumerationMemberReference.enumerationMember()); >+ })); >+ } >+ for (auto& enumerationMember : downcast<AST::EnumerationDefinition>(valueNamedUnifyNode).enumerationMembers()) { >+ if (!values.contains(&enumerationMember.get())) { >+ setError(); >+ return; >+ } >+ } >+ } >+ } >+ } >+ >+ void visit(AST::CommaExpression& commaExpression) override >+ { >+ ASSERT(commaExpression.list().size() > 0); >+ Visitor::visit(commaExpression); >+ auto lastIterator = m_typeMap.find(static_cast<Expression&>(commaExpression.list().last())); >+ ASSERT(lastIterator != m_typeMap.end()); >+ auto& lastType = lastIterator->value; >+ WTF::visit(WTF::makeVisitor([&](std::unique_ptr<AST::UnnamedType>& lastType) { >+ auto addResult = m_typeMap.add(&commaExpression, lastType->clone()); >+ ASSERT_UNUSED(addResult, addResult.isNewEntry); >+ }, [&](Ref<ResolvableTypeReference>& lastType) { >+ auto addResult = m_typeMap.add(&commaExpression, lastType.copyRef()); >+ ASSERT_UNUSED(addResult, addResult.isNewEntry); >+ }), lastType); >+ } >+ >+ void visit(AST::TernaryExpression& ternaryExpression) override >+ { >+ checkErrorAndVisit(ternaryExpression.predicate()); >+ auto predicateIterator = m_typeMap.find(&ternaryExpression.predicate()); >+ ASSERT(predicateIterator != m_typeMap.end()); >+ auto& predicateType = predicateIterator->value; >+ if (!isBoolType(predicateType)) { >+ setError(); >+ return; >+ } >+ >+ checkErrorAndVisit(ternaryExpression.bodyExpression()); >+ auto bodyIterator = m_typeMap.find(&ternaryExpression.bodyExpression()); >+ ASSERT(bodyIterator != m_typeMap.end()); >+ auto& bodyType = bodyIterator->value; >+ >+ checkErrorAndVisit(ternaryExpression.elseExpression()); >+ auto elseIterator = m_typeMap.find(&ternaryExpression.elseExpression()); >+ ASSERT(elseIterator != m_typeMap.end()); >+ auto& elseType = elseIterator->value; >+ >+ auto resultType = WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& bodyType) -> Optional<UniqueRef<AST::UnnamedType>> { >+ return WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& elseType) -> std::unique_ptr<AST::UnnamedType> { >+ if (matches(static_cast<AST::UnnamedType&>(bodyType), static_cast<AST::UnnamedType&>(elseType))) >+ return bodyType->clone(); >+ return WTF::nullopt; >+ }, [&](Ref<ResolvableTypeReference>& elseType) -> std::unique_ptr<AST::UnnamedType> { >+ return matchAndCommit(*bodyType, elseType->resolvableType()); >+ }), elseType); >+ }, [&](Ref<ResolvableTypeReference>& bodyType) -> std::unique_ptr<AST::UnnamedType> { >+ return WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& elseType) -> Optional<UniqueRef<AST::UnnamedType>> { >+ return matchAndCommit(static_cast<AST::UnnamedType&>(elseType), bodyType->resolvableType()); >+ }, [&](Ref<ResolvableTypeReference>& elseType) -> std::unique_ptr<AST::UnnamedType> { >+ return matchAndCommit(bodyType->resolvableType(), elseType->resolvableType()); >+ }), elseType); >+ }), bodyType); >+ if (!resultType) { >+ setError(); >+ return; >+ } >+ auto addResult = m_typeMap.add(&ternaryExpression, WTFMove(*resultType)); >+ ASSERT_UNUSED(addResult, addResult.isNewEntry); >+ } >+ >+ void visit(AST::CallExpression& callExpression) override >+ { >+ for (auto& argument : callExpression.arguments()) >+ checkErrorAndVisit(static_cast<Expression&>(argument)); >+ if (callExpression.castReturnType()) >+ checkErrorAndVisit(callExpression.castReturnType()->get()); >+ Vector<std::reference_wrapper<ResolvingType>> types; >+ types.reserveInitialCapacity(callExpression.arguments().size()); >+ for (auto& argument : callExpression.arguments()) { >+ auto iterator = m_typeMap.find(&static_cast<Expression&>(argument)); >+ ASSERT(iterator != m_typeMap.end()); >+ types.uncheckedAppend(iterator->value); >+ } >+ >+ ASSERT(callExpression.hasOverloads()); >+ auto* function = resolveFunctionOverloadImpl(*callExpression.overloads(), types, callExpression.castReturnType()); >+ if (!function) { >+ if (auto newFunction = resolveByInstantiation(callExpression, types, m_intrinsics)) { >+ m_program.append(WTFMove(*newFunction)); >+ function = m_program.nativeFunctionDeclarations().last().get(); >+ } >+ } >+ >+ if (!function) { >+ setError(); >+ return; >+ } >+ >+ for (size_t i = 0; i < function->parameters().size(); ++i) { >+ auto success = WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>&) -> bool { >+ return true; >+ }, [&](Ref<ResolvableTypeReference>& resolvableTypeReference) -> bool { >+ return static_cast<bool>(matchAndCommit(*function->parameters()[i].type(), resolvableTypeReference->resolvableType())); >+ }), types[i].get()); >+ if (!success) { >+ setError(); >+ return; >+ } >+ } >+ >+ callExpression.setFunction(*function); >+ >+ auto addResult = m_typeMap.add(&callExpression, function->type().clone()); >+ ASSERT_UNUSED(addResult, addResult.isNewEntry); >+ } >+ >+private: >+ >+ /*class ResolvingTypeHashTraits : public SimpleClassHashTraits<ResolvingType> >+ { >+ public: >+ static ResolvingType& emptyValue() >+ { >+ ASSERT_NOT_REACHED(); >+ static NeverDestroyed<ResolvingType> emptyValue; >+ return emptyValue.get(); >+ } >+ >+ typedef ResolvingType& PeekType; >+ static PeekType peek(ResolvingType& value) { return value; } >+ typedef ResolvingType&& TakeType; >+ static TakeType take(ResolvingType&& value) { return WTFMove(value); } >+ };*/ >+ >+ HashMap<AST::Expression*, ResolvingType /*, WTF::PtrHash<AST::Expression*>, WTF::HashTraits<AST::Expression*>, ResolvingTypeHashTraits*/> m_typeMap; >+ HashSet<String> m_vertexEntryPoints; >+ HashSet<String> m_fragmentEntryPoints; >+ HashSet<String> m_computeEntryPoints; >+ const Intrinsics& m_intrinsics; >+ Program& m_program; >+}; >+ >+bool check(Program& program) >+{ >+ Checker checker(program.intrinsics(), program); >+ checker.checkErrorAndVisit(program); >+ return !checker.error(); >+} >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.h >new file mode 100644 >index 00000000000..ed268d7341f >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.h >@@ -0,0 +1,42 @@ >+/* >+ * 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) >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+class Program; >+ >+bool check(Program&); >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLGatherEntryPointItems.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLGatherEntryPointItems.cpp >new file mode 100644 >index 00000000000..8b5b4b3f55e >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLGatherEntryPointItems.cpp >@@ -0,0 +1,175 @@ >+/* >+ * 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. >+ */ >+ >+#if ENABLE(WEBGPU) >+ >+#include "config.h" >+#include "WHLSLGatherEntryPointItems.h" >+ >+#include "WHLSLPointerType.h" >+#include "WHLSLVisitor.h" >+#include <wtf/Optional.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+class Gatherer : public Visitor { >+public: >+ Gatherer(const Intrinsics& intrinsics, AST::Semantic* semantic = nullptr) >+ : m_intrinsics(intrinsics) >+ , m_currentSemantic(semantic) >+ { >+ } >+ >+ virtual ~Gatherer() = default; >+ >+ void reset() >+ { >+ m_currentSemantic = nullptr; >+ } >+ >+ Vector<EntryPointItem>&& takeEntryPointItems() >+ { >+ return WTFMove(m_entryPointItems); >+ } >+ >+ void visit(AST::EnumerationDefinition&) >+ { >+ if (!m_currentSemantic) { >+ setError(); >+ return; >+ } >+ m_entryPointItems.append(EntryPointItem(m_typeReferences.last().get(), *m_currentSemantic)); >+ } >+ >+ void visit(AST::NativeTypeDeclaration& nativeTypeDeclaration) >+ { >+ if (!m_currentSemantic) { >+ setError(); >+ return; >+ } >+ if (matches(nativeTypeDeclaration, m_intrinsics.voidType())) { >+ setError(); >+ return; >+ } >+ >+ m_entryPointItems.append(EntryPointItem(m_typeReferences.last().get(), *m_currentSemantic)); >+ } >+ >+ void visit(AST::StructureDefinition& structureDefinition) >+ { >+ if (m_currentSemantic) { >+ setError(); >+ return; >+ } >+ >+ for (auto& structureElement : structureDefinition.structureElements()) { >+ if (structureElement.semantic()) >+ m_currentSemantic = &*structureElement.semantic(); >+ checkErrorAndVisit(structureElement); >+ } >+ } >+ >+ void visit(AST::TypeDefinition& typeDefinition) >+ { >+ ASSERT(typeDefinition.type()); >+ checkErrorAndVisit(*typeDefinition.type()); >+ } >+ >+ void visit(AST::TypeReference& typeReference) >+ { >+ ASSERT(typeReference.resolvedType()); >+ m_typeReferences.append(typeReference); >+ auto depth = m_typeReferences.size(); >+ checkErrorAndVisit(*typeReference.resolvedType()); >+ ASSERT_UNUSED(depth, m_typeReferences.size() == depth); >+ } >+ >+ void visit(AST::PointerType& pointerType) >+ { >+ if (!m_currentSemantic) { >+ setError(); >+ return; >+ } >+ m_entryPointItems.append(EntryPointItem(pointerType, *m_currentSemantic)); >+ } >+ >+ void visit(AST::ArrayReferenceType& arrayReferenceType) >+ { >+ if (!m_currentSemantic) { >+ setError(); >+ return; >+ } >+ m_entryPointItems.append(EntryPointItem(arrayReferenceType, *m_currentSemantic)); >+ } >+ >+ void visit(AST::ArrayType& arrayType) >+ { >+ if (!m_currentSemantic) { >+ setError(); >+ return; >+ } >+ m_entryPointItems.append(EntryPointItem(arrayType, *m_currentSemantic)); >+ } >+ >+ void visit(AST::VariableDeclaration& variableDeclaration) >+ { >+ ASSERT(!m_currentSemantic); >+ if (variableDeclaration.semantic()) >+ m_currentSemantic = &*variableDeclaration.semantic(); >+ checkErrorAndVisit(variableDeclaration.type()); >+ } >+ >+private: >+ const Intrinsics& m_intrinsics; >+ AST::Semantic* m_currentSemantic { nullptr }; >+ Vector<std::reference_wrapper<AST::TypeReference>> m_typeReferences; >+ Vector<EntryPointItem> m_entryPointItems; >+}; >+ >+Optional<EntryPointItems> gatherEntryPointItems(const Intrinsics& intrinsics, AST::FunctionDefinition& functionDefinition) >+{ >+ ASSERT(functionDefinition.entryPointType()); >+ Gatherer inputGatherer(intrinsics); >+ for (auto& parameter : functionDefinition.parameters()) { >+ inputGatherer.reset(); >+ inputGatherer.checkErrorAndVisit(parameter); >+ if (inputGatherer.error()) >+ return WTF::nullopt; >+ } >+ Gatherer outputGatherer(intrinsics, functionDefinition.semantic() ? &*functionDefinition.semantic() : nullptr); >+ outputGatherer.checkErrorAndVisit(functionDefinition.type()); >+ if (outputGatherer.error()) >+ return WTF::nullopt; >+ >+ return {{ inputGatherer.takeEntryPointItems(), outputGatherer.takeEntryPointItems() }}; >+} >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLParameter.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLGatherEntryPointItems.h >similarity index 62% >rename from Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLParameter.h >rename to Source/WebCore/Modules/webgpu/WHLSL/WHLSLGatherEntryPointItems.h >index 92586f8691f..e1eb82921a0 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLParameter.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLGatherEntryPointItems.h >@@ -27,13 +27,9 @@ > > #if ENABLE(WEBGPU) > >-#include "WHLSLLexer.h" >-#include "WHLSLQualifier.h" > #include "WHLSLSemantic.h" >-#include "WHLSLType.h" >-#include "WHLSLValue.h" >+#include <wtf/Optional.h> > #include <wtf/Vector.h> >-#include <wtf/text/WTFString.h> > > namespace WebCore { > >@@ -41,36 +37,30 @@ namespace WHLSL { > > namespace AST { > >-class Parameter : public Value { >-public: >- Parameter(Lexer::Token&& origin, Qualifiers&& qualifiers, std::unique_ptr<AST::Type>&& type, Optional<String>&& name, Optional<AST::Semantic>&& semantic) >- : m_origin(WTFMove(origin)) >- , m_qualifiers(WTFMove(qualifiers)) >- , m_type(WTFMove(type)) >- , m_name(WTFMove(name)) >- , m_semantic(WTFMove(semantic)) >- { >- } >+class FunctionDefinition; > >- virtual ~Parameter() = default; >+} > >- Parameter(const Parameter&) = delete; >- Parameter(Parameter&&) = default; >+class Intrinsics; >+class UnnamedType; > >- Type& type() { return *m_type; } >- Optional<AST::Semantic>& semantic() { return m_semantic; } >+struct EntryPointItem { >+ EntryPointItem(AST::UnnamedType& unnamedType, AST::Semantic& semantic) >+ : unnamedType(unnamedType) >+ , semantic(semantic) >+ { >+ } > >-private: >- Lexer::Token m_origin; >- Qualifiers m_qualifiers; >- std::unique_ptr<AST::Type> m_type; >- Optional<String> m_name; >- Optional<AST::Semantic> m_semantic; >+ AST::UnnamedType& unnamedType; >+ AST::Semantic& semantic; > }; > >-typedef Vector<Parameter> Parameters; >+struct EntryPointItems { >+ Vector<EntryPointItem> inputs; >+ Vector<EntryPointItem> outputs; >+}; > >-} >+Optional<EntryPointItems> gatherEntryPointItems(const Intrinsics&, AST::FunctionDefinition&); > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLInferTypes.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLInferTypes.cpp >new file mode 100644 >index 00000000000..9fe07833795 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLInferTypes.cpp >@@ -0,0 +1,239 @@ >+/* >+ * 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. >+ */ >+ >+#if ENABLE(WEBGPU) >+ >+#include "config.h" >+#include "WHLSLInferTypes.h" >+ >+#include "WHLSLArrayReferenceType.h" >+#include "WHLSLArrayType.h" >+#include "WHLSLFunctionDeclaration.h" >+#include "WHLSLNamedType.h" >+#include "WHLSLNativeTypeDeclaration.h" >+#include "WHLSLPointerType.h" >+#include "WHLSLResolvableType.h" >+#include "WHLSLStructureDefinition.h" >+#include "WHLSLTypeDefinition.h" >+#include "WHLSLTypeReference.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+static bool matches(const AST::Type& unifyThis, const AST::Type& unifyOther) >+{ >+ if (&unifyThis == &unifyOther) >+ return true; >+ >+ if (is<AST::NamedType>(unifyThis) && is<AST::NamedType>(unifyOther)) { >+#if !ASSERT_DISABLED >+ auto& namedThis = downcast<AST::NamedType>(unifyThis); >+ auto& namedOther = downcast<AST::NamedType>(unifyOther); >+ ASSERT(!is<AST::TypeDefinition>(namedThis) && !is<AST::TypeDefinition>(namedOther)); >+#endif >+ return false; >+ } else if (is<AST::UnnamedType>(unifyThis) && is<AST::UnnamedType>(unifyOther)) { >+ auto& unnamedThis = downcast<AST::UnnamedType>(unifyThis); >+ auto& unnamedOther = downcast<AST::UnnamedType>(unifyOther); >+ ASSERT(!is<AST::TypeReference>(unnamedThis) && !is<AST::TypeReference>(unnamedOther)); >+ if (is<AST::PointerType>(unnamedThis) && is<AST::PointerType>(unnamedOther)) { >+ auto& pointerThis = downcast<AST::PointerType>(unnamedThis); >+ auto& pointerOther = downcast<AST::PointerType>(unnamedOther); >+ if (pointerThis.addressSpace() != pointerOther.addressSpace()) >+ return false; >+ return matches(pointerThis.elementType(), pointerOther.elementType()); >+ } >+ if (is<AST::ArrayReferenceType>(unnamedThis) && is<AST::ArrayReferenceType>(unnamedOther)){ >+ auto& arrayReferenceThis = downcast<AST::ArrayReferenceType>(unnamedThis); >+ auto& arrayReferenceOther = downcast<AST::ArrayReferenceType>(unnamedOther); >+ if (arrayReferenceThis.addressSpace() != arrayReferenceOther.addressSpace()) >+ return false; >+ return matches(arrayReferenceThis.elementType(), arrayReferenceOther.elementType()); >+ } >+ if (is<AST::ArrayType>(unnamedThis) && is<AST::ArrayType>(unnamedOther)) { >+ auto& arrayThis = downcast<AST::ArrayType>(unnamedThis); >+ auto& arrayOther = downcast<AST::ArrayType>(unnamedOther); >+ if (arrayThis.numElements() != arrayOther.numElements()) >+ return false; >+ return matches(arrayThis.type(), arrayOther.type()); >+ } >+ return false; >+ } >+ return false; >+} >+ >+bool matches(const AST::UnnamedType& unnamedType, const AST::UnnamedType& other) >+{ >+ return matches(unnamedType.unifyNode(), other.unifyNode()); >+} >+ >+bool matches(const AST::NamedType& namedType, const AST::NamedType& other) >+{ >+ return matches(namedType.unifyNode(), other.unifyNode()); >+} >+ >+bool matches(const AST::UnnamedType& unnamedType, const AST::NamedType& other) >+{ >+ return matches(unnamedType.unifyNode(), other.unifyNode()); >+} >+ >+static std::unique_ptr<AST::UnnamedType> matchAndCommit(AST::Type& unifyNode, AST::ResolvableType& resolvableType) >+{ >+ if (!resolvableType.canResolve(unifyNode)) >+ return nullptr; >+ std::unique_ptr<AST::UnnamedType> result; >+ if (is<AST::NamedType>(unifyNode)) { >+ auto& namedUnifyNode = downcast<AST::NamedType>(unifyNode); >+ result = AST::TypeReference::wrap(Lexer::Token(namedUnifyNode.origin()), namedUnifyNode).takeUniquePtr(); >+ } else >+ result = downcast<AST::UnnamedType>(unifyNode).clone().takeUniquePtr(); >+ ASSERT(!resolvableType.resolvedType()); >+ resolvableType.resolve(result->clone()); >+ return result; >+} >+ >+std::unique_ptr<AST::UnnamedType> matchAndCommit(AST::UnnamedType& unnamedType, AST::ResolvableType& resolvableType) >+{ >+ return matchAndCommit(unnamedType.unifyNode(), resolvableType); >+} >+ >+std::unique_ptr<AST::UnnamedType> matchAndCommit(AST::NamedType& namedType, AST::ResolvableType& resolvableType) >+{ >+ return matchAndCommit(namedType.unifyNode(), resolvableType); >+} >+ >+std::unique_ptr<AST::UnnamedType> matchAndCommit(AST::ResolvableType& resolvableType1, AST::ResolvableType& resolvableType2) >+{ >+ ASSERT(!resolvableType1.resolvedType()); >+ ASSERT(!resolvableType2.resolvedType()); >+ if (is<AST::FloatLiteralType>(resolvableType1) && is<AST::FloatLiteralType>(resolvableType2)) { >+ resolvableType1.resolve(downcast<AST::FloatLiteralType>(resolvableType1).preferredType().clone()); >+ resolvableType2.resolve(downcast<AST::FloatLiteralType>(resolvableType2).preferredType().clone()); >+ return downcast<AST::FloatLiteralType>(resolvableType1).preferredType().clone().takeUniquePtr(); >+ } >+ if (is<AST::IntegerLiteralType>(resolvableType1) && is<AST::IntegerLiteralType>(resolvableType2)) { >+ resolvableType1.resolve(downcast<AST::IntegerLiteralType>(resolvableType1).preferredType().clone()); >+ resolvableType2.resolve(downcast<AST::IntegerLiteralType>(resolvableType2).preferredType().clone()); >+ return downcast<AST::IntegerLiteralType>(resolvableType1).preferredType().clone().takeUniquePtr(); >+ } >+ if (is<AST::UnsignedIntegerLiteralType>(resolvableType1) && is<AST::UnsignedIntegerLiteralType>(resolvableType2)) { >+ resolvableType1.resolve(downcast<AST::UnsignedIntegerLiteralType>(resolvableType1).preferredType().clone()); >+ resolvableType2.resolve(downcast<AST::UnsignedIntegerLiteralType>(resolvableType2).preferredType().clone()); >+ return downcast<AST::UnsignedIntegerLiteralType>(resolvableType1).preferredType().clone().takeUniquePtr(); >+ } >+ if (is<AST::NullLiteralType>(resolvableType1) && is<AST::NullLiteralType>(resolvableType2)) { >+ // FIXME: Trying to match nullptr and nullptr fails. >+ return nullptr; >+ } >+ return nullptr; >+} >+ >+std::unique_ptr<AST::UnnamedType> commit(AST::ResolvableType& resolvableType) >+{ >+ ASSERT(!resolvableType.resolvedType()); >+ if (is<AST::FloatLiteralType>(resolvableType)) { >+ resolvableType.resolve(downcast<AST::FloatLiteralType>(resolvableType).preferredType().clone()); >+ return downcast<AST::FloatLiteralType>(resolvableType).preferredType().clone().takeUniquePtr(); >+ } >+ if (is<AST::IntegerLiteralType>(resolvableType)) { >+ resolvableType.resolve(downcast<AST::IntegerLiteralType>(resolvableType).preferredType().clone()); >+ return downcast<AST::IntegerLiteralType>(resolvableType).preferredType().clone().takeUniquePtr(); >+ } >+ if (is<AST::UnsignedIntegerLiteralType>(resolvableType)) { >+ resolvableType.resolve(downcast<AST::UnsignedIntegerLiteralType>(resolvableType).preferredType().clone()); >+ return downcast<AST::UnsignedIntegerLiteralType>(resolvableType).preferredType().clone().takeUniquePtr(); >+ } >+ if (is<AST::NullLiteralType>(resolvableType)) { >+ // FIXME: Trying to match nullptr and nullptr fails. >+ return nullptr; >+ } >+ return nullptr; >+} >+ >+bool inferTypesForTypeArguments(AST::NamedType& possibleType, AST::TypeArguments& typeArguments) >+{ >+ if (is<AST::TypeDefinition>(possibleType) >+ || is<AST::StructureDefinition>(possibleType) >+ || is<AST::EnumerationDefinition>(possibleType)) { >+ return typeArguments.isEmpty(); >+ } >+ >+ ASSERT(is<AST::NativeTypeDeclaration>(possibleType)); >+ auto& nativeTypeDeclaration = downcast<AST::NativeTypeDeclaration>(possibleType); >+ if (nativeTypeDeclaration.typeArguments().size() != typeArguments.size()) >+ return false; >+ for (size_t i = 0; i < nativeTypeDeclaration.typeArguments().size(); ++i) { >+ AST::ConstantExpression* typeArgumentExpression = nullptr; >+ AST::TypeReference* typeArgumentTypeReference = nullptr; >+ AST::ConstantExpression* nativeTypeArgumentExpression = nullptr; >+ AST::TypeReference* nativeTypeArgumentTypeReference = nullptr; >+ >+ auto assign = [&](AST::TypeArgument& typeArgument, AST::ConstantExpression*& expression, AST::TypeReference*& typeReference) { >+ WTF::visit(WTF::makeVisitor([&](AST::ConstantExpression& constantExpression) { >+ expression = &constantExpression; >+ }, [&](std::unique_ptr<AST::TypeReference>& theTypeReference) { >+ typeReference = theTypeReference.get(); >+ }), typeArgument); >+ }; >+ >+ assign(typeArguments[i], typeArgumentExpression, typeArgumentTypeReference); >+ assign(nativeTypeDeclaration.typeArguments()[i], nativeTypeArgumentExpression, nativeTypeArgumentTypeReference); >+ >+ if (typeArgumentExpression && nativeTypeArgumentExpression) { >+ if (!typeArgumentExpression->matches(*nativeTypeArgumentExpression)) >+ return false; >+ } else if (typeArgumentTypeReference && nativeTypeArgumentTypeReference) { >+ if (!matches(*typeArgumentTypeReference, *nativeTypeArgumentTypeReference)) >+ return false; >+ } >+ } >+ >+ return true; >+} >+ >+bool inferTypesForCall(AST::FunctionDeclaration& possibleFunction, Vector<std::reference_wrapper<ResolvingType>>& argumentTypes, Optional<std::reference_wrapper<AST::NamedType>>& castReturnType) >+{ >+ if (possibleFunction.parameters().size() != argumentTypes.size()) >+ return false; >+ for (size_t i = 0; i < possibleFunction.parameters().size(); ++i) { >+ auto success = WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& unnamedType) -> bool { >+ return matches(*possibleFunction.parameters()[i].type(), static_cast<AST::UnnamedType&>(unnamedType)); >+ }, [&](Ref<ResolvableTypeReference>& resolvableTypeReference) -> bool { >+ return resolvableTypeReference->resolvableType().canResolve(*possibleFunction.parameters()[i].type()); >+ }), argumentTypes[i].get()); >+ if (!success) >+ return false; >+ } >+ if (castReturnType && !matches(castReturnType->get(), possibleFunction.type())) >+ return false; >+ return true; >+} >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLInferTypes.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLInferTypes.h >new file mode 100644 >index 00000000000..63b0610c3e3 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLInferTypes.h >@@ -0,0 +1,62 @@ >+/* >+ * 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 "WHLSLResolvingType.h" >+#include "WHLSLTypeArgument.h" >+#include <memory> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class FunctionDeclaration; >+class NamedType; >+class ResolvableType; >+class UnnamedType; >+ >+} >+ >+bool matches(const AST::UnnamedType&, const AST::UnnamedType&); >+bool matches(const AST::NamedType&, const AST::NamedType&); >+bool matches(const AST::UnnamedType&, const AST::NamedType&); >+// FIXME: Is anyone actually using the return type here? >+std::unique_ptr<AST::UnnamedType> matchAndCommit(AST::UnnamedType&, AST::ResolvableType&); >+std::unique_ptr<AST::UnnamedType> matchAndCommit(AST::NamedType&, AST::ResolvableType&); >+std::unique_ptr<AST::UnnamedType> matchAndCommit(AST::ResolvableType&, AST::ResolvableType&); >+std::unique_ptr<AST::UnnamedType> commit(AST::ResolvableType&); >+bool inferTypesForTypeArguments(AST::NamedType& possibleType, AST::TypeArguments& typeArguments); >+bool inferTypesForCall(AST::FunctionDeclaration& possibleFunction, Vector<std::reference_wrapper<ResolvingType>>& argumentTypes, Optional<std::reference_wrapper<AST::NamedType>>& castReturnType); >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLIntrinsics.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLIntrinsics.cpp >new file mode 100644 >index 00000000000..ee06279fff0 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLIntrinsics.cpp >@@ -0,0 +1,444 @@ >+/* >+ * 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. >+ */ >+ >+#if ENABLE(WEBGPU) >+ >+#include "config.h" >+#include "WHLSLIntrinsics.h" >+ >+#include "WHLSLConstantExpression.h" >+#include "WHLSLTypeArgument.h" >+#include "WHLSLTypeReference.h" >+#include <algorithm> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+Intrinsics::Intrinsics() >+ : m_textureTypeNames { String("Texture1D", String::ConstructFromLiteral), >+ String("RWTexture1D", String::ConstructFromLiteral), >+ String("Texture1DArray", String::ConstructFromLiteral), >+ String("RWTexture1DArray", String::ConstructFromLiteral), >+ String("Texture2D", String::ConstructFromLiteral), >+ String("RWTexture2D", String::ConstructFromLiteral), >+ String("Texture2DArray", String::ConstructFromLiteral), >+ String("RWTexture2DArray", String::ConstructFromLiteral), >+ String("Texture3D", String::ConstructFromLiteral), >+ String("RWTexture3D", String::ConstructFromLiteral), >+ String("TextureCube", String::ConstructFromLiteral) } >+ , m_textureInnerTypeNames { String("uchar", String::ConstructFromLiteral), >+ String("ushort", String::ConstructFromLiteral), >+ String("uint", String::ConstructFromLiteral), >+ String("char", String::ConstructFromLiteral), >+ String("short", String::ConstructFromLiteral), >+ String("int", String::ConstructFromLiteral), >+ String("half", String::ConstructFromLiteral), >+ String("float", String::ConstructFromLiteral) } >+ , m_depthTextureInnerTypes { String("half", String::ConstructFromLiteral), >+ String("float", String::ConstructFromLiteral) } >+{ >+ ASSERT(m_textureTypeNames.size() == 11); // fullTextures hardcodes the length of this array. >+ ASSERT(m_textureInnerTypeNames.size() == 8); // fullTextures hardcodes the length of this array. >+ ASSERT(m_depthTextureInnerTypes.size() == 2); // textureDepth2D & friends hardcodes the length of this array. >+} >+ >+void Intrinsics::add(AST::NativeFunctionDeclaration&) >+{ >+ // FIXME: Populate this. >+} >+ >+bool Intrinsics::addPrimitive(AST::NativeTypeDeclaration& nativeTypeDeclaration) >+{ >+ if (nativeTypeDeclaration.typeArguments().size() != 0) >+ return false; >+ >+ if (nativeTypeDeclaration.name() == "void") >+ m_voidType = &nativeTypeDeclaration; >+ else if (nativeTypeDeclaration.name() == "bool") >+ m_boolType = &nativeTypeDeclaration; >+ else if (nativeTypeDeclaration.name() == "uchar") { >+ nativeTypeDeclaration.setIsInt(); >+ nativeTypeDeclaration.setIsNumber(); >+ nativeTypeDeclaration.setCanRepresentInteger([](int x) { >+ return x >= 0 && x <= 0xFF; >+ }); >+ nativeTypeDeclaration.setCanRepresentUnsignedInteger([](unsigned x) { >+ return x <= 0xFF; >+ }); >+ nativeTypeDeclaration.setCanRepresentFloat([](float x) { >+ return static_cast<float>(static_cast<uint8_t>(x)) == x; >+ }); >+ nativeTypeDeclaration.setSuccessor([](int64_t x) -> int64_t { >+ return static_cast<uint8_t>(x + 1); >+ }); >+ nativeTypeDeclaration.setFormatValueFromInteger([](int x) -> int64_t { >+ return static_cast<uint8_t>(x); >+ }); >+ nativeTypeDeclaration.setFormatValueFromUnsignedInteger([](unsigned x) -> int64_t { >+ return static_cast<uint8_t>(x); >+ }); >+ nativeTypeDeclaration.setIterateAllValues([](const std::function<bool(int64_t)>& callback) { >+ for (int64_t i = 0; i < 0x100; ++i) { >+ if (callback(i)) >+ break; >+ } >+ }); >+ m_ucharType = &nativeTypeDeclaration; >+ } else if (nativeTypeDeclaration.name() == "ushort") { >+ nativeTypeDeclaration.setIsInt(); >+ nativeTypeDeclaration.setIsNumber(); >+ nativeTypeDeclaration.setCanRepresentInteger([](int x) { >+ return x >= 0 && x <= 0xFFFF; >+ }); >+ nativeTypeDeclaration.setCanRepresentUnsignedInteger([](unsigned x) { >+ return x <= 0xFFFF; >+ }); >+ nativeTypeDeclaration.setCanRepresentFloat([](float x) { >+ return static_cast<float>(static_cast<uint16_t>(x)) == x; >+ }); >+ nativeTypeDeclaration.setSuccessor([](int64_t x) -> int64_t { >+ return static_cast<uint16_t>(x + 1); >+ }); >+ nativeTypeDeclaration.setFormatValueFromInteger([](int x) -> int64_t { >+ return static_cast<uint16_t>(x); >+ }); >+ nativeTypeDeclaration.setFormatValueFromUnsignedInteger([](unsigned x) -> int64_t { >+ return static_cast<uint16_t>(x); >+ }); >+ nativeTypeDeclaration.setIterateAllValues([](const std::function<bool(int64_t)>& callback) { >+ for (int64_t i = 0; i < 0x10000; ++i) { >+ if (callback(i)) >+ break; >+ } >+ }); >+ m_ushortType = &nativeTypeDeclaration; >+ } else if (nativeTypeDeclaration.name() == "uint") { >+ nativeTypeDeclaration.setIsInt(); >+ nativeTypeDeclaration.setIsNumber(); >+ nativeTypeDeclaration.setCanRepresentInteger([](int x) { >+ return x >= 0; >+ }); >+ nativeTypeDeclaration.setCanRepresentUnsignedInteger([](unsigned) { >+ return true; >+ }); >+ nativeTypeDeclaration.setCanRepresentFloat([](float x) { >+ return static_cast<float>(static_cast<uint32_t>(x)) == x; >+ }); >+ nativeTypeDeclaration.setSuccessor([](int64_t x) -> int64_t { >+ return static_cast<uint32_t>(x + 1); >+ }); >+ nativeTypeDeclaration.setFormatValueFromInteger([](int x) -> int64_t { >+ return static_cast<uint32_t>(x); >+ }); >+ nativeTypeDeclaration.setFormatValueFromUnsignedInteger([](unsigned x) -> int64_t { >+ return static_cast<uint32_t>(x); >+ }); >+ nativeTypeDeclaration.setIterateAllValues([](const std::function<bool(int64_t)>& callback) { >+ for (int64_t i = 0; i < 0x100000000; ++i) { >+ if (callback(i)) >+ break; >+ } >+ }); >+ m_uintType = &nativeTypeDeclaration; >+ } else if (nativeTypeDeclaration.name() == "char") { >+ nativeTypeDeclaration.setIsInt(); >+ nativeTypeDeclaration.setIsNumber(); >+ nativeTypeDeclaration.setIsSigned(); >+ nativeTypeDeclaration.setCanRepresentInteger([](int x) { >+ return x >= -128 && x <= 127; >+ }); >+ nativeTypeDeclaration.setCanRepresentUnsignedInteger([](unsigned x) { >+ return x <= 127; >+ }); >+ nativeTypeDeclaration.setCanRepresentFloat([](float x) { >+ return static_cast<float>(static_cast<int8_t>(x)) == x; >+ }); >+ nativeTypeDeclaration.setSuccessor([](int64_t x) -> int64_t { >+ return static_cast<int8_t>(x + 1); >+ }); >+ nativeTypeDeclaration.setFormatValueFromInteger([](int x) -> int64_t { >+ return static_cast<int8_t>(x); >+ }); >+ nativeTypeDeclaration.setFormatValueFromUnsignedInteger([](unsigned x) -> int64_t { >+ return static_cast<int8_t>(x); >+ }); >+ nativeTypeDeclaration.setIterateAllValues([](const std::function<bool(int64_t)>& callback) { >+ for (int64_t i = -128; i < 128; ++i) { >+ if (callback(i)) >+ break; >+ } >+ }); >+ m_charType = &nativeTypeDeclaration; >+ } else if (nativeTypeDeclaration.name() == "short") { >+ nativeTypeDeclaration.setIsInt(); >+ nativeTypeDeclaration.setIsNumber(); >+ nativeTypeDeclaration.setIsSigned(); >+ nativeTypeDeclaration.setCanRepresentInteger([](int x) { >+ return x >= -32768 && x <= 32767; >+ }); >+ nativeTypeDeclaration.setCanRepresentUnsignedInteger([](unsigned x) { >+ return x <= 32767; >+ }); >+ nativeTypeDeclaration.setCanRepresentFloat([](float x) { >+ return static_cast<float>(static_cast<int16_t>(x)) == x; >+ }); >+ nativeTypeDeclaration.setSuccessor([](int64_t x) -> int64_t { >+ return static_cast<int16_t>(x + 1); >+ }); >+ nativeTypeDeclaration.setFormatValueFromInteger([](int x) -> int64_t { >+ return static_cast<int16_t>(x); >+ }); >+ nativeTypeDeclaration.setFormatValueFromUnsignedInteger([](unsigned x) -> int64_t { >+ return static_cast<int16_t>(x); >+ }); >+ nativeTypeDeclaration.setIterateAllValues([](const std::function<bool(int64_t)>& callback) { >+ for (int64_t i = -32768; i < 32768; ++i) { >+ if (callback(i)) >+ break; >+ } >+ }); >+ m_shortType = &nativeTypeDeclaration; >+ } else if (nativeTypeDeclaration.name() == "int") { >+ nativeTypeDeclaration.setIsInt(); >+ nativeTypeDeclaration.setIsNumber(); >+ nativeTypeDeclaration.setIsSigned(); >+ nativeTypeDeclaration.setCanRepresentInteger([](int) { >+ return true; >+ }); >+ nativeTypeDeclaration.setCanRepresentUnsignedInteger([](unsigned x) { >+ return x <= 2147483647; >+ }); >+ nativeTypeDeclaration.setCanRepresentFloat([](float x) { >+ return static_cast<float>(static_cast<int32_t>(x)) == x; >+ }); >+ nativeTypeDeclaration.setSuccessor([](int64_t x) -> int64_t { >+ return static_cast<int32_t>(x + 1); >+ }); >+ nativeTypeDeclaration.setFormatValueFromInteger([](int x) -> int64_t { >+ return static_cast<int32_t>(x); >+ }); >+ nativeTypeDeclaration.setFormatValueFromUnsignedInteger([](unsigned x) -> int64_t { >+ return static_cast<int32_t>(x); >+ }); >+ nativeTypeDeclaration.setIterateAllValues([](const std::function<bool(int64_t)>& callback) { >+ for (int64_t i = -2147483647; i < 2147483648; ++i) { >+ if (callback(i)) >+ break; >+ } >+ }); >+ m_intType = &nativeTypeDeclaration; >+ } else if (nativeTypeDeclaration.name() == "half") { >+ nativeTypeDeclaration.setIsNumber(); >+ nativeTypeDeclaration.setIsFloating(); >+ nativeTypeDeclaration.setCanRepresentInteger([](int) { >+ return true; >+ }); >+ nativeTypeDeclaration.setCanRepresentUnsignedInteger([](unsigned) { >+ return true; >+ }); >+ nativeTypeDeclaration.setCanRepresentFloat([](float) { >+ return true; >+ }); >+ m_halfType = &nativeTypeDeclaration; >+ } else if (nativeTypeDeclaration.name() == "float") { >+ nativeTypeDeclaration.setIsNumber(); >+ nativeTypeDeclaration.setIsFloating(); >+ nativeTypeDeclaration.setCanRepresentInteger([](int) { >+ return true; >+ }); >+ nativeTypeDeclaration.setCanRepresentUnsignedInteger([](unsigned) { >+ return true; >+ }); >+ nativeTypeDeclaration.setCanRepresentFloat([](float) { >+ return true; >+ }); >+ m_floatType = &nativeTypeDeclaration; >+ } >+ else if (nativeTypeDeclaration.name() == "atomic_int") >+ m_atomicIntType = &nativeTypeDeclaration; >+ else if (nativeTypeDeclaration.name() == "atomic_uint") >+ m_atomicUintType = &nativeTypeDeclaration; >+ else if (nativeTypeDeclaration.name() == "sampler") >+ m_samplerType = &nativeTypeDeclaration; >+ else >+ ASSERT_NOT_REACHED(); >+ return true; >+} >+ >+bool Intrinsics::addVector(AST::NativeTypeDeclaration& nativeTypeDeclaration) >+{ >+ if (nativeTypeDeclaration.name() != "vector") >+ return false; >+ >+ ASSERT(nativeTypeDeclaration.typeArguments().size() == 2); >+ ASSERT(WTF::holds_alternative<UniqueRef<AST::TypeReference>>(nativeTypeDeclaration.typeArguments()[0])); >+ ASSERT(WTF::holds_alternative<AST::ConstantExpression>(nativeTypeDeclaration.typeArguments()[1])); >+ auto& innerType = static_cast<AST::TypeReference&>(WTF::get<UniqueRef<AST::TypeReference>>(nativeTypeDeclaration.typeArguments()[0])); >+ auto& lengthExpression = WTF::get<AST::ConstantExpression>(nativeTypeDeclaration.typeArguments()[1]); >+ ASSERT(innerType.typeArguments().size() == 0); >+ AST::NativeTypeDeclaration** array; >+ if (innerType.name() == "bool") >+ array = m_vectorBool; >+ else if (innerType.name() == "uchar") >+ array = m_vectorUchar; >+ else if (innerType.name() == "ushort") >+ array = m_vectorUshort; >+ else if (innerType.name() == "uint") >+ array = m_vectorUint; >+ else if (innerType.name() == "char") >+ array = m_vectorChar; >+ else if (innerType.name() == "short") >+ array = m_vectorShort; >+ else if (innerType.name() == "int") >+ array = m_vectorInt; >+ else if (innerType.name() == "half") >+ array = m_vectorHalf; >+ else if (innerType.name() == "float") >+ array = m_vectorFloat; >+ else >+ ASSERT_NOT_REACHED(); >+ int length = lengthExpression.integerLiteral().value(); >+ ASSERT(length >= 2 && length <= 4); >+ nativeTypeDeclaration.setIsVector(); >+ array[length - 2] = &nativeTypeDeclaration; >+ return true; >+} >+ >+bool Intrinsics::addMatrix(AST::NativeTypeDeclaration& nativeTypeDeclaration) >+{ >+ if (nativeTypeDeclaration.name() != "matrix") >+ return false; >+ >+ ASSERT(nativeTypeDeclaration.typeArguments().size() == 3); >+ ASSERT(WTF::holds_alternative<UniqueRef<AST::TypeReference>>(nativeTypeDeclaration.typeArguments()[0])); >+ ASSERT(WTF::holds_alternative<AST::ConstantExpression>(nativeTypeDeclaration.typeArguments()[1])); >+ ASSERT(WTF::holds_alternative<AST::ConstantExpression>(nativeTypeDeclaration.typeArguments()[2])); >+ auto& innerType = static_cast<AST::TypeReference&>(WTF::get<UniqueRef<AST::TypeReference>>(nativeTypeDeclaration.typeArguments()[0])); >+ auto& rowExpression = WTF::get<AST::ConstantExpression>(nativeTypeDeclaration.typeArguments()[1]); >+ auto& columnExpression = WTF::get<AST::ConstantExpression>(nativeTypeDeclaration.typeArguments()[2]); >+ ASSERT(innerType.typeArguments().size() == 0); >+ AST::NativeTypeDeclaration* (*array)[3]; >+ if (innerType.name() == "half") >+ array = m_matrixHalf; >+ if (innerType.name() == "float") >+ array = m_matrixFloat; >+ int row = rowExpression.integerLiteral().value(); >+ ASSERT(row >= 2 && row <= 4); >+ int column = columnExpression.integerLiteral().value(); >+ ASSERT(column >= 2 && column <= 4); >+ nativeTypeDeclaration.setIsMatrix(); >+ array[row - 2][column - 2] = &nativeTypeDeclaration; >+ return true; >+} >+ >+bool Intrinsics::addFullTexture(AST::NativeTypeDeclaration& nativeTypeDeclaration, AST::TypeReference& innerType) >+{ >+ unsigned textureTypeIndex = m_textureTypeNames.size(); >+ for (unsigned i = 0; i < m_textureTypeNames.size(); ++i) { >+ if (nativeTypeDeclaration.name() == m_textureTypeNames[i]) >+ textureTypeIndex = i; >+ } >+ if (textureTypeIndex == m_textureTypeNames.size()) >+ return false; >+ >+ unsigned innerTypeIndex = m_textureInnerTypeNames.size(); >+ unsigned vectorLength; >+ for (unsigned i = 0; i < m_textureInnerTypeNames.size(); ++i) { >+ if (innerType.name().startsWith(m_textureInnerTypeNames[i])) { >+ textureTypeIndex = i; >+ if (innerType.name() == m_textureInnerTypeNames[i]) >+ vectorLength = 1; >+ else { >+ ASSERT(innerType.name().length() == m_textureInnerTypeNames[i].length() + 1); >+ ASSERT(innerType.name()[innerType.name().length() - 1] == '2' >+ || innerType.name()[innerType.name().length() - 1] == '3' >+ || innerType.name()[innerType.name().length() - 1] == '4'); >+ vectorLength = innerType.name()[innerType.name().length() - 1] - '0'; >+ } >+ } >+ } >+ ASSERT(innerTypeIndex != m_textureInnerTypeNames.size()); >+ nativeTypeDeclaration.setIsTexture(); >+ m_fullTextures[textureTypeIndex][innerTypeIndex][vectorLength - 1] = &nativeTypeDeclaration; >+ return true; >+} >+ >+bool Intrinsics::addDepthTexture(AST::NativeTypeDeclaration& nativeTypeDeclaration, AST::TypeReference& innerType) >+{ >+ AST::NativeTypeDeclaration** texture; >+ if (nativeTypeDeclaration.name() == "TextureDepth2D") >+ texture = m_textureDepth2D; >+ else if (nativeTypeDeclaration.name() == "RWTextureDepth2D") >+ texture = m_rwTextureDepth2D; >+ else if (nativeTypeDeclaration.name() == "TextureDepth2DArray") >+ texture = m_textureDepth2DArray; >+ else if (nativeTypeDeclaration.name() == "RWTextureDepth2DArray") >+ texture = m_rwTextureDepth2DArray; >+ else if (nativeTypeDeclaration.name() == "TextureDepthCube") >+ texture = m_textureDepthCube; >+ else >+ ASSERT_NOT_REACHED(); >+ unsigned innerTypeIndex = m_depthTextureInnerTypes.size(); >+ for (unsigned i = 0; i < m_depthTextureInnerTypes.size(); ++i) { >+ if (innerType.name() == m_depthTextureInnerTypes[i]) >+ innerTypeIndex = i; >+ } >+ ASSERT(innerTypeIndex != m_depthTextureInnerTypes.size()); >+ nativeTypeDeclaration.setIsTexture(); >+ texture[innerTypeIndex] = &nativeTypeDeclaration; >+ return true; >+} >+ >+void Intrinsics::addTexture(AST::NativeTypeDeclaration& nativeTypeDeclaration) >+{ >+ ASSERT(nativeTypeDeclaration.typeArguments().size() == 1); >+ ASSERT(WTF::holds_alternative<UniqueRef<AST::TypeReference>>(nativeTypeDeclaration.typeArguments()[0])); >+ auto& innerType = static_cast<AST::TypeReference&>(WTF::get<UniqueRef<AST::TypeReference>>(nativeTypeDeclaration.typeArguments()[0])); >+ ASSERT(innerType.typeArguments().size() == 0); >+ if (addFullTexture(nativeTypeDeclaration, innerType)) { >+ m_textureSet.add(&nativeTypeDeclaration); >+ return; >+ } >+ if (addDepthTexture(nativeTypeDeclaration, innerType)) >+ m_textureSet.add(&nativeTypeDeclaration); >+} >+ >+void Intrinsics::add(AST::NativeTypeDeclaration& nativeTypeDeclaration) >+{ >+ if (addPrimitive(nativeTypeDeclaration)) >+ return; >+ if (addVector(nativeTypeDeclaration)) >+ return; >+ if (addMatrix(nativeTypeDeclaration)) >+ return; >+ addTexture(nativeTypeDeclaration); >+} >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLIntrinsics.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLIntrinsics.h >new file mode 100644 >index 00000000000..31a98ab3db7 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLIntrinsics.h >@@ -0,0 +1,151 @@ >+/* >+ * 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 "WHLSLNativeFunctionDeclaration.h" >+#include "WHLSLNativeTypeDeclaration.h" >+#include <cstring> >+#include <wtf/HashSet.h> >+#include <wtf/StdLibExtras.h> >+#include <wtf/Vector.h> >+#include <wtf/text/WTFString.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+class Intrinsics { >+public: >+ Intrinsics(); >+ >+ void add(AST::NativeFunctionDeclaration&); >+ void add(AST::NativeTypeDeclaration&); >+ >+ AST::NativeTypeDeclaration& voidType() const >+ { >+ ASSERT(m_voidType); >+ return *m_voidType; >+ } >+ >+ AST::NativeTypeDeclaration& boolType() const >+ { >+ ASSERT(m_boolType); >+ return *m_boolType; >+ } >+ >+ AST::NativeTypeDeclaration& intType() const >+ { >+ ASSERT(m_intType); >+ return *m_intType; >+ } >+ >+ AST::NativeTypeDeclaration& uintType() const >+ { >+ ASSERT(m_uintType); >+ return *m_uintType; >+ } >+ >+ AST::NativeTypeDeclaration& samplerType() const >+ { >+ ASSERT(m_samplerType); >+ return *m_samplerType; >+ } >+ >+ AST::NativeTypeDeclaration& floatType() const >+ { >+ ASSERT(m_floatType); >+ return *m_floatType; >+ } >+ >+ AST::NativeTypeDeclaration& float3Type() const >+ { >+ ASSERT(m_vectorFloat[1]); >+ return *m_vectorFloat[1]; >+ } >+ >+ AST::NativeTypeDeclaration& float4Type() const >+ { >+ ASSERT(m_vectorFloat[2]); >+ return *m_vectorFloat[2]; >+ } >+ >+private: >+ bool addPrimitive(AST::NativeTypeDeclaration&); >+ bool addVector(AST::NativeTypeDeclaration&); >+ bool addMatrix(AST::NativeTypeDeclaration&); >+ bool addFullTexture(AST::NativeTypeDeclaration&, AST::TypeReference&); >+ bool addDepthTexture(AST::NativeTypeDeclaration&, AST::TypeReference&); >+ void addTexture(AST::NativeTypeDeclaration&); >+ >+ HashSet<const AST::NativeTypeDeclaration*> m_textureSet; >+ >+ AST::NativeTypeDeclaration* m_voidType; >+ AST::NativeTypeDeclaration* m_boolType; >+ AST::NativeTypeDeclaration* m_ucharType; >+ AST::NativeTypeDeclaration* m_ushortType; >+ AST::NativeTypeDeclaration* m_uintType; >+ AST::NativeTypeDeclaration* m_charType; >+ AST::NativeTypeDeclaration* m_shortType; >+ AST::NativeTypeDeclaration* m_intType; >+ AST::NativeTypeDeclaration* m_halfType; >+ AST::NativeTypeDeclaration* m_floatType; >+ AST::NativeTypeDeclaration* m_atomicIntType; >+ AST::NativeTypeDeclaration* m_atomicUintType; >+ AST::NativeTypeDeclaration* m_samplerType; >+ >+ AST::NativeTypeDeclaration* m_vectorBool[3]; >+ AST::NativeTypeDeclaration* m_vectorUchar[3]; >+ AST::NativeTypeDeclaration* m_vectorUshort[3]; >+ AST::NativeTypeDeclaration* m_vectorUint[3]; >+ AST::NativeTypeDeclaration* m_vectorChar[3]; >+ AST::NativeTypeDeclaration* m_vectorShort[3]; >+ AST::NativeTypeDeclaration* m_vectorInt[3]; >+ AST::NativeTypeDeclaration* m_vectorHalf[3]; >+ AST::NativeTypeDeclaration* m_vectorFloat[3]; >+ >+ AST::NativeTypeDeclaration* m_matrixHalf[3][3]; >+ AST::NativeTypeDeclaration* m_matrixFloat[3][3]; >+ >+ Vector<String> m_textureTypeNames; >+ Vector<String> m_textureInnerTypeNames; >+ >+ AST::NativeTypeDeclaration* m_fullTextures[11][8][4]; >+ >+ Vector<String> m_depthTextureInnerTypes; >+ AST::NativeTypeDeclaration* m_textureDepth2D[2]; >+ AST::NativeTypeDeclaration* m_rwTextureDepth2D[2]; >+ AST::NativeTypeDeclaration* m_textureDepth2DArray[2]; >+ AST::NativeTypeDeclaration* m_rwTextureDepth2DArray[2]; >+ AST::NativeTypeDeclaration* m_textureDepthCube[2]; >+}; >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLLexer.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLLexer.cpp >index 3b1934e9316..e9aeae7b542 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLLexer.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLLexer.cpp >@@ -23,8 +23,6 @@ > * THE POSSIBILITY OF SUCH DAMAGE. > */ > >-#pragma once >- > #include "config.h" > #include "WHLSLLexer.h" > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameContext.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameContext.cpp >new file mode 100644 >index 00000000000..4e86bb9804a >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameContext.cpp >@@ -0,0 +1,163 @@ >+/* >+ * 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. >+ */ >+ >+#if ENABLE(WEBGPU) >+ >+#include "config.h" >+#include "WHLSLNameContext.h" >+ >+#include "WHLSLEnumerationDefinition.h" >+#include "WHLSLFunctionDefinition.h" >+#include "WHLSLNativeFunctionDeclaration.h" >+#include "WHLSLNativeTypeDeclaration.h" >+#include "WHLSLStructureDefinition.h" >+#include "WHLSLTypeDefinition.h" >+#include "WHLSLVariableDeclaration.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+NameContext::NameContext(NameContext* parent) >+ : m_parent(parent) >+{ >+} >+ >+bool NameContext::add(AST::TypeDefinition& typeDefinition) >+{ >+ if (exists(typeDefinition.name())) >+ return false; >+ auto result = m_types.add(typeDefinition.name(), Vector<std::reference_wrapper<AST::NamedType>, 1>()); >+ if (!result.isNewEntry) >+ return false; >+ result.iterator->value.append(typeDefinition); >+ return true; >+} >+ >+bool NameContext::add(AST::StructureDefinition& structureDefinition) >+{ >+ if (exists(structureDefinition.name())) >+ return false; >+ auto result = m_types.add(structureDefinition.name(), Vector<std::reference_wrapper<AST::NamedType>, 1>()); >+ if (!result.isNewEntry) >+ return false; >+ result.iterator->value.append(structureDefinition); >+ return true; >+} >+ >+bool NameContext::add(AST::EnumerationDefinition& enumerationDefinition) >+{ >+ if (exists(enumerationDefinition.name())) >+ return false; >+ auto result = m_types.add(enumerationDefinition.name(), Vector<std::reference_wrapper<AST::NamedType>, 1>()); >+ if (!result.isNewEntry) >+ return false; >+ result.iterator->value.append(enumerationDefinition); >+ return true; >+} >+ >+bool NameContext::add(AST::FunctionDefinition& functionDefinition) >+{ >+ if (m_types.find(functionDefinition.name()) != m_types.end() >+ || m_variables.find(functionDefinition.name()) != m_variables.end()) >+ return false; >+ auto result = m_functions.add(functionDefinition.name(), Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>()); >+ result.iterator->value.append(functionDefinition); >+ return true; >+} >+ >+bool NameContext::add(AST::NativeFunctionDeclaration& nativeFunctionDeclaration) >+{ >+ if (m_types.find(nativeFunctionDeclaration.name()) != m_types.end() >+ || m_variables.find(nativeFunctionDeclaration.name()) != m_variables.end()) >+ return false; >+ auto result = m_functions.add(nativeFunctionDeclaration.name(), Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>()); >+ result.iterator->value.append(nativeFunctionDeclaration); >+ return true; >+} >+ >+bool NameContext::add(AST::NativeTypeDeclaration& nativeTypeDeclaration) >+{ >+ if (m_functions.find(nativeTypeDeclaration.name()) != m_functions.end() >+ || m_variables.find(nativeTypeDeclaration.name()) != m_variables.end()) >+ return false; >+ auto result = m_types.add(nativeTypeDeclaration.name(), Vector<std::reference_wrapper<AST::NamedType>, 1>()); >+ result.iterator->value.append(nativeTypeDeclaration); >+ return true; >+} >+ >+bool NameContext::add(AST::VariableDeclaration& variableDeclaration) >+{ >+ if (exists(variableDeclaration.name())) >+ return false; >+ auto result = m_variables.add(String(variableDeclaration.name()), &variableDeclaration); >+ return result.isNewEntry; >+} >+ >+Vector<std::reference_wrapper<AST::NamedType>, 1>* NameContext::getTypes(const String& name) >+{ >+ auto iterator = m_types.find(name); >+ if (iterator == m_types.end()) { >+ if (m_parent) >+ return m_parent->getTypes(name); >+ return nullptr; >+ } >+ return &iterator->value; >+} >+ >+Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>* NameContext::getFunctions(const String& name) >+{ >+ auto iterator = m_functions.find(name); >+ if (iterator == m_functions.end()) { >+ if (m_parent) >+ return m_parent->getFunctions(name); >+ return nullptr; >+ } >+ return &iterator->value; >+} >+ >+AST::VariableDeclaration* NameContext::getVariable(const String& name) >+{ >+ auto iterator = m_variables.find(name); >+ if (iterator == m_variables.end()) { >+ if (m_parent) >+ return m_parent->getVariable(name); >+ return nullptr; >+ } >+ return iterator->value; >+} >+ >+bool NameContext::exists(String& name) >+{ >+ return m_types.find(name) != m_types.end() >+ || m_functions.find(name) != m_functions.end() >+ || m_variables.find(name) != m_variables.end(); >+} >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameContext.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameContext.h >new file mode 100644 >index 00000000000..d3df80014ae >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameContext.h >@@ -0,0 +1,82 @@ >+/* >+ * 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 <functional> >+#include <wtf/HashMap.h> >+#include <wtf/Vector.h> >+#include <wtf/text/WTFString.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class NamedType; >+class FunctionDeclaration; >+class TypeDefinition; >+class StructureDefinition; >+class EnumerationDefinition; >+class FunctionDefinition; >+class NativeFunctionDeclaration; >+class NativeTypeDeclaration; >+class VariableDeclaration; >+ >+} >+ >+class NameContext { >+public: >+ NameContext(NameContext* parent = nullptr); >+ >+ bool add(AST::TypeDefinition&); >+ bool add(AST::StructureDefinition&); >+ bool add(AST::EnumerationDefinition&); >+ bool add(AST::FunctionDefinition&); >+ bool add(AST::NativeFunctionDeclaration&); >+ bool add(AST::NativeTypeDeclaration&); >+ bool add(AST::VariableDeclaration&); >+ >+ Vector<std::reference_wrapper<AST::NamedType>, 1>* getTypes(const String&); >+ Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>* getFunctions(const String&); >+ AST::VariableDeclaration* getVariable(const String&); >+ >+private: >+ bool exists(String&); >+ >+ HashMap<String, Vector<std::reference_wrapper<AST::NamedType>, 1>> m_types; >+ HashMap<String, Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>> m_functions; >+ HashMap<String, AST::VariableDeclaration*> m_variables; >+ NameContext* m_parent; >+}; >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.cpp >index 780d5c5425a..fbf5058544f 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.cpp >@@ -28,19 +28,250 @@ > #include "config.h" > #include "WHLSLNameResolver.h" > >-#include "WHLSLVisitor.h" >+#include "WHLSLEnumerationMemberLiteral.h" >+#include "WHLSLNameContext.h" >+#include "WHLSLResolveOverloadImpl.h" >+#include "WHLSLTypeReference.h" >+#include "WHLSLFunctionDefinition.h" >+#include "WHLSLIfStatement.h" >+#include "WHLSLWhileLoop.h" >+#include "WHLSLDoWhileLoop.h" >+#include "WHLSLForLoop.h" >+#include "WHLSLVariableDeclaration.h" >+#include "WHLSLVariableReference.h" >+#include "WHLSLReturn.h" >+#include "WHLSLPropertyAccessExpression.h" >+#include "WHLSLDotExpression.h" >+#include "WHLSLEnumerationDefinition.h" >+#include "WHLSLCallExpression.h" >+#include "WHLSLProgram.h" > > namespace WebCore { > > namespace WHLSL { > >-class NameResolver : public Visitor { >- ~NameResolver() = default; >-}; >+NameResolver::NameResolver(NameContext& nameContext) >+ : m_nameContext(nameContext) >+{ >+} >+ >+void NameResolver::visit(AST::TypeReference& typeReference) >+{ >+ checkErrorAndVisit(typeReference); >+ if (typeReference.resolvedType()) >+ return; >+ >+ auto* candidates = m_nameContext.getTypes(typeReference.name()); >+ if (candidates == nullptr) { >+ setError(); >+ return; >+ } >+ if (auto result = resolveTypeOverloadImpl(*candidates, typeReference.typeArguments())) >+ typeReference.setResolvedType(*result); >+ else { >+ setError(); >+ return; >+ } >+} >+ >+void NameResolver::visit(AST::FunctionDefinition& functionDefinition) >+{ >+ NameContext newNameContext(&m_nameContext); >+ NameResolver newNameResolver(newNameContext); >+ checkErrorAndVisit(functionDefinition.type()); >+ for (auto& parameter : functionDefinition.parameters()) { >+ newNameResolver.checkErrorAndVisit(parameter); >+ auto success = newNameContext.add(parameter); >+ if (!success) { >+ setError(); >+ return; >+ } >+ } >+ newNameResolver.checkErrorAndVisit(functionDefinition.block()); >+} >+ >+void NameResolver::visit(AST::Block& block) >+{ >+ NameContext nameContext(&m_nameContext); >+ NameResolver(nameContext).checkErrorAndVisit(block); >+} >+ >+void NameResolver::visit(AST::IfStatement& ifStatement) >+{ >+ checkErrorAndVisit(ifStatement.conditional()); >+ NameContext nameContext(&m_nameContext); >+ NameResolver(nameContext).checkErrorAndVisit(ifStatement.body()); >+ if (ifStatement.elseBody()) { >+ NameContext nameContext(&m_nameContext); >+ NameResolver(nameContext).checkErrorAndVisit(*ifStatement.elseBody()); >+ } >+} >+ >+void NameResolver::visit(AST::WhileLoop& whileLoop) >+{ >+ checkErrorAndVisit(whileLoop.conditional()); >+ NameContext nameContext(&m_nameContext); >+ NameResolver(nameContext).checkErrorAndVisit(whileLoop.body()); >+} >+ >+void NameResolver::visit(AST::DoWhileLoop& whileLoop) >+{ >+ NameContext nameContext(&m_nameContext); >+ NameResolver(nameContext).checkErrorAndVisit(whileLoop.body()); >+ checkErrorAndVisit(whileLoop.conditional()); >+} >+ >+void NameResolver::visit(AST::ForLoop& forLoop) >+{ >+ NameContext nameContext(&m_nameContext); >+ NameResolver(nameContext).checkErrorAndVisit(forLoop); >+} >+ >+void NameResolver::visit(AST::VariableDeclaration& variableDeclaration) >+{ >+ m_nameContext.add(variableDeclaration); >+ checkErrorAndVisit(variableDeclaration); >+} > >-void resolveNamesInTypes(Program&) >+void NameResolver::visit(AST::VariableReference& variableReference) > { >+ if (variableReference.variable()) >+ return; >+ >+ if (auto* variable = m_nameContext.getVariable(variableReference.name())) >+ variableReference.setVariable(*variable); >+ else { >+ setError(); >+ return; >+ } >+} >+ >+void NameResolver::visit(AST::Return& returnStatement) >+{ >+ ASSERT(m_currentFunction); >+ returnStatement.setFunction(m_currentFunction); >+ checkErrorAndVisit(returnStatement); >+} > >+void NameResolver::visit(AST::PropertyAccessExpression& propertyAccessExpression) >+{ >+ if (auto* getFunctions = m_nameContext.getFunctions(propertyAccessExpression.getFunctionName())) >+ propertyAccessExpression.setPossibleGetOverloads(*getFunctions); >+ if (auto* setFunctions = m_nameContext.getFunctions(propertyAccessExpression.setFunctionName())) >+ propertyAccessExpression.setPossibleSetOverloads(*setFunctions); >+ if (auto* andFunctions = m_nameContext.getFunctions(propertyAccessExpression.andFunctionName())) >+ propertyAccessExpression.setPossibleAndOverloads(*andFunctions); >+ checkErrorAndVisit(propertyAccessExpression); >+} >+ >+void NameResolver::visit(AST::DotExpression& dotExpression) >+{ >+ if (is<AST::VariableReference>(dotExpression.base())) { >+ if (auto enumerationTypes = m_nameContext.getTypes(downcast<AST::VariableReference>(dotExpression.base()).name())) { >+ ASSERT(enumerationTypes->size() == 1); >+ AST::NamedType& type = (*enumerationTypes)[0]; >+ if (is<AST::EnumerationDefinition>(type)) { >+ AST::EnumerationDefinition& enumerationDefinition = downcast<AST::EnumerationDefinition>(type); >+ if (auto* member = enumerationDefinition.memberByName(dotExpression.fieldName())) { >+ static_assert(sizeof(AST::EnumerationMemberLiteral) <= sizeof(AST::DotExpression), "Dot expressions need to be able to become EnumerationMemberLiterals without updating backreferences"); >+ Lexer::Token origin = dotExpression.origin(); >+ // FIXME: Perhaps do this with variants or a Rewriter instead. >+ dotExpression.~DotExpression(); >+ new (&dotExpression) AST::EnumerationMemberLiteral(WTFMove(origin), *member); >+ return; >+ } else { >+ setError(); >+ return; >+ } >+ } >+ } >+ } >+ >+ checkErrorAndVisit(dotExpression); >+} >+ >+void NameResolver::visit(AST::CallExpression& callExpression) >+{ >+ if (!callExpression.hasOverloads()) { >+ if (auto* functions = m_nameContext.getFunctions(callExpression.name())) >+ callExpression.setOverloads(*functions); >+ else { >+ if (auto* types = m_nameContext.getTypes(callExpression.name())) { >+ if (types->size() == 1) { >+ if (auto* functions = m_nameContext.getFunctions(String("operator cast", String::ConstructFromLiteral))) { >+ callExpression.setCastData((*types)[0].get()); >+ callExpression.setOverloads(*functions); >+ } >+ } >+ } >+ } >+ } >+ if (!callExpression.hasOverloads()) { >+ setError(); >+ return; >+ } >+ checkErrorAndVisit(callExpression); >+} >+ >+void NameResolver::visit(AST::ConstantExpressionEnumerationMemberReference& constantExpressionEnumerationMemberReference) >+{ >+ if (auto enumerationTypes = m_nameContext.getTypes(constantExpressionEnumerationMemberReference.left())) { >+ ASSERT(enumerationTypes->size() == 1); >+ AST::NamedType& type = (*enumerationTypes)[0]; >+ if (is<AST::EnumerationDefinition>(type)) { >+ AST::EnumerationDefinition& enumerationDefinition = downcast<AST::EnumerationDefinition>(type); >+ if (auto* member = enumerationDefinition.memberByName(constantExpressionEnumerationMemberReference.right())) { >+ constantExpressionEnumerationMemberReference.setEnumerationMember(enumerationDefinition, *member); >+ return; >+ } >+ } >+ } >+ >+ setError(); >+} >+ >+// FIXME: Make sure all the names have been resolved. >+ >+bool resolveNamesInTypes(Program& program, NameResolver& nameResolver) >+{ >+ for (auto& typeDefinition : program.typeDefinitions()) { >+ nameResolver.checkErrorAndVisit(*typeDefinition); >+ if (nameResolver.error()) >+ return false; >+ } >+ for (auto& structureDefinition : program.structureDefinitions()) { >+ nameResolver.checkErrorAndVisit(*structureDefinition); >+ if (nameResolver.error()) >+ return false; >+ } >+ for (auto& enumerationDefinition : program.enumerationDefinitions()) { >+ nameResolver.checkErrorAndVisit(*enumerationDefinition); >+ if (nameResolver.error()) >+ return false; >+ } >+ for (auto& nativeTypeDeclaration : program.nativeTypeDeclarations()) { >+ nameResolver.checkErrorAndVisit(*nativeTypeDeclaration); >+ if (nameResolver.error()) >+ return false; >+ } >+ return true; >+} >+ >+bool resolveNamesInFunctions(Program& program, NameResolver& nameResolver) >+{ >+ for (auto& functionDefinition : program.functionDefinitions()) { >+ nameResolver.setCurrentFunctionDefinition(functionDefinition.get()); >+ nameResolver.checkErrorAndVisit(*functionDefinition); >+ if (nameResolver.error()) >+ return false; >+ } >+ nameResolver.setCurrentFunctionDefinition(nullptr); >+ for (auto& nativeFunctionDeclaration : program.nativeFunctionDeclarations()) { >+ nameResolver.checkErrorAndVisit(*nativeFunctionDeclaration); >+ if (nameResolver.error()) >+ return false; >+ } >+ return true; > } > > } >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.h >index 47d4d6a5793..15afde3d03b 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.h >@@ -27,13 +27,49 @@ > > #if ENABLE(WEBGPU) > >-#include "WHLSLProgram.h" >+#include "WHLSLNameContext.h" >+#include "WHLSLVisitor.h" > > namespace WebCore { > > namespace WHLSL { > >-void resolveNamesInTypes(Program& program); >+class Program; >+ >+class NameResolver : public Visitor { >+public: >+ NameResolver(NameContext&); >+ >+ virtual ~NameResolver() = default; >+ >+ void visit(AST::FunctionDefinition& functionDefinition) override; >+ >+ void setCurrentFunctionDefinition(AST::FunctionDefinition* functionDefinition) >+ { >+ m_currentFunction = functionDefinition; >+ } >+ >+private: >+ void visit(AST::TypeReference&) override; >+ void visit(AST::Block&) override; >+ void visit(AST::IfStatement&) override; >+ void visit(AST::WhileLoop&) override; >+ void visit(AST::DoWhileLoop&) override; >+ void visit(AST::ForLoop&) override; >+ void visit(AST::VariableDeclaration&) override; >+ void visit(AST::VariableReference&) override; >+ void visit(AST::Return&) override; >+ void visit(AST::PropertyAccessExpression&) override; >+ void visit(AST::DotExpression&) override; >+ void visit(AST::CallExpression&) override; >+ void visit(AST::ConstantExpressionEnumerationMemberReference&) override; >+ >+ NameContext m_nameContext; >+ AST::FunctionDefinition* m_currentFunction { nullptr }; >+}; >+ >+bool resolveNamesInTypes(Program&, NameResolver&); >+bool resolveNamesInFunctions(Program&, NameResolver&); > > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.cpp >index bc6e73e6a1f..59e0ac75b59 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.cpp >@@ -38,7 +38,8 @@ Parser::Parser() > { > } > >-auto Parser::parse(Program& result, StringView stringView, Mode mode) -> Optional<Error> >+// FIXME: Return a better error code from this, and report it to JavaScript. >+auto Parser::parse(Program& program, StringView stringView, Mode mode) -> Optional<Error> > { > m_lexer = Lexer(stringView); > m_mode = mode; >@@ -54,7 +55,11 @@ auto Parser::parse(Program& result, StringView stringView, Mode mode) -> Optiona > return parseTypeDefinition(); > }); > if (typeDefinition) { >- result.append(WTFMove(*typeDefinition)); >+ auto success = program.append(WTFMove(*typeDefinition)); >+ if (!success) { >+ WTFLogAlways("Name Error! %s", typeDefinition->name().utf8().data()); >+ return WTF::nullopt; >+ } > continue; > } > } >@@ -64,7 +69,11 @@ auto Parser::parse(Program& result, StringView stringView, Mode mode) -> Optiona > return parseStructureDefinition(); > }); > if (structureDefinition) { >- result.append(WTFMove(*structureDefinition)); >+ auto success = program.append(WTFMove(*structureDefinition)); >+ if (!success) { >+ WTFLogAlways("Name Error! %s", structureDefinition->name().utf8().data()); >+ return WTF::nullopt; >+ } > continue; > } > } >@@ -74,7 +83,11 @@ auto Parser::parse(Program& result, StringView stringView, Mode mode) -> Optiona > return parseEnumerationDefinition(); > }); > if (enumerationDefinition) { >- result.append(WTFMove(*enumerationDefinition)); >+ auto success = program.append(WTFMove(*enumerationDefinition)); >+ if (!success) { >+ WTFLogAlways("Name Error! %s", enumerationDefinition->name().utf8().data()); >+ return WTF::nullopt; >+ } > continue; > } > } >@@ -85,7 +98,11 @@ auto Parser::parse(Program& result, StringView stringView, Mode mode) -> Optiona > return parseFunctionDefinition(); > }); > if (functionDefinition) { >- result.append(WTFMove(*functionDefinition)); >+ auto success = program.append(WTFMove(*functionDefinition)); >+ if (!success) { >+ WTFLogAlways("Name Error! %s", functionDefinition->name().utf8().data()); >+ return WTF::nullopt; >+ } > continue; > } > error = functionDefinition.error(); >@@ -96,7 +113,11 @@ auto Parser::parse(Program& result, StringView stringView, Mode mode) -> Optiona > return parseNativeFunctionDeclaration(); > }); > if (nativeFunctionDeclaration) { >- result.append(WTFMove(*nativeFunctionDeclaration)); >+ auto success = program.append(WTFMove(*nativeFunctionDeclaration)); >+ if (!success) { >+ WTFLogAlways("Name Error! %s", nativeFunctionDeclaration->name().utf8().data()); >+ return WTF::nullopt; >+ } > continue; > } > } >@@ -106,7 +127,11 @@ auto Parser::parse(Program& result, StringView stringView, Mode mode) -> Optiona > return parseNativeTypeDeclaration(); > }); > if (nativeTypeDeclaration) { >- result.append(WTFMove(*nativeTypeDeclaration)); >+ auto success = program.append(WTFMove(*nativeTypeDeclaration)); >+ if (!success) { >+ WTFLogAlways("Name Error! %s", nativeTypeDeclaration->name().utf8().data()); >+ return WTF::nullopt; >+ } > continue; > } > } >@@ -383,7 +408,7 @@ auto Parser::parseTypeArgument() -> Expected<AST::TypeArgument, Error> { > auto result = consumeType(Lexer::Token::Type::Identifier); > if (!result) > return Unexpected<Error>(result.error()); >- return AST::TypeArgument(std::make_unique<AST::TypeReference>(Lexer::Token(*result), result->stringView.toString(), AST::TypeArguments())); >+ return AST::TypeArgument(makeUniqueRef<AST::TypeReference>(Lexer::Token(*result), result->stringView.toString(), AST::TypeArguments())); > } > > auto Parser::parseTypeArguments() -> Expected<AST::TypeArguments, Error> { >@@ -454,16 +479,52 @@ auto Parser::parseTypeSuffixNonAbbreviated() -> Expected<TypeSuffixNonAbbreviate > return Unexpected<Error>(rightSquareBracket.error()); > return {{ *token, WTF::nullopt, *numElements }}; > } >- auto addressSpace = consumeTypes({ Lexer::Token::Type::Constant, Lexer::Token::Type::Device, Lexer::Token::Type::Threadgroup, Lexer::Token::Type::Thread}); >- if (!addressSpace) >- return Unexpected<Error>(addressSpace.error()); >- return {{ *token, { *addressSpace }, WTF::nullopt }}; >+ auto addressSpaceToken = consumeTypes({ Lexer::Token::Type::Constant, Lexer::Token::Type::Device, Lexer::Token::Type::Threadgroup, Lexer::Token::Type::Thread}); >+ if (!addressSpaceToken) >+ return Unexpected<Error>(addressSpaceToken.error()); >+ AST::ReferenceType::AddressSpace addressSpace; >+ switch (addressSpaceToken->type) { >+ case Lexer::Token::Type::Constant: >+ addressSpace = AST::ReferenceType::AddressSpace::Constant; >+ break; >+ case Lexer::Token::Type::Device: >+ addressSpace = AST::ReferenceType::AddressSpace::Device; >+ break; >+ case Lexer::Token::Type::Threadgroup: >+ addressSpace = AST::ReferenceType::AddressSpace::Threadgroup; >+ break; >+ case Lexer::Token::Type::Thread: >+ addressSpace = AST::ReferenceType::AddressSpace::Thread; >+ break; >+ default: >+ ASSERT_NOT_REACHED(); >+ return Unexpected<Error>(Error(String("Something really bad happened", String::ConstructFromLiteral))); >+ } >+ return {{ *token, { addressSpace }, WTF::nullopt }}; > } > >-auto Parser::parseAddressSpaceType() -> Expected<std::unique_ptr<AST::Type>, Error> { >- auto addressSpace = consumeTypes({ Lexer::Token::Type::Constant, Lexer::Token::Type::Device, Lexer::Token::Type::Threadgroup, Lexer::Token::Type::Thread}); >- if (!addressSpace) >- return Unexpected<Error>(addressSpace.error()); >+auto Parser::parseAddressSpaceType() -> Expected<UniqueRef<AST::UnnamedType>, Error> { >+ auto addressSpaceToken = consumeTypes({ Lexer::Token::Type::Constant, Lexer::Token::Type::Device, Lexer::Token::Type::Threadgroup, Lexer::Token::Type::Thread}); >+ if (!addressSpaceToken) >+ return Unexpected<Error>(addressSpaceToken.error()); >+ AST::ReferenceType::AddressSpace addressSpace; >+ switch (addressSpaceToken->type) { >+ case Lexer::Token::Type::Constant: >+ addressSpace = AST::ReferenceType::AddressSpace::Constant; >+ break; >+ case Lexer::Token::Type::Device: >+ addressSpace = AST::ReferenceType::AddressSpace::Device; >+ break; >+ case Lexer::Token::Type::Threadgroup: >+ addressSpace = AST::ReferenceType::AddressSpace::Threadgroup; >+ break; >+ case Lexer::Token::Type::Thread: >+ addressSpace = AST::ReferenceType::AddressSpace::Thread; >+ break; >+ default: >+ ASSERT_NOT_REACHED(); >+ return Unexpected<Error>(Error(String("Something really bad happened", String::ConstructFromLiteral))); >+ } > auto name = consumeType(Lexer::Token::Type::Identifier); > if (!name) > return Unexpected<Error>(name.error()); >@@ -471,24 +532,23 @@ auto Parser::parseAddressSpaceType() -> Expected<std::unique_ptr<AST::Type>, Err > if (!typeArguments) > return Unexpected<Error>(typeArguments.error()); > >- auto constructTypeFromSuffixAbbreviated = [&](const TypeSuffixAbbreviated& typeSuffixAbbreviated, std::unique_ptr<AST::Type>&& previous) -> std::unique_ptr<AST::Type> { >+ auto constructTypeFromSuffixAbbreviated = [&](const TypeSuffixAbbreviated& typeSuffixAbbreviated, UniqueRef<AST::UnnamedType>&& previous) -> UniqueRef<AST::UnnamedType> { > switch (typeSuffixAbbreviated.token.type) { > case Lexer::Token::Type::Star: >- return std::make_unique<AST::PointerType>(Lexer::Token(typeSuffixAbbreviated.token), addressSpace->stringView.toString(), WTFMove(previous)); >+ return makeUniqueRef<AST::PointerType>(Lexer::Token(typeSuffixAbbreviated.token), addressSpace, WTFMove(previous)); > case Lexer::Token::Type::SquareBracketPair: >- return std::make_unique<AST::ArrayReferenceType>(Lexer::Token(typeSuffixAbbreviated.token), addressSpace->stringView.toString(), WTFMove(previous)); >+ return makeUniqueRef<AST::ArrayReferenceType>(Lexer::Token(typeSuffixAbbreviated.token), addressSpace, WTFMove(previous)); > case Lexer::Token::Type::LeftSquareBracket: >- return std::make_unique<AST::ArrayType>(Lexer::Token(typeSuffixAbbreviated.token), WTFMove(previous), *typeSuffixAbbreviated.numElements); >+ return makeUniqueRef<AST::ArrayType>(Lexer::Token(typeSuffixAbbreviated.token), WTFMove(previous), *typeSuffixAbbreviated.numElements); > default: > ASSERT_NOT_REACHED(); >- return nullptr; > } > }; > > auto firstTypeSuffixAbbreviated = parseTypeSuffixAbbreviated(); > if (!firstTypeSuffixAbbreviated) > return Unexpected<Error>(firstTypeSuffixAbbreviated.error()); >- std::unique_ptr<AST::Type> result = std::make_unique<AST::TypeReference>(Lexer::Token(*addressSpace), name->stringView.toString(), WTFMove(*typeArguments)); >+ UniqueRef<AST::UnnamedType> result = makeUniqueRef<AST::TypeReference>(WTFMove(*addressSpaceToken), name->stringView.toString(), WTFMove(*typeArguments)); > result = constructTypeFromSuffixAbbreviated(*firstTypeSuffixAbbreviated, WTFMove(result)); > while (true) { > auto typeSuffixAbbreviated = backtrackingScope<Expected<TypeSuffixAbbreviated, Error>>([&]() { >@@ -503,7 +563,7 @@ auto Parser::parseAddressSpaceType() -> Expected<std::unique_ptr<AST::Type>, Err > return WTFMove(result); > } > >-auto Parser::parseNonAddressSpaceType() -> Expected<std::unique_ptr<AST::Type>, Error> { >+auto Parser::parseNonAddressSpaceType() -> Expected<UniqueRef<AST::UnnamedType>, Error> { > auto origin = peek(); > if (!origin) > return Unexpected<Error>(origin.error()); >@@ -514,21 +574,20 @@ auto Parser::parseNonAddressSpaceType() -> Expected<std::unique_ptr<AST::Type>, > if (!typeArguments) > return Unexpected<Error>(typeArguments.error()); > >- auto constructTypeFromSuffixNonAbbreviated = [&](const TypeSuffixNonAbbreviated& typeSuffixNonAbbreviated, std::unique_ptr<AST::Type>&& previous) -> std::unique_ptr<AST::Type> { >+ auto constructTypeFromSuffixNonAbbreviated = [&](const TypeSuffixNonAbbreviated& typeSuffixNonAbbreviated, UniqueRef<AST::UnnamedType>&& previous) -> UniqueRef<AST::UnnamedType> { > switch (typeSuffixNonAbbreviated.token.type) { > case Lexer::Token::Type::Star: >- return std::make_unique<AST::PointerType>(Lexer::Token(typeSuffixNonAbbreviated.token), typeSuffixNonAbbreviated.addressSpace->stringView.toString(), WTFMove(previous)); >+ return makeUniqueRef<AST::PointerType>(Lexer::Token(typeSuffixNonAbbreviated.token), *typeSuffixNonAbbreviated.addressSpace, WTFMove(previous)); > case Lexer::Token::Type::SquareBracketPair: >- return std::make_unique<AST::ArrayReferenceType>(Lexer::Token(typeSuffixNonAbbreviated.token), typeSuffixNonAbbreviated.addressSpace->stringView.toString(), WTFMove(previous)); >+ return makeUniqueRef<AST::ArrayReferenceType>(Lexer::Token(typeSuffixNonAbbreviated.token), *typeSuffixNonAbbreviated.addressSpace, WTFMove(previous)); > case Lexer::Token::Type::LeftSquareBracket: >- return std::make_unique<AST::ArrayType>(Lexer::Token(typeSuffixNonAbbreviated.token), WTFMove(previous), *typeSuffixNonAbbreviated.numElements); >+ return makeUniqueRef<AST::ArrayType>(Lexer::Token(typeSuffixNonAbbreviated.token), WTFMove(previous), *typeSuffixNonAbbreviated.numElements); > default: > ASSERT_NOT_REACHED(); >- return nullptr; > } > }; > >- std::unique_ptr<AST::Type> result = std::make_unique<AST::TypeReference>(WTFMove(*origin), name->stringView.toString(), WTFMove(*typeArguments)); >+ UniqueRef<AST::UnnamedType> result = makeUniqueRef<AST::TypeReference>(WTFMove(*origin), name->stringView.toString(), WTFMove(*typeArguments)); > while (true) { > auto typeSuffixNonAbbreviated = backtrackingScope<Expected<TypeSuffixNonAbbreviated, Error>>([&]() { > return parseTypeSuffixNonAbbreviated(); >@@ -542,14 +601,14 @@ auto Parser::parseNonAddressSpaceType() -> Expected<std::unique_ptr<AST::Type>, > return WTFMove(result); > } > >-auto Parser::parseType() -> Expected<std::unique_ptr<AST::Type>, Error> { >- auto type = backtrackingScope<Expected<std::unique_ptr<AST::Type>, Error>>([&]() { >+auto Parser::parseType() -> Expected<UniqueRef<AST::UnnamedType>, Error> { >+ auto type = backtrackingScope<Expected<UniqueRef<AST::UnnamedType>, Error>>([&]() { > return parseAddressSpaceType(); > }); > if (type) > return type; > >- type = backtrackingScope<Expected<std::unique_ptr<AST::Type>, Error>>([&]() { >+ type = backtrackingScope<Expected<UniqueRef<AST::UnnamedType>, Error>>([&]() { > return parseNonAddressSpaceType(); > }); > if (type) >@@ -847,12 +906,12 @@ auto Parser::parseEnumerationDefinition() -> Expected<AST::EnumerationDefinition > if (!name) > return Unexpected<Error>(name.error()); > >- std::unique_ptr<AST::Type> type; >+ std::unique_ptr<AST::UnnamedType> type; > if (tryType(Lexer::Token::Type::Colon)) { > auto parsedType = parseType(); > if (!parsedType) > return Unexpected<Error>(parsedType.error()); >- type = WTFMove(*parsedType); >+ type = parsedType->takeUniquePtr(); > } > > auto leftCurlyBracket = consumeType(Lexer::Token::Type::LeftCurlyBracket); >@@ -863,21 +922,25 @@ auto Parser::parseEnumerationDefinition() -> Expected<AST::EnumerationDefinition > if (!firstEnumerationMember) > return Unexpected<Error>(firstEnumerationMember.error()); > >- AST::EnumerationMembers members; >- members.append(WTFMove(*firstEnumerationMember)); >+ AST::EnumerationDefinition result(WTFMove(*origin), name->stringView.toString(), WTFMove(type)); >+ auto success = result.add(WTFMove(*firstEnumerationMember)); >+ if (!success) >+ return fail(String("Cannot add enumeration member", String::ConstructFromLiteral)); > > while (tryType(Lexer::Token::Type::Comma)) { > auto member = parseEnumerationMember(); > if (!member) > return Unexpected<Error>(member.error()); >- members.append(WTFMove(*member)); >+ success = result.add(WTFMove(*member)); >+ if (!success) >+ return fail(String("Cannot add enumeration member", String::ConstructFromLiteral)); > } > > auto rightCurlyBracket = consumeType(Lexer::Token::Type::RightCurlyBracket); > if (!rightCurlyBracket) > return Unexpected<Error>(rightCurlyBracket.error()); > >- return AST::EnumerationDefinition(WTFMove(*origin), name->stringView.toString(), WTFMove(type), WTFMove(members)); >+ return WTFMove(result); > } > > auto Parser::parseEnumerationMember() -> Expected<AST::EnumerationMember, Error> { >@@ -981,7 +1044,7 @@ auto Parser::parseAttributeBlock() -> Expected<AST::AttributeBlock, Error> { > return WTFMove(result); > } > >-auto Parser::parseParameter() -> Expected<AST::Parameter, Error> { >+auto Parser::parseParameter() -> Expected<AST::VariableDeclaration, Error> { > auto origin = peek(); > if (!origin) > return Unexpected<Error>(origin.error()); >@@ -992,7 +1055,7 @@ auto Parser::parseParameter() -> Expected<AST::Parameter, Error> { > if (!type) > return Unexpected<Error>(type.error()); > >- Optional<String> name; >+ String name; > if (auto token = tryType(Lexer::Token::Type::Identifier)) > name = token->stringView.toString(); > >@@ -1000,18 +1063,18 @@ auto Parser::parseParameter() -> Expected<AST::Parameter, Error> { > auto semantic = parseSemantic(); > if (!semantic) > return Unexpected<Error>(semantic.error()); >- return AST::Parameter(WTFMove(*origin), WTFMove(qualifiers), WTFMove(*type), WTFMove(name), WTFMove(*semantic)); >+ return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), type->takeUniquePtr(), WTFMove(name), WTFMove(*semantic), nullptr); > } > >- return AST::Parameter(WTFMove(*origin), WTFMove(qualifiers), WTFMove(*type), WTFMove(name), WTF::nullopt); >+ return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), type->takeUniquePtr(), WTFMove(name), WTF::nullopt, nullptr); > } > >-auto Parser::parseParameters() -> Expected<AST::Parameters, Error> { >+auto Parser::parseParameters() -> Expected<AST::VariableDeclarations, Error> { > auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis); > if (!leftParenthesis) > return Unexpected<Error>(leftParenthesis.error()); > >- AST::Parameters parameters; >+ AST::VariableDeclarations parameters; > if (tryType(Lexer::Token::Type::RightParenthesis)) > return WTFMove(parameters); > >@@ -1095,14 +1158,16 @@ auto Parser::parseEntryPointFunctionDeclaration() -> Expected<AST::FunctionDecla > if (!parameters) > return Unexpected<Error>(parameters.error()); > >+ bool isOperator = false; >+ > if (tryType(Lexer::Token::Type::Colon)) { > auto semantic = parseSemantic(); > if (!semantic) > return Unexpected<Error>(semantic.error()); >- return AST::FunctionDeclaration(WTFMove(*origin), WTFMove(attributeBlock), entryPointType, WTFMove(*type), name->stringView.toString(), WTFMove(*parameters), WTFMove(*semantic)); >+ return AST::FunctionDeclaration(WTFMove(*origin), WTFMove(attributeBlock), entryPointType, WTFMove(*type), name->stringView.toString(), WTFMove(*parameters), WTFMove(*semantic), isOperator); > } > >- return AST::FunctionDeclaration(WTFMove(*origin), WTFMove(attributeBlock), entryPointType, WTFMove(*type), name->stringView.toString(), WTFMove(*parameters), WTF::nullopt); >+ return AST::FunctionDeclaration(WTFMove(*origin), WTFMove(attributeBlock), entryPointType, WTFMove(*type), name->stringView.toString(), WTFMove(*parameters), WTF::nullopt, isOperator); > } > > auto Parser::parseRegularFunctionDeclaration() -> Expected<AST::FunctionDeclaration, Error> { >@@ -1117,6 +1182,7 @@ auto Parser::parseRegularFunctionDeclaration() -> Expected<AST::FunctionDeclarat > auto name = consumeTypes({ Lexer::Token::Type::Identifier, Lexer::Token::Type::OperatorName }); > if (!name) > return Unexpected<Error>(name.error()); >+ auto isOperator = name->type == Lexer::Token::Type::OperatorName; > > auto parameters = parseParameters(); > if (!parameters) >@@ -1126,10 +1192,10 @@ auto Parser::parseRegularFunctionDeclaration() -> Expected<AST::FunctionDeclarat > auto semantic = parseSemantic(); > if (!semantic) > return Unexpected<Error>(semantic.error()); >- return AST::FunctionDeclaration(WTFMove(*origin), { }, WTF::nullopt, WTFMove(*type), name->stringView.toString(), WTFMove(*parameters), WTFMove(*semantic)); >+ return AST::FunctionDeclaration(WTFMove(*origin), { }, WTF::nullopt, WTFMove(*type), name->stringView.toString(), WTFMove(*parameters), WTFMove(*semantic), isOperator); > } > >- return AST::FunctionDeclaration(WTFMove(*origin), { }, WTF::nullopt, WTFMove(*type), name->stringView.toString(), WTFMove(*parameters), WTF::nullopt); >+ return AST::FunctionDeclaration(WTFMove(*origin), { }, WTF::nullopt, WTFMove(*type), name->stringView.toString(), WTFMove(*parameters), WTF::nullopt, isOperator); > } > > auto Parser::parseOperatorFunctionDeclaration() -> Expected<AST::FunctionDeclaration, Error> { >@@ -1145,14 +1211,16 @@ auto Parser::parseOperatorFunctionDeclaration() -> Expected<AST::FunctionDeclara > if (!parameters) > return Unexpected<Error>(parameters.error()); > >+ bool isOperator = true; >+ > if (tryType(Lexer::Token::Type::Colon)) { > auto semantic = parseSemantic(); > if (!semantic) > return Unexpected<Error>(semantic.error()); >- return AST::FunctionDeclaration(WTFMove(*origin), { }, WTF::nullopt, WTFMove(*type), String("Operator Cast", String::ConstructFromLiteral), WTFMove(*parameters), WTFMove(*semantic)); >+ return AST::FunctionDeclaration(WTFMove(*origin), { }, WTF::nullopt, WTFMove(*type), String("operator cast", String::ConstructFromLiteral), WTFMove(*parameters), WTFMove(*semantic), isOperator); > } > >- return AST::FunctionDeclaration(WTFMove(*origin), { }, WTF::nullopt, WTFMove(*type), String("Operator Cast", String::ConstructFromLiteral), WTFMove(*parameters), WTF::nullopt); >+ return AST::FunctionDeclaration(WTFMove(*origin), { }, WTF::nullopt, WTFMove(*type), String("operator cast", String::ConstructFromLiteral), WTFMove(*parameters), WTF::nullopt, isOperator); > } > > auto Parser::parseFunctionDeclaration() -> Expected<AST::FunctionDeclaration, Error> { >@@ -1200,7 +1268,7 @@ auto Parser::parseNativeFunctionDeclaration() -> Expected<AST::NativeFunctionDec > if (!semicolon) > return Unexpected<Error>(semicolon.error()); > >- return AST::NativeFunctionDeclaration(functionDeclaration->takeOrigin(), functionDeclaration->takeAttributeBlock(), functionDeclaration->takeEntryPointType(), functionDeclaration->takeType(), functionDeclaration->takeName(), functionDeclaration->takeParameters(), functionDeclaration->takeSemantic(), restricted); >+ return AST::NativeFunctionDeclaration(WTFMove(*functionDeclaration), restricted); > } > > auto Parser::parseBlock() -> Expected<AST::Block, Error> { >@@ -1221,7 +1289,7 @@ AST::Block Parser::parseBlockBody(Lexer::Token&& origin) > { > AST::Statements statements; > while (true) { >- auto statement = backtrackingScope<Expected<std::unique_ptr<AST::Statement>, Error>>([&]() { >+ auto statement = backtrackingScope<Expected<UniqueRef<AST::Statement>, Error>>([&]() { > return parseStatement(); > }); > if (statement) >@@ -1258,10 +1326,13 @@ auto Parser::parseIfStatement() -> Expected<AST::IfStatement, Error> { > auto parsedElseBody = parseStatement(); > if (!parsedElseBody) > return Unexpected<Error>(parsedElseBody.error()); >- elseBody = WTFMove(*parsedElseBody); >+ elseBody = parsedElseBody->takeUniquePtr(); > } > >- return AST::IfStatement(WTFMove(*origin), WTFMove(*conditional), WTFMove(*body), WTFMove(elseBody)); >+ Vector<std::unique_ptr<AST::Expression>> castArguments; >+ castArguments.append(WTFMove(*conditional)); >+ auto boolCast = makeUniqueRef<AST::CallExpression>(Lexer::Token(*origin), String("bool", String::ConstructFromLiteral), WTFMove(castArguments)); >+ return AST::IfStatement(WTFMove(*origin), WTFMove(boolCast), WTFMove(*body), WTFMove(elseBody)); > } > > auto Parser::parseSwitchStatement() -> Expected<AST::SwitchStatement, Error> { >@@ -1342,14 +1413,14 @@ auto Parser::parseForLoop() -> Expected<AST::ForLoop, Error> { > if (!origin) > return Unexpected<Error>(origin.error()); > >- auto parseRemainder = [&](Variant<AST::VariableDeclarationsStatement, std::unique_ptr<AST::Expression>>&& initialization) -> Expected<AST::ForLoop, Error> { >+ auto parseRemainder = [&](Variant<AST::VariableDeclarationsStatement, UniqueRef<AST::Expression>>&& initialization) -> Expected<AST::ForLoop, Error> { > auto semicolon = consumeType(Lexer::Token::Type::Semicolon); > if (!semicolon) > return Unexpected<Error>(semicolon.error()); > > auto condition = backtrackingScope<std::unique_ptr<AST::Expression>>([&]() -> std::unique_ptr<AST::Expression> { > if (auto expression = parseExpression()) >- return WTFMove(*expression); >+ return expression->takeUniquePtr(); > return nullptr; > }); > >@@ -1359,7 +1430,7 @@ auto Parser::parseForLoop() -> Expected<AST::ForLoop, Error> { > > auto increment = backtrackingScope<std::unique_ptr<AST::Expression>>([&]() -> std::unique_ptr<AST::Expression> { > if (auto expression = parseExpression()) >- return WTFMove(*expression); >+ return expression->takeUniquePtr(); > return nullptr; > }); > >@@ -1443,7 +1514,7 @@ auto Parser::parseDoWhileLoop() -> Expected<AST::DoWhileLoop, Error> { > return AST::DoWhileLoop(WTFMove(*origin), WTFMove(*body), WTFMove(*conditional)); > } > >-auto Parser::parseVariableDeclaration(std::unique_ptr<AST::Type>&& type) -> Expected<AST::VariableDeclaration, Error> { >+auto Parser::parseVariableDeclaration(UniqueRef<AST::UnnamedType>&& type) -> Expected<AST::VariableDeclaration, Error> { > auto origin = peek(); > if (!origin) > return Unexpected<Error>(origin.error()); >@@ -1463,20 +1534,20 @@ auto Parser::parseVariableDeclaration(std::unique_ptr<AST::Type>&& type) -> Expe > auto initializer = parseExpression(); > if (!initializer) > return Unexpected<Error>(initializer.error()); >- return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), WTFMove(type), name->stringView.toString(), WTFMove(*semantic), WTFMove(*initializer)); >+ return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), type.takeUniquePtr(), name->stringView.toString(), WTFMove(*semantic), initializer->takeUniquePtr()); > } > >- return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), WTFMove(type), name->stringView.toString(), WTFMove(*semantic), nullptr); >+ return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), type.takeUniquePtr(), name->stringView.toString(), WTFMove(*semantic), nullptr); > } > > if (tryType(Lexer::Token::Type::EqualsSign)) { > auto initializer = parseExpression(); > if (!initializer) > return Unexpected<Error>(initializer.error()); >- return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), WTFMove(type), name->stringView.toString(), WTF::nullopt, WTFMove(*initializer)); >+ return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), type.takeUniquePtr(), name->stringView.toString(), WTF::nullopt, initializer->takeUniquePtr()); > } > >- return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), WTFMove(type), name->stringView.toString(), WTF::nullopt, nullptr); >+ return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), type.takeUniquePtr(), name->stringView.toString(), WTF::nullopt, nullptr); > } > > auto Parser::parseVariableDeclarations() -> Expected<AST::VariableDeclarationsStatement, Error> { >@@ -1488,7 +1559,7 @@ auto Parser::parseVariableDeclarations() -> Expected<AST::VariableDeclarationsSt > if (!type) > return Unexpected<Error>(type.error()); > >- auto firstVariableDeclaration = parseVariableDeclaration(std::unique_ptr<AST::Type>((*type)->clone())); >+ auto firstVariableDeclaration = parseVariableDeclaration((*type)->clone()); > if (!firstVariableDeclaration) > return Unexpected<Error>(firstVariableDeclaration.error()); > >@@ -1496,7 +1567,7 @@ auto Parser::parseVariableDeclarations() -> Expected<AST::VariableDeclarationsSt > result.append(WTFMove(*firstVariableDeclaration)); > > while (tryType(Lexer::Token::Type::Comma)) { >- auto variableDeclaration = parseVariableDeclaration(std::unique_ptr<AST::Type>((*type)->clone())); >+ auto variableDeclaration = parseVariableDeclaration((*type)->clone()); > if (!variableDeclaration) > return Unexpected<Error>(variableDeclaration.error()); > result.append(WTFMove(*variableDeclaration)); >@@ -1505,13 +1576,13 @@ auto Parser::parseVariableDeclarations() -> Expected<AST::VariableDeclarationsSt > return AST::VariableDeclarationsStatement(WTFMove(*origin), WTFMove(result)); > } > >-auto Parser::parseStatement() -> Expected<std::unique_ptr<AST::Statement>, Error> { >+auto Parser::parseStatement() -> Expected<UniqueRef<AST::Statement>, Error> { > { > auto block = backtrackingScope<Expected<AST::Block, Error>>([&]() { > return parseBlock(); > }); > if (block) >- return std::unique_ptr<AST::Statement>(std::make_unique<AST::Block>(WTFMove(*block))); >+ return { makeUniqueRef<AST::Block>(WTFMove(*block)) }; > } > > { >@@ -1519,7 +1590,7 @@ auto Parser::parseStatement() -> Expected<std::unique_ptr<AST::Statement>, Error > return parseIfStatement(); > }); > if (ifStatement) >- return std::unique_ptr<AST::Statement>(std::make_unique<AST::IfStatement>(WTFMove(*ifStatement))); >+ return { makeUniqueRef<AST::IfStatement>(WTFMove(*ifStatement)) }; > } > > { >@@ -1527,7 +1598,7 @@ auto Parser::parseStatement() -> Expected<std::unique_ptr<AST::Statement>, Error > return parseSwitchStatement(); > }); > if (switchStatement) >- return std::unique_ptr<AST::Statement>(std::make_unique<AST::SwitchStatement>(WTFMove(*switchStatement))); >+ return { makeUniqueRef<AST::SwitchStatement>(WTFMove(*switchStatement)) }; > } > > { >@@ -1535,7 +1606,7 @@ auto Parser::parseStatement() -> Expected<std::unique_ptr<AST::Statement>, Error > return parseForLoop(); > }); > if (forLoop) >- return std::unique_ptr<AST::Statement>(std::make_unique<AST::ForLoop>(WTFMove(*forLoop))); >+ return { makeUniqueRef<AST::ForLoop>(WTFMove(*forLoop)) }; > } > > { >@@ -1543,7 +1614,7 @@ auto Parser::parseStatement() -> Expected<std::unique_ptr<AST::Statement>, Error > return parseWhileLoop(); > }); > if (whileLoop) >- return std::unique_ptr<AST::Statement>(std::make_unique<AST::WhileLoop>(WTFMove(*whileLoop))); >+ return { makeUniqueRef<AST::WhileLoop>(WTFMove(*whileLoop)) }; > } > > { >@@ -1559,7 +1630,7 @@ auto Parser::parseStatement() -> Expected<std::unique_ptr<AST::Statement>, Error > return result; > }); > if (doWhileLoop) >- return std::unique_ptr<AST::Statement>(std::make_unique<AST::DoWhileLoop>(WTFMove(*doWhileLoop))); >+ return { makeUniqueRef<AST::DoWhileLoop>(WTFMove(*doWhileLoop)) }; > } > > { >@@ -1575,7 +1646,7 @@ auto Parser::parseStatement() -> Expected<std::unique_ptr<AST::Statement>, Error > return AST::Break(WTFMove(*origin)); > }); > if (breakObject) >- return std::unique_ptr<AST::Statement>(std::make_unique<AST::Break>(WTFMove(*breakObject))); >+ return { makeUniqueRef<AST::Break>(WTFMove(*breakObject)) }; > } > > { >@@ -1591,7 +1662,7 @@ auto Parser::parseStatement() -> Expected<std::unique_ptr<AST::Statement>, Error > return AST::Continue(WTFMove(*origin)); > }); > if (continueObject) >- return std::unique_ptr<AST::Statement>(std::make_unique<AST::Continue>(WTFMove(*continueObject))); >+ return { makeUniqueRef<AST::Continue>(WTFMove(*continueObject)) }; > } > > { >@@ -1607,7 +1678,7 @@ auto Parser::parseStatement() -> Expected<std::unique_ptr<AST::Statement>, Error > return AST::Fallthrough(WTFMove(*origin)); > }); > if (fallthroughObject) >- return std::unique_ptr<AST::Statement>(std::make_unique<AST::Fallthrough>(WTFMove(*fallthroughObject))); >+ return { makeUniqueRef<AST::Fallthrough>(WTFMove(*fallthroughObject)) }; > } > > { >@@ -1623,7 +1694,7 @@ auto Parser::parseStatement() -> Expected<std::unique_ptr<AST::Statement>, Error > return AST::Trap(WTFMove(*origin)); > }); > if (trapObject) >- return std::unique_ptr<AST::Statement>(std::make_unique<AST::Trap>(WTFMove(*trapObject))); >+ return { makeUniqueRef<AST::Trap>(WTFMove(*trapObject)) }; > } > > { >@@ -1643,10 +1714,10 @@ auto Parser::parseStatement() -> Expected<std::unique_ptr<AST::Statement>, Error > if (!semicolon) > return Unexpected<Error>(semicolon.error()); > >- return AST::Return(WTFMove(*origin), WTFMove(*expression)); >+ return AST::Return(WTFMove(*origin), expression->takeUniquePtr()); > }); > if (returnObject) >- return std::unique_ptr<AST::Statement>(std::make_unique<AST::Return>(WTFMove(*returnObject))); >+ return { makeUniqueRef<AST::Return>(WTFMove(*returnObject)) }; > } > > { >@@ -1662,10 +1733,10 @@ auto Parser::parseStatement() -> Expected<std::unique_ptr<AST::Statement>, Error > return result; > }); > if (variableDeclarations) >- return std::unique_ptr<AST::Statement>(std::make_unique<AST::VariableDeclarationsStatement>(WTFMove(*variableDeclarations))); >+ return { makeUniqueRef<AST::VariableDeclarationsStatement>(WTFMove(*variableDeclarations)) }; > } > >- auto effectfulExpression = backtrackingScope<Expected<std::unique_ptr<AST::Expression>, Error>>([&]() -> Expected<std::unique_ptr<AST::Expression>, Error> { >+ auto effectfulExpression = backtrackingScope<Expected<std::unique_ptr<AST::Expression>, Error>>([&]() -> Expected<UniqueRef<AST::Expression>, Error> { > auto result = parseEffectfulExpression(); > if (!result) > return Unexpected<Error>(result.error()); >@@ -1677,12 +1748,12 @@ auto Parser::parseStatement() -> Expected<std::unique_ptr<AST::Statement>, Error > return result; > }); > if (effectfulExpression) >- return std::unique_ptr<AST::Statement>(std::make_unique<AST::EffectfulExpressionStatement>(WTFMove(*effectfulExpression))); >+ return { makeUniqueRef<AST::EffectfulExpressionStatement>(WTFMove(*effectfulExpression)) }; > > return Unexpected<Error>(effectfulExpression.error()); > } > >-auto Parser::parseEffectfulExpression() -> Expected<std::unique_ptr<AST::Expression>, Error> { >+auto Parser::parseEffectfulExpression() -> Expected<UniqueRef<AST::Expression>, Error> { > auto origin = peek(); > if (!origin) > return Unexpected<Error>(origin.error()); >@@ -1693,7 +1764,7 @@ auto Parser::parseEffectfulExpression() -> Expected<std::unique_ptr<AST::Express > auto effectfulExpression = parseEffectfulAssignment(); > if (!effectfulExpression) > return nullptr; >- return WTFMove(*effectfulExpression); >+ return effectfulExpression->takeUniquePtr(); > }); > if (!first) > return std::unique_ptr<AST::Expression>(std::make_unique<AST::CommaExpression>(WTFMove(*origin), WTFMove(expressions))); >@@ -1713,19 +1784,19 @@ auto Parser::parseEffectfulExpression() -> Expected<std::unique_ptr<AST::Express > } > > auto Parser::parseEffectfulAssignment() -> Expected<std::unique_ptr<AST::Expression>, Error> { >- auto assignment = backtrackingScope<Expected<std::unique_ptr<AST::Expression>, Error>>([&]() { >+ auto assignment = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() { > return parseAssignment(); > }); > if (assignment) > return assignment; > >- assignment = backtrackingScope<Expected<std::unique_ptr<AST::Expression>, Error>>([&]() { >+ assignment = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() { > return parseEffectfulPrefix(); > }); > if (assignment) > return assignment; > >- assignment = backtrackingScope<Expected<std::unique_ptr<AST::Expression>, Error>>([&]() { >+ assignment = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() { > return parseCallExpression(); > }); > if (assignment) >@@ -1734,7 +1805,7 @@ auto Parser::parseEffectfulAssignment() -> Expected<std::unique_ptr<AST::Express > return Unexpected<Error>(assignment.error()); > } > >-auto Parser::parseEffectfulPrefix() -> Expected<std::unique_ptr<AST::Expression>, Error> { >+auto Parser::parseEffectfulPrefix() -> Expected<UniqueRef<AST::Expression>, Error> { > auto prefix = consumeTypes({ Lexer::Token::Type::PlusPlus, Lexer::Token::Type::MinusMinus }); > if (!prefix) > return Unexpected<Error>(prefix.error()); >@@ -1748,7 +1819,7 @@ auto Parser::parseEffectfulPrefix() -> Expected<std::unique_ptr<AST::Expression> > auto result = std::make_unique<AST::ReadModifyWriteExpression>(Lexer::Token(*prefix), WTFMove(*previous)); > Vector<std::unique_ptr<AST::Expression>> callArguments; > callArguments.append(result->oldVariableReference()); >- result->setNewValueExpression(std::make_unique<AST::CallExpression>(WTFMove(*prefix), String("operator++", String::ConstructFromLiteral), WTFMove(callArguments))); >+ result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(WTFMove(*prefix), String("operator++", String::ConstructFromLiteral), WTFMove(callArguments))); > result->setResultExpression(result->newVariableReference()); > return std::unique_ptr<AST::Expression>(WTFMove(result)); > } >@@ -1756,7 +1827,7 @@ auto Parser::parseEffectfulPrefix() -> Expected<std::unique_ptr<AST::Expression> > auto result = std::make_unique<AST::ReadModifyWriteExpression>(Lexer::Token(*prefix), WTFMove(*previous)); > Vector<std::unique_ptr<AST::Expression>> callArguments; > callArguments.append(result->oldVariableReference()); >- result->setNewValueExpression(std::make_unique<AST::CallExpression>(WTFMove(*prefix), String("operator--", String::ConstructFromLiteral), WTFMove(callArguments))); >+ result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(WTFMove(*prefix), String("operator--", String::ConstructFromLiteral), WTFMove(callArguments))); > result->setResultExpression(result->newVariableReference()); > return std::unique_ptr<AST::Expression>(WTFMove(result)); > } >@@ -1766,7 +1837,7 @@ auto Parser::parseEffectfulPrefix() -> Expected<std::unique_ptr<AST::Expression> > } > } > >-auto Parser::parseEffectfulSuffix() -> Expected<std::unique_ptr<AST::Expression>, Error> { >+auto Parser::parseEffectfulSuffix() -> Expected<UniqueRef<AST::Expression>, Error> { > auto effectfulSuffix = backtrackingScope<Expected<std::unique_ptr<AST::Expression>, Error>>([&]() -> Expected<std::unique_ptr<AST::Expression>, Error> { > auto previous = parsePossibleSuffix(); > if (!previous) >@@ -1781,7 +1852,7 @@ auto Parser::parseEffectfulSuffix() -> Expected<std::unique_ptr<AST::Expression> > auto result = std::make_unique<AST::ReadModifyWriteExpression>(Lexer::Token(*suffix), WTFMove(*previous)); > Vector<std::unique_ptr<AST::Expression>> callArguments; > callArguments.append(result->oldVariableReference()); >- result->setNewValueExpression(std::make_unique<AST::CallExpression>(WTFMove(*suffix), String("operator++", String::ConstructFromLiteral), WTFMove(callArguments))); >+ result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(WTFMove(*suffix), String("operator++", String::ConstructFromLiteral), WTFMove(callArguments))); > result->setResultExpression(result->oldVariableReference()); > return std::unique_ptr<AST::Expression>(WTFMove(result)); > } >@@ -1789,7 +1860,7 @@ auto Parser::parseEffectfulSuffix() -> Expected<std::unique_ptr<AST::Expression> > auto result = std::make_unique<AST::ReadModifyWriteExpression>(Lexer::Token(*suffix), WTFMove(*previous)); > Vector<std::unique_ptr<AST::Expression>> callArguments; > callArguments.append(result->oldVariableReference()); >- result->setNewValueExpression(std::make_unique<AST::CallExpression>(WTFMove(*suffix), String("operator--", String::ConstructFromLiteral), WTFMove(callArguments))); >+ result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(WTFMove(*suffix), String("operator--", String::ConstructFromLiteral), WTFMove(callArguments))); > result->setResultExpression(result->oldVariableReference()); > return std::unique_ptr<AST::Expression>(WTFMove(result)); > } >@@ -1801,7 +1872,7 @@ auto Parser::parseEffectfulSuffix() -> Expected<std::unique_ptr<AST::Expression> > if (effectfulSuffix) > return effectfulSuffix; > >- effectfulSuffix = backtrackingScope<Expected<std::unique_ptr<AST::Expression>, Error>>([&]() { >+ effectfulSuffix = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() { > return parseCallExpression(); > }); > if (effectfulSuffix) >@@ -1820,7 +1891,7 @@ auto Parser::parseEffectfulSuffix() -> Expected<std::unique_ptr<AST::Expression> > if (!rightParenthesis) > return Unexpected<Error>(rightParenthesis.error()); > >- return std::unique_ptr<AST::Expression>(WTFMove(*expression)); >+ return { WTFMove(*expression) }; > }); > if (effectfulSuffix) > return effectfulSuffix; >@@ -1892,7 +1963,7 @@ auto Parser::parseSuffixOperator(std::unique_ptr<AST::Expression>&& previous) -> > auto result = std::make_unique<AST::ReadModifyWriteExpression>(Lexer::Token(*suffix), WTFMove(previous)); > Vector<std::unique_ptr<AST::Expression>> callArguments; > callArguments.append(result->oldVariableReference()); >- result->setNewValueExpression(std::make_unique<AST::CallExpression>(WTFMove(*suffix), String("operator++", String::ConstructFromLiteral), WTFMove(callArguments))); >+ result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(WTFMove(*suffix), String("operator++", String::ConstructFromLiteral), WTFMove(callArguments))); > result->setResultExpression(result->oldVariableReference()); > return SuffixExpression(WTFMove(result), true); > } >@@ -1900,7 +1971,7 @@ auto Parser::parseSuffixOperator(std::unique_ptr<AST::Expression>&& previous) -> > auto result = std::make_unique<AST::ReadModifyWriteExpression>(Lexer::Token(*suffix), WTFMove(previous)); > Vector<std::unique_ptr<AST::Expression>> callArguments; > callArguments.append(result->oldVariableReference()); >- result->setNewValueExpression(std::make_unique<AST::CallExpression>(WTFMove(*suffix), String("operator--", String::ConstructFromLiteral), WTFMove(callArguments))); >+ result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(WTFMove(*suffix), String("operator--", String::ConstructFromLiteral), WTFMove(callArguments))); > result->setResultExpression(result->oldVariableReference()); > return SuffixExpression(WTFMove(result), true); > } >@@ -1910,7 +1981,7 @@ auto Parser::parseSuffixOperator(std::unique_ptr<AST::Expression>&& previous) -> > } > } > >-auto Parser::parseExpression() -> Expected<std::unique_ptr<AST::Expression>, Error> { >+auto Parser::parseExpression() -> Expected<UniqueRef<AST::Expression>, Error> { > auto origin = peek(); > if (!origin) > return Unexpected<Error>(origin.error()); >@@ -1934,7 +2005,7 @@ auto Parser::parseExpression() -> Expected<std::unique_ptr<AST::Expression>, Err > return std::unique_ptr<AST::Expression>(std::make_unique<AST::CommaExpression>(WTFMove(*origin), WTFMove(expressions))); > } > >-auto Parser::parseTernaryConditional() -> Expected<std::unique_ptr<AST::Expression>, Error> { >+auto Parser::parseTernaryConditional() -> Expected<UniqueRef<AST::Expression>, Error> { > auto origin = peek(); > if (!origin) > return Unexpected<Error>(origin.error()); >@@ -1959,8 +2030,10 @@ auto Parser::parseTernaryConditional() -> Expected<std::unique_ptr<AST::Expressi > if (!elseExpression) > return Unexpected<Error>(elseExpression.error()); > >- // FIXME: Cast the predicate to a bool. >- return std::unique_ptr<AST::Expression>(std::make_unique<AST::TernaryExpression>(WTFMove(*origin), WTFMove(*predicate), WTFMove(*bodyExpression), WTFMove(*elseExpression))); >+ Vector<std::unique_ptr<AST::Expression>> castArguments; >+ castArguments.append(WTFMove(*predicate)); >+ auto boolCast = std::make_unique<AST::CallExpression>(Lexer::Token(*origin), String("bool", String::ConstructFromLiteral), WTFMove(castArguments)); >+ return std::unique_ptr<AST::Expression>(std::make_unique<AST::TernaryExpression>(WTFMove(*origin), WTFMove(boolCast), WTFMove(*bodyExpression), WTFMove(*elseExpression))); > } > > auto Parser::parseAssignment() -> Expected<std::unique_ptr<AST::Expression>, Error> { >@@ -2178,7 +2251,6 @@ auto Parser::parsePossibleRelationalBinaryOperation() -> Expected<std::unique_pt > callArguments.append(WTFMove(previous)); > callArguments.append(WTFMove(*next)); > previous = std::make_unique<AST::CallExpression>(Lexer::Token(*relationalBinaryOperation), String("operator==", String::ConstructFromLiteral), WTFMove(callArguments)); >- // FIXME: Cast the argument to a bool > previous = std::make_unique<AST::LogicalNotExpression>(WTFMove(*relationalBinaryOperation), WTFMove(previous)); > break; > } >@@ -2364,8 +2436,12 @@ auto Parser::parsePossiblePrefix() -> Expected<std::unique_ptr<AST::Expression>, > callArguments.append(WTFMove(*next)); > return std::unique_ptr<AST::Expression>(std::make_unique<AST::CallExpression>(Lexer::Token(*prefix), String("operator~", String::ConstructFromLiteral), WTFMove(callArguments))); > } >- case Lexer::Token::Type::ExclamationPoint: >- return std::unique_ptr<AST::Expression>(std::make_unique<AST::LogicalNotExpression>(Lexer::Token(*prefix), WTFMove(*next))); >+ case Lexer::Token::Type::ExclamationPoint: { >+ Vector<std::unique_ptr<AST::Expression>> castArguments; >+ castArguments.append(WTFMove(*next)); >+ auto boolCast = std::make_unique<AST::CallExpression>(Lexer::Token(*prefix), String("bool", String::ConstructFromLiteral), WTFMove(castArguments)); >+ return std::unique_ptr<AST::Expression>(std::make_unique<AST::LogicalNotExpression>(Lexer::Token(*prefix), WTFMove(boolCast))); >+ } > case Lexer::Token::Type::And: > return std::unique_ptr<AST::Expression>(std::make_unique<AST::MakePointerExpression>(Lexer::Token(*prefix), WTFMove(*next))); > case Lexer::Token::Type::At: >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.h >index da3e06b01e4..e0480d18834 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.h >@@ -27,7 +27,6 @@ > > #if ENABLE(WEBGPU) > >-#include "WHLSLAnonymousVariableDeclaration.h" > #include "WHLSLArrayReferenceType.h" > #include "WHLSLArrayType.h" > #include "WHLSLAssignmentExpression.h" >@@ -68,7 +67,6 @@ > #include "WHLSLNode.h" > #include "WHLSLNullLiteral.h" > #include "WHLSLNumThreadsFunctionAttribute.h" >-#include "WHLSLParameter.h" > #include "WHLSLPointerType.h" > #include "WHLSLProgram.h" > #include "WHLSLPropertyAccessExpression.h" >@@ -154,13 +152,13 @@ private: > Expected<TypeSuffixAbbreviated, Error> parseTypeSuffixAbbreviated(); > struct TypeSuffixNonAbbreviated { > Lexer::Token token; >- Optional<Lexer::Token> addressSpace; >+ Optional<AST::ReferenceType::AddressSpace> addressSpace; > Optional<unsigned> numElements; > }; > Expected<TypeSuffixNonAbbreviated, Error> parseTypeSuffixNonAbbreviated(); >- Expected<std::unique_ptr<AST::Type>, Error> parseAddressSpaceType(); >- Expected<std::unique_ptr<AST::Type>, Error> parseNonAddressSpaceType(); >- Expected<std::unique_ptr<AST::Type>, Error> parseType(); >+ Expected<UniqueRef<AST::UnnamedType>, Error> parseAddressSpaceType(); >+ Expected<UniqueRef<AST::UnnamedType>, Error> parseNonAddressSpaceType(); >+ Expected<UniqueRef<AST::UnnamedType>, Error> parseType(); > Expected<AST::TypeDefinition, Error> parseTypeDefinition(); > Expected<AST::BuiltInSemantic, Error> parseBuiltInSemantic(); > Expected<AST::ResourceSemantic, Error> parseResourceSemantic(); >@@ -175,8 +173,8 @@ private: > Expected<AST::NativeTypeDeclaration, Error> parseNativeTypeDeclaration(); > Expected<AST::NumThreadsFunctionAttribute, Error> parseNumThreadsFunctionAttribute(); > Expected<AST::AttributeBlock, Error> parseAttributeBlock(); >- Expected<AST::Parameter, Error> parseParameter(); >- Expected<AST::Parameters, Error> parseParameters(); >+ Expected<AST::VariableDeclaration, Error> parseParameter(); >+ Expected<AST::VariableDeclarations, Error> parseParameters(); > Expected<AST::FunctionDeclaration, Error> parseEntryPointFunctionDeclaration(); > Expected<AST::FunctionDeclaration, Error> parseRegularFunctionDeclaration(); > Expected<AST::FunctionDeclaration, Error> parseOperatorFunctionDeclaration(); >@@ -192,14 +190,14 @@ private: > Expected<AST::ForLoop, Error> parseForLoop(); > Expected<AST::WhileLoop, Error> parseWhileLoop(); > Expected<AST::DoWhileLoop, Error> parseDoWhileLoop(); >- Expected<AST::VariableDeclaration, Error> parseVariableDeclaration(std::unique_ptr<AST::Type>&&); >+ Expected<AST::VariableDeclaration, Error> parseVariableDeclaration(UniqueRef<AST::UnnamedType>&&); > Expected<AST::VariableDeclarationsStatement, Error> parseVariableDeclarations(); >- Expected<std::unique_ptr<AST::Statement>, Error> parseStatement(); >+ Expected<UniqueRef<AST::Statement>, Error> parseStatement(); > >- Expected<std::unique_ptr<AST::Expression>, Error> parseEffectfulExpression(); >- Expected<std::unique_ptr<AST::Expression>, Error> parseEffectfulAssignment(); >- Expected<std::unique_ptr<AST::Expression>, Error> parseEffectfulPrefix(); >- Expected<std::unique_ptr<AST::Expression>, Error> parseEffectfulSuffix(); >+ Expected<UniqueRef<AST::Expression>, Error> parseEffectfulExpression(); >+ Expected<UniqueRef<AST::Expression>, Error> parseEffectfulAssignment(); >+ Expected<UniqueRef<AST::Expression>, Error> parseEffectfulPrefix(); >+ Expected<UniqueRef<AST::Expression>, Error> parseEffectfulSuffix(); > struct SuffixExpression { > SuffixExpression(std::unique_ptr<AST::Expression>&& result, bool success) > : result(WTFMove(result)) >@@ -214,19 +212,19 @@ private: > SuffixExpression parseLimitedSuffixOperator(std::unique_ptr<AST::Expression>&&); > SuffixExpression parseSuffixOperator(std::unique_ptr<AST::Expression>&&); > >- Expected<std::unique_ptr<AST::Expression>, Error> parseExpression(); >- Expected<std::unique_ptr<AST::Expression>, Error> parseTernaryConditional(); >- Expected<std::unique_ptr<AST::Expression>, Error> parseAssignment(); >- Expected<std::unique_ptr<AST::Expression>, Error> parsePossibleTernaryConditional(); >- Expected<std::unique_ptr<AST::Expression>, Error> parsePossibleLogicalBinaryOperation(); >- Expected<std::unique_ptr<AST::Expression>, Error> parsePossibleRelationalBinaryOperation(); >- Expected<std::unique_ptr<AST::Expression>, Error> parsePossibleShift(); >- Expected<std::unique_ptr<AST::Expression>, Error> parsePossibleAdd(); >- Expected<std::unique_ptr<AST::Expression>, Error> parsePossibleMultiply(); >- Expected<std::unique_ptr<AST::Expression>, Error> parsePossiblePrefix(); >- Expected<std::unique_ptr<AST::Expression>, Error> parsePossibleSuffix(); >- Expected<std::unique_ptr<AST::Expression>, Error> parseCallExpression(); >- Expected<std::unique_ptr<AST::Expression>, Error> parseTerm(); >+ Expected<UniqueRef<AST::Expression>, Error> parseExpression(); >+ Expected<UniqueRef<AST::Expression>, Error> parseTernaryConditional(); >+ Expected<UniqueRef<AST::Expression>, Error> parseAssignment(); >+ Expected<UniqueRef<AST::Expression>, Error> parsePossibleTernaryConditional(); >+ Expected<UniqueRef<AST::Expression>, Error> parsePossibleLogicalBinaryOperation(); >+ Expected<UniqueRef<AST::Expression>, Error> parsePossibleRelationalBinaryOperation(); >+ Expected<UniqueRef<AST::Expression>, Error> parsePossibleShift(); >+ Expected<UniqueRef<AST::Expression>, Error> parsePossibleAdd(); >+ Expected<UniqueRef<AST::Expression>, Error> parsePossibleMultiply(); >+ Expected<UniqueRef<AST::Expression>, Error> parsePossiblePrefix(); >+ Expected<UniqueRef<AST::Expression>, Error> parsePossibleSuffix(); >+ Expected<UniqueRef<AST::Expression>, Error> parseCallExpression(); >+ Expected<UniqueRef<AST::Expression>, Error> parseTerm(); > > Lexer m_lexer; > Mode m_mode; >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp >index 0eb64decd4d..460e946fdda 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp >@@ -28,10 +28,17 @@ > #include "config.h" > #include "WHLSLPrepare.h" > >+#include "WHLSLCheckDuplicateFunctions.h" >+#include "WHLSLChecker.h" > #include "WHLSLNameResolver.h" > #include "WHLSLParser.h" > #include "WHLSLProgram.h" >+#include "WHLSLRecursiveTypeChecker.h" > #include "WHLSLStandardLibrary.h" >+#include "WHLSLSynthesizeArrayOperatorLength.h" >+#include "WHLSLSynthesizeConstructors.h" >+#include "WHLSLSynthesizeEnumerationFunctions.h" >+#include "WHLSLSynthesizeStructureAccessors.h" > > namespace WebCore { > >@@ -50,8 +57,23 @@ Optional<PreparationResult> prepare(StringView source) > if (!success) > return WTF::nullopt; > >- resolveNamesInTypes(program); >+ NameResolver nameResolver(program.nameContext()); >+ if (!resolveNamesInTypes(program, nameResolver)) >+ return WTF::nullopt; >+ if (!checkRecursiveTypes(program)) >+ return WTF::nullopt; >+ synthesizeStructureAccessors(program); >+ synthesizeEnumerationFunctions(program); >+ synthesizeArrayOperatorLength(program); >+ synthesizeConstructors(program); >+ if (!checkDuplicateFunctions(program)) >+ return WTF::nullopt; >+ if (!resolveNamesInFunctions(program, nameResolver)) >+ return WTF::nullopt; >+ > >+ if (check(program)) >+ return WTF::nullopt; > return PreparationResult(); > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLProgram.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLProgram.h >index 5630fe69ee4..60ee479015a 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLProgram.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLProgram.h >@@ -29,6 +29,8 @@ > > #include "WHLSLEnumerationDefinition.h" > #include "WHLSLFunctionDefinition.h" >+#include "WHLSLIntrinsics.h" >+#include "WHLSLNameContext.h" > #include "WHLSLNativeFunctionDeclaration.h" > #include "WHLSLNativeTypeDeclaration.h" > #include "WHLSLStructureDefinition.h" >@@ -44,45 +46,64 @@ public: > Program() = default; > Program(Program&&) = default; > >- void append(AST::TypeDefinition&& typeDefinition) >+ bool append(AST::TypeDefinition&& typeDefinition) > { >- m_typeDefinitions.append(WTFMove(typeDefinition)); >+ m_typeDefinitions.append(std::make_unique<AST::TypeDefinition>(WTFMove(typeDefinition))); >+ return m_nameContext.add(*m_typeDefinitions.last()); > } >- void append(AST::StructureDefinition&& structureDefinition) >+ >+ bool append(AST::StructureDefinition&& structureDefinition) > { >- m_structureDefinitions.append(WTFMove(structureDefinition)); >+ m_structureDefinitions.append(std::make_unique<AST::StructureDefinition>(WTFMove(structureDefinition))); >+ return m_nameContext.add(*m_structureDefinitions.last()); > } >- void append(AST::EnumerationDefinition&& enumerationDefinition) >+ >+ bool append(AST::EnumerationDefinition&& enumerationDefinition) > { >- m_enumerationDefinitions.append(WTFMove(enumerationDefinition)); >+ m_enumerationDefinitions.append(std::make_unique<AST::EnumerationDefinition>(WTFMove(enumerationDefinition))); >+ return m_nameContext.add(*m_enumerationDefinitions.last()); > } >- void append(AST::FunctionDefinition&& functionDefinition) >+ >+ bool append(AST::FunctionDefinition&& functionDefinition) > { >- m_functionDefinitions.append(WTFMove(functionDefinition)); >+ m_functionDefinitions.append(std::make_unique<AST::FunctionDefinition>(WTFMove(functionDefinition))); >+ return m_nameContext.add(*m_functionDefinitions.last()); > } >- void append(AST::NativeFunctionDeclaration&& nativeFunctionDeclaration) >+ >+ bool append(AST::NativeFunctionDeclaration&& nativeFunctionDeclaration) > { >- m_nativeFunctionDeclarations.append(WTFMove(nativeFunctionDeclaration)); >+ m_nativeFunctionDeclarations.append(std::make_unique<AST::NativeFunctionDeclaration>(WTFMove(nativeFunctionDeclaration))); >+ m_intrinsics.add(*m_nativeFunctionDeclarations.last()); >+ return m_nameContext.add(*m_nativeFunctionDeclarations.last()); > } >- void append(AST::NativeTypeDeclaration&& nativeTypeDeclaration) >+ >+ bool append(AST::NativeTypeDeclaration&& nativeTypeDeclaration) > { >- m_nativeTypeDeclarations.append(WTFMove(nativeTypeDeclaration)); >+ m_nativeTypeDeclarations.append(std::make_unique<AST::NativeTypeDeclaration>(WTFMove(nativeTypeDeclaration))); >+ m_intrinsics.add(*m_nativeTypeDeclarations.last()); >+ return m_nameContext.add(*m_nativeTypeDeclarations.last()); > } > >- Vector<AST::TypeDefinition>& typeDefinitions() { return m_typeDefinitions; } >- Vector<AST::StructureDefinition>& structureDefinitions() { return m_structureDefinitions; } >- Vector<AST::EnumerationDefinition>& enumerationDefinitions() { return m_enumerationDefinitions; } >- Vector<AST::FunctionDefinition>& functionDefinitions() { return m_functionDefinitions; } >- Vector<AST::NativeFunctionDeclaration>& nativeFunctionDeclarations() { return m_nativeFunctionDeclarations; } >- Vector<AST::NativeTypeDeclaration>& nativeTypeDeclarations() { return m_nativeTypeDeclarations; } >+ NameContext& nameContext() { return m_nameContext; } >+ Intrinsics& intrinsics() { return m_intrinsics; } >+ Vector<std::unique_ptr<AST::TypeDefinition>>& typeDefinitions() { return m_typeDefinitions; } >+ Vector<std::unique_ptr<AST::StructureDefinition>>& structureDefinitions() { return m_structureDefinitions; } >+ Vector<std::unique_ptr<AST::EnumerationDefinition>>& enumerationDefinitions() { return m_enumerationDefinitions; } >+ const Vector<std::unique_ptr<AST::FunctionDefinition>>& functionDefinitions() const { return m_functionDefinitions; } >+ Vector<std::unique_ptr<AST::FunctionDefinition>>& functionDefinitions() { return m_functionDefinitions; } >+ const Vector<std::unique_ptr<AST::NativeFunctionDeclaration>>& nativeFunctionDeclarations() const { return m_nativeFunctionDeclarations; } >+ Vector<std::unique_ptr<AST::NativeFunctionDeclaration>>& nativeFunctionDeclarations() { return m_nativeFunctionDeclarations; } >+ Vector<std::unique_ptr<AST::NativeTypeDeclaration>>& nativeTypeDeclarations() { return m_nativeTypeDeclarations; } > > private: >- Vector<AST::TypeDefinition> m_typeDefinitions; >- Vector<AST::StructureDefinition> m_structureDefinitions; >- Vector<AST::EnumerationDefinition> m_enumerationDefinitions; >- Vector<AST::FunctionDefinition> m_functionDefinitions; >- Vector<AST::NativeFunctionDeclaration> m_nativeFunctionDeclarations; >- Vector<AST::NativeTypeDeclaration> m_nativeTypeDeclarations; >+ NameContext m_nameContext; >+ Intrinsics m_intrinsics; >+ Vector<std::unique_ptr<AST::TypeDefinition>> m_typeDefinitions; >+ Vector<std::unique_ptr<AST::StructureDefinition>> m_structureDefinitions; >+ Vector<std::unique_ptr<AST::EnumerationDefinition>> m_enumerationDefinitions; >+ Vector<std::unique_ptr<AST::FunctionDefinition>> m_functionDefinitions; >+ Vector<std::unique_ptr<AST::NativeFunctionDeclaration>> m_nativeFunctionDeclarations; >+ Vector<std::unique_ptr<AST::NativeTypeDeclaration>> m_nativeTypeDeclarations; > }; > > } >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLRecursiveTypeChecker.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLRecursiveTypeChecker.cpp >new file mode 100644 >index 00000000000..d6b1b4a9836 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLRecursiveTypeChecker.cpp >@@ -0,0 +1,105 @@ >+/* >+ * 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. >+ */ >+ >+#if ENABLE(WEBGPU) >+ >+#include "config.h" >+#include "WHLSLRecursiveTypeChecker.h" >+ >+#include "WHLSLVisitor.h" >+#include <wtf/HashSet.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+class RecursiveTypeChecker : public Visitor { >+public: >+ ~RecursiveTypeChecker() = default; >+ >+ void visit(AST::TypeDefinition& typeDefinition) override >+ { >+ auto addResult = m_types.add(&typeDefinition); >+ if (addResult.isNewEntry) { >+ setError(); >+ return; >+ } >+ >+ checkErrorAndVisit(typeDefinition); >+ >+ auto success = m_types.remove(&typeDefinition); >+ ASSERT_UNUSED(success, success); >+ } >+ >+ void visit(AST::StructureDefinition& structureDefinition) override >+ { >+ auto addResult = m_types.add(&structureDefinition); >+ if (addResult.isNewEntry) { >+ setError(); >+ return; >+ } >+ >+ checkErrorAndVisit(structureDefinition); >+ >+ auto success = m_types.remove(&structureDefinition); >+ ASSERT_UNUSED(success, success); >+ } >+ >+ void visit(AST::TypeReference& typeReference) override >+ { >+ auto addResult = m_types.add(&typeReference); >+ if (addResult.isNewEntry) { >+ setError(); >+ return; >+ } >+ >+ for (auto& typeArgument : typeReference.typeArguments()) >+ checkErrorAndVisit(typeArgument); >+ checkErrorAndVisit(*typeReference.resolvedType()); >+ >+ auto success = m_types.remove(&typeReference); >+ ASSERT_UNUSED(success, success); >+ } >+ >+ void visit(AST::ReferenceType&) override >+ { >+ } >+ >+private: >+ HashSet<AST::Type*> m_types; >+}; >+ >+bool checkRecursiveTypes(Program& program) >+{ >+ RecursiveTypeChecker recursiveTypeChecker; >+ recursiveTypeChecker.checkErrorAndVisit(program); >+ return recursiveTypeChecker.error(); >+} >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLRecursiveTypeChecker.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLRecursiveTypeChecker.h >new file mode 100644 >index 00000000000..9a3a19dce20 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLRecursiveTypeChecker.h >@@ -0,0 +1,43 @@ >+/* >+ * 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) >+ >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+class Program; >+ >+bool checkRecursiveTypes(Program&); >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLResolveOverloadImpl.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLResolveOverloadImpl.cpp >new file mode 100644 >index 00000000000..ee251c67f05 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLResolveOverloadImpl.cpp >@@ -0,0 +1,114 @@ >+/* >+ * 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. >+ */ >+ >+#if ENABLE(WEBGPU) >+ >+#include "config.h" >+#include "WHLSLResolveOverloadImpl.h" >+ >+#include "WHLSLFunctionDeclaration.h" >+#include "WHLSLFunctionDefinition.h" >+#include "WHLSLInferTypes.h" >+#include <limits> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+static unsigned conversionCost(AST::FunctionDeclaration& candidate, const Vector<std::reference_wrapper<ResolvingType>>& argumentTypes) >+{ >+ unsigned conversionCost = 0; >+ for (size_t i = 0; i < candidate.parameters().size(); ++i) { >+ conversionCost += WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>&) -> unsigned { >+ return 0; >+ }, [&](Ref<ResolvableTypeReference>& resolvableTypeReference) -> unsigned { >+ return resolvableTypeReference->resolvableType().conversionCost(*candidate.parameters()[i].type()); >+ }), argumentTypes[i].get()); >+ } >+ // The return type can never be a literal type, so its conversion cost is always 0. >+ return conversionCost; >+} >+ >+AST::FunctionDeclaration* resolveFunctionOverloadImpl(Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>& possibleFunctions, Vector<std::reference_wrapper<ResolvingType>>& argumentTypes, Optional<std::reference_wrapper<AST::NamedType>>& castReturnType) >+{ >+ Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1> candidates; >+ for (auto& possibleFunction : possibleFunctions) { >+ if (possibleFunction.get().entryPointType()) >+ continue; >+ if (inferTypesForCall(possibleFunction.get(), argumentTypes, castReturnType)) >+ candidates.append(possibleFunction.get()); >+ } >+ >+ unsigned minimumConversionCost = std::numeric_limits<unsigned>::max(); >+ for (auto& candidate : candidates) >+ minimumConversionCost = std::min(minimumConversionCost, conversionCost(candidate.get(), argumentTypes)); >+ >+ Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1> minimumCostCandidates; >+ for (auto& candidate : candidates) { >+ if (conversionCost(candidate.get(), argumentTypes) == minimumConversionCost) >+ minimumCostCandidates.append(candidate); >+ } >+ >+ bool restrictedCandidateExists = false; >+ for (auto& candidate : minimumCostCandidates) { >+ if (is<AST::FunctionDefinition>(candidate.get()) && downcast<AST::FunctionDefinition>(candidate.get()).restricted()) { >+ restrictedCandidateExists = true; >+ break; >+ } >+ } >+ >+ candidates.clear(); >+ if (restrictedCandidateExists) { >+ for (auto& candidate : minimumCostCandidates) { >+ if (is<AST::FunctionDefinition>(candidate.get()) && downcast<AST::FunctionDefinition>(candidate.get()).restricted()) >+ candidates.append(candidate.get()); >+ } >+ } else >+ candidates = minimumCostCandidates; >+ >+ if (candidates.size() == 1) >+ return &candidates[0].get(); >+ return nullptr; >+} >+ >+AST::NamedType* resolveTypeOverloadImpl(Vector<std::reference_wrapper<AST::NamedType>, 1>& possibleTypes, AST::TypeArguments& typeArguments) >+{ >+ AST::NamedType* result = nullptr; >+ for (auto& possibleType : possibleTypes) { >+ if (inferTypesForTypeArguments(possibleType, typeArguments)) { >+ if (result) >+ return nullptr; >+ result = &static_cast<AST::NamedType&>(possibleType); >+ } >+ } >+ >+ return result; >+} >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAnonymousVariableDeclaration.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLResolveOverloadImpl.h >similarity index 73% >rename from Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAnonymousVariableDeclaration.h >rename to Source/WebCore/Modules/webgpu/WHLSL/WHLSLResolveOverloadImpl.h >index ef61ed12619..ac7903bafc3 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAnonymousVariableDeclaration.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLResolveOverloadImpl.h >@@ -27,8 +27,10 @@ > > #if ENABLE(WEBGPU) > >-#include "WHLSLLexer.h" >-#include "WHLSLValue.h" >+#include "WHLSLResolvingType.h" >+#include "WHLSLTypeArgument.h" >+#include <functional> >+#include <wtf/Vector.h> > > namespace WebCore { > >@@ -36,26 +38,14 @@ namespace WHLSL { > > namespace AST { > >-class AnonymousVariableDeclaration : public Value { >-public: >- AnonymousVariableDeclaration(Lexer::Token&& origin) >- : m_origin(WTFMove(origin)) >- { >- } >- >- virtual ~AnonymousVariableDeclaration() = default; >- >- AnonymousVariableDeclaration(const AnonymousVariableDeclaration&) = delete; >- AnonymousVariableDeclaration(AnonymousVariableDeclaration&&) = default; >- >- Lexer::Token origin() const { return m_origin; } >- >-private: >- Lexer::Token m_origin; >-}; >+class FunctionDeclaration; >+class NamedType; > > } > >+AST::FunctionDeclaration* resolveFunctionOverloadImpl(Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>& possibleFunctions, Vector<std::reference_wrapper<ResolvingType>>& argumentTypes, Optional<std::reference_wrapper<AST::NamedType>>& castReturnType); >+AST::NamedType* resolveTypeOverloadImpl(Vector<std::reference_wrapper<AST::NamedType>, 1>&, AST::TypeArguments&); >+ > } > > } >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLResolvingType.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLResolvingType.h >new file mode 100644 >index 00000000000..97c0ebae81f >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLResolvingType.h >@@ -0,0 +1,69 @@ >+/* >+ * 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 <memory> >+#include <wtf/Ref.h> >+#include <wtf/RefCounted.h> >+#include <wtf/UniqueRef.h> >+#include <wtf/Variant.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class ResolvableType; >+class UnnamedType; >+ >+} >+ >+class ResolvableTypeReference : public RefCounted<ResolvableTypeReference> { >+public: >+ ResolvableTypeReference(AST::ResolvableType& resolvableType) >+ : m_resolvableType(&resolvableType) >+ { >+ } >+ >+ ResolvableTypeReference(const ResolvableTypeReference&) = delete; >+ ResolvableTypeReference(ResolvableTypeReference&&) = delete; >+ >+ AST::ResolvableType& resolvableType() { return *m_resolvableType; } >+ >+private: >+ AST::ResolvableType* m_resolvableType; >+}; >+ >+using ResolvingType = Variant<UniqueRef<AST::UnnamedType>, Ref<ResolvableTypeReference>>; >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeArrayOperatorLength.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeArrayOperatorLength.cpp >new file mode 100644 >index 00000000000..815380aee8e >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeArrayOperatorLength.cpp >@@ -0,0 +1,81 @@ >+/* >+ * 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. >+ */ >+ >+#if ENABLE(WEBGPU) >+ >+#include "config.h" >+#include "WHLSLSynthesizeArrayOperatorLength.h" >+ >+#include "WHLSLArrayType.h" >+#include "WHLSLProgram.h" >+#include "WHLSLTypeReference.h" >+#include "WHLSLVisitor.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+class FindArrayTypes : public Visitor { >+public: >+ ~FindArrayTypes() = default; >+ >+ void visit(AST::ArrayType& arrayType) override >+ { >+ m_arrayTypes.append(arrayType); >+ checkErrorAndVisit(arrayType); >+ } >+ >+ Vector<std::reference_wrapper<AST::ArrayType>>&& takeArrayTypes() >+ { >+ return WTFMove(m_arrayTypes); >+ } >+ >+private: >+ Vector<std::reference_wrapper<AST::ArrayType>> m_arrayTypes; >+}; >+ >+void synthesizeArrayOperatorLength(Program& program) >+{ >+ FindArrayTypes findArrayTypes; >+ findArrayTypes.checkErrorAndVisit(program); >+ auto arrayTypes = findArrayTypes.takeArrayTypes(); >+ >+ bool isOperator = true; >+ bool isRestricted = false; >+ >+ for (auto& arrayType : arrayTypes) { >+ AST::VariableDeclaration variableDeclaration(Lexer::Token(arrayType.get().origin()), AST::Qualifiers(), arrayType.get().clone().takeUniquePtr(), String(), WTF::nullopt, nullptr); >+ AST::VariableDeclarations parameters; >+ parameters.append(WTFMove(variableDeclaration)); >+ AST::NativeFunctionDeclaration nativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(arrayType.get().origin()), AST::AttributeBlock(), WTF::nullopt, AST::TypeReference::wrap(Lexer::Token(arrayType.get().origin()), program.intrinsics().uintType()), String("operator.length", String::ConstructFromLiteral), WTFMove(parameters), WTF::nullopt, isOperator), isRestricted); >+ program.append(WTFMove(nativeFunctionDeclaration)); >+ } >+} >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeArrayOperatorLength.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeArrayOperatorLength.h >new file mode 100644 >index 00000000000..e9a9a114f27 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeArrayOperatorLength.h >@@ -0,0 +1,42 @@ >+/* >+ * 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) >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+class Program; >+ >+void synthesizeArrayOperatorLength(Program&); >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeConstructors.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeConstructors.cpp >new file mode 100644 >index 00000000000..0368e8d7511 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeConstructors.cpp >@@ -0,0 +1,127 @@ >+/* >+ * 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. >+ */ >+ >+#if ENABLE(WEBGPU) >+ >+#include "config.h" >+#include "WHLSLSynthesizeConstructors.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+class FindAllTypes : public Visitor { >+public: >+ ~FindAllTypes() = default; >+ >+ void visit(AST::PointerType& pointerType) override >+ { >+ m_unnamedTypes.append(pointerType); >+ checkErrorAndVisit(pointerType); >+ } >+ >+ void visit(AST::ArrayReferenceType& arrayReferenceType) override >+ { >+ m_unnamedTypes.append(arrayReferenceType); >+ checkErrorAndVisit(arrayReferenceType); >+ } >+ >+ void visit(AST::ArrayType& arrayType) override >+ { >+ m_unnamedTypes.append(arrayType); >+ checkErrorAndVisit(arrayType); >+ } >+ >+ void visit(AST::EnumerationDefinition& enumerationDefinition) override >+ { >+ m_namedTypes.append(enumerationDefinition); >+ checkErrorAndVisit(enumerationDefinition); >+ } >+ >+ void visit(AST::StructureDefinition& structureDefinition) override >+ { >+ m_namedTypes.append(structureDefinition); >+ checkErrorAndVisit(structureDefinition); >+ } >+ >+ void visit(AST::NativeTypeDeclaration& nativeTypeDeclaration) override >+ { >+ m_namedTypes.append(nativeTypeDeclaration); >+ checkErrorAndVisit(nativeTypeDeclaration); >+ } >+ >+ Vector<std::reference_wrapper<AST::UnnamedType>>&& takeUnnamedTypes() >+ { >+ return WTFMove(m_unnamedTypes); >+ } >+ >+ Vector<std::reference_wrapper<AST::NamedType>>&& takeNamedTypes() >+ { >+ return WTFMove(m_namedTypes); >+ } >+ >+private: >+ Vector<std::reference_wrapper<AST::UnnamedType>> m_unnamedTypes; >+ Vector<std::reference_wrapper<AST::NamedType>> m_namedTypes; >+}; >+ >+void synthesizeConstructors(Program& program) >+{ >+ FindAllTypes findAllTypes; >+ findAllTypes.checkErrorAndVisit(program); >+ auto m_unnamedTypes = findAllTypes.takeUnnamedTypes(); >+ auto m_namedTypes = findAllTypes.takeNamedTypes(); >+ >+ bool isOperator = true; >+ bool isRestricted = false; >+ >+ for (auto& unnamedType : m_unnamedTypes) { >+ AST::VariableDeclaration variableDeclaration(Lexer::Token(unnamedType.get().origin()), AST::Qualifiers(), unnamedType.get().clone().takeUniquePtr(), String(), WTF::nullopt, nullptr); >+ AST::VariableDeclarations parameters; >+ parameters.append(WTFMove(variableDeclaration)); >+ AST::NativeFunctionDeclaration copyConstructor(AST::FunctionDeclaration(Lexer::Token(unnamedType.get().origin()), AST::AttributeBlock(), WTF::nullopt, unnamedType.get().clone(), String("operator cast", String::ConstructFromLiteral), WTFMove(parameters), WTF::nullopt, isOperator), isRestricted); >+ program.append(WTFMove(copyConstructor)); >+ >+ AST::NativeFunctionDeclaration defaultConstructor(AST::FunctionDeclaration(Lexer::Token(unnamedType.get().origin()), AST::AttributeBlock(), WTF::nullopt, unnamedType.get().clone(), String("operator cast", String::ConstructFromLiteral), AST::VariableDeclarations(), WTF::nullopt, isOperator), isRestricted); >+ program.append(WTFMove(defaultConstructor)); >+ } >+ >+ for (auto& namedType : m_namedTypes) { >+ AST::VariableDeclaration variableDeclaration(Lexer::Token(namedType.get().origin()), AST::Qualifiers(), AST::TypeReference::wrap(Lexer::Token(namedType.get().origin()), namedType.get()).takeUniquePtr(), String(), WTF::nullopt, nullptr); >+ AST::VariableDeclarations parameters; >+ parameters.append(WTFMove(variableDeclaration)); >+ AST::NativeFunctionDeclaration copyConstructor(AST::FunctionDeclaration(Lexer::Token(namedType.get().origin()), AST::AttributeBlock(), WTF::nullopt, AST::TypeReference::wrap(Lexer::Token(namedType.get().origin()), namedType.get()), String("operator cast", String::ConstructFromLiteral), WTFMove(parameters), WTF::nullopt, isOperator), isRestricted); >+ program.append(WTFMove(copyConstructor)); >+ >+ AST::NativeFunctionDeclaration defaultConstructor(AST::FunctionDeclaration(Lexer::Token(namedType.get().origin()), AST::AttributeBlock(), WTF::nullopt, AST::TypeReference::wrap(Lexer::Token(namedType.get().origin()), namedType.get()), String("operator cast", String::ConstructFromLiteral), AST::VariableDeclarations(), WTF::nullopt, isOperator), isRestricted); >+ program.append(WTFMove(defaultConstructor)); >+ } >+} >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeConstructors.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeConstructors.h >new file mode 100644 >index 00000000000..80020dd7c70 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeConstructors.h >@@ -0,0 +1,42 @@ >+/* >+ * 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) >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+class Program; >+ >+void synthesizeConstructors(Program&); >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeEnumerationFunctions.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeEnumerationFunctions.cpp >new file mode 100644 >index 00000000000..0fae0555a16 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeEnumerationFunctions.cpp >@@ -0,0 +1,83 @@ >+/* >+ * 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. >+ */ >+ >+#if ENABLE(WEBGPU) >+ >+#include "config.h" >+#include "WHLSLSynthesizeEnumerationFunctions.h" >+ >+#include "WHLSLProgram.h" >+#include "WHLSLTypeReference.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+void synthesizeEnumerationFunctions(Program& program) >+{ >+ bool isOperator = true; >+ bool isRestricted = false; >+ for (auto& enumerationDefinition : program.enumerationDefinitions()) { >+ { >+ AST::VariableDeclaration variableDeclaration1(Lexer::Token(enumerationDefinition->origin()), AST::Qualifiers(), AST::TypeReference::wrap(Lexer::Token(enumerationDefinition->origin()), *enumerationDefinition).takeUniquePtr(), String(), WTF::nullopt, nullptr); >+ AST::VariableDeclaration variableDeclaration2(Lexer::Token(enumerationDefinition->origin()), AST::Qualifiers(), AST::TypeReference::wrap(Lexer::Token(enumerationDefinition->origin()), *enumerationDefinition).takeUniquePtr(), String(), WTF::nullopt, nullptr); >+ AST::VariableDeclarations parameters; >+ parameters.append(WTFMove(variableDeclaration1)); >+ parameters.append(WTFMove(variableDeclaration2)); >+ AST::NativeFunctionDeclaration nativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(enumerationDefinition->origin()), AST::AttributeBlock(), WTF::nullopt, AST::TypeReference::wrap(Lexer::Token(enumerationDefinition->origin()), program.intrinsics().boolType()), String("operator==", String::ConstructFromLiteral), WTFMove(parameters), WTF::nullopt, isOperator), isRestricted); >+ program.append(WTFMove(nativeFunctionDeclaration)); >+ } >+ >+ { >+ AST::VariableDeclaration variableDeclaration(Lexer::Token(enumerationDefinition->origin()), AST::Qualifiers(), AST::TypeReference::wrap(Lexer::Token(enumerationDefinition->origin()), *enumerationDefinition).takeUniquePtr(), String(), WTF::nullopt, nullptr); >+ AST::VariableDeclarations parameters; >+ parameters.append(WTFMove(variableDeclaration)); >+ AST::NativeFunctionDeclaration nativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(enumerationDefinition->origin()), AST::AttributeBlock(), WTF::nullopt, enumerationDefinition->type().clone(), String("operator.value", String::ConstructFromLiteral), WTFMove(parameters), WTF::nullopt, isOperator), isRestricted); >+ program.append(WTFMove(nativeFunctionDeclaration)); >+ } >+ >+ { >+ AST::VariableDeclaration variableDeclaration(Lexer::Token(enumerationDefinition->origin()), AST::Qualifiers(), AST::TypeReference::wrap(Lexer::Token(enumerationDefinition->origin()), *enumerationDefinition).takeUniquePtr(), String(), WTF::nullopt, nullptr); >+ AST::VariableDeclarations parameters; >+ parameters.append(WTFMove(variableDeclaration)); >+ AST::NativeFunctionDeclaration nativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(enumerationDefinition->origin()), AST::AttributeBlock(), WTF::nullopt, enumerationDefinition->type().clone(), String("operator cast", String::ConstructFromLiteral), WTFMove(parameters), WTF::nullopt, isOperator), isRestricted); >+ program.append(WTFMove(nativeFunctionDeclaration)); >+ } >+ >+ { >+ AST::VariableDeclaration variableDeclaration(Lexer::Token(enumerationDefinition->origin()), AST::Qualifiers(), enumerationDefinition->type().clone().takeUniquePtr(), String(), WTF::nullopt, nullptr); >+ AST::VariableDeclarations parameters; >+ parameters.append(WTFMove(variableDeclaration)); >+ AST::NativeFunctionDeclaration nativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(enumerationDefinition->origin()), AST::AttributeBlock(), WTF::nullopt, AST::TypeReference::wrap(Lexer::Token(enumerationDefinition->origin()), *enumerationDefinition), String("operator cast", String::ConstructFromLiteral), WTFMove(parameters), WTF::nullopt, isOperator), isRestricted); >+ program.append(WTFMove(nativeFunctionDeclaration)); >+ } >+ } >+} >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeEnumerationFunctions.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeEnumerationFunctions.h >new file mode 100644 >index 00000000000..ac107872ef9 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeEnumerationFunctions.h >@@ -0,0 +1,42 @@ >+/* >+ * 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) >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+class Program; >+ >+void synthesizeEnumerationFunctions(Program&); >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeStructureAccessors.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeStructureAccessors.cpp >new file mode 100644 >index 00000000000..13df467b7e0 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeStructureAccessors.cpp >@@ -0,0 +1,89 @@ >+/* >+ * 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. >+ */ >+ >+#if ENABLE(WEBGPU) >+ >+#include "config.h" >+#include "WHLSLSynthesizeStructureAccessors.h" >+ >+#include "WHLSLPointerType.h" >+#include "WHLSLProgram.h" >+#include "WHLSLReferenceType.h" >+#include "WHLSLTypeReference.h" >+#include "WHLSLVariableDeclaration.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+void synthesizeStructureAccessors(Program& program) >+{ >+ bool isOperator = true; >+ bool isRestricted = false; >+ for (auto& structureDefinition : program.structureDefinitions()) { >+ for (auto& structureElement : structureDefinition->structureElements()) { >+ { >+ // The getter: operator.field >+ AST::VariableDeclaration variableDeclaration(Lexer::Token(structureElement.origin()), AST::Qualifiers(), AST::TypeReference::wrap(Lexer::Token(structureElement.origin()), *structureDefinition).takeUniquePtr(), String(), WTF::nullopt, nullptr); >+ AST::VariableDeclarations parameters; >+ parameters.append(WTFMove(variableDeclaration)); >+ AST::NativeFunctionDeclaration nativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(structureElement.origin()), AST::AttributeBlock(), WTF::nullopt, structureElement.type().clone(), String::format("operator.%s", structureElement.name().utf8().data()), WTFMove(parameters), WTF::nullopt, isOperator), isRestricted); >+ program.append(WTFMove(nativeFunctionDeclaration)); >+ } >+ >+ { >+ // The setter: operator.field= >+ AST::VariableDeclaration variableDeclaration1(Lexer::Token(structureElement.origin()), AST::Qualifiers(), AST::TypeReference::wrap(Lexer::Token(structureElement.origin()), *structureDefinition).takeUniquePtr(), String(), WTF::nullopt, nullptr); >+ AST::VariableDeclaration variableDeclaration2(Lexer::Token(structureElement.origin()), AST::Qualifiers(), structureElement.type().clone().takeUniquePtr(), String(), WTF::nullopt, nullptr); >+ AST::VariableDeclarations parameters; >+ parameters.append(WTFMove(variableDeclaration1)); >+ parameters.append(WTFMove(variableDeclaration2)); >+ AST::NativeFunctionDeclaration nativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(structureElement.origin()), AST::AttributeBlock(), WTF::nullopt, AST::TypeReference::wrap(Lexer::Token(structureElement.origin()), *structureDefinition), String::format("operator.%s=", structureElement.name().utf8().data()), WTFMove(parameters), WTF::nullopt, isOperator), isRestricted); >+ program.append(WTFMove(nativeFunctionDeclaration)); >+ } >+ >+ // The ander: operator&.field >+ auto createAnder = [&](AST::ReferenceType::AddressSpace addressSpace) -> AST::NativeFunctionDeclaration { >+ auto argumentType = makeUniqueRef<AST::PointerType>(Lexer::Token(structureElement.origin()), addressSpace, AST::TypeReference::wrap(Lexer::Token(structureElement.origin()), *structureDefinition)); >+ AST::VariableDeclaration variableDeclaration(Lexer::Token(structureElement.origin()), AST::Qualifiers(), argumentType.takeUniquePtr(), String(), WTF::nullopt, nullptr); >+ AST::VariableDeclarations parameters; >+ parameters.append(WTFMove(variableDeclaration)); >+ auto returnType = makeUniqueRef<AST::PointerType>(Lexer::Token(structureElement.origin()), addressSpace, structureElement.type().clone()); >+ AST::NativeFunctionDeclaration nativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(structureElement.origin()), AST::AttributeBlock(), WTF::nullopt, WTFMove(returnType), String::format("operator&.%s", structureElement.name().utf8().data()), WTFMove(parameters), WTF::nullopt, isOperator), isRestricted); >+ return nativeFunctionDeclaration; >+ }; >+ program.append(createAnder(AST::ReferenceType::AddressSpace::Constant)); >+ program.append(createAnder(AST::ReferenceType::AddressSpace::Device)); >+ program.append(createAnder(AST::ReferenceType::AddressSpace::Threadgroup)); >+ program.append(createAnder(AST::ReferenceType::AddressSpace::Thread)); >+ } >+ } >+} >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeStructureAccessors.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeStructureAccessors.h >new file mode 100644 >index 00000000000..4e9b9ff70c0 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeStructureAccessors.h >@@ -0,0 +1,42 @@ >+/* >+ * 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) >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+class Program; >+ >+void synthesizeStructureAccessors(Program&); >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.cpp >new file mode 100644 >index 00000000000..f739e5a68cc >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.cpp >@@ -0,0 +1,1030 @@ >+/* >+ * 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. >+ */ >+ >+#if ENABLE(WEBGPU) >+ >+#include "config.h" >+#include "WHLSLVisitor.h" >+ >+#include "WHLSLProgram.h" >+#include "WHLSLArrayReferenceType.h" >+#include "WHLSLArrayType.h" >+#include "WHLSLAssignmentExpression.h" >+#include "WHLSLBaseFunctionAttribute.h" >+#include "WHLSLBaseSemantic.h" >+#include "WHLSLBlock.h" >+#include "WHLSLBooleanLiteral.h" >+#include "WHLSLBreak.h" >+#include "WHLSLBuiltInSemantic.h" >+#include "WHLSLCallExpression.h" >+#include "WHLSLCommaExpression.h" >+#include "WHLSLConstantExpression.h" >+#include "WHLSLConstantExpressionEnumerationMemberReference.h" >+#include "WHLSLContinue.h" >+#include "WHLSLDereferenceExpression.h" >+#include "WHLSLDoWhileLoop.h" >+#include "WHLSLDotExpression.h" >+#include "WHLSLEffectfulExpressionStatement.h" >+#include "WHLSLEnumerationDefinition.h" >+#include "WHLSLEnumerationMember.h" >+#include "WHLSLExpression.h" >+#include "WHLSLFallthrough.h" >+#include "WHLSLFloatLiteral.h" >+#include "WHLSLForLoop.h" >+#include "WHLSLFunctionAttribute.h" >+#include "WHLSLFunctionDeclaration.h" >+#include "WHLSLFunctionDefinition.h" >+#include "WHLSLIfStatement.h" >+#include "WHLSLIndexExpression.h" >+#include "WHLSLIntegerLiteral.h" >+#include "WHLSLLogicalExpression.h" >+#include "WHLSLLogicalNotExpression.h" >+#include "WHLSLMakeArrayReferenceExpression.h" >+#include "WHLSLMakePointerExpression.h" >+#include "WHLSLNativeFunctionDeclaration.h" >+#include "WHLSLNativeTypeDeclaration.h" >+#include "WHLSLNode.h" >+#include "WHLSLNullLiteral.h" >+#include "WHLSLNumThreadsFunctionAttribute.h" >+#include "WHLSLPointerType.h" >+#include "WHLSLPropertyAccessExpression.h" >+#include "WHLSLQualifier.h" >+#include "WHLSLReadModifyWriteExpression.h" >+#include "WHLSLReferenceType.h" >+#include "WHLSLResourceSemantic.h" >+#include "WHLSLReturn.h" >+#include "WHLSLSemantic.h" >+#include "WHLSLSpecializationConstantSemantic.h" >+#include "WHLSLStageInOutSemantic.h" >+#include "WHLSLStatement.h" >+#include "WHLSLStructureDefinition.h" >+#include "WHLSLStructureElement.h" >+#include "WHLSLSwitchCase.h" >+#include "WHLSLSwitchStatement.h" >+#include "WHLSLTernaryExpression.h" >+#include "WHLSLTrap.h" >+#include "WHLSLType.h" >+#include "WHLSLTypeArgument.h" >+#include "WHLSLTypeDefinition.h" >+#include "WHLSLTypeReference.h" >+#include "WHLSLUnsignedIntegerLiteral.h" >+#include "WHLSLValue.h" >+#include "WHLSLVariableDeclaration.h" >+#include "WHLSLVariableDeclarationsStatement.h" >+#include "WHLSLVariableReference.h" >+#include "WHLSLWhileLoop.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+void Visitor::visit(Program& program) >+{ >+ // These visiting functions might add new global statements, so don't use foreach syntax. >+ for (size_t i = 0; i < program.typeDefinitions().size(); ++i) >+ checkErrorAndVisit(*program.typeDefinitions()[i]); >+ for (size_t i = 0; i < program.structureDefinitions().size(); ++i) >+ checkErrorAndVisit(*program.structureDefinitions()[i]); >+ for (size_t i = 0; i < program.enumerationDefinitions().size(); ++i) >+ checkErrorAndVisit(*program.enumerationDefinitions()[i]); >+ for (size_t i = 0; i < program.functionDefinitions().size(); ++i) >+ checkErrorAndVisit(*program.functionDefinitions()[i]); >+ for (size_t i = 0; i < program.nativeFunctionDeclarations().size(); ++i) >+ checkErrorAndVisit(*program.nativeFunctionDeclarations()[i]); >+ for (size_t i = 0; i < program.nativeTypeDeclarations().size(); ++i) >+ checkErrorAndVisit(*program.nativeTypeDeclarations()[i]); >+} >+ >+void Visitor::visit(AST::UnnamedType& unnamedType) >+{ >+ if (is<AST::TypeReference>(unnamedType)) >+ checkErrorAndVisit(downcast<AST::TypeReference>(unnamedType)); >+ else if (is<AST::PointerType>(unnamedType)) >+ checkErrorAndVisit(downcast<AST::PointerType>(unnamedType)); >+ else if (is<AST::ArrayReferenceType>(unnamedType)) >+ checkErrorAndVisit(downcast<AST::ArrayReferenceType>(unnamedType)); >+ else { >+ ASSERT(is<AST::ArrayType>(unnamedType)); >+ checkErrorAndVisit(downcast<AST::ArrayType>(unnamedType)); >+ } >+} >+ >+void Visitor::visit(AST::NamedType& namedType) >+{ >+ if (is<AST::TypeDefinition>(namedType)) >+ checkErrorAndVisit(downcast<AST::TypeDefinition>(namedType)); >+ else if (is<AST::StructureDefinition>(namedType)) >+ checkErrorAndVisit(downcast<AST::StructureDefinition>(namedType)); >+ else if (is<AST::EnumerationDefinition>(namedType)) >+ checkErrorAndVisit(downcast<AST::EnumerationDefinition>(namedType)); >+ else { >+ ASSERT(is<AST::NativeTypeDeclaration>(namedType)); >+ checkErrorAndVisit(downcast<AST::NativeTypeDeclaration>(namedType)); >+ } >+} >+ >+void Visitor::visit(AST::TypeDefinition& typeDefinition) >+{ >+ checkErrorAndVisit(typeDefinition.type()); >+} >+ >+void Visitor::visit(AST::StructureDefinition& structureDefinition) >+{ >+ for (auto& structureElement : structureDefinition.structureElements()) >+ checkErrorAndVisit(structureElement); >+} >+ >+void Visitor::visit(AST::EnumerationDefinition& enumerationDefinition) >+{ >+ checkErrorAndVisit(enumerationDefinition.type()); >+ for (auto& enumerationMember : enumerationDefinition.enumerationMembers()) >+ checkErrorAndVisit(enumerationMember); >+} >+ >+void Visitor::visit(AST::FunctionDefinition& functionDefinition) >+{ >+ checkErrorAndVisit(static_cast<AST::FunctionDeclaration&>(functionDefinition)); >+ checkErrorAndVisit(functionDefinition.block()); >+} >+ >+void Visitor::visit(AST::NativeFunctionDeclaration& nativeFunctionDeclaration) >+{ >+ checkErrorAndVisit(static_cast<AST::FunctionDeclaration&>(nativeFunctionDeclaration)); >+} >+ >+void Visitor::visit(AST::NativeTypeDeclaration& nativeTypeDeclaration) >+{ >+ for (auto& typeArgument : nativeTypeDeclaration.typeArguments()) >+ checkErrorAndVisit(typeArgument); >+} >+ >+void Visitor::visit(AST::TypeReference& typeReference) >+{ >+ for (auto& typeArgument : typeReference.typeArguments()) >+ checkErrorAndVisit(typeArgument); >+ if (typeReference.resolvedType() && is<AST::TypeDefinition>(*typeReference.resolvedType())) { >+ auto& typeDefinition = downcast<AST::TypeDefinition>(*typeReference.resolvedType()); >+ checkErrorAndVisit(typeDefinition.type()); >+ } >+} >+ >+void Visitor::visit(AST::PointerType& pointerType) >+{ >+ checkErrorAndVisit(static_cast<AST::ReferenceType&>(pointerType)); >+} >+ >+void Visitor::visit(AST::ArrayReferenceType& arrayReferenceType) >+{ >+ checkErrorAndVisit(static_cast<AST::ReferenceType&>(arrayReferenceType)); >+} >+ >+void Visitor::visit(AST::ArrayType& arrayType) >+{ >+ checkErrorAndVisit(arrayType.type()); >+} >+ >+void Visitor::visit(AST::StructureElement& structureElement) >+{ >+ checkErrorAndVisit(structureElement.type()); >+ if (structureElement.semantic()) >+ checkErrorAndVisit(*structureElement.semantic()); >+} >+ >+void Visitor::visit(AST::EnumerationMember& enumerationMember) >+{ >+ if (enumerationMember.value()) >+ checkErrorAndVisit(*enumerationMember.value()); >+} >+ >+void Visitor::visit(AST::FunctionDeclaration& functionDeclaration) >+{ >+ checkErrorAndVisit(functionDeclaration.attributeBlock()); >+ checkErrorAndVisit(functionDeclaration.type()); >+ for (auto& parameter : functionDeclaration.parameters()) >+ checkErrorAndVisit(parameter); >+ if (functionDeclaration.semantic()) >+ checkErrorAndVisit(*functionDeclaration.semantic()); >+} >+ >+void Visitor::visit(AST::TypeArgument& typeArgument) >+{ >+ WTF::visit(WTF::makeVisitor([&](AST::ConstantExpression& constantExpression) { >+ checkErrorAndVisit(constantExpression); >+ }, [&](UniqueRef<AST::TypeReference>& typeReference) { >+ checkErrorAndVisit(static_cast<AST::TypeReference&>(typeReference)); >+ }), typeArgument); >+} >+ >+void Visitor::visit(AST::ReferenceType& referenceType) >+{ >+ checkErrorAndVisit(referenceType.elementType()); >+} >+ >+void Visitor::visit(AST::Semantic& semantic) >+{ >+ WTF::visit(WTF::makeVisitor([&](AST::BuiltInSemantic& builtInSemantic) { >+ checkErrorAndVisit(builtInSemantic); >+ }, [&](AST::ResourceSemantic& resourceSemantic) { >+ checkErrorAndVisit(resourceSemantic); >+ }, [&](AST::SpecializationConstantSemantic& specializationConstantSemantic) { >+ checkErrorAndVisit(specializationConstantSemantic); >+ }, [&](AST::StageInOutSemantic& stageInOutSemantic) { >+ checkErrorAndVisit(stageInOutSemantic); >+ }), semantic); >+} >+ >+void Visitor::visit(AST::ConstantExpression& constantExpression) >+{ >+ constantExpression.visit(WTF::makeVisitor([&](AST::IntegerLiteral& integerLiteral) { >+ checkErrorAndVisit(integerLiteral); >+ }, [&](AST::UnsignedIntegerLiteral& unsignedIntegerLiteral) { >+ checkErrorAndVisit(unsignedIntegerLiteral); >+ }, [&](AST::FloatLiteral& floatLiteral) { >+ checkErrorAndVisit(floatLiteral); >+ }, [&](AST::NullLiteral& nullLiteral) { >+ checkErrorAndVisit(nullLiteral); >+ }, [&](AST::BooleanLiteral& booleanLiteral) { >+ checkErrorAndVisit(booleanLiteral); >+ }, [&](AST::ConstantExpressionEnumerationMemberReference& constantExpressionEnumerationMemberReference) { >+ checkErrorAndVisit(constantExpressionEnumerationMemberReference); >+ })); >+} >+ >+void Visitor::visit(AST::AttributeBlock& attributeBlock) >+{ >+ for (auto& functionAttribute : attributeBlock) >+ checkErrorAndVisit(functionAttribute); >+} >+ >+void Visitor::visit(AST::BuiltInSemantic&) >+{ >+} >+ >+void Visitor::visit(AST::ResourceSemantic&) >+{ >+} >+ >+void Visitor::visit(AST::SpecializationConstantSemantic&) >+{ >+} >+ >+void Visitor::visit(AST::StageInOutSemantic&) >+{ >+} >+ >+void Visitor::visit(AST::IntegerLiteral& integerLiteral) >+{ >+ checkErrorAndVisit(integerLiteral.type()); >+} >+ >+void Visitor::visit(AST::UnsignedIntegerLiteral& unsignedIntegerLiteral) >+{ >+ checkErrorAndVisit(unsignedIntegerLiteral.type()); >+} >+ >+void Visitor::visit(AST::FloatLiteral& floatLiteral) >+{ >+ checkErrorAndVisit(floatLiteral.type()); >+} >+ >+void Visitor::visit(AST::NullLiteral& nullLiteral) >+{ >+ checkErrorAndVisit(nullLiteral.type()); >+} >+ >+void Visitor::visit(AST::BooleanLiteral&) >+{ >+} >+ >+void Visitor::visit(AST::IntegerLiteralType& integerLiteralType) >+{ >+ if (integerLiteralType.resolvedType()) >+ checkErrorAndVisit(*integerLiteralType.resolvedType()); >+ checkErrorAndVisit(integerLiteralType.preferredType()); >+} >+ >+void Visitor::visit(AST::UnsignedIntegerLiteralType& unsignedIntegerLiteralType) >+{ >+ if (unsignedIntegerLiteralType.resolvedType()) >+ checkErrorAndVisit(*unsignedIntegerLiteralType.resolvedType()); >+ checkErrorAndVisit(unsignedIntegerLiteralType.preferredType()); >+} >+ >+void Visitor::visit(AST::FloatLiteralType& floatLiteralType) >+{ >+ if (floatLiteralType.resolvedType()) >+ checkErrorAndVisit(*floatLiteralType.resolvedType()); >+ checkErrorAndVisit(floatLiteralType.preferredType()); >+} >+ >+void Visitor::visit(AST::NullLiteralType& nullLiteralType) >+{ >+ if (nullLiteralType.resolvedType()) >+ checkErrorAndVisit(*nullLiteralType.resolvedType()); >+} >+ >+void Visitor::visit(AST::ConstantExpressionEnumerationMemberReference&) >+{ >+} >+ >+void Visitor::visit(AST::FunctionAttribute& functionAttribute) >+{ >+ WTF::visit(WTF::makeVisitor([&](AST::NumThreadsFunctionAttribute& numThreadsFunctionAttribute) { >+ checkErrorAndVisit(numThreadsFunctionAttribute); >+ }), functionAttribute); >+} >+ >+void Visitor::visit(AST::NumThreadsFunctionAttribute&) >+{ >+} >+ >+void Visitor::visit(AST::Block& block) >+{ >+ for (auto& statement : block.statements()) >+ checkErrorAndVisit(static_cast<AST::Statement&>(statement)); >+} >+ >+void Visitor::visit(AST::Statement& statement) >+{ >+ if (is<AST::Block>(statement)) >+ checkErrorAndVisit(downcast<AST::Block>(statement)); >+ else if (is<AST::Break>(statement)) >+ checkErrorAndVisit(downcast<AST::Break>(statement)); >+ else if (is<AST::Continue>(statement)) >+ checkErrorAndVisit(downcast<AST::Continue>(statement)); >+ else if (is<AST::DoWhileLoop>(statement)) >+ checkErrorAndVisit(downcast<AST::DoWhileLoop>(statement)); >+ else if (is<AST::EffectfulExpressionStatement>(statement)) >+ checkErrorAndVisit(downcast<AST::EffectfulExpressionStatement>(statement)); >+ else if (is<AST::Fallthrough>(statement)) >+ checkErrorAndVisit(downcast<AST::Fallthrough>(statement)); >+ else if (is<AST::ForLoop>(statement)) >+ checkErrorAndVisit(downcast<AST::ForLoop>(statement)); >+ else if (is<AST::IfStatement>(statement)) >+ checkErrorAndVisit(downcast<AST::IfStatement>(statement)); >+ else if (is<AST::Return>(statement)) >+ checkErrorAndVisit(downcast<AST::Return>(statement)); >+ else if (is<AST::SwitchCase>(statement)) >+ checkErrorAndVisit(downcast<AST::SwitchCase>(statement)); >+ else if (is<AST::SwitchStatement>(statement)) >+ checkErrorAndVisit(downcast<AST::SwitchStatement>(statement)); >+ else if (is<AST::Trap>(statement)) >+ checkErrorAndVisit(downcast<AST::Trap>(statement)); >+ else if (is<AST::VariableDeclarationsStatement>(statement)) >+ checkErrorAndVisit(downcast<AST::VariableDeclarationsStatement>(statement)); >+ else { >+ ASSERT(is<AST::WhileLoop>(statement)); >+ checkErrorAndVisit(downcast<AST::WhileLoop>(statement)); >+ } >+} >+ >+void Visitor::visit(AST::Break&) >+{ >+} >+ >+void Visitor::visit(AST::Continue&) >+{ >+} >+ >+void Visitor::visit(AST::DoWhileLoop& doWhileLoop) >+{ >+ checkErrorAndVisit(doWhileLoop.body()); >+ checkErrorAndVisit(doWhileLoop.conditional()); >+} >+ >+void Visitor::visit(AST::Expression& expression) >+{ >+ if (is<AST::AssignmentExpression>(expression)) >+ checkErrorAndVisit(downcast<AST::AssignmentExpression>(expression)); >+ else if (is<AST::BooleanLiteral>(expression)) >+ checkErrorAndVisit(downcast<AST::BooleanLiteral>(expression)); >+ else if (is<AST::CallExpression>(expression)) >+ checkErrorAndVisit(downcast<AST::CallExpression>(expression)); >+ else if (is<AST::CommaExpression>(expression)) >+ checkErrorAndVisit(downcast<AST::CommaExpression>(expression)); >+ else if (is<AST::DereferenceExpression>(expression)) >+ checkErrorAndVisit(downcast<AST::DereferenceExpression>(expression)); >+ else if (is<AST::FloatLiteral>(expression)) >+ checkErrorAndVisit(downcast<AST::FloatLiteral>(expression)); >+ else if (is<AST::IntegerLiteral>(expression)) >+ checkErrorAndVisit(downcast<AST::IntegerLiteral>(expression)); >+ else if (is<AST::LogicalExpression>(expression)) >+ checkErrorAndVisit(downcast<AST::LogicalExpression>(expression)); >+ else if (is<AST::LogicalNotExpression>(expression)) >+ checkErrorAndVisit(downcast<AST::LogicalNotExpression>(expression)); >+ else if (is<AST::MakeArrayReferenceExpression>(expression)) >+ checkErrorAndVisit(downcast<AST::MakeArrayReferenceExpression>(expression)); >+ else if (is<AST::MakePointerExpression>(expression)) >+ checkErrorAndVisit(downcast<AST::MakePointerExpression>(expression)); >+ else if (is<AST::NullLiteral>(expression)) >+ checkErrorAndVisit(downcast<AST::NullLiteral>(expression)); >+ else if (is<AST::DotExpression>(expression)) >+ checkErrorAndVisit(downcast<AST::DotExpression>(expression)); >+ else if (is<AST::IndexExpression>(expression)) >+ checkErrorAndVisit(downcast<AST::IndexExpression>(expression)); >+ else if (is<AST::ReadModifyWriteExpression>(expression)) >+ checkErrorAndVisit(downcast<AST::ReadModifyWriteExpression>(expression)); >+ else if (is<AST::TernaryExpression>(expression)) >+ checkErrorAndVisit(downcast<AST::TernaryExpression>(expression)); >+ else if (is<AST::UnsignedIntegerLiteral>(expression)) >+ checkErrorAndVisit(downcast<AST::UnsignedIntegerLiteral>(expression)); >+ else { >+ ASSERT(is<AST::VariableReference>(expression)); >+ checkErrorAndVisit(downcast<AST::VariableReference>(expression)); >+ } >+} >+ >+void Visitor::visit(AST::DotExpression& dotExpression) >+{ >+ checkErrorAndVisit(static_cast<AST::PropertyAccessExpression&>(dotExpression)); >+} >+ >+void Visitor::visit(AST::IndexExpression& indexExpression) >+{ >+ checkErrorAndVisit(indexExpression.indexExpression()); >+ checkErrorAndVisit(static_cast<AST::PropertyAccessExpression&>(indexExpression)); >+} >+ >+void Visitor::visit(AST::PropertyAccessExpression& expression) >+{ >+ checkErrorAndVisit(expression.base()); >+} >+ >+void Visitor::visit(AST::EffectfulExpressionStatement& effectfulExpressionStatement) >+{ >+ checkErrorAndVisit(effectfulExpressionStatement.effectfulExpression()); >+} >+ >+void Visitor::visit(AST::Fallthrough&) >+{ >+} >+ >+void Visitor::visit(AST::ForLoop& forLoop) >+{ >+ WTF::visit(WTF::makeVisitor([&](AST::VariableDeclarationsStatement& variableDeclarationsStatement) { >+ checkErrorAndVisit(variableDeclarationsStatement); >+ }, [&](UniqueRef<AST::Expression>& expression) { >+ checkErrorAndVisit(static_cast<AST::Expression&>(expression)); >+ }), forLoop.initialization()); >+ if (forLoop.condition()) >+ checkErrorAndVisit(*forLoop.condition()); >+ if (forLoop.increment()) >+ checkErrorAndVisit(*forLoop.increment()); >+ checkErrorAndVisit(forLoop.body()); >+} >+ >+void Visitor::visit(AST::IfStatement& ifStatement) >+{ >+ checkErrorAndVisit(ifStatement.conditional()); >+ checkErrorAndVisit(ifStatement.body()); >+ if (ifStatement.elseBody()) >+ checkErrorAndVisit(*ifStatement.elseBody()); >+} >+ >+void Visitor::visit(AST::Return& returnStatement) >+{ >+ if (returnStatement.value()) >+ checkErrorAndVisit(*returnStatement.value()); >+} >+ >+void Visitor::visit(AST::SwitchCase& switchCase) >+{ >+ if (switchCase.value()) >+ checkErrorAndVisit(*switchCase.value()); >+ checkErrorAndVisit(switchCase.block()); >+} >+ >+void Visitor::visit(AST::SwitchStatement& switchStatement) >+{ >+ checkErrorAndVisit(switchStatement.value()); >+ for (auto& switchCase : switchStatement.switchCases()) >+ checkErrorAndVisit(switchCase); >+} >+ >+void Visitor::visit(AST::Trap&) >+{ >+} >+ >+void Visitor::visit(AST::VariableDeclarationsStatement& variableDeclarationsStatement) >+{ >+ for (auto& variableDeclaration : variableDeclarationsStatement.variableDeclarations()) >+ checkErrorAndVisit(variableDeclaration); >+} >+ >+void Visitor::visit(AST::WhileLoop& whileLoop) >+{ >+ checkErrorAndVisit(whileLoop.conditional()); >+ checkErrorAndVisit(whileLoop.body()); >+} >+ >+void Visitor::visit(AST::VariableDeclaration& variableDeclaration) >+{ >+ if (variableDeclaration.type()) >+ checkErrorAndVisit(*variableDeclaration.type()); >+ if (variableDeclaration.semantic()) >+ checkErrorAndVisit(*variableDeclaration.semantic()); >+ if (variableDeclaration.initializer()) >+ checkErrorAndVisit(*variableDeclaration.initializer()); >+} >+ >+void Visitor::visit(AST::AssignmentExpression& assignmentExpression) >+{ >+ checkErrorAndVisit(assignmentExpression.left()); >+ checkErrorAndVisit(assignmentExpression.right()); >+} >+ >+void Visitor::visit(AST::CallExpression& callExpression) >+{ >+ for (auto& argument : callExpression.arguments()) >+ checkErrorAndVisit(static_cast<AST::Expression&>(argument)); >+ if (callExpression.castReturnType()) >+ checkErrorAndVisit(callExpression.castReturnType()->get()); >+} >+ >+void Visitor::visit(AST::CommaExpression& commaExpression) >+{ >+ for (auto& expression : commaExpression.list()) >+ checkErrorAndVisit(static_cast<AST::Expression&>(expression)); >+} >+ >+void Visitor::visit(AST::DereferenceExpression& dereferenceExpression) >+{ >+ checkErrorAndVisit(dereferenceExpression.pointer()); >+} >+ >+void Visitor::visit(AST::LogicalExpression& logicalExpression) >+{ >+ checkErrorAndVisit(logicalExpression.left()); >+ checkErrorAndVisit(logicalExpression.right()); >+} >+ >+void Visitor::visit(AST::LogicalNotExpression& logicalNotExpression) >+{ >+ checkErrorAndVisit(logicalNotExpression.operand()); >+} >+ >+void Visitor::visit(AST::MakeArrayReferenceExpression& makeArrayReferenceExpression) >+{ >+ checkErrorAndVisit(makeArrayReferenceExpression.lValue()); >+} >+ >+void Visitor::visit(AST::MakePointerExpression& makePointerExpression) >+{ >+ checkErrorAndVisit(makePointerExpression.lValue()); >+} >+ >+void Visitor::visit(AST::ReadModifyWriteExpression& readModifyWriteExpression) >+{ >+ checkErrorAndVisit(readModifyWriteExpression.lValue()); >+ checkErrorAndVisit(readModifyWriteExpression.oldValue()); >+ checkErrorAndVisit(readModifyWriteExpression.newValue()); >+ checkErrorAndVisit(readModifyWriteExpression.newValueExpression()); >+ checkErrorAndVisit(readModifyWriteExpression.resultExpression()); >+} >+ >+void Visitor::visit(AST::TernaryExpression& ternaryExpression) >+{ >+ checkErrorAndVisit(ternaryExpression.predicate()); >+ checkErrorAndVisit(ternaryExpression.bodyExpression()); >+ checkErrorAndVisit(ternaryExpression.elseExpression()); >+} >+ >+void Visitor::visit(AST::VariableReference&) >+{ >+} >+ >+void Visitor::checkErrorAndVisit(Program& program) >+{ >+ if (!error()) >+ visit(program); >+} >+ >+void Visitor::checkErrorAndVisit(AST::UnnamedType& unnamedType) >+{ >+ if (!error()) >+ visit(unnamedType); >+} >+ >+void Visitor::checkErrorAndVisit(AST::NamedType& namedType) >+{ >+ if (!error()) >+ visit(namedType); >+} >+ >+void Visitor::checkErrorAndVisit(AST::TypeDefinition& typeDefinition) >+{ >+ if (!error()) >+ visit(typeDefinition); >+} >+ >+void Visitor::checkErrorAndVisit(AST::StructureDefinition& structureDefinition) >+{ >+ if (!error()) >+ visit(structureDefinition); >+} >+ >+void Visitor::checkErrorAndVisit(AST::EnumerationDefinition& enumerationDefinition) >+{ >+ if (!error()) >+ visit(enumerationDefinition); >+} >+ >+void Visitor::checkErrorAndVisit(AST::FunctionDefinition& functionDefinition) >+{ >+ if (!error()) >+ visit(functionDefinition); >+} >+ >+void Visitor::checkErrorAndVisit(AST::NativeFunctionDeclaration& nativeFunctionDeclaration) >+{ >+ if (!error()) >+ visit(nativeFunctionDeclaration); >+} >+ >+void Visitor::checkErrorAndVisit(AST::NativeTypeDeclaration& nativeTypeDeclaration) >+{ >+ if (!error()) >+ visit(nativeTypeDeclaration); >+} >+ >+void Visitor::checkErrorAndVisit(AST::TypeReference& typeReference) >+{ >+ if (!error()) >+ visit(typeReference); >+} >+ >+void Visitor::checkErrorAndVisit(AST::PointerType& pointerType) >+{ >+ if (!error()) >+ visit(pointerType); >+} >+ >+void Visitor::checkErrorAndVisit(AST::ArrayReferenceType& arrayReferenceType) >+{ >+ if (!error()) >+ visit(arrayReferenceType); >+} >+ >+void Visitor::checkErrorAndVisit(AST::ArrayType& arrayType) >+{ >+ if (!error()) >+ visit(arrayType); >+} >+ >+void Visitor::checkErrorAndVisit(AST::StructureElement& structureElement) >+{ >+ if (!error()) >+ visit(structureElement); >+} >+ >+void Visitor::checkErrorAndVisit(AST::EnumerationMember& enumerationMember) >+{ >+ if (!error()) >+ visit(enumerationMember); >+} >+ >+void Visitor::checkErrorAndVisit(AST::FunctionDeclaration& functionDeclaration) >+{ >+ if (!error()) >+ visit(functionDeclaration); >+} >+ >+void Visitor::checkErrorAndVisit(AST::TypeArgument& typeArgument) >+{ >+ if (!error()) >+ visit(typeArgument); >+} >+ >+void Visitor::checkErrorAndVisit(AST::ReferenceType& referenceType) >+{ >+ if (!error()) >+ visit(referenceType); >+} >+ >+void Visitor::checkErrorAndVisit(AST::Semantic& semantic) >+{ >+ if (!error()) >+ visit(semantic); >+} >+ >+void Visitor::checkErrorAndVisit(AST::ConstantExpression& constantExpression) >+{ >+ if (!error()) >+ visit(constantExpression); >+} >+ >+void Visitor::checkErrorAndVisit(AST::AttributeBlock& attributeBlock) >+{ >+ if (!error()) >+ visit(attributeBlock); >+} >+ >+void Visitor::checkErrorAndVisit(AST::BuiltInSemantic& builtInSemantic) >+{ >+ if (!error()) >+ visit(builtInSemantic); >+} >+ >+void Visitor::checkErrorAndVisit(AST::ResourceSemantic& resourceSemantic) >+{ >+ if (!error()) >+ visit(resourceSemantic); >+} >+ >+void Visitor::checkErrorAndVisit(AST::SpecializationConstantSemantic& specializationConstantSemantic) >+{ >+ if (!error()) >+ visit(specializationConstantSemantic); >+} >+ >+void Visitor::checkErrorAndVisit(AST::StageInOutSemantic& stageInOutSemantic) >+{ >+ if (!error()) >+ visit(stageInOutSemantic); >+} >+ >+void Visitor::checkErrorAndVisit(AST::IntegerLiteral& integerLiteral) >+{ >+ if (!error()) >+ visit(integerLiteral); >+} >+ >+void Visitor::checkErrorAndVisit(AST::UnsignedIntegerLiteral& unsignedIntegerLiteral) >+{ >+ if (!error()) >+ visit(unsignedIntegerLiteral); >+} >+ >+void Visitor::checkErrorAndVisit(AST::FloatLiteral& floatLiteral) >+{ >+ if (!error()) >+ visit(floatLiteral); >+} >+ >+void Visitor::checkErrorAndVisit(AST::NullLiteral& nullLiteral) >+{ >+ if (!error()) >+ visit(nullLiteral); >+} >+ >+void Visitor::checkErrorAndVisit(AST::BooleanLiteral& booleanLiteral) >+{ >+ if (!error()) >+ visit(booleanLiteral); >+} >+ >+void Visitor::checkErrorAndVisit(AST::IntegerLiteralType& integerLiteralType) >+{ >+ if (!error()) >+ visit(integerLiteralType); >+} >+ >+void Visitor::checkErrorAndVisit(AST::UnsignedIntegerLiteralType& unsignedIntegerLiteralType) >+{ >+ if (!error()) >+ visit(unsignedIntegerLiteralType); >+} >+ >+void Visitor::checkErrorAndVisit(AST::FloatLiteralType& floatLiteralType) >+{ >+ if (!error()) >+ visit(floatLiteralType); >+} >+ >+void Visitor::checkErrorAndVisit(AST::NullLiteralType& nullLiteralType) >+{ >+ if (!error()) >+ visit(nullLiteralType); >+} >+ >+void Visitor::checkErrorAndVisit(AST::ConstantExpressionEnumerationMemberReference& constantExpressionEnumerationMemberReference) >+{ >+ if (!error()) >+ visit(constantExpressionEnumerationMemberReference); >+} >+ >+void Visitor::checkErrorAndVisit(AST::FunctionAttribute& functionAttribute) >+{ >+ if (!error()) >+ visit(functionAttribute); >+} >+ >+void Visitor::checkErrorAndVisit(AST::NumThreadsFunctionAttribute& numThreadsFunctionAttribute) >+{ >+ if (!error()) >+ visit(numThreadsFunctionAttribute); >+} >+ >+void Visitor::checkErrorAndVisit(AST::Block& block) >+{ >+ if (!error()) >+ visit(block); >+} >+ >+void Visitor::checkErrorAndVisit(AST::Statement& statement) >+{ >+ if (!error()) >+ visit(statement); >+} >+ >+void Visitor::checkErrorAndVisit(AST::Break& breakStatement) >+{ >+ if (!error()) >+ visit(breakStatement); >+} >+ >+void Visitor::checkErrorAndVisit(AST::Continue& continueStatement) >+{ >+ if (!error()) >+ visit(continueStatement); >+} >+ >+void Visitor::checkErrorAndVisit(AST::DoWhileLoop& doWhileLoop) >+{ >+ if (!error()) >+ visit(doWhileLoop); >+} >+ >+void Visitor::checkErrorAndVisit(AST::Expression& expression) >+{ >+ if (!error()) >+ visit(expression); >+} >+ >+void Visitor::checkErrorAndVisit(AST::DotExpression& dotExpression) >+{ >+ if (!error()) >+ visit(dotExpression); >+} >+ >+void Visitor::checkErrorAndVisit(AST::IndexExpression& indexExpression) >+{ >+ if (!error()) >+ visit(indexExpression); >+} >+ >+void Visitor::checkErrorAndVisit(AST::PropertyAccessExpression& propertyAccessExpression) >+{ >+ if (!error()) >+ visit(propertyAccessExpression); >+} >+ >+void Visitor::checkErrorAndVisit(AST::EffectfulExpressionStatement& effectfulExpressionStatement) >+{ >+ if (!error()) >+ visit(effectfulExpressionStatement); >+} >+ >+void Visitor::checkErrorAndVisit(AST::Fallthrough& fallthroughStatement) >+{ >+ if (!error()) >+ visit(fallthroughStatement); >+} >+ >+void Visitor::checkErrorAndVisit(AST::ForLoop& forLoop) >+{ >+ if (!error()) >+ visit(forLoop); >+} >+ >+void Visitor::checkErrorAndVisit(AST::IfStatement& ifStatement) >+{ >+ if (!error()) >+ visit(ifStatement); >+} >+ >+void Visitor::checkErrorAndVisit(AST::Return& returnStatement) >+{ >+ if (!error()) >+ visit(returnStatement); >+} >+ >+void Visitor::checkErrorAndVisit(AST::SwitchCase& switchCase) >+{ >+ if (!error()) >+ visit(switchCase); >+} >+ >+void Visitor::checkErrorAndVisit(AST::SwitchStatement& switchStatement) >+{ >+ if (!error()) >+ visit(switchStatement); >+} >+ >+void Visitor::checkErrorAndVisit(AST::Trap& trap) >+{ >+ if (!error()) >+ visit(trap); >+} >+ >+void Visitor::checkErrorAndVisit(AST::VariableDeclarationsStatement& variableDeclarationsStatement) >+{ >+ if (!error()) >+ visit(variableDeclarationsStatement); >+} >+ >+void Visitor::checkErrorAndVisit(AST::WhileLoop& whileLoop) >+{ >+ if (!error()) >+ visit(whileLoop); >+} >+ >+void Visitor::checkErrorAndVisit(AST::VariableDeclaration& variableDeclaration) >+{ >+ if (!error()) >+ visit(variableDeclaration); >+} >+ >+void Visitor::checkErrorAndVisit(AST::AssignmentExpression& assignmentExpression) >+{ >+ if (!error()) >+ visit(assignmentExpression); >+} >+ >+void Visitor::checkErrorAndVisit(AST::CallExpression& callExpression) >+{ >+ if (!error()) >+ visit(callExpression); >+} >+ >+void Visitor::checkErrorAndVisit(AST::CommaExpression& commaExpression) >+{ >+ if (!error()) >+ visit(commaExpression); >+} >+ >+void Visitor::checkErrorAndVisit(AST::DereferenceExpression& dereferenceExpression) >+{ >+ if (!error()) >+ visit(dereferenceExpression); >+} >+ >+void Visitor::checkErrorAndVisit(AST::LogicalExpression& logicalExpression) >+{ >+ if (!error()) >+ visit(logicalExpression); >+} >+ >+void Visitor::checkErrorAndVisit(AST::LogicalNotExpression& logicalNotExpression) >+{ >+ if (!error()) >+ visit(logicalNotExpression); >+} >+ >+void Visitor::checkErrorAndVisit(AST::MakeArrayReferenceExpression& makeArrayReferenceExpression) >+{ >+ if (!error()) >+ visit(makeArrayReferenceExpression); >+} >+ >+void Visitor::checkErrorAndVisit(AST::MakePointerExpression& makePointerExpression) >+{ >+ if (!error()) >+ visit(makePointerExpression); >+} >+ >+void Visitor::checkErrorAndVisit(AST::ReadModifyWriteExpression& readModifyWriteExpression) >+{ >+ if (!error()) >+ visit(readModifyWriteExpression); >+} >+ >+void Visitor::checkErrorAndVisit(AST::TernaryExpression& ternaryExpression) >+{ >+ if (!error()) >+ visit(ternaryExpression); >+} >+ >+void Visitor::checkErrorAndVisit(AST::VariableReference& variableReference) >+{ >+ if (!error()) >+ visit(variableReference); >+} >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.h >index 516856e41d0..85e78ff599e 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.h >@@ -27,543 +27,234 @@ > > #if ENABLE(WEBGPU) > >-#include "WHLSLProgram.h" >-#include "WHLSLAnonymousVariableDeclaration.h" >-#include "WHLSLArrayReferenceType.h" >-#include "WHLSLArrayType.h" >-#include "WHLSLAssignmentExpression.h" >-#include "WHLSLBaseFunctionAttribute.h" >-#include "WHLSLBaseSemantic.h" >-#include "WHLSLBlock.h" >-#include "WHLSLBooleanLiteral.h" >-#include "WHLSLBreak.h" >-#include "WHLSLBuiltInSemantic.h" >-#include "WHLSLCallExpression.h" >-#include "WHLSLCommaExpression.h" >-#include "WHLSLConstantExpression.h" >-#include "WHLSLConstantExpressionEnumerationMemberReference.h" >-#include "WHLSLContinue.h" >-#include "WHLSLDereferenceExpression.h" >-#include "WHLSLDoWhileLoop.h" >-#include "WHLSLDotExpression.h" >-#include "WHLSLEffectfulExpressionStatement.h" >-#include "WHLSLEnumerationDefinition.h" >-#include "WHLSLEnumerationMember.h" >-#include "WHLSLExpression.h" >-#include "WHLSLFallthrough.h" >-#include "WHLSLFloatLiteral.h" >-#include "WHLSLForLoop.h" > #include "WHLSLFunctionAttribute.h" >-#include "WHLSLFunctionDeclaration.h" >-#include "WHLSLFunctionDefinition.h" >-#include "WHLSLIfStatement.h" >-#include "WHLSLIndexExpression.h" >-#include "WHLSLIntegerLiteral.h" >-#include "WHLSLLogicalExpression.h" >-#include "WHLSLLogicalNotExpression.h" >-#include "WHLSLMakeArrayReferenceExpression.h" >-#include "WHLSLMakePointerExpression.h" >-#include "WHLSLNativeFunctionDeclaration.h" >-#include "WHLSLNativeTypeDeclaration.h" >-#include "WHLSLNode.h" >-#include "WHLSLNullLiteral.h" >-#include "WHLSLNumThreadsFunctionAttribute.h" >-#include "WHLSLParameter.h" >-#include "WHLSLPointerType.h" >-#include "WHLSLPropertyAccessExpression.h" >-#include "WHLSLQualifier.h" >-#include "WHLSLReadModifyWriteExpression.h" >-#include "WHLSLReferenceType.h" >-#include "WHLSLResourceSemantic.h" >-#include "WHLSLReturn.h" > #include "WHLSLSemantic.h" >-#include "WHLSLSpecializationConstantSemantic.h" >-#include "WHLSLStageInOutSemantic.h" >-#include "WHLSLStatement.h" >-#include "WHLSLStructureDefinition.h" >-#include "WHLSLStructureElement.h" >-#include "WHLSLSwitchCase.h" >-#include "WHLSLSwitchStatement.h" >-#include "WHLSLTernaryExpression.h" >-#include "WHLSLTrap.h" >-#include "WHLSLType.h" > #include "WHLSLTypeArgument.h" >-#include "WHLSLTypeDefinition.h" >-#include "WHLSLTypeReference.h" >-#include "WHLSLUnsignedIntegerLiteral.h" >-#include "WHLSLValue.h" >-#include "WHLSLVariableDeclaration.h" >-#include "WHLSLVariableDeclarationsStatement.h" >-#include "WHLSLVariableReference.h" >-#include "WHLSLWhileLoop.h" >- > > namespace WebCore { > > namespace WHLSL { > >-class Visitor { >- ~Visitor() = default; >- >- virtual void visit(Program& program) >- { >- for (auto& typeDefinition : program.typeDefinitions()) >- visit(typeDefinition); >- for (auto& structureDefinition : program.structureDefinitions()) >- visit(structureDefinition); >- for (auto& enumerationDefinition : program.enumerationDefinitions()) >- visit(enumerationDefinition); >- for (auto& functionDefinition : program.functionDefinitions()) >- visit(functionDefinition); >- for (auto& nativeFunctionDeclaration : program.nativeFunctionDeclarations()) >- visit(nativeFunctionDeclaration); >- for (auto& nativeTypeDeclaration : program.nativeTypeDeclarations()) >- visit(nativeTypeDeclaration); >- } >- >- void visitType(AST::Type& type) >- { >- if (is<AST::TypeReference>(type)) >- visit(downcast<AST::TypeReference>(type)); >- else if (is<AST::PointerType>(type)) >- visit(downcast<AST::PointerType>(type)); >- else if (is<AST::ArrayReferenceType>(type)) >- visit(downcast<AST::ArrayReferenceType>(type)); >- else { >- ASSERT(is<AST::ArrayType>(type)); >- visit(downcast<AST::ArrayType>(type)); >- } >- } >- >- virtual void visit(AST::TypeDefinition& typeDefinition) >- { >- visitType(typeDefinition.type()); >- } >- >- virtual void visit(AST::StructureDefinition& structureDefinition) >- { >- for (auto& structureElement : structureDefinition.structureElements()) >- visit(structureElement); >- } >- >- virtual void visit(AST::EnumerationDefinition& enumerationDefinition) >- { >- visitType(enumerationDefinition.type()); >- for (auto& enumerationMember : enumerationDefinition.enumerationMembers()) >- visit(enumerationMember); >- } >- >- virtual void visit(AST::FunctionDefinition& functionDefinition) >- { >- visit(static_cast<AST::FunctionDeclaration&>(functionDefinition)); >- visit(functionDefinition.block()); >- } >- >- virtual void visit(AST::NativeFunctionDeclaration& nativeFunctionDeclaration) >- { >- visit(static_cast<AST::FunctionDeclaration&>(nativeFunctionDeclaration)); >- } >- >- virtual void visit(AST::NativeTypeDeclaration& nativeTypeDeclaration) >- { >- for (auto& typeArgument : nativeTypeDeclaration.typeArguments()) >- visit(typeArgument); >- } >- >- virtual void visit(AST::TypeReference& typeReference) >- { >- for (auto& typeArgument : typeReference.typeArguments()) >- visit(typeArgument); >- } >- >- virtual void visit(AST::PointerType& pointerType) >- { >- visit(static_cast<AST::ReferenceType&>(pointerType)); >- } >- >- virtual void visit(AST::ArrayReferenceType& arrayReferenceType) >- { >- visit(static_cast<AST::ReferenceType&>(arrayReferenceType)); >- } >- >- virtual void visit(AST::ArrayType& arrayType) >- { >- visitType(arrayType.type()); >- } >- >- virtual void visit(AST::StructureElement& structureElement) >- { >- visitType(structureElement.type()); >- if (structureElement.semantic()) >- visit(*structureElement.semantic()); >- } >- >- virtual void visit(AST::EnumerationMember& enumerationMember) >- { >- if (enumerationMember.value()) >- visit(*enumerationMember.value()); >- } >- >- virtual void visit(AST::FunctionDeclaration& functionDeclaration) >- { >- visit(functionDeclaration.attributeBlock()); >- visitType(functionDeclaration.type()); >- for (auto& parameter : functionDeclaration.parameters()) >- visit(parameter); >- if (functionDeclaration.semantic()) >- visit(*functionDeclaration.semantic()); >- } >- >- virtual void visit(AST::TypeArgument& typeArgument) >- { >- WTF::visit(WTF::makeVisitor([&](AST::ConstantExpression& constantExpression) { >- visit(constantExpression); >- }, [&](std::unique_ptr<AST::TypeReference>& typeReference) { >- visit(*typeReference); >- }), typeArgument); >- } >- >- virtual void visit(AST::ReferenceType& referenceType) >- { >- visitType(referenceType.elementType()); >- } >- >- virtual void visit(AST::Semantic& semantic) >- { >- WTF::visit(WTF::makeVisitor([&](AST::BuiltInSemantic& builtInSemantic) { >- visit(builtInSemantic); >- }, [&](AST::ResourceSemantic& resourceSemantic) { >- visit(resourceSemantic); >- }, [&](AST::SpecializationConstantSemantic& specializationConstantSemantic) { >- visit(specializationConstantSemantic); >- }, [&](AST::StageInOutSemantic& stageInOutSemantic) { >- visit(stageInOutSemantic); >- }), semantic); >- } >- >- virtual void visit(AST::ConstantExpression& constantExpression) >- { >- constantExpression.visit(WTF::makeVisitor([&](AST::IntegerLiteral& integerLiteral) { >- visit(integerLiteral); >- }, [&](AST::UnsignedIntegerLiteral& unsignedIntegerLiteral) { >- visit(unsignedIntegerLiteral); >- }, [&](AST::FloatLiteral& floatLiteral) { >- visit(floatLiteral); >- }, [&](AST::NullLiteral& nullLiteral) { >- visit(nullLiteral); >- }, [&](AST::BooleanLiteral& booleanLiteral) { >- visit(booleanLiteral); >- }, [&](AST::ConstantExpressionEnumerationMemberReference& constantExpressionEnumerationMemberReference) { >- visit(constantExpressionEnumerationMemberReference); >- })); >- } >- >- virtual void visit(AST::AttributeBlock& attributeBlock) >- { >- for (auto& functionAttribute : attributeBlock) >- visit(functionAttribute); >- } >- >- virtual void visit(AST::Parameter& parameter) >- { >- visitType(parameter.type()); >- if (parameter.semantic()) >- visit(*parameter.semantic()); >- } >- >- virtual void visit(AST::BuiltInSemantic&) >- { >- } >- >- virtual void visit(AST::ResourceSemantic&) >- { >- } >- >- virtual void visit(AST::SpecializationConstantSemantic&) >- { >- } >- >- virtual void visit(AST::StageInOutSemantic&) >- { >- } >- >- virtual void visit(AST::IntegerLiteral&) >- { >- } >- >- virtual void visit(AST::UnsignedIntegerLiteral&) >- { >- } >- >- virtual void visit(AST::FloatLiteral&) >- { >- } >- >- virtual void visit(AST::NullLiteral&) >- { >- } >- >- virtual void visit(AST::BooleanLiteral&) >- { >- } >- >- virtual void visit(AST::ConstantExpressionEnumerationMemberReference&) >- { >- } >- >- virtual void visit(AST::FunctionAttribute& functionAttribute) >- { >- WTF::visit(WTF::makeVisitor([&](AST::NumThreadsFunctionAttribute& numThreadsFunctionAttribute) { >- visit(numThreadsFunctionAttribute); >- }), functionAttribute); >- } >- >- virtual void visit(AST::NumThreadsFunctionAttribute&) >- { >- } >- >- virtual void visit(AST::Block& block) >- { >- for (auto& statement : block.statements()) >- visit(*statement); >- } >- >- virtual void visit(AST::Statement& statement) >- { >- if (is<AST::Block>(statement)) >- visit(downcast<AST::Block>(statement)); >- else if (is<AST::Break>(statement)) >- visit(downcast<AST::Break>(statement)); >- else if (is<AST::Continue>(statement)) >- visit(downcast<AST::Continue>(statement)); >- else if (is<AST::DoWhileLoop>(statement)) >- visit(downcast<AST::DoWhileLoop>(statement)); >- else if (is<AST::EffectfulExpressionStatement>(statement)) >- visit(downcast<AST::EffectfulExpressionStatement>(statement)); >- else if (is<AST::Fallthrough>(statement)) >- visit(downcast<AST::Fallthrough>(statement)); >- else if (is<AST::ForLoop>(statement)) >- visit(downcast<AST::ForLoop>(statement)); >- else if (is<AST::IfStatement>(statement)) >- visit(downcast<AST::IfStatement>(statement)); >- else if (is<AST::Return>(statement)) >- visit(downcast<AST::Return>(statement)); >- else if (is<AST::SwitchCase>(statement)) >- visit(downcast<AST::SwitchCase>(statement)); >- else if (is<AST::SwitchStatement>(statement)) >- visit(downcast<AST::SwitchStatement>(statement)); >- else if (is<AST::Trap>(statement)) >- visit(downcast<AST::Trap>(statement)); >- else if (is<AST::VariableDeclarationsStatement>(statement)) >- visit(downcast<AST::VariableDeclarationsStatement>(statement)); >- else { >- ASSERT(is<AST::WhileLoop>(statement)); >- visit(downcast<AST::WhileLoop>(statement)); >- } >- } >- >- virtual void visit(AST::Break&) >- { >- } >- >- virtual void visit(AST::Continue&) >- { >- } >- >- virtual void visit(AST::DoWhileLoop& doWhileLoop) >- { >- visit(doWhileLoop.body()); >- visit(doWhileLoop.conditional()); >- } >- >- virtual void visit(AST::Expression& expression) >- { >- if (is<AST::AssignmentExpression>(expression)) >- visit(downcast<AST::AssignmentExpression>(expression)); >- else if (is<AST::BooleanLiteral>(expression)) >- visit(downcast<AST::BooleanLiteral>(expression)); >- else if (is<AST::CallExpression>(expression)) >- visit(downcast<AST::CallExpression>(expression)); >- else if (is<AST::CommaExpression>(expression)) >- visit(downcast<AST::CommaExpression>(expression)); >- else if (is<AST::DereferenceExpression>(expression)) >- visit(downcast<AST::DereferenceExpression>(expression)); >- else if (is<AST::FloatLiteral>(expression)) >- visit(downcast<AST::FloatLiteral>(expression)); >- else if (is<AST::IntegerLiteral>(expression)) >- visit(downcast<AST::IntegerLiteral>(expression)); >- else if (is<AST::LogicalExpression>(expression)) >- visit(downcast<AST::LogicalExpression>(expression)); >- else if (is<AST::LogicalNotExpression>(expression)) >- visit(downcast<AST::LogicalNotExpression>(expression)); >- else if (is<AST::MakeArrayReferenceExpression>(expression)) >- visit(downcast<AST::MakeArrayReferenceExpression>(expression)); >- else if (is<AST::MakePointerExpression>(expression)) >- visit(downcast<AST::MakePointerExpression>(expression)); >- else if (is<AST::NullLiteral>(expression)) >- visit(downcast<AST::NullLiteral>(expression)); >- else if (is<AST::PropertyAccessExpression>(expression)) >- visit(downcast<AST::PropertyAccessExpression>(expression)); >- else if (is<AST::ReadModifyWriteExpression>(expression)) >- visit(downcast<AST::ReadModifyWriteExpression>(expression)); >- else if (is<AST::TernaryExpression>(expression)) >- visit(downcast<AST::TernaryExpression>(expression)); >- else if (is<AST::UnsignedIntegerLiteral>(expression)) >- visit(downcast<AST::UnsignedIntegerLiteral>(expression)); >- else { >- ASSERT(is<AST::VariableReference>(expression)); >- visit(downcast<AST::VariableReference>(expression)); >- } >- } >- >- virtual void visit(AST::EffectfulExpressionStatement& effectfulExpressionStatement) >- { >- visit(effectfulExpressionStatement.effectfulExpression()); >- } >- >- virtual void visit(AST::Fallthrough&) >- { >- } >- >- virtual void visit(AST::ForLoop& forLoop) >- { >- WTF::visit(WTF::makeVisitor([&](AST::VariableDeclarationsStatement& variableDeclarationsStatement) { >- visit(variableDeclarationsStatement); >- }, [&](std::unique_ptr<AST::Expression>& expression) { >- visit(*expression); >- }), forLoop.initialization()); >- if (forLoop.condition()) >- visit(*forLoop.condition()); >- if (forLoop.increment()) >- visit(*forLoop.increment()); >- visit(forLoop.body()); >- } >- >- virtual void visit(AST::IfStatement& ifStatement) >- { >- visit(ifStatement.conditional()); >- visit(ifStatement.body()); >- if (ifStatement.elseBody()) >- visit(*ifStatement.elseBody()); >- } >- >- virtual void visit(AST::Return& returnStatement) >- { >- if (returnStatement.value()) >- visit(*returnStatement.value()); >- } >- >- virtual void visit(AST::SwitchCase& switchCase) >- { >- if (switchCase.value()) >- visit(*switchCase.value()); >- visit(switchCase.block()); >- } >- >- virtual void visit(AST::SwitchStatement& switchStatement) >- { >- visit(switchStatement.value()); >- for (auto& switchCase : switchStatement.switchCases()) >- visit(switchCase); >- } >- >- virtual void visit(AST::Trap&) >- { >- } >+class Program; >+ >+namespace AST { >+ >+class TypeDefinition; >+class StructureDefinition; >+class EnumerationDefinition; >+class FunctionDefinition; >+class NativeFunctionDeclaration; >+class NativeTypeDeclaration; >+class TypeReference; >+class PointerType; >+class ArrayReferenceType; >+class ArrayType; >+class StructureElement; >+class EnumerationMember; >+class FunctionDeclaration; >+class ReferenceType; >+class ConstantExpression; >+class BuiltInSemantic; >+class ResourceSemantic; >+class SpecializationConstantSemantic; >+class StageInOutSemantic; >+class IntegerLiteral; >+class UnsignedIntegerLiteral; >+class FloatLiteral; >+class NullLiteral; >+class BooleanLiteral; >+class ConstantExpressionEnumerationMemberReference; >+class NumThreadsFunctionAttribute; >+class Block; >+class Statement; >+class Break; >+class Continue; >+class DoWhileLoop; >+class Expression; >+class DotExpression; >+class IndexExpression; >+class PropertyAccessExpression; >+class EffectfulExpressionStatement; >+class Fallthrough; >+class ForLoop; >+class IfStatement; >+class Return; >+class SwitchCase; >+class SwitchStatement; >+class Trap; >+class VariableDeclarationsStatement; >+class WhileLoop; >+class VariableDeclaration; >+class AssignmentExpression; >+class CallExpression; >+class CommaExpression; >+class DereferenceExpression; >+class LogicalExpression; >+class LogicalNotExpression; >+class MakeArrayReferenceExpression; >+class MakePointerExpression; >+class ReadModifyWriteExpression; >+class TernaryExpression; >+class VariableReference; >+class UnnamedType; >+class NamedType; > >- virtual void visit(AST::VariableDeclarationsStatement& variableDeclarationsStatement) >- { >- for (auto& variableDeclaration : variableDeclarationsStatement.variableDeclarations()) >- visit(variableDeclaration); >- } >- >- virtual void visit(AST::WhileLoop& whileLoop) >- { >- visit(whileLoop.conditional()); >- visit(whileLoop.body()); >- } >- >- virtual void visit(AST::VariableDeclaration& variableDeclaration) >- { >- visitType(variableDeclaration.type()); >- if (variableDeclaration.semantic()) >- visit(*variableDeclaration.semantic()); >- if (variableDeclaration.initializer()) >- visit(*variableDeclaration.initializer()); >- } >- >- virtual void visit(AST::AssignmentExpression& assignmentExpression) >- { >- visit(assignmentExpression.left()); >- visit(assignmentExpression.right()); >- } >- >- virtual void visit(AST::CallExpression& callExpression) >- { >- for (auto& argument : callExpression.arguments()) >- visit(*argument); >- } >- >- virtual void visit(AST::CommaExpression& commaExpression) >- { >- for (auto& expression : commaExpression.list()) >- visit(*expression); >- } >- >- virtual void visit(AST::DereferenceExpression& dereferenceExpression) >- { >- visit(dereferenceExpression.pointer()); >- } >- >- virtual void visit(AST::LogicalExpression& logicalExpression) >- { >- visit(logicalExpression.left()); >- visit(logicalExpression.right()); >- } >- >- virtual void visit(AST::LogicalNotExpression& logicalNotExpression) >- { >- visit(logicalNotExpression.operand()); >- } >- >- virtual void visit(AST::MakeArrayReferenceExpression& makeArrayReferenceExpression) >- { >- visit(makeArrayReferenceExpression.lValue()); >- } >- >- virtual void visit(AST::MakePointerExpression& makePointerExpression) >- { >- visit(makePointerExpression.lValue()); >- } >- >- virtual void visit(AST::PropertyAccessExpression& propertyAccessExpression) >- { >- visit(propertyAccessExpression.base()); >- } >- >- virtual void visit(AST::ReadModifyWriteExpression& readModifyWriteExpression) >- { >- visit(readModifyWriteExpression.lValue()); >- visit(readModifyWriteExpression.oldValue()); >- visit(readModifyWriteExpression.newValue()); >- visit(readModifyWriteExpression.newValueExpression()); >- visit(readModifyWriteExpression.resultExpression()); >- } >- >- virtual void visit(AST::TernaryExpression& ternaryExpression) >- { >- visit(ternaryExpression.predicate()); >- visit(ternaryExpression.bodyExpression()); >- visit(ternaryExpression.elseExpression()); >- } >- >- virtual void visit(AST::VariableReference&) >- { >- } >+} > >- virtual void visit(AST::AnonymousVariableDeclaration&) >- { >- } >+class Visitor { >+public: >+ virtual ~Visitor() = default; >+ >+ // FIXME: Add a way to visit a const Program >+ >+ virtual void visit(Program&); >+ void visit(AST::UnnamedType& unnamedType); >+ void visit(AST::NamedType& namedType); >+ virtual void visit(AST::TypeDefinition&); >+ virtual void visit(AST::StructureDefinition&); >+ virtual void visit(AST::EnumerationDefinition&); >+ virtual void visit(AST::FunctionDefinition&); >+ virtual void visit(AST::NativeFunctionDeclaration&); >+ virtual void visit(AST::NativeTypeDeclaration&); >+ virtual void visit(AST::TypeReference&); >+ virtual void visit(AST::PointerType&); >+ virtual void visit(AST::ArrayReferenceType&); >+ virtual void visit(AST::ArrayType&); >+ virtual void visit(AST::StructureElement&); >+ virtual void visit(AST::EnumerationMember&); >+ virtual void visit(AST::FunctionDeclaration&); >+ virtual void visit(AST::TypeArgument&); >+ virtual void visit(AST::ReferenceType&); >+ virtual void visit(AST::Semantic&); >+ virtual void visit(AST::ConstantExpression&); >+ virtual void visit(AST::AttributeBlock&); >+ virtual void visit(AST::BuiltInSemantic&); >+ virtual void visit(AST::ResourceSemantic&); >+ virtual void visit(AST::SpecializationConstantSemantic&); >+ virtual void visit(AST::StageInOutSemantic&); >+ virtual void visit(AST::IntegerLiteral&); >+ virtual void visit(AST::UnsignedIntegerLiteral&); >+ virtual void visit(AST::FloatLiteral&); >+ virtual void visit(AST::NullLiteral&); >+ virtual void visit(AST::BooleanLiteral&); >+ virtual void visit(AST::IntegerLiteralType&); >+ virtual void visit(AST::UnsignedIntegerLiteralType&); >+ virtual void visit(AST::FloatLiteralType&); >+ virtual void visit(AST::NullLiteralType&); >+ virtual void visit(AST::ConstantExpressionEnumerationMemberReference&); >+ virtual void visit(AST::FunctionAttribute&); >+ virtual void visit(AST::NumThreadsFunctionAttribute&); >+ virtual void visit(AST::Block&); >+ virtual void visit(AST::Statement&); >+ virtual void visit(AST::Break&); >+ virtual void visit(AST::Continue&); >+ virtual void visit(AST::DoWhileLoop&); >+ virtual void visit(AST::Expression&); >+ virtual void visit(AST::DotExpression&); >+ virtual void visit(AST::IndexExpression&); >+ virtual void visit(AST::PropertyAccessExpression&); >+ virtual void visit(AST::EffectfulExpressionStatement&); >+ virtual void visit(AST::Fallthrough&); >+ virtual void visit(AST::ForLoop&); >+ virtual void visit(AST::IfStatement&); >+ virtual void visit(AST::Return&); >+ virtual void visit(AST::SwitchCase&); >+ virtual void visit(AST::SwitchStatement&); >+ virtual void visit(AST::Trap&); >+ virtual void visit(AST::VariableDeclarationsStatement&); >+ virtual void visit(AST::WhileLoop&); >+ virtual void visit(AST::VariableDeclaration&); >+ virtual void visit(AST::AssignmentExpression&); >+ virtual void visit(AST::CallExpression&); >+ virtual void visit(AST::CommaExpression&); >+ virtual void visit(AST::DereferenceExpression&); >+ virtual void visit(AST::LogicalExpression&); >+ virtual void visit(AST::LogicalNotExpression&); >+ virtual void visit(AST::MakeArrayReferenceExpression&); >+ virtual void visit(AST::MakePointerExpression&); >+ virtual void visit(AST::ReadModifyWriteExpression&); >+ virtual void visit(AST::TernaryExpression&); >+ virtual void visit(AST::VariableReference&); >+ >+ void checkErrorAndVisit(Program&); >+ void checkErrorAndVisit(AST::UnnamedType& unnamedType); >+ void checkErrorAndVisit(AST::NamedType& namedType); >+ void checkErrorAndVisit(AST::TypeDefinition&); >+ void checkErrorAndVisit(AST::StructureDefinition&); >+ void checkErrorAndVisit(AST::EnumerationDefinition&); >+ void checkErrorAndVisit(AST::FunctionDefinition&); >+ void checkErrorAndVisit(AST::NativeFunctionDeclaration&); >+ void checkErrorAndVisit(AST::NativeTypeDeclaration&); >+ void checkErrorAndVisit(AST::TypeReference&); >+ void checkErrorAndVisit(AST::PointerType&); >+ void checkErrorAndVisit(AST::ArrayReferenceType&); >+ void checkErrorAndVisit(AST::ArrayType&); >+ void checkErrorAndVisit(AST::StructureElement&); >+ void checkErrorAndVisit(AST::EnumerationMember&); >+ void checkErrorAndVisit(AST::FunctionDeclaration&); >+ void checkErrorAndVisit(AST::TypeArgument&); >+ void checkErrorAndVisit(AST::ReferenceType&); >+ void checkErrorAndVisit(AST::Semantic&); >+ void checkErrorAndVisit(AST::ConstantExpression&); >+ void checkErrorAndVisit(AST::AttributeBlock&); >+ void checkErrorAndVisit(AST::BuiltInSemantic&); >+ void checkErrorAndVisit(AST::ResourceSemantic&); >+ void checkErrorAndVisit(AST::SpecializationConstantSemantic&); >+ void checkErrorAndVisit(AST::StageInOutSemantic&); >+ void checkErrorAndVisit(AST::IntegerLiteral&); >+ void checkErrorAndVisit(AST::UnsignedIntegerLiteral&); >+ void checkErrorAndVisit(AST::FloatLiteral&); >+ void checkErrorAndVisit(AST::NullLiteral&); >+ void checkErrorAndVisit(AST::BooleanLiteral&); >+ void checkErrorAndVisit(AST::IntegerLiteralType&); >+ void checkErrorAndVisit(AST::UnsignedIntegerLiteralType&); >+ void checkErrorAndVisit(AST::FloatLiteralType&); >+ void checkErrorAndVisit(AST::NullLiteralType&); >+ void checkErrorAndVisit(AST::ConstantExpressionEnumerationMemberReference&); >+ void checkErrorAndVisit(AST::FunctionAttribute&); >+ void checkErrorAndVisit(AST::NumThreadsFunctionAttribute&); >+ void checkErrorAndVisit(AST::Block&); >+ void checkErrorAndVisit(AST::Statement&); >+ void checkErrorAndVisit(AST::Break&); >+ void checkErrorAndVisit(AST::Continue&); >+ void checkErrorAndVisit(AST::DoWhileLoop&); >+ void checkErrorAndVisit(AST::Expression&); >+ void checkErrorAndVisit(AST::DotExpression&); >+ void checkErrorAndVisit(AST::IndexExpression&); >+ void checkErrorAndVisit(AST::PropertyAccessExpression&); >+ void checkErrorAndVisit(AST::EffectfulExpressionStatement&); >+ void checkErrorAndVisit(AST::Fallthrough&); >+ void checkErrorAndVisit(AST::ForLoop&); >+ void checkErrorAndVisit(AST::IfStatement&); >+ void checkErrorAndVisit(AST::Return&); >+ void checkErrorAndVisit(AST::SwitchCase&); >+ void checkErrorAndVisit(AST::SwitchStatement&); >+ void checkErrorAndVisit(AST::Trap&); >+ void checkErrorAndVisit(AST::VariableDeclarationsStatement&); >+ void checkErrorAndVisit(AST::WhileLoop&); >+ void checkErrorAndVisit(AST::VariableDeclaration&); >+ void checkErrorAndVisit(AST::AssignmentExpression&); >+ void checkErrorAndVisit(AST::CallExpression&); >+ void checkErrorAndVisit(AST::CommaExpression&); >+ void checkErrorAndVisit(AST::DereferenceExpression&); >+ void checkErrorAndVisit(AST::LogicalExpression&); >+ void checkErrorAndVisit(AST::LogicalNotExpression&); >+ void checkErrorAndVisit(AST::MakeArrayReferenceExpression&); >+ void checkErrorAndVisit(AST::MakePointerExpression&); >+ void checkErrorAndVisit(AST::ReadModifyWriteExpression&); >+ void checkErrorAndVisit(AST::TernaryExpression&); >+ void checkErrorAndVisit(AST::VariableReference&); >+ >+ void setError() >+ { >+ ASSERT(!m_error); >+ m_error = true; >+ } >+ >+ bool error() const { return m_error; } >+ >+private: >+ bool m_error { false }; // FIXME: Migrate this to be some sort of descriptive string. > }; > > } >diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt >index cdfa1c6f77f..734e45ed50c 100644 >--- a/Source/WebCore/Sources.txt >+++ b/Source/WebCore/Sources.txt >@@ -309,8 +309,32 @@ Modules/webgpu/DOMWindowWebGPU.cpp > Modules/webgpu/WHLSL/WHLSLLexer.cpp > Modules/webgpu/WHLSL/WHLSLParser.cpp > Modules/webgpu/WHLSL/WHLSLPrepare.cpp >+Modules/webgpu/WHLSL/WHLSLIntrinsics.cpp >+Modules/webgpu/WHLSL/WHLSLChecker.cpp >+Modules/webgpu/WHLSL/WHLSLInferTypes.cpp > Modules/webgpu/WHLSL/WHLSLNameResolver.cpp >+Modules/webgpu/WHLSL/WHLSLNameContext.cpp >+Modules/webgpu/WHLSL/WHLSLRecursiveTypeChecker.cpp >+Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.cpp >+Modules/webgpu/WHLSL/WHLSLSynthesizeStructureAccessors.cpp >+Modules/webgpu/WHLSL/WHLSLSynthesizeEnumerationFunctions.cpp >+Modules/webgpu/WHLSL/WHLSLSynthesizeArrayOperatorLength.cpp >+Modules/webgpu/WHLSL/WHLSLSynthesizeConstructors.cpp >+Modules/webgpu/WHLSL/WHLSLVisitor.cpp > Modules/webgpu/WHLSL/AST/WHLSLTypeArgument.cpp >+Modules/webgpu/WHLSL/AST/WHLSLBuiltInSemantic.cpp >+Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.cpp >+Modules/webgpu/WHLSL/AST/WHLSLSpecializationConstantSemantic.cpp >+Modules/webgpu/WHLSL/AST/WHLSLStageInOutSemantic.cpp >+Modules/webgpu/WHLSL/AST/WHLSLFloatLiteralType.cpp >+Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteralType.cpp >+Modules/webgpu/WHLSL/AST/WHLSLNullLiteralType.cpp >+Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteralType.cpp >+Modules/webgpu/WHLSL/AST/WHLSLTypeReference.cpp >+Modules/webgpu/WHLSL/WHLSLResolveOverloadImpl.cpp >+Modules/webgpu/WHLSL/WHLSLGatherEntryPointItems.cpp >+Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.cpp >+Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.cpp > Modules/webgpu/WebGPU.cpp > Modules/webgpu/WebGPUAdapter.cpp > Modules/webgpu/WebGPUBindGroupLayout.cpp >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index 8548558b377..77aa36671e5 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -6404,9 +6404,20 @@ > 1C24EEA71C72A7B40080F8FC /* JSFontFaceSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSFontFaceSet.h; path = DerivedSources/WebCore/JSFontFaceSet.h; sourceTree = BUILT_PRODUCTS_DIR; }; > 1C2649790D7E248A00BD10F2 /* DocumentLoaderMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentLoaderMac.cpp; sourceTree = "<group>"; }; > 1C3249101C6D6A3B007EDB32 /* FontVariantBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FontVariantBuilder.cpp; sourceTree = "<group>"; }; >+ 1C33276C21CEDA42000DC9F2 /* WHLSLEnumerationMemberLiteral.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLEnumerationMemberLiteral.h; sourceTree = "<group>"; }; >+ 1C33276E21CEFF74000DC9F2 /* WHLSLResolveOverloadImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLResolveOverloadImpl.h; sourceTree = "<group>"; }; >+ 1C33276F21CF0131000DC9F2 /* WHLSLInferTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLInferTypes.h; sourceTree = "<group>"; }; >+ 1C33277121CF0BE1000DC9F2 /* WHLSLNamedType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLNamedType.h; sourceTree = "<group>"; }; >+ 1C33277221CF0D2E000DC9F2 /* WHLSLUnnamedType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLUnnamedType.h; sourceTree = "<group>"; }; >+ 1C33277421D5A706000DC9F2 /* WHLSLRecursiveTypeChecker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLRecursiveTypeChecker.h; sourceTree = "<group>"; }; >+ 1C33277521D5B0F8000DC9F2 /* WHLSLCheckDuplicateFunctions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLCheckDuplicateFunctions.h; sourceTree = "<group>"; }; >+ 1C33277621D5C07E000DC9F2 /* WHLSLSynthesizeStructureAccessors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLSynthesizeStructureAccessors.h; sourceTree = "<group>"; }; >+ 1C33277721D5CA83000DC9F2 /* WHLSLSynthesizeEnumerationFunctions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLSynthesizeEnumerationFunctions.h; sourceTree = "<group>"; }; >+ 1C33277821D5CED4000DC9F2 /* WHLSLSynthesizeArrayOperatorLength.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLSynthesizeArrayOperatorLength.h; sourceTree = "<group>"; }; > 1C3969CF1B74211E002BCFA7 /* FontCacheCoreText.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FontCacheCoreText.cpp; sourceTree = "<group>"; }; > 1C66260E1C6E7CA600AB527C /* FontFace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FontFace.cpp; sourceTree = "<group>"; }; > 1C66260F1C6E7CA600AB527C /* FontFace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontFace.h; sourceTree = "<group>"; }; >+ 1C7CC21D21CDE19800C1FA2C /* WHLSLNameContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLNameContext.h; sourceTree = "<group>"; }; > 1C81B9560E97330800266E07 /* InspectorController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorController.h; sourceTree = "<group>"; }; > 1C81B9570E97330800266E07 /* InspectorController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorController.cpp; sourceTree = "<group>"; }; > 1C81B9580E97330800266E07 /* InspectorClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorClient.h; sourceTree = "<group>"; }; >@@ -6416,6 +6427,18 @@ > 1CAF347E0A6C405200ABE06E /* WebScriptObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebScriptObject.h; sourceTree = "<group>"; }; > 1CAF347F0A6C405200ABE06E /* WebScriptObject.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebScriptObject.mm; sourceTree = "<group>"; }; > 1CAF34800A6C405200ABE06E /* WebScriptObjectPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebScriptObjectPrivate.h; sourceTree = "<group>"; }; >+ 1CB69B2C21DD96EF006E846A /* WHLSLGatherEntryPointItems.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLGatherEntryPointItems.cpp; sourceTree = "<group>"; }; >+ 1CB69B2D21DD96EF006E846A /* WHLSLGatherEntryPointItems.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLGatherEntryPointItems.h; sourceTree = "<group>"; }; >+ 1CB69B3221DED40B006E846A /* WHLSLResolvableType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLResolvableType.h; sourceTree = "<group>"; }; >+ 1CB69B3421DED63A006E846A /* WHLSLFloatLiteralType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLFloatLiteralType.h; sourceTree = "<group>"; }; >+ 1CB69B3521DED649006E846A /* WHLSLIntegerLiteralType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLIntegerLiteralType.h; sourceTree = "<group>"; }; >+ 1CB69B3621DED657006E846A /* WHLSLNullLiteralType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLNullLiteralType.h; sourceTree = "<group>"; }; >+ 1CB69B3721DED66B006E846A /* WHLSLUnsignedIntegerLiteralType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLUnsignedIntegerLiteralType.h; sourceTree = "<group>"; }; >+ 1CB69B3821DF03E1006E846A /* WHLSLFloatLiteralType.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLFloatLiteralType.cpp; sourceTree = "<group>"; }; >+ 1CB69B3921DF03F3006E846A /* WHLSLIntegerLiteralType.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLIntegerLiteralType.cpp; sourceTree = "<group>"; }; >+ 1CB69B3A21DF0403006E846A /* WHLSLNullLiteralType.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLNullLiteralType.cpp; sourceTree = "<group>"; }; >+ 1CB69B3B21DF041E006E846A /* WHLSLUnsignedIntegerLiteralType.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLUnsignedIntegerLiteralType.cpp; sourceTree = "<group>"; }; >+ 1CB69B3E21E035F3006E846A /* WHLSLResolvingType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLResolvingType.h; sourceTree = "<group>"; }; > 1CB6B4F8217B83930093B9CD /* TextDecorationThickness.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TextDecorationThickness.h; sourceTree = "<group>"; }; > 1CB6B4FB217B83940093B9CD /* TextUnderlineOffset.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TextUnderlineOffset.h; sourceTree = "<group>"; }; > 1CCDF5BB1990332400BCEBAD /* SVGToOTFFontConversion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGToOTFFontConversion.cpp; sourceTree = "<group>"; }; >@@ -13223,9 +13246,19 @@ > C11A9ECD21403A5C00CFB20A /* SwitchingGPUClient.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SwitchingGPUClient.h; sourceTree = "<group>"; }; > C11A9ED22140578B00CFB20A /* SwitchingGPUClient.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = SwitchingGPUClient.cpp; sourceTree = "<group>"; }; > C1E1D235203DF15400584665 /* ScreenProperties.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScreenProperties.h; sourceTree = "<group>"; }; >+ C201334421DAC09500B60C27 /* WHLSLIntrinsics.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLIntrinsics.h; sourceTree = "<group>"; }; >+ C201334621DAEE6E00B60C27 /* WHLSLIntrinsics.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLIntrinsics.cpp; sourceTree = "<group>"; }; >+ C201334721DB436300B60C27 /* WHLSLSynthesizeConstructors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLSynthesizeConstructors.h; sourceTree = "<group>"; }; > C2015C091BE6FE2C00822389 /* FontVariantBuilder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FontVariantBuilder.h; sourceTree = "<group>"; }; >+ C20F4F6421DFBE5C0070C45A /* WHLSLTypeReference.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLTypeReference.cpp; sourceTree = "<group>"; }; >+ C20F4F6621DFF2360070C45A /* WHLSLIntegerLiteral.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLIntegerLiteral.cpp; sourceTree = "<group>"; }; >+ C20F4F6721DFF3A70070C45A /* WHLSLUnsignedIntegerLiteral.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLUnsignedIntegerLiteral.cpp; sourceTree = "<group>"; }; > C210E91121B4BD1000B7F83D /* WHLSLLexer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLLexer.cpp; sourceTree = "<group>"; }; > C210E91221B4BD1000B7F83D /* WHLSLLexer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLLexer.h; sourceTree = "<group>"; }; >+ C2138A1321DDECD300F516BA /* WHLSLBuiltInSemantic.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLBuiltInSemantic.cpp; sourceTree = "<group>"; }; >+ C2138A1521DDECE900F516BA /* WHLSLResourceSemantic.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLResourceSemantic.cpp; sourceTree = "<group>"; }; >+ C2138A1621DDECFB00F516BA /* WHLSLSpecializationConstantSemantic.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLSpecializationConstantSemantic.cpp; sourceTree = "<group>"; }; >+ C2138A1721DDED0D00F516BA /* WHLSLStageInOutSemantic.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLStageInOutSemantic.cpp; sourceTree = "<group>"; }; > C21BF6F321CD89AD00227979 /* WHLSLTrap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLTrap.h; sourceTree = "<group>"; }; > C21BF6F421CD89B300227979 /* WHLSLFunctionDefinition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLFunctionDefinition.h; sourceTree = "<group>"; }; > C21BF6F521CD89B500227979 /* WHLSLContinue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLContinue.h; sourceTree = "<group>"; }; >@@ -13254,7 +13287,6 @@ > C21BF70C21CD89CC00227979 /* WHLSLExpression.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLExpression.h; sourceTree = "<group>"; }; > C21BF70D21CD89CD00227979 /* WHLSLReferenceType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLReferenceType.h; sourceTree = "<group>"; }; > C21BF70E21CD89CE00227979 /* WHLSLStageInOutSemantic.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLStageInOutSemantic.h; sourceTree = "<group>"; }; >- C21BF70F21CD89CF00227979 /* WHLSLAnonymousVariableDeclaration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLAnonymousVariableDeclaration.h; sourceTree = "<group>"; }; > C21BF71021CD89D000227979 /* WHLSLVariableDeclaration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLVariableDeclaration.h; sourceTree = "<group>"; }; > C21BF71121CD89D100227979 /* WHLSLTypeArgument.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLTypeArgument.h; sourceTree = "<group>"; }; > C21BF71221CD89D100227979 /* WHLSLStatement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLStatement.h; sourceTree = "<group>"; }; >@@ -13262,7 +13294,6 @@ > C21BF71421CD89D300227979 /* WHLSLVariableDeclarationsStatement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLVariableDeclarationsStatement.h; sourceTree = "<group>"; }; > C21BF71521CD89D400227979 /* WHLSLLogicalNotExpression.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLLogicalNotExpression.h; sourceTree = "<group>"; }; > C21BF71621CD89D500227979 /* WHLSLCallExpression.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLCallExpression.h; sourceTree = "<group>"; }; >- C21BF71721CD89D600227979 /* WHLSLParameter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLParameter.h; sourceTree = "<group>"; }; > C21BF71821CD89D700227979 /* WHLSLDotExpression.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLDotExpression.h; sourceTree = "<group>"; }; > C21BF71921CD89D700227979 /* WHLSLSwitchCase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLSwitchCase.h; sourceTree = "<group>"; }; > C21BF71A21CD89D800227979 /* WHLSLBreak.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLBreak.h; sourceTree = "<group>"; }; >@@ -13308,15 +13339,27 @@ > C280833D1C6DC22C001451B6 /* JSFontFace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JSFontFace.cpp; path = DerivedSources/WebCore/JSFontFace.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; > C280833E1C6DC22C001451B6 /* JSFontFace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSFontFace.h; path = DerivedSources/WebCore/JSFontFace.h; sourceTree = BUILT_PRODUCTS_DIR; }; > C280B3FD1EF4608900D35135 /* FontFamilySpecificationNull.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FontFamilySpecificationNull.cpp; sourceTree = "<group>"; }; >+ C286ED9E21DB5ABA00713C40 /* WHLSLResolveOverloadImpl.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLResolveOverloadImpl.cpp; sourceTree = "<group>"; }; > C288C72721C8C6EF002DF5CA /* WHLSLVisitor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLVisitor.h; sourceTree = "<group>"; }; > C288C72921C8CA50002DF5CA /* WHLSLPrepare.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLPrepare.cpp; sourceTree = "<group>"; }; > C288C72A21C8CA50002DF5CA /* WHLSLPrepare.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLPrepare.h; sourceTree = "<group>"; }; >- C288C72B21C8CCC2002DF5CA /* WHLSLNameResolver.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLNameResolver.cpp; sourceTree = "<group>"; }; > C288C72C21C8CCC2002DF5CA /* WHLSLNameResolver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLNameResolver.h; sourceTree = "<group>"; }; > C288C72D21C991DA002DF5CA /* WHLSLTypeArgument.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLTypeArgument.cpp; sourceTree = "<group>"; }; > C2AB0AF41E6B3C6C001348C5 /* FontSelectionAlgorithm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FontSelectionAlgorithm.cpp; sourceTree = "<group>"; }; > C2AB0AF51E6B3C6C001348C5 /* FontSelectionAlgorithm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontSelectionAlgorithm.h; sourceTree = "<group>"; }; > C2AB0B031E6DE92C001348C5 /* FontSelectionValueInlines.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FontSelectionValueInlines.h; sourceTree = "<group>"; }; >+ C2B5517021DB4B48004BE26E /* WHLSLChecker.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLChecker.cpp; sourceTree = "<group>"; }; >+ C2B5517121DB4B48004BE26E /* WHLSLChecker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLChecker.h; sourceTree = "<group>"; }; >+ C2B5517321DB4BBD004BE26E /* WHLSLNameResolver.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLNameResolver.cpp; sourceTree = "<group>"; }; >+ C2B5517421DB510F004BE26E /* WHLSLNameContext.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLNameContext.cpp; sourceTree = "<group>"; }; >+ C2B5517521DB5266004BE26E /* WHLSLInferTypes.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLInferTypes.cpp; sourceTree = "<group>"; }; >+ C2B5517621DB5394004BE26E /* WHLSLRecursiveTypeChecker.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLRecursiveTypeChecker.cpp; sourceTree = "<group>"; }; >+ C2B5517721DB540F004BE26E /* WHLSLCheckDuplicateFunctions.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLCheckDuplicateFunctions.cpp; sourceTree = "<group>"; }; >+ C2B5517821DB5575004BE26E /* WHLSLSynthesizeStructureAccessors.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLSynthesizeStructureAccessors.cpp; sourceTree = "<group>"; }; >+ C2B5517921DB558F004BE26E /* WHLSLSynthesizeEnumerationFunctions.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLSynthesizeEnumerationFunctions.cpp; sourceTree = "<group>"; }; >+ C2B5517A21DB559E004BE26E /* WHLSLSynthesizeArrayOperatorLength.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLSynthesizeArrayOperatorLength.cpp; sourceTree = "<group>"; }; >+ C2B5517B21DB55AF004BE26E /* WHLSLSynthesizeConstructors.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLSynthesizeConstructors.cpp; sourceTree = "<group>"; }; >+ C2B5517C21DB57ED004BE26E /* WHLSLVisitor.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLVisitor.cpp; sourceTree = "<group>"; }; > C2C2CF551EF3761A004281A8 /* FontFamilySpecificationNull.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontFamilySpecificationNull.h; sourceTree = "<group>"; }; > C2E38EFB1E8396FD00CA3ADF /* CSSFontStyleValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSFontStyleValue.cpp; sourceTree = "<group>"; }; > C2E38EFC1E8396FD00CA3ADF /* CSSFontStyleValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSFontStyleValue.h; sourceTree = "<group>"; }; >@@ -25351,11 +25394,37 @@ > C21BF73721CD8A0200227979 /* WHLSLParser.cpp */, > C21BF73821CD8A0300227979 /* WHLSLParser.h */, > C21BF73A21CD8D7000227979 /* WHLSLProgram.h */, >- C288C72721C8C6EF002DF5CA /* WHLSLVisitor.h */, >- C288C72921C8CA50002DF5CA /* WHLSLPrepare.cpp */, >- C288C72A21C8CA50002DF5CA /* WHLSLPrepare.h */, >- C288C72B21C8CCC2002DF5CA /* WHLSLNameResolver.cpp */, >- C288C72C21C8CCC2002DF5CA /* WHLSLNameResolver.h */, >+ C288C72721C8C6EF002DF5CA /* WHLSLVisitor.h */, >+ C2B5517C21DB57ED004BE26E /* WHLSLVisitor.cpp */, >+ C288C72921C8CA50002DF5CA /* WHLSLPrepare.cpp */, >+ C288C72A21C8CA50002DF5CA /* WHLSLPrepare.h */, >+ C288C72C21C8CCC2002DF5CA /* WHLSLNameResolver.h */, >+ C2B5517321DB4BBD004BE26E /* WHLSLNameResolver.cpp */, >+ 1C7CC21D21CDE19800C1FA2C /* WHLSLNameContext.h */, >+ C2B5517421DB510F004BE26E /* WHLSLNameContext.cpp */, >+ 1C33276E21CEFF74000DC9F2 /* WHLSLResolveOverloadImpl.h */, >+ C286ED9E21DB5ABA00713C40 /* WHLSLResolveOverloadImpl.cpp */, >+ 1C33276F21CF0131000DC9F2 /* WHLSLInferTypes.h */, >+ C2B5517521DB5266004BE26E /* WHLSLInferTypes.cpp */, >+ 1C33277421D5A706000DC9F2 /* WHLSLRecursiveTypeChecker.h */, >+ C2B5517621DB5394004BE26E /* WHLSLRecursiveTypeChecker.cpp */, >+ 1C33277521D5B0F8000DC9F2 /* WHLSLCheckDuplicateFunctions.h */, >+ C2B5517721DB540F004BE26E /* WHLSLCheckDuplicateFunctions.cpp */, >+ 1C33277621D5C07E000DC9F2 /* WHLSLSynthesizeStructureAccessors.h */, >+ C2B5517821DB5575004BE26E /* WHLSLSynthesizeStructureAccessors.cpp */, >+ 1C33277721D5CA83000DC9F2 /* WHLSLSynthesizeEnumerationFunctions.h */, >+ C2B5517921DB558F004BE26E /* WHLSLSynthesizeEnumerationFunctions.cpp */, >+ 1C33277821D5CED4000DC9F2 /* WHLSLSynthesizeArrayOperatorLength.h */, >+ C2B5517A21DB559E004BE26E /* WHLSLSynthesizeArrayOperatorLength.cpp */, >+ C201334721DB436300B60C27 /* WHLSLSynthesizeConstructors.h */, >+ C2B5517B21DB55AF004BE26E /* WHLSLSynthesizeConstructors.cpp */, >+ C201334421DAC09500B60C27 /* WHLSLIntrinsics.h */, >+ C201334621DAEE6E00B60C27 /* WHLSLIntrinsics.cpp */, >+ C2B5517021DB4B48004BE26E /* WHLSLChecker.cpp */, >+ C2B5517121DB4B48004BE26E /* WHLSLChecker.h */, >+ 1CB69B2C21DD96EF006E846A /* WHLSLGatherEntryPointItems.cpp */, >+ 1CB69B2D21DD96EF006E846A /* WHLSLGatherEntryPointItems.h */, >+ 1CB69B3E21E035F3006E846A /* WHLSLResolvingType.h */, > ); > path = WHLSL; > sourceTree = "<group>"; >@@ -25363,7 +25432,6 @@ > C21BF6F121CD898D00227979 /* AST */ = { > isa = PBXGroup; > children = ( >- C21BF70F21CD89CF00227979 /* WHLSLAnonymousVariableDeclaration.h */, > C21BF72521CD89E200227979 /* WHLSLArrayReferenceType.h */, > C21BF70921CD89CA00227979 /* WHLSLArrayType.h */, > C21BF73021CD89ED00227979 /* WHLSLAssignmentExpression.h */, >@@ -25403,7 +25471,6 @@ > C21BF72421CD89E100227979 /* WHLSLNode.h */, > C21BF70721CD89C800227979 /* WHLSLNullLiteral.h */, > C21BF72121CD89DE00227979 /* WHLSLNumThreadsFunctionAttribute.h */, >- C21BF71721CD89D600227979 /* WHLSLParameter.h */, > C21BF72F21CD89EC00227979 /* WHLSLPointerType.h */, > C21BF72E21CD89EA00227979 /* WHLSLPropertyAccessExpression.h */, > C21BF70B21CD89CC00227979 /* WHLSLQualifier.h */, >@@ -25431,7 +25498,26 @@ > C21BF71421CD89D300227979 /* WHLSLVariableDeclarationsStatement.h */, > C21BF71321CD89D200227979 /* WHLSLVariableReference.h */, > C21BF70421CD89C600227979 /* WHLSLWhileLoop.h */, >- C288C72D21C991DA002DF5CA /* WHLSLTypeArgument.cpp */, >+ C288C72D21C991DA002DF5CA /* WHLSLTypeArgument.cpp */, >+ 1C33276C21CEDA42000DC9F2 /* WHLSLEnumerationMemberLiteral.h */, >+ 1C33277121CF0BE1000DC9F2 /* WHLSLNamedType.h */, >+ 1C33277221CF0D2E000DC9F2 /* WHLSLUnnamedType.h */, >+ C2138A1321DDECD300F516BA /* WHLSLBuiltInSemantic.cpp */, >+ C2138A1521DDECE900F516BA /* WHLSLResourceSemantic.cpp */, >+ C2138A1621DDECFB00F516BA /* WHLSLSpecializationConstantSemantic.cpp */, >+ C2138A1721DDED0D00F516BA /* WHLSLStageInOutSemantic.cpp */, >+ 1CB69B3221DED40B006E846A /* WHLSLResolvableType.h */, >+ 1CB69B3421DED63A006E846A /* WHLSLFloatLiteralType.h */, >+ 1CB69B3521DED649006E846A /* WHLSLIntegerLiteralType.h */, >+ 1CB69B3621DED657006E846A /* WHLSLNullLiteralType.h */, >+ 1CB69B3721DED66B006E846A /* WHLSLUnsignedIntegerLiteralType.h */, >+ 1CB69B3821DF03E1006E846A /* WHLSLFloatLiteralType.cpp */, >+ 1CB69B3921DF03F3006E846A /* WHLSLIntegerLiteralType.cpp */, >+ 1CB69B3A21DF0403006E846A /* WHLSLNullLiteralType.cpp */, >+ 1CB69B3B21DF041E006E846A /* WHLSLUnsignedIntegerLiteralType.cpp */, >+ C20F4F6421DFBE5C0070C45A /* WHLSLTypeReference.cpp */, >+ C20F4F6621DFF2360070C45A /* WHLSLIntegerLiteral.cpp */, >+ C20F4F6721DFF3A70070C45A /* WHLSLUnsignedIntegerLiteral.cpp */, > ); > path = AST; > sourceTree = "<group>";
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 193080
:
358187
|
358234
|
358247
|
358304
|
358378
|
358425
|
358482
|
358582
|
358621
|
358667
|
358719
|
358936
|
359002
|
359018
|
359019
|
359122