WebKit Bugzilla
Attachment 358719 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]
Patch
patch.txt (text/plain), 704.42 KB, created by
Myles C. Maxfield
on 2019-01-09 11:44:06 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Myles C. Maxfield
Created:
2019-01-09 11:44:06 PST
Size:
704.42 KB
patch
obsolete
>diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index b83270c0e2c..68463b2df3a 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,502 @@ >+2019-01-02 Myles C. Maxfield <mmaxfield@apple.com> >+ >+ [WHLSL] Add a Visitor class >+ https://bugs.webkit.org/show_bug.cgi?id=192826 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This patch exposes a bunch of the private members of WHLSL's AST nodes so that Visitor can recurse on constituent nodes. >+ It also writes the recursion in Visitor.h. This is a virtual base class that gets subclassed for compiler passes. >+ >+ I've split this part into its own patch to aid reviewing of the compiler. >+ >+ No new tests because it's not hooked up yet. >+ >+ * Modules/webgpu/WHLSL/AST/WHLSLArrayReferenceType.h: >+ * Modules/webgpu/WHLSL/AST/WHLSLArrayType.h: >+ (WebCore::WHLSL::AST::ArrayType::type): >+ * Modules/webgpu/WHLSL/AST/WHLSLAssignmentExpression.h: >+ (WebCore::WHLSL::AST::AssignmentExpression::left): >+ (WebCore::WHLSL::AST::AssignmentExpression::right): >+ * Modules/webgpu/WHLSL/AST/WHLSLBlock.h: >+ (WebCore::WHLSL::AST::Block::Block): >+ (WebCore::WHLSL::AST::Block::statements): >+ * Modules/webgpu/WHLSL/AST/WHLSLBooleanLiteral.h: >+ * Modules/webgpu/WHLSL/AST/WHLSLBreak.h: >+ * Modules/webgpu/WHLSL/AST/WHLSLCallExpression.h: >+ (WebCore::WHLSL::AST::CallExpression::arguments): >+ * Modules/webgpu/WHLSL/AST/WHLSLCommaExpression.h: >+ (WebCore::WHLSL::AST::CommaExpression::list): >+ * Modules/webgpu/WHLSL/AST/WHLSLConstantExpression.h: >+ (WebCore::WHLSL::AST::ConstantExpression::ConstantExpression): >+ (WebCore::WHLSL::AST::ConstantExpression::visit): >+ * Modules/webgpu/WHLSL/AST/WHLSLContinue.h: >+ * Modules/webgpu/WHLSL/AST/WHLSLDereferenceExpression.h: >+ (WebCore::WHLSL::AST::DereferenceExpression::pointer): >+ * Modules/webgpu/WHLSL/AST/WHLSLDoWhileLoop.h: >+ (WebCore::WHLSL::AST::DoWhileLoop::body): >+ (WebCore::WHLSL::AST::DoWhileLoop::conditional): >+ * Modules/webgpu/WHLSL/AST/WHLSLEffectfulExpressionStatement.h: >+ (WebCore::WHLSL::AST::EffectfulExpressionStatement::effectfulExpression): >+ * Modules/webgpu/WHLSL/AST/WHLSLEnumerationDefinition.h: >+ (WebCore::WHLSL::AST::EnumerationDefinition::EnumerationDefinition): >+ (WebCore::WHLSL::AST::EnumerationDefinition::type): >+ (WebCore::WHLSL::AST::EnumerationDefinition::enumerationMembers): >+ (): Deleted. >+ * Modules/webgpu/WHLSL/AST/WHLSLEnumerationMember.h: >+ (WebCore::WHLSL::AST::EnumerationMember::value): >+ * Modules/webgpu/WHLSL/AST/WHLSLExpression.h: >+ (WebCore::WHLSL::AST::Expression::isAssignmentExpression const): >+ (WebCore::WHLSL::AST::Expression::isBooleanLiteral const): >+ (WebCore::WHLSL::AST::Expression::isCallExpression const): >+ (WebCore::WHLSL::AST::Expression::isCommaExpression const): >+ (WebCore::WHLSL::AST::Expression::isDereferenceExpression const): >+ (WebCore::WHLSL::AST::Expression::isFloatLiteral const): >+ (WebCore::WHLSL::AST::Expression::isIntegerLiteral const): >+ (WebCore::WHLSL::AST::Expression::isLogicalExpression const): >+ (WebCore::WHLSL::AST::Expression::isLogicalNotExpression const): >+ (WebCore::WHLSL::AST::Expression::isMakeArrayReferenceExpression const): >+ (WebCore::WHLSL::AST::Expression::isMakePointerExpression const): >+ (WebCore::WHLSL::AST::Expression::isNullLiteral const): >+ (WebCore::WHLSL::AST::Expression::isPropertyAccessExpression const): >+ (WebCore::WHLSL::AST::Expression::isReadModifyWriteExpression const): >+ (WebCore::WHLSL::AST::Expression::isTernaryExpression const): >+ (WebCore::WHLSL::AST::Expression::isUnsignedIntegerLiteral const): >+ (WebCore::WHLSL::AST::Expression::isVariableReference const): >+ * Modules/webgpu/WHLSL/AST/WHLSLFallthrough.h: >+ * Modules/webgpu/WHLSL/AST/WHLSLFloatLiteral.h: >+ * Modules/webgpu/WHLSL/AST/WHLSLForLoop.h: >+ (WebCore::WHLSL::AST::ForLoop::initialization): >+ (WebCore::WHLSL::AST::ForLoop::condition): >+ (WebCore::WHLSL::AST::ForLoop::increment): >+ (WebCore::WHLSL::AST::ForLoop::body): >+ * Modules/webgpu/WHLSL/AST/WHLSLFunctionDeclaration.h: >+ (WebCore::WHLSL::AST::FunctionDeclaration::attributeBlock): >+ (WebCore::WHLSL::AST::FunctionDeclaration::type): >+ (WebCore::WHLSL::AST::FunctionDeclaration::parameters): >+ (WebCore::WHLSL::AST::FunctionDeclaration::semantic): >+ * Modules/webgpu/WHLSL/AST/WHLSLFunctionDefinition.h: >+ (WebCore::WHLSL::AST::FunctionDefinition::block): >+ * Modules/webgpu/WHLSL/AST/WHLSLIfStatement.h: >+ (WebCore::WHLSL::AST::IfStatement::conditional): >+ (WebCore::WHLSL::AST::IfStatement::body): >+ (WebCore::WHLSL::AST::IfStatement::elseBody): >+ * Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.h: >+ * Modules/webgpu/WHLSL/AST/WHLSLLogicalExpression.h: >+ (WebCore::WHLSL::AST::LogicalExpression::left): >+ (WebCore::WHLSL::AST::LogicalExpression::right): >+ * Modules/webgpu/WHLSL/AST/WHLSLLogicalNotExpression.h: >+ (WebCore::WHLSL::AST::LogicalNotExpression::operand): >+ * Modules/webgpu/WHLSL/AST/WHLSLMakeArrayReferenceExpression.h: >+ (WebCore::WHLSL::AST::MakeArrayReferenceExpression::lValue): >+ * Modules/webgpu/WHLSL/AST/WHLSLMakePointerExpression.h: >+ (WebCore::WHLSL::AST::MakePointerExpression::lValue): >+ * Modules/webgpu/WHLSL/AST/WHLSLNativeTypeDeclaration.h: >+ (WebCore::WHLSL::AST::NativeTypeDeclaration::typeArguments): >+ * Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h: >+ * Modules/webgpu/WHLSL/AST/WHLSLParameter.h: >+ (WebCore::WHLSL::AST::Parameter::type): >+ (WebCore::WHLSL::AST::Parameter::semantic): >+ * Modules/webgpu/WHLSL/AST/WHLSLPointerType.h: >+ * Modules/webgpu/WHLSL/AST/WHLSLPropertyAccessExpression.h: >+ (WebCore::WHLSL::AST::PropertyAccessExpression::base): >+ * Modules/webgpu/WHLSL/AST/WHLSLReadModifyWriteExpression.h: >+ (WebCore::WHLSL::AST::ReadModifyWriteExpression::lValue): >+ (WebCore::WHLSL::AST::ReadModifyWriteExpression::oldValue): >+ (WebCore::WHLSL::AST::ReadModifyWriteExpression::newValue): >+ (WebCore::WHLSL::AST::ReadModifyWriteExpression::newValueExpression): >+ (WebCore::WHLSL::AST::ReadModifyWriteExpression::resultExpression): >+ * Modules/webgpu/WHLSL/AST/WHLSLReferenceType.h: >+ (WebCore::WHLSL::AST::ReferenceType::elementType): >+ (WebCore::WHLSL::AST::ReferenceType::elementType const): >+ * Modules/webgpu/WHLSL/AST/WHLSLReturn.h: >+ (WebCore::WHLSL::AST::Return::value): >+ * Modules/webgpu/WHLSL/AST/WHLSLStatement.h: >+ (WebCore::WHLSL::AST::Statement::isBlock const): >+ (WebCore::WHLSL::AST::Statement::isBreak const): >+ (WebCore::WHLSL::AST::Statement::isContinue const): >+ (WebCore::WHLSL::AST::Statement::isDoWhileLoop const): >+ (WebCore::WHLSL::AST::Statement::isEffectfulExpressionStatement const): >+ (WebCore::WHLSL::AST::Statement::isFallthrough const): >+ (WebCore::WHLSL::AST::Statement::isForLoop const): >+ (WebCore::WHLSL::AST::Statement::isIfStatement const): >+ (WebCore::WHLSL::AST::Statement::isReturn const): >+ (WebCore::WHLSL::AST::Statement::isSwitchCase const): >+ (WebCore::WHLSL::AST::Statement::isSwitchStatement const): >+ (WebCore::WHLSL::AST::Statement::isTrap const): >+ (WebCore::WHLSL::AST::Statement::isVariableDeclarationsStatement const): >+ (WebCore::WHLSL::AST::Statement::isWhileLoop const): >+ * Modules/webgpu/WHLSL/AST/WHLSLStructureDefinition.h: >+ (WebCore::WHLSL::AST::StructureDefinition::structureElements): >+ * Modules/webgpu/WHLSL/AST/WHLSLStructureElement.h: >+ (WebCore::WHLSL::AST::StructureElement::type): >+ (WebCore::WHLSL::AST::StructureElement::semantic): >+ * Modules/webgpu/WHLSL/AST/WHLSLSwitchCase.h: >+ (WebCore::WHLSL::AST::SwitchCase::value): >+ (WebCore::WHLSL::AST::SwitchCase::block): >+ * Modules/webgpu/WHLSL/AST/WHLSLSwitchStatement.h: >+ (WebCore::WHLSL::AST::SwitchStatement::value): >+ (WebCore::WHLSL::AST::SwitchStatement::switchCases): >+ * Modules/webgpu/WHLSL/AST/WHLSLTernaryExpression.h: >+ (WebCore::WHLSL::AST::TernaryExpression::predicate): >+ (WebCore::WHLSL::AST::TernaryExpression::bodyExpression): >+ (WebCore::WHLSL::AST::TernaryExpression::elseExpression): >+ * Modules/webgpu/WHLSL/AST/WHLSLTrap.h: >+ * Modules/webgpu/WHLSL/AST/WHLSLType.h: >+ (WebCore::WHLSL::AST::Type::isTypeReference const): >+ (WebCore::WHLSL::AST::Type::isPointerType const): >+ (WebCore::WHLSL::AST::Type::isArrayReferenceType const): >+ (WebCore::WHLSL::AST::Type::isArrayType const): >+ * Modules/webgpu/WHLSL/AST/WHLSLTypeArgument.cpp: Copied from Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSwitchCase.h. >+ (WebCore::WHLSL::AST::clone): >+ * Modules/webgpu/WHLSL/AST/WHLSLTypeArgument.h: >+ * Modules/webgpu/WHLSL/AST/WHLSLTypeDefinition.h: >+ (WebCore::WHLSL::AST::TypeDefinition::type): >+ * Modules/webgpu/WHLSL/AST/WHLSLTypeReference.h: >+ (WebCore::WHLSL::AST::TypeReference::typeArguments): >+ (WebCore::WHLSL::AST::TypeReference::cloneTypeReference const): >+ * Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.h: >+ * Modules/webgpu/WHLSL/AST/WHLSLVariableDeclaration.h: >+ (WebCore::WHLSL::AST::VariableDeclaration::type): >+ (WebCore::WHLSL::AST::VariableDeclaration::semantic): >+ (WebCore::WHLSL::AST::VariableDeclaration::initializer): >+ * Modules/webgpu/WHLSL/AST/WHLSLVariableDeclarationsStatement.h: >+ (WebCore::WHLSL::AST::VariableDeclarationsStatement::variableDeclarations): >+ * Modules/webgpu/WHLSL/AST/WHLSLVariableReference.h: >+ * Modules/webgpu/WHLSL/AST/WHLSLWhileLoop.h: >+ (WebCore::WHLSL::AST::WhileLoop::conditional): >+ (WebCore::WHLSL::AST::WhileLoop::body): >+ * Modules/webgpu/WHLSL/WHLSLNameResolver.cpp: Copied from Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLType.h. >+ (WebCore::WHLSL::resolveNamesInTypes): >+ * Modules/webgpu/WHLSL/WHLSLNameResolver.h: Copied from Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLType.h. >+ * Modules/webgpu/WHLSL/WHLSLParser.cpp: >+ (WebCore::WHLSL::Parser::parseTypeArgument): >+ (WebCore::WHLSL::Parser::parseEnumerationDefinition): >+ (WebCore::WHLSL::Parser::parseBlockBody): >+ * Modules/webgpu/WHLSL/WHLSLPrepare.cpp: Copied from Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBreak.h. >+ (WebCore::WHLSL::prepare): >+ * Modules/webgpu/WHLSL/WHLSLPrepare.h: Copied from Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeArgument.h. >+ * Modules/webgpu/WHLSL/WHLSLProgram.h: >+ (WebCore::WHLSL::Program::typeDefinitions): >+ (WebCore::WHLSL::Program::structureDefinitions): >+ (WebCore::WHLSL::Program::enumerationDefinitions): >+ (WebCore::WHLSL::Program::functionDefinitions): >+ (WebCore::WHLSL::Program::nativeFunctionDeclarations): >+ (WebCore::WHLSL::Program::nativeTypeDeclarations): >+ * Modules/webgpu/WHLSL/WHLSLVisitor.h: Added. >+ (WebCore::WHLSL::Visitor::visit): >+ (WebCore::WHLSL::Visitor::visitType): >+ * Sources.txt: >+ * WebCore.xcodeproj/project.pbxproj: >+ >+2019-01-02 Myles C. Maxfield <mmaxfield@apple.com> >+ >+ [WHLSL] Include the standard library >+ https://bugs.webkit.org/show_bug.cgi?id=192994 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ A small section of the standard library is present in WHLSLStandardLibrary.txt. This gets turned into a header file containing >+ its raw data at build time by invoking our xxd.pl script (which WebCore already uses for other purposes). The standard >+ library is generated by running a JavaScript script, but currently there is no way to invoke JavaScript from our build >+ process, so this patch includes in the standard library's raw text instead. Once the parser is faster, we can include the >+ entire standard library. >+ >+ No new tests because it isn't hooked up yet. >+ >+ * DerivedSources.make: >+ * Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt: Added. >+ * WebCore.xcodeproj/project.pbxproj: >+ >+2019-01-02 Myles C. Maxfield <mmaxfield@apple.com> >+ >+ [WHLSL] Add a handwritten parser >+ https://bugs.webkit.org/show_bug.cgi?id=192355 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ The parser is a mechanical representation of WHLSL's ANTLR grammar at >+ https://github.com/gpuweb/WHLSL/blob/master/Spec/WHLSL.g4. The parser >+ uses Expected<> to return an appropriate Error string when parsing fails. >+ >+ This patch doesn't include the AST nodes themselves - those are in >+ https://bugs.webkit.org/show_bug.cgi?id=192991. I split up the patch to >+ aid easier reviewing. >+ >+ No new tests because the parser isn't hooked up yet. >+ >+ * Modules/webgpu/WHLSL/WHLSLParser.cpp: >+ (WebCore::WHLSL::Parser::Parser): >+ (WebCore::WHLSL::Parser::parse): >+ (WebCore::WHLSL::Parser::fail): >+ (WebCore::WHLSL::Parser::peek): >+ (WebCore::WHLSL::Parser::tryType): >+ (WebCore::WHLSL::Parser::tryTypes): >+ (WebCore::WHLSL::Parser::consumeType): >+ (WebCore::WHLSL::Parser::consumeTypes): >+ (WebCore::WHLSL::digitValue): >+ (WebCore::WHLSL::intLiteralToInt): >+ (WebCore::WHLSL::uintLiteralToUint): >+ (WebCore::WHLSL::floatLiteralToFloat): >+ (WebCore::WHLSL::Parser::consumeIntegralLiteral): >+ (WebCore::WHLSL::Parser::consumeNonNegativeIntegralLiteral): >+ (WebCore::WHLSL::recognizeSimpleUnsignedInteger): >+ (WebCore::WHLSL::Parser::parseConstantExpression): >+ (WebCore::WHLSL::Parser::parseTypeArgument): >+ (WebCore::WHLSL::Parser::parseTypeArguments): >+ (WebCore::WHLSL::Parser::parseTypeSuffixAbbreviated): >+ (WebCore::WHLSL::Parser::parseTypeSuffixNonAbbreviated): >+ (WebCore::WHLSL::Parser::parseAddressSpaceType): >+ (WebCore::WHLSL::Parser::parseNonAddressSpaceType): >+ (WebCore::WHLSL::Parser::parseType): >+ (WebCore::WHLSL::Parser::parseTypeDefinition): >+ (WebCore::WHLSL::Parser::parseBuiltInSemantic): >+ (WebCore::WHLSL::Parser::parseResourceSemantic): >+ (WebCore::WHLSL::Parser::parseSpecializationConstantSemantic): >+ (WebCore::WHLSL::Parser::parseStageInOutSemantic): >+ (WebCore::WHLSL::Parser::parseSemantic): >+ (WebCore::WHLSL::Parser::parseQualifiers): >+ (WebCore::WHLSL::Parser::parseStructureElement): >+ (WebCore::WHLSL::Parser::parseStructureDefinition): >+ (WebCore::WHLSL::Parser::parseEnumerationDefinition): >+ (WebCore::WHLSL::Parser::parseEnumerationMember): >+ (WebCore::WHLSL::Parser::parseNativeTypeDeclaration): >+ (WebCore::WHLSL::Parser::parseNumThreadsFunctionAttribute): >+ (WebCore::WHLSL::Parser::parseAttributeBlock): >+ (WebCore::WHLSL::Parser::parseParameter): >+ (WebCore::WHLSL::Parser::parseParameters): >+ (WebCore::WHLSL::Parser::parseFunctionDefinition): >+ (WebCore::WHLSL::Parser::parseEntryPointFunctionDeclaration): >+ (WebCore::WHLSL::Parser::parseRegularFunctionDeclaration): >+ (WebCore::WHLSL::Parser::parseOperatorFunctionDeclaration): >+ (WebCore::WHLSL::Parser::parseFunctionDeclaration): >+ (WebCore::WHLSL::Parser::parseNativeFunctionDeclaration): >+ (WebCore::WHLSL::Parser::parseBlock): >+ (WebCore::WHLSL::Parser::parseBlockBody): >+ (WebCore::WHLSL::Parser::parseIfStatement): >+ (WebCore::WHLSL::Parser::parseSwitchStatement): >+ (WebCore::WHLSL::Parser::parseSwitchCase): >+ (WebCore::WHLSL::Parser::parseForLoop): >+ (WebCore::WHLSL::Parser::parseWhileLoop): >+ (WebCore::WHLSL::Parser::parseDoWhileLoop): >+ (WebCore::WHLSL::Parser::parseVariableDeclaration): >+ (WebCore::WHLSL::Parser::parseVariableDeclarations): >+ (WebCore::WHLSL::Parser::parseStatement): >+ (WebCore::WHLSL::Parser::parseEffectfulExpression): >+ (WebCore::WHLSL::Parser::parseEffectfulAssignment): >+ (WebCore::WHLSL::Parser::parseEffectfulPrefix): >+ (WebCore::WHLSL::Parser::parseEffectfulSuffix): >+ (WebCore::WHLSL::Parser::parseLimitedSuffixOperator): >+ (WebCore::WHLSL::Parser::parseSuffixOperator): >+ (WebCore::WHLSL::Parser::parseExpression): >+ (WebCore::WHLSL::Parser::parseTernaryConditional): >+ (WebCore::WHLSL::Parser::parseAssignment): >+ (WebCore::WHLSL::Parser::parsePossibleTernaryConditional): >+ (WebCore::WHLSL::Parser::parsePossibleLogicalBinaryOperation): >+ (WebCore::WHLSL::Parser::parsePossibleRelationalBinaryOperation): >+ (WebCore::WHLSL::Parser::parsePossibleShift): >+ (WebCore::WHLSL::Parser::parsePossibleAdd): >+ (WebCore::WHLSL::Parser::parsePossibleMultiply): >+ (WebCore::WHLSL::Parser::parsePossiblePrefix): >+ (WebCore::WHLSL::Parser::parsePossibleSuffix): >+ (WebCore::WHLSL::Parser::parseCallExpression): >+ (WebCore::WHLSL::Parser::parseTerm): >+ * Modules/webgpu/WHLSL/WHLSLParser.h: >+ (WebCore::WHLSL::Parser::Error::Error): >+ (WebCore::WHLSL::Parser::backtrackingScope): >+ (WebCore::WHLSL::Parser::SuffixExpression::SuffixExpression): >+ (WebCore::WHLSL::Parser::SuffixExpression::operator bool const): >+ >+2019-01-02 Myles C. Maxfield <mmaxfield@apple.com> >+ >+ [WHLSL] Implement parser AST nodes >+ https://bugs.webkit.org/show_bug.cgi?id=192991 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This patch creates all the AST nodes which will be the result of running the parser. >+ This patch used to be a part of the "create a WHLSL parser" patch but I split them >+ out in order to aid reviewing. >+ >+ The classes were mechanically created to match the result of the parser. There are >+ nodes for things like ForLoops, LogicalNotExpressions, DereferenceExpressions, >+ StructureDefinitions, and things like that. The classes don't actually have any logic >+ in them - they are currently just containers to hold the structure of the parsed >+ program. Some of these nodes (like constexprs) are just Variants of the various things >+ they can in the form of. >+ >+ No new tests because the parser doesn't exist to create the new AST nodes yet. >+ >+ * Modules/webgpu/WHLSL/AST/WHLSLAnonymousVariableDeclaration.h: Added. >+ (WebCore::WHLSL::AST::AnonymousVariableDeclaration::AnonymousVariableDeclaration): >+ (WebCore::WHLSL::AST::AnonymousVariableDeclaration::origin const): >+ * Modules/webgpu/WHLSL/AST/WHLSLArrayReferenceType.h: Added. >+ (WebCore::WHLSL::AST::ArrayReferenceType::ArrayReferenceType): >+ * Modules/webgpu/WHLSL/AST/WHLSLArrayType.h: Added. >+ (WebCore::WHLSL::AST::ArrayType::ArrayType): >+ (WebCore::WHLSL::AST::ArrayType::numElements const): >+ * Modules/webgpu/WHLSL/AST/WHLSLAssignmentExpression.h: Added. >+ (WebCore::WHLSL::AST::AssignmentExpression::AssignmentExpression): >+ * Modules/webgpu/WHLSL/AST/WHLSLBaseFunctionAttribute.h: Added. >+ (WebCore::WHLSL::AST::BaseFunctionAttribute::BaseFunctionAttribute): >+ * Modules/webgpu/WHLSL/AST/WHLSLBaseSemantic.h: Added. >+ (WebCore::WHLSL::AST::BaseSemantic::BaseSemantic): >+ * Modules/webgpu/WHLSL/AST/WHLSLBlock.h: Added. >+ (WebCore::WHLSL::AST::Block::Block): >+ * Modules/webgpu/WHLSL/AST/WHLSLBooleanLiteral.h: Added. >+ (WebCore::WHLSL::AST::BooleanLiteral::BooleanLiteral): >+ (WebCore::WHLSL::AST::BooleanLiteral::value const): >+ * Modules/webgpu/WHLSL/AST/WHLSLBreak.h: Added. >+ (WebCore::WHLSL::AST::Break::Break): >+ * Modules/webgpu/WHLSL/AST/WHLSLBuiltInSemantic.h: Added. >+ (WebCore::WHLSL::AST::BuiltInSemantic::BuiltInSemantic): >+ (WebCore::WHLSL::AST::BuiltInSemantic::variable const): >+ * Modules/webgpu/WHLSL/AST/WHLSLCallExpression.h: Added. >+ (WebCore::WHLSL::AST::CallExpression::CallExpression): >+ * Modules/webgpu/WHLSL/AST/WHLSLCommaExpression.h: Added. >+ (WebCore::WHLSL::AST::CommaExpression::CommaExpression): >+ * Modules/webgpu/WHLSL/AST/WHLSLConstantExpression.h: Added. >+ (WebCore::WHLSL::AST::ConstantExpression::ConstantExpression): >+ * Modules/webgpu/WHLSL/AST/WHLSLConstantExpressionEnumerationMemberReference.h: Added. >+ (WebCore::WHLSL::AST::ConstantExpressionEnumerationMemberReference::ConstantExpressionEnumerationMemberReference): >+ * Modules/webgpu/WHLSL/AST/WHLSLContinue.h: Added. >+ (WebCore::WHLSL::AST::Continue::Continue): >+ * Modules/webgpu/WHLSL/AST/WHLSLDereferenceExpression.h: Added. >+ (WebCore::WHLSL::AST::DereferenceExpression::DereferenceExpression): >+ * Modules/webgpu/WHLSL/AST/WHLSLDoWhileLoop.h: Added. >+ (WebCore::WHLSL::AST::DoWhileLoop::DoWhileLoop): >+ * Modules/webgpu/WHLSL/AST/WHLSLDotExpression.h: Added. >+ (WebCore::WHLSL::AST::DotExpression::DotExpression): >+ * Modules/webgpu/WHLSL/AST/WHLSLEffectfulExpressionStatement.h: Added. >+ (WebCore::WHLSL::AST::EffectfulExpressionStatement::EffectfulExpressionStatement): >+ * Modules/webgpu/WHLSL/AST/WHLSLEnumerationDefinition.h: Added. >+ (WebCore::WHLSL::AST::EnumerationDefinition::EnumerationDefinition): >+ * Modules/webgpu/WHLSL/AST/WHLSLEnumerationMember.h: Added. >+ (WebCore::WHLSL::AST::EnumerationMember::EnumerationMember): >+ * Modules/webgpu/WHLSL/AST/WHLSLExpression.h: Added. >+ (WebCore::WHLSL::AST::Expression::Expression): >+ (WebCore::WHLSL::AST::Expression::origin const): >+ * Modules/webgpu/WHLSL/AST/WHLSLFallthrough.h: Added. >+ (WebCore::WHLSL::AST::Fallthrough::Fallthrough): >+ * Modules/webgpu/WHLSL/AST/WHLSLFloatLiteral.h: Added. >+ (WebCore::WHLSL::AST::FloatLiteral::FloatLiteral): >+ (WebCore::WHLSL::AST::FloatLiteral::value const): >+ * Modules/webgpu/WHLSL/AST/WHLSLForLoop.h: Added. >+ (WebCore::WHLSL::AST::ForLoop::ForLoop): >+ (WebCore::WHLSL::AST::ForLoop::~ForLoop): >+ * Modules/webgpu/WHLSL/AST/WHLSLFunctionAttribute.h: Added. >+ * Modules/webgpu/WHLSL/AST/WHLSLFunctionDeclaration.h: Added. >+ (WebCore::WHLSL::AST::FunctionDeclaration::FunctionDeclaration): >+ (WebCore::WHLSL::AST::FunctionDeclaration::takeOrigin): >+ (WebCore::WHLSL::AST::FunctionDeclaration::takeAttributeBlock): >+ (WebCore::WHLSL::AST::FunctionDeclaration::takeEntryPointType): >+ (WebCore::WHLSL::AST::FunctionDeclaration::takeType): >+ (WebCore::WHLSL::AST::FunctionDeclaration::takeName): >+ (WebCore::WHLSL::AST::FunctionDeclaration::takeParameters): >+ (WebCore::WHLSL::AST::FunctionDeclaration::takeSemantic): >+ * Modules/webgpu/WHLSL/AST/WHLSLFunctionDefinition.h: Added. >+ (WebCore::WHLSL::AST::FunctionDefinition::FunctionDefinition): >+ (WebCore::WHLSL::AST::FunctionDefinition::restricted const): >+ * Modules/webgpu/WHLSL/AST/WHLSLIfStatement.h: Added. >+ (WebCore::WHLSL::AST::IfStatement::IfStatement): >+ * Modules/webgpu/WHLSL/AST/WHLSLIndexExpression.h: Added. >+ (WebCore::WHLSL::AST::IndexExpression::IndexExpression): >+ * Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.h: Added. >+ (WebCore::WHLSL::AST::IntegerLiteral::IntegerLiteral): >+ (WebCore::WHLSL::AST::IntegerLiteral::value const): >+ * Modules/webgpu/WHLSL/AST/WHLSLLogicalExpression.h: Added. >+ (WebCore::WHLSL::AST::LogicalExpression::LogicalExpression): >+ (WebCore::WHLSL::AST::LogicalExpression::type const): >+ * Modules/webgpu/WHLSL/AST/WHLSLLogicalNotExpression.h: Added. >+ (WebCore::WHLSL::AST::LogicalNotExpression::LogicalNotExpression): >+ * Modules/webgpu/WHLSL/AST/WHLSLMakeArrayReferenceExpression.h: Added. >+ (WebCore::WHLSL::AST::MakeArrayReferenceExpression::MakeArrayReferenceExpression): >+ * Modules/webgpu/WHLSL/AST/WHLSLMakePointerExpression.h: Added. >+ (WebCore::WHLSL::AST::MakePointerExpression::MakePointerExpression): >+ * Modules/webgpu/WHLSL/AST/WHLSLNativeFunctionDeclaration.h: Added. >+ (WebCore::WHLSL::AST::NativeFunctionDeclaration::NativeFunctionDeclaration): >+ (WebCore::WHLSL::AST::NativeFunctionDeclaration::restricted const): >+ * Modules/webgpu/WHLSL/AST/WHLSLNativeTypeDeclaration.h: Added. >+ (WebCore::WHLSL::AST::NativeTypeDeclaration::NativeTypeDeclaration): >+ * Modules/webgpu/WHLSL/AST/WHLSLNode.h: Added. >+ * Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h: Added. >+ (WebCore::WHLSL::AST::NullLiteral::NullLiteral): >+ * Modules/webgpu/WHLSL/AST/WHLSLNumThreadsFunctionAttribute.h: Added. >+ (WebCore::WHLSL::AST::NumThreadsFunctionAttribute::NumThreadsFunctionAttribute): >+ (WebCore::WHLSL::AST::NumThreadsFunctionAttribute::width const): >+ (WebCore::WHLSL::AST::NumThreadsFunctionAttribute::height const): >+ (WebCore::WHLSL::AST::NumThreadsFunctionAttribute::depth const): >+ * Modules/webgpu/WHLSL/AST/WHLSLParameter.h: Added. >+ (WebCore::WHLSL::AST::Parameter::Parameter): >+ * Modules/webgpu/WHLSL/AST/WHLSLPointerType.h: Added. >+ (WebCore::WHLSL::AST::PointerType::PointerType): >+ * Modules/webgpu/WHLSL/AST/WHLSLPropertyAccessExpression.h: Added. >+ (WebCore::WHLSL::AST::PropertyAccessExpression::PropertyAccessExpression): >+ * Modules/webgpu/WHLSL/AST/WHLSLQualifier.h: Added. >+ * Modules/webgpu/WHLSL/AST/WHLSLReadModifyWriteExpression.h: Added. >+ (WebCore::WHLSL::AST::ReadModifyWriteExpression::ReadModifyWriteExpression): >+ (WebCore::WHLSL::AST::ReadModifyWriteExpression::setNewValueExpression): >+ (WebCore::WHLSL::AST::ReadModifyWriteExpression::setResultExpression): >+ (WebCore::WHLSL::AST::ReadModifyWriteExpression::oldVariableReference): >+ (WebCore::WHLSL::AST::ReadModifyWriteExpression::newVariableReference): >+ * Modules/webgpu/WHLSL/AST/WHLSLReferenceType.h: Added. >+ (WebCore::WHLSL::AST::ReferenceType::ReferenceType): >+ (WebCore::WHLSL::AST::ReferenceType::origin const): >+ (WebCore::WHLSL::AST::ReferenceType::addressSpace const): >+ (WebCore::WHLSL::AST::ReferenceType::elementType const): >+ * Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.h: Added. >+ (WebCore::WHLSL::AST::ResourceSemantic::ResourceSemantic): >+ (WebCore::WHLSL::AST::ResourceSemantic::mode const): >+ (WebCore::WHLSL::AST::ResourceSemantic::index const): >+ (WebCore::WHLSL::AST::ResourceSemantic::space const): >+ * Modules/webgpu/WHLSL/AST/WHLSLReturn.h: Added. >+ (WebCore::WHLSL::AST::Return::Return): >+ * Modules/webgpu/WHLSL/AST/WHLSLSemantic.h: Added. >+ * Modules/webgpu/WHLSL/AST/WHLSLSpecializationConstantSemantic.h: Added. >+ (WebCore::WHLSL::AST::SpecializationConstantSemantic::SpecializationConstantSemantic): >+ * Modules/webgpu/WHLSL/AST/WHLSLStageInOutSemantic.h: Added. >+ (WebCore::WHLSL::AST::StageInOutSemantic::StageInOutSemantic): >+ (WebCore::WHLSL::AST::StageInOutSemantic::index const): >+ * Modules/webgpu/WHLSL/AST/WHLSLStatement.h: Added. >+ (WebCore::WHLSL::AST::Statement::Statement): >+ * Modules/webgpu/WHLSL/AST/WHLSLStructureDefinition.h: Added. >+ (WebCore::WHLSL::AST::StructureDefinition::StructureDefinition): >+ * Modules/webgpu/WHLSL/AST/WHLSLStructureElement.h: Added. >+ (WebCore::WHLSL::AST::StructureElement::StructureElement): >+ * Modules/webgpu/WHLSL/AST/WHLSLSwitchCase.h: Added. >+ (WebCore::WHLSL::AST::SwitchCase::SwitchCase): >+ * Modules/webgpu/WHLSL/AST/WHLSLSwitchStatement.h: Added. >+ (WebCore::WHLSL::AST::SwitchStatement::SwitchStatement): >+ * Modules/webgpu/WHLSL/AST/WHLSLTernaryExpression.h: Added. >+ (WebCore::WHLSL::AST::TernaryExpression::TernaryExpression): >+ * Modules/webgpu/WHLSL/AST/WHLSLTrap.h: Added. >+ (WebCore::WHLSL::AST::Trap::Trap): >+ * Modules/webgpu/WHLSL/AST/WHLSLType.h: Added. >+ * Modules/webgpu/WHLSL/AST/WHLSLTypeArgument.h: Added. >+ * Modules/webgpu/WHLSL/AST/WHLSLTypeDefinition.h: Added. >+ (WebCore::WHLSL::AST::TypeDefinition::TypeDefinition): >+ * Modules/webgpu/WHLSL/AST/WHLSLTypeReference.h: Added. >+ (WebCore::WHLSL::AST::TypeReference::TypeReference): >+ * Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.h: Added. >+ (WebCore::WHLSL::AST::UnsignedIntegerLiteral::UnsignedIntegerLiteral): >+ (WebCore::WHLSL::AST::UnsignedIntegerLiteral::value const): >+ * Modules/webgpu/WHLSL/AST/WHLSLValue.h: Added. >+ (WebCore::WHLSL::AST::Value::Value): >+ * Modules/webgpu/WHLSL/AST/WHLSLVariableDeclaration.h: Added. >+ (WebCore::WHLSL::AST::VariableDeclaration::VariableDeclaration): >+ (WebCore::WHLSL::AST::VariableDeclaration::origin const): >+ * Modules/webgpu/WHLSL/AST/WHLSLVariableDeclarationsStatement.h: Added. >+ (WebCore::WHLSL::AST::VariableDeclarationsStatement::VariableDeclarationsStatement): >+ * Modules/webgpu/WHLSL/AST/WHLSLVariableReference.h: Added. >+ (WebCore::WHLSL::AST::VariableReference::VariableReference): >+ (WebCore::WHLSL::AST::VariableReference::wrap): >+ * Modules/webgpu/WHLSL/AST/WHLSLWhileLoop.h: Added. >+ (WebCore::WHLSL::AST::WhileLoop::WhileLoop): >+ * Modules/webgpu/WHLSL/WHLSLParser.cpp: Added. >+ * Modules/webgpu/WHLSL/WHLSLParser.h: Added. >+ * Sources.txt: >+ * WebCore.xcodeproj/project.pbxproj: >+ > 2019-01-02 Wenson Hsieh <wenson_hsieh@apple.com> > > Add support for using the current text selection as the find string on iOS >diff --git a/Source/WebCore/DerivedSources.make b/Source/WebCore/DerivedSources.make >index e948b702f37..f5113794727 100644 >--- a/Source/WebCore/DerivedSources.make >+++ b/Source/WebCore/DerivedSources.make >@@ -1598,6 +1598,15 @@ $(GENERATE_SETTINGS_PATTERNS) : $(WebCore)/Scripts/GenerateSettings.rb $(GENERAT > > # -------- > >+# WHLSL Standard Library >+ >+all : WHLSLStandardLibrary.cpp >+ >+WHLSLStandardLibrary.cpp : $(JavaScriptCore_SCRIPTS_DIR)/xxd.pl $(WebCore)/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt >+ $(PERL) $(JavaScriptCore_SCRIPTS_DIR)/xxd.pl WHLSLStandardLibrary $(WebCore)/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt WHLSLStandardLibrary.h >+ >+# -------- >+ > # Common generator things > > COMMON_BINDINGS_SCRIPTS = \ >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLArrayReferenceType.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLArrayReferenceType.h >new file mode 100644 >index 00000000000..01d68f1276d >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLArrayReferenceType.h >@@ -0,0 +1,71 @@ >+/* >+ * 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 "WHLSLReferenceType.h" >+#include <wtf/UniqueRef.h> >+#include <wtf/text/WTFString.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class ArrayReferenceType : public ReferenceType { >+public: >+ ArrayReferenceType(Lexer::Token&& origin, AddressSpace addressSpace, UniqueRef<UnnamedType>&& elementType) >+ : ReferenceType(WTFMove(origin), addressSpace, WTFMove(elementType)) >+ { >+ } >+ >+ virtual ~ArrayReferenceType() = default; >+ >+ ArrayReferenceType(const ArrayReferenceType&) = delete; >+ ArrayReferenceType(ArrayReferenceType&&) = default; >+ >+ bool isArrayReferenceType() const override { return true; } >+ >+ UniqueRef<UnnamedType> clone() const override >+ { >+ return makeUniqueRef<ArrayReferenceType>(Lexer::Token(origin()), addressSpace(), elementType().clone()); >+ } >+ >+private: >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+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 >new file mode 100644 >index 00000000000..422fd3c713a >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLArrayType.h >@@ -0,0 +1,80 @@ >+/* >+ * 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 "WHLSLUnnamedType.h" >+#include "WHLSLTypeArgument.h" >+#include <wtf/UniqueRef.h> >+#include <wtf/text/WTFString.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class ArrayType : public UnnamedType { >+public: >+ ArrayType(Lexer::Token&& origin, UniqueRef<UnnamedType>&& elementType, unsigned numElements) >+ : UnnamedType(WTFMove(origin)) >+ , m_elementType(WTFMove(elementType)) >+ , m_numElements(numElements) >+ { >+ } >+ >+ virtual ~ArrayType() = default; >+ >+ ArrayType(const ArrayType&) = delete; >+ ArrayType(ArrayType&&) = default; >+ >+ bool isArrayType() const override { return true; } >+ >+ 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; } >+ >+ UniqueRef<UnnamedType> clone() const override >+ { >+ return makeUniqueRef<ArrayType>(Lexer::Token(origin()), m_elementType->clone(), m_numElements); >+ } >+ >+private: >+ UniqueRef<UnnamedType> m_elementType; >+ unsigned m_numElements; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+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 >new file mode 100644 >index 00000000000..9dd07f8c827 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAssignmentExpression.h >@@ -0,0 +1,72 @@ >+/* >+ * 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 "WHLSLExpression.h" >+#include "WHLSLLexer.h" >+#include <wtf/UniqueRef.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class AssignmentExpression : public Expression { >+public: >+ AssignmentExpression(Lexer::Token&& origin, UniqueRef<Expression>&& left, UniqueRef<Expression>&& right) >+ : Expression(WTFMove(origin)) >+ , m_left(WTFMove(left)) >+ , m_right(WTFMove(right)) >+ { >+ } >+ >+ virtual ~AssignmentExpression() = default; >+ >+ AssignmentExpression(const AssignmentExpression&) = delete; >+ AssignmentExpression(AssignmentExpression&&) = default; >+ >+ bool isAssignmentExpression() const override { return true; } >+ >+ Expression& left() { return static_cast<Expression&>(m_left); } >+ Expression& right() { return static_cast<Expression&>(m_right); } >+ >+private: >+ UniqueRef<Expression> m_left; >+ UniqueRef<Expression> m_right; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_EXPRESSION(AssignmentExpression, isAssignmentExpression()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBaseFunctionAttribute.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBaseFunctionAttribute.h >new file mode 100644 >index 00000000000..a6a0613b2e8 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBaseFunctionAttribute.h >@@ -0,0 +1,61 @@ >+/* >+ * 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" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class BaseFunctionAttribute : public Node { >+public: >+ BaseFunctionAttribute(Lexer::Token&& origin) >+ : m_origin(WTFMove(origin)) >+ { >+ } >+ >+ virtual ~BaseFunctionAttribute() = default; >+ >+ BaseFunctionAttribute(const BaseFunctionAttribute&) = delete; >+ BaseFunctionAttribute(BaseFunctionAttribute&&) = default; >+ >+private: >+ Lexer::Token m_origin; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBaseSemantic.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBaseSemantic.h >new file mode 100644 >index 00000000000..cb436537387 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBaseSemantic.h >@@ -0,0 +1,74 @@ >+/* >+ * 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" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+class Intrinsics; >+ >+namespace AST { >+ >+class FunctionDefinition; >+class UnnamedType; >+ >+class BaseSemantic : public Node { >+public: >+ BaseSemantic(Lexer::Token&& origin) >+ : m_origin(WTFMove(origin)) >+ { >+ } >+ >+ virtual ~BaseSemantic() = default; >+ >+ BaseSemantic(const BaseSemantic&) = delete; >+ BaseSemantic(BaseSemantic&&) = default; >+ >+ virtual bool isAcceptableType(const 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 >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBlock.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBlock.h >new file mode 100644 >index 00000000000..6c436cd074a >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBlock.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 "WHLSLLexer.h" >+#include "WHLSLStatement.h" >+#include <wtf/Vector.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class Block : public Statement { >+public: >+ Block(Lexer::Token&& origin, Statements&& statements) >+ : Statement(WTFMove(origin)) >+ , m_statements(WTFMove(statements)) >+ { >+ } >+ >+ virtual ~Block() = default; >+ >+ Block(const Block&) = delete; >+ Block(Block&&) = default; >+ >+ Statements& statements() { return m_statements; } >+ >+ bool isBlock() const override { return true; } >+ >+private: >+ Statements m_statements; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_STATEMENT(Block, isBlock()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBooleanLiteral.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBooleanLiteral.h >new file mode 100644 >index 00000000000..3b25c8b5d7f >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBooleanLiteral.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 "WHLSLExpression.h" >+#include "WHLSLLexer.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class BooleanLiteral : public Expression { >+public: >+ BooleanLiteral(Lexer::Token&& origin, bool value) >+ : Expression(WTFMove(origin)) >+ , m_value(value) >+ { >+ } >+ >+ virtual ~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 >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_EXPRESSION(BooleanLiteral, isBooleanLiteral()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBreak.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBreak.h >new file mode 100644 >index 00000000000..5fffe8698a5 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBreak.h >@@ -0,0 +1,64 @@ >+/* >+ * 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 "WHLSLStatement.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class Break : public Statement { >+public: >+ Break(Lexer::Token&& origin) >+ : Statement(WTFMove(origin)) >+ { >+ } >+ >+ virtual ~Break() = default; >+ >+ Break(const Break&) = delete; >+ Break(Break&&) = default; >+ >+ bool isBreak() const override { return true; } >+ >+private: >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_STATEMENT(Break, isBreak()) >+ >+#endif >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..f7f4da4f953 >--- /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 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 >new file mode 100644 >index 00000000000..13ee139eb10 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBuiltInSemantic.h >@@ -0,0 +1,97 @@ >+/* >+ * 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 "WHLSLBaseSemantic.h" >+#include "WHLSLLexer.h" >+#include <wtf/Optional.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class BuiltInSemantic : public BaseSemantic { >+public: >+ enum class Variable : uint8_t { >+ SVInstanceID, >+ SVVertexID, >+ PSize, >+ SVPosition, >+ SVIsFrontFace, >+ SVSampleIndex, >+ SVInnerCoverage, >+ SVTarget, >+ SVDepth, >+ SVCoverage, >+ SVDispatchThreadID, >+ SVGroupID, >+ SVGroupIndex, >+ SVGroupThreadID >+ }; >+ >+ BuiltInSemantic(Lexer::Token&& origin, Variable variable, Optional<unsigned>&& targetIndex = WTF::nullopt) >+ : BaseSemantic(WTFMove(origin)) >+ , m_variable(variable) >+ , m_targetIndex(WTFMove(targetIndex)) >+ { >+ } >+ >+ virtual ~BuiltInSemantic() = default; >+ >+ BuiltInSemantic(const BuiltInSemantic&) = delete; >+ BuiltInSemantic(BuiltInSemantic&&) = default; >+ >+ 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 UnnamedType&, const Intrinsics&) const override; >+ bool isAcceptableForShaderItemDirection(ShaderItemDirection, const FunctionDefinition&) const override; >+ >+private: >+ Variable m_variable; >+ Optional<unsigned> m_targetIndex; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLCallExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLCallExpression.h >new file mode 100644 >index 00000000000..f35bed70817 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLCallExpression.h >@@ -0,0 +1,100 @@ >+/* >+ * 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 "WHLSLExpression.h" >+#include "WHLSLFunctionDeclaration.h" >+#include "WHLSLLexer.h" >+#include <wtf/UniqueRef.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class NamedType; >+ >+class CallExpression : public Expression { >+public: >+ CallExpression(Lexer::Token&& origin, String&& name, Vector<UniqueRef<Expression>>&& arguments) >+ : Expression(WTFMove(origin)) >+ , m_name(WTFMove(name)) >+ , m_arguments(WTFMove(arguments)) >+ { >+ } >+ >+ virtual ~CallExpression() = default; >+ >+ CallExpression(const CallExpression&) = delete; >+ CallExpression(CallExpression&&) = default; >+ >+ bool isCallExpression() const override { return true; } >+ >+ Vector<UniqueRef<Expression>>& arguments() { return m_arguments; } >+ >+ String& name() { return m_name; } >+ >+ void setCastData(NamedType& namedType) >+ { >+ m_castReturnType = { namedType }; >+ } >+ >+ bool isCast() { return static_cast<bool>(m_castReturnType); } >+ Optional<std::reference_wrapper<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<UniqueRef<Expression>> m_arguments; >+ Optional<Vector<std::reference_wrapper<FunctionDeclaration>, 1>> m_overloads; >+ FunctionDeclaration* m_function { nullptr }; >+ Optional<std::reference_wrapper<NamedType>> m_castReturnType { WTF::nullopt }; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_EXPRESSION(CallExpression, isCallExpression()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLCommaExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLCommaExpression.h >new file mode 100644 >index 00000000000..e322f53e734 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLCommaExpression.h >@@ -0,0 +1,70 @@ >+/* >+ * 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 "WHLSLExpression.h" >+#include "WHLSLLexer.h" >+#include <wtf/UniqueRef.h> >+#include <wtf/Vector.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class CommaExpression : public Expression { >+public: >+ CommaExpression(Lexer::Token&& origin, Vector<UniqueRef<Expression>>&& list) >+ : Expression(WTFMove(origin)) >+ , m_list(WTFMove(list)) >+ { >+ } >+ >+ virtual ~CommaExpression() = default; >+ >+ CommaExpression(const CommaExpression&) = delete; >+ CommaExpression(CommaExpression&&) = default; >+ >+ bool isCommaExpression() const override { return true; } >+ >+ Vector<UniqueRef<Expression>>& list() { return m_list; } >+ >+private: >+ Vector<UniqueRef<Expression>> m_list; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_EXPRESSION(CommaExpression, isCommaExpression()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLConstantExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLConstantExpression.h >new file mode 100644 >index 00000000000..1d4fa7d9fe1 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLConstantExpression.h >@@ -0,0 +1,182 @@ >+/* >+ * 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 "WHLSLBooleanLiteral.h" >+#include "WHLSLConstantExpressionEnumerationMemberReference.h" >+#include "WHLSLFloatLiteral.h" >+#include "WHLSLIntegerLiteral.h" >+#include "WHLSLNullLiteral.h" >+#include "WHLSLUnsignedIntegerLiteral.h" >+#include <wtf/Variant.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+// FIXME: macOS Sierra doesn't seem to support putting Variants inside Variants, >+// so this is a wrapper class to make sure that doesn't happen. As soon as we don't >+// have to support Sierra, this can be migrated to a Variant proper. >+class ConstantExpression { >+public: >+ ConstantExpression(IntegerLiteral&& integerLiteral) >+ : m_variant(WTFMove(integerLiteral)) >+ { >+ } >+ >+ ConstantExpression(UnsignedIntegerLiteral&& unsignedIntegerLiteral) >+ : m_variant(WTFMove(unsignedIntegerLiteral)) >+ { >+ } >+ >+ ConstantExpression(FloatLiteral&& floatLiteral) >+ : m_variant(WTFMove(floatLiteral)) >+ { >+ } >+ >+ ConstantExpression(NullLiteral&& nullLiteral) >+ : m_variant(WTFMove(nullLiteral)) >+ { >+ } >+ >+ ConstantExpression(BooleanLiteral&& booleanLiteral) >+ : m_variant(WTFMove(booleanLiteral)) >+ { >+ } >+ >+ ConstantExpression(ConstantExpressionEnumerationMemberReference&& constantExpressionEnumerationMemberReference) >+ : m_variant(WTFMove(constantExpressionEnumerationMemberReference)) >+ { >+ } >+ >+ 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, >+ UnsignedIntegerLiteral, >+ FloatLiteral, >+ NullLiteral, >+ BooleanLiteral, >+ ConstantExpressionEnumerationMemberReference >+ > m_variant; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLConstantExpressionEnumerationMemberReference.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLConstantExpressionEnumerationMemberReference.h >new file mode 100644 >index 00000000000..7a20c30d5c3 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLConstantExpressionEnumerationMemberReference.h >@@ -0,0 +1,108 @@ >+/* >+ * 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 <wtf/text/WTFString.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class EnumerationDefinition; >+class EnumerationMember; >+ >+class ConstantExpressionEnumerationMemberReference : public Expression { >+public: >+ ConstantExpressionEnumerationMemberReference(Lexer::Token&& origin, String&& left, String&& right) >+ : Expression(WTFMove(origin)) >+ , m_left(WTFMove(left)) >+ , m_right(WTFMove(right)) >+ { >+ } >+ >+ virtual ~ConstantExpressionEnumerationMemberReference() = default; >+ >+ 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; >+ } >+ >+ EnumerationDefinition* enumerationDefinition() >+ { >+ return m_enumerationDefinition; >+ } >+ >+ EnumerationDefinition* enumerationDefinition() const >+ { >+ return m_enumerationDefinition; >+ } >+ >+ EnumerationMember* enumerationMember() >+ { >+ return m_enumerationMember; >+ } >+ >+ EnumerationMember* enumerationMember() const >+ { >+ return m_enumerationMember; >+ } >+ >+ void setEnumerationMember(EnumerationDefinition& enumerationDefinition, EnumerationMember& enumerationMember) >+ { >+ m_enumerationDefinition = &enumerationDefinition; >+ m_enumerationMember = &enumerationMember; >+ } >+ >+private: >+ String m_left; >+ String m_right; >+ EnumerationDefinition* m_enumerationDefinition { nullptr }; >+ EnumerationMember* m_enumerationMember { nullptr }; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLContinue.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLContinue.h >new file mode 100644 >index 00000000000..534ae22063d >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLContinue.h >@@ -0,0 +1,64 @@ >+/* >+ * 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 "WHLSLStatement.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class Continue : public Statement { >+public: >+ Continue(Lexer::Token&& origin) >+ : Statement(WTFMove(origin)) >+ { >+ } >+ >+ virtual ~Continue() = default; >+ >+ Continue(const Continue&) = delete; >+ Continue(Continue&&) = default; >+ >+ bool isContinue() const override { return true; } >+ >+private: >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_STATEMENT(Continue, isContinue()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDereferenceExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDereferenceExpression.h >new file mode 100644 >index 00000000000..afc3103188a >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDereferenceExpression.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 "WHLSLExpression.h" >+#include "WHLSLLexer.h" >+#include <wtf/UniqueRef.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class DereferenceExpression : public Expression { >+public: >+ DereferenceExpression(Lexer::Token&& origin, UniqueRef<Expression>&& pointer) >+ : Expression(WTFMove(origin)) >+ , m_pointer(WTFMove(pointer)) >+ { >+ } >+ >+ virtual ~DereferenceExpression() = default; >+ >+ DereferenceExpression(const DereferenceExpression&) = delete; >+ DereferenceExpression(DereferenceExpression&&) = default; >+ >+ bool isDereferenceExpression() const override { return true; } >+ >+ Expression& pointer() { return static_cast<Expression&>(m_pointer); } >+ >+private: >+ UniqueRef<Expression> m_pointer; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_EXPRESSION(DereferenceExpression, isDereferenceExpression()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDoWhileLoop.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDoWhileLoop.h >new file mode 100644 >index 00000000000..fbf44872de2 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDoWhileLoop.h >@@ -0,0 +1,73 @@ >+/* >+ * 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 "WHLSLExpression.h" >+#include "WHLSLLexer.h" >+#include "WHLSLStatement.h" >+#include <wtf/UniqueRef.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class DoWhileLoop : public Statement { >+public: >+ DoWhileLoop(Lexer::Token&& origin, UniqueRef<Statement>&& body, UniqueRef<Expression>&& conditional) >+ : Statement(WTFMove(origin)) >+ , m_body(WTFMove(body)) >+ , m_conditional(WTFMove(conditional)) >+ { >+ } >+ >+ virtual ~DoWhileLoop() = default; >+ >+ DoWhileLoop(const DoWhileLoop&) = delete; >+ DoWhileLoop(DoWhileLoop&&) = default; >+ >+ bool isDoWhileLoop() const override { return true; } >+ >+ Statement& body() { return static_cast<Statement&>(m_body); } >+ Expression& conditional() { return static_cast<Expression&>(m_conditional); } >+ >+private: >+ UniqueRef<Statement> m_body; >+ UniqueRef<Expression> m_conditional; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_STATEMENT(DoWhileLoop, isDoWhileLoop()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDotExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDotExpression.h >new file mode 100644 >index 00000000000..c1cf50e5627 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDotExpression.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 "WHLSLPropertyAccessExpression.h" >+#include <wtf/UniqueRef.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class DotExpression : public PropertyAccessExpression { >+public: >+ DotExpression(Lexer::Token&& origin, UniqueRef<Expression>&& base, String&& fieldName) >+ : PropertyAccessExpression(WTFMove(origin), WTFMove(base)) >+ , m_fieldName(WTFMove(fieldName)) >+ { >+ } >+ >+ virtual ~DotExpression() = default; >+ >+ 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 >new file mode 100644 >index 00000000000..33325f17824 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEffectfulExpressionStatement.h >@@ -0,0 +1,70 @@ >+/* >+ * 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 "WHLSLExpression.h" >+#include "WHLSLLexer.h" >+#include "WHLSLStatement.h" >+#include <wtf/UniqueRef.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class EffectfulExpressionStatement : public Statement { >+public: >+ EffectfulExpressionStatement(UniqueRef<Expression>&& effectfulExpression) >+ : Statement(Lexer::Token(effectfulExpression->origin())) >+ , m_effectfulExpression(WTFMove(effectfulExpression)) >+ { >+ } >+ >+ virtual ~EffectfulExpressionStatement() = default; >+ >+ EffectfulExpressionStatement(const EffectfulExpressionStatement&) = delete; >+ EffectfulExpressionStatement(EffectfulExpressionStatement&&) = default; >+ >+ bool isEffectfulExpressionStatement() const override { return true; } >+ >+ Expression& effectfulExpression() { return static_cast<Expression&>(m_effectfulExpression); } >+ >+private: >+ UniqueRef<Expression> m_effectfulExpression; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_STATEMENT(EffectfulExpressionStatement, isEffectfulExpressionStatement()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEnumerationDefinition.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEnumerationDefinition.h >new file mode 100644 >index 00000000000..23857f3464e >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEnumerationDefinition.h >@@ -0,0 +1,99 @@ >+/* >+ * 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 "WHLSLLexer.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 { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class EnumerationDefinition : public NamedType { >+public: >+ EnumerationDefinition(Lexer::Token&& origin, String&& name, Optional<UniqueRef<UnnamedType>>&& type) >+ : NamedType(WTFMove(origin), WTFMove(name)) >+ , m_type(WTFMove(type)) >+ { >+ } >+ >+ virtual ~EnumerationDefinition() = default; >+ >+ EnumerationDefinition(const EnumerationDefinition&) = delete; >+ EnumerationDefinition(EnumerationDefinition&&) = default; >+ >+ bool isEnumerationDefinition() const override { return true; } >+ >+ UnnamedType* type() { return m_type ? &static_cast<UnnamedType&>(*m_type) : nullptr; } >+ >+ 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: >+ Optional<UniqueRef<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 >new file mode 100644 >index 00000000000..afeb18600e9 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEnumerationMember.h >@@ -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. >+ */ >+ >+#pragma once >+ >+#if ENABLE(WEBGPU) >+ >+#include "WHLSLConstantExpression.h" >+#include "WHLSLLexer.h" >+#include "WHLSLNode.h" >+#include <wtf/Optional.h> >+#include <wtf/Vector.h> >+#include <wtf/text/WTFString.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class EnumerationMember : public Node { >+public: >+ EnumerationMember(Lexer::Token&& origin, String&& name, Optional<ConstantExpression>&& value = WTF::nullopt) >+ : m_origin(WTFMove(origin)) >+ , m_name(WTFMove(name)) >+ , m_value(WTFMove(value)) >+ { >+ } >+ >+ virtual ~EnumerationMember() = default; >+ >+ 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; >+}; >+ >+using EnumerationMembers = Vector<EnumerationMember>; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >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 >new file mode 100644 >index 00000000000..8fafa29fe67 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLExpression.h >@@ -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. >+ */ >+ >+#pragma once >+ >+#if ENABLE(WEBGPU) >+ >+#include "WHLSLLexer.h" >+#include "WHLSLValue.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class Expression : public Value { >+public: >+ Expression(Lexer::Token&& origin) >+ : m_origin(WTFMove(origin)) >+ { >+ } >+ >+ virtual ~Expression() = default; >+ >+ explicit Expression(const Expression&) = default; >+ Expression(Expression&&) = default; >+ >+ 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; } >+ virtual bool isMakeArrayReferenceExpression() const { return false; } >+ virtual bool isMakePointerExpression() const { return false; } >+ virtual bool isNullLiteral() const { return false; } >+ virtual bool isPropertyAccessExpression() const { return false; } >+ virtual bool isReadModifyWriteExpression() const { return false; } >+ 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 >+ >+} >+ >+} >+ >+#define SPECIALIZE_TYPE_TRAITS_WHLSL_EXPRESSION(ToValueTypeName, predicate) \ >+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::WHLSL::AST::ToValueTypeName) \ >+ static bool isType(const WebCore::WHLSL::AST::Expression& expression) { return expression.predicate; } \ >+SPECIALIZE_TYPE_TRAITS_END() >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFallthrough.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFallthrough.h >new file mode 100644 >index 00000000000..4e66c9a4f54 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFallthrough.h >@@ -0,0 +1,64 @@ >+/* >+ * 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 "WHLSLStatement.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class Fallthrough : public Statement { >+public: >+ Fallthrough(Lexer::Token&& origin) >+ : Statement(WTFMove(origin)) >+ { >+ } >+ >+ virtual ~Fallthrough() = default; >+ >+ Fallthrough(const Fallthrough&) = delete; >+ Fallthrough(Fallthrough&&) = default; >+ >+ bool isFallthrough() const override { return true; } >+ >+private: >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_STATEMENT(Fallthrough, isFallthrough()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteral.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteral.h >new file mode 100644 >index 00000000000..2263b4a2043 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteral.h >@@ -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. >+ */ >+ >+#pragma once >+ >+#if ENABLE(WEBGPU) >+ >+#include "WHLSLExpression.h" >+#include "WHLSLFloatLiteralType.h" >+#include "WHLSLLexer.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class FloatLiteral : public Expression { >+public: >+ FloatLiteral(Lexer::Token&& origin, float value) >+ : Expression(Lexer::Token(origin)) >+ , m_type(WTFMove(origin), value) >+ , m_value(value) >+ { >+ } >+ >+ virtual ~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 >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_EXPRESSION(FloatLiteral, isFloatLiteral()) >+ >+#endif >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 >new file mode 100644 >index 00000000000..5ebe9b9a676 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLForLoop.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 "WHLSLExpression.h" >+#include "WHLSLLexer.h" >+#include "WHLSLStatement.h" >+#include "WHLSLVariableDeclarationsStatement.h" >+#include <memory> >+#include <wtf/UniqueRef.h> >+#include <wtf/Variant.h> >+#include <wtf/Vector.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class ForLoop : public Statement { >+public: >+ ForLoop(Lexer::Token&& origin, Variant<VariableDeclarationsStatement, UniqueRef<Expression>>&& initialization, Optional<UniqueRef<Expression>>&& condition, Optional<UniqueRef<Expression>>&& increment, UniqueRef<Statement>&& body) >+ : Statement(WTFMove(origin)) >+ , m_initialization(WTFMove(initialization)) >+ , m_condition(WTFMove(condition)) >+ , m_increment(WTFMove(increment)) >+ , m_body(WTFMove(body)) >+ { >+ } >+ >+ virtual ~ForLoop() >+ { >+ } >+ >+ ForLoop(const ForLoop&) = delete; >+ ForLoop(ForLoop&&) = default; >+ >+ bool isForLoop() const override { return true; } >+ >+ Variant<VariableDeclarationsStatement, UniqueRef<Expression>>& initialization() { return m_initialization; } >+ Expression* condition() { return m_condition ? &static_cast<Expression&>(*m_condition) : nullptr; } >+ Expression* increment() { return m_increment ? &static_cast<Expression&>(*m_increment) : nullptr; } >+ Statement& body() { return static_cast<Statement&>(m_body); } >+ >+private: >+ Variant<VariableDeclarationsStatement, UniqueRef<Expression>> m_initialization; >+ Optional<UniqueRef<Expression>> m_condition; >+ Optional<UniqueRef<Expression>> m_increment; >+ UniqueRef<Statement> m_body; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_STATEMENT(ForLoop, isForLoop()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFunctionAttribute.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFunctionAttribute.h >new file mode 100644 >index 00000000000..7749be6522f >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFunctionAttribute.h >@@ -0,0 +1,49 @@ >+/* >+ * 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 "WHLSLNumThreadsFunctionAttribute.h" >+#include <wtf/Variant.h> >+#include <wtf/Vector.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+using FunctionAttribute = Variant<NumThreadsFunctionAttribute>; >+using AttributeBlock = Vector<FunctionAttribute>; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFunctionDeclaration.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFunctionDeclaration.h >new file mode 100644 >index 00000000000..6af7b50954e >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFunctionDeclaration.h >@@ -0,0 +1,107 @@ >+/* >+ * 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 "WHLSLFunctionAttribute.h" >+#include "WHLSLLexer.h" >+#include "WHLSLNode.h" >+#include "WHLSLSemantic.h" >+#include "WHLSLUnnamedType.h" >+#include "WHLSLVariableDeclaration.h" >+#include <wtf/UniqueRef.h> >+#include <wtf/text/WTFString.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class FunctionDeclaration : public Node { >+public: >+ enum class EntryPointType : uint8_t { >+ Vertex, >+ Fragment, >+ Compute, >+ // FIXME: Add an entry point type for testing >+ }; >+ >+ FunctionDeclaration(Lexer::Token&& origin, AttributeBlock&& attributeBlock, Optional<EntryPointType> entryPointType, UniqueRef<UnnamedType>&& type, String&& name, VariableDeclarations&& parameters, Optional<Semantic>&& semantic, bool isOperator) >+ : m_origin(WTFMove(origin)) >+ , m_attributeBlock(WTFMove(attributeBlock)) >+ , m_entryPointType(entryPointType) >+ , m_type(WTFMove(type)) >+ , m_name(WTFMove(name)) >+ , m_parameters(WTFMove(parameters)) >+ , m_semantic(WTFMove(semantic)) >+ , m_isOperator(WTFMove(isOperator)) >+ { >+ } >+ >+ virtual ~FunctionDeclaration() = default; >+ >+ FunctionDeclaration(const FunctionDeclaration&) = delete; >+ FunctionDeclaration(FunctionDeclaration&&) = default; >+ >+ virtual bool isFunctionDefinition() const { return false; } >+ virtual bool isNativeFunctionDeclaration() const { return false; } >+ >+ AttributeBlock& attributeBlock() { return m_attributeBlock; } >+ const Optional<EntryPointType>& entryPointType() const { return m_entryPointType; } >+ const UnnamedType& type() const { return static_cast<const UnnamedType&>(m_type); } >+ UnnamedType& type() { return static_cast<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<Semantic>& semantic() { return m_semantic; } >+ bool isOperator() const { return m_isOperator; } >+ >+private: >+ Lexer::Token m_origin; >+ AttributeBlock m_attributeBlock; >+ Optional<EntryPointType> m_entryPointType; >+ UniqueRef<UnnamedType> m_type; >+ String m_name; >+ VariableDeclarations m_parameters; >+ Optional<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 >new file mode 100644 >index 00000000000..2a4b9834750 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFunctionDefinition.h >@@ -0,0 +1,71 @@ >+/* >+ * 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 "WHLSLBlock.h" >+#include "WHLSLFunctionDeclaration.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class FunctionDefinition : public FunctionDeclaration { >+public: >+ FunctionDefinition(FunctionDeclaration&& functionDeclaration, Block&& block, bool restricted) >+ : FunctionDeclaration(WTFMove(functionDeclaration)) >+ , m_block(WTFMove(block)) >+ , m_restricted(restricted) >+ { >+ } >+ >+ virtual ~FunctionDefinition() = default; >+ >+ FunctionDefinition(const FunctionDefinition&) = delete; >+ FunctionDefinition(FunctionDefinition&&) = default; >+ >+ bool isFunctionDefinition() const override { return true; } >+ >+ Block& block() { return m_block; } >+ bool restricted() const { return m_restricted; } >+ >+private: >+ Block m_block; >+ 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 >new file mode 100644 >index 00000000000..7b23ce02f9f >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIfStatement.h >@@ -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. >+ */ >+ >+#pragma once >+ >+#if ENABLE(WEBGPU) >+ >+#include "WHLSLExpression.h" >+#include "WHLSLLexer.h" >+#include "WHLSLStatement.h" >+#include <memory> >+#include <wtf/UniqueRef.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class IfStatement : public Statement { >+public: >+ IfStatement(Lexer::Token&& origin, UniqueRef<Expression>&& conditional, UniqueRef<Statement>&& body, Optional<UniqueRef<Statement>>&& elseBody) >+ : Statement(WTFMove(origin)) >+ , m_conditional(WTFMove(conditional)) >+ , m_body(WTFMove(body)) >+ , m_elseBody(WTFMove(elseBody)) >+ { >+ } >+ >+ virtual ~IfStatement() = default; >+ >+ IfStatement(const IfStatement&) = delete; >+ IfStatement(IfStatement&&) = default; >+ >+ bool isIfStatement() const override { return true; } >+ >+ Expression& conditional() { return static_cast<Expression&>(m_conditional); } >+ Statement& body() { return static_cast<Statement&>(m_body); } >+ Statement* elseBody() { return m_elseBody ? &static_cast<Statement&>(*m_elseBody) : nullptr; } >+ >+private: >+ UniqueRef<Expression> m_conditional; >+ UniqueRef<Statement> m_body; >+ Optional<UniqueRef<Statement>> m_elseBody; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_STATEMENT(IfStatement, isIfStatement()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIndexExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIndexExpression.h >new file mode 100644 >index 00000000000..33901fca580 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIndexExpression.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 "WHLSLPropertyAccessExpression.h" >+#include <wtf/UniqueRef.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class IndexExpression : public PropertyAccessExpression { >+public: >+ IndexExpression(Lexer::Token&& origin, UniqueRef<Expression>&& base, UniqueRef<Expression>&& index) >+ : PropertyAccessExpression(WTFMove(origin), WTFMove(base)) >+ , m_index(WTFMove(index)) >+ { >+ } >+ >+ virtual ~IndexExpression() = default; >+ >+ 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: >+ 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 >new file mode 100644 >index 00000000000..cc9a0ed5846 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.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 "WHLSLExpression.h" >+#include "WHLSLIntegerLiteralType.h" >+#include "WHLSLLexer.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class IntegerLiteral : public Expression { >+public: >+ IntegerLiteral(Lexer::Token&& origin, int value) >+ : Expression(Lexer::Token(origin)) >+ , m_type(WTFMove(origin), value) >+ , m_value(value) >+ { >+ } >+ >+ virtual ~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 >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_EXPRESSION(IntegerLiteral, isIntegerLiteral()) >+ >+#endif >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 >new file mode 100644 >index 00000000000..78718bdfa95 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLLogicalExpression.h >@@ -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. >+ */ >+ >+#pragma once >+ >+#if ENABLE(WEBGPU) >+ >+#include "WHLSLExpression.h" >+#include "WHLSLLexer.h" >+#include <wtf/UniqueRef.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class LogicalExpression : public Expression { >+public: >+ enum class Type : uint8_t { >+ And, >+ Or >+ }; >+ >+ LogicalExpression(Lexer::Token&& origin, Type type, UniqueRef<Expression>&& left, UniqueRef<Expression>&& right) >+ : Expression(WTFMove(origin)) >+ , m_type(type) >+ , m_left(WTFMove(left)) >+ , m_right(WTFMove(right)) >+ { >+ } >+ >+ virtual ~LogicalExpression() = default; >+ >+ LogicalExpression(const LogicalExpression&) = delete; >+ LogicalExpression(LogicalExpression&&) = default; >+ >+ Type type() const { return m_type; } >+ >+ bool isLogicalExpression() const override { return true; } >+ >+ Expression& left() { return static_cast<Expression&>(m_left); } >+ Expression& right() { return static_cast<Expression&>(m_right); } >+ >+private: >+ Type m_type; >+ UniqueRef<Expression> m_left; >+ UniqueRef<Expression> m_right; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_EXPRESSION(LogicalExpression, isLogicalExpression()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLLogicalNotExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLLogicalNotExpression.h >new file mode 100644 >index 00000000000..decad35b526 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLLogicalNotExpression.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 "WHLSLExpression.h" >+#include "WHLSLLexer.h" >+#include <wtf/UniqueRef.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class LogicalNotExpression : public Expression { >+public: >+ LogicalNotExpression(Lexer::Token&& origin, UniqueRef<Expression>&& operand) >+ : Expression(WTFMove(origin)) >+ , m_operand(WTFMove(operand)) >+ { >+ } >+ >+ virtual ~LogicalNotExpression() = default; >+ >+ LogicalNotExpression(const LogicalNotExpression&) = delete; >+ LogicalNotExpression(LogicalNotExpression&&) = default; >+ >+ bool isLogicalNotExpression() const override { return true; } >+ >+ Expression& operand() { return static_cast<Expression&>(m_operand); } >+ >+private: >+ UniqueRef<Expression> m_operand; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_EXPRESSION(LogicalNotExpression, isLogicalNotExpression()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLMakeArrayReferenceExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLMakeArrayReferenceExpression.h >new file mode 100644 >index 00000000000..6688f87f396 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLMakeArrayReferenceExpression.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 "WHLSLExpression.h" >+#include "WHLSLLexer.h" >+#include <wtf/UniqueRef.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class MakeArrayReferenceExpression : public Expression { >+public: >+ MakeArrayReferenceExpression(Lexer::Token&& origin, UniqueRef<Expression>&& lValue) >+ : Expression(WTFMove(origin)) >+ , m_lValue(WTFMove(lValue)) >+ { >+ } >+ >+ virtual ~MakeArrayReferenceExpression() = default; >+ >+ MakeArrayReferenceExpression(const MakeArrayReferenceExpression&) = delete; >+ MakeArrayReferenceExpression(MakeArrayReferenceExpression&&) = default; >+ >+ bool isMakeArrayReferenceExpression() const override { return true; } >+ >+ Expression& lValue() { return static_cast<Expression&>(m_lValue); } >+ >+private: >+ UniqueRef<Expression> m_lValue; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_EXPRESSION(MakeArrayReferenceExpression, isMakeArrayReferenceExpression()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLMakePointerExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLMakePointerExpression.h >new file mode 100644 >index 00000000000..0da4be589dc >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLMakePointerExpression.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 "WHLSLExpression.h" >+#include "WHLSLLexer.h" >+#include <wtf/UniqueRef.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class MakePointerExpression : public Expression { >+public: >+ MakePointerExpression(Lexer::Token&& origin, UniqueRef<Expression>&& lValue) >+ : Expression(WTFMove(origin)) >+ , m_lValue(WTFMove(lValue)) >+ { >+ } >+ >+ virtual ~MakePointerExpression() = default; >+ >+ MakePointerExpression(const MakePointerExpression&) = delete; >+ MakePointerExpression(MakePointerExpression&&) = default; >+ >+ bool isMakePointerExpression() const override { return true; } >+ >+ Expression& lValue() { return static_cast<Expression&>(m_lValue); } >+ >+private: >+ UniqueRef<Expression> m_lValue; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_EXPRESSION(MakePointerExpression, isMakePointerExpression()) >+ >+#endif >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 >new file mode 100644 >index 00000000000..06d8e36223e >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNativeFunctionDeclaration.h >@@ -0,0 +1,67 @@ >+/* >+ * 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 "WHLSLFunctionDeclaration.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class NativeFunctionDeclaration : public FunctionDeclaration { >+public: >+ NativeFunctionDeclaration(FunctionDeclaration&& functionDeclaration, bool restricted) >+ : FunctionDeclaration(WTFMove(functionDeclaration)) >+ , m_restricted(restricted) >+ { >+ } >+ >+ virtual ~NativeFunctionDeclaration() = default; >+ >+ 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 >new file mode 100644 >index 00000000000..e7980b4f40f >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNativeTypeDeclaration.h >@@ -0,0 +1,117 @@ >+/* >+ * 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 "WHLSLNamedType.h" >+#include "WHLSLTypeArgument.h" >+#include <wtf/text/WTFString.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class NativeTypeDeclaration : public NamedType { >+public: >+ NativeTypeDeclaration(Lexer::Token&& origin, String&& name, TypeArguments&& typeArguments) >+ : NamedType(WTFMove(origin), WTFMove(name)) >+ , m_typeArguments(WTFMove(typeArguments)) >+ { >+ } >+ >+ virtual ~NativeTypeDeclaration() = default; >+ >+ 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; } >+ >+ 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: >+ 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 >new file mode 100644 >index 00000000000..c1790b5e1ea >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNode.h >@@ -0,0 +1,57 @@ >+/* >+ * 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 { >+ >+namespace AST { >+ >+class Node { >+public: >+ Node() = default; >+ >+ virtual ~Node() = default; >+ >+ explicit Node(const Node&) = default; >+ Node(Node&&) = default; >+ >+ Node& operator=(const Node&) = default; >+ Node& operator=(Node&&) = default; >+ >+private: >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h >new file mode 100644 >index 00000000000..050272fe661 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h >@@ -0,0 +1,79 @@ >+/* >+ * 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 "WHLSLExpression.h" >+#include "WHLSLLexer.h" >+#include "WHLSLNullLiteralType.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class NullLiteral : public Expression { >+public: >+ NullLiteral(Lexer::Token&& origin) >+ : Expression(WTFMove(origin)) >+ { >+ } >+ >+ virtual ~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 >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_EXPRESSION(NullLiteral, isNullLiteral()) >+ >+#endif >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 >new file mode 100644 >index 00000000000..8c88f2d7741 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNumThreadsFunctionAttribute.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 "WHLSLBaseFunctionAttribute.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class NumThreadsFunctionAttribute : public BaseFunctionAttribute { >+public: >+ NumThreadsFunctionAttribute(Lexer::Token&& origin, unsigned width, unsigned height, unsigned depth) >+ : BaseFunctionAttribute(WTFMove(origin)) >+ , m_width(width) >+ , m_height(height) >+ , m_depth(depth) >+ { >+ } >+ >+ virtual ~NumThreadsFunctionAttribute() = default; >+ >+ NumThreadsFunctionAttribute(const NumThreadsFunctionAttribute&) = delete; >+ NumThreadsFunctionAttribute(NumThreadsFunctionAttribute&&) = default; >+ >+ unsigned width() const { return m_width; } >+ unsigned height() const { return m_height; } >+ unsigned depth() const { return m_depth; } >+ >+private: >+ unsigned m_width; >+ unsigned m_height; >+ unsigned m_depth; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPointerType.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPointerType.h >new file mode 100644 >index 00000000000..05e3be6569a >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPointerType.h >@@ -0,0 +1,71 @@ >+/* >+ * 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 "WHLSLReferenceType.h" >+#include <wtf/UniqueRef.h> >+#include <wtf/text/WTFString.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class PointerType : public ReferenceType { >+public: >+ PointerType(Lexer::Token&& origin, AddressSpace addressSpace, UniqueRef<UnnamedType> elementType) >+ : ReferenceType(WTFMove(origin), addressSpace, WTFMove(elementType)) >+ { >+ } >+ >+ virtual ~PointerType() = default; >+ >+ PointerType(const PointerType&) = delete; >+ PointerType(PointerType&&) = default; >+ >+ bool isPointerType() const override { return true; } >+ >+ UniqueRef<UnnamedType> clone() const override >+ { >+ return makeUniqueRef<PointerType>(Lexer::Token(origin()), addressSpace(), elementType().clone()); >+ } >+ >+private: >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+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 >new file mode 100644 >index 00000000000..ef745c4fdfe >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPropertyAccessExpression.h >@@ -0,0 +1,93 @@ >+/* >+ * 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 "WHLSLExpression.h" >+#include "WHLSLLexer.h" >+#include <wtf/UniqueRef.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class PropertyAccessExpression : public Expression { >+public: >+ PropertyAccessExpression(Lexer::Token&& origin, UniqueRef<Expression>&& base) >+ : Expression(WTFMove(origin)) >+ , m_base(WTFMove(base)) >+ { >+ } >+ >+ virtual ~PropertyAccessExpression() = default; >+ >+ PropertyAccessExpression(const PropertyAccessExpression&) = delete; >+ PropertyAccessExpression(PropertyAccessExpression&&) = default; >+ >+ bool isPropertyAccessExpression() const override { return true; } >+ >+ 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: >+ 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 >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_EXPRESSION(PropertyAccessExpression, isPropertyAccessExpression()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLQualifier.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLQualifier.h >new file mode 100644 >index 00000000000..ff65cd0f93a >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLQualifier.h >@@ -0,0 +1,57 @@ >+/* >+ * 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 "WHLSLType.h" >+#include <wtf/Vector.h> >+#include <wtf/text/WTFString.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+enum class Qualifier : uint8_t { >+ Nointerpolation, >+ Noperspective, >+ Uniform, >+ Centroid, >+ Sample >+}; >+ >+using Qualifiers = Vector<Qualifier>; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReadModifyWriteExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReadModifyWriteExpression.h >new file mode 100644 >index 00000000000..147bdb7ef24 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReadModifyWriteExpression.h >@@ -0,0 +1,120 @@ >+/* >+ * 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 "WHLSLVariableDeclaration.h" >+#include "WHLSLExpression.h" >+#include "WHLSLLexer.h" >+#include "WHLSLVariableReference.h" >+#include <memory> >+#include <wtf/UniqueRef.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+/* >+ * 1. Evaluate m_lValue >+ * 2. Assign the result to m_oldValue >+ * 3. Evaluate m_newValueExpression >+ * 4. Assign the result to m_newValue >+ * 5. Assign the result to m_lValue >+ * 6. Evaluate m_resultExpression >+ * 7. Return the result >+ */ >+class ReadModifyWriteExpression : public Expression { >+public: >+ static UniqueRef<ReadModifyWriteExpression> create(Lexer::Token&& origin, UniqueRef<Expression> lValue) >+ { >+ return makeUniqueRef<ReadModifyWriteExpression>(WTFMove(origin), WTFMove(lValue)); >+ } >+ >+ virtual ~ReadModifyWriteExpression() = default; >+ >+ ReadModifyWriteExpression(const ReadModifyWriteExpression&) = delete; >+ ReadModifyWriteExpression(ReadModifyWriteExpression&&) = default; >+ >+ void setNewValueExpression(UniqueRef<Expression>&& newValueExpression) >+ { >+ m_newValueExpression = WTFMove(newValueExpression); >+ } >+ >+ void setResultExpression(UniqueRef<Expression>&& resultExpression) >+ { >+ m_resultExpression = WTFMove(resultExpression); >+ } >+ >+ 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 makeUniqueRef<VariableReference>(VariableReference::wrap(m_oldValue)); >+ } >+ >+ 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 makeUniqueRef<VariableReference>(VariableReference::wrap(m_newValue)); >+ } >+ >+ bool isReadModifyWriteExpression() const override { return true; } >+ >+ Expression& lValue() { return static_cast<Expression&>(m_lValue); } >+ VariableDeclaration& oldValue() { return m_oldValue; } >+ VariableDeclaration& newValue() { return m_newValue; } >+ Expression* newValueExpression() { return m_newValueExpression ? &static_cast<Expression&>(*m_newValueExpression) : nullptr; } >+ Expression* resultExpression() { return m_resultExpression ? &static_cast<Expression&>(*m_resultExpression) : nullptr; } >+ >+private: >+ 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(), WTF::nullopt, String(), WTF::nullopt, WTF::nullopt) >+ , m_newValue(WTFMove(origin), Qualifiers(), WTF::nullopt, String(), WTF::nullopt, WTF::nullopt) >+ { >+ } >+ >+ UniqueRef<Expression> m_lValue; >+ VariableDeclaration m_oldValue; >+ VariableDeclaration m_newValue; >+ Optional<UniqueRef<Expression>> m_newValueExpression; >+ Optional<UniqueRef<Expression>> m_resultExpression; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_EXPRESSION(ReadModifyWriteExpression, isReadModifyWriteExpression()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReferenceType.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReferenceType.h >new file mode 100644 >index 00000000000..f2ba1747c48 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReferenceType.h >@@ -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. >+ */ >+ >+#pragma once >+ >+#if ENABLE(WEBGPU) >+ >+#include "WHLSLLexer.h" >+#include "WHLSLUnnamedType.h" >+#include <wtf/UniqueRef.h> >+#include <wtf/text/WTFString.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class ReferenceType : public UnnamedType { >+public: >+ 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)) >+ { >+ } >+ >+ virtual ~ReferenceType() = default; >+ >+ ReferenceType(const ReferenceType&) = delete; >+ ReferenceType(ReferenceType&&) = default; >+ >+ 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: >+ 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..3a85c1f4b32 >--- /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; >+ >+ const UnnamedType* resolvedType() const { return m_resolvedType ? &static_cast<const UnnamedType&>(*m_resolvedType) : nullptr; } >+ UnnamedType* resolvedType() { return m_resolvedType ? &static_cast<UnnamedType&>(*m_resolvedType) : nullptr; } >+ >+ void resolve(UniqueRef<UnnamedType>&& type) >+ { >+ m_resolvedType = WTFMove(type); >+ } >+ >+private: >+ Optional<UniqueRef<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..cd69334bb5f >--- /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 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 >new file mode 100644 >index 00000000000..63c53468128 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.h >@@ -0,0 +1,90 @@ >+/* >+ * 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 "WHLSLBaseSemantic.h" >+#include "WHLSLLexer.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class ResourceSemantic : public BaseSemantic { >+public: >+ enum class Mode : uint8_t { >+ UnorderedAccessView, >+ Texture, >+ Buffer, >+ Sampler >+ }; >+ >+ ResourceSemantic(Lexer::Token&& origin, Mode mode, unsigned index, unsigned space) >+ : BaseSemantic(WTFMove(origin)) >+ , m_mode(mode) >+ , m_index(index) >+ , m_space(space) >+ { >+ } >+ >+ virtual ~ResourceSemantic() = default; >+ >+ ResourceSemantic(const ResourceSemantic&) = delete; >+ ResourceSemantic(ResourceSemantic&&) = default; >+ >+ Mode mode() const { return m_mode; } >+ 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 UnnamedType&, const Intrinsics&) const override; >+ bool isAcceptableForShaderItemDirection(ShaderItemDirection, const FunctionDefinition&) const override; >+ >+private: >+ Mode m_mode; >+ unsigned m_index; >+ unsigned m_space; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReturn.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReturn.h >new file mode 100644 >index 00000000000..7b60cf6a7d6 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReturn.h >@@ -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. >+ */ >+ >+#pragma once >+ >+#if ENABLE(WEBGPU) >+ >+#include "WHLSLExpression.h" >+#include "WHLSLLexer.h" >+#include "WHLSLStatement.h" >+#include <memory> >+#include <wtf/UniqueRef.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class Return : public Statement { >+public: >+ Return(Lexer::Token&& origin, Optional<UniqueRef<Expression>>&& value) >+ : Statement(WTFMove(origin)) >+ , m_value(WTFMove(value)) >+ { >+ } >+ >+ virtual ~Return() = default; >+ >+ Return(const Return&) = delete; >+ Return(Return&&) = default; >+ >+ bool isReturn() const override { return true; } >+ >+ Expression* value() { return m_value ? &static_cast<Expression&>(*m_value) : nullptr; } >+ >+ FunctionDefinition* function() { return m_function; } >+ void setFunction(FunctionDefinition* functionDefinition) { m_function = functionDefinition; } >+ >+private: >+ Optional<UniqueRef<Expression>> m_value; >+ FunctionDefinition* m_function; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_STATEMENT(Return, isReturn()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSemantic.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSemantic.h >new file mode 100644 >index 00000000000..60564c916a5 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSemantic.h >@@ -0,0 +1,50 @@ >+/* >+ * 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 "WHLSLBuiltInSemantic.h" >+#include "WHLSLResourceSemantic.h" >+#include "WHLSLSpecializationConstantSemantic.h" >+#include "WHLSLStageInOutSemantic.h" >+#include <wtf/Variant.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+using Semantic = Variant<BuiltInSemantic, ResourceSemantic, SpecializationConstantSemantic, StageInOutSemantic>; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >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..f73e4843af1 >--- /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 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 >new file mode 100644 >index 00000000000..9a7f8bc0854 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSpecializationConstantSemantic.h >@@ -0,0 +1,73 @@ >+/* >+ * 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 "WHLSLBaseSemantic.h" >+#include "WHLSLLexer.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class SpecializationConstantSemantic : public BaseSemantic { >+public: >+ SpecializationConstantSemantic(Lexer::Token&& origin) >+ : BaseSemantic(WTFMove(origin)) >+ { >+ } >+ >+ virtual ~SpecializationConstantSemantic() = default; >+ >+ SpecializationConstantSemantic(const SpecializationConstantSemantic&) = delete; >+ SpecializationConstantSemantic(SpecializationConstantSemantic&&) = default; >+ >+ bool operator==(const SpecializationConstantSemantic&) const >+ { >+ return true; >+ } >+ >+ bool operator!=(const SpecializationConstantSemantic&) const >+ { >+ return false; >+ } >+ >+ bool isAcceptableType(const UnnamedType&, const Intrinsics&) const override; >+ bool isAcceptableForShaderItemDirection(ShaderItemDirection, const FunctionDefinition&) const override; >+ >+private: >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >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..309aefabc28 >--- /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 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 >new file mode 100644 >index 00000000000..e057cfb3c9d >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStageInOutSemantic.h >@@ -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. >+ */ >+ >+#pragma once >+ >+#if ENABLE(WEBGPU) >+ >+#include "WHLSLBaseSemantic.h" >+#include "WHLSLLexer.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class StageInOutSemantic : public BaseSemantic { >+public: >+ StageInOutSemantic(Lexer::Token&& origin, unsigned index) >+ : BaseSemantic(WTFMove(origin)) >+ , m_index(index) >+ { >+ } >+ >+ virtual ~StageInOutSemantic() = default; >+ >+ StageInOutSemantic(const StageInOutSemantic&) = delete; >+ StageInOutSemantic(StageInOutSemantic&&) = default; >+ >+ 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 UnnamedType&, const Intrinsics&) const override; >+ bool isAcceptableForShaderItemDirection(ShaderItemDirection, const FunctionDefinition&) const override; >+ >+private: >+ unsigned m_index; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStatement.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStatement.h >new file mode 100644 >index 00000000000..c5e65918d28 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStatement.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 "WHLSLValue.h" >+#include <wtf/UniqueRef.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class Statement : public Value { >+public: >+ Statement(Lexer::Token&& origin) >+ : m_origin(WTFMove(origin)) >+ { >+ } >+ >+ virtual ~Statement() = default; >+ >+ Statement(const Statement&) = delete; >+ Statement(Statement&&) = default; >+ >+ virtual bool isBlock() const { return false; } >+ virtual bool isBreak() const { return false; } >+ virtual bool isContinue() const { return false; } >+ virtual bool isDoWhileLoop() const { return false; } >+ virtual bool isEffectfulExpressionStatement() const { return false; } >+ virtual bool isFallthrough() const { return false; } >+ virtual bool isForLoop() const { return false; } >+ virtual bool isIfStatement() const { return false; } >+ virtual bool isReturn() const { return false; } >+ virtual bool isSwitchCase() const { return false; } >+ virtual bool isSwitchStatement() const { return false; } >+ virtual bool isTrap() const { return false; } >+ virtual bool isVariableDeclarationsStatement() const { return false; } >+ virtual bool isWhileLoop() const { return false; } >+ >+private: >+ Lexer::Token m_origin; >+}; >+ >+using Statements = Vector<UniqueRef<Statement>>; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#define SPECIALIZE_TYPE_TRAITS_WHLSL_STATEMENT(ToValueTypeName, predicate) \ >+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::WHLSL::AST::ToValueTypeName) \ >+ static bool isType(const WebCore::WHLSL::AST::Statement& statement) { return statement.predicate; } \ >+SPECIALIZE_TYPE_TRAITS_END() >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStructureDefinition.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStructureDefinition.h >new file mode 100644 >index 00000000000..6bb1487a600 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStructureDefinition.h >@@ -0,0 +1,71 @@ >+/* >+ * 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 "WHLSLStructureElement.h" >+#include "WHLSLNamedType.h" >+#include <wtf/Vector.h> >+#include <wtf/text/WTFString.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class StructureDefinition : public NamedType { >+public: >+ StructureDefinition(Lexer::Token&& origin, String&& name, StructureElements&& structureElements) >+ : NamedType(WTFMove(origin), WTFMove(name)) >+ , m_structureElements(WTFMove(structureElements)) >+ { >+ } >+ >+ virtual ~StructureDefinition() = default; >+ >+ StructureDefinition(const StructureDefinition&) = delete; >+ StructureDefinition(StructureDefinition&&) = default; >+ >+ bool isStructureDefinition() const override { return true; } >+ >+ StructureElements& structureElements() { return m_structureElements; } >+ >+private: >+ 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 >new file mode 100644 >index 00000000000..e4a76463ce9 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStructureElement.h >@@ -0,0 +1,80 @@ >+/* >+ * 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 "WHLSLQualifier.h" >+#include "WHLSLSemantic.h" >+#include "WHLSLType.h" >+#include <wtf/UniqueRef.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class StructureElement : public Node { >+public: >+ 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)) >+ , m_name(WTFMove(name)) >+ , m_semantic(WTFMove(semantic)) >+ { >+ } >+ >+ virtual ~StructureElement() = default; >+ >+ StructureElement(const StructureElement&) = delete; >+ StructureElement(StructureElement&&) = default; >+ >+ 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; >+ UniqueRef<UnnamedType> m_type; >+ String m_name; >+ Optional<Semantic> m_semantic; >+}; >+ >+using StructureElements = Vector<StructureElement>; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSwitchCase.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSwitchCase.h >new file mode 100644 >index 00000000000..15f09c26698 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSwitchCase.h >@@ -0,0 +1,74 @@ >+/* >+ * 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 "WHLSLBlock.h" >+#include "WHLSLConstantExpression.h" >+#include "WHLSLLexer.h" >+#include "WHLSLStatement.h" >+#include <wtf/Optional.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class SwitchCase : public Statement { >+public: >+ SwitchCase(Lexer::Token&& origin, Optional<ConstantExpression>&& value, Block&& block) >+ : Statement(WTFMove(origin)) >+ , m_value(WTFMove(value)) >+ , m_block(WTFMove(block)) >+ { >+ } >+ >+ virtual ~SwitchCase() = default; >+ >+ SwitchCase(const SwitchCase&) = delete; >+ SwitchCase(SwitchCase&&) = default; >+ >+ bool isSwitchCase() const override { return true; } >+ >+ Optional<ConstantExpression>& value() { return m_value; } >+ Block& block() { return m_block; } >+ >+private: >+ Optional<ConstantExpression> m_value; >+ Block m_block; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_STATEMENT(SwitchCase, isSwitchCase()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSwitchStatement.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSwitchStatement.h >new file mode 100644 >index 00000000000..d9af69d7732 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSwitchStatement.h >@@ -0,0 +1,74 @@ >+/* >+ * 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 "WHLSLExpression.h" >+#include "WHLSLLexer.h" >+#include "WHLSLStatement.h" >+#include "WHLSLSwitchCase.h" >+#include <wtf/UniqueRef.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class SwitchStatement : public Statement { >+public: >+ SwitchStatement(Lexer::Token&& origin, UniqueRef<Expression>&& value, Vector<SwitchCase>&& switchCases) >+ : Statement(WTFMove(origin)) >+ , m_value(WTFMove(value)) >+ , m_switchCases(WTFMove(switchCases)) >+ { >+ } >+ >+ virtual ~SwitchStatement() = default; >+ >+ SwitchStatement(const SwitchStatement&) = delete; >+ SwitchStatement(SwitchStatement&&) = default; >+ >+ bool isSwitchStatement() const override { return true; } >+ >+ Expression& value() { return static_cast<Expression&>(m_value); } >+ Vector<SwitchCase>& switchCases() { return m_switchCases; } >+ >+private: >+ UniqueRef<Expression> m_value; >+ Vector<SwitchCase> m_switchCases; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_STATEMENT(SwitchStatement, isSwitchStatement()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTernaryExpression.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTernaryExpression.h >new file mode 100644 >index 00000000000..5d862ee4e5c >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTernaryExpression.h >@@ -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. >+ */ >+ >+#pragma once >+ >+#if ENABLE(WEBGPU) >+ >+#include "WHLSLExpression.h" >+#include "WHLSLLexer.h" >+#include <wtf/UniqueRef.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class TernaryExpression : public Expression { >+public: >+ TernaryExpression(Lexer::Token&& origin, UniqueRef<Expression>&& predicate, UniqueRef<Expression>&& bodyExpression, UniqueRef<Expression>&& elseExpression) >+ : Expression(WTFMove(origin)) >+ , m_predicate(WTFMove(predicate)) >+ , m_bodyExpression(WTFMove(bodyExpression)) >+ , m_elseExpression(WTFMove(elseExpression)) >+ { >+ } >+ >+ virtual ~TernaryExpression() = default; >+ >+ TernaryExpression(const TernaryExpression&) = delete; >+ TernaryExpression(TernaryExpression&&) = default; >+ >+ bool isTernaryExpression() const override { return true; } >+ >+ 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: >+ UniqueRef<Expression> m_predicate; >+ UniqueRef<Expression> m_bodyExpression; >+ UniqueRef<Expression> m_elseExpression; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_EXPRESSION(TernaryExpression, isTernaryExpression()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTrap.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTrap.h >new file mode 100644 >index 00000000000..0a93b368f0b >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTrap.h >@@ -0,0 +1,64 @@ >+/* >+ * 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 "WHLSLStatement.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class Trap : public Statement { >+public: >+ Trap(Lexer::Token&& origin) >+ : Statement(WTFMove(origin)) >+ { >+ } >+ >+ virtual ~Trap() = default; >+ >+ Trap(const Trap&) = delete; >+ Trap(Trap&&) = default; >+ >+ bool isTrap() const override { return true; } >+ >+private: >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_STATEMENT(Trap, isTrap()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLType.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLType.h >new file mode 100644 >index 00000000000..db92ff5428b >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLType.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 "WHLSLNode.h" >+#include <wtf/TypeCasts.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class Type : public Node { >+public: >+ Type() = default; >+ >+ virtual ~Type() = default; >+ >+ explicit Type(const Type&) = delete; >+ Type(Type&&) = default; >+ >+ Type& operator=(const Type&) = delete; >+ Type& operator=(Type&&) = default; >+ >+ virtual bool isNamedType() const { return false; } >+ virtual bool isUnnamedType() const { return false; } >+ virtual bool isResolvableType() const { return false; } >+ >+private: >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#define SPECIALIZE_TYPE_TRAITS_WHLSL_TYPE(ToValueTypeName, predicate) \ >+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::WHLSL::AST::ToValueTypeName) \ >+ static bool isType(const WebCore::WHLSL::AST::Type& type) { return type.predicate; } \ >+SPECIALIZE_TYPE_TRAITS_END() >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeArgument.cpp b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeArgument.cpp >new file mode 100644 >index 00000000000..8735065a1bb >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeArgument.cpp >@@ -0,0 +1,65 @@ >+/* >+ * 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 "WHLSLTypeArgument.h" >+ >+#include "WHLSLConstantExpression.h" >+#include "WHLSLTypeReference.h" >+#include <wtf/UniqueRef.h> >+#include <wtf/Variant.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+TypeArguments clone(const TypeArguments& typeArguments) >+{ >+ TypeArguments result; >+ for (const auto& typeArgument : typeArguments) >+ result.append(clone(typeArgument)); >+ return result; >+} >+ >+TypeArgument clone(const TypeArgument& typeArgument) >+{ >+ return WTF::visit(WTF::makeVisitor([](const ConstantExpression& constantExpression) -> TypeArgument { >+ return constantExpression.clone(); >+ }, [](const UniqueRef<TypeReference>& typeReference) -> TypeArgument { >+ return typeReference->cloneTypeReference(); >+ }), typeArgument); >+} >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeArgument.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeArgument.h >new file mode 100644 >index 00000000000..67383aa1dbb >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeArgument.h >@@ -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. >+ */ >+ >+#pragma once >+ >+#if ENABLE(WEBGPU) >+ >+#include "WHLSLConstantExpression.h" >+#include "WHLSLLexer.h" >+#include <wtf/UniqueRef.h> >+#include <wtf/Variant.h> >+#include <wtf/Vector.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class TypeReference; >+ >+using TypeArgument = Variant<ConstantExpression, UniqueRef<TypeReference>>; >+using TypeArguments = Vector<TypeArgument>; >+ >+TypeArgument clone(const TypeArgument&); >+TypeArguments clone(const TypeArguments&); >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeDefinition.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeDefinition.h >new file mode 100644 >index 00000000000..6c99a925811 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeDefinition.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 "WHLSLLexer.h" >+#include "WHLSLNode.h" >+#include "WHLSLNamedType.h" >+#include "WHLSLUnnamedType.h" >+#include <wtf/UniqueRef.h> >+#include <wtf/text/WTFString.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class TypeDefinition : public NamedType { >+public: >+ TypeDefinition(Lexer::Token&& origin, String&& name, UniqueRef<UnnamedType>&& type) >+ : NamedType(WTFMove(origin), WTFMove(name)) >+ , m_type(WTFMove(type)) >+ { >+ } >+ >+ virtual ~TypeDefinition() = default; >+ >+ TypeDefinition(const TypeDefinition&) = delete; >+ TypeDefinition(TypeDefinition&&) = default; >+ >+ bool isTypeDefinition() const override { return true; } >+ >+ UnnamedType& type() { return static_cast<UnnamedType&>(m_type); } >+ >+ const Type& unifyNode() const override >+ { >+ return m_type->unifyNode(); >+ } >+ >+ Type& unifyNode() override >+ { >+ return m_type->unifyNode(); >+ } >+ >+private: >+ UniqueRef<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 >new file mode 100644 >index 00000000000..b8e4bf850b4 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeReference.h >@@ -0,0 +1,107 @@ >+/* >+ * 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 "WHLSLTypeArgument.h" >+#include "WHLSLUnnamedType.h" >+#include <wtf/UniqueRef.h> >+#include <wtf/text/WTFString.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class NamedType; >+ >+class TypeReference : public UnnamedType { >+public: >+ TypeReference(Lexer::Token&& origin, String&& name, TypeArguments&& typeArguments) >+ : UnnamedType(WTFMove(origin)) >+ , m_name(WTFMove(name)) >+ , m_typeArguments(WTFMove(typeArguments)) >+ { >+ } >+ >+ virtual ~TypeReference() = default; >+ >+ 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; } >+ >+ const Type& unifyNode() const override >+ { >+ ASSERT(m_resolvedType); >+ return m_resolvedType->unifyNode(); >+ } >+ >+ 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: >+ String m_name; >+ TypeArguments m_typeArguments; >+ NamedType* m_resolvedType { nullptr }; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+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 >new file mode 100644 >index 00000000000..b64c9868e3c >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.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 "WHLSLExpression.h" >+#include "WHLSLLexer.h" >+#include "WHLSLUnsignedIntegerLiteralType.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class UnsignedIntegerLiteral : public Expression { >+public: >+ UnsignedIntegerLiteral(Lexer::Token&& origin, unsigned value) >+ : Expression(Lexer::Token(origin)) >+ , m_type(WTFMove(origin), value) >+ , m_value(value) >+ { >+ } >+ >+ virtual ~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 >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_EXPRESSION(UnsignedIntegerLiteral, isUnsignedIntegerLiteral()) >+ >+#endif >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..58a7c9a87ce >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteralType.cpp >@@ -0,0 +1,78 @@ >+/* >+ * 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" >+#include <wtf/UniqueRef.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+UnsignedIntegerLiteralType::UnsignedIntegerLiteralType(Lexer::Token&& origin, unsigned value) >+ : m_value(value) >+ , m_preferredType(makeUniqueRef<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, static_cast<const TypeReference&>(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 >new file mode 100644 >index 00000000000..b912d0e4852 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLValue.h >@@ -0,0 +1,61 @@ >+/* >+ * 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 "WHLSLNode.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class Value : public Node { >+public: >+ Value() >+ { >+ } >+ >+ virtual ~Value() = default; >+ >+ explicit Value(const Value&) = default; >+ Value(Value&&) = default; >+ >+ Value& operator=(const Value&) = default; >+ Value& operator=(Value&&) = default; >+ >+private: >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclaration.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclaration.h >new file mode 100644 >index 00000000000..5570745b30d >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclaration.h >@@ -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. >+ */ >+ >+#pragma once >+ >+#if ENABLE(WEBGPU) >+ >+#include "WHLSLExpression.h" >+#include "WHLSLLexer.h" >+#include "WHLSLQualifier.h" >+#include "WHLSLSemantic.h" >+#include "WHLSLType.h" >+#include "WHLSLValue.h" >+#include <memory> >+#include <wtf/UniqueRef.h> >+#include <wtf/Vector.h> >+#include <wtf/text/WTFString.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class VariableDeclaration : public Value { >+public: >+ VariableDeclaration(Lexer::Token&& origin, Qualifiers&& qualifiers, Optional<UniqueRef<UnnamedType>>&& type, String&& name, Optional<Semantic>&& semantic, Optional<UniqueRef<Expression>>&& initializer) >+ : m_origin(WTFMove(origin)) >+ , m_qualifiers(WTFMove(qualifiers)) >+ , m_type(WTFMove(type)) >+ , m_name(WTFMove(name)) >+ , m_semantic(WTFMove(semantic)) >+ , m_initializer(WTFMove(initializer)) >+ { >+ } >+ >+ virtual ~VariableDeclaration() = default; >+ >+ VariableDeclaration(const VariableDeclaration&) = delete; >+ VariableDeclaration(VariableDeclaration&&) = default; >+ >+ const Lexer::Token& origin() const { return m_origin; } >+ String& name() { return m_name; } >+ >+ const Optional<UniqueRef<UnnamedType>>& type() const { return m_type; } // Anonymous variables inside ReadModifyWriteExpressions have their type set by the type checker. >+ UnnamedType* type() { return m_type ? &static_cast<UnnamedType&>(*m_type) : nullptr; } >+ Optional<Semantic>& semantic() { return m_semantic; } >+ Expression* initializer() { return m_initializer ? &static_cast<Expression&>(*m_initializer) : nullptr; } >+ >+private: >+ Lexer::Token m_origin; >+ Qualifiers m_qualifiers; >+ Optional<UniqueRef<UnnamedType>> m_type; >+ String m_name; >+ Optional<Semantic> m_semantic; >+ Optional<UniqueRef<Expression>> m_initializer; >+}; >+ >+using VariableDeclarations = Vector<VariableDeclaration>; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclarationsStatement.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclarationsStatement.h >new file mode 100644 >index 00000000000..5544b18363c >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclarationsStatement.h >@@ -0,0 +1,70 @@ >+/* >+ * 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 "WHLSLStatement.h" >+#include "WHLSLVariableDeclaration.h" >+#include <wtf/Vector.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class VariableDeclarationsStatement : public Statement { >+public: >+ VariableDeclarationsStatement(Lexer::Token&& origin, Vector<VariableDeclaration>&& variableDeclarations) >+ : Statement(WTFMove(origin)) >+ , m_variableDeclarations(WTFMove(variableDeclarations)) >+ { >+ } >+ >+ virtual ~VariableDeclarationsStatement() = default; >+ >+ VariableDeclarationsStatement(const VariableDeclarationsStatement&) = delete; >+ VariableDeclarationsStatement(VariableDeclarationsStatement&&) = default; >+ >+ bool isVariableDeclarationsStatement() const override { return true; } >+ >+ Vector<VariableDeclaration>& variableDeclarations() { return m_variableDeclarations; } >+ >+private: >+ Vector<VariableDeclaration> m_variableDeclarations; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_STATEMENT(VariableDeclarationsStatement, isVariableDeclarationsStatement()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableReference.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableReference.h >new file mode 100644 >index 00000000000..ef4fb55d19d >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableReference.h >@@ -0,0 +1,91 @@ >+/* >+ * 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 "WHLSLVariableDeclaration.h" >+#include "WHLSLExpression.h" >+#include "WHLSLLexer.h" >+#include "WHLSLVariableDeclaration.h" >+#include <wtf/text/WTFString.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class VariableReference : public Expression { >+public: >+ VariableReference(Lexer::Token&& origin, String&& name) >+ : Expression(WTFMove(origin)) >+ , m_name(WTFMove(name)) >+ { >+ } >+ >+ virtual ~VariableReference() = default; >+ >+ VariableReference(const VariableReference&) = delete; >+ VariableReference(VariableReference&&) = default; >+ >+ static VariableReference wrap(VariableDeclaration& variableDeclaration) >+ { >+ VariableReference result(Lexer::Token(variableDeclaration.origin())); >+ result.m_variable = &variableDeclaration; >+ return result; >+ } >+ >+ bool isVariableReference() const override { return true; } >+ >+ String& name() { return m_name; } >+ >+ VariableDeclaration* variable() { return m_variable; } >+ >+ void setVariable(VariableDeclaration& variableDeclaration) >+ { >+ m_variable = &variableDeclaration; >+ } >+ >+private: >+ VariableReference(Lexer::Token&& origin) >+ : Expression(WTFMove(origin)) >+ { >+ } >+ >+ String m_name; >+ VariableDeclaration* m_variable; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_EXPRESSION(VariableReference, isVariableReference()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLWhileLoop.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLWhileLoop.h >new file mode 100644 >index 00000000000..aec64caac30 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLWhileLoop.h >@@ -0,0 +1,73 @@ >+/* >+ * 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 "WHLSLExpression.h" >+#include "WHLSLLexer.h" >+#include "WHLSLStatement.h" >+#include <wtf/UniqueRef.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class WhileLoop : public Statement { >+public: >+ WhileLoop(Lexer::Token&& origin, UniqueRef<Expression>&& conditional, UniqueRef<Statement>&& body) >+ : Statement(WTFMove(origin)) >+ , m_conditional(WTFMove(conditional)) >+ , m_body(WTFMove(body)) >+ { >+ } >+ >+ virtual ~WhileLoop() = default; >+ >+ WhileLoop(const WhileLoop&) = delete; >+ WhileLoop(WhileLoop&&) = default; >+ >+ bool isWhileLoop() const override { return true; } >+ >+ Expression& conditional() { return static_cast<Expression&>(m_conditional); } >+ Statement& body() { return static_cast<Statement&>(m_body); } >+ >+private: >+ UniqueRef<Expression> m_conditional; >+ UniqueRef<Statement> m_body; >+}; >+ >+} // namespace AST >+ >+} >+ >+} >+ >+SPECIALIZE_TYPE_TRAITS_WHLSL_STATEMENT(WhileLoop, isWhileLoop()) >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.cpp >new file mode 100644 >index 00000000000..47c26f50890 >--- /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<const AST::FunctionDeclaration>> functions; >+ for (auto& functionDefinition : program.functionDefinitions()) >+ functions.append(static_cast<const AST::FunctionDefinition&>(functionDefinition)); >+ for (auto& nativeFunctionDeclaration : program.nativeFunctionDeclarations()) >+ functions.append(static_cast<const AST::NativeFunctionDeclaration&>(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>(static_cast<const AST::UnnamedType&>(*functions[i].get().parameters()[0].type()))) { >+ auto& type = static_cast<const AST::UnnamedType&>(*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>(static_cast<const AST::UnnamedType&>(*functions[i].get().parameters()[0].type())) >+ || is<AST::ArrayType>(static_cast<const AST::UnnamedType&>(*functions[i].get().parameters()[0].type())))) >+ return false; >+ else if (functions[i].get().name() == "operator==" >+ && functions[i].get().parameters().size() == 2 >+ && is<AST::ReferenceType>(static_cast<const AST::UnnamedType&>(*functions[i].get().parameters()[0].type())) >+ && is<AST::ReferenceType>(static_cast<const AST::UnnamedType&>(*functions[i].get().parameters()[1].type())) >+ && matches(static_cast<const AST::UnnamedType&>(*functions[i].get().parameters()[0].type()), static_cast<const AST::UnnamedType&>(*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..80a0dc3983e >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp >@@ -0,0 +1,1493 @@ >+/* >+ * 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() }, String(), WTF::nullopt, WTF::nullopt)); >+ parameters.append(AST::VariableDeclaration(Lexer::Token(callExpression.origin()), AST::Qualifiers(), { AST::TypeReference::wrap(Lexer::Token(callExpression.origin()), intrinsics.uintType()) }, String(), WTF::nullopt, WTF::nullopt)); >+ 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() }, String(), WTF::nullopt, WTF::nullopt)); >+ 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() }, String(), WTF::nullopt, WTF::nullopt)); >+ parameters.append(AST::VariableDeclaration(Lexer::Token(callExpression.origin()), AST::Qualifiers(), { WTFMove(argumentType) }, String(), WTF::nullopt, WTF::nullopt)); >+ 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(static_cast<AST::TypeDefinition&>(typeDefinition)); >+ for (auto& structureDefinition : program.structureDefinitions()) >+ checkErrorAndVisit(static_cast<AST::StructureDefinition&>(structureDefinition)); >+ for (auto& enumerationDefinition : program.enumerationDefinitions()) >+ checkErrorAndVisit(static_cast<AST::EnumerationDefinition&>(enumerationDefinition)); >+ for (auto& nativeTypeDeclaration : program.nativeTypeDeclarations()) >+ checkErrorAndVisit(static_cast<AST::NativeTypeDeclaration&>(nativeTypeDeclaration)); >+ >+ for (auto& functionDefinition : program.functionDefinitions()) >+ checkErrorAndVisit(static_cast<AST::FunctionDefinition&>(functionDefinition)); >+ for (auto& nativeFunctionDeclaration : program.nativeFunctionDeclarations()) >+ checkErrorAndVisit(static_cast<AST::NativeFunctionDeclaration&>(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 { >+ 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()[0].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 >+ { >+ if (!enumerationDefinition.type()) { >+ // FIXME: Handle a null base type. >+ setError(); >+ return; >+ } >+ checkErrorAndVisit(static_cast<AST::UnnamedType&>(*enumerationDefinition.type())); >+ >+ auto& baseType = static_cast<AST::UnnamedType&>(*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([&](UniqueRef<AST::UnnamedType>& unnamedType) -> bool { >+ return matches(static_cast<AST::UnnamedType&>(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) -> Optional<UniqueRef<AST::UnnamedType>> { >+ return WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& right) -> Optional<UniqueRef<AST::UnnamedType>> { >+ if (matches(static_cast<AST::UnnamedType&>(left), static_cast<AST::UnnamedType&>(right))) >+ return left->clone(); >+ return WTF::nullopt; >+ }, [&](Ref<ResolvableTypeReference>& right) -> Optional<UniqueRef<AST::UnnamedType>> { >+ return matchAndCommit(static_cast<AST::UnnamedType&>(left), right->resolvableType()); >+ }), rhsType); >+ }, [&](Ref<ResolvableTypeReference>& left) -> Optional<UniqueRef<AST::UnnamedType>> { >+ return WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& right) -> Optional<UniqueRef<AST::UnnamedType>> { >+ return matchAndCommit(static_cast<AST::UnnamedType&>(right), left->resolvableType()); >+ }, [&](Ref<ResolvableTypeReference>& right) -> Optional<UniqueRef<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. >+ ASSERT(readModifyWriteExpression.newValueExpression()); >+ 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; >+ } >+ ASSERT(readModifyWriteExpression.resultExpression()); >+ 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, ResolvingType(makeUniqueRef<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, ResolvingType(makeUniqueRef<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, ResolvingType(makeUniqueRef<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, ResolvingType(makeUniqueRef<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(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(*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(setArgument1Type); >+ setArgumentTypes.append(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, ResolvingType(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, ResolvingType(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, ResolvingType(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, ResolvingType(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(static_cast<AST::Statement&>(*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); >+ }, [&](UniqueRef<AST::Expression>& expression) { >+ checkErrorAndVisit(static_cast<AST::Expression&>(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<AST::Expression&>(commaExpression.list().last())); >+ ASSERT(lastIterator != m_typeMap.end()); >+ auto& lastType = lastIterator->value; >+ WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& lastType) { >+ auto addResult = m_typeMap.add(&commaExpression, ResolvingType(lastType->clone())); >+ ASSERT_UNUSED(addResult, addResult.isNewEntry); >+ }, [&](Ref<ResolvableTypeReference>& lastType) { >+ auto addResult = m_typeMap.add(&commaExpression, ResolvingType(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) -> Optional<UniqueRef<AST::UnnamedType>> { >+ if (matches(static_cast<AST::UnnamedType&>(bodyType), static_cast<AST::UnnamedType&>(elseType))) >+ return bodyType->clone(); >+ return WTF::nullopt; >+ }, [&](Ref<ResolvableTypeReference>& elseType) -> Optional<UniqueRef<AST::UnnamedType>> { >+ return matchAndCommit(static_cast<AST::UnnamedType&>(bodyType), elseType->resolvableType()); >+ }), elseType); >+ }, [&](Ref<ResolvableTypeReference>& bodyType) -> Optional<UniqueRef<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) -> Optional<UniqueRef<AST::UnnamedType>> { >+ return matchAndCommit(bodyType->resolvableType(), elseType->resolvableType()); >+ }), elseType); >+ }), bodyType); >+ if (!resultType) { >+ setError(); >+ return; >+ } >+ auto addResult = m_typeMap.add(&ternaryExpression, ResolvingType(WTFMove(*resultType))); >+ ASSERT_UNUSED(addResult, addResult.isNewEntry); >+ } >+ >+ void visit(AST::CallExpression& callExpression) override >+ { >+ for (auto& argument : callExpression.arguments()) >+ checkErrorAndVisit(static_cast<AST::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<AST::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 = &static_cast<AST::NativeFunctionDeclaration&>(m_program.nativeFunctionDeclarations().last()); >+ } >+ } >+ >+ 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, ResolvingType(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..ee418d70285 >--- /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) >+ { >+ 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(); >+ if (variableDeclaration.type()) >+ 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/WHLSLGatherEntryPointItems.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLGatherEntryPointItems.h >new file mode 100644 >index 00000000000..e1eb82921a0 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLGatherEntryPointItems.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 "WHLSLSemantic.h" >+#include <wtf/Optional.h> >+#include <wtf/Vector.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+class FunctionDefinition; >+ >+} >+ >+class Intrinsics; >+class UnnamedType; >+ >+struct EntryPointItem { >+ EntryPointItem(AST::UnnamedType& unnamedType, AST::Semantic& semantic) >+ : unnamedType(unnamedType) >+ , semantic(semantic) >+ { >+ } >+ >+ AST::UnnamedType& unnamedType; >+ AST::Semantic& semantic; >+}; >+ >+struct EntryPointItems { >+ Vector<EntryPointItem> inputs; >+ Vector<EntryPointItem> outputs; >+}; >+ >+Optional<EntryPointItems> gatherEntryPointItems(const Intrinsics&, AST::FunctionDefinition&); >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLInferTypes.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLInferTypes.cpp >new file mode 100644 >index 00000000000..e7d202e33cc >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLInferTypes.cpp >@@ -0,0 +1,241 @@ >+/* >+ * 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 Optional<UniqueRef<AST::UnnamedType>> matchAndCommit(AST::Type& unifyNode, AST::ResolvableType& resolvableType) >+{ >+ ASSERT(!resolvableType.resolvedType()); >+ if (!resolvableType.canResolve(unifyNode)) >+ return WTF::nullopt; >+ if (is<AST::NamedType>(unifyNode)) { >+ auto& namedUnifyNode = downcast<AST::NamedType>(unifyNode); >+ auto result = AST::TypeReference::wrap(Lexer::Token(namedUnifyNode.origin()), namedUnifyNode); >+ resolvableType.resolve(result->clone()); >+ return { WTFMove(result) }; >+ } >+ >+ auto result = downcast<AST::UnnamedType>(unifyNode).clone(); >+ resolvableType.resolve(result->clone()); >+ return result; >+} >+ >+Optional<UniqueRef<AST::UnnamedType>> matchAndCommit(AST::UnnamedType& unnamedType, AST::ResolvableType& resolvableType) >+{ >+ return matchAndCommit(unnamedType.unifyNode(), resolvableType); >+} >+ >+Optional<UniqueRef<AST::UnnamedType>> matchAndCommit(AST::NamedType& namedType, AST::ResolvableType& resolvableType) >+{ >+ return matchAndCommit(namedType.unifyNode(), resolvableType); >+} >+ >+Optional<UniqueRef<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(); >+ } >+ 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(); >+ } >+ 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(); >+ } >+ if (is<AST::NullLiteralType>(resolvableType1) && is<AST::NullLiteralType>(resolvableType2)) { >+ // FIXME: Trying to match nullptr and nullptr fails. >+ return WTF::nullopt; >+ } >+ return WTF::nullopt; >+} >+ >+Optional<UniqueRef<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(); >+ } >+ if (is<AST::IntegerLiteralType>(resolvableType)) { >+ resolvableType.resolve(downcast<AST::IntegerLiteralType>(resolvableType).preferredType().clone()); >+ return downcast<AST::IntegerLiteralType>(resolvableType).preferredType().clone(); >+ } >+ if (is<AST::UnsignedIntegerLiteralType>(resolvableType)) { >+ resolvableType.resolve(downcast<AST::UnsignedIntegerLiteralType>(resolvableType).preferredType().clone()); >+ return downcast<AST::UnsignedIntegerLiteralType>(resolvableType).preferredType().clone(); >+ } >+ if (is<AST::NullLiteralType>(resolvableType)) { >+ // FIXME: Trying to match nullptr and nullptr fails. >+ return WTF::nullopt; >+ } >+ return WTF::nullopt; >+} >+ >+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; >+ }, [&](UniqueRef<AST::TypeReference>& theTypeReference) { >+ typeReference = &static_cast<AST::TypeReference&>(theTypeReference); >+ }), 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..2284164ccb3 >--- /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? >+Optional<UniqueRef<AST::UnnamedType>> matchAndCommit(AST::UnnamedType&, AST::ResolvableType&); >+Optional<UniqueRef<AST::UnnamedType>> matchAndCommit(AST::NamedType&, AST::ResolvableType&); >+Optional<UniqueRef<AST::UnnamedType>> matchAndCommit(AST::ResolvableType&, AST::ResolvableType&); >+Optional<UniqueRef<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 >new file mode 100644 >index 00000000000..e4e0e2a5db8 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.cpp >@@ -0,0 +1,281 @@ >+/* >+ * 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 "WHLSLNameResolver.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 { >+ >+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(static_cast<AST::Statement&>(*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 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(static_cast<AST::TypeDefinition&>(typeDefinition)); >+ if (nameResolver.error()) >+ return false; >+ } >+ for (auto& structureDefinition : program.structureDefinitions()) { >+ nameResolver.checkErrorAndVisit(static_cast<AST::StructureDefinition&>(structureDefinition)); >+ if (nameResolver.error()) >+ return false; >+ } >+ for (auto& enumerationDefinition : program.enumerationDefinitions()) { >+ nameResolver.checkErrorAndVisit(static_cast<AST::EnumerationDefinition&>(enumerationDefinition)); >+ if (nameResolver.error()) >+ return false; >+ } >+ for (auto& nativeTypeDeclaration : program.nativeTypeDeclarations()) { >+ nameResolver.checkErrorAndVisit(static_cast<AST::NativeTypeDeclaration&>(nativeTypeDeclaration)); >+ if (nameResolver.error()) >+ return false; >+ } >+ return true; >+} >+ >+bool resolveNamesInFunctions(Program& program, NameResolver& nameResolver) >+{ >+ for (auto& functionDefinition : program.functionDefinitions()) { >+ nameResolver.setCurrentFunctionDefinition(&static_cast<AST::FunctionDefinition&>(functionDefinition)); >+ nameResolver.checkErrorAndVisit(static_cast<AST::FunctionDefinition&>(functionDefinition)); >+ if (nameResolver.error()) >+ return false; >+ } >+ nameResolver.setCurrentFunctionDefinition(nullptr); >+ for (auto& nativeFunctionDeclaration : program.nativeFunctionDeclarations()) { >+ nameResolver.checkErrorAndVisit(static_cast<AST::FunctionDeclaration&>(nativeFunctionDeclaration)); >+ if (nameResolver.error()) >+ return false; >+ } >+ return true; >+} >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.h >new file mode 100644 >index 00000000000..15afde3d03b >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.h >@@ -0,0 +1,78 @@ >+/* >+ * 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 "WHLSLNameContext.h" >+#include "WHLSLVisitor.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+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&); >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.cpp >new file mode 100644 >index 00000000000..9a9d5d7b337 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.cpp >@@ -0,0 +1,2591 @@ >+/* >+ * 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. >+ */ >+ >+#include "config.h" >+#include "WHLSLParser.h" >+ >+#if ENABLE(WEBGPU) >+ >+#include <wtf/text/StringBuilder.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+Parser::Parser() >+{ >+} >+ >+// 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; >+ >+ while (!m_lexer.isFullyConsumed()) { >+ if (tryType(Lexer::Token::Type::Semicolon)) { >+ m_lexer.consumeToken(); >+ continue; >+ } >+ >+ { >+ auto typeDefinition = backtrackingScope<Expected<AST::TypeDefinition, Error>>([&]() { >+ return parseTypeDefinition(); >+ }); >+ if (typeDefinition) { >+ auto success = program.append(WTFMove(*typeDefinition)); >+ if (!success) { >+ WTFLogAlways("Name Error! %s", typeDefinition->name().utf8().data()); >+ return WTF::nullopt; >+ } >+ continue; >+ } >+ } >+ >+ { >+ auto structureDefinition = backtrackingScope<Expected<AST::StructureDefinition, Error>>([&]() { >+ return parseStructureDefinition(); >+ }); >+ if (structureDefinition) { >+ auto success = program.append(WTFMove(*structureDefinition)); >+ if (!success) { >+ WTFLogAlways("Name Error! %s", structureDefinition->name().utf8().data()); >+ return WTF::nullopt; >+ } >+ continue; >+ } >+ } >+ >+ { >+ auto enumerationDefinition = backtrackingScope<Expected<AST::EnumerationDefinition, Error>>([&]() { >+ return parseEnumerationDefinition(); >+ }); >+ if (enumerationDefinition) { >+ auto success = program.append(WTFMove(*enumerationDefinition)); >+ if (!success) { >+ WTFLogAlways("Name Error! %s", enumerationDefinition->name().utf8().data()); >+ return WTF::nullopt; >+ } >+ continue; >+ } >+ } >+ >+ Optional<Error> error; >+ { >+ auto functionDefinition = backtrackingScope<Expected<AST::FunctionDefinition, Error>>([&]() { >+ return parseFunctionDefinition(); >+ }); >+ if (functionDefinition) { >+ auto success = program.append(WTFMove(*functionDefinition)); >+ if (!success) { >+ WTFLogAlways("Name Error! %s", functionDefinition->name().utf8().data()); >+ return WTF::nullopt; >+ } >+ continue; >+ } >+ error = functionDefinition.error(); >+ } >+ >+ if (m_mode == Mode::StandardLibrary) { >+ auto nativeFunctionDeclaration = backtrackingScope<Expected<AST::NativeFunctionDeclaration, Error>>([&]() { >+ return parseNativeFunctionDeclaration(); >+ }); >+ if (nativeFunctionDeclaration) { >+ auto success = program.append(WTFMove(*nativeFunctionDeclaration)); >+ if (!success) { >+ WTFLogAlways("Name Error! %s", nativeFunctionDeclaration->name().utf8().data()); >+ return WTF::nullopt; >+ } >+ continue; >+ } >+ } >+ >+ if (m_mode == Mode::StandardLibrary) { >+ auto nativeTypeDeclaration = backtrackingScope<Expected<AST::NativeTypeDeclaration, Error>>([&]() { >+ return parseNativeTypeDeclaration(); >+ }); >+ if (nativeTypeDeclaration) { >+ auto success = program.append(WTFMove(*nativeTypeDeclaration)); >+ if (!success) { >+ WTFLogAlways("Name Error! %s", nativeTypeDeclaration->name().utf8().data()); >+ return WTF::nullopt; >+ } >+ continue; >+ } >+ } >+ >+ WTFLogAlways("%s", error->error.utf8().data()); >+ return WTFMove(*error); >+ } >+ return WTF::nullopt; >+} >+ >+auto Parser::fail(const String& message) -> Unexpected<Error> { >+ if (auto nextToken = peek()) >+ return Unexpected<Error>(Error(m_lexer.errorString(*nextToken, message))); >+ return Unexpected<Error>(Error(String::format("Cannot lex: %s", message.utf8().data()))); >+} >+ >+auto Parser::peek() -> Expected<Lexer::Token, Error> { >+ if (auto token = m_lexer.consumeToken()) { >+ m_lexer.unconsumeToken(Lexer::Token(*token)); >+ return *token; >+ } >+ return fail(String("Cannot consume token", String::ConstructFromLiteral)); >+} >+ >+Optional<Lexer::Token> Parser::tryType(Lexer::Token::Type type) >+{ >+ if (auto token = m_lexer.consumeToken()) { >+ if (token->type == type) >+ return token; >+ m_lexer.unconsumeToken(Lexer::Token(*token)); >+ } >+ return WTF::nullopt; >+} >+ >+Optional<Lexer::Token> Parser::tryTypes(Vector<Lexer::Token::Type> types) >+{ >+ if (auto token = m_lexer.consumeToken()) { >+ if (std::find(types.begin(), types.end(), token->type) != types.end()) >+ return token; >+ m_lexer.unconsumeToken(Lexer::Token(*token)); >+ } >+ return WTF::nullopt; >+} >+ >+auto Parser::consumeType(Lexer::Token::Type type) -> Expected<Lexer::Token, Error> { >+ if (auto token = m_lexer.consumeToken()) { >+ if (token->type == type) >+ return *token; >+ return fail(String::format("Unexpected token (expected %s got %s)", Lexer::Token::typeName(type), Lexer::Token::typeName(token->type))); >+ } >+ return fail(String::format("Cannot consume token (expected %s)", Lexer::Token::typeName(type))); >+} >+ >+auto Parser::consumeTypes(Vector<Lexer::Token::Type> types) -> Expected<Lexer::Token, Error> { >+ auto buildExpectedString = [&]() -> String { >+ StringBuilder builder; >+ builder.append("["); >+ for (unsigned i = 0; i < types.size(); ++i) { >+ if (i > 0) >+ builder.append(", "); >+ builder.append(Lexer::Token::typeName(types[i])); >+ } >+ builder.append("]"); >+ return builder.toString(); >+ }; >+ >+ if (auto token = m_lexer.consumeToken()) { >+ if (std::find(types.begin(), types.end(), token->type) != types.end()) >+ return *token; >+ return fail(String::format("Unexpected token (expected one of %s got %s)", buildExpectedString().utf8().data(), Lexer::Token::typeName(token->type))); >+ } >+ return fail(String::format("Cannot consume token (expected %s)", buildExpectedString().utf8().data())); >+} >+ >+static int digitValue(UChar character) >+{ >+ if (character >= '0' && character <= '9') >+ return character - '0'; >+ if (character >= 'a' && character <= 'f') >+ return character - 'a' + 10; >+ return character - 'A' + 10; >+} >+ >+static Expected<int, Parser::Error> intLiteralToInt(StringView text) >+{ >+ bool negate = false; >+ if (text.startsWith(String("-", String::ConstructFromLiteral))) { >+ negate = true; >+ text = text.substring(1); >+ } >+ int base = 10; >+ if (text.startsWith(String("0x", String::ConstructFromLiteral))) { >+ text = text.substring(2); >+ base = 16; >+ } >+ >+ int result = 0; >+ for (unsigned i = 0; i < text.length(); ++i) { >+ int digit = digitValue(text[i]); >+ auto previous = result; >+ result = result * base + digit; >+ if (result < previous) // FIXME: overflow on signed integers is undefined >+ return Unexpected<Parser::Error>(Parser::Error(String::format("int literal %s is out of bounds", text.utf8().data()))); >+ } >+ if (negate) >+ result *= -1; >+ // FIXME: This algorithm makes it impossible to represent 0x800000 (the most negative representable value) >+ return { result }; >+} >+ >+static Expected<unsigned, Parser::Error> uintLiteralToUint(StringView text) >+{ >+ unsigned base = 10; >+ if (text.startsWith(String("0x", String::ConstructFromLiteral))) { >+ text = text.substring(2); >+ base = 16; >+ } >+ ASSERT(text.substring(text.length() - 1) == "u"); >+ text = text.substring(0, text.length() - 1); >+ unsigned result = 0; >+ for (unsigned i = 0; i < text.length(); ++i) { >+ unsigned digit = digitValue(text[i]); >+ auto previous = result; >+ result = result * base + digit; >+ if (result < previous) >+ return Unexpected<Parser::Error>(Parser::Error(String::format("uint literal %s is out of bounds", text.utf8().data()))); >+ } >+ return { result }; >+} >+ >+static Expected<float, Parser::Error> floatLiteralToFloat(StringView text) >+{ >+ bool negate = false; >+ if (text.length() > 0 && text[0] == '-') { >+ negate = true; >+ text = text.substring(1); >+ } >+ if (text.length() > 0 && text[text.length() - 1] == 'f') >+ text = text.substring(0, text.length() - 1); >+ float result; >+ unsigned index = 0; >+ for (index = 0; index < text.length() && text[index] != '.'; ++index) { >+ ASSERT(text[index] >= '0' && text[index] <= '9'); >+ result = result * 10 + (text[index] - '0'); >+ } >+ ASSERT(index < text.length()); >+ ASSERT(text[index] == '.'); >+ float decimal = 1.0f / 10.0f; >+ for (++index; index < text.length(); ++index) { >+ ASSERT(text[index] >= '0' && text[index] <= '9'); >+ result += decimal * (text[index] - '0'); >+ decimal /= 10.0f; >+ } >+ if (negate) >+ result *= -1; >+ return result; >+} >+ >+auto Parser::consumeIntegralLiteral() -> Expected<Variant<int, unsigned>, Error> { >+ auto integralLiteralToken = consumeTypes({ Lexer::Token::Type::IntLiteral, Lexer::Token::Type::UintLiteral }); >+ if (!integralLiteralToken) >+ return Unexpected<Error>(integralLiteralToken.error()); >+ >+ switch (integralLiteralToken->type) { >+ case Lexer::Token::Type::IntLiteral: { >+ auto result = intLiteralToInt(integralLiteralToken->stringView); >+ if (result) >+ return {{ *result }}; >+ return Unexpected<Error>(result.error()); >+ } >+ case Lexer::Token::Type::UintLiteral: { >+ auto result = uintLiteralToUint(integralLiteralToken->stringView); >+ if (result) >+ return {{ *result }}; >+ return Unexpected<Error>(result.error()); >+ } >+ default: >+ ASSERT_NOT_REACHED(); >+ return Unexpected<Error>(Error(String("Something really bad happened", String::ConstructFromLiteral))); >+ } >+} >+ >+auto Parser::consumeNonNegativeIntegralLiteral() -> Expected<unsigned, Error> { >+ auto integralLiteral = consumeIntegralLiteral(); >+ if (!integralLiteral) >+ return Unexpected<Error>(integralLiteral.error()); >+ auto result = WTF::visit(WTF::makeVisitor([](int x) -> Optional<unsigned> { >+ if (x < 0) >+ return WTF::nullopt; >+ return x; >+ }, [](unsigned x) -> Optional<unsigned> { >+ return x; >+ }), *integralLiteral); >+ if (result) >+ return *result; >+ return fail(String("int literal is negative", String::ConstructFromLiteral)); >+} >+ >+static Expected<unsigned, Parser::Error> recognizeSimpleUnsignedInteger(StringView stringView) >+{ >+ unsigned result = 0; >+ if (stringView.length() < 1) >+ return Unexpected<Parser::Error>(Parser::Error(String::format("Simple unsigned literal %s is too short", stringView.utf8().data()))); >+ for (unsigned i = 0; i < stringView.length(); ++i) { >+ if (stringView[i] < '0' || stringView[i] > '9') >+ return Unexpected<Parser::Error>(Parser::Error(String::format("Simple unsigned literal %s isn't of the form [0-9]+", stringView.utf8().data()))); >+ auto previous = result; >+ result = result * 10 + (stringView[i] - '0'); >+ if (result < previous) >+ return Unexpected<Parser::Error>(Parser::Error(String::format("Simple unsigned literal %s is out of bounds", stringView.utf8().data()))); >+ } >+ return result; >+} >+ >+auto Parser::parseConstantExpression() -> Expected<AST::ConstantExpression, Error> { >+ auto type = consumeTypes({ >+ Lexer::Token::Type::IntLiteral, >+ Lexer::Token::Type::UintLiteral, >+ Lexer::Token::Type::FloatLiteral, >+ Lexer::Token::Type::Null, >+ Lexer::Token::Type::True, >+ Lexer::Token::Type::False, >+ Lexer::Token::Type::Identifier, >+ }); >+ if (!type) >+ return Unexpected<Error>(type.error()); >+ >+ switch (type->type) { >+ case Lexer::Token::Type::IntLiteral: { >+ auto value = intLiteralToInt(type->stringView); >+ if (!value) >+ return Unexpected<Error>(value.error()); >+ return {{ AST::IntegerLiteral(WTFMove(*type), *value) }}; >+ } >+ case Lexer::Token::Type::UintLiteral: { >+ auto value = uintLiteralToUint(type->stringView); >+ if (!value) >+ return Unexpected<Error>(value.error()); >+ return {{ AST::UnsignedIntegerLiteral(WTFMove(*type), *value) }}; >+ } >+ case Lexer::Token::Type::FloatLiteral: { >+ auto value = floatLiteralToFloat(type->stringView); >+ if (!value) >+ return Unexpected<Error>(value.error()); >+ return {{ AST::FloatLiteral(WTFMove(*type), *value) }}; >+ } >+ case Lexer::Token::Type::Null: >+ return { AST::NullLiteral(WTFMove(*type)) }; >+ case Lexer::Token::Type::True: >+ return { AST::BooleanLiteral(WTFMove(*type), true) }; >+ case Lexer::Token::Type::False: >+ return { AST::BooleanLiteral(WTFMove(*type), false) }; >+ case Lexer::Token::Type::Identifier: { >+ auto origin = consumeType(Lexer::Token::Type::FullStop); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ auto next = consumeType(Lexer::Token::Type::Identifier); >+ if (!next) >+ return Unexpected<Error>(next.error()); >+ return { AST::ConstantExpressionEnumerationMemberReference(WTFMove(*origin), type->stringView.toString(), next->stringView.toString()) }; >+ } >+ default: >+ ASSERT_NOT_REACHED(); >+ return Unexpected<Error>(Error(String("Something really bad happened", String::ConstructFromLiteral))); >+ } >+} >+ >+auto Parser::parseTypeArgument() -> Expected<AST::TypeArgument, Error> { >+ auto constantExpression = backtrackingScope<Expected<AST::ConstantExpression, Error>>([&]() { >+ return parseConstantExpression(); >+ }); >+ if (constantExpression) >+ return AST::TypeArgument(WTFMove(*constantExpression)); >+ auto result = consumeType(Lexer::Token::Type::Identifier); >+ if (!result) >+ return Unexpected<Error>(result.error()); >+ return AST::TypeArgument(makeUniqueRef<AST::TypeReference>(Lexer::Token(*result), result->stringView.toString(), AST::TypeArguments())); >+} >+ >+auto Parser::parseTypeArguments() -> Expected<AST::TypeArguments, Error> { >+ auto typeArguments = backtrackingScope<Optional<AST::TypeArguments>>([&]() -> Optional<AST::TypeArguments> { >+ auto lessThanSign = consumeType(Lexer::Token::Type::LessThanSign); >+ if (!lessThanSign) >+ return WTF::nullopt; >+ AST::TypeArguments typeArguments; >+ auto typeArgument = parseTypeArgument(); >+ if (!typeArgument) >+ return WTF::nullopt; >+ typeArguments.append(WTFMove(*typeArgument)); >+ while (tryType(Lexer::Token::Type::Comma)) { >+ auto typeArgument = parseTypeArgument(); >+ if (!typeArgument) >+ return WTF::nullopt; >+ typeArguments.append(WTFMove(*typeArgument)); >+ } >+ auto greaterThanSign = consumeType(Lexer::Token::Type::GreaterThanSign); >+ if (!greaterThanSign) >+ return WTF::nullopt; >+ return typeArguments; >+ }); >+ if (typeArguments) >+ return WTFMove(*typeArguments); >+ >+ typeArguments = backtrackingScope<Optional<AST::TypeArguments>>([&]() -> Optional<AST::TypeArguments> { >+ auto lessThanSign = consumeType(Lexer::Token::Type::LessThanSign); >+ if (!lessThanSign) >+ return WTF::nullopt; >+ auto greaterThanSign = consumeType(Lexer::Token::Type::GreaterThanSign); >+ if (!greaterThanSign) >+ return WTF::nullopt; >+ return {{ }}; >+ }); >+ if (typeArguments) >+ return WTFMove(*typeArguments); >+ >+ return AST::TypeArguments(); >+} >+ >+auto Parser::parseTypeSuffixAbbreviated() -> Expected<TypeSuffixAbbreviated, Error> { >+ auto token = consumeTypes({ Lexer::Token::Type::Star, Lexer::Token::Type::SquareBracketPair, Lexer::Token::Type::LeftSquareBracket }); >+ if (!token) >+ return Unexpected<Error>(token.error()); >+ if (token->type == Lexer::Token::Type::LeftSquareBracket) { >+ auto numElements = consumeNonNegativeIntegralLiteral(); >+ if (!numElements) >+ return Unexpected<Error>(numElements.error()); >+ auto rightSquareBracket = consumeType(Lexer::Token::Type::RightSquareBracket); >+ if (!rightSquareBracket) >+ return Unexpected<Error>(rightSquareBracket.error()); >+ return {{ *token, *numElements }}; >+ } >+ return {{ *token, WTF::nullopt }}; >+} >+ >+auto Parser::parseTypeSuffixNonAbbreviated() -> Expected<TypeSuffixNonAbbreviated, Error> { >+ auto token = consumeTypes({ Lexer::Token::Type::Star, Lexer::Token::Type::SquareBracketPair, Lexer::Token::Type::LeftSquareBracket }); >+ if (!token) >+ return Unexpected<Error>(token.error()); >+ if (token->type == Lexer::Token::Type::LeftSquareBracket) { >+ auto numElements = consumeNonNegativeIntegralLiteral(); >+ if (!numElements) >+ return Unexpected<Error>(numElements.error()); >+ auto rightSquareBracket = consumeType(Lexer::Token::Type::RightSquareBracket); >+ if (!rightSquareBracket) >+ return Unexpected<Error>(rightSquareBracket.error()); >+ return {{ *token, WTF::nullopt, *numElements }}; >+ } >+ 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<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()); >+ auto typeArguments = parseTypeArguments(); >+ if (!typeArguments) >+ return Unexpected<Error>(typeArguments.error()); >+ >+ auto constructTypeFromSuffixAbbreviated = [&](const TypeSuffixAbbreviated& typeSuffixAbbreviated, UniqueRef<AST::UnnamedType>&& previous) -> UniqueRef<AST::UnnamedType> { >+ switch (typeSuffixAbbreviated.token.type) { >+ case Lexer::Token::Type::Star: >+ return makeUniqueRef<AST::PointerType>(Lexer::Token(typeSuffixAbbreviated.token), addressSpace, WTFMove(previous)); >+ case Lexer::Token::Type::SquareBracketPair: >+ return makeUniqueRef<AST::ArrayReferenceType>(Lexer::Token(typeSuffixAbbreviated.token), addressSpace, WTFMove(previous)); >+ case Lexer::Token::Type::LeftSquareBracket: >+ return makeUniqueRef<AST::ArrayType>(Lexer::Token(typeSuffixAbbreviated.token), WTFMove(previous), *typeSuffixAbbreviated.numElements); >+ default: >+ ASSERT_NOT_REACHED(); >+ } >+ }; >+ >+ auto firstTypeSuffixAbbreviated = parseTypeSuffixAbbreviated(); >+ if (!firstTypeSuffixAbbreviated) >+ return Unexpected<Error>(firstTypeSuffixAbbreviated.error()); >+ 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>>([&]() { >+ return parseTypeSuffixAbbreviated(); >+ }); >+ if (!typeSuffixAbbreviated) >+ break; >+ // FIXME: The nesting here might be in the wrong order. >+ result = constructTypeFromSuffixAbbreviated(*typeSuffixAbbreviated, WTFMove(result)); >+ } >+ >+ return WTFMove(result); >+} >+ >+auto Parser::parseNonAddressSpaceType() -> Expected<UniqueRef<AST::UnnamedType>, Error> { >+ auto origin = peek(); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ auto name = consumeType(Lexer::Token::Type::Identifier); >+ if (!name) >+ return Unexpected<Error>(name.error()); >+ auto typeArguments = parseTypeArguments(); >+ if (!typeArguments) >+ return Unexpected<Error>(typeArguments.error()); >+ >+ auto constructTypeFromSuffixNonAbbreviated = [&](const TypeSuffixNonAbbreviated& typeSuffixNonAbbreviated, UniqueRef<AST::UnnamedType>&& previous) -> UniqueRef<AST::UnnamedType> { >+ switch (typeSuffixNonAbbreviated.token.type) { >+ case Lexer::Token::Type::Star: >+ return makeUniqueRef<AST::PointerType>(Lexer::Token(typeSuffixNonAbbreviated.token), *typeSuffixNonAbbreviated.addressSpace, WTFMove(previous)); >+ case Lexer::Token::Type::SquareBracketPair: >+ return makeUniqueRef<AST::ArrayReferenceType>(Lexer::Token(typeSuffixNonAbbreviated.token), *typeSuffixNonAbbreviated.addressSpace, WTFMove(previous)); >+ case Lexer::Token::Type::LeftSquareBracket: >+ return makeUniqueRef<AST::ArrayType>(Lexer::Token(typeSuffixNonAbbreviated.token), WTFMove(previous), *typeSuffixNonAbbreviated.numElements); >+ default: >+ ASSERT_NOT_REACHED(); >+ } >+ }; >+ >+ UniqueRef<AST::UnnamedType> result = makeUniqueRef<AST::TypeReference>(WTFMove(*origin), name->stringView.toString(), WTFMove(*typeArguments)); >+ while (true) { >+ auto typeSuffixNonAbbreviated = backtrackingScope<Expected<TypeSuffixNonAbbreviated, Error>>([&]() { >+ return parseTypeSuffixNonAbbreviated(); >+ }); >+ if (!typeSuffixNonAbbreviated) >+ break; >+ // FIXME: The nesting here might be in the wrong order. >+ result = constructTypeFromSuffixNonAbbreviated(*typeSuffixNonAbbreviated, WTFMove(result)); >+ } >+ >+ return WTFMove(result); >+} >+ >+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<UniqueRef<AST::UnnamedType>, Error>>([&]() { >+ return parseNonAddressSpaceType(); >+ }); >+ if (type) >+ return type; >+ >+ return Unexpected<Error>(type.error()); >+} >+ >+auto Parser::parseTypeDefinition() -> Expected<AST::TypeDefinition, Error> { >+ auto origin = consumeType(Lexer::Token::Type::Typedef); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ auto name = consumeType(Lexer::Token::Type::Identifier); >+ if (!name) >+ return Unexpected<Error>(name.error()); >+ auto equals = consumeType(Lexer::Token::Type::EqualsSign); >+ if (!equals) >+ return Unexpected<Error>(equals.error()); >+ auto type = parseType(); >+ if (!type) >+ return Unexpected<Error>(type.error()); >+ auto semicolon = consumeType(Lexer::Token::Type::Semicolon); >+ if (!semicolon) >+ return Unexpected<Error>(semicolon.error()); >+ return AST::TypeDefinition(WTFMove(*origin), name->stringView.toString(), WTFMove(*type)); >+} >+ >+auto Parser::parseBuiltInSemantic() -> Expected<AST::BuiltInSemantic, Error> { >+ auto origin = consumeTypes({ >+ Lexer::Token::Type::SVInstanceID, >+ Lexer::Token::Type::SVVertexID, >+ Lexer::Token::Type::PSize, >+ Lexer::Token::Type::SVPosition, >+ Lexer::Token::Type::SVIsFrontFace, >+ Lexer::Token::Type::SVSampleIndex, >+ Lexer::Token::Type::SVInnerCoverage, >+ Lexer::Token::Type::SVTarget, >+ Lexer::Token::Type::SVDepth, >+ Lexer::Token::Type::SVCoverage, >+ Lexer::Token::Type::SVDispatchThreadID, >+ Lexer::Token::Type::SVGroupID, >+ Lexer::Token::Type::SVGroupIndex, >+ Lexer::Token::Type::SVGroupThreadID}); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ switch (origin->type) { >+ case Lexer::Token::Type::SVInstanceID: >+ return AST::BuiltInSemantic(WTFMove(*origin), AST::BuiltInSemantic::Variable::SVInstanceID); >+ case Lexer::Token::Type::SVVertexID: >+ return AST::BuiltInSemantic(WTFMove(*origin), AST::BuiltInSemantic::Variable::SVVertexID); >+ case Lexer::Token::Type::PSize: >+ return AST::BuiltInSemantic(WTFMove(*origin), AST::BuiltInSemantic::Variable::PSize); >+ case Lexer::Token::Type::SVPosition: >+ return AST::BuiltInSemantic(WTFMove(*origin), AST::BuiltInSemantic::Variable::SVPosition); >+ case Lexer::Token::Type::SVIsFrontFace: >+ return AST::BuiltInSemantic(WTFMove(*origin), AST::BuiltInSemantic::Variable::SVIsFrontFace); >+ case Lexer::Token::Type::SVSampleIndex: >+ return AST::BuiltInSemantic(WTFMove(*origin), AST::BuiltInSemantic::Variable::SVSampleIndex); >+ case Lexer::Token::Type::SVInnerCoverage: >+ return AST::BuiltInSemantic(WTFMove(*origin), AST::BuiltInSemantic::Variable::SVInnerCoverage); >+ case Lexer::Token::Type::SVTarget: { >+ auto target = consumeNonNegativeIntegralLiteral(); >+ if (!target) >+ return Unexpected<Error>(target.error()); >+ return AST::BuiltInSemantic(WTFMove(*origin), AST::BuiltInSemantic::Variable::SVTarget, *target); >+ } >+ case Lexer::Token::Type::SVDepth: >+ return AST::BuiltInSemantic(WTFMove(*origin), AST::BuiltInSemantic::Variable::SVDepth); >+ case Lexer::Token::Type::SVCoverage: >+ return AST::BuiltInSemantic(WTFMove(*origin), AST::BuiltInSemantic::Variable::SVCoverage); >+ case Lexer::Token::Type::SVDispatchThreadID: >+ return AST::BuiltInSemantic(WTFMove(*origin), AST::BuiltInSemantic::Variable::SVDispatchThreadID); >+ case Lexer::Token::Type::SVGroupID: >+ return AST::BuiltInSemantic(WTFMove(*origin), AST::BuiltInSemantic::Variable::SVGroupID); >+ case Lexer::Token::Type::SVGroupIndex: >+ return AST::BuiltInSemantic(WTFMove(*origin), AST::BuiltInSemantic::Variable::SVGroupIndex); >+ case Lexer::Token::Type::SVGroupThreadID: >+ return AST::BuiltInSemantic(WTFMove(*origin), AST::BuiltInSemantic::Variable::SVGroupThreadID); >+ default: >+ ASSERT_NOT_REACHED(); >+ return Unexpected<Error>(Error(String("Something really bad happened", String::ConstructFromLiteral))); >+ } >+} >+ >+auto Parser::parseResourceSemantic() -> Expected<AST::ResourceSemantic, Error> { >+ auto origin = consumeType(Lexer::Token::Type::Register); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis); >+ if (!leftParenthesis) >+ return Unexpected<Error>(leftParenthesis.error()); >+ >+ auto info = consumeType(Lexer::Token::Type::Identifier); >+ if (!info) >+ return Unexpected<Error>(info.error()); >+ if (info->stringView.length() < 2 || (info->stringView[0] != 'u' >+ && info->stringView[0] != 't' >+ && info->stringView[0] != 'b' >+ && info->stringView[0] != 's')) >+ return Unexpected<Error>(Error(String::format("%c is not a known resource type ('u', 't', 'b', or 's')", info->stringView[0]))); >+ >+ AST::ResourceSemantic::Mode mode; >+ switch (info->stringView[0]) { >+ case 'u': >+ mode = AST::ResourceSemantic::Mode::UnorderedAccessView; >+ break; >+ case 't': >+ mode = AST::ResourceSemantic::Mode::Texture; >+ break; >+ case 'b': >+ mode = AST::ResourceSemantic::Mode::Buffer; >+ break; >+ case 's': >+ mode = AST::ResourceSemantic::Mode::Sampler; >+ break; >+ } >+ >+ auto index = recognizeSimpleUnsignedInteger(info->stringView.substring(1)); >+ if (!index) >+ return Unexpected<Error>(index.error()); >+ >+ unsigned space = 0; >+ if (tryType(Lexer::Token::Type::Comma)) { >+ auto spaceToken = consumeType(Lexer::Token::Type::Identifier); >+ if (!spaceToken) >+ return Unexpected<Error>(spaceToken.error()); >+ auto prefix = String("space", String::ConstructFromLiteral); >+ if (!spaceToken->stringView.startsWith(StringView(prefix))) >+ return Unexpected<Error>(Error(String::format("Second argument to resource semantic %s needs be of the form 'space0'", spaceToken->stringView.utf8().data()))); >+ if (spaceToken->stringView.length() <= prefix.length()) >+ return Unexpected<Error>(Error(String::format("Second argument to resource semantic %s needs be of the form 'space0'", spaceToken->stringView.utf8().data()))); >+ auto spaceValue = recognizeSimpleUnsignedInteger(spaceToken->stringView.substring(prefix.length())); >+ if (!spaceValue) >+ return Unexpected<Error>(spaceValue.error()); >+ space = *spaceValue; >+ } >+ >+ auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); >+ if (!rightParenthesis) >+ return Unexpected<Error>(rightParenthesis.error()); >+ >+ return AST::ResourceSemantic(WTFMove(*origin), mode, *index, space); >+} >+ >+auto Parser::parseSpecializationConstantSemantic() -> Expected<AST::SpecializationConstantSemantic, Error> { >+ auto origin = consumeType(Lexer::Token::Type::Specialized); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ return AST::SpecializationConstantSemantic(WTFMove(*origin)); >+} >+ >+auto Parser::parseStageInOutSemantic() -> Expected<AST::StageInOutSemantic, Error> { >+ auto origin = consumeType(Lexer::Token::Type::Attribute); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis); >+ if (!leftParenthesis) >+ return Unexpected<Error>(leftParenthesis.error()); >+ >+ auto index = consumeNonNegativeIntegralLiteral(); >+ if (!index) >+ return Unexpected<Error>(index.error()); >+ >+ auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); >+ if (!rightParenthesis) >+ return Unexpected<Error>(rightParenthesis.error()); >+ >+ return AST::StageInOutSemantic(WTFMove(*origin), *index); >+} >+ >+auto Parser::parseSemantic() -> Expected<AST::Semantic, Error> { >+ auto builtInSemantic = backtrackingScope<Expected<AST::BuiltInSemantic, Error>>([&]() { >+ return parseBuiltInSemantic(); >+ }); >+ if (builtInSemantic) >+ return AST::Semantic(WTFMove(*builtInSemantic)); >+ >+ auto resourceSemantic = backtrackingScope<Expected<AST::ResourceSemantic, Error>>([&]() { >+ return parseResourceSemantic(); >+ }); >+ if (resourceSemantic) >+ return AST::Semantic(WTFMove(*resourceSemantic)); >+ >+ auto specializationConstantSemantic = backtrackingScope<Expected<AST::SpecializationConstantSemantic, Error>>([&]() { >+ return parseSpecializationConstantSemantic(); >+ }); >+ if (specializationConstantSemantic) >+ return AST::Semantic(WTFMove(*specializationConstantSemantic)); >+ >+ auto stageInOutSemantic = backtrackingScope<Expected<AST::StageInOutSemantic, Error>>([&]() { >+ return parseStageInOutSemantic(); >+ }); >+ if (stageInOutSemantic) >+ return AST::Semantic(WTFMove(*stageInOutSemantic)); >+ >+ return Unexpected<Error>(stageInOutSemantic.error()); >+} >+AST::Qualifiers Parser::parseQualifiers() >+{ >+ AST::Qualifiers qualifiers; >+ while (true) { >+ if (auto next = tryType(Lexer::Token::Type::Qualifier)) { >+ if ("nointerpolation" == next->stringView) >+ qualifiers.append(AST::Qualifier::Nointerpolation); >+ else if ("noperspective" == next->stringView) >+ qualifiers.append(AST::Qualifier::Noperspective); >+ else if ("uniform" == next->stringView) >+ qualifiers.append(AST::Qualifier::Uniform); >+ else if ("centroid" == next->stringView) >+ qualifiers.append(AST::Qualifier::Centroid); >+ else if ("sample" == next->stringView) >+ qualifiers.append(AST::Qualifier::Sample); >+ else >+ ASSERT_NOT_REACHED(); >+ } else >+ break; >+ } >+ return qualifiers; >+} >+ >+auto Parser::parseStructureElement() -> Expected<AST::StructureElement, Error> { >+ auto origin = peek(); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ AST::Qualifiers qualifiers = parseQualifiers(); >+ >+ auto type = parseType(); >+ if (!type) >+ return Unexpected<Error>(type.error()); >+ >+ auto name = consumeType(Lexer::Token::Type::Identifier); >+ if (!name) >+ return Unexpected<Error>(name.error()); >+ >+ if (tryType(Lexer::Token::Type::Colon)) { >+ auto semantic = parseSemantic(); >+ if (!semantic) >+ return Unexpected<Error>(semantic.error()); >+ >+ auto semicolon = consumeType(Lexer::Token::Type::Semicolon); >+ if (!semicolon) >+ return Unexpected<Error>(semicolon.error()); >+ >+ return AST::StructureElement(WTFMove(*origin), WTFMove(qualifiers), WTFMove(*type), name->stringView.toString(), WTFMove(*semantic)); >+ } >+ >+ auto semicolon = consumeType(Lexer::Token::Type::Semicolon); >+ if (!semicolon) >+ return Unexpected<Error>(semicolon.error()); >+ >+ return AST::StructureElement(WTFMove(*origin), WTFMove(qualifiers), WTFMove(*type), name->stringView.toString(), WTF::nullopt); >+} >+ >+auto Parser::parseStructureDefinition() -> Expected<AST::StructureDefinition, Error> { >+ auto origin = consumeType(Lexer::Token::Type::Struct); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ auto name = consumeType(Lexer::Token::Type::Identifier); >+ if (!name) >+ return Unexpected<Error>(name.error()); >+ >+ auto leftCurlyBracket = consumeType(Lexer::Token::Type::LeftCurlyBracket); >+ if (!leftCurlyBracket) >+ return Unexpected<Error>(leftCurlyBracket.error()); >+ >+ AST::StructureElements structureElements; >+ while (true) { >+ auto structureElement = backtrackingScope<Expected<AST::StructureElement, Error>>([&]() { >+ return parseStructureElement(); >+ }); >+ if (structureElement) >+ structureElements.append(WTFMove(*structureElement)); >+ else >+ break; >+ } >+ >+ auto rightCurlyBracket = consumeType(Lexer::Token::Type::RightCurlyBracket); >+ if (!rightCurlyBracket) >+ return Unexpected<Error>(rightCurlyBracket.error()); >+ >+ return AST::StructureDefinition(WTFMove(*origin), name->stringView.toString(), WTFMove(structureElements)); >+} >+ >+auto Parser::parseEnumerationDefinition() -> Expected<AST::EnumerationDefinition, Error> { >+ auto origin = consumeType(Lexer::Token::Type::Enum); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ auto name = consumeType(Lexer::Token::Type::Identifier); >+ if (!name) >+ return Unexpected<Error>(name.error()); >+ >+ Optional<UniqueRef<AST::UnnamedType>> type; >+ if (tryType(Lexer::Token::Type::Colon)) { >+ auto parsedType = parseType(); >+ if (!parsedType) >+ return Unexpected<Error>(parsedType.error()); >+ type = WTFMove(*parsedType); >+ } >+ >+ auto leftCurlyBracket = consumeType(Lexer::Token::Type::LeftCurlyBracket); >+ if (!leftCurlyBracket) >+ return Unexpected<Error>(leftCurlyBracket.error()); >+ >+ auto firstEnumerationMember = parseEnumerationMember(); >+ if (!firstEnumerationMember) >+ return Unexpected<Error>(firstEnumerationMember.error()); >+ >+ 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()); >+ 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 WTFMove(result); >+} >+ >+auto Parser::parseEnumerationMember() -> Expected<AST::EnumerationMember, Error> { >+ auto identifier = consumeType(Lexer::Token::Type::Identifier); >+ if (!identifier) >+ return Unexpected<Error>(identifier.error()); >+ auto name = identifier->stringView.toString(); >+ >+ if (tryType(Lexer::Token::Type::EqualsSign)) { >+ auto constantExpression = parseConstantExpression(); >+ if (!constantExpression) >+ return Unexpected<Error>(constantExpression.error()); >+ return AST::EnumerationMember(Lexer::Token(*identifier), WTFMove(name), WTFMove(*constantExpression)); >+ } >+ return AST::EnumerationMember(Lexer::Token(*identifier), WTFMove(name)); >+} >+ >+auto Parser::parseNativeTypeDeclaration() -> Expected<AST::NativeTypeDeclaration, Error> { >+ auto origin = consumeType(Lexer::Token::Type::Native); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ auto parsedTypedef = consumeType(Lexer::Token::Type::Typedef); >+ if (!parsedTypedef) >+ return Unexpected<Error>(parsedTypedef.error()); >+ >+ auto name = consumeType(Lexer::Token::Type::Identifier); >+ if (!name) >+ return Unexpected<Error>(name.error()); >+ >+ auto typeArguments = parseTypeArguments(); >+ if (!typeArguments) >+ return Unexpected<Error>(typeArguments.error()); >+ >+ auto semicolon = consumeType(Lexer::Token::Type::Semicolon); >+ if (!semicolon) >+ return Unexpected<Error>(semicolon.error()); >+ >+ return AST::NativeTypeDeclaration(WTFMove(*origin), name->stringView.toString(), WTFMove(*typeArguments)); >+} >+ >+auto Parser::parseNumThreadsFunctionAttribute() -> Expected<AST::NumThreadsFunctionAttribute, Error> { >+ auto origin = consumeType(Lexer::Token::Type::NumThreads); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis); >+ if (!leftParenthesis) >+ return Unexpected<Error>(leftParenthesis.error()); >+ >+ auto width = consumeNonNegativeIntegralLiteral(); >+ if (!width) >+ return Unexpected<Error>(width.error()); >+ >+ auto comma = consumeType(Lexer::Token::Type::Comma); >+ if (!comma) >+ return Unexpected<Error>(comma.error()); >+ >+ auto height = consumeNonNegativeIntegralLiteral(); >+ if (!height) >+ return Unexpected<Error>(height.error()); >+ >+ comma = consumeType(Lexer::Token::Type::Comma); >+ if (!comma) >+ return Unexpected<Error>(comma.error()); >+ >+ auto depth = consumeNonNegativeIntegralLiteral(); >+ if (!depth) >+ return Unexpected<Error>(depth.error()); >+ >+ auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); >+ if (!rightParenthesis) >+ return Unexpected<Error>(rightParenthesis.error()); >+ >+ return AST::NumThreadsFunctionAttribute(WTFMove(*origin), *width, *height, *depth); >+} >+ >+auto Parser::parseAttributeBlock() -> Expected<AST::AttributeBlock, Error> { >+ auto leftSquareBracket = consumeType(Lexer::Token::Type::LeftSquareBracket); >+ if (!leftSquareBracket) >+ return Unexpected<Error>(leftSquareBracket.error()); >+ >+ AST::AttributeBlock result; >+ >+ while (true) { >+ auto numThreadsFunctionAttribute = backtrackingScope<Expected<AST::NumThreadsFunctionAttribute, Error>>([&]() { >+ return parseNumThreadsFunctionAttribute(); >+ }); >+ if (numThreadsFunctionAttribute) { >+ result.append(WTFMove(*numThreadsFunctionAttribute)); >+ continue; >+ } >+ >+ break; >+ } >+ >+ auto rightSquareBracket = consumeType(Lexer::Token::Type::RightSquareBracket); >+ if (!rightSquareBracket) >+ return Unexpected<Error>(rightSquareBracket.error()); >+ >+ return WTFMove(result); >+} >+ >+auto Parser::parseParameter() -> Expected<AST::VariableDeclaration, Error> { >+ auto origin = peek(); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ AST::Qualifiers qualifiers = parseQualifiers(); >+ >+ auto type = parseType(); >+ if (!type) >+ return Unexpected<Error>(type.error()); >+ >+ String name; >+ if (auto token = tryType(Lexer::Token::Type::Identifier)) >+ name = token->stringView.toString(); >+ >+ if (tryType(Lexer::Token::Type::Colon)) { >+ auto semantic = parseSemantic(); >+ if (!semantic) >+ return Unexpected<Error>(semantic.error()); >+ return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), Optional<UniqueRef<AST::UnnamedType>>(WTFMove(*type)), WTFMove(name), WTFMove(*semantic), WTF::nullopt); >+ } >+ >+ return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), { WTFMove(*type) }, WTFMove(name), WTF::nullopt, WTF::nullopt); >+} >+ >+auto Parser::parseParameters() -> Expected<AST::VariableDeclarations, Error> { >+ auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis); >+ if (!leftParenthesis) >+ return Unexpected<Error>(leftParenthesis.error()); >+ >+ AST::VariableDeclarations parameters; >+ if (tryType(Lexer::Token::Type::RightParenthesis)) >+ return WTFMove(parameters); >+ >+ auto firstParameter = parseParameter(); >+ if (!firstParameter) >+ return Unexpected<Error>(firstParameter.error()); >+ parameters.append(WTFMove(*firstParameter)); >+ >+ while (tryType(Lexer::Token::Type::Comma)) { >+ auto parameter = parseParameter(); >+ if (!parameter) >+ return Unexpected<Error>(parameter.error()); >+ parameters.append(WTFMove(*parameter)); >+ } >+ >+ auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); >+ if (!rightParenthesis) >+ return Unexpected<Error>(rightParenthesis.error()); >+ >+ return WTFMove(parameters); >+} >+ >+auto Parser::parseFunctionDefinition() -> Expected<AST::FunctionDefinition, Error> { >+ bool restricted = static_cast<bool>(tryType(Lexer::Token::Type::Restricted)); >+ >+ auto functionDeclaration = parseFunctionDeclaration(); >+ if (!functionDeclaration) >+ return Unexpected<Error>(functionDeclaration.error()); >+ >+ auto block = parseBlock(); >+ if (!block) >+ return Unexpected<Error>(block.error()); >+ >+ return AST::FunctionDefinition(WTFMove(*functionDeclaration), WTFMove(*block), restricted); >+} >+ >+auto Parser::parseEntryPointFunctionDeclaration() -> Expected<AST::FunctionDeclaration, Error> { >+ auto origin = peek(); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ AST::AttributeBlock attributeBlock; >+ AST::FunctionDeclaration::EntryPointType entryPointType; >+ >+ auto parsedAttributeBlock = backtrackingScope<Expected<AST::AttributeBlock, Error>>([&]() { >+ return parseAttributeBlock(); >+ }); >+ if (parsedAttributeBlock) { >+ auto compute = consumeType(Lexer::Token::Type::Compute); >+ if (!compute) >+ return Unexpected<Error>(compute.error()); >+ attributeBlock = WTFMove(*parsedAttributeBlock); >+ entryPointType = AST::FunctionDeclaration::EntryPointType::Compute; >+ } else { >+ auto type = consumeTypes({ Lexer::Token::Type::Vertex, Lexer::Token::Type::Fragment }); >+ if (!type) >+ return Unexpected<Error>(type.error()); >+ >+ switch (origin->type) { >+ case Lexer::Token::Type::Vertex: >+ entryPointType = AST::FunctionDeclaration::EntryPointType::Vertex; >+ break; >+ case Lexer::Token::Type::Fragment: >+ entryPointType = AST::FunctionDeclaration::EntryPointType::Fragment; >+ break; >+ default: >+ ASSERT_NOT_REACHED(); >+ entryPointType = AST::FunctionDeclaration::EntryPointType::Vertex; >+ } >+ } >+ >+ auto type = parseType(); >+ if (!type) >+ return Unexpected<Error>(type.error()); >+ >+ auto name = consumeType(Lexer::Token::Type::Identifier); >+ if (!name) >+ return Unexpected<Error>(name.error()); >+ >+ auto parameters = parseParameters(); >+ 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), isOperator); >+ } >+ >+ 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> { >+ auto origin = peek(); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ auto type = parseType(); >+ if (!type) >+ return Unexpected<Error>(type.error()); >+ >+ 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) >+ return Unexpected<Error>(parameters.error()); >+ >+ 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), name->stringView.toString(), WTFMove(*parameters), WTFMove(*semantic), isOperator); >+ } >+ >+ return AST::FunctionDeclaration(WTFMove(*origin), { }, WTF::nullopt, WTFMove(*type), name->stringView.toString(), WTFMove(*parameters), WTF::nullopt, isOperator); >+} >+ >+auto Parser::parseOperatorFunctionDeclaration() -> Expected<AST::FunctionDeclaration, Error> { >+ auto origin = consumeType(Lexer::Token::Type::Operator); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ auto type = parseType(); >+ if (!type) >+ return Unexpected<Error>(type.error()); >+ >+ auto parameters = parseParameters(); >+ 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), isOperator); >+ } >+ >+ 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> { >+ auto entryPointFunctionDeclaration = backtrackingScope<Expected<AST::FunctionDeclaration, Error>>([&]() { >+ return parseEntryPointFunctionDeclaration(); >+ }); >+ if (entryPointFunctionDeclaration) >+ return WTFMove(*entryPointFunctionDeclaration); >+ >+ auto regularFunctionDeclaration = backtrackingScope<Expected<AST::FunctionDeclaration, Error>>([&]() { >+ return parseRegularFunctionDeclaration(); >+ }); >+ if (regularFunctionDeclaration) >+ return WTFMove(*regularFunctionDeclaration); >+ >+ auto operatorFunctionDeclaration = backtrackingScope<Expected<AST::FunctionDeclaration, Error>>([&]() { >+ return parseOperatorFunctionDeclaration(); >+ }); >+ if (operatorFunctionDeclaration) >+ return WTFMove(*operatorFunctionDeclaration); >+ >+ return Unexpected<Error>(operatorFunctionDeclaration.error()); >+} >+ >+auto Parser::parseNativeFunctionDeclaration() -> Expected<AST::NativeFunctionDeclaration, Error> { >+ Optional<Lexer::Token> origin; >+ >+ bool restricted = false; >+ if (auto restrictedValue = tryType(Lexer::Token::Type::Restricted)) { >+ origin = *restrictedValue; >+ restricted = true; >+ } >+ >+ auto native = consumeType(Lexer::Token::Type::Native); >+ if (!native) >+ return Unexpected<Error>(native.error()); >+ if (!origin) >+ origin = *native; >+ >+ auto functionDeclaration = parseFunctionDeclaration(); >+ if (!functionDeclaration) >+ return Unexpected<Error>(functionDeclaration.error()); >+ >+ auto semicolon = consumeType(Lexer::Token::Type::Semicolon); >+ if (!semicolon) >+ return Unexpected<Error>(semicolon.error()); >+ >+ return AST::NativeFunctionDeclaration(WTFMove(*functionDeclaration), restricted); >+} >+ >+auto Parser::parseBlock() -> Expected<AST::Block, Error> { >+ auto origin = consumeType(Lexer::Token::Type::LeftCurlyBracket); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ auto result = parseBlockBody(WTFMove(*origin)); >+ >+ auto rightCurlyBracket = consumeType(Lexer::Token::Type::RightCurlyBracket); >+ if (!rightCurlyBracket) >+ return Unexpected<Error>(rightCurlyBracket.error()); >+ >+ return WTFMove(result); >+} >+ >+AST::Block Parser::parseBlockBody(Lexer::Token&& origin) >+{ >+ AST::Statements statements; >+ while (true) { >+ auto statement = backtrackingScope<Expected<UniqueRef<AST::Statement>, Error>>([&]() { >+ return parseStatement(); >+ }); >+ if (statement) >+ statements.append(WTFMove(*statement)); >+ else >+ break; >+ } >+ return AST::Block(WTFMove(origin), WTFMove(statements)); >+} >+ >+auto Parser::parseIfStatement() -> Expected<AST::IfStatement, Error> { >+ auto origin = consumeType(Lexer::Token::Type::If); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis); >+ if (!leftParenthesis) >+ return Unexpected<Error>(leftParenthesis.error()); >+ >+ auto conditional = parseExpression(); >+ if (!conditional) >+ return Unexpected<Error>(conditional.error()); >+ >+ auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); >+ if (!rightParenthesis) >+ return Unexpected<Error>(rightParenthesis.error()); >+ >+ auto body = parseStatement(); >+ if (!body) >+ return Unexpected<Error>(body.error()); >+ >+ Optional<UniqueRef<AST::Statement>> elseBody; >+ if (tryType(Lexer::Token::Type::Else)) { >+ auto parsedElseBody = parseStatement(); >+ if (!parsedElseBody) >+ return Unexpected<Error>(parsedElseBody.error()); >+ elseBody = WTFMove(*parsedElseBody); >+ } >+ >+ Vector<UniqueRef<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> { >+ auto origin = consumeType(Lexer::Token::Type::Switch); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis); >+ if (!leftParenthesis) >+ return Unexpected<Error>(leftParenthesis.error()); >+ >+ auto value = parseExpression(); >+ if (!value) >+ return Unexpected<Error>(value.error()); >+ >+ auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); >+ if (!rightParenthesis) >+ return Unexpected<Error>(rightParenthesis.error()); >+ >+ auto leftCurlyBracket = consumeType(Lexer::Token::Type::LeftCurlyBracket); >+ if (!leftCurlyBracket) >+ return Unexpected<Error>(leftCurlyBracket.error()); >+ >+ Vector<AST::SwitchCase> switchCases; >+ while (true) { >+ auto switchCase = backtrackingScope<Expected<AST::SwitchCase, Error>>([&]() { >+ return parseSwitchCase(); >+ }); >+ if (switchCase) >+ switchCases.append(WTFMove(*switchCase)); >+ else >+ break; >+ } >+ >+ auto rightCurlyBracket = consumeType(Lexer::Token::Type::RightCurlyBracket); >+ if (!rightCurlyBracket) >+ return Unexpected<Error>(rightCurlyBracket.error()); >+ >+ return AST::SwitchStatement(WTFMove(*origin), WTFMove(*value), WTFMove(switchCases)); >+} >+ >+auto Parser::parseSwitchCase() -> Expected<AST::SwitchCase, Error> { >+ auto origin = consumeTypes({ Lexer::Token::Type::Case, Lexer::Token::Type::Default }); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ switch (origin->type) { >+ case Lexer::Token::Type::Case: { >+ auto value = parseConstantExpression(); >+ if (!value) >+ return Unexpected<Error>(value.error()); >+ >+ auto origin = consumeType(Lexer::Token::Type::Colon); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ auto block = parseBlockBody(Lexer::Token(*origin)); >+ >+ return AST::SwitchCase(WTFMove(*origin), WTFMove(*value), WTFMove(block)); >+ } >+ case Lexer::Token::Type::Default: { >+ auto origin = consumeType(Lexer::Token::Type::Colon); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ auto block = parseBlockBody(Lexer::Token(*origin)); >+ >+ return AST::SwitchCase(WTFMove(*origin), WTF::nullopt, WTFMove(block)); >+ } >+ default: >+ ASSERT_NOT_REACHED(); >+ return Unexpected<Error>(Error(String("Something really bad happened", String::ConstructFromLiteral))); >+ } >+} >+ >+auto Parser::parseForLoop() -> Expected<AST::ForLoop, Error> { >+ auto origin = consumeType(Lexer::Token::Type::For); >+ if (!origin) >+ return Unexpected<Error>(origin.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<Optional<UniqueRef<AST::Expression>>>([&]() -> Optional<UniqueRef<AST::Expression>> { >+ if (auto expression = parseExpression()) >+ return { WTFMove(*expression) }; >+ return WTF::nullopt; >+ }); >+ >+ semicolon = consumeType(Lexer::Token::Type::Semicolon); >+ if (!semicolon) >+ return Unexpected<Error>(semicolon.error()); >+ >+ auto increment = backtrackingScope<Optional<UniqueRef<AST::Expression>>>([&]() -> Optional<UniqueRef<AST::Expression>> { >+ if (auto expression = parseExpression()) >+ return { WTFMove(*expression) }; >+ return WTF::nullopt; >+ }); >+ >+ auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); >+ if (!rightParenthesis) >+ return Unexpected<Error>(rightParenthesis.error()); >+ >+ auto body = parseStatement(); >+ if (!body) >+ return Unexpected<Error>(body.error()); >+ >+ return AST::ForLoop(WTFMove(*origin), WTFMove(initialization), WTFMove(condition), WTFMove(increment), WTFMove(*body)); >+ }; >+ >+ auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis); >+ if (!leftParenthesis) >+ return Unexpected<Error>(leftParenthesis.error()); >+ >+ auto variableDeclarations = backtrackingScope<Expected<AST::VariableDeclarationsStatement, Error>>([&]() { >+ return parseVariableDeclarations(); >+ }); >+ if (variableDeclarations) >+ return parseRemainder(WTFMove(*variableDeclarations)); >+ >+ auto effectfulExpression = parseEffectfulExpression(); >+ if (!effectfulExpression) >+ return Unexpected<Error>(effectfulExpression.error()); >+ >+ return parseRemainder(WTFMove(*effectfulExpression)); >+} >+ >+auto Parser::parseWhileLoop() -> Expected<AST::WhileLoop, Error> { >+ auto origin = consumeType(Lexer::Token::Type::While); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis); >+ if (!leftParenthesis) >+ return Unexpected<Error>(leftParenthesis.error()); >+ >+ auto conditional = parseExpression(); >+ if (!conditional) >+ return Unexpected<Error>(conditional.error()); >+ >+ auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); >+ if (!rightParenthesis) >+ return Unexpected<Error>(rightParenthesis.error()); >+ >+ auto body = parseStatement(); >+ if (!body) >+ return Unexpected<Error>(body.error()); >+ >+ return AST::WhileLoop(WTFMove(*origin), WTFMove(*conditional), WTFMove(*body)); >+} >+ >+auto Parser::parseDoWhileLoop() -> Expected<AST::DoWhileLoop, Error> { >+ auto origin = consumeType(Lexer::Token::Type::Do); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ auto body = parseStatement(); >+ if (!body) >+ return Unexpected<Error>(body.error()); >+ >+ auto whileKeyword = consumeType(Lexer::Token::Type::While); >+ if (!whileKeyword) >+ return Unexpected<Error>(whileKeyword.error()); >+ >+ auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis); >+ if (!leftParenthesis) >+ return Unexpected<Error>(leftParenthesis.error()); >+ >+ auto conditional = parseExpression(); >+ if (!conditional) >+ return Unexpected<Error>(conditional.error()); >+ >+ auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); >+ if (!rightParenthesis) >+ return Unexpected<Error>(rightParenthesis.error()); >+ >+ return AST::DoWhileLoop(WTFMove(*origin), WTFMove(*body), WTFMove(*conditional)); >+} >+ >+auto Parser::parseVariableDeclaration(UniqueRef<AST::UnnamedType>&& type) -> Expected<AST::VariableDeclaration, Error> { >+ auto origin = peek(); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ auto qualifiers = parseQualifiers(); >+ >+ auto name = consumeType(Lexer::Token::Type::Identifier); >+ if (!name) >+ return Unexpected<Error>(name.error()); >+ >+ if (tryType(Lexer::Token::Type::Colon)) { >+ auto semantic = parseSemantic(); >+ if (!semantic) >+ return Unexpected<Error>(semantic.error()); >+ >+ 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(), WTFMove(*semantic), WTFMove(*initializer)); >+ } >+ >+ return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), { WTFMove(type) }, name->stringView.toString(), WTFMove(*semantic), WTF::nullopt); >+ } >+ >+ 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), { WTFMove(type) }, name->stringView.toString(), WTF::nullopt, WTF::nullopt); >+} >+ >+auto Parser::parseVariableDeclarations() -> Expected<AST::VariableDeclarationsStatement, Error> { >+ auto origin = peek(); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ auto type = parseType(); >+ if (!type) >+ return Unexpected<Error>(type.error()); >+ >+ auto firstVariableDeclaration = parseVariableDeclaration((*type)->clone()); >+ if (!firstVariableDeclaration) >+ return Unexpected<Error>(firstVariableDeclaration.error()); >+ >+ Vector<AST::VariableDeclaration> result; >+ result.append(WTFMove(*firstVariableDeclaration)); >+ >+ while (tryType(Lexer::Token::Type::Comma)) { >+ auto variableDeclaration = parseVariableDeclaration((*type)->clone()); >+ if (!variableDeclaration) >+ return Unexpected<Error>(variableDeclaration.error()); >+ result.append(WTFMove(*variableDeclaration)); >+ } >+ >+ return AST::VariableDeclarationsStatement(WTFMove(*origin), WTFMove(result)); >+} >+ >+auto Parser::parseStatement() -> Expected<UniqueRef<AST::Statement>, Error> { >+ { >+ auto block = backtrackingScope<Expected<AST::Block, Error>>([&]() { >+ return parseBlock(); >+ }); >+ if (block) >+ return { makeUniqueRef<AST::Block>(WTFMove(*block)) }; >+ } >+ >+ { >+ auto ifStatement = backtrackingScope<Expected<AST::IfStatement, Error>>([&]() { >+ return parseIfStatement(); >+ }); >+ if (ifStatement) >+ return { makeUniqueRef<AST::IfStatement>(WTFMove(*ifStatement)) }; >+ } >+ >+ { >+ auto switchStatement = backtrackingScope<Expected<AST::SwitchStatement, Error>>([&]() { >+ return parseSwitchStatement(); >+ }); >+ if (switchStatement) >+ return { makeUniqueRef<AST::SwitchStatement>(WTFMove(*switchStatement)) }; >+ } >+ >+ { >+ auto forLoop = backtrackingScope<Expected<AST::ForLoop, Error>>([&]() { >+ return parseForLoop(); >+ }); >+ if (forLoop) >+ return { makeUniqueRef<AST::ForLoop>(WTFMove(*forLoop)) }; >+ } >+ >+ { >+ auto whileLoop = backtrackingScope<Expected<AST::WhileLoop, Error>>([&]() { >+ return parseWhileLoop(); >+ }); >+ if (whileLoop) >+ return { makeUniqueRef<AST::WhileLoop>(WTFMove(*whileLoop)) }; >+ } >+ >+ { >+ auto doWhileLoop = backtrackingScope<Expected<AST::DoWhileLoop, Error>>([&]() -> Expected<AST::DoWhileLoop, Error> { >+ auto result = parseDoWhileLoop(); >+ if (!result) >+ return Unexpected<Error>(result.error()); >+ >+ auto semicolon = consumeType(Lexer::Token::Type::Semicolon); >+ if (!semicolon) >+ return Unexpected<Error>(semicolon.error()); >+ >+ return result; >+ }); >+ if (doWhileLoop) >+ return { makeUniqueRef<AST::DoWhileLoop>(WTFMove(*doWhileLoop)) }; >+ } >+ >+ { >+ auto breakObject = backtrackingScope<Expected<AST::Break, Error>>([&]() -> Expected<AST::Break, Error> { >+ auto origin = consumeType(Lexer::Token::Type::Break); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ auto semicolon = consumeType(Lexer::Token::Type::Semicolon); >+ if (!semicolon) >+ return Unexpected<Error>(semicolon.error()); >+ >+ return AST::Break(WTFMove(*origin)); >+ }); >+ if (breakObject) >+ return { makeUniqueRef<AST::Break>(WTFMove(*breakObject)) }; >+ } >+ >+ { >+ auto continueObject = backtrackingScope<Expected<AST::Continue, Error>>([&]() -> Expected<AST::Continue, Error> { >+ auto origin = consumeType(Lexer::Token::Type::Continue); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ auto semicolon = consumeType(Lexer::Token::Type::Semicolon); >+ if (!semicolon) >+ return Unexpected<Error>(semicolon.error()); >+ >+ return AST::Continue(WTFMove(*origin)); >+ }); >+ if (continueObject) >+ return { makeUniqueRef<AST::Continue>(WTFMove(*continueObject)) }; >+ } >+ >+ { >+ auto fallthroughObject = backtrackingScope<Expected<AST::Fallthrough, Error>>([&]() -> Expected<AST::Fallthrough, Error> { >+ auto origin = consumeType(Lexer::Token::Type::Fallthrough); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ auto semicolon = consumeType(Lexer::Token::Type::Semicolon); >+ if (!semicolon) >+ return Unexpected<Error>(semicolon.error()); >+ >+ return AST::Fallthrough(WTFMove(*origin)); >+ }); >+ if (fallthroughObject) >+ return { makeUniqueRef<AST::Fallthrough>(WTFMove(*fallthroughObject)) }; >+ } >+ >+ { >+ auto trapObject = backtrackingScope<Expected<AST::Trap, Error>>([&]() -> Expected<AST::Trap, Error> { >+ auto origin = consumeType(Lexer::Token::Type::Trap); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ auto semicolon = consumeType(Lexer::Token::Type::Semicolon); >+ if (!semicolon) >+ return Unexpected<Error>(semicolon.error()); >+ >+ return AST::Trap(WTFMove(*origin)); >+ }); >+ if (trapObject) >+ return { makeUniqueRef<AST::Trap>(WTFMove(*trapObject)) }; >+ } >+ >+ { >+ auto returnObject = backtrackingScope<Expected<AST::Return, Error>>([&]() -> Expected<AST::Return, Error> { >+ auto origin = consumeType(Lexer::Token::Type::Return); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ if (auto semicolon = tryType(Lexer::Token::Type::Semicolon)) >+ return AST::Return(WTFMove(*origin), WTF::nullopt); >+ >+ auto expression = parseExpression(); >+ if (!expression) >+ return Unexpected<Error>(expression.error()); >+ >+ auto semicolon = consumeType(Lexer::Token::Type::Semicolon); >+ if (!semicolon) >+ return Unexpected<Error>(semicolon.error()); >+ >+ return AST::Return(WTFMove(*origin), { WTFMove(*expression) }); >+ }); >+ if (returnObject) >+ return { makeUniqueRef<AST::Return>(WTFMove(*returnObject)) }; >+ } >+ >+ { >+ auto variableDeclarations = backtrackingScope<Expected<AST::VariableDeclarationsStatement, Error>>([&]() -> Expected<AST::VariableDeclarationsStatement, Error> { >+ auto result = parseVariableDeclarations(); >+ if (!result) >+ return Unexpected<Error>(result.error()); >+ >+ auto semicolon = consumeType(Lexer::Token::Type::Semicolon); >+ if (!semicolon) >+ return Unexpected<Error>(semicolon.error()); >+ >+ return result; >+ }); >+ if (variableDeclarations) >+ return { makeUniqueRef<AST::VariableDeclarationsStatement>(WTFMove(*variableDeclarations)) }; >+ } >+ >+ auto effectfulExpression = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() -> Expected<UniqueRef<AST::Expression>, Error> { >+ auto result = parseEffectfulExpression(); >+ if (!result) >+ return Unexpected<Error>(result.error()); >+ >+ auto semicolon = consumeType(Lexer::Token::Type::Semicolon); >+ if (!semicolon) >+ return Unexpected<Error>(semicolon.error()); >+ >+ return result; >+ }); >+ if (effectfulExpression) >+ return { makeUniqueRef<AST::EffectfulExpressionStatement>(WTFMove(*effectfulExpression)) }; >+ >+ return Unexpected<Error>(effectfulExpression.error()); >+} >+ >+auto Parser::parseEffectfulExpression() -> Expected<UniqueRef<AST::Expression>, Error> { >+ auto origin = peek(); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ Vector<UniqueRef<AST::Expression>> expressions; >+ >+ auto first = backtrackingScope<Optional<UniqueRef<AST::Expression>>>([&]() -> Optional<UniqueRef<AST::Expression>> { >+ auto effectfulExpression = parseEffectfulAssignment(); >+ if (!effectfulExpression) >+ return WTF::nullopt; >+ return { WTFMove(*effectfulExpression) }; >+ }); >+ if (!first) >+ return { makeUniqueRef<AST::CommaExpression>(WTFMove(*origin), WTFMove(expressions)) }; >+ >+ expressions.append(WTFMove(*first)); >+ >+ while (tryType(Lexer::Token::Type::Comma)) { >+ auto expression = parseEffectfulAssignment(); >+ if (!expression) >+ return Unexpected<Error>(expression.error()); >+ expressions.append(WTFMove(*expression)); >+ } >+ >+ if (expressions.size() == 1) >+ return WTFMove(expressions[0]); >+ return { makeUniqueRef<AST::CommaExpression>(WTFMove(*origin), WTFMove(expressions)) }; >+} >+ >+auto Parser::parseEffectfulAssignment() -> Expected<UniqueRef<AST::Expression>, Error> { >+ auto assignment = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() { >+ return parseAssignment(); >+ }); >+ if (assignment) >+ return assignment; >+ >+ assignment = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() { >+ return parseEffectfulPrefix(); >+ }); >+ if (assignment) >+ return assignment; >+ >+ assignment = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() { >+ return parseCallExpression(); >+ }); >+ if (assignment) >+ return assignment; >+ >+ return Unexpected<Error>(assignment.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()); >+ >+ auto previous = parsePossiblePrefix(); >+ if (!previous) >+ return Unexpected<Error>(previous.error()); >+ >+ switch (prefix->type) { >+ case Lexer::Token::Type::PlusPlus: { >+ auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(*prefix), WTFMove(*previous)); >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(result->oldVariableReference()); >+ result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(WTFMove(*prefix), String("operator++", String::ConstructFromLiteral), WTFMove(callArguments))); >+ result->setResultExpression(result->newVariableReference()); >+ return { WTFMove(result) }; >+ } >+ case Lexer::Token::Type::MinusMinus: { >+ auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(*prefix), WTFMove(*previous)); >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(result->oldVariableReference()); >+ result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(WTFMove(*prefix), String("operator--", String::ConstructFromLiteral), WTFMove(callArguments))); >+ result->setResultExpression(result->newVariableReference()); >+ return { WTFMove(result) }; >+ } >+ default: >+ ASSERT_NOT_REACHED(); >+ return Unexpected<Error>(Error(String("Something really bad happened", String::ConstructFromLiteral))); >+ } >+} >+ >+auto Parser::parseEffectfulSuffix() -> Expected<UniqueRef<AST::Expression>, Error> { >+ auto effectfulSuffix = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() -> Expected<UniqueRef<AST::Expression>, Error> { >+ auto previous = parsePossibleSuffix(); >+ if (!previous) >+ return Unexpected<Error>(previous.error()); >+ >+ auto suffix = consumeTypes({ Lexer::Token::Type::PlusPlus, Lexer::Token::Type::MinusMinus }); >+ if (!suffix) >+ return Unexpected<Error>(suffix.error()); >+ >+ switch (suffix->type) { >+ case Lexer::Token::Type::PlusPlus: { >+ auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(*suffix), WTFMove(*previous)); >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(result->oldVariableReference()); >+ result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(WTFMove(*suffix), String("operator++", String::ConstructFromLiteral), WTFMove(callArguments))); >+ result->setResultExpression(result->oldVariableReference()); >+ return makeUniqueRef<AST::Expression>(WTFMove(result)); >+ } >+ case Lexer::Token::Type::MinusMinus: { >+ auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(*suffix), WTFMove(*previous)); >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(result->oldVariableReference()); >+ result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(WTFMove(*suffix), String("operator--", String::ConstructFromLiteral), WTFMove(callArguments))); >+ result->setResultExpression(result->oldVariableReference()); >+ return makeUniqueRef<AST::Expression>(WTFMove(result)); >+ } >+ default: >+ ASSERT_NOT_REACHED(); >+ return Unexpected<Error>(Error(String("Something really bad happened", String::ConstructFromLiteral))); >+ } >+ }); >+ if (effectfulSuffix) >+ return effectfulSuffix; >+ >+ effectfulSuffix = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() { >+ return parseCallExpression(); >+ }); >+ if (effectfulSuffix) >+ return effectfulSuffix; >+ >+ effectfulSuffix = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() -> Expected<UniqueRef<AST::Expression>, Error> { >+ auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis); >+ if (!leftParenthesis) >+ return Unexpected<Error>(leftParenthesis.error()); >+ >+ auto expression = parseExpression(); >+ if (!expression) >+ return Unexpected<Error>(expression.error()); >+ >+ auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); >+ if (!rightParenthesis) >+ return Unexpected<Error>(rightParenthesis.error()); >+ >+ return { WTFMove(*expression) }; >+ }); >+ if (effectfulSuffix) >+ return effectfulSuffix; >+ >+ return Unexpected<Error>(effectfulSuffix.error()); >+} >+ >+auto Parser::parseLimitedSuffixOperator(UniqueRef<AST::Expression>&& previous) -> SuffixExpression >+{ >+ auto type = consumeTypes({ Lexer::Token::Type::FullStop, Lexer::Token::Type::Arrow, Lexer::Token::Type::LeftSquareBracket }); >+ if (!type) >+ return SuffixExpression(WTFMove(previous), false); >+ >+ switch (type->type) { >+ case Lexer::Token::Type::FullStop: { >+ auto identifier = consumeType(Lexer::Token::Type::Identifier); >+ if (!identifier) >+ return SuffixExpression(WTFMove(previous), false); >+ return SuffixExpression(makeUniqueRef<AST::DotExpression>(WTFMove(*type), WTFMove(previous), identifier->stringView.toString()), true); >+ } >+ case Lexer::Token::Type::Arrow: { >+ auto identifier = consumeType(Lexer::Token::Type::Identifier); >+ if (!identifier) >+ return SuffixExpression(WTFMove(previous), false); >+ return SuffixExpression(makeUniqueRef<AST::DotExpression>(Lexer::Token(*type), makeUniqueRef<AST::DereferenceExpression>(WTFMove(*type), WTFMove(previous)), identifier->stringView.toString()), true); >+ } >+ case Lexer::Token::Type::LeftSquareBracket: { >+ auto expression = parseExpression(); >+ if (!expression) >+ return SuffixExpression(WTFMove(previous), false); >+ if (!consumeType(Lexer::Token::Type::RightSquareBracket)) >+ return SuffixExpression(WTFMove(previous), false); >+ return SuffixExpression(makeUniqueRef<AST::IndexExpression>(WTFMove(*type), WTFMove(previous), WTFMove(*expression)), true); >+ } >+ default: >+ ASSERT_NOT_REACHED(); >+ return SuffixExpression(WTFMove(previous), false); >+ } >+} >+ >+auto Parser::parseSuffixOperator(UniqueRef<AST::Expression>&& previous) -> SuffixExpression >+{ >+ auto suffix = consumeTypes({ Lexer::Token::Type::FullStop, Lexer::Token::Type::Arrow, Lexer::Token::Type::LeftSquareBracket, Lexer::Token::Type::PlusPlus, Lexer::Token::Type::MinusMinus }); >+ if (!suffix) >+ return SuffixExpression(WTFMove(previous), false); >+ >+ switch (suffix->type) { >+ case Lexer::Token::Type::FullStop: { >+ auto identifier = consumeType(Lexer::Token::Type::Identifier); >+ if (!identifier) >+ return SuffixExpression(WTFMove(previous), false); >+ return SuffixExpression(makeUniqueRef<AST::DotExpression>(WTFMove(*suffix), WTFMove(previous), identifier->stringView.toString()), true); >+ } >+ case Lexer::Token::Type::Arrow: { >+ auto identifier = consumeType(Lexer::Token::Type::Identifier); >+ if (!identifier) >+ return SuffixExpression(WTFMove(previous), false); >+ return SuffixExpression(makeUniqueRef<AST::DotExpression>(Lexer::Token(*suffix), makeUniqueRef<AST::DereferenceExpression>(WTFMove(*suffix), WTFMove(previous)), identifier->stringView.toString()), true); >+ } >+ case Lexer::Token::Type::LeftSquareBracket: { >+ auto expression = parseExpression(); >+ if (!expression) >+ return SuffixExpression(WTFMove(previous), false); >+ if (!consumeType(Lexer::Token::Type::RightSquareBracket)) >+ return SuffixExpression(WTFMove(previous), false); >+ return SuffixExpression(makeUniqueRef<AST::IndexExpression>(WTFMove(*suffix), WTFMove(previous), WTFMove(*expression)), true); >+ } >+ case Lexer::Token::Type::PlusPlus: { >+ auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(*suffix), WTFMove(previous)); >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(result->oldVariableReference()); >+ result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(WTFMove(*suffix), String("operator++", String::ConstructFromLiteral), WTFMove(callArguments))); >+ result->setResultExpression(result->oldVariableReference()); >+ return SuffixExpression(WTFMove(result), true); >+ } >+ case Lexer::Token::Type::MinusMinus: { >+ auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(*suffix), WTFMove(previous)); >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(result->oldVariableReference()); >+ result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(WTFMove(*suffix), String("operator--", String::ConstructFromLiteral), WTFMove(callArguments))); >+ result->setResultExpression(result->oldVariableReference()); >+ return SuffixExpression(WTFMove(result), true); >+ } >+ default: >+ ASSERT_NOT_REACHED(); >+ return SuffixExpression(WTFMove(previous), false); >+ } >+} >+ >+auto Parser::parseExpression() -> Expected<UniqueRef<AST::Expression>, Error> { >+ auto origin = peek(); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ auto first = parsePossibleTernaryConditional(); >+ if (!first) >+ return Unexpected<Error>(first.error()); >+ >+ Vector<UniqueRef<AST::Expression>> expressions; >+ expressions.append(WTFMove(*first)); >+ >+ while (tryType(Lexer::Token::Type::Comma)) { >+ auto expression = parsePossibleTernaryConditional(); >+ if (!expression) >+ return Unexpected<Error>(expression.error()); >+ expressions.append(WTFMove(*expression)); >+ } >+ >+ if (expressions.size() == 1) >+ return WTFMove(expressions[0]); >+ return { makeUniqueRef<AST::CommaExpression>(WTFMove(*origin), WTFMove(expressions)) }; >+} >+ >+auto Parser::parseTernaryConditional() -> Expected<UniqueRef<AST::Expression>, Error> { >+ auto origin = peek(); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ auto predicate = parsePossibleLogicalBinaryOperation(); >+ if (!predicate) >+ return Unexpected<Error>(predicate.error()); >+ >+ auto questionMark = consumeType(Lexer::Token::Type::QuestionMark); >+ if (!questionMark) >+ return Unexpected<Error>(questionMark.error()); >+ >+ auto bodyExpression = parseExpression(); >+ if (!bodyExpression) >+ return Unexpected<Error>(bodyExpression.error()); >+ >+ auto colon = consumeType(Lexer::Token::Type::Colon); >+ if (!colon) >+ return Unexpected<Error>(colon.error()); >+ >+ auto elseExpression = parsePossibleTernaryConditional(); >+ if (!elseExpression) >+ return Unexpected<Error>(elseExpression.error()); >+ >+ Vector<UniqueRef<AST::Expression>> castArguments; >+ castArguments.append(WTFMove(*predicate)); >+ auto boolCast = makeUniqueRef<AST::CallExpression>(Lexer::Token(*origin), String("bool", String::ConstructFromLiteral), WTFMove(castArguments)); >+ return { makeUniqueRef<AST::TernaryExpression>(WTFMove(*origin), WTFMove(boolCast), WTFMove(*bodyExpression), WTFMove(*elseExpression)) }; >+} >+ >+auto Parser::parseAssignment() -> Expected<UniqueRef<AST::Expression>, Error> { >+ auto origin = peek(); >+ if (!origin) >+ return Unexpected<Error>(origin.error()); >+ >+ auto left = parsePossiblePrefix(); >+ if (!left) >+ return Unexpected<Error>(left.error()); >+ >+ auto assignmentOperator = consumeTypes({ >+ Lexer::Token::Type::EqualsSign, >+ Lexer::Token::Type::PlusEquals, >+ Lexer::Token::Type::MinusEquals, >+ Lexer::Token::Type::TimesEquals, >+ Lexer::Token::Type::DivideEquals, >+ Lexer::Token::Type::ModEquals, >+ Lexer::Token::Type::XorEquals, >+ Lexer::Token::Type::AndEquals, >+ Lexer::Token::Type::OrEquals, >+ Lexer::Token::Type::RightShiftEquals, >+ Lexer::Token::Type::LeftShiftEquals >+ }); >+ if (!assignmentOperator) >+ return Unexpected<Error>(assignmentOperator.error()); >+ >+ auto right = parsePossibleTernaryConditional(); >+ if (!right) >+ return Unexpected<Error>(right.error()); >+ >+ if (assignmentOperator->type == Lexer::Token::Type::EqualsSign) >+ return { makeUniqueRef<AST::AssignmentExpression>(WTFMove(*origin), WTFMove(*left), WTFMove(*right))} ; >+ >+ String name; >+ switch (assignmentOperator->type) { >+ case Lexer::Token::Type::PlusEquals: >+ name = String("operator+", String::ConstructFromLiteral); >+ break; >+ case Lexer::Token::Type::MinusEquals: >+ name = String("operator-", String::ConstructFromLiteral); >+ break; >+ case Lexer::Token::Type::TimesEquals: >+ name = String("operator*", String::ConstructFromLiteral); >+ break; >+ case Lexer::Token::Type::DivideEquals: >+ name = String("operator/", String::ConstructFromLiteral); >+ break; >+ case Lexer::Token::Type::ModEquals: >+ name = String("operator%", String::ConstructFromLiteral); >+ break; >+ case Lexer::Token::Type::XorEquals: >+ name = String("operator^", String::ConstructFromLiteral); >+ break; >+ case Lexer::Token::Type::AndEquals: >+ name = String("operator&", String::ConstructFromLiteral); >+ break; >+ case Lexer::Token::Type::OrEquals: >+ name = String("operator|", String::ConstructFromLiteral); >+ break; >+ case Lexer::Token::Type::RightShiftEquals: >+ name = String("operator>>", String::ConstructFromLiteral); >+ break; >+ case Lexer::Token::Type::LeftShiftEquals: >+ name = String("operator<<", String::ConstructFromLiteral); >+ break; >+ default: >+ ASSERT_NOT_REACHED(); >+ return Unexpected<Error>(Error(String("Something really bad happened", String::ConstructFromLiteral))); >+ } >+ >+ auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(*origin), WTFMove(*left)); >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(result->oldVariableReference()); >+ callArguments.append(WTFMove(*right)); >+ result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(WTFMove(*origin), WTFMove(name), WTFMove(callArguments))); >+ result->setResultExpression(result->newVariableReference()); >+ return { WTFMove(result) }; >+} >+ >+auto Parser::parsePossibleTernaryConditional() -> Expected<UniqueRef<AST::Expression>, Error> { >+ auto ternaryExpression = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() { >+ return parseTernaryConditional(); >+ }); >+ if (ternaryExpression) >+ return ternaryExpression; >+ >+ auto assignmentExpression = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() { >+ return parseAssignment(); >+ }); >+ if (assignmentExpression) >+ return assignmentExpression; >+ >+ auto binaryOperation = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() { >+ return parsePossibleLogicalBinaryOperation(); >+ }); >+ if (binaryOperation) >+ return binaryOperation; >+ >+ return Unexpected<Error>(binaryOperation.error()); >+} >+ >+auto Parser::parsePossibleLogicalBinaryOperation() -> Expected<UniqueRef<AST::Expression>, Error> { >+ auto parsedPrevious = parsePossibleRelationalBinaryOperation(); >+ if (!parsedPrevious) >+ return Unexpected<Error>(parsedPrevious.error()); >+ UniqueRef<AST::Expression> previous = WTFMove(*parsedPrevious); >+ >+ while (auto logicalBinaryOperation = tryTypes({ >+ Lexer::Token::Type::OrOr, >+ Lexer::Token::Type::AndAnd, >+ Lexer::Token::Type::Or, >+ Lexer::Token::Type::Xor, >+ Lexer::Token::Type::And >+ })) { >+ auto next = parsePossibleRelationalBinaryOperation(); >+ if (!next) >+ return Unexpected<Error>(next.error()); >+ >+ switch (logicalBinaryOperation->type) { >+ case Lexer::Token::Type::OrOr: >+ previous = makeUniqueRef<AST::LogicalExpression>(WTFMove(*logicalBinaryOperation), AST::LogicalExpression::Type::Or, WTFMove(previous), WTFMove(*next)); >+ break; >+ case Lexer::Token::Type::AndAnd: >+ previous = makeUniqueRef<AST::LogicalExpression>(WTFMove(*logicalBinaryOperation), AST::LogicalExpression::Type::And, WTFMove(previous), WTFMove(*next)); >+ break; >+ case Lexer::Token::Type::Or: { >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(WTFMove(previous)); >+ callArguments.append(WTFMove(*next)); >+ previous = makeUniqueRef<AST::CallExpression>(WTFMove(*logicalBinaryOperation), String("operator|", String::ConstructFromLiteral), WTFMove(callArguments)); >+ break; >+ } >+ case Lexer::Token::Type::Xor: { >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(WTFMove(previous)); >+ callArguments.append(WTFMove(*next)); >+ previous = makeUniqueRef<AST::CallExpression>(WTFMove(*logicalBinaryOperation), String("operator^", String::ConstructFromLiteral), WTFMove(callArguments)); >+ break; >+ } >+ case Lexer::Token::Type::And: { >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(WTFMove(previous)); >+ callArguments.append(WTFMove(*next)); >+ previous = makeUniqueRef<AST::CallExpression>(WTFMove(*logicalBinaryOperation), String("operator&", String::ConstructFromLiteral), WTFMove(callArguments)); >+ break; >+ } >+ default: >+ ASSERT_NOT_REACHED(); >+ return Unexpected<Error>(Error(String("Something really bad happened", String::ConstructFromLiteral))); >+ } >+ } >+ >+ return { WTFMove(previous) }; >+} >+ >+auto Parser::parsePossibleRelationalBinaryOperation() -> Expected<UniqueRef<AST::Expression>, Error> { >+ auto parsedPrevious = parsePossibleShift(); >+ if (!parsedPrevious) >+ return Unexpected<Error>(parsedPrevious.error()); >+ UniqueRef<AST::Expression> previous = WTFMove(*parsedPrevious); >+ >+ while (auto relationalBinaryOperation = tryTypes({ >+ Lexer::Token::Type::LessThanSign, >+ Lexer::Token::Type::GreaterThanSign, >+ Lexer::Token::Type::LessThanOrEqualTo, >+ Lexer::Token::Type::GreaterThanOrEqualTo, >+ Lexer::Token::Type::EqualComparison, >+ Lexer::Token::Type::NotEqual >+ })) { >+ auto next = parsePossibleShift(); >+ if (!next) >+ return Unexpected<Error>(next.error()); >+ >+ switch (relationalBinaryOperation->type) { >+ case Lexer::Token::Type::LessThanSign: { >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(WTFMove(previous)); >+ callArguments.append(WTFMove(*next)); >+ previous = makeUniqueRef<AST::CallExpression>(WTFMove(*relationalBinaryOperation), String("operator<", String::ConstructFromLiteral), WTFMove(callArguments)); >+ break; >+ } >+ case Lexer::Token::Type::GreaterThanSign: { >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(WTFMove(previous)); >+ callArguments.append(WTFMove(*next)); >+ previous = makeUniqueRef<AST::CallExpression>(WTFMove(*relationalBinaryOperation), String("operator>", String::ConstructFromLiteral), WTFMove(callArguments)); >+ break; >+ } >+ case Lexer::Token::Type::LessThanOrEqualTo: { >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(WTFMove(previous)); >+ callArguments.append(WTFMove(*next)); >+ previous = makeUniqueRef<AST::CallExpression>(WTFMove(*relationalBinaryOperation), String("operator<=", String::ConstructFromLiteral), WTFMove(callArguments)); >+ break; >+ } >+ case Lexer::Token::Type::GreaterThanOrEqualTo: { >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(WTFMove(previous)); >+ callArguments.append(WTFMove(*next)); >+ previous = makeUniqueRef<AST::CallExpression>(WTFMove(*relationalBinaryOperation), String("operator>=", String::ConstructFromLiteral), WTFMove(callArguments)); >+ break; >+ } >+ case Lexer::Token::Type::EqualComparison: { >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(WTFMove(previous)); >+ callArguments.append(WTFMove(*next)); >+ previous = makeUniqueRef<AST::CallExpression>(WTFMove(*relationalBinaryOperation), String("operator==", String::ConstructFromLiteral), WTFMove(callArguments)); >+ break; >+ } >+ case Lexer::Token::Type::NotEqual: { >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(WTFMove(previous)); >+ callArguments.append(WTFMove(*next)); >+ previous = makeUniqueRef<AST::CallExpression>(Lexer::Token(*relationalBinaryOperation), String("operator==", String::ConstructFromLiteral), WTFMove(callArguments)); >+ previous = makeUniqueRef<AST::LogicalNotExpression>(WTFMove(*relationalBinaryOperation), WTFMove(previous)); >+ break; >+ } >+ default: >+ ASSERT_NOT_REACHED(); >+ return Unexpected<Error>(Error(String("Something really bad happened", String::ConstructFromLiteral))); >+ } >+ } >+ >+ return WTFMove(previous); >+} >+ >+auto Parser::parsePossibleShift() -> Expected<UniqueRef<AST::Expression>, Error> { >+ auto parsedPrevious = parsePossibleAdd(); >+ if (!parsedPrevious) >+ return Unexpected<Error>(parsedPrevious.error()); >+ UniqueRef<AST::Expression> previous = WTFMove(*parsedPrevious); >+ >+ while (auto shift = tryTypes({ >+ Lexer::Token::Type::LeftShift, >+ Lexer::Token::Type::RightShift >+ })) { >+ auto next = parsePossibleAdd(); >+ if (!next) >+ return Unexpected<Error>(next.error()); >+ >+ switch (shift->type) { >+ case Lexer::Token::Type::LeftShift: { >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(WTFMove(previous)); >+ callArguments.append(WTFMove(*next)); >+ previous = makeUniqueRef<AST::CallExpression>(WTFMove(*shift), String("operator<<", String::ConstructFromLiteral), WTFMove(callArguments)); >+ break; >+ } >+ case Lexer::Token::Type::RightShift: { >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(WTFMove(previous)); >+ callArguments.append(WTFMove(*next)); >+ previous = makeUniqueRef<AST::CallExpression>(WTFMove(*shift), String("operator>>", String::ConstructFromLiteral), WTFMove(callArguments)); >+ break; >+ } >+ default: >+ ASSERT_NOT_REACHED(); >+ return Unexpected<Error>(Error(String("Something really bad happened", String::ConstructFromLiteral))); >+ } >+ } >+ >+ return WTFMove(previous); >+} >+ >+auto Parser::parsePossibleAdd() -> Expected<UniqueRef<AST::Expression>, Error> { >+ auto parsedPrevious = parsePossibleMultiply(); >+ if (!parsedPrevious) >+ return Unexpected<Error>(parsedPrevious.error()); >+ UniqueRef<AST::Expression> previous = WTFMove(*parsedPrevious); >+ >+ while (auto add = tryTypes({ >+ Lexer::Token::Type::Plus, >+ Lexer::Token::Type::Minus >+ })) { >+ auto next = parsePossibleMultiply(); >+ if (!next) >+ return Unexpected<Error>(next.error()); >+ >+ switch (add->type) { >+ case Lexer::Token::Type::Plus: { >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(WTFMove(previous)); >+ callArguments.append(WTFMove(*next)); >+ previous = makeUniqueRef<AST::CallExpression>(WTFMove(*add), String("operator+", String::ConstructFromLiteral), WTFMove(callArguments)); >+ break; >+ } >+ case Lexer::Token::Type::Minus: { >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(WTFMove(previous)); >+ callArguments.append(WTFMove(*next)); >+ previous = makeUniqueRef<AST::CallExpression>(WTFMove(*add), String("operator-", String::ConstructFromLiteral), WTFMove(callArguments)); >+ break; >+ } >+ default: >+ ASSERT_NOT_REACHED(); >+ return Unexpected<Error>(Error(String("Something really bad happened", String::ConstructFromLiteral))); >+ } >+ } >+ >+ return WTFMove(previous); >+} >+ >+auto Parser::parsePossibleMultiply() -> Expected<UniqueRef<AST::Expression>, Error> { >+ auto parsedPrevious = parsePossiblePrefix(); >+ if (!parsedPrevious) >+ return Unexpected<Error>(parsedPrevious.error()); >+ UniqueRef<AST::Expression> previous = WTFMove(*parsedPrevious); >+ >+ while (auto multiply = tryTypes({ >+ Lexer::Token::Type::Star, >+ Lexer::Token::Type::Divide, >+ Lexer::Token::Type::Mod >+ })) { >+ auto next = parsePossiblePrefix(); >+ if (!next) >+ return Unexpected<Error>(next.error()); >+ >+ switch (multiply->type) { >+ case Lexer::Token::Type::Star: { >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(WTFMove(previous)); >+ callArguments.append(WTFMove(*next)); >+ previous = makeUniqueRef<AST::CallExpression>(WTFMove(*multiply), String("operator*", String::ConstructFromLiteral), WTFMove(callArguments)); >+ break; >+ } >+ case Lexer::Token::Type::Divide: { >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(WTFMove(previous)); >+ callArguments.append(WTFMove(*next)); >+ previous = makeUniqueRef<AST::CallExpression>(WTFMove(*multiply), String("operator/", String::ConstructFromLiteral), WTFMove(callArguments)); >+ break; >+ } >+ case Lexer::Token::Type::Mod: { >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(WTFMove(previous)); >+ callArguments.append(WTFMove(*next)); >+ previous = makeUniqueRef<AST::CallExpression>(WTFMove(*multiply), String("operator%", String::ConstructFromLiteral), WTFMove(callArguments)); >+ break; >+ } >+ default: >+ ASSERT_NOT_REACHED(); >+ return Unexpected<Error>(Error(String("Something really bad happened", String::ConstructFromLiteral))); >+ } >+ } >+ >+ return WTFMove(previous); >+} >+ >+auto Parser::parsePossiblePrefix() -> Expected<UniqueRef<AST::Expression>, Error> { >+ if (auto prefix = tryTypes({ >+ Lexer::Token::Type::PlusPlus, >+ Lexer::Token::Type::MinusMinus, >+ Lexer::Token::Type::Plus, >+ Lexer::Token::Type::Minus, >+ Lexer::Token::Type::Tilde, >+ Lexer::Token::Type::ExclamationPoint, >+ Lexer::Token::Type::And, >+ Lexer::Token::Type::At, >+ Lexer::Token::Type::Star >+ })) { >+ auto next = parsePossiblePrefix(); >+ if (!next) >+ return Unexpected<Error>(next.error()); >+ >+ switch (prefix->type) { >+ case Lexer::Token::Type::PlusPlus: { >+ auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(*prefix), WTFMove(*next)); >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(result->oldVariableReference()); >+ result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(Lexer::Token(*prefix), String("operator++", String::ConstructFromLiteral), WTFMove(callArguments))); >+ result->setResultExpression(result->newVariableReference()); >+ return { WTFMove(result) }; >+ } >+ case Lexer::Token::Type::MinusMinus: { >+ auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(*prefix), WTFMove(*next)); >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(result->oldVariableReference()); >+ result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(Lexer::Token(*prefix), String("operator--", String::ConstructFromLiteral), WTFMove(callArguments))); >+ result->setResultExpression(result->newVariableReference()); >+ return { WTFMove(result) }; >+ } >+ case Lexer::Token::Type::Plus: { >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(WTFMove(*next)); >+ return { makeUniqueRef<AST::CallExpression>(Lexer::Token(*prefix), String("operator+", String::ConstructFromLiteral), WTFMove(callArguments)) }; >+ } >+ case Lexer::Token::Type::Minus: { >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(WTFMove(*next)); >+ return { makeUniqueRef<AST::CallExpression>(Lexer::Token(*prefix), String("operator-", String::ConstructFromLiteral), WTFMove(callArguments)) }; >+ } >+ case Lexer::Token::Type::Tilde: { >+ Vector<UniqueRef<AST::Expression>> callArguments; >+ callArguments.append(WTFMove(*next)); >+ return { makeUniqueRef<AST::CallExpression>(Lexer::Token(*prefix), String("operator~", String::ConstructFromLiteral), WTFMove(callArguments)) }; >+ } >+ case Lexer::Token::Type::ExclamationPoint: { >+ Vector<UniqueRef<AST::Expression>> castArguments; >+ castArguments.append(WTFMove(*next)); >+ auto boolCast = makeUniqueRef<AST::CallExpression>(Lexer::Token(*prefix), String("bool", String::ConstructFromLiteral), WTFMove(castArguments)); >+ return { makeUniqueRef<AST::LogicalNotExpression>(Lexer::Token(*prefix), WTFMove(boolCast)) }; >+ } >+ case Lexer::Token::Type::And: >+ return { makeUniqueRef<AST::MakePointerExpression>(Lexer::Token(*prefix), WTFMove(*next)) }; >+ case Lexer::Token::Type::At: >+ return { makeUniqueRef<AST::MakeArrayReferenceExpression>(Lexer::Token(*prefix), WTFMove(*next)) }; >+ case Lexer::Token::Type::Star: >+ return { makeUniqueRef<AST::DereferenceExpression>(Lexer::Token(*prefix), WTFMove(*next)) }; >+ default: >+ ASSERT_NOT_REACHED(); >+ return Unexpected<Error>(Error(String("Something really bad happened", String::ConstructFromLiteral))); >+ } >+ } >+ >+ return parsePossibleSuffix(); >+} >+ >+auto Parser::parsePossibleSuffix() -> Expected<UniqueRef<AST::Expression>, Error> { >+ auto suffix = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() -> Expected<UniqueRef<AST::Expression>, Error> { >+ auto expression = parseCallExpression(); >+ if (!expression) >+ return Unexpected<Error>(expression.error()); >+ >+ while (true) { >+ auto result = backtrackingScope<SuffixExpression>([&]() -> SuffixExpression { >+ return parseLimitedSuffixOperator(WTFMove(*expression)); >+ }); >+ expression = WTFMove(result.result); >+ if (!result) >+ break; >+ } >+ return expression; >+ }); >+ if (suffix) >+ return suffix; >+ >+ suffix = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() -> Expected<UniqueRef<AST::Expression>, Error> { >+ auto expression = parseTerm(); >+ if (!expression) >+ return Unexpected<Error>(expression.error()); >+ >+ while (true) { >+ auto result = backtrackingScope<SuffixExpression>([&]() -> SuffixExpression { >+ return parseSuffixOperator(WTFMove(*expression)); >+ }); >+ expression = WTFMove(result.result); >+ if (!result) >+ break; >+ } >+ return expression; >+ }); >+ if (suffix) >+ return suffix; >+ >+ return Unexpected<Error>(suffix.error()); >+} >+ >+auto Parser::parseCallExpression() -> Expected<UniqueRef<AST::Expression>, Error> { >+ auto name = consumeType(Lexer::Token::Type::Identifier); >+ if (!name) >+ return Unexpected<Error>(name.error()); >+ auto callName = name->stringView.toString(); >+ >+ auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis); >+ if (!leftParenthesis) >+ return Unexpected<Error>(leftParenthesis.error()); >+ >+ Vector<UniqueRef<AST::Expression>> arguments; >+ if (tryType(Lexer::Token::Type::RightParenthesis)) >+ return { makeUniqueRef<AST::CallExpression>(WTFMove(*name), WTFMove(callName), WTFMove(arguments)) }; >+ >+ auto firstArgument = parsePossibleTernaryConditional(); >+ if (!firstArgument) >+ return Unexpected<Error>(firstArgument.error()); >+ arguments.append(WTFMove(*firstArgument)); >+ while (tryType(Lexer::Token::Type::Comma)) { >+ auto argument = parsePossibleTernaryConditional(); >+ if (!argument) >+ return Unexpected<Error>(argument.error()); >+ arguments.append(WTFMove(*argument)); >+ } >+ >+ auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); >+ if (!rightParenthesis) >+ return Unexpected<Error>(rightParenthesis.error()); >+ >+ return { makeUniqueRef<AST::CallExpression>(WTFMove(*name), WTFMove(callName), WTFMove(arguments)) }; >+} >+ >+auto Parser::parseTerm() -> Expected<UniqueRef<AST::Expression>, Error> { >+ auto type = consumeTypes({ >+ Lexer::Token::Type::IntLiteral, >+ Lexer::Token::Type::UintLiteral, >+ Lexer::Token::Type::FloatLiteral, >+ Lexer::Token::Type::Null, >+ Lexer::Token::Type::True, >+ Lexer::Token::Type::False, >+ Lexer::Token::Type::Identifier, >+ Lexer::Token::Type::LeftParenthesis >+ }); >+ if (!type) >+ return Unexpected<Error>(type.error()); >+ >+ switch (type->type) { >+ case Lexer::Token::Type::IntLiteral: { >+ auto value = intLiteralToInt(type->stringView); >+ if (!value) >+ return Unexpected<Error>(value.error()); >+ return { makeUniqueRef<AST::IntegerLiteral>(WTFMove(*type), *value) }; >+ } >+ case Lexer::Token::Type::UintLiteral: { >+ auto value = uintLiteralToUint(type->stringView); >+ if (!value) >+ return Unexpected<Error>(value.error()); >+ return { makeUniqueRef<AST::UnsignedIntegerLiteral>(WTFMove(*type), *value) }; >+ } >+ case Lexer::Token::Type::FloatLiteral: { >+ auto value = floatLiteralToFloat(type->stringView); >+ if (!value) >+ return Unexpected<Error>(value.error()); >+ return { makeUniqueRef<AST::FloatLiteral>(WTFMove(*type), *value) }; >+ } >+ case Lexer::Token::Type::Null: >+ return { makeUniqueRef<AST::NullLiteral>(WTFMove(*type)) }; >+ case Lexer::Token::Type::True: >+ return { makeUniqueRef<AST::BooleanLiteral>(WTFMove(*type), true) }; >+ case Lexer::Token::Type::False: >+ return { makeUniqueRef<AST::BooleanLiteral>(WTFMove(*type), false) }; >+ case Lexer::Token::Type::Identifier: { >+ auto name = type->stringView.toString(); >+ return { makeUniqueRef<AST::VariableReference>(WTFMove(*type), WTFMove(name)) }; >+ } >+ case Lexer::Token::Type::LeftParenthesis: { >+ auto expression = parseExpression(); >+ if (!expression) >+ return Unexpected<Error>(expression.error()); >+ >+ auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); >+ if (!rightParenthesis) >+ return Unexpected<Error>(rightParenthesis.error()); >+ >+ return { WTFMove(*expression) }; >+ } >+ default: >+ ASSERT_NOT_REACHED(); >+ return Unexpected<Error>(Error(String("Something really bad happened", String::ConstructFromLiteral))); >+ } >+} >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.h >new file mode 100644 >index 00000000000..07f59f46ce9 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.h >@@ -0,0 +1,237 @@ >+/* >+ * 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 "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 "WHLSLLexer.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 "WHLSLProgram.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" >+#include <wtf/Expected.h> >+#include <wtf/Optional.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+class Parser { >+public: >+ enum class Mode { >+ StandardLibrary, >+ User >+ }; >+ >+ struct Error { >+ Error(String&& error) >+ : error(WTFMove(error)) >+ { >+ } >+ >+ String error; >+ }; >+ >+ Parser(); >+ >+ Optional<Error> parse(Program&, StringView, Mode); >+ >+private: >+ template<typename T> T backtrackingScope(std::function<T()> callback) >+ { >+ auto state = m_lexer.state(); >+ auto result = callback(); >+ if (result) >+ return result; >+ m_lexer.setState(WTFMove(state)); >+ return result; >+ } >+ >+ Unexpected<Error> fail(const String& message); >+ Expected<Lexer::Token, Error> peek(); >+ Optional<Lexer::Token> tryType(Lexer::Token::Type); >+ Optional<Lexer::Token> tryTypes(Vector<Lexer::Token::Type>); >+ Expected<Lexer::Token, Error> consumeType(Lexer::Token::Type); >+ Expected<Lexer::Token, Error> consumeTypes(Vector<Lexer::Token::Type>); >+ >+ Expected<Variant<int, unsigned>, Error> consumeIntegralLiteral(); >+ Expected<unsigned, Error> consumeNonNegativeIntegralLiteral(); >+ Expected<AST::ConstantExpression, Error> parseConstantExpression(); >+ Expected<AST::TypeArgument, Error> parseTypeArgument(); >+ Expected<AST::TypeArguments, Error> parseTypeArguments(); >+ struct TypeSuffixAbbreviated { >+ Lexer::Token token; >+ Optional<unsigned> numElements; >+ }; >+ Expected<TypeSuffixAbbreviated, Error> parseTypeSuffixAbbreviated(); >+ struct TypeSuffixNonAbbreviated { >+ Lexer::Token token; >+ Optional<AST::ReferenceType::AddressSpace> addressSpace; >+ Optional<unsigned> numElements; >+ }; >+ Expected<TypeSuffixNonAbbreviated, Error> parseTypeSuffixNonAbbreviated(); >+ 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(); >+ Expected<AST::SpecializationConstantSemantic, Error> parseSpecializationConstantSemantic(); >+ Expected<AST::StageInOutSemantic, Error> parseStageInOutSemantic(); >+ Expected<AST::Semantic, Error> parseSemantic(); >+ AST::Qualifiers parseQualifiers(); >+ Expected<AST::StructureElement, Error> parseStructureElement(); >+ Expected<AST::StructureDefinition, Error> parseStructureDefinition(); >+ Expected<AST::EnumerationDefinition, Error> parseEnumerationDefinition(); >+ Expected<AST::EnumerationMember, Error> parseEnumerationMember(); >+ Expected<AST::NativeTypeDeclaration, Error> parseNativeTypeDeclaration(); >+ Expected<AST::NumThreadsFunctionAttribute, Error> parseNumThreadsFunctionAttribute(); >+ Expected<AST::AttributeBlock, Error> parseAttributeBlock(); >+ 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(); >+ Expected<AST::FunctionDeclaration, Error> parseFunctionDeclaration(); >+ Expected<AST::FunctionDefinition, Error> parseFunctionDefinition(); >+ Expected<AST::NativeFunctionDeclaration, Error> parseNativeFunctionDeclaration(); >+ >+ Expected<AST::Block, Error> parseBlock(); >+ AST::Block parseBlockBody(Lexer::Token&& origin); >+ Expected<AST::IfStatement, Error> parseIfStatement(); >+ Expected<AST::SwitchStatement, Error> parseSwitchStatement(); >+ Expected<AST::SwitchCase, Error> parseSwitchCase(); >+ Expected<AST::ForLoop, Error> parseForLoop(); >+ Expected<AST::WhileLoop, Error> parseWhileLoop(); >+ Expected<AST::DoWhileLoop, Error> parseDoWhileLoop(); >+ Expected<AST::VariableDeclaration, Error> parseVariableDeclaration(UniqueRef<AST::UnnamedType>&&); >+ Expected<AST::VariableDeclarationsStatement, Error> parseVariableDeclarations(); >+ Expected<UniqueRef<AST::Statement>, Error> parseStatement(); >+ >+ 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(UniqueRef<AST::Expression>&& result, bool success) >+ : result(WTFMove(result)) >+ , success(success) >+ { >+ } >+ >+ UniqueRef<AST::Expression> result; >+ bool success; >+ operator bool() const { return success; } >+ }; >+ SuffixExpression parseLimitedSuffixOperator(UniqueRef<AST::Expression>&&); >+ SuffixExpression parseSuffixOperator(UniqueRef<AST::Expression>&&); >+ >+ 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; >+}; >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp >new file mode 100644 >index 00000000000..460e946fdda >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp >@@ -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. >+ */ >+ >+#if ENABLE(WEBGPU) >+ >+#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 { >+ >+namespace WHLSL { >+ >+Optional<PreparationResult> prepare(StringView source) >+{ >+ Program program; >+ >+ Parser parser; >+ auto standardLibrary = String::fromUTF8(WHLSLStandardLibrary, sizeof(WHLSLStandardLibrary)); >+ bool success = static_cast<bool>(parser.parse(program, standardLibrary, WHLSL::Parser::Mode::StandardLibrary)); >+ if (!success) >+ return WTF::nullopt; >+ success = static_cast<bool>(parser.parse(program, source, WHLSL::Parser::Mode::User)); >+ if (!success) >+ return WTF::nullopt; >+ >+ 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(); >+} >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.h >new file mode 100644 >index 00000000000..094926724f6 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.h >@@ -0,0 +1,50 @@ >+/* >+ * 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 <wtf/Optional.h> >+#include <wtf/text/StringView.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+struct PreparationResult >+{ >+ // Metal shading language code >+ // Mapping of attribute IDs >+ // etc. >+}; >+ >+Optional<PreparationResult> prepare(StringView source); >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLProgram.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLProgram.h >new file mode 100644 >index 00000000000..0d8207db0e0 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLProgram.h >@@ -0,0 +1,113 @@ >+/* >+ * 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 "WHLSLEnumerationDefinition.h" >+#include "WHLSLFunctionDefinition.h" >+#include "WHLSLIntrinsics.h" >+#include "WHLSLNameContext.h" >+#include "WHLSLNativeFunctionDeclaration.h" >+#include "WHLSLNativeTypeDeclaration.h" >+#include "WHLSLStructureDefinition.h" >+#include "WHLSLTypeDefinition.h" >+#include <wtf/Vector.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+class Program { >+public: >+ Program() = default; >+ Program(Program&&) = default; >+ >+ bool append(AST::TypeDefinition&& typeDefinition) >+ { >+ m_typeDefinitions.append(makeUniqueRef<AST::TypeDefinition>(WTFMove(typeDefinition))); >+ return m_nameContext.add(static_cast<AST::TypeDefinition&>(m_typeDefinitions.last())); >+ } >+ >+ bool append(AST::StructureDefinition&& structureDefinition) >+ { >+ m_structureDefinitions.append(makeUniqueRef<AST::StructureDefinition>(WTFMove(structureDefinition))); >+ return m_nameContext.add(static_cast<AST::StructureDefinition&>(m_structureDefinitions.last())); >+ } >+ >+ bool append(AST::EnumerationDefinition&& enumerationDefinition) >+ { >+ m_enumerationDefinitions.append(makeUniqueRef<AST::EnumerationDefinition>(WTFMove(enumerationDefinition))); >+ return m_nameContext.add(static_cast<AST::EnumerationDefinition&>(m_enumerationDefinitions.last())); >+ } >+ >+ bool append(AST::FunctionDefinition&& functionDefinition) >+ { >+ m_functionDefinitions.append(makeUniqueRef<AST::FunctionDefinition>(WTFMove(functionDefinition))); >+ return m_nameContext.add(static_cast<AST::FunctionDefinition&>(m_functionDefinitions.last())); >+ } >+ >+ bool append(AST::NativeFunctionDeclaration&& nativeFunctionDeclaration) >+ { >+ m_nativeFunctionDeclarations.append(makeUniqueRef<AST::NativeFunctionDeclaration>(WTFMove(nativeFunctionDeclaration))); >+ m_intrinsics.add(static_cast<AST::NativeFunctionDeclaration&>(m_nativeFunctionDeclarations.last())); >+ return m_nameContext.add(static_cast<AST::NativeFunctionDeclaration&>(m_nativeFunctionDeclarations.last())); >+ } >+ >+ bool append(AST::NativeTypeDeclaration&& nativeTypeDeclaration) >+ { >+ m_nativeTypeDeclarations.append(makeUniqueRef<AST::NativeTypeDeclaration>(WTFMove(nativeTypeDeclaration))); >+ m_intrinsics.add(static_cast<AST::NativeTypeDeclaration&>(m_nativeTypeDeclarations.last())); >+ return m_nameContext.add(static_cast<AST::NativeTypeDeclaration&>(m_nativeTypeDeclarations.last())); >+ } >+ >+ NameContext& nameContext() { return m_nameContext; } >+ Intrinsics& intrinsics() { return m_intrinsics; } >+ Vector<UniqueRef<AST::TypeDefinition>>& typeDefinitions() { return m_typeDefinitions; } >+ Vector<UniqueRef<AST::StructureDefinition>>& structureDefinitions() { return m_structureDefinitions; } >+ Vector<UniqueRef<AST::EnumerationDefinition>>& enumerationDefinitions() { return m_enumerationDefinitions; } >+ const Vector<UniqueRef<AST::FunctionDefinition>>& functionDefinitions() const { return m_functionDefinitions; } >+ Vector<UniqueRef<AST::FunctionDefinition>>& functionDefinitions() { return m_functionDefinitions; } >+ const Vector<UniqueRef<AST::NativeFunctionDeclaration>>& nativeFunctionDeclarations() const { return m_nativeFunctionDeclarations; } >+ Vector<UniqueRef<AST::NativeFunctionDeclaration>>& nativeFunctionDeclarations() { return m_nativeFunctionDeclarations; } >+ Vector<UniqueRef<AST::NativeTypeDeclaration>>& nativeTypeDeclarations() { return m_nativeTypeDeclarations; } >+ >+private: >+ NameContext m_nameContext; >+ Intrinsics m_intrinsics; >+ Vector<UniqueRef<AST::TypeDefinition>> m_typeDefinitions; >+ Vector<UniqueRef<AST::StructureDefinition>> m_structureDefinitions; >+ Vector<UniqueRef<AST::EnumerationDefinition>> m_enumerationDefinitions; >+ Vector<UniqueRef<AST::FunctionDefinition>> m_functionDefinitions; >+ Vector<UniqueRef<AST::NativeFunctionDeclaration>> m_nativeFunctionDeclarations; >+ Vector<UniqueRef<AST::NativeTypeDeclaration>> m_nativeTypeDeclarations; >+}; >+ >+} >+ >+} >+ >+#endif >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/WHLSLResolveOverloadImpl.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLResolveOverloadImpl.h >new file mode 100644 >index 00000000000..ac7903bafc3 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLResolveOverloadImpl.h >@@ -0,0 +1,53 @@ >+/* >+ * 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 <functional> >+#include <wtf/Vector.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+namespace AST { >+ >+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&); >+ >+} >+ >+} >+ >+#endif >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/WHLSLStandardLibrary.txt b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt >new file mode 100644 >index 00000000000..570747b23b4 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt >@@ -0,0 +1,471 @@ >+// https://github.com/gpuweb/WHLSL/blob/9528f19aaa71fd5c3c706d2873f4b8c8cce857b5/Spec/source/Generate_Standard_Library.js >+// This was autogenerated from Generate_Standard_Library.js! Do not edit!! >+ >+native typedef void; >+native typedef bool; >+native typedef uchar; >+native typedef ushort; >+native typedef uint; >+native typedef char; >+native typedef short; >+native typedef int; >+native typedef half; >+native typedef float; >+native typedef atomic_int; >+native typedef atomic_uint; >+native typedef vector<bool, 2>; >+typedef bool2 = vector<bool, 2>; >+native typedef vector<bool, 3>; >+typedef bool3 = vector<bool, 3>; >+native typedef vector<bool, 4>; >+typedef bool4 = vector<bool, 4>; >+native typedef vector<uchar, 2>; >+typedef uchar2 = vector<uchar, 2>; >+native typedef vector<uchar, 3>; >+typedef uchar3 = vector<uchar, 3>; >+native typedef vector<uchar, 4>; >+typedef uchar4 = vector<uchar, 4>; >+native typedef vector<ushort, 2>; >+typedef ushort2 = vector<ushort, 2>; >+native typedef vector<ushort, 3>; >+typedef ushort3 = vector<ushort, 3>; >+native typedef vector<ushort, 4>; >+typedef ushort4 = vector<ushort, 4>; >+native typedef vector<uint, 2>; >+typedef uint2 = vector<uint, 2>; >+native typedef vector<uint, 3>; >+typedef uint3 = vector<uint, 3>; >+native typedef vector<uint, 4>; >+typedef uint4 = vector<uint, 4>; >+native typedef vector<char, 2>; >+typedef char2 = vector<char, 2>; >+native typedef vector<char, 3>; >+typedef char3 = vector<char, 3>; >+native typedef vector<char, 4>; >+typedef char4 = vector<char, 4>; >+native typedef vector<short, 2>; >+typedef short2 = vector<short, 2>; >+native typedef vector<short, 3>; >+typedef short3 = vector<short, 3>; >+native typedef vector<short, 4>; >+typedef short4 = vector<short, 4>; >+native typedef vector<int, 2>; >+typedef int2 = vector<int, 2>; >+native typedef vector<int, 3>; >+typedef int3 = vector<int, 3>; >+native typedef vector<int, 4>; >+typedef int4 = vector<int, 4>; >+native typedef vector<half, 2>; >+typedef half2 = vector<half, 2>; >+native typedef vector<half, 3>; >+typedef half3 = vector<half, 3>; >+native typedef vector<half, 4>; >+typedef half4 = vector<half, 4>; >+native typedef vector<float, 2>; >+typedef float2 = vector<float, 2>; >+native typedef vector<float, 3>; >+typedef float3 = vector<float, 3>; >+native typedef vector<float, 4>; >+typedef float4 = vector<float, 4>; >+ >+native typedef matrix<half, 2, 2>; >+typedef half2x2 = matrix<half, 2, 2>; >+native typedef matrix<half, 2, 3>; >+typedef half2x3 = matrix<half, 2, 3>; >+native typedef matrix<half, 2, 4>; >+typedef half2x4 = matrix<half, 2, 4>; >+native typedef matrix<half, 3, 2>; >+typedef half3x2 = matrix<half, 3, 2>; >+native typedef matrix<half, 3, 3>; >+typedef half3x3 = matrix<half, 3, 3>; >+native typedef matrix<half, 3, 4>; >+typedef half3x4 = matrix<half, 3, 4>; >+native typedef matrix<half, 4, 2>; >+typedef half4x2 = matrix<half, 4, 2>; >+native typedef matrix<half, 4, 3>; >+typedef half4x3 = matrix<half, 4, 3>; >+native typedef matrix<half, 4, 4>; >+typedef half4x4 = matrix<half, 4, 4>; >+native typedef matrix<float, 2, 2>; >+typedef float2x2 = matrix<float, 2, 2>; >+native typedef matrix<float, 2, 3>; >+typedef float2x3 = matrix<float, 2, 3>; >+native typedef matrix<float, 2, 4>; >+typedef float2x4 = matrix<float, 2, 4>; >+native typedef matrix<float, 3, 2>; >+typedef float3x2 = matrix<float, 3, 2>; >+native typedef matrix<float, 3, 3>; >+typedef float3x3 = matrix<float, 3, 3>; >+native typedef matrix<float, 3, 4>; >+typedef float3x4 = matrix<float, 3, 4>; >+native typedef matrix<float, 4, 2>; >+typedef float4x2 = matrix<float, 4, 2>; >+native typedef matrix<float, 4, 3>; >+typedef float4x3 = matrix<float, 4, 3>; >+native typedef matrix<float, 4, 4>; >+typedef float4x4 = matrix<float, 4, 4>; >+native typedef sampler; >+native typedef Texture1D<uchar>; >+native typedef Texture1D<uchar2>; >+native typedef Texture1D<uchar3>; >+native typedef Texture1D<uchar4>; >+native typedef Texture1D<ushort>; >+native typedef Texture1D<ushort2>; >+native typedef Texture1D<ushort3>; >+native typedef Texture1D<ushort4>; >+native typedef Texture1D<uint>; >+native typedef Texture1D<uint2>; >+native typedef Texture1D<uint3>; >+native typedef Texture1D<uint4>; >+native typedef Texture1D<char>; >+native typedef Texture1D<char2>; >+native typedef Texture1D<char3>; >+native typedef Texture1D<char4>; >+native typedef Texture1D<short>; >+native typedef Texture1D<short2>; >+native typedef Texture1D<short3>; >+native typedef Texture1D<short4>; >+native typedef Texture1D<int>; >+native typedef Texture1D<int2>; >+native typedef Texture1D<int3>; >+native typedef Texture1D<int4>; >+native typedef Texture1D<half>; >+native typedef Texture1D<half2>; >+native typedef Texture1D<half3>; >+native typedef Texture1D<half4>; >+native typedef Texture1D<float>; >+native typedef Texture1D<float2>; >+native typedef Texture1D<float3>; >+native typedef Texture1D<float4>; >+native typedef RWTexture1D<uchar>; >+native typedef RWTexture1D<uchar2>; >+native typedef RWTexture1D<uchar3>; >+native typedef RWTexture1D<uchar4>; >+native typedef RWTexture1D<ushort>; >+native typedef RWTexture1D<ushort2>; >+native typedef RWTexture1D<ushort3>; >+native typedef RWTexture1D<ushort4>; >+native typedef RWTexture1D<uint>; >+native typedef RWTexture1D<uint2>; >+native typedef RWTexture1D<uint3>; >+native typedef RWTexture1D<uint4>; >+native typedef RWTexture1D<char>; >+native typedef RWTexture1D<char2>; >+native typedef RWTexture1D<char3>; >+native typedef RWTexture1D<char4>; >+native typedef RWTexture1D<short>; >+native typedef RWTexture1D<short2>; >+native typedef RWTexture1D<short3>; >+native typedef RWTexture1D<short4>; >+native typedef RWTexture1D<int>; >+native typedef RWTexture1D<int2>; >+native typedef RWTexture1D<int3>; >+native typedef RWTexture1D<int4>; >+native typedef RWTexture1D<half>; >+native typedef RWTexture1D<half2>; >+native typedef RWTexture1D<half3>; >+native typedef RWTexture1D<half4>; >+native typedef RWTexture1D<float>; >+native typedef RWTexture1D<float2>; >+native typedef RWTexture1D<float3>; >+native typedef RWTexture1D<float4>; >+native typedef Texture1DArray<uchar>; >+native typedef Texture1DArray<uchar2>; >+native typedef Texture1DArray<uchar3>; >+native typedef Texture1DArray<uchar4>; >+native typedef Texture1DArray<ushort>; >+native typedef Texture1DArray<ushort2>; >+native typedef Texture1DArray<ushort3>; >+native typedef Texture1DArray<ushort4>; >+native typedef Texture1DArray<uint>; >+native typedef Texture1DArray<uint2>; >+native typedef Texture1DArray<uint3>; >+native typedef Texture1DArray<uint4>; >+native typedef Texture1DArray<char>; >+native typedef Texture1DArray<char2>; >+native typedef Texture1DArray<char3>; >+native typedef Texture1DArray<char4>; >+native typedef Texture1DArray<short>; >+native typedef Texture1DArray<short2>; >+native typedef Texture1DArray<short3>; >+native typedef Texture1DArray<short4>; >+native typedef Texture1DArray<int>; >+native typedef Texture1DArray<int2>; >+native typedef Texture1DArray<int3>; >+native typedef Texture1DArray<int4>; >+native typedef Texture1DArray<half>; >+native typedef Texture1DArray<half2>; >+native typedef Texture1DArray<half3>; >+native typedef Texture1DArray<half4>; >+native typedef Texture1DArray<float>; >+native typedef Texture1DArray<float2>; >+native typedef Texture1DArray<float3>; >+native typedef Texture1DArray<float4>; >+native typedef RWTexture1DArray<uchar>; >+native typedef RWTexture1DArray<uchar2>; >+native typedef RWTexture1DArray<uchar3>; >+native typedef RWTexture1DArray<uchar4>; >+native typedef RWTexture1DArray<ushort>; >+native typedef RWTexture1DArray<ushort2>; >+native typedef RWTexture1DArray<ushort3>; >+native typedef RWTexture1DArray<ushort4>; >+native typedef RWTexture1DArray<uint>; >+native typedef RWTexture1DArray<uint2>; >+native typedef RWTexture1DArray<uint3>; >+native typedef RWTexture1DArray<uint4>; >+native typedef RWTexture1DArray<char>; >+native typedef RWTexture1DArray<char2>; >+native typedef RWTexture1DArray<char3>; >+native typedef RWTexture1DArray<char4>; >+native typedef RWTexture1DArray<short>; >+native typedef RWTexture1DArray<short2>; >+native typedef RWTexture1DArray<short3>; >+native typedef RWTexture1DArray<short4>; >+native typedef RWTexture1DArray<int>; >+native typedef RWTexture1DArray<int2>; >+native typedef RWTexture1DArray<int3>; >+native typedef RWTexture1DArray<int4>; >+native typedef RWTexture1DArray<half>; >+native typedef RWTexture1DArray<half2>; >+native typedef RWTexture1DArray<half3>; >+native typedef RWTexture1DArray<half4>; >+native typedef RWTexture1DArray<float>; >+native typedef RWTexture1DArray<float2>; >+native typedef RWTexture1DArray<float3>; >+native typedef RWTexture1DArray<float4>; >+native typedef Texture2D<uchar>; >+native typedef Texture2D<uchar2>; >+native typedef Texture2D<uchar3>; >+native typedef Texture2D<uchar4>; >+native typedef Texture2D<ushort>; >+native typedef Texture2D<ushort2>; >+native typedef Texture2D<ushort3>; >+native typedef Texture2D<ushort4>; >+native typedef Texture2D<uint>; >+native typedef Texture2D<uint2>; >+native typedef Texture2D<uint3>; >+native typedef Texture2D<uint4>; >+native typedef Texture2D<char>; >+native typedef Texture2D<char2>; >+native typedef Texture2D<char3>; >+native typedef Texture2D<char4>; >+native typedef Texture2D<short>; >+native typedef Texture2D<short2>; >+native typedef Texture2D<short3>; >+native typedef Texture2D<short4>; >+native typedef Texture2D<int>; >+native typedef Texture2D<int2>; >+native typedef Texture2D<int3>; >+native typedef Texture2D<int4>; >+native typedef Texture2D<half>; >+native typedef Texture2D<half2>; >+native typedef Texture2D<half3>; >+native typedef Texture2D<half4>; >+native typedef Texture2D<float>; >+native typedef Texture2D<float2>; >+native typedef Texture2D<float3>; >+native typedef Texture2D<float4>; >+native typedef RWTexture2D<uchar>; >+native typedef RWTexture2D<uchar2>; >+native typedef RWTexture2D<uchar3>; >+native typedef RWTexture2D<uchar4>; >+native typedef RWTexture2D<ushort>; >+native typedef RWTexture2D<ushort2>; >+native typedef RWTexture2D<ushort3>; >+native typedef RWTexture2D<ushort4>; >+native typedef RWTexture2D<uint>; >+native typedef RWTexture2D<uint2>; >+native typedef RWTexture2D<uint3>; >+native typedef RWTexture2D<uint4>; >+native typedef RWTexture2D<char>; >+native typedef RWTexture2D<char2>; >+native typedef RWTexture2D<char3>; >+native typedef RWTexture2D<char4>; >+native typedef RWTexture2D<short>; >+native typedef RWTexture2D<short2>; >+native typedef RWTexture2D<short3>; >+native typedef RWTexture2D<short4>; >+native typedef RWTexture2D<int>; >+native typedef RWTexture2D<int2>; >+native typedef RWTexture2D<int3>; >+native typedef RWTexture2D<int4>; >+native typedef RWTexture2D<half>; >+native typedef RWTexture2D<half2>; >+native typedef RWTexture2D<half3>; >+native typedef RWTexture2D<half4>; >+native typedef RWTexture2D<float>; >+native typedef RWTexture2D<float2>; >+native typedef RWTexture2D<float3>; >+native typedef RWTexture2D<float4>; >+native typedef Texture2DArray<uchar>; >+native typedef Texture2DArray<uchar2>; >+native typedef Texture2DArray<uchar3>; >+native typedef Texture2DArray<uchar4>; >+native typedef Texture2DArray<ushort>; >+native typedef Texture2DArray<ushort2>; >+native typedef Texture2DArray<ushort3>; >+native typedef Texture2DArray<ushort4>; >+native typedef Texture2DArray<uint>; >+native typedef Texture2DArray<uint2>; >+native typedef Texture2DArray<uint3>; >+native typedef Texture2DArray<uint4>; >+native typedef Texture2DArray<char>; >+native typedef Texture2DArray<char2>; >+native typedef Texture2DArray<char3>; >+native typedef Texture2DArray<char4>; >+native typedef Texture2DArray<short>; >+native typedef Texture2DArray<short2>; >+native typedef Texture2DArray<short3>; >+native typedef Texture2DArray<short4>; >+native typedef Texture2DArray<int>; >+native typedef Texture2DArray<int2>; >+native typedef Texture2DArray<int3>; >+native typedef Texture2DArray<int4>; >+native typedef Texture2DArray<half>; >+native typedef Texture2DArray<half2>; >+native typedef Texture2DArray<half3>; >+native typedef Texture2DArray<half4>; >+native typedef Texture2DArray<float>; >+native typedef Texture2DArray<float2>; >+native typedef Texture2DArray<float3>; >+native typedef Texture2DArray<float4>; >+native typedef RWTexture2DArray<uchar>; >+native typedef RWTexture2DArray<uchar2>; >+native typedef RWTexture2DArray<uchar3>; >+native typedef RWTexture2DArray<uchar4>; >+native typedef RWTexture2DArray<ushort>; >+native typedef RWTexture2DArray<ushort2>; >+native typedef RWTexture2DArray<ushort3>; >+native typedef RWTexture2DArray<ushort4>; >+native typedef RWTexture2DArray<uint>; >+native typedef RWTexture2DArray<uint2>; >+native typedef RWTexture2DArray<uint3>; >+native typedef RWTexture2DArray<uint4>; >+native typedef RWTexture2DArray<char>; >+native typedef RWTexture2DArray<char2>; >+native typedef RWTexture2DArray<char3>; >+native typedef RWTexture2DArray<char4>; >+native typedef RWTexture2DArray<short>; >+native typedef RWTexture2DArray<short2>; >+native typedef RWTexture2DArray<short3>; >+native typedef RWTexture2DArray<short4>; >+native typedef RWTexture2DArray<int>; >+native typedef RWTexture2DArray<int2>; >+native typedef RWTexture2DArray<int3>; >+native typedef RWTexture2DArray<int4>; >+native typedef RWTexture2DArray<half>; >+native typedef RWTexture2DArray<half2>; >+native typedef RWTexture2DArray<half3>; >+native typedef RWTexture2DArray<half4>; >+native typedef RWTexture2DArray<float>; >+native typedef RWTexture2DArray<float2>; >+native typedef RWTexture2DArray<float3>; >+native typedef RWTexture2DArray<float4>; >+native typedef Texture3D<uchar>; >+native typedef Texture3D<uchar2>; >+native typedef Texture3D<uchar3>; >+native typedef Texture3D<uchar4>; >+native typedef Texture3D<ushort>; >+native typedef Texture3D<ushort2>; >+native typedef Texture3D<ushort3>; >+native typedef Texture3D<ushort4>; >+native typedef Texture3D<uint>; >+native typedef Texture3D<uint2>; >+native typedef Texture3D<uint3>; >+native typedef Texture3D<uint4>; >+native typedef Texture3D<char>; >+native typedef Texture3D<char2>; >+native typedef Texture3D<char3>; >+native typedef Texture3D<char4>; >+native typedef Texture3D<short>; >+native typedef Texture3D<short2>; >+native typedef Texture3D<short3>; >+native typedef Texture3D<short4>; >+native typedef Texture3D<int>; >+native typedef Texture3D<int2>; >+native typedef Texture3D<int3>; >+native typedef Texture3D<int4>; >+native typedef Texture3D<half>; >+native typedef Texture3D<half2>; >+native typedef Texture3D<half3>; >+native typedef Texture3D<half4>; >+native typedef Texture3D<float>; >+native typedef Texture3D<float2>; >+native typedef Texture3D<float3>; >+native typedef Texture3D<float4>; >+native typedef RWTexture3D<uchar>; >+native typedef RWTexture3D<uchar2>; >+native typedef RWTexture3D<uchar3>; >+native typedef RWTexture3D<uchar4>; >+native typedef RWTexture3D<ushort>; >+native typedef RWTexture3D<ushort2>; >+native typedef RWTexture3D<ushort3>; >+native typedef RWTexture3D<ushort4>; >+native typedef RWTexture3D<uint>; >+native typedef RWTexture3D<uint2>; >+native typedef RWTexture3D<uint3>; >+native typedef RWTexture3D<uint4>; >+native typedef RWTexture3D<char>; >+native typedef RWTexture3D<char2>; >+native typedef RWTexture3D<char3>; >+native typedef RWTexture3D<char4>; >+native typedef RWTexture3D<short>; >+native typedef RWTexture3D<short2>; >+native typedef RWTexture3D<short3>; >+native typedef RWTexture3D<short4>; >+native typedef RWTexture3D<int>; >+native typedef RWTexture3D<int2>; >+native typedef RWTexture3D<int3>; >+native typedef RWTexture3D<int4>; >+native typedef RWTexture3D<half>; >+native typedef RWTexture3D<half2>; >+native typedef RWTexture3D<half3>; >+native typedef RWTexture3D<half4>; >+native typedef RWTexture3D<float>; >+native typedef RWTexture3D<float2>; >+native typedef RWTexture3D<float3>; >+native typedef RWTexture3D<float4>; >+native typedef TextureCube<uchar>; >+native typedef TextureCube<uchar2>; >+native typedef TextureCube<uchar3>; >+native typedef TextureCube<uchar4>; >+native typedef TextureCube<ushort>; >+native typedef TextureCube<ushort2>; >+native typedef TextureCube<ushort3>; >+native typedef TextureCube<ushort4>; >+native typedef TextureCube<uint>; >+native typedef TextureCube<uint2>; >+native typedef TextureCube<uint3>; >+native typedef TextureCube<uint4>; >+native typedef TextureCube<char>; >+native typedef TextureCube<char2>; >+native typedef TextureCube<char3>; >+native typedef TextureCube<char4>; >+native typedef TextureCube<short>; >+native typedef TextureCube<short2>; >+native typedef TextureCube<short3>; >+native typedef TextureCube<short4>; >+native typedef TextureCube<int>; >+native typedef TextureCube<int2>; >+native typedef TextureCube<int3>; >+native typedef TextureCube<int4>; >+native typedef TextureCube<half>; >+native typedef TextureCube<half2>; >+native typedef TextureCube<half3>; >+native typedef TextureCube<half4>; >+native typedef TextureCube<float>; >+native typedef TextureCube<float2>; >+native typedef TextureCube<float3>; >+native typedef TextureCube<float4>; >+native typedef TextureDepth2D<float>; >+native typedef TextureDepth2D<half>; >+native typedef RWTextureDepth2D<float>; >+native typedef RWTextureDepth2D<half>; >+native typedef TextureDepth2DArray<float>; >+native typedef TextureDepth2DArray<half>; >+native typedef RWTextureDepth2DArray<float>; >+native typedef RWTextureDepth2DArray<half>; >+native typedef TextureDepthCube<float>; >+native typedef TextureDepthCube<half>; >+ >+// FIXME: Insert the rest of the standard library once the parser is fast enough >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeArrayOperatorLength.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeArrayOperatorLength.cpp >new file mode 100644 >index 00000000000..613143bd1eb >--- /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() }, String(), WTF::nullopt, WTF::nullopt); >+ 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..37e6c78ca6e >--- /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() }, String(), WTF::nullopt, WTF::nullopt); >+ 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()) }, String(), WTF::nullopt, WTF::nullopt); >+ 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..1ddcfecfc06 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeEnumerationFunctions.cpp >@@ -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. >+ */ >+ >+#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()), static_cast<AST::EnumerationDefinition&>(enumerationDefinition)) }, String(), WTF::nullopt, WTF::nullopt); >+ AST::VariableDeclaration variableDeclaration2(Lexer::Token(enumerationDefinition->origin()), AST::Qualifiers(), { AST::TypeReference::wrap(Lexer::Token(enumerationDefinition->origin()), static_cast<AST::EnumerationDefinition&>(enumerationDefinition)) }, String(), WTF::nullopt, WTF::nullopt); >+ 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)); >+ } >+ >+ if (enumerationDefinition->type()) { >+ // FIXME: Handle a null base type. >+ { >+ AST::VariableDeclaration variableDeclaration(Lexer::Token(enumerationDefinition->origin()), AST::Qualifiers(), { AST::TypeReference::wrap(Lexer::Token(enumerationDefinition->origin()), static_cast<AST::EnumerationDefinition&>(enumerationDefinition)) }, String(), WTF::nullopt, WTF::nullopt); >+ 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()), static_cast<AST::EnumerationDefinition&>(enumerationDefinition)) }, String(), WTF::nullopt, WTF::nullopt); >+ 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(), String(), WTF::nullopt, WTF::nullopt); >+ 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()), static_cast<AST::EnumerationDefinition&>(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..c22d5db0db5 >--- /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()), static_cast<AST::StructureDefinition&>(structureDefinition)) }, String(), WTF::nullopt, WTF::nullopt); >+ 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()), static_cast<AST::StructureDefinition&>(structureDefinition)) }, String(), WTF::nullopt, WTF::nullopt); >+ AST::VariableDeclaration variableDeclaration2(Lexer::Token(structureElement.origin()), AST::Qualifiers(), { structureElement.type().clone() }, String(), WTF::nullopt, WTF::nullopt); >+ 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()), static_cast<AST::StructureDefinition&>(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()), static_cast<AST::StructureDefinition&>(structureDefinition))); >+ AST::VariableDeclaration variableDeclaration(Lexer::Token(structureElement.origin()), AST::Qualifiers(), { WTFMove(argumentType) }, String(), WTF::nullopt, WTF::nullopt); >+ 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..ba6ae53cb7d >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.cpp >@@ -0,0 +1,1033 @@ >+/* >+ * 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(static_cast<AST::TypeDefinition&>(program.typeDefinitions()[i])); >+ for (size_t i = 0; i < program.structureDefinitions().size(); ++i) >+ checkErrorAndVisit(static_cast<AST::StructureDefinition&>(program.structureDefinitions()[i])); >+ for (size_t i = 0; i < program.enumerationDefinitions().size(); ++i) >+ checkErrorAndVisit(static_cast<AST::EnumerationDefinition&>(program.enumerationDefinitions()[i])); >+ for (size_t i = 0; i < program.functionDefinitions().size(); ++i) >+ checkErrorAndVisit(static_cast<AST::FunctionDefinition&>(program.functionDefinitions()[i])); >+ for (size_t i = 0; i < program.nativeFunctionDeclarations().size(); ++i) >+ checkErrorAndVisit(static_cast<AST::NativeFunctionDeclaration&>(program.nativeFunctionDeclarations()[i])); >+ for (size_t i = 0; i < program.nativeTypeDeclarations().size(); ++i) >+ checkErrorAndVisit(static_cast<AST::NativeTypeDeclaration&>(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) >+{ >+ if (enumerationDefinition.type()) >+ checkErrorAndVisit(static_cast<AST::UnnamedType&>(*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(static_cast<AST::Statement&>(*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()); >+ if (readModifyWriteExpression.newValueExpression()) >+ checkErrorAndVisit(*readModifyWriteExpression.newValueExpression()); >+ if (readModifyWriteExpression.resultExpression()) >+ 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 >new file mode 100644 >index 00000000000..85e78ff599e >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.h >@@ -0,0 +1,264 @@ >+/* >+ * 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 "WHLSLFunctionAttribute.h" >+#include "WHLSLSemantic.h" >+#include "WHLSLTypeArgument.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+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; >+ >+} >+ >+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. >+}; >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt >index e7d934ad27f..d40c34f04df 100644 >--- a/Source/WebCore/Sources.txt >+++ b/Source/WebCore/Sources.txt >@@ -304,6 +304,34 @@ Modules/websockets/WorkerThreadableWebSocketChannel.cpp > > 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 de452c062a6..4f056bb1a39 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -6403,9 +6403,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>"; }; >@@ -6415,6 +6426,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>"; }; >@@ -13214,9 +13237,90 @@ > 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>"; }; >+ C21BF6F621CD89B700227979 /* WHLSLBooleanLiteral.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLBooleanLiteral.h; sourceTree = "<group>"; }; >+ C21BF6F721CD89B900227979 /* WHLSLIndexExpression.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLIndexExpression.h; sourceTree = "<group>"; }; >+ C21BF6F821CD89BB00227979 /* WHLSLIntegerLiteral.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLIntegerLiteral.h; sourceTree = "<group>"; }; >+ C21BF6F921CD89BD00227979 /* WHLSLSemantic.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLSemantic.h; sourceTree = "<group>"; }; >+ C21BF6FA21CD89BE00227979 /* WHLSLBaseSemantic.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLBaseSemantic.h; sourceTree = "<group>"; }; >+ C21BF6FB21CD89BE00227979 /* WHLSLDoWhileLoop.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLDoWhileLoop.h; sourceTree = "<group>"; }; >+ C21BF6FC21CD89BF00227979 /* WHLSLValue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLValue.h; sourceTree = "<group>"; }; >+ C21BF6FD21CD89C000227979 /* WHLSLFunctionDeclaration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLFunctionDeclaration.h; sourceTree = "<group>"; }; >+ C21BF6FE21CD89C100227979 /* WHLSLStructureElement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLStructureElement.h; sourceTree = "<group>"; }; >+ C21BF6FF21CD89C200227979 /* WHLSLIfStatement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLIfStatement.h; sourceTree = "<group>"; }; >+ C21BF70021CD89C200227979 /* WHLSLFallthrough.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLFallthrough.h; sourceTree = "<group>"; }; >+ C21BF70121CD89C400227979 /* WHLSLDereferenceExpression.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLDereferenceExpression.h; sourceTree = "<group>"; }; >+ C21BF70221CD89C400227979 /* WHLSLConstantExpressionEnumerationMemberReference.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLConstantExpressionEnumerationMemberReference.h; sourceTree = "<group>"; }; >+ C21BF70321CD89C500227979 /* WHLSLReturn.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLReturn.h; sourceTree = "<group>"; }; >+ C21BF70421CD89C600227979 /* WHLSLWhileLoop.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLWhileLoop.h; sourceTree = "<group>"; }; >+ C21BF70521CD89C700227979 /* WHLSLFunctionAttribute.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLFunctionAttribute.h; sourceTree = "<group>"; }; >+ C21BF70621CD89C700227979 /* WHLSLCommaExpression.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLCommaExpression.h; sourceTree = "<group>"; }; >+ C21BF70721CD89C800227979 /* WHLSLNullLiteral.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLNullLiteral.h; sourceTree = "<group>"; }; >+ C21BF70821CD89C900227979 /* WHLSLResourceSemantic.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLResourceSemantic.h; sourceTree = "<group>"; }; >+ C21BF70921CD89CA00227979 /* WHLSLArrayType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLArrayType.h; sourceTree = "<group>"; }; >+ C21BF70A21CD89CB00227979 /* WHLSLBaseFunctionAttribute.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLBaseFunctionAttribute.h; sourceTree = "<group>"; }; >+ C21BF70B21CD89CC00227979 /* WHLSLQualifier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLQualifier.h; sourceTree = "<group>"; }; >+ 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>"; }; >+ 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>"; }; >+ C21BF71321CD89D200227979 /* WHLSLVariableReference.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLVariableReference.h; sourceTree = "<group>"; }; >+ 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>"; }; >+ 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>"; }; >+ C21BF71B21CD89D900227979 /* WHLSLReadModifyWriteExpression.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLReadModifyWriteExpression.h; sourceTree = "<group>"; }; >+ C21BF71C21CD89DA00227979 /* WHLSLTernaryExpression.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLTernaryExpression.h; sourceTree = "<group>"; }; >+ C21BF71D21CD89DB00227979 /* WHLSLType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLType.h; sourceTree = "<group>"; }; >+ C21BF71E21CD89DC00227979 /* WHLSLBlock.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLBlock.h; sourceTree = "<group>"; }; >+ C21BF71F21CD89DC00227979 /* WHLSLTypeReference.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLTypeReference.h; sourceTree = "<group>"; }; >+ C21BF72021CD89DD00227979 /* WHLSLEnumerationDefinition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLEnumerationDefinition.h; sourceTree = "<group>"; }; >+ C21BF72121CD89DE00227979 /* WHLSLNumThreadsFunctionAttribute.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLNumThreadsFunctionAttribute.h; sourceTree = "<group>"; }; >+ C21BF72221CD89DF00227979 /* WHLSLBuiltInSemantic.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLBuiltInSemantic.h; sourceTree = "<group>"; }; >+ C21BF72321CD89E100227979 /* WHLSLNativeFunctionDeclaration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLNativeFunctionDeclaration.h; sourceTree = "<group>"; }; >+ C21BF72421CD89E100227979 /* WHLSLNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLNode.h; sourceTree = "<group>"; }; >+ C21BF72521CD89E200227979 /* WHLSLArrayReferenceType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLArrayReferenceType.h; sourceTree = "<group>"; }; >+ C21BF72621CD89E300227979 /* WHLSLEnumerationMember.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLEnumerationMember.h; sourceTree = "<group>"; }; >+ C21BF72721CD89E400227979 /* WHLSLStructureDefinition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLStructureDefinition.h; sourceTree = "<group>"; }; >+ C21BF72821CD89E500227979 /* WHLSLEffectfulExpressionStatement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLEffectfulExpressionStatement.h; sourceTree = "<group>"; }; >+ C21BF72921CD89E600227979 /* WHLSLTypeDefinition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLTypeDefinition.h; sourceTree = "<group>"; }; >+ C21BF72A21CD89E700227979 /* WHLSLNativeTypeDeclaration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLNativeTypeDeclaration.h; sourceTree = "<group>"; }; >+ C21BF72B21CD89E800227979 /* WHLSLUnsignedIntegerLiteral.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLUnsignedIntegerLiteral.h; sourceTree = "<group>"; }; >+ C21BF72C21CD89E900227979 /* WHLSLMakePointerExpression.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLMakePointerExpression.h; sourceTree = "<group>"; }; >+ C21BF72D21CD89E900227979 /* WHLSLMakeArrayReferenceExpression.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLMakeArrayReferenceExpression.h; sourceTree = "<group>"; }; >+ C21BF72E21CD89EA00227979 /* WHLSLPropertyAccessExpression.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLPropertyAccessExpression.h; sourceTree = "<group>"; }; >+ C21BF72F21CD89EC00227979 /* WHLSLPointerType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLPointerType.h; sourceTree = "<group>"; }; >+ C21BF73021CD89ED00227979 /* WHLSLAssignmentExpression.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLAssignmentExpression.h; sourceTree = "<group>"; }; >+ C21BF73121CD89EE00227979 /* WHLSLSwitchStatement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLSwitchStatement.h; sourceTree = "<group>"; }; >+ C21BF73221CD89EF00227979 /* WHLSLLogicalExpression.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLLogicalExpression.h; sourceTree = "<group>"; }; >+ C21BF73321CD89F000227979 /* WHLSLConstantExpression.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLConstantExpression.h; sourceTree = "<group>"; }; >+ C21BF73421CD89F100227979 /* WHLSLForLoop.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLForLoop.h; sourceTree = "<group>"; }; >+ C21BF73521CD89F200227979 /* WHLSLFloatLiteral.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLFloatLiteral.h; sourceTree = "<group>"; }; >+ C21BF73621CD89F300227979 /* WHLSLSpecializationConstantSemantic.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLSpecializationConstantSemantic.h; sourceTree = "<group>"; }; >+ C21BF73721CD8A0200227979 /* WHLSLParser.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLParser.cpp; sourceTree = "<group>"; }; >+ C21BF73821CD8A0300227979 /* WHLSLParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLParser.h; sourceTree = "<group>"; }; >+ C21BF73A21CD8D7000227979 /* WHLSLProgram.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLProgram.h; sourceTree = "<group>"; }; >+ C21BF74221CD963B00227979 /* WHLSLStandardLibrary.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WHLSLStandardLibrary.h; path = DerivedSources/WebCore/WHLSLStandardLibrary.h; sourceTree = BUILT_PRODUCTS_DIR; }; >+ C21BF74521CD969800227979 /* WHLSLStandardLibrary.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = WHLSLStandardLibrary.txt; sourceTree = "<group>"; }; > C21DF2E71D9E4E9900F5B24C /* CSSFontVariationValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSFontVariationValue.cpp; sourceTree = "<group>"; }; > C21DF2E81D9E4E9900F5B24C /* CSSFontVariationValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSFontVariationValue.h; sourceTree = "<group>"; }; > C2458E611FE8979E00594759 /* FontCacheCoreText.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FontCacheCoreText.h; sourceTree = "<group>"; }; >@@ -13226,9 +13330,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>"; }; >+ 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>"; }; >@@ -19543,6 +19665,7 @@ > 656580EC09D12B20000E61D7 /* Derived Sources */ = { > isa = PBXGroup; > children = ( >+ C21BF74221CD963B00227979 /* WHLSLStandardLibrary.h */, > 538EC7EA1F96A95B004D22A8 /* unified-sources */, > 9908B0F31BCACFFE00ED0F65 /* ByteLengthQueuingStrategyBuiltins.cpp */, > 9908B0F51BCAD07D00ED0F65 /* ByteLengthQueuingStrategyBuiltins.h */, >@@ -25245,12 +25368,141 @@ > C210E90D21B4BCA400B7F83D /* WHLSL */ = { > isa = PBXGroup; > children = ( >+ C21BF74521CD969800227979 /* WHLSLStandardLibrary.txt */, >+ C21BF6F121CD898D00227979 /* AST */, > C210E91121B4BD1000B7F83D /* WHLSLLexer.cpp */, > C210E91221B4BD1000B7F83D /* WHLSLLexer.h */, >+ C21BF73721CD8A0200227979 /* WHLSLParser.cpp */, >+ C21BF73821CD8A0300227979 /* WHLSLParser.h */, >+ C21BF73A21CD8D7000227979 /* WHLSLProgram.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>"; > }; >+ C21BF6F121CD898D00227979 /* AST */ = { >+ isa = PBXGroup; >+ children = ( >+ C21BF72521CD89E200227979 /* WHLSLArrayReferenceType.h */, >+ C21BF70921CD89CA00227979 /* WHLSLArrayType.h */, >+ C21BF73021CD89ED00227979 /* WHLSLAssignmentExpression.h */, >+ C21BF70A21CD89CB00227979 /* WHLSLBaseFunctionAttribute.h */, >+ C21BF6FA21CD89BE00227979 /* WHLSLBaseSemantic.h */, >+ C21BF71E21CD89DC00227979 /* WHLSLBlock.h */, >+ C21BF6F621CD89B700227979 /* WHLSLBooleanLiteral.h */, >+ C21BF71A21CD89D800227979 /* WHLSLBreak.h */, >+ C21BF72221CD89DF00227979 /* WHLSLBuiltInSemantic.h */, >+ C21BF71621CD89D500227979 /* WHLSLCallExpression.h */, >+ C21BF70621CD89C700227979 /* WHLSLCommaExpression.h */, >+ C21BF73321CD89F000227979 /* WHLSLConstantExpression.h */, >+ C21BF70221CD89C400227979 /* WHLSLConstantExpressionEnumerationMemberReference.h */, >+ C21BF6F521CD89B500227979 /* WHLSLContinue.h */, >+ C21BF70121CD89C400227979 /* WHLSLDereferenceExpression.h */, >+ C21BF71821CD89D700227979 /* WHLSLDotExpression.h */, >+ C21BF6FB21CD89BE00227979 /* WHLSLDoWhileLoop.h */, >+ C21BF72821CD89E500227979 /* WHLSLEffectfulExpressionStatement.h */, >+ C21BF72021CD89DD00227979 /* WHLSLEnumerationDefinition.h */, >+ C21BF72621CD89E300227979 /* WHLSLEnumerationMember.h */, >+ C21BF70C21CD89CC00227979 /* WHLSLExpression.h */, >+ C21BF70021CD89C200227979 /* WHLSLFallthrough.h */, >+ C21BF73521CD89F200227979 /* WHLSLFloatLiteral.h */, >+ C21BF73421CD89F100227979 /* WHLSLForLoop.h */, >+ C21BF70521CD89C700227979 /* WHLSLFunctionAttribute.h */, >+ C21BF6FD21CD89C000227979 /* WHLSLFunctionDeclaration.h */, >+ C21BF6F421CD89B300227979 /* WHLSLFunctionDefinition.h */, >+ C21BF6FF21CD89C200227979 /* WHLSLIfStatement.h */, >+ C21BF6F721CD89B900227979 /* WHLSLIndexExpression.h */, >+ C21BF6F821CD89BB00227979 /* WHLSLIntegerLiteral.h */, >+ C21BF73221CD89EF00227979 /* WHLSLLogicalExpression.h */, >+ C21BF71521CD89D400227979 /* WHLSLLogicalNotExpression.h */, >+ C21BF72D21CD89E900227979 /* WHLSLMakeArrayReferenceExpression.h */, >+ C21BF72C21CD89E900227979 /* WHLSLMakePointerExpression.h */, >+ C21BF72321CD89E100227979 /* WHLSLNativeFunctionDeclaration.h */, >+ C21BF72A21CD89E700227979 /* WHLSLNativeTypeDeclaration.h */, >+ C21BF72421CD89E100227979 /* WHLSLNode.h */, >+ C21BF70721CD89C800227979 /* WHLSLNullLiteral.h */, >+ C21BF72121CD89DE00227979 /* WHLSLNumThreadsFunctionAttribute.h */, >+ C21BF72F21CD89EC00227979 /* WHLSLPointerType.h */, >+ C21BF72E21CD89EA00227979 /* WHLSLPropertyAccessExpression.h */, >+ C21BF70B21CD89CC00227979 /* WHLSLQualifier.h */, >+ C21BF71B21CD89D900227979 /* WHLSLReadModifyWriteExpression.h */, >+ C21BF70D21CD89CD00227979 /* WHLSLReferenceType.h */, >+ C21BF70821CD89C900227979 /* WHLSLResourceSemantic.h */, >+ C21BF70321CD89C500227979 /* WHLSLReturn.h */, >+ C21BF6F921CD89BD00227979 /* WHLSLSemantic.h */, >+ C21BF73621CD89F300227979 /* WHLSLSpecializationConstantSemantic.h */, >+ C21BF70E21CD89CE00227979 /* WHLSLStageInOutSemantic.h */, >+ C21BF71221CD89D100227979 /* WHLSLStatement.h */, >+ C21BF72721CD89E400227979 /* WHLSLStructureDefinition.h */, >+ C21BF6FE21CD89C100227979 /* WHLSLStructureElement.h */, >+ C21BF71921CD89D700227979 /* WHLSLSwitchCase.h */, >+ C21BF73121CD89EE00227979 /* WHLSLSwitchStatement.h */, >+ C21BF71C21CD89DA00227979 /* WHLSLTernaryExpression.h */, >+ C21BF6F321CD89AD00227979 /* WHLSLTrap.h */, >+ C21BF71D21CD89DB00227979 /* WHLSLType.h */, >+ C21BF71121CD89D100227979 /* WHLSLTypeArgument.h */, >+ C21BF72921CD89E600227979 /* WHLSLTypeDefinition.h */, >+ C21BF71F21CD89DC00227979 /* WHLSLTypeReference.h */, >+ C21BF72B21CD89E800227979 /* WHLSLUnsignedIntegerLiteral.h */, >+ C21BF6FC21CD89BF00227979 /* WHLSLValue.h */, >+ C21BF71021CD89D000227979 /* WHLSLVariableDeclaration.h */, >+ C21BF71421CD89D300227979 /* WHLSLVariableDeclarationsStatement.h */, >+ C21BF71321CD89D200227979 /* WHLSLVariableReference.h */, >+ C21BF70421CD89C600227979 /* WHLSLWhileLoop.h */, >+ 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>"; >+ }; > C96F5EBF1B5872260091EA9D /* mediasession */ = { > isa = PBXGroup; > children = (
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