[WHLSL] Add descriptive error messages
authorsbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Jul 2019 19:42:42 +0000 (19:42 +0000)
committersbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Jul 2019 19:42:42 +0000 (19:42 +0000)
https://bugs.webkit.org/show_bug.cgi?id=195682
<rdar://problem/50746322>

Reviewed by Myles C. Maxfield.

This patch adds error messages to the WHLSL compiler. I'm taking a first pass
at having decent error messages everywhere we set an error. However, we will
probably refine these messages to be more accurate and descriptive over time.

Passes that can fail no longer return a boolean. Instead, they return Expected<void, Error>.
From Error, we can generate a descriptive error message. Visitor::setError now
requires an Error as an argument. So anywhere in Visitor that might fail is
now required to provide an error message.

In a follow-up to this, we should actually make our checkFail tests test that
they get the expected error message: https://bugs.webkit.org/show_bug.cgi?id=200049

* Modules/webgpu/WHLSL/AST/WHLSLArrayReferenceType.h:
* Modules/webgpu/WHLSL/AST/WHLSLArrayType.h:
* Modules/webgpu/WHLSL/AST/WHLSLAssignmentExpression.h:
* Modules/webgpu/WHLSL/AST/WHLSLBaseFunctionAttribute.h:
* Modules/webgpu/WHLSL/AST/WHLSLBaseSemantic.h:
* Modules/webgpu/WHLSL/AST/WHLSLBlock.h:
* Modules/webgpu/WHLSL/AST/WHLSLBooleanLiteral.h:
* Modules/webgpu/WHLSL/AST/WHLSLBreak.h:
* Modules/webgpu/WHLSL/AST/WHLSLBuiltInSemantic.h:
* Modules/webgpu/WHLSL/AST/WHLSLCallExpression.h:
* Modules/webgpu/WHLSL/AST/WHLSLCommaExpression.h:
* Modules/webgpu/WHLSL/AST/WHLSLContinue.h:
* Modules/webgpu/WHLSL/AST/WHLSLDereferenceExpression.h:
* Modules/webgpu/WHLSL/AST/WHLSLDoWhileLoop.h:
* Modules/webgpu/WHLSL/AST/WHLSLDotExpression.h:
* Modules/webgpu/WHLSL/AST/WHLSLEffectfulExpressionStatement.h:
* Modules/webgpu/WHLSL/AST/WHLSLEnumerationDefinition.h:
* Modules/webgpu/WHLSL/AST/WHLSLEnumerationMember.h:
* Modules/webgpu/WHLSL/AST/WHLSLEnumerationMemberLiteral.h:
* Modules/webgpu/WHLSL/AST/WHLSLExpression.h:
* Modules/webgpu/WHLSL/AST/WHLSLFallthrough.h:
* Modules/webgpu/WHLSL/AST/WHLSLFloatLiteral.h:
* Modules/webgpu/WHLSL/AST/WHLSLForLoop.h:
* Modules/webgpu/WHLSL/AST/WHLSLFunctionDeclaration.h:
* Modules/webgpu/WHLSL/AST/WHLSLGlobalVariableReference.h:
* Modules/webgpu/WHLSL/AST/WHLSLIfStatement.h:
* Modules/webgpu/WHLSL/AST/WHLSLIndexExpression.h:
* Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.h:
* Modules/webgpu/WHLSL/AST/WHLSLLogicalExpression.h:
* Modules/webgpu/WHLSL/AST/WHLSLLogicalNotExpression.h:
* Modules/webgpu/WHLSL/AST/WHLSLMakeArrayReferenceExpression.h:
* Modules/webgpu/WHLSL/AST/WHLSLMakePointerExpression.h:
* Modules/webgpu/WHLSL/AST/WHLSLNamedType.h:
* Modules/webgpu/WHLSL/AST/WHLSLNativeTypeDeclaration.h:
* Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h:
* Modules/webgpu/WHLSL/AST/WHLSLPointerType.h:
* Modules/webgpu/WHLSL/AST/WHLSLPropertyAccessExpression.h:
* Modules/webgpu/WHLSL/AST/WHLSLQualifier.h:
* Modules/webgpu/WHLSL/AST/WHLSLReadModifyWriteExpression.h:
* Modules/webgpu/WHLSL/AST/WHLSLReferenceType.h:
* Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.h:
* Modules/webgpu/WHLSL/AST/WHLSLReturn.h:
* Modules/webgpu/WHLSL/AST/WHLSLSpecializationConstantSemantic.h:
* Modules/webgpu/WHLSL/AST/WHLSLStageInOutSemantic.h:
* Modules/webgpu/WHLSL/AST/WHLSLStatement.h:
* Modules/webgpu/WHLSL/AST/WHLSLStatementList.h:
* Modules/webgpu/WHLSL/AST/WHLSLStructureDefinition.h:
* Modules/webgpu/WHLSL/AST/WHLSLStructureElement.h:
* Modules/webgpu/WHLSL/AST/WHLSLSwitchCase.h:
* Modules/webgpu/WHLSL/AST/WHLSLSwitchStatement.h:
* Modules/webgpu/WHLSL/AST/WHLSLTernaryExpression.h:
* Modules/webgpu/WHLSL/AST/WHLSLTypeArgument.h:
* Modules/webgpu/WHLSL/AST/WHLSLTypeDefinition.h:
* Modules/webgpu/WHLSL/AST/WHLSLTypeReference.h:
* Modules/webgpu/WHLSL/AST/WHLSLUnnamedType.h:
* Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.h:
* Modules/webgpu/WHLSL/AST/WHLSLVariableDeclaration.h:
* Modules/webgpu/WHLSL/AST/WHLSLVariableDeclarationsStatement.h:
* Modules/webgpu/WHLSL/AST/WHLSLVariableReference.h:
* Modules/webgpu/WHLSL/AST/WHLSLWhileLoop.h:
* Modules/webgpu/WHLSL/WHLSLAutoInitializeVariables.cpp:
(WebCore::WHLSL::AutoInitialize::visit):
(WebCore::WHLSL::autoInitializeVariables):
* Modules/webgpu/WHLSL/WHLSLAutoInitializeVariables.h:
* Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.cpp:
(WebCore::WHLSL::checkDuplicateFunctions):
* Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.h:
* Modules/webgpu/WHLSL/WHLSLCheckTextureReferences.cpp:
(WebCore::WHLSL::TextureReferencesChecker::visit):
(WebCore::WHLSL::checkTextureReferences):
* Modules/webgpu/WHLSL/WHLSLCheckTextureReferences.h:
* Modules/webgpu/WHLSL/WHLSLChecker.cpp:
(WebCore::WHLSL::resolveWithOperatorAnderIndexer):
(WebCore::WHLSL::resolveWithOperatorLength):
(WebCore::WHLSL::resolveWithReferenceComparator):
(WebCore::WHLSL::resolveByInstantiation):
(WebCore::WHLSL::resolveFunction):
(WebCore::WHLSL::checkSemantics):
(WebCore::WHLSL::Checker::assignTypes):
(WebCore::WHLSL::Checker::visit):
(WebCore::WHLSL::Checker::recurseAndGetInfo):
(WebCore::WHLSL::Checker::getInfo):
(WebCore::WHLSL::Checker::finishVisiting):
(WebCore::WHLSL::Checker::recurseAndRequireBoolType):
(WebCore::WHLSL::check):
* Modules/webgpu/WHLSL/WHLSLChecker.h:
* Modules/webgpu/WHLSL/WHLSLCodeLocation.h: Added.
(WebCore::WHLSL::CodeLocation::CodeLocation):
(WebCore::WHLSL::CodeLocation::startOffset const):
(WebCore::WHLSL::CodeLocation::endOffset const):
(WebCore::WHLSL::CodeLocation::operator== const):
(WebCore::WHLSL::CodeLocation::operator!= const):
(WebCore::WHLSL::CodeLocation::operator bool const):
* Modules/webgpu/WHLSL/WHLSLComputeDimensions.cpp:
(WebCore::WHLSL::computeDimensions):
* Modules/webgpu/WHLSL/WHLSLError.h: Added.
(WebCore::WHLSL::Error::Error):
(WebCore::WHLSL::Error::codeLocation const):
(WebCore::WHLSL::Error::message const):
* Modules/webgpu/WHLSL/WHLSLFunctionStageChecker.cpp:
(WebCore::WHLSL::checkFunctionStages):
* Modules/webgpu/WHLSL/WHLSLFunctionStageChecker.h:
* Modules/webgpu/WHLSL/WHLSLGatherEntryPointItems.cpp:
(WebCore::WHLSL::Gatherer::reset):
(WebCore::WHLSL::Gatherer::visit):
(WebCore::WHLSL::gatherEntryPointItems):
* Modules/webgpu/WHLSL/WHLSLGatherEntryPointItems.h:
* Modules/webgpu/WHLSL/WHLSLLexer.cpp:
(WebCore::WHLSL::Lexer::lineAndColumnNumberFromOffset):
(WebCore::WHLSL::Lexer::errorString):
(WebCore::WHLSL::Lexer::lineNumberFromOffset): Deleted.
* Modules/webgpu/WHLSL/WHLSLLexer.h:
(WebCore::WHLSL::CodeLocation::CodeLocation):
(WebCore::WHLSL::Lexer::errorString):
(WebCore::WHLSL::AST::CodeLocation::CodeLocation): Deleted.
(WebCore::WHLSL::AST::CodeLocation::startOffset const): Deleted.
(WebCore::WHLSL::AST::CodeLocation::endOffset const): Deleted.
* Modules/webgpu/WHLSL/WHLSLNameResolver.cpp:
(WebCore::WHLSL::NameResolver::~NameResolver):
(WebCore::WHLSL::NameResolver::visit):
(WebCore::WHLSL::resolveNamesInTypes):
(WebCore::WHLSL::resolveTypeNamesInFunctions):
* Modules/webgpu/WHLSL/WHLSLNameResolver.h:
* Modules/webgpu/WHLSL/WHLSLParser.cpp:
(WebCore::WHLSL::Parser::parse):
(WebCore::WHLSL::intLiteralToInt):
(WebCore::WHLSL::uintLiteralToUint):
(WebCore::WHLSL::floatLiteralToFloat):
(WebCore::WHLSL::recognizeSimpleUnsignedInteger):
(WebCore::WHLSL::Parser::parseTypeArgument):
(WebCore::WHLSL::Parser::parseType):
(WebCore::WHLSL::Parser::parseForLoop):
(WebCore::WHLSL::Parser::parseWhileLoop):
(WebCore::WHLSL::Parser::parseEffectfulExpression):
(WebCore::WHLSL::Parser::parseLimitedSuffixOperator):
(WebCore::WHLSL::Parser::parseSuffixOperator):
(WebCore::WHLSL::Parser::parseExpression):
(WebCore::WHLSL::Parser::completeTernaryConditional):
(WebCore::WHLSL::Parser::completeAssignment):
(WebCore::WHLSL::Parser::completePossibleLogicalBinaryOperation):
(WebCore::WHLSL::Parser::completePossibleRelationalBinaryOperation):
(WebCore::WHLSL::Parser::completePossibleShift):
(WebCore::WHLSL::Parser::completePossibleAdd):
(WebCore::WHLSL::Parser::completePossibleMultiply):
(WebCore::WHLSL::Parser::parsePossiblePrefix):
(WebCore::WHLSL::Parser::parseCallExpression):
* Modules/webgpu/WHLSL/WHLSLParser.h:
(WebCore::WHLSL::Parser::Error::Error): Deleted.
(WebCore::WHLSL::Parser::Error::dump const): Deleted.
* Modules/webgpu/WHLSL/WHLSLPrepare.cpp:
(WebCore::WHLSL::prepareShared):
(WebCore::WHLSL::prepare):
* Modules/webgpu/WHLSL/WHLSLPrepare.h:
* Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp:
(WebCore::WHLSL::setterCall):
(WebCore::WHLSL::getterCall):
(WebCore::WHLSL::modify):
(WebCore::WHLSL::PropertyResolver::visit):
* Modules/webgpu/WHLSL/WHLSLRecursionChecker.cpp:
(WebCore::WHLSL::checkRecursion):
* Modules/webgpu/WHLSL/WHLSLRecursionChecker.h:
* Modules/webgpu/WHLSL/WHLSLRecursiveTypeChecker.cpp:
(WebCore::WHLSL::checkRecursiveTypes):
* Modules/webgpu/WHLSL/WHLSLRecursiveTypeChecker.h:
* Modules/webgpu/WHLSL/WHLSLStandardLibraryUtilities.cpp:
(WebCore::WHLSL::includeStandardLibrary):
* Modules/webgpu/WHLSL/WHLSLStatementBehaviorChecker.cpp:
(WebCore::WHLSL::checkStatementBehavior):
* Modules/webgpu/WHLSL/WHLSLStatementBehaviorChecker.h:
* Modules/webgpu/WHLSL/WHLSLSynthesizeArrayOperatorLength.cpp:
(WebCore::WHLSL::synthesizeArrayOperatorLength):
* Modules/webgpu/WHLSL/WHLSLSynthesizeArrayOperatorLength.h:
* Modules/webgpu/WHLSL/WHLSLSynthesizeConstructors.cpp:
(WebCore::WHLSL::synthesizeConstructors):
* Modules/webgpu/WHLSL/WHLSLSynthesizeConstructors.h:
* Modules/webgpu/WHLSL/WHLSLSynthesizeEnumerationFunctions.cpp:
(WebCore::WHLSL::synthesizeEnumerationFunctions):
* Modules/webgpu/WHLSL/WHLSLSynthesizeEnumerationFunctions.h:
* Modules/webgpu/WHLSL/WHLSLSynthesizeStructureAccessors.cpp:
(WebCore::WHLSL::synthesizeStructureAccessors):
* Modules/webgpu/WHLSL/WHLSLSynthesizeStructureAccessors.h:
* Modules/webgpu/WHLSL/WHLSLVisitor.h:
(WebCore::WHLSL::Visitor::hasError const):
(WebCore::WHLSL::Visitor::expectedError):
(WebCore::WHLSL::Visitor::checkErrorAndVisit):
(WebCore::WHLSL::Visitor::setError):
(WebCore::WHLSL::Visitor::error const): Deleted.
(): Deleted.
* WebCore.xcodeproj/project.pbxproj:
* platform/graphics/gpu/cocoa/GPUComputePipelineMetal.mm:
(WebCore::trySetFunctions):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@247834 268f45cc-cd09-0410-ab3c-d52691b4dbfc

103 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLArrayReferenceType.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLArrayType.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAssignmentExpression.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBaseFunctionAttribute.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBaseSemantic.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBlock.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBooleanLiteral.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBreak.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBuiltInSemantic.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLCallExpression.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLCommaExpression.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLContinue.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDereferenceExpression.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDoWhileLoop.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLDotExpression.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEffectfulExpressionStatement.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEnumerationDefinition.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEnumerationMember.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEnumerationMemberLiteral.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLExpression.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFallthrough.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFloatLiteral.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLForLoop.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLFunctionDeclaration.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLGlobalVariableReference.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIfStatement.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIndexExpression.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLLogicalExpression.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLLogicalNotExpression.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLMakeArrayReferenceExpression.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLMakePointerExpression.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNamedType.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNativeTypeDeclaration.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPointerType.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPropertyAccessExpression.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLQualifier.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReadModifyWriteExpression.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReferenceType.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLReturn.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSpecializationConstantSemantic.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStageInOutSemantic.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStatement.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStatementList.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStructureDefinition.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStructureElement.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSwitchCase.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLSwitchStatement.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTernaryExpression.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeArgument.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeDefinition.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLTypeReference.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnnamedType.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclaration.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclarationsStatement.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableReference.h
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLWhileLoop.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLAutoInitializeVariables.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLAutoInitializeVariables.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLCheckTextureReferences.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLCheckTextureReferences.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLCodeLocation.h [new file with mode: 0644]
Source/WebCore/Modules/webgpu/WHLSL/WHLSLComputeDimensions.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLError.h [new file with mode: 0644]
Source/WebCore/Modules/webgpu/WHLSL/WHLSLFunctionStageChecker.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLFunctionStageChecker.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLGatherEntryPointItems.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLGatherEntryPointItems.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLLexer.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLLexer.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLRecursionChecker.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLRecursionChecker.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLRecursiveTypeChecker.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLRecursiveTypeChecker.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibraryUtilities.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLStatementBehaviorChecker.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLStatementBehaviorChecker.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeArrayOperatorLength.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeArrayOperatorLength.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeConstructors.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeConstructors.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeEnumerationFunctions.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeEnumerationFunctions.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeStructureAccessors.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeStructureAccessors.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.h
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/platform/graphics/gpu/cocoa/GPUComputePipelineMetal.mm

index 03fa1ee..008f8f6 100644 (file)
@@ -1,5 +1,217 @@
 2019-07-25  Saam Barati  <sbarati@apple.com>
 
+        [WHLSL] Add descriptive error messages
+        https://bugs.webkit.org/show_bug.cgi?id=195682
+        <rdar://problem/50746322>
+
+        Reviewed by Myles C. Maxfield.
+
+        This patch adds error messages to the WHLSL compiler. I'm taking a first pass
+        at having decent error messages everywhere we set an error. However, we will
+        probably refine these messages to be more accurate and descriptive over time.
+        
+        Passes that can fail no longer return a boolean. Instead, they return Expected<void, Error>.
+        From Error, we can generate a descriptive error message. Visitor::setError now
+        requires an Error as an argument. So anywhere in Visitor that might fail is
+        now required to provide an error message.
+        
+        In a follow-up to this, we should actually make our checkFail tests test that
+        they get the expected error message: https://bugs.webkit.org/show_bug.cgi?id=200049
+
+        * Modules/webgpu/WHLSL/AST/WHLSLArrayReferenceType.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLArrayType.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLAssignmentExpression.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLBaseFunctionAttribute.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLBaseSemantic.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLBlock.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLBooleanLiteral.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLBreak.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLBuiltInSemantic.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLCallExpression.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLCommaExpression.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLContinue.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLDereferenceExpression.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLDoWhileLoop.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLDotExpression.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLEffectfulExpressionStatement.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLEnumerationDefinition.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLEnumerationMember.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLEnumerationMemberLiteral.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLExpression.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLFallthrough.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLFloatLiteral.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLForLoop.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLFunctionDeclaration.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLGlobalVariableReference.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLIfStatement.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLIndexExpression.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLIntegerLiteral.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLLogicalExpression.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLLogicalNotExpression.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLMakeArrayReferenceExpression.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLMakePointerExpression.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLNamedType.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLNativeTypeDeclaration.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLNullLiteral.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLPointerType.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLPropertyAccessExpression.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLQualifier.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLReadModifyWriteExpression.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLReferenceType.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLReturn.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLSpecializationConstantSemantic.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLStageInOutSemantic.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLStatement.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLStatementList.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLStructureDefinition.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLStructureElement.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLSwitchCase.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLSwitchStatement.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLTernaryExpression.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLTypeArgument.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLTypeDefinition.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLTypeReference.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLUnnamedType.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLUnsignedIntegerLiteral.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLVariableDeclaration.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLVariableDeclarationsStatement.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLVariableReference.h:
+        * Modules/webgpu/WHLSL/AST/WHLSLWhileLoop.h:
+        * Modules/webgpu/WHLSL/WHLSLAutoInitializeVariables.cpp:
+        (WebCore::WHLSL::AutoInitialize::visit):
+        (WebCore::WHLSL::autoInitializeVariables):
+        * Modules/webgpu/WHLSL/WHLSLAutoInitializeVariables.h:
+        * Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.cpp:
+        (WebCore::WHLSL::checkDuplicateFunctions):
+        * Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.h:
+        * Modules/webgpu/WHLSL/WHLSLCheckTextureReferences.cpp:
+        (WebCore::WHLSL::TextureReferencesChecker::visit):
+        (WebCore::WHLSL::checkTextureReferences):
+        * Modules/webgpu/WHLSL/WHLSLCheckTextureReferences.h:
+        * Modules/webgpu/WHLSL/WHLSLChecker.cpp:
+        (WebCore::WHLSL::resolveWithOperatorAnderIndexer):
+        (WebCore::WHLSL::resolveWithOperatorLength):
+        (WebCore::WHLSL::resolveWithReferenceComparator):
+        (WebCore::WHLSL::resolveByInstantiation):
+        (WebCore::WHLSL::resolveFunction):
+        (WebCore::WHLSL::checkSemantics):
+        (WebCore::WHLSL::Checker::assignTypes):
+        (WebCore::WHLSL::Checker::visit):
+        (WebCore::WHLSL::Checker::recurseAndGetInfo):
+        (WebCore::WHLSL::Checker::getInfo):
+        (WebCore::WHLSL::Checker::finishVisiting):
+        (WebCore::WHLSL::Checker::recurseAndRequireBoolType):
+        (WebCore::WHLSL::check):
+        * Modules/webgpu/WHLSL/WHLSLChecker.h:
+        * Modules/webgpu/WHLSL/WHLSLCodeLocation.h: Added.
+        (WebCore::WHLSL::CodeLocation::CodeLocation):
+        (WebCore::WHLSL::CodeLocation::startOffset const):
+        (WebCore::WHLSL::CodeLocation::endOffset const):
+        (WebCore::WHLSL::CodeLocation::operator== const):
+        (WebCore::WHLSL::CodeLocation::operator!= const):
+        (WebCore::WHLSL::CodeLocation::operator bool const):
+        * Modules/webgpu/WHLSL/WHLSLComputeDimensions.cpp:
+        (WebCore::WHLSL::computeDimensions):
+        * Modules/webgpu/WHLSL/WHLSLError.h: Added.
+        (WebCore::WHLSL::Error::Error):
+        (WebCore::WHLSL::Error::codeLocation const):
+        (WebCore::WHLSL::Error::message const):
+        * Modules/webgpu/WHLSL/WHLSLFunctionStageChecker.cpp:
+        (WebCore::WHLSL::checkFunctionStages):
+        * Modules/webgpu/WHLSL/WHLSLFunctionStageChecker.h:
+        * Modules/webgpu/WHLSL/WHLSLGatherEntryPointItems.cpp:
+        (WebCore::WHLSL::Gatherer::reset):
+        (WebCore::WHLSL::Gatherer::visit):
+        (WebCore::WHLSL::gatherEntryPointItems):
+        * Modules/webgpu/WHLSL/WHLSLGatherEntryPointItems.h:
+        * Modules/webgpu/WHLSL/WHLSLLexer.cpp:
+        (WebCore::WHLSL::Lexer::lineAndColumnNumberFromOffset):
+        (WebCore::WHLSL::Lexer::errorString):
+        (WebCore::WHLSL::Lexer::lineNumberFromOffset): Deleted.
+        * Modules/webgpu/WHLSL/WHLSLLexer.h:
+        (WebCore::WHLSL::CodeLocation::CodeLocation):
+        (WebCore::WHLSL::Lexer::errorString):
+        (WebCore::WHLSL::AST::CodeLocation::CodeLocation): Deleted.
+        (WebCore::WHLSL::AST::CodeLocation::startOffset const): Deleted.
+        (WebCore::WHLSL::AST::CodeLocation::endOffset const): Deleted.
+        * Modules/webgpu/WHLSL/WHLSLNameResolver.cpp:
+        (WebCore::WHLSL::NameResolver::~NameResolver):
+        (WebCore::WHLSL::NameResolver::visit):
+        (WebCore::WHLSL::resolveNamesInTypes):
+        (WebCore::WHLSL::resolveTypeNamesInFunctions):
+        * Modules/webgpu/WHLSL/WHLSLNameResolver.h:
+        * Modules/webgpu/WHLSL/WHLSLParser.cpp:
+        (WebCore::WHLSL::Parser::parse):
+        (WebCore::WHLSL::intLiteralToInt):
+        (WebCore::WHLSL::uintLiteralToUint):
+        (WebCore::WHLSL::floatLiteralToFloat):
+        (WebCore::WHLSL::recognizeSimpleUnsignedInteger):
+        (WebCore::WHLSL::Parser::parseTypeArgument):
+        (WebCore::WHLSL::Parser::parseType):
+        (WebCore::WHLSL::Parser::parseForLoop):
+        (WebCore::WHLSL::Parser::parseWhileLoop):
+        (WebCore::WHLSL::Parser::parseEffectfulExpression):
+        (WebCore::WHLSL::Parser::parseLimitedSuffixOperator):
+        (WebCore::WHLSL::Parser::parseSuffixOperator):
+        (WebCore::WHLSL::Parser::parseExpression):
+        (WebCore::WHLSL::Parser::completeTernaryConditional):
+        (WebCore::WHLSL::Parser::completeAssignment):
+        (WebCore::WHLSL::Parser::completePossibleLogicalBinaryOperation):
+        (WebCore::WHLSL::Parser::completePossibleRelationalBinaryOperation):
+        (WebCore::WHLSL::Parser::completePossibleShift):
+        (WebCore::WHLSL::Parser::completePossibleAdd):
+        (WebCore::WHLSL::Parser::completePossibleMultiply):
+        (WebCore::WHLSL::Parser::parsePossiblePrefix):
+        (WebCore::WHLSL::Parser::parseCallExpression):
+        * Modules/webgpu/WHLSL/WHLSLParser.h:
+        (WebCore::WHLSL::Parser::Error::Error): Deleted.
+        (WebCore::WHLSL::Parser::Error::dump const): Deleted.
+        * Modules/webgpu/WHLSL/WHLSLPrepare.cpp:
+        (WebCore::WHLSL::prepareShared):
+        (WebCore::WHLSL::prepare):
+        * Modules/webgpu/WHLSL/WHLSLPrepare.h:
+        * Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp:
+        (WebCore::WHLSL::setterCall):
+        (WebCore::WHLSL::getterCall):
+        (WebCore::WHLSL::modify):
+        (WebCore::WHLSL::PropertyResolver::visit):
+        * Modules/webgpu/WHLSL/WHLSLRecursionChecker.cpp:
+        (WebCore::WHLSL::checkRecursion):
+        * Modules/webgpu/WHLSL/WHLSLRecursionChecker.h:
+        * Modules/webgpu/WHLSL/WHLSLRecursiveTypeChecker.cpp:
+        (WebCore::WHLSL::checkRecursiveTypes):
+        * Modules/webgpu/WHLSL/WHLSLRecursiveTypeChecker.h:
+        * Modules/webgpu/WHLSL/WHLSLStandardLibraryUtilities.cpp:
+        (WebCore::WHLSL::includeStandardLibrary):
+        * Modules/webgpu/WHLSL/WHLSLStatementBehaviorChecker.cpp:
+        (WebCore::WHLSL::checkStatementBehavior):
+        * Modules/webgpu/WHLSL/WHLSLStatementBehaviorChecker.h:
+        * Modules/webgpu/WHLSL/WHLSLSynthesizeArrayOperatorLength.cpp:
+        (WebCore::WHLSL::synthesizeArrayOperatorLength):
+        * Modules/webgpu/WHLSL/WHLSLSynthesizeArrayOperatorLength.h:
+        * Modules/webgpu/WHLSL/WHLSLSynthesizeConstructors.cpp:
+        (WebCore::WHLSL::synthesizeConstructors):
+        * Modules/webgpu/WHLSL/WHLSLSynthesizeConstructors.h:
+        * Modules/webgpu/WHLSL/WHLSLSynthesizeEnumerationFunctions.cpp:
+        (WebCore::WHLSL::synthesizeEnumerationFunctions):
+        * Modules/webgpu/WHLSL/WHLSLSynthesizeEnumerationFunctions.h:
+        * Modules/webgpu/WHLSL/WHLSLSynthesizeStructureAccessors.cpp:
+        (WebCore::WHLSL::synthesizeStructureAccessors):
+        * Modules/webgpu/WHLSL/WHLSLSynthesizeStructureAccessors.h:
+        * Modules/webgpu/WHLSL/WHLSLVisitor.h:
+        (WebCore::WHLSL::Visitor::hasError const):
+        (WebCore::WHLSL::Visitor::expectedError):
+        (WebCore::WHLSL::Visitor::checkErrorAndVisit):
+        (WebCore::WHLSL::Visitor::setError):
+        (WebCore::WHLSL::Visitor::error const): Deleted.
+        (): Deleted.
+        * WebCore.xcodeproj/project.pbxproj:
+        * platform/graphics/gpu/cocoa/GPUComputePipelineMetal.mm:
+        (WebCore::trySetFunctions):
+
+2019-07-25  Saam Barati  <sbarati@apple.com>
+
         [WHLSL] Add optional logging for phase timings
         https://bugs.webkit.org/show_bug.cgi?id=200099
 
index 0722c60..381b086 100644 (file)
@@ -27,7 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include "WHLSLReferenceType.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/UniqueRef.h>
index 42158d7..fc0843e 100644 (file)
@@ -27,7 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include "WHLSLTypeArgument.h"
 #include "WHLSLUnnamedType.h"
 #include <wtf/FastMalloc.h>
index c664867..f7eecea 100644 (file)
@@ -28,7 +28,6 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLExpression.h"
-#include "WHLSLLexer.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/UniqueRef.h>
 
index 7cdaa16..e36acf5 100644 (file)
@@ -27,7 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include <wtf/FastMalloc.h>
 
 namespace WebCore {
index 93a4d97..2018e03 100644 (file)
@@ -27,8 +27,8 @@
 
 #if ENABLE(WEBGPU)
 
+#include "WHLSLCodeLocation.h"
 #include "WHLSLEntryPointType.h"
-#include "WHLSLLexer.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/Optional.h>
 
index ed1c795..26f68d8 100644 (file)
@@ -27,7 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include "WHLSLStatement.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/Vector.h>
index 12f75d0..a386ae1 100644 (file)
@@ -28,7 +28,6 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLExpression.h"
-#include "WHLSLLexer.h"
 #include <wtf/FastMalloc.h>
 
 namespace WebCore {
index c6903ef..3946774 100644 (file)
@@ -27,7 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include "WHLSLStatement.h"
 #include <wtf/FastMalloc.h>
 
index 103edb3..45a2008 100644 (file)
@@ -28,7 +28,7 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLBaseSemantic.h"
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/Optional.h>
 
index 8fd3dd1..3412645 100644 (file)
@@ -29,7 +29,6 @@
 
 #include "WHLSLExpression.h"
 #include "WHLSLFunctionDeclaration.h"
-#include "WHLSLLexer.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/UniqueRef.h>
 
index 59a1079..f94f0de 100644 (file)
@@ -28,7 +28,6 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLExpression.h"
-#include "WHLSLLexer.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/UniqueRef.h>
 #include <wtf/Vector.h>
index 309fc90..d7e33c8 100644 (file)
@@ -27,7 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include "WHLSLStatement.h"
 #include <wtf/FastMalloc.h>
 
index 4018a00..85ca677 100644 (file)
@@ -28,7 +28,6 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLExpression.h"
-#include "WHLSLLexer.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/UniqueRef.h>
 
index 55dc4bd..bd154a3 100644 (file)
@@ -28,7 +28,6 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLExpression.h"
-#include "WHLSLLexer.h"
 #include "WHLSLStatement.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/UniqueRef.h>
index 12c3d98..d06c8e3 100644 (file)
@@ -27,7 +27,6 @@
 
 #if ENABLE(WEBGPU)
 
-#include "WHLSLLexer.h"
 #include "WHLSLPropertyAccessExpression.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/UniqueRef.h>
index 8d379b8..6688e2b 100644 (file)
@@ -28,7 +28,6 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLExpression.h"
-#include "WHLSLLexer.h"
 #include "WHLSLStatement.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/UniqueRef.h>
index f9c7029..954e1a8 100644 (file)
@@ -27,8 +27,8 @@
 
 #if ENABLE(WEBGPU)
 
+#include "WHLSLCodeLocation.h"
 #include "WHLSLEnumerationMember.h"
-#include "WHLSLLexer.h"
 #include "WHLSLNamedType.h"
 #include "WHLSLUnnamedType.h"
 #include <memory>
index 9ffd4b4..b9ffd86 100644 (file)
@@ -27,8 +27,8 @@
 
 #if ENABLE(WEBGPU)
 
+#include "WHLSLCodeLocation.h"
 #include "WHLSLConstantExpression.h"
-#include "WHLSLLexer.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/Optional.h>
 #include <wtf/Vector.h>
index 16f42c3..15bfb79 100644 (file)
@@ -27,7 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/text/WTFString.h>
 
index ec748d9..0bf8cc3 100644 (file)
@@ -28,7 +28,7 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLAddressSpace.h"
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include "WHLSLUnnamedType.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/Optional.h>
index 93c7767..30d7ed4 100644 (file)
@@ -27,7 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include "WHLSLStatement.h"
 #include <wtf/FastMalloc.h>
 
index bdc4738..91d9745 100644 (file)
@@ -29,7 +29,6 @@
 
 #include "WHLSLExpression.h"
 #include "WHLSLFloatLiteralType.h"
-#include "WHLSLLexer.h"
 #include <wtf/FastMalloc.h>
 
 namespace WebCore {
index de117eb..7ea49e1 100644 (file)
@@ -28,7 +28,6 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLExpression.h"
-#include "WHLSLLexer.h"
 #include "WHLSLStatement.h"
 #include "WHLSLVariableDeclarationsStatement.h"
 #include <memory>
index 99ba3f7..00dc020 100644 (file)
@@ -27,9 +27,9 @@
 
 #if ENABLE(WEBGPU)
 
+#include "WHLSLCodeLocation.h"
 #include "WHLSLEntryPointType.h"
 #include "WHLSLFunctionAttribute.h"
-#include "WHLSLLexer.h"
 #include "WHLSLSemantic.h"
 #include "WHLSLUnnamedType.h"
 #include "WHLSLVariableDeclaration.h"
index cdc51f4..0ef6eb9 100644 (file)
@@ -27,7 +27,6 @@
 
 #if ENABLE(WEBGPU)
 
-#include "WHLSLLexer.h"
 #include "WHLSLStructureElement.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/UniqueRef.h>
index fab6e19..1155164 100644 (file)
@@ -28,7 +28,6 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLExpression.h"
-#include "WHLSLLexer.h"
 #include "WHLSLStatement.h"
 #include <memory>
 #include <wtf/FastMalloc.h>
index c4f3d38..dd5c7f5 100644 (file)
@@ -27,7 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include "WHLSLPropertyAccessExpression.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/UniqueRef.h>
index 47a1151..d3fb7f3 100644 (file)
@@ -29,7 +29,6 @@
 
 #include "WHLSLExpression.h"
 #include "WHLSLIntegerLiteralType.h"
-#include "WHLSLLexer.h"
 #include <wtf/FastMalloc.h>
 
 namespace WebCore {
index d8cc39a..25bbfd6 100644 (file)
@@ -28,7 +28,6 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLExpression.h"
-#include "WHLSLLexer.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/UniqueRef.h>
 
index 7fa92d7..727cd2a 100644 (file)
@@ -28,7 +28,6 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLExpression.h"
-#include "WHLSLLexer.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/UniqueRef.h>
 
index 871a5da..fdb98a8 100644 (file)
@@ -28,7 +28,6 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLExpression.h"
-#include "WHLSLLexer.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/UniqueRef.h>
 
index abfe3b6..3259d89 100644 (file)
@@ -27,7 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include "WHLSLType.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/text/WTFString.h>
index 5192960..170b64f 100644 (file)
@@ -27,7 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include "WHLSLNamedType.h"
 #include "WHLSLTypeArgument.h"
 #include "WHLSLTypeReference.h"
index b1ed599..e1c7586 100644 (file)
@@ -28,7 +28,6 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLExpression.h"
-#include "WHLSLLexer.h"
 #include "WHLSLNullLiteralType.h"
 #include <wtf/FastMalloc.h>
 
index 9b5fd5a..803e406 100644 (file)
@@ -27,7 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include "WHLSLReferenceType.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/UniqueRef.h>
index 5dbaffa..3f731c7 100644 (file)
@@ -29,7 +29,6 @@
 
 #include "WHLSLExpression.h"
 #include "WHLSLFunctionDeclaration.h"
-#include "WHLSLLexer.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/UniqueRef.h>
 
index 295d6dd..23460e5 100644 (file)
@@ -27,7 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include "WHLSLType.h"
 #include <wtf/Vector.h>
 #include <wtf/text/WTFString.h>
index 9ed68a4..abb634e 100644 (file)
@@ -28,7 +28,6 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLExpression.h"
-#include "WHLSLLexer.h"
 #include "WHLSLVariableDeclaration.h"
 #include "WHLSLVariableReference.h"
 #include <memory>
index 3bcbc8c..8e78fff 100644 (file)
@@ -28,7 +28,7 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLAddressSpace.h"
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include "WHLSLUnnamedType.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/UniqueRef.h>
index 6feb82f..560232d 100644 (file)
@@ -28,7 +28,7 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLBaseSemantic.h"
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include <wtf/FastMalloc.h>
 
 namespace WebCore {
index 4ab8d21..e5742dc 100644 (file)
@@ -28,7 +28,6 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLExpression.h"
-#include "WHLSLLexer.h"
 #include "WHLSLStatement.h"
 #include <memory>
 #include <wtf/FastMalloc.h>
index 1fdb968..de15a41 100644 (file)
@@ -28,7 +28,7 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLBaseSemantic.h"
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include <wtf/FastMalloc.h>
 
 namespace WebCore {
index b8f1fbf..5a59d42 100644 (file)
@@ -28,7 +28,7 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLBaseSemantic.h"
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include <wtf/FastMalloc.h>
 
 namespace WebCore {
index 48ebb58..06c3ed7 100644 (file)
@@ -27,7 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/UniqueRef.h>
 
index 5d13537..adf8087 100644 (file)
@@ -27,7 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include "WHLSLStatement.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/Vector.h>
index 3797226..d3b63f7 100644 (file)
@@ -27,7 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include "WHLSLNamedType.h"
 #include "WHLSLStructureElement.h"
 #include <wtf/FastMalloc.h>
index bd866ac..e68972f 100644 (file)
@@ -27,7 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include "WHLSLQualifier.h"
 #include "WHLSLSemantic.h"
 #include "WHLSLType.h"
index 6bceca5..0d95021 100644 (file)
@@ -28,8 +28,8 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLBlock.h"
+#include "WHLSLCodeLocation.h"
 #include "WHLSLConstantExpression.h"
-#include "WHLSLLexer.h"
 #include "WHLSLStatement.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/Optional.h>
index 659f279..1fd1a92 100644 (file)
@@ -28,7 +28,6 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLExpression.h"
-#include "WHLSLLexer.h"
 #include "WHLSLStatement.h"
 #include "WHLSLSwitchCase.h"
 #include <wtf/FastMalloc.h>
index b42ec74..ef79fd3 100644 (file)
@@ -28,7 +28,6 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLExpression.h"
-#include "WHLSLLexer.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/UniqueRef.h>
 
index 0e6709d..7eee238 100644 (file)
@@ -28,7 +28,6 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLConstantExpression.h"
-#include "WHLSLLexer.h"
 #include <wtf/UniqueRef.h>
 #include <wtf/Variant.h>
 #include <wtf/Vector.h>
index 8da870f..b8347d4 100644 (file)
@@ -27,7 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include "WHLSLNamedType.h"
 #include "WHLSLUnnamedType.h"
 #include <wtf/FastMalloc.h>
index 2930fc2..a84451c 100644 (file)
@@ -27,7 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include "WHLSLNamedType.h"
 #include "WHLSLTypeArgument.h"
 #include "WHLSLUnnamedType.h"
index 8022fc1..1360ae6 100644 (file)
@@ -27,7 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include "WHLSLType.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/UniqueRef.h>
index e1d39dd..c0681f4 100644 (file)
@@ -28,7 +28,6 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLExpression.h"
-#include "WHLSLLexer.h"
 #include "WHLSLUnsignedIntegerLiteralType.h"
 #include <wtf/FastMalloc.h>
 
index ffa4f3e..e98980f 100644 (file)
@@ -28,7 +28,6 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLExpression.h"
-#include "WHLSLLexer.h"
 #include "WHLSLQualifier.h"
 #include "WHLSLSemantic.h"
 #include "WHLSLType.h"
index b7b3dd0..e1b8ca5 100644 (file)
@@ -27,7 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
-#include "WHLSLLexer.h"
+#include "WHLSLCodeLocation.h"
 #include "WHLSLStatement.h"
 #include "WHLSLVariableDeclaration.h"
 #include <wtf/FastMalloc.h>
index e01411b..cb2e984 100644 (file)
@@ -28,7 +28,6 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLExpression.h"
-#include "WHLSLLexer.h"
 #include "WHLSLVariableDeclaration.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/text/WTFString.h>
index eaa655f..758088f 100644 (file)
@@ -28,7 +28,6 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLExpression.h"
-#include "WHLSLLexer.h"
 #include "WHLSLStatement.h"
 #include <wtf/FastMalloc.h>
 #include <wtf/UniqueRef.h>
index 7c76f02..6bbef36 100644 (file)
@@ -76,7 +76,7 @@ private:
         Vector<std::reference_wrapper<ResolvingType>> argumentTypes;
         auto* function = resolveFunctionOverload(m_castFunctions, argumentTypes, type);
         if (!function) {
-            setError();
+            setError(Error("Cannot find the default constructor for variable.", variableDeclaration.codeLocation()));
             return;
         }
         callExpression->setFunction(*function);
@@ -88,11 +88,11 @@ private:
     Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>& m_castFunctions;
 };
 
-bool autoInitializeVariables(Program& program)
+Expected<void, Error> autoInitializeVariables(Program& program)
 {
     AutoInitialize autoInitialize(program.nameContext());
     autoInitialize.Visitor::visit(program);
-    return !autoInitialize.error();
+    return autoInitialize.result();
 }
 
 } // namespace WHLSL
index 29aabb0..2867789 100644 (file)
 
 #if ENABLE(WEBGPU)
 
+#include "WHLSLError.h"
+#include <wtf/Expected.h>
+
 namespace WebCore {
 
 namespace WHLSL {
 
 class Program;
 
-bool autoInitializeVariables(Program&);
+Expected<void, Error> autoInitializeVariables(Program&);
 
 }
 
index 7c6db8b..6ff8685 100644 (file)
@@ -115,9 +115,9 @@ private:
     const AST::FunctionDeclaration* m_function { nullptr };
 };
 
-bool checkDuplicateFunctions(const Program& program)
+Expected<void, Error> checkDuplicateFunctions(const Program& program)
 {
-    auto passesStaticChecks = [&] (const AST::FunctionDeclaration& function) {
+    auto passesStaticChecks = [&] (const AST::FunctionDeclaration& function) -> Expected<void, Error> {
         if (function.name() == "operator&[]" && function.parameters().size() == 2
             && is<AST::ArrayReferenceType>(static_cast<const AST::UnnamedType&>(*function.parameters()[0]->type()))) {
             auto& type = static_cast<const AST::UnnamedType&>(*function.parameters()[1]->type());
@@ -127,44 +127,45 @@ bool checkDuplicateFunctions(const Program& program)
                     if (is<AST::NativeTypeDeclaration>(*resolvedType)) {
                         auto& nativeTypeDeclaration = downcast<AST::NativeTypeDeclaration>(*resolvedType);
                         if (nativeTypeDeclaration.name() == "uint")
-                            return false;
+                            return makeUnexpected(Error("Cannot define array reference ander."));
                     }
                 }
             }
         } else if (function.name() == "operator.length" && function.parameters().size() == 1
             && (is<AST::ArrayReferenceType>(static_cast<const AST::UnnamedType&>(*function.parameters()[0]->type()))
             || is<AST::ArrayType>(static_cast<const AST::UnnamedType&>(*function.parameters()[0]->type()))))
-            return false;
+            return makeUnexpected(Error("Cannot define operator.length for an array."));
         else if (function.name() == "operator=="
             && function.parameters().size() == 2
             && is<AST::ReferenceType>(static_cast<const AST::UnnamedType&>(*function.parameters()[0]->type()))
             && is<AST::ReferenceType>(static_cast<const AST::UnnamedType&>(*function.parameters()[1]->type()))
             && matches(*function.parameters()[0]->type(), *function.parameters()[1]->type()))
-            return false;
+            return makeUnexpected(Error("Cannot define operator== on two reference types."));
         else if (function.isCast() && function.parameters().isEmpty()) {
             auto& unifyNode = function.type().unifyNode();
             if (is<AST::NamedType>(unifyNode) && is<AST::NativeTypeDeclaration>(downcast<AST::NamedType>(unifyNode))) {
                 auto& nativeTypeDeclaration = downcast<AST::NativeTypeDeclaration>(downcast<AST::NamedType>(unifyNode));
                 if (nativeTypeDeclaration.isOpaqueType())
-                    return false;
+                    return makeUnexpected(Error("Cannot define a cast on an opaque type."));
             }
         }
 
-        return true;
+        return { };
     };
 
     HashSet<DuplicateFunctionKey, DuplicateFunctionKey::Hash, DuplicateFunctionKey::Traits> functions;
 
-    auto add = [&] (const AST::FunctionDeclaration& function) {
+    auto add = [&] (const AST::FunctionDeclaration& function) -> Expected<void, Error> {
         auto addResult = functions.add(DuplicateFunctionKey { function });
         if (!addResult.isNewEntry)
-            return false;
+            return makeUnexpected(Error("Found duplicate function"));
         return passesStaticChecks(function);
     };
 
     for (auto& functionDefinition : program.functionDefinitions()) {
-        if (!add(functionDefinition.get()))
-            return false;
+        auto addResult = add(functionDefinition.get());
+        if (!addResult)
+            return addResult;
     }
 
     for (auto& nativeFunctionDeclaration : program.nativeFunctionDeclarations()) {
@@ -180,10 +181,10 @@ bool checkDuplicateFunctions(const Program& program)
         // https://bugs.webkit.org/show_bug.cgi?id=198861
         // ASSERT(passesStaticChecks(nativeFunctionDeclaration.get()));
         if (functions.contains(DuplicateFunctionKey { nativeFunctionDeclaration.get() }))
-            return false;
+            return makeUnexpected(Error("Duplicate native function."));
     }
 
-    return true;
+    return { };
 }
 
 } // namespace WHLSL
index c1caf55..20f258b 100644 (file)
 
 #if ENABLE(WEBGPU)
 
+#include "WHLSLError.h"
 #include "WHLSLProgram.h"
+#include <wtf/Expected.h>
 
 namespace WebCore {
 
 namespace WHLSL {
 
-bool checkDuplicateFunctions(const Program&);
+Expected<void, Error> checkDuplicateFunctions(const Program&);
 
 }
 
index 7386b10..cc0abd5 100644 (file)
@@ -84,28 +84,28 @@ bool TextureReferencesChecker::containsTextureOrSampler(AST::UnnamedType& unname
 void TextureReferencesChecker::visit(AST::PointerType& pointerType)
 {
     Visitor::visit(pointerType);
-    if (error())
+    if (hasError())
         return;
     if (containsTextureOrSampler(pointerType.elementType()))
-        setError();
+        setError(Error("Cannot have a pointer to a texture or sampler.", pointerType.codeLocation()));
 }
 
 void TextureReferencesChecker::visit(AST::ArrayReferenceType& arrayReferenceType)
 {
     Visitor::visit(arrayReferenceType);
-    if (error())
+    if (hasError())
         return;
     if (containsTextureOrSampler(arrayReferenceType.elementType()))
-        setError();
+        setError(Error("Cannot have an array reference to a texture or sampler.", arrayReferenceType.codeLocation()));
 }
 
 void TextureReferencesChecker::visit(AST::ArrayType& arrayType)
 {
     Visitor::visit(arrayType);
-    if (error())
+    if (hasError())
         return;
     if (containsTextureOrSampler(arrayType.type()))
-        setError();
+        setError(Error("Cannot have an array of textures or samplers.", arrayType.codeLocation()));
 }
 
 void TextureReferencesChecker::visit(AST::Expression& expression)
@@ -114,11 +114,11 @@ void TextureReferencesChecker::visit(AST::Expression& expression)
     checkErrorAndVisit(expression.resolvedType());
 }
 
-bool checkTextureReferences(Program& program)
+Expected<void, Error> checkTextureReferences(Program& program)
 {
     TextureReferencesChecker textureReferencesChecker;
     textureReferencesChecker.checkErrorAndVisit(program);
-    return !textureReferencesChecker.error();
+    return textureReferencesChecker.result();
 }
 
 } // namespace WHLSL
index 5327fab..a432661 100644 (file)
 
 #if ENABLE(WEBGPU)
 
+#include "WHLSLError.h"
+#include <wtf/Expected.h>
+
 namespace WebCore {
 
 namespace WHLSL {
 
 class Program;
 
-bool checkTextureReferences(Program&);
+Expected<void, Error> checkTextureReferences(Program&);
 
 }
 
index 3d21a7c..32c9661 100644 (file)
@@ -84,7 +84,7 @@ public:
         if (!nativeTypeDeclaration.isNumber()
             && !nativeTypeDeclaration.isVector()
             && !nativeTypeDeclaration.isMatrix())
-            setError();
+            setError(Error("Use of native type is not a POD in entrypoint semantic.", nativeTypeDeclaration.codeLocation()));
     }
 
     void visit(AST::StructureDefinition& structureDefinition) override
@@ -102,14 +102,14 @@ public:
         Visitor::visit(arrayType);
     }
 
-    void visit(AST::PointerType&) override
+    void visit(AST::PointerType& pointerType) override
     {
-        setError();
+        setError(Error("Illegal use of pointer in entrypoint semantic.", pointerType.codeLocation()));
     }
 
-    void visit(AST::ArrayReferenceType&) override
+    void visit(AST::ArrayReferenceType& arrayReferenceType) override
     {
-        setError();
+        setError(Error("Illegal use of array reference in entrypoint semantic.", arrayReferenceType.codeLocation()));
     }
 
     void visit(AST::TypeReference& typeReference) override
@@ -118,7 +118,7 @@ public:
     }
 };
 
-static AST::NativeFunctionDeclaration resolveWithOperatorAnderIndexer(AST::CodeLocation location, AST::ArrayReferenceType& firstArgument, const Intrinsics& intrinsics)
+static AST::NativeFunctionDeclaration resolveWithOperatorAnderIndexer(CodeLocation location, AST::ArrayReferenceType& firstArgument, const Intrinsics& intrinsics)
 {
     const bool isOperator = true;
     auto returnType = makeUniqueRef<AST::PointerType>(location, firstArgument.addressSpace(), firstArgument.elementType().clone());
@@ -128,7 +128,7 @@ static AST::NativeFunctionDeclaration resolveWithOperatorAnderIndexer(AST::CodeL
     return AST::NativeFunctionDeclaration(AST::FunctionDeclaration(location, AST::AttributeBlock(), WTF::nullopt, WTFMove(returnType), String("operator&[]", String::ConstructFromLiteral), WTFMove(parameters), nullptr, isOperator));
 }
 
-static AST::NativeFunctionDeclaration resolveWithOperatorLength(AST::CodeLocation location, AST::UnnamedType& firstArgument, const Intrinsics& intrinsics)
+static AST::NativeFunctionDeclaration resolveWithOperatorLength(CodeLocation location, AST::UnnamedType& firstArgument, const Intrinsics& intrinsics)
 {
     const bool isOperator = true;
     auto returnType = AST::TypeReference::wrap(location, intrinsics.uintType());
@@ -137,7 +137,7 @@ static AST::NativeFunctionDeclaration resolveWithOperatorLength(AST::CodeLocatio
     return AST::NativeFunctionDeclaration(AST::FunctionDeclaration(location, AST::AttributeBlock(), WTF::nullopt, WTFMove(returnType), String("operator.length", String::ConstructFromLiteral), WTFMove(parameters), nullptr, isOperator));
 }
 
-static AST::NativeFunctionDeclaration resolveWithReferenceComparator(AST::CodeLocation location, ResolvingType& firstArgument, ResolvingType& secondArgument, const Intrinsics& intrinsics)
+static AST::NativeFunctionDeclaration resolveWithReferenceComparator(CodeLocation location, ResolvingType& firstArgument, ResolvingType& secondArgument, const Intrinsics& intrinsics)
 {
     const bool isOperator = true;
     auto returnType = AST::TypeReference::wrap(location, intrinsics.boolType());
@@ -165,7 +165,7 @@ enum class Acceptability {
     No
 };
 
-static Optional<AST::NativeFunctionDeclaration> resolveByInstantiation(const String& name, AST::CodeLocation location, const Vector<std::reference_wrapper<ResolvingType>>& types, const Intrinsics& intrinsics)
+static Optional<AST::NativeFunctionDeclaration> resolveByInstantiation(const String& name, CodeLocation location, const Vector<std::reference_wrapper<ResolvingType>>& types, const Intrinsics& intrinsics)
 {
     if (name == "operator&[]" && types.size() == 2) {
         auto* firstArgumentArrayRef = types[0].get().visit(WTF::makeVisitor([](UniqueRef<AST::UnnamedType>& unnamedType) -> AST::ArrayReferenceType* {
@@ -217,7 +217,7 @@ static Optional<AST::NativeFunctionDeclaration> resolveByInstantiation(const Str
     return WTF::nullopt;
 }
 
-static AST::FunctionDeclaration* resolveFunction(Program& program, Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>* possibleOverloads, Vector<std::reference_wrapper<ResolvingType>>& types, const String& name, AST::CodeLocation location, const Intrinsics& intrinsics, AST::NamedType* castReturnType = nullptr)
+static AST::FunctionDeclaration* resolveFunction(Program& program, Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>* possibleOverloads, Vector<std::reference_wrapper<ResolvingType>>& types, const String& name, CodeLocation location, const Intrinsics& intrinsics, AST::NamedType* castReturnType = nullptr)
 {
     if (possibleOverloads) {
         if (AST::FunctionDeclaration* function = resolveFunctionOverload(*possibleOverloads, types, castReturnType))
@@ -296,7 +296,7 @@ static bool checkSemantics(Vector<EntryPointItem>& inputItems, Vector<EntryPoint
                     podChecker.checkErrorAndVisit(downcast<AST::ArrayType>(*item.unnamedType).type());
                 else
                     continue;
-                if (podChecker.error())
+                if (podChecker.hasError())
                     return false;
             }
             return true;
@@ -460,7 +460,7 @@ public:
 
     void visit(Program&) override;
 
-    bool assignTypes();
+    Expected<void, Error> assignTypes();
 
 private:
     bool checkShaderType(const AST::FunctionDefinition&);
@@ -538,7 +538,7 @@ void Checker::visit(Program& program)
         checkErrorAndVisit(program.nativeFunctionDeclarations()[i]);
 }
 
-bool Checker::assignTypes()
+Expected<void, Error> Checker::assignTypes()
 {
     for (auto& keyValuePair : m_typeMap) {
         auto success = keyValuePair.value->visit(WTF::makeVisitor([&](UniqueRef<AST::UnnamedType>& unnamedType) -> bool {
@@ -553,10 +553,10 @@ bool Checker::assignTypes()
             return true;
         }));
         if (!success)
-            return false;
+            return makeUnexpected(Error("Could not resolve the type of a constant."));
     }
 
-    return true;
+    return { };
 }
 
 bool Checker::checkShaderType(const AST::FunctionDefinition& functionDefinition)
@@ -576,21 +576,21 @@ void Checker::visit(AST::FunctionDefinition& functionDefinition)
     m_currentFunction = &functionDefinition;
     if (functionDefinition.entryPointType()) {
         if (!checkShaderType(functionDefinition)) {
-            setError();
+            setError(Error("Duplicate entrypoint function.", functionDefinition.codeLocation()));
             return;
         }
         auto entryPointItems = gatherEntryPointItems(m_intrinsics, functionDefinition);
         if (!entryPointItems) {
-            setError();
+            setError(entryPointItems.error());
             return;
         }
         if (!checkSemantics(entryPointItems->inputs, entryPointItems->outputs, functionDefinition.entryPointType(), m_intrinsics)) {
-            setError();
+            setError(Error("Bad semantics for entrypoint.", functionDefinition.codeLocation()));
             return;
         }
     }
     if (!checkOperatorOverload(functionDefinition, m_intrinsics, m_program.nameContext())) {
-        setError();
+        setError(Error("Operator does not match expected signature.", functionDefinition.codeLocation()));
         return;
     }
 
@@ -656,7 +656,7 @@ void Checker::visit(AST::EnumerationDefinition& enumerationDefinition)
         return &nativeTypeDeclaration;
     })();
     if (!baseType) {
-        setError();
+        setError(Error("Invalid base type for enum.", enumerationDefinition.codeLocation()));
         return;
     }
 
@@ -666,12 +666,12 @@ void Checker::visit(AST::EnumerationDefinition& enumerationDefinition)
         int64_t value = member.get().value();
         if (isSigned) {
             if (static_cast<int64_t>(static_cast<int32_t>(value)) != value) {
-                setError();
+                setError(Error("Invalid enumeration value.", member.get().codeLocation()));
                 return;
             }
         } else {
             if (static_cast<int64_t>(static_cast<uint32_t>(value)) != value) {
-                setError();
+                setError(Error("Invalid enumeration value.", member.get().codeLocation()));
                 return;
             }
         }
@@ -682,7 +682,7 @@ void Checker::visit(AST::EnumerationDefinition& enumerationDefinition)
         for (size_t j = i + 1; j < enumerationMembers.size(); ++j) {
             auto otherValue = enumerationMembers[j].get().value();
             if (value == otherValue) {
-                setError();
+                setError(Error("Cannot declare duplicate enumeration values.", enumerationMembers[j].get().codeLocation()));
                 return;
             }
         }
@@ -696,7 +696,7 @@ void Checker::visit(AST::EnumerationDefinition& enumerationDefinition)
         }
     }
     if (!foundZero) {
-        setError();
+        setError(Error("enum definition must contain a zero value.", enumerationDefinition.codeLocation()));
         return;
     }
 }
@@ -712,7 +712,7 @@ void Checker::visit(AST::TypeReference& typeReference)
 auto Checker::recurseAndGetInfo(AST::Expression& expression, bool requiresLeftValue) -> Optional<RecurseInfo>
 {
     Visitor::visit(expression);
-    if (error())
+    if (hasError())
         return WTF::nullopt;
     return getInfo(expression, requiresLeftValue);
 }
@@ -724,7 +724,7 @@ auto Checker::getInfo(AST::Expression& expression, bool requiresLeftValue) -> Op
 
     const auto& typeAnnotation = expression.typeAnnotation();
     if (requiresLeftValue && typeAnnotation.isRightValue()) {
-        setError();
+        setError(Error("Unexpected rvalue.", expression.codeLocation()));
         return WTF::nullopt;
     }
     return {{ *typeIterator->value, typeAnnotation }};
@@ -741,7 +741,7 @@ void Checker::visit(AST::VariableDeclaration& variableDeclaration)
         if (!initializerInfo)
             return;
         if (!matchAndCommit(initializerInfo->resolvingType, lhsType)) {
-            setError();
+            setError(Error("Declared variable type does not match its initializer's type.", variableDeclaration.codeLocation()));
             return;
         }
     }
@@ -785,7 +785,7 @@ void Checker::visit(AST::AssignmentExpression& assignmentExpression)
 
     auto resultType = matchAndCommit(leftInfo->resolvingType, rightInfo->resolvingType);
     if (!resultType) {
-        setError();
+        setError(Error("Left hand side of assignment does not match the type of the right hand side.", assignmentExpression.codeLocation()));
         return;
     }
 
@@ -807,7 +807,7 @@ void Checker::visit(AST::ReadModifyWriteExpression& readModifyWriteExpression)
     if (Optional<UniqueRef<AST::UnnamedType>> matchedType = matchAndCommit(leftValueInfo->resolvingType, newValueInfo->resolvingType))
         readModifyWriteExpression.newValue().setType(WTFMove(matchedType.value()));
     else {
-        setError();
+        setError(Error("Base of the read-modify-write expression does not match the type of the new value.", readModifyWriteExpression.codeLocation()));
         return;
     }
 
@@ -848,7 +848,7 @@ void Checker::visit(AST::DereferenceExpression& dereferenceExpression)
         return &downcast<AST::PointerType>(unnamedUnifyType);
     })(unnamedType);
     if (!pointerType) {
-        setError();
+        setError(Error("Cannot dereference a non-pointer type.", dereferenceExpression.codeLocation()));
         return;
     }
 
@@ -863,13 +863,13 @@ void Checker::visit(AST::MakePointerExpression& makePointerExpression)
 
     auto leftAddressSpace = leftValueInfo->typeAnnotation.leftAddressSpace();
     if (!leftAddressSpace) {
-        setError();
+        setError(Error("Cannot take the address of a non lvalue.", makePointerExpression.codeLocation()));
         return;
     }
 
     auto* leftValueType = getUnnamedType(leftValueInfo->resolvingType);
     if (!leftValueType) {
-        setError();
+        setError(Error("Cannot take the address of a value without a type.", makePointerExpression.codeLocation()));
         return;
     }
 
@@ -884,7 +884,7 @@ void Checker::visit(AST::MakeArrayReferenceExpression& makeArrayReferenceExpress
 
     auto* leftValueType = getUnnamedType(leftValueInfo->resolvingType);
     if (!leftValueType) {
-        setError();
+        setError(Error("Cannot make an array reference of a value without a type.", makeArrayReferenceExpression.codeLocation()));
         return;
     }
 
@@ -900,7 +900,7 @@ void Checker::visit(AST::MakeArrayReferenceExpression& makeArrayReferenceExpress
 
         auto leftAddressSpace = leftValueInfo->typeAnnotation.leftAddressSpace();
         if (!leftAddressSpace) {
-            setError();
+            setError(Error("Cannot make an array reference from a non-left-value.", makeArrayReferenceExpression.codeLocation()));
             return;
         }
 
@@ -914,7 +914,7 @@ void Checker::visit(AST::MakeArrayReferenceExpression& makeArrayReferenceExpress
 
     auto leftAddressSpace = leftValueInfo->typeAnnotation.leftAddressSpace();
     if (!leftAddressSpace) {
-        setError();
+        setError(Error("Cannot make an array reference from a non-left-value.", makeArrayReferenceExpression.codeLocation()));
         return;
     }
 
@@ -950,7 +950,7 @@ void Checker::finishVisiting(AST::PropertyAccessExpression& propertyAccessExpres
         return;
     auto baseUnnamedType = commit(baseInfo->resolvingType);
     if (!baseUnnamedType) {
-        setError();
+        setError(Error("Cannot resolve the type of the base of a property access expression.", propertyAccessExpression.codeLocation()));
         return;
     }
 
@@ -999,32 +999,32 @@ void Checker::finishVisiting(AST::PropertyAccessExpression& propertyAccessExpres
     }
 
     if (leftAddressSpace && !anderFunction && !getterFunction) {
-        setError();
+        setError(Error("Property access instruction must either have an ander or a getter.", propertyAccessExpression.codeLocation()));
         return;
     }
 
     if (!leftAddressSpace && !threadAnderFunction && !getterFunction) {
-        setError();
+        setError(Error("Property access instruction must either have a thread ander or a getter.", propertyAccessExpression.codeLocation()));
         return;
     }
 
     if (threadAnderFunction && getterFunction) {
-        setError();
+        setError(Error("Cannot have both a thread ander and a getter.", propertyAccessExpression.codeLocation()));
         return;
     }
 
     if (anderFunction && threadAnderFunction && !matches(*anderReturnType, *threadAnderReturnType)) {
-        setError();
+        setError(Error("Return type of ander must match the return type of the thread ander.", propertyAccessExpression.codeLocation()));
         return;
     }
 
     if (getterFunction && anderFunction && !matches(*getterReturnType, *anderReturnType)) {
-        setError();
+        setError(Error("Return type of ander must match the return type of the getter.", propertyAccessExpression.codeLocation()));
         return;
     }
 
     if (getterFunction && threadAnderFunction && !matches(*getterReturnType, *threadAnderReturnType)) {
-        setError();
+        setError(Error("Return type of the thread ander must match the return type of the getter.", propertyAccessExpression.codeLocation()));
         return;
     }
 
@@ -1046,7 +1046,7 @@ void Checker::finishVisiting(AST::PropertyAccessExpression& propertyAccessExpres
     }
 
     if (setterFunction && !getterFunction) {
-        setError();
+        setError(Error("Cannot define a setter function without a corresponding getter.", propertyAccessExpression.codeLocation()));
         return;
     }
 
@@ -1094,12 +1094,12 @@ void Checker::visit(AST::Return& returnStatement)
         if (!valueInfo)
             return;
         if (!matchAndCommit(valueInfo->resolvingType, m_currentFunction->type()))
-            setError();
+            setError(Error("Type of the return value must match the return type of the function.", returnStatement.codeLocation()));
         return;
     }
 
     if (!matches(m_currentFunction->type(), m_intrinsics.voidType()))
-        setError();
+        setError(Error("Cannot return a value from a void function.", returnStatement.codeLocation()));
 }
 
 void Checker::visit(AST::PointerType&)
@@ -1163,7 +1163,7 @@ bool Checker::recurseAndRequireBoolType(AST::Expression& expression)
     if (!expressionInfo)
         return false;
     if (!isBoolType(expressionInfo->resolvingType)) {
-        setError();
+        setError(Error("Expected bool type from expression.", expression.codeLocation()));
         return false;
     }
     return true;
@@ -1214,7 +1214,7 @@ void Checker::visit(AST::ForLoop& forLoop)
     }, [&](UniqueRef<AST::Expression>& expression) {
         checkErrorAndVisit(expression);
     }), forLoop.initialization());
-    if (error())
+    if (hasError())
         return;
     if (forLoop.condition()) {
         if (!recurseAndRequireBoolType(*forLoop.condition()))
@@ -1244,7 +1244,7 @@ void Checker::visit(AST::SwitchStatement& switchStatement)
         return &valueNamedUnifyNode;
     })();
     if (!valueType) {
-        setError();
+        setError(Error("Invalid type for the expression condition of the switch statement.", switchStatement.codeLocation()));
         return;
     }
 
@@ -1270,7 +1270,7 @@ void Checker::visit(AST::SwitchStatement& switchStatement)
             return matches(*valueType, *enumerationMemberLiteral.enumerationDefinition());
         }));
         if (!success) {
-            setError();
+            setError(Error("Invalid type for switch case.", switchCase.codeLocation()));
             return;
         }
     }
@@ -1284,7 +1284,7 @@ void Checker::visit(AST::SwitchStatement& switchStatement)
                 continue;
 
             if (!static_cast<bool>(firstCase.value())) {
-                setError();
+                setError(Error("Cannot define multiple default cases in switch statement.", secondCase.codeLocation()));
                 return;
             }
 
@@ -1316,7 +1316,7 @@ void Checker::visit(AST::SwitchStatement& switchStatement)
                 return true;
             }));
             if (!success) {
-                setError();
+                setError(Error("Cannot define duplicate case statements in a switch.", secondCase.codeLocation()));
                 return;
             }
         }
@@ -1356,7 +1356,7 @@ void Checker::visit(AST::SwitchStatement& switchStatement)
                 return false;
             });
             if (!success) {
-                setError();
+                setError(Error("Switch cases must be exhaustive or you must define a default case.", switchStatement.codeLocation()));
                 return;
             }
         } else {
@@ -1371,7 +1371,7 @@ void Checker::visit(AST::SwitchStatement& switchStatement)
             }
             for (auto& enumerationMember : downcast<AST::EnumerationDefinition>(*valueType).enumerationMembers()) {
                 if (!values.contains(&enumerationMember.get())) {
-                    setError();
+                    setError(Error("Switch cases over an enum must be exhaustive or you must define a default case.", switchStatement.codeLocation()));
                     return;
                 }
             }
@@ -1383,7 +1383,7 @@ void Checker::visit(AST::CommaExpression& commaExpression)
 {
     ASSERT(commaExpression.list().size() > 0);
     Visitor::visit(commaExpression);
-    if (error())
+    if (hasError())
         return;
     auto lastInfo = getInfo(commaExpression.list().last());
     forwardType(commaExpression, lastInfo->resolvingType);
@@ -1400,7 +1400,7 @@ void Checker::visit(AST::TernaryExpression& ternaryExpression)
     
     auto resultType = matchAndCommit(bodyInfo->resolvingType, elseInfo->resolvingType);
     if (!resultType) {
-        setError();
+        setError(Error("lhs and rhs of a ternary expression must match.", ternaryExpression.codeLocation()));
         return;
     }
 
@@ -1431,19 +1431,21 @@ void Checker::visit(AST::CallExpression& callExpression)
         }
     }
     if (!functions) {
-        setError();
+        setError(Error("Could not find any functions with appropriate name.", callExpression.codeLocation()));
         return;
     }
 
     auto* function = resolveFunction(m_program, functions, types, callExpression.name(), callExpression.codeLocation(), m_intrinsics, callExpression.castReturnType());
     if (!function) {
-        setError();
+        // FIXME: Add better error messages for why we can't resolve to one of the overrides.
+        // https://bugs.webkit.org/show_bug.cgi?id=200133
+        setError(Error("Cannot resolve function call to a concrete callee. Make sure you are using compatible types.", callExpression.codeLocation()));
         return;
     }
 
     for (size_t i = 0; i < function->parameters().size(); ++i) {
         if (!matchAndCommit(types[i].get(), *function->parameters()[i]->type())) {
-            setError();
+            setError(Error(makeString("Invalid type for parameter number ", i + 1, " in function call."), callExpression.codeLocation()));
             return;
         }
     }
@@ -1453,12 +1455,12 @@ void Checker::visit(AST::CallExpression& callExpression)
     assignType(callExpression, function->type().clone());
 }
 
-bool check(Program& program)
+Expected<void, Error> check(Program& program)
 {
     Checker checker(program.intrinsics(), program);
     checker.checkErrorAndVisit(program);
-    if (checker.error())
-        return false;
+    if (checker.hasError())
+        return checker.result();
     return checker.assignTypes();
 }
 
index f6f0857..ef1f3f8 100644 (file)
 
 #if ENABLE(WEBGPU)
 
+#include "WHLSLError.h"
+#include <wtf/Expected.h>
+
 namespace WebCore {
 
 namespace WHLSL {
 
 class Program;
 
-bool check(Program&);
+Expected<void, Error> check(Program&);
 
 }
 
diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLCodeLocation.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLCodeLocation.h
new file mode 100644 (file)
index 0000000..9e3173b
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2019 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 {
+
+struct Token;
+
+class CodeLocation {
+public:
+    CodeLocation() = default;
+    CodeLocation(unsigned startOffset, unsigned endOffset)
+        : m_startOffset(startOffset)
+        , m_endOffset(endOffset)
+    { }
+    CodeLocation(const Token&);
+    CodeLocation(const CodeLocation& location1, const CodeLocation& location2)
+        : m_startOffset(location1.startOffset())
+        , m_endOffset(location2.endOffset())
+    { }
+
+    unsigned startOffset() const { return m_startOffset; }
+    unsigned endOffset() const { return m_endOffset; }
+
+    bool operator==(const CodeLocation& other) const 
+    {
+        return m_startOffset == other.m_startOffset
+            && m_endOffset == other.m_endOffset;
+    }
+    bool operator!=(const CodeLocation& other) const { return !(*this == other); }
+    explicit operator bool() const { return *this != CodeLocation(); }
+
+private:
+    unsigned m_startOffset { std::numeric_limits<unsigned>::max() };
+    unsigned m_endOffset { std::numeric_limits<unsigned>::max() };
+};
+
+} // namespace WHLSL
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGPU)
index cca36f2..8292400 100644 (file)
@@ -65,7 +65,7 @@ private:
                 return true;
             }), functionAttribute);
             if (!success) {
-                setError();
+                setError(Error("Cannot declare multiple numthread attributes.", functionDeclaration.codeLocation()));
                 return;
             }
         }
@@ -79,7 +79,7 @@ Optional<ComputeDimensions> computeDimensions(Program& program, AST::FunctionDef
 {
     ComputeDimensionsVisitor computeDimensions(entryPoint);
     computeDimensions.Visitor::visit(program);
-    if (computeDimensions.error())
+    if (computeDimensions.hasError())
         return WTF::nullopt;
     return computeDimensions.computeDimensions();
 }
diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLError.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLError.h
new file mode 100644 (file)
index 0000000..ae0515a
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2019 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 "WHLSLCodeLocation.h"
+#include <wtf/text/StringConcatenate.h>
+#include <wtf/text/StringConcatenateNumbers.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+namespace WHLSL {
+
+class Error {
+public:
+    Error(String&& message, CodeLocation codeLocation)
+        : m_message(WTFMove(message))
+        , m_location(codeLocation)
+    {
+    }
+
+    Error(String&& message)
+        : m_message(WTFMove(message))
+    {
+    }
+
+    CodeLocation codeLocation() const { return m_location; }
+    String message() const { return m_message; }
+
+private:
+    String m_message;
+    CodeLocation m_location;
+};
+
+} // namespace WHLSL
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGPU)
index aa33e5b..0f4df55 100644 (file)
@@ -50,12 +50,12 @@ public:
     void visit(AST::CallExpression& callExpression) override
     {
         if ((&callExpression.function() == m_intrinsics.ddx() || &callExpression.function() == m_intrinsics.ddy()) && m_entryPointType != AST::EntryPointType::Fragment) {
-            setError();
+            setError(Error("Cannot use ddx or ddy in a non-fragment shader.", callExpression.codeLocation()));
             return;
         }
         if ((&callExpression.function() == m_intrinsics.allMemoryBarrier() || &callExpression.function() == m_intrinsics.deviceMemoryBarrier() || &callExpression.function() == m_intrinsics.groupMemoryBarrier())
             && m_entryPointType != AST::EntryPointType::Compute) {
-            setError();
+            setError(Error("Cannot use memory barrier in a non-compute shader.", callExpression.codeLocation()));
             return;
         }
         Visitor::visit(callExpression.function());
@@ -65,17 +65,17 @@ public:
     const Intrinsics& m_intrinsics;
 };
 
-bool checkFunctionStages(Program& program)
+Expected<void, Error> checkFunctionStages(Program& program)
 {
     for (auto& functionDefinition : program.functionDefinitions()) {
         if (!functionDefinition->entryPointType())
             continue;
         FunctionStageChecker functionStageChecker(*functionDefinition->entryPointType(), program.intrinsics());
         functionStageChecker.Visitor::visit(functionDefinition);
-        if (functionStageChecker.error())
-            return false;
+        if (functionStageChecker.hasError())
+            return makeUnexpected(functionStageChecker.result().error());
     }
-    return true;
+    return { };
 }
 
 }
index 21956bb..9aaa6c8 100644 (file)
 
 #if ENABLE(WEBGPU)
 
+#include "WHLSLError.h"
+#include <wtf/Expected.h>
+
 namespace WebCore {
 
 namespace WHLSL {
 
 class Program;
 
-bool checkFunctionStages(Program&);
+Expected<void, Error> checkFunctionStages(Program&);
 
 }
 
index 7274536..b6f0306 100644 (file)
@@ -58,6 +58,7 @@ public:
     void reset()
     {
         m_currentSemantic = nullptr;
+        m_currentVariableLocation = { };
     }
 
     Vector<EntryPointItem> takeEntryPointItems()
@@ -68,7 +69,7 @@ public:
     void visit(AST::EnumerationDefinition&)
     {
         if (!m_currentSemantic) {
-            setError();
+            setError(Error("Expected semantic for entrypoint argument.", m_currentVariableLocation));
             return;
         }
         m_entryPointItems.append(EntryPointItem(m_typeReferences.last().get(), *m_currentSemantic, m_path));
@@ -77,11 +78,11 @@ public:
     void visit(AST::NativeTypeDeclaration& nativeTypeDeclaration)
     {
         if (!m_currentSemantic) {
-            setError();
+            setError(Error("Expected semantic for entrypoint argument.", m_currentVariableLocation));
             return;
         }
         if (matches(nativeTypeDeclaration, m_intrinsics.voidType())) {
-            setError();
+            setError(Error("Unexpected void type for entrypoint argument.", m_currentVariableLocation));
             return;
         }
 
@@ -91,7 +92,7 @@ public:
     void visit(AST::StructureDefinition& structureDefinition)
     {
         if (m_currentSemantic) {
-            setError();
+            setError(Error("Unexpected semantic for struct entrypoint argument.", m_currentVariableLocation));
             return;
         }
 
@@ -121,7 +122,7 @@ public:
     void visit(AST::PointerType& pointerType)
     {
         if (!m_currentSemantic) {
-            setError();
+            setError(Error("Expected semantic for entrypoint argument.", m_currentVariableLocation));
             return;
         }
         m_entryPointItems.append(EntryPointItem(pointerType, *m_currentSemantic, m_path));
@@ -130,7 +131,7 @@ public:
     void visit(AST::ArrayReferenceType& arrayReferenceType)
     {
         if (!m_currentSemantic) {
-            setError();
+            setError(Error("Expected semantic for entrypoint argument.", m_currentVariableLocation));
             return;
         }
         m_entryPointItems.append(EntryPointItem(arrayReferenceType, *m_currentSemantic, m_path));
@@ -139,7 +140,7 @@ public:
     void visit(AST::ArrayType& arrayType)
     {
         if (!m_currentSemantic) {
-            setError();
+            setError(Error("Expected semantic for entrypoint argument.", m_currentVariableLocation));
             return;
         }
         m_entryPointItems.append(EntryPointItem(arrayType, *m_currentSemantic, m_path));
@@ -148,6 +149,7 @@ public:
     void visit(AST::VariableDeclaration& variableDeclaration)
     {
         ASSERT(!m_currentSemantic);
+        m_currentVariableLocation = variableDeclaration.codeLocation();
         if (variableDeclaration.semantic())
             m_currentSemantic = variableDeclaration.semantic();
         ASSERT(variableDeclaration.type());
@@ -160,25 +162,26 @@ private:
     Vector<String> m_path;
     const Intrinsics& m_intrinsics;
     AST::Semantic* m_currentSemantic { nullptr };
+    CodeLocation m_currentVariableLocation;
     Vector<std::reference_wrapper<AST::TypeReference>> m_typeReferences;
     Vector<EntryPointItem> m_entryPointItems;
 };
 
-Optional<EntryPointItems> gatherEntryPointItems(const Intrinsics& intrinsics, AST::FunctionDefinition& functionDefinition)
+Expected<EntryPointItems, Error> 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;
+        if (inputGatherer.hasError())
+            return makeUnexpected(inputGatherer.result().error());
     }
     Gatherer outputGatherer(intrinsics, functionDefinition.semantic());
     if (*functionDefinition.entryPointType() != AST::EntryPointType::Compute)
         outputGatherer.checkErrorAndVisit(functionDefinition.type());
-    if (outputGatherer.error())
-        return WTF::nullopt;
+    if (outputGatherer.hasError())
+        return makeUnexpected(outputGatherer.result().error());
 
     return {{ inputGatherer.takeEntryPointItems(), outputGatherer.takeEntryPointItems() }};
 }
index fefd428..7ffd3fd 100644 (file)
@@ -27,6 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
+#include "WHLSLError.h"
 #include "WHLSLSemantic.h"
 #include <wtf/Vector.h>
 #include <wtf/text/WTFString.h>
@@ -62,7 +63,7 @@ struct EntryPointItems {
     Vector<EntryPointItem> outputs;
 };
 
-Optional<EntryPointItems> gatherEntryPointItems(const Intrinsics&, AST::FunctionDefinition&);
+Expected<EntryPointItems, Error> gatherEntryPointItems(const Intrinsics&, AST::FunctionDefinition&);
 
 } // namespace WHLSL
 
index 93be968..f600d4d 100644 (file)
@@ -498,16 +498,6 @@ auto Lexer::consumeTokenFromStream() -> Token
     return prepare(m_offset, Token::Type::Invalid);
 }
 
-unsigned Lexer::lineNumberFromOffset(unsigned targetOffset)
-{
-    // Counting from 1 to match most text editors.
-    unsigned lineNumber = 1;
-    for (unsigned offset = 0; offset < targetOffset; ++offset) {
-        if (m_stringView[offset] == '\n')
-            ++lineNumber;
-    }
-    return lineNumber;
-}
 
 // We can take advantage of two properties of Unicode:
 // 1. The consitutent UTF-16 code units for all non-BMP code points are surrogates,
@@ -539,6 +529,31 @@ static inline bool isNewline(UChar codeUnit)
     }
 }
 
+
+auto Lexer::lineAndColumnNumberFromOffset(const StringView& stringView, unsigned targetOffset) -> LineAndColumn
+{
+    // Counting from 1 to match most text editors.
+    unsigned lineNumber = 1;
+    unsigned columnNumber = 1;
+    for (unsigned offset = 0; offset < std::min(stringView.length(), targetOffset); ++offset) {
+        ++columnNumber;
+        if (isNewline(stringView[offset])) {
+            ++lineNumber;
+            columnNumber = 1;
+        }
+    }
+    return { lineNumber, columnNumber };
+}
+
+String Lexer::errorString(const StringView& source, Error error)
+{
+    if (error.codeLocation()) {
+        auto lineAndColumn = lineAndColumnNumberFromOffset(source, error.codeLocation().startOffset());
+        return makeString(lineAndColumn.line, ':', lineAndColumn.column, ": ", error.message());
+    }
+    return error.message();
+}
+
 void Lexer::skipWhitespaceAndComments()
 {
     while (m_offset < m_stringView.length()) {
index fa99f58..4e92a0d 100644 (file)
@@ -27,6 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
+#include "WHLSLCodeLocation.h"
 #include <wtf/Optional.h>
 #include <wtf/Vector.h>
 #include <wtf/text/StringConcatenate.h>
@@ -38,37 +39,10 @@ namespace WebCore {
 
 namespace WHLSL {
 
-struct Token;
-
-namespace AST {
-
-class CodeLocation {
-public:
-    CodeLocation() = default;
-    CodeLocation(unsigned startOffset, unsigned endOffset)
-        : m_startOffset(startOffset)
-        , m_endOffset(endOffset)
-    { }
-    inline CodeLocation(const Token&);
-    CodeLocation(const CodeLocation& location1, const CodeLocation& location2)
-        : m_startOffset(location1.startOffset())
-        , m_endOffset(location2.endOffset())
-    { }
-
-    unsigned startOffset() const { return m_startOffset; }
-    unsigned endOffset() const { return m_endOffset; }
-
-private:
-    unsigned m_startOffset { 0 };
-    unsigned m_endOffset { 0 };
-};
-
-} // namespace AST
-
 class Lexer;
 
 struct Token {
-    AST::CodeLocation codeLocation;
+    CodeLocation codeLocation;
     enum class Type : uint8_t {
         IntLiteral,
         UintLiteral,
@@ -189,7 +163,7 @@ struct Token {
     }
 };
 
-AST::CodeLocation::CodeLocation(const Token& token)
+inline CodeLocation::CodeLocation(const Token& token)
     : m_startOffset(token.codeLocation.startOffset())
     , m_endOffset(token.codeLocation.endOffset())
 { }
@@ -273,16 +247,22 @@ public:
 
     String errorString(const Token& token, const String& message)
     {
-        return makeString("Parse error at line ", lineNumberFromOffset(token.startOffset()), ": ", message);
+        return makeString("Parse error at line ", lineAndColumnNumberFromOffset(m_stringView, token.startOffset()).line, ": ", message);
     }
 
+    static String errorString(const StringView& source, Error);
+
 private:
     friend struct Token;
     Token consumeTokenFromStream();
 
     void skipWhitespaceAndComments();
 
-    unsigned lineNumberFromOffset(unsigned offset);
+    struct LineAndColumn {
+        unsigned line;
+        unsigned column;
+    };
+    static LineAndColumn lineAndColumnNumberFromOffset(const StringView&, unsigned offset);
 
     Optional<Token::Type> recognizeKeyword(unsigned end);
 
index 3660439..235ceda 100644 (file)
@@ -62,27 +62,27 @@ NameResolver::NameResolver(NameResolver& parentResolver, NameContext& nameContex
 
 NameResolver::~NameResolver()
 {
-    if (error() && m_parentNameResolver)
-        m_parentNameResolver->setError();
+    if (hasError() && m_parentNameResolver)
+        m_parentNameResolver->setError(result().error());
 }
 
 void NameResolver::visit(AST::TypeReference& typeReference)
 {
     ScopedSetAdder<AST::TypeReference*> adder(m_typeReferences, &typeReference);
     if (!adder.isNewEntry()) {
-        setError();
+        setError(Error("Cannot use recursive type arguments.", typeReference.codeLocation()));
         return;
     }
 
     Visitor::visit(typeReference);
-    if (error())
+    if (hasError())
         return;
     if (typeReference.maybeResolvedType()) // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198161 Shouldn't we know by now whether the type has been resolved or not?
         return;
 
     auto* candidates = m_nameContext.getTypes(typeReference.name());
     if (candidates == nullptr) {
-        setError();
+        setError(Error("Cannot find type reference.", typeReference.codeLocation()));
         return;
     }
     for (auto& candidate : *candidates)
@@ -90,7 +90,7 @@ void NameResolver::visit(AST::TypeReference& typeReference)
     if (auto result = resolveTypeOverloadImpl(*candidates, typeReference.typeArguments()))
         typeReference.setResolvedType(*result);
     else {
-        setError();
+        setError(Error("Cannot resolve type arguments.", typeReference.codeLocation()));
         return;
     }
 }
@@ -100,7 +100,7 @@ void NameResolver::visit(AST::FunctionDefinition& functionDefinition)
     NameContext newNameContext(&m_nameContext);
     NameResolver newNameResolver(*this, newNameContext);
     checkErrorAndVisit(functionDefinition.type());
-    if (error())
+    if (hasError())
         return;
     for (auto& parameter : functionDefinition.parameters())
         newNameResolver.checkErrorAndVisit(parameter);
@@ -117,7 +117,7 @@ void NameResolver::visit(AST::Block& block)
 void NameResolver::visit(AST::IfStatement& ifStatement)
 {
     checkErrorAndVisit(ifStatement.conditional());
-    if (error())
+    if (hasError())
         return;
 
     {
@@ -125,7 +125,7 @@ void NameResolver::visit(AST::IfStatement& ifStatement)
         NameResolver newNameResolver(*this, nameContext);
         newNameResolver.checkErrorAndVisit(ifStatement.body());
     }
-    if (error())
+    if (hasError())
         return;
 
     if (ifStatement.elseBody()) {
@@ -138,7 +138,7 @@ void NameResolver::visit(AST::IfStatement& ifStatement)
 void NameResolver::visit(AST::WhileLoop& whileLoop)
 {
     checkErrorAndVisit(whileLoop.conditional());
-    if (error())
+    if (hasError())
         return;
 
     NameContext nameContext(&m_nameContext);
@@ -167,7 +167,7 @@ void NameResolver::visit(AST::ForLoop& forLoop)
 void NameResolver::visit(AST::VariableDeclaration& variableDeclaration)
 {
     if (!m_nameContext.add(variableDeclaration)) {
-        setError();
+        setError(Error("Cannot declare duplicate variables.", variableDeclaration.codeLocation()));
         return;
     }
     Visitor::visit(variableDeclaration);
@@ -181,7 +181,7 @@ void NameResolver::visit(AST::VariableReference& variableReference)
     if (auto* variable = m_nameContext.getVariable(variableReference.name()))
         variableReference.setVariable(*variable);
     else {
-        setError();
+        setError(Error("Cannot find the variable declaration.", variableReference.codeLocation()));
         return;
     }
 }
@@ -201,7 +201,7 @@ void NameResolver::visit(AST::DotExpression& dotExpression)
                     AST::replaceWith<AST::EnumerationMemberLiteral>(dotExpression, WTFMove(enumerationMemberLiteral));
                     return;
                 }
-                setError();
+                setError(Error("No enum member matches the used name.", dotExpression.codeLocation()));
                 return;
             }
         }
@@ -227,7 +227,7 @@ void NameResolver::visit(AST::EnumerationMemberLiteral& enumerationMemberLiteral
         }
     }
     
-    setError();
+    setError(Error("Cannot resolve enumeration member literal.", enumerationMemberLiteral.codeLocation()));
 }
 
 void NameResolver::visit(AST::NativeFunctionDeclaration& nativeFunctionDeclaration)
@@ -239,44 +239,44 @@ void NameResolver::visit(AST::NativeFunctionDeclaration& nativeFunctionDeclarati
 
 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198167 Make sure all the names have been resolved.
 
-bool resolveNamesInTypes(Program& program, NameResolver& nameResolver)
+Expected<void, Error> resolveNamesInTypes(Program& program, NameResolver& nameResolver)
 {
     for (auto& typeDefinition : program.typeDefinitions()) {
         nameResolver.checkErrorAndVisit(typeDefinition);
-        if (nameResolver.error())
-            return false;
+        if (nameResolver.hasError())
+            return nameResolver.result();
     }
     for (auto& structureDefinition : program.structureDefinitions()) {
         nameResolver.checkErrorAndVisit(structureDefinition);
-        if (nameResolver.error())
-            return false;
+        if (nameResolver.hasError())
+            return nameResolver.result();
     }
     for (auto& enumerationDefinition : program.enumerationDefinitions()) {
         nameResolver.checkErrorAndVisit(enumerationDefinition);
-        if (nameResolver.error())
-            return false;
+        if (nameResolver.hasError())
+            return nameResolver.result();
     }
     for (auto& nativeTypeDeclaration : program.nativeTypeDeclarations()) {
         nameResolver.checkErrorAndVisit(nativeTypeDeclaration);
-        if (nameResolver.error())
-            return false;
+        if (nameResolver.hasError())
+            return nameResolver.result();
     }
-    return true;
+    return { };
 }
 
-bool resolveTypeNamesInFunctions(Program& program, NameResolver& nameResolver)
+Expected<void, Error> resolveTypeNamesInFunctions(Program& program, NameResolver& nameResolver)
 {
     for (auto& functionDefinition : program.functionDefinitions()) {
         nameResolver.checkErrorAndVisit(functionDefinition);
-        if (nameResolver.error())
-            return false;
+        if (nameResolver.hasError())
+            return nameResolver.result();
     }
     for (auto& nativeFunctionDeclaration : program.nativeFunctionDeclarations()) {
         nameResolver.checkErrorAndVisit(nativeFunctionDeclaration);
-        if (nameResolver.error())
-            return false;
+        if (nameResolver.hasError())
+            return nameResolver.result();
     }
-    return true;
+    return { };
 }
 
 } // namespace WHLSL
index 3acdadf..658c35f 100644 (file)
 
 #if ENABLE(WEBGPU)
 
+#include "WHLSLError.h"
 #include "WHLSLNameContext.h"
 #include "WHLSLVisitor.h"
+#include <wtf/Expected.h>
 #include <wtf/HashSet.h>
 
 namespace WebCore {
@@ -63,8 +65,8 @@ private:
     NameResolver* m_parentNameResolver { nullptr };
 };
 
-bool resolveNamesInTypes(Program&, NameResolver&);
-bool resolveTypeNamesInFunctions(Program&, NameResolver&);
+Expected<void, Error> resolveNamesInTypes(Program&, NameResolver&);
+Expected<void, Error> resolveTypeNamesInFunctions(Program&, NameResolver&);
 
 } // namespace WHLSL
 
index 75a9c95..16e876f 100644 (file)
@@ -59,7 +59,7 @@ namespace WHLSL {
         return Unexpected<Error>(name.error());
 
 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195682 Return a better error code from this, and report it to JavaScript.
-auto Parser::parse(Program& program, StringView stringView, Mode mode) -> Optional<Error>
+auto Parser::parse(Program& program, StringView stringView, Mode mode) -> Expected<void, Error>
 {
     m_lexer = Lexer(stringView);
     m_mode = mode;
@@ -68,28 +68,28 @@ auto Parser::parse(Program& program, StringView stringView, Mode mode) -> Option
         auto token = m_lexer.peek();
         switch (token.type) {
         case Token::Type::Invalid:
-            return WTF::nullopt;
+            return { };
         case Token::Type::Semicolon:
             m_lexer.consumeToken();
             continue;
         case Token::Type::Typedef: {
             auto typeDefinition = parseTypeDefinition();
             if (!typeDefinition)
-                return typeDefinition.error();
+                return makeUnexpected(typeDefinition.error());
             program.append(WTFMove(*typeDefinition));
             continue;
         }
         case Token::Type::Struct: {
             auto structureDefinition = parseStructureDefinition();
             if (!structureDefinition)
-                return structureDefinition.error();
+                return makeUnexpected(structureDefinition.error());
             program.append(WTFMove(*structureDefinition));
             continue;
         }
         case Token::Type::Enum: {
             auto enumerationDefinition = parseEnumerationDefinition();
             if (!enumerationDefinition)
-                return enumerationDefinition.error();
+                return makeUnexpected(enumerationDefinition.error());
             program.append(WTFMove(*enumerationDefinition));
             continue;
         }
@@ -97,31 +97,31 @@ auto Parser::parse(Program& program, StringView stringView, Mode mode) -> Option
             ASSERT(m_mode == Mode::StandardLibrary);
             auto furtherToken = peekFurther();
             if (!furtherToken)
-                return WTF::nullopt;
+                return { };
             if (furtherToken->type == Token::Type::Typedef) {
                 auto nativeTypeDeclaration = parseNativeTypeDeclaration();
                 if (!nativeTypeDeclaration)
-                    return nativeTypeDeclaration.error();
+                    return makeUnexpected(nativeTypeDeclaration.error());
                 program.append(WTFMove(*nativeTypeDeclaration));
                 continue;
             }
             auto nativeFunctionDeclaration = parseNativeFunctionDeclaration();
             if (!nativeFunctionDeclaration)
-                return nativeFunctionDeclaration.error();
+                return makeUnexpected(nativeFunctionDeclaration.error());
             program.append(WTFMove(*nativeFunctionDeclaration));
             continue;
         }
         default: {
             auto functionDefinition = parseFunctionDefinition();
             if (!functionDefinition)
-                return functionDefinition.error();
+                return makeUnexpected(functionDefinition.error());
             program.append(WTFMove(*functionDefinition));
             continue;
         }
         }
     }
 
-    return WTF::nullopt;
+    return { };
 }
 
 auto Parser::fail(const String& message, TryToPeek tryToPeek) -> Unexpected<Error>
@@ -241,7 +241,7 @@ static int digitValue(UChar character)
     return character - 'A' + 10;
 }
 
-static Expected<int, Parser::Error> intLiteralToInt(StringView text)
+static Expected<int, Error> intLiteralToInt(StringView text)
 {
     bool negate = false;
     if (text.startsWith("-"_str)) {
@@ -260,21 +260,21 @@ static Expected<int, Parser::Error> intLiteralToInt(StringView text)
         auto previous = result;
         result = result * base + digit;
         if (result < previous)
-            return Unexpected<Parser::Error>(Parser::Error(makeString("int literal ", text, " is out of bounds")));
+            return makeUnexpected(Error(makeString("int literal ", text, " is out of bounds")));
     }
     if (negate) {
         static_assert(sizeof(int64_t) > sizeof(unsigned) && sizeof(int64_t) > sizeof(int), "This code would be wrong otherwise");
         int64_t intResult = -static_cast<int64_t>(result);
         if (intResult < static_cast<int64_t>(std::numeric_limits<int>::min()))
-            return Unexpected<Parser::Error>(Parser::Error(makeString("int literal ", text, " is out of bounds")));
+            return makeUnexpected(Error(makeString("int literal ", text, " is out of bounds")));
         return { static_cast<int>(intResult) };
     }
     if (result > static_cast<unsigned>(std::numeric_limits<int>::max()))
-        return Unexpected<Parser::Error>(Parser::Error(makeString("int literal ", text, " is out of bounds")));
+        return makeUnexpected(Error(makeString("int literal ", text, " is out of bounds")));
     return { static_cast<int>(result) };
 }
 
-static Expected<unsigned, Parser::Error> uintLiteralToUint(StringView text)
+static Expected<unsigned, Error> uintLiteralToUint(StringView text)
 {
     unsigned base = 10;
     if (text.startsWith("0x"_str)) {
@@ -289,17 +289,17 @@ static Expected<unsigned, Parser::Error> uintLiteralToUint(StringView text)
         auto previous = result;
         result = result * base + digit;
         if (result < previous)
-            return Unexpected<Parser::Error>(Parser::Error(makeString("uint literal ", text, " is out of bounds")));
+            return makeUnexpected(Error(makeString("uint literal ", text, " is out of bounds")));
     }
     return { result };
 }
 
-static Expected<float, Parser::Error> floatLiteralToFloat(StringView text)
+static Expected<float, Error> floatLiteralToFloat(StringView text)
 {
     size_t parsedLength;
     auto result = parseDouble(text, parsedLength);
     if (parsedLength != text.length())
-        return Unexpected<Parser::Error>(Parser::Error(makeString("Cannot parse float ", text)));
+        return makeUnexpected(Error(makeString("Cannot parse float ", text)));
     return static_cast<float>(result);
 }
 
@@ -343,18 +343,18 @@ auto Parser::consumeNonNegativeIntegralLiteral() -> Expected<unsigned, Error>
     return fail("int literal is negative"_str);
 }
 
-static Expected<unsigned, Parser::Error> recognizeSimpleUnsignedInteger(StringView stringView)
+static Expected<unsigned, Error> recognizeSimpleUnsignedInteger(StringView stringView)
 {
     unsigned result = 0;
     if (stringView.length() < 1)
-        return Unexpected<Parser::Error>(Parser::Error(makeString("Simple unsigned literal ", stringView, " is too short")));
+        return makeUnexpected(Error(makeString("Simple unsigned literal ", stringView, " is too short")));
     for (auto codePoint : stringView.codePoints()) {
         if (codePoint < '0' || codePoint > '9')
-            return Unexpected<Parser::Error>(Parser::Error(makeString("Simple unsigned literal ", stringView, " isn't of the form [0-9]+")));
+            return makeUnexpected(Error(makeString("Simple unsigned literal ", stringView, " isn't of the form [0-9]+")));
         auto previous = result;
         result = result * 10 + (codePoint - '0');
         if (result < previous)
-            return Unexpected<Parser::Error>(Parser::Error(makeString("Simple unsigned literal ", stringView, " is out of bounds")));
+            return makeUnexpected(Error(makeString("Simple unsigned literal ", stringView, " is out of bounds")));
     }
     return result;
 }
@@ -415,7 +415,7 @@ auto Parser::parseTypeArgument() -> Expected<AST::TypeArgument, Error>
         return AST::TypeArgument(WTFMove(*constantExpression));
     }
     CONSUME_TYPE(result, Identifier);
-    AST::CodeLocation location(*result);
+    CodeLocation location(*result);
     return AST::TypeArgument(makeUniqueRef<AST::TypeReference>(location, result->stringView(m_lexer).toString(), AST::TypeArguments()));
 }
 
@@ -534,7 +534,7 @@ auto Parser::parseType() -> Expected<UniqueRef<AST::UnnamedType>, Error>
             break;
         }
         auto constructTypeFromSuffixAbbreviated = [&](const TypeSuffixAbbreviated& typeSuffixAbbreviated, UniqueRef<AST::UnnamedType>&& previous) -> UniqueRef<AST::UnnamedType> {
-            AST::CodeLocation location(*addressSpaceToken, typeSuffixAbbreviated.location);
+            CodeLocation location(*addressSpaceToken, typeSuffixAbbreviated.location);
             switch (typeSuffixAbbreviated.token.type) {
             case Token::Type::Star:
                 return { makeUniqueRef<AST::PointerType>(location, addressSpace, WTFMove(previous)) };
@@ -565,7 +565,7 @@ auto Parser::parseType() -> Expected<UniqueRef<AST::UnnamedType>, Error>
     }
 
     auto constructTypeFromSuffixNonAbbreviated = [&](const TypeSuffixNonAbbreviated& typeSuffixNonAbbreviated, UniqueRef<AST::UnnamedType>&& previous) -> UniqueRef<AST::UnnamedType> {
-        AST::CodeLocation location(*name, typeSuffixNonAbbreviated.location);
+        CodeLocation location(*name, typeSuffixNonAbbreviated.location);
         switch (typeSuffixNonAbbreviated.token.type) {
         case Token::Type::Star:
             return { makeUniqueRef<AST::PointerType>(location, *typeSuffixNonAbbreviated.addressSpace, WTFMove(previous)) };
@@ -1186,7 +1186,7 @@ auto Parser::parseForLoop() -> Expected<AST::ForLoop, Error>
         }
 
         PARSE(body, Statement);
-        AST::CodeLocation location(origin->codeLocation,  (*body)->codeLocation());
+        CodeLocation location(origin->codeLocation,  (*body)->codeLocation());
         return AST::ForLoop(location, WTFMove(initialization), WTFMove(condition), WTFMove(increment), WTFMove(*body));
     };
 
@@ -1211,7 +1211,7 @@ auto Parser::parseWhileLoop() -> Expected<AST::WhileLoop, Error>
     CONSUME_TYPE(rightParenthesis, RightParenthesis);
     PARSE(body, Statement);
 
-    AST::CodeLocation location(origin->codeLocation,  (*body)->codeLocation());
+    CodeLocation location(origin->codeLocation,  (*body)->codeLocation());
     return AST::WhileLoop(location, WTFMove(*conditional), WTFMove(*body));
 }
 
@@ -1389,7 +1389,7 @@ auto Parser::parseEffectfulExpression() -> Expected<UniqueRef<AST::Expression>,
     if (expressions.size() == 1)
         return WTFMove(expressions[0]);
     unsigned endOffset = m_lexer.peek().startOffset();
-    AST::CodeLocation location(origin->startOffset(), endOffset);
+    CodeLocation location(origin->startOffset(), endOffset);
     return { makeUniqueRef<AST::CommaExpression>(location, WTFMove(expressions)) };
 }
 
@@ -1433,14 +1433,14 @@ auto Parser::parseLimitedSuffixOperator(UniqueRef<AST::Expression>&& previous) -
         auto identifier = consumeType(Token::Type::Identifier);
         if (!identifier)
             return SuffixExpression(WTFMove(previous), false);
-        AST::CodeLocation location(previous->codeLocation(), *identifier);
+        CodeLocation location(previous->codeLocation(), *identifier);
         return SuffixExpression(makeUniqueRef<AST::DotExpression>(location, WTFMove(previous), identifier->stringView(m_lexer).toString()), true);
     }
     case Token::Type::Arrow: {
         auto identifier = consumeType(Token::Type::Identifier);
         if (!identifier)
             return SuffixExpression(WTFMove(previous), false);
-        AST::CodeLocation location(previous->codeLocation(), *identifier);
+        CodeLocation location(previous->codeLocation(), *identifier);
         return SuffixExpression(makeUniqueRef<AST::DotExpression>(location, makeUniqueRef<AST::DereferenceExpression>(location, WTFMove(previous)), identifier->stringView(m_lexer).toString()), true);
     }
     default: {
@@ -1449,7 +1449,7 @@ auto Parser::parseLimitedSuffixOperator(UniqueRef<AST::Expression>&& previous) -
         if (!expression)
             return SuffixExpression(WTFMove(previous), false);
         if (auto rightSquareBracket = consumeType(Token::Type::RightSquareBracket)) {
-            AST::CodeLocation location(previous->codeLocation(), *rightSquareBracket);
+            CodeLocation location(previous->codeLocation(), *rightSquareBracket);
             return SuffixExpression(makeUniqueRef<AST::IndexExpression>(location, WTFMove(previous), WTFMove(*expression)), true);
         }
         return SuffixExpression(WTFMove(previous), false);
@@ -1473,14 +1473,14 @@ auto Parser::parseSuffixOperator(UniqueRef<AST::Expression>&& previous) -> Suffi
         auto identifier = consumeType(Token::Type::Identifier);
         if (!identifier)
             return SuffixExpression(WTFMove(previous), false);
-        AST::CodeLocation location(previous->codeLocation(), *identifier);
+        CodeLocation location(previous->codeLocation(), *identifier);
         return SuffixExpression(makeUniqueRef<AST::DotExpression>(location, WTFMove(previous), identifier->stringView(m_lexer).toString()), true);
     }
     case Token::Type::Arrow: {
         auto identifier = consumeType(Token::Type::Identifier);
         if (!identifier)
             return SuffixExpression(WTFMove(previous), false);
-        AST::CodeLocation location(previous->codeLocation(), *identifier);
+        CodeLocation location(previous->codeLocation(), *identifier);
         return SuffixExpression(makeUniqueRef<AST::DotExpression>(location, makeUniqueRef<AST::DereferenceExpression>(WTFMove(*suffix), WTFMove(previous)), identifier->stringView(m_lexer).toString()), true);
     }
     case Token::Type::LeftSquareBracket: {
@@ -1488,13 +1488,13 @@ auto Parser::parseSuffixOperator(UniqueRef<AST::Expression>&& previous) -> Suffi
         if (!expression)
             return SuffixExpression(WTFMove(previous), false);
         if (auto rightSquareBracket = consumeType(Token::Type::RightSquareBracket)) {
-            AST::CodeLocation location(previous->codeLocation(), *rightSquareBracket);
+            CodeLocation location(previous->codeLocation(), *rightSquareBracket);
             return SuffixExpression(makeUniqueRef<AST::IndexExpression>(location, WTFMove(previous), WTFMove(*expression)), true);
         }
         return SuffixExpression(WTFMove(previous), false);
     }
     case Token::Type::PlusPlus: {
-        AST::CodeLocation location(previous->codeLocation(), *suffix);
+        CodeLocation location(previous->codeLocation(), *suffix);
         auto result = AST::ReadModifyWriteExpression::create(location, WTFMove(previous));
         Vector<UniqueRef<AST::Expression>> callArguments;
         callArguments.append(result->oldVariableReference());
@@ -1504,7 +1504,7 @@ auto Parser::parseSuffixOperator(UniqueRef<AST::Expression>&& previous) -> Suffi
     }
     default: {
         ASSERT(suffix->type == Token::Type::MinusMinus);
-        AST::CodeLocation location(previous->codeLocation(), *suffix);
+        CodeLocation location(previous->codeLocation(), *suffix);
         auto result = AST::ReadModifyWriteExpression::create(location, WTFMove(previous));
         Vector<UniqueRef<AST::Expression>> callArguments;
         callArguments.append(result->oldVariableReference());
@@ -1530,7 +1530,7 @@ auto Parser::parseExpression() -> Expected<UniqueRef<AST::Expression>, Error>
     if (expressions.size() == 1)
         return WTFMove(expressions[0]);
     auto endOffset = m_lexer.peek().startOffset();
-    AST::CodeLocation location(startOffset, endOffset);
+    CodeLocation location(startOffset, endOffset);
     return { makeUniqueRef<AST::CommaExpression>(location, WTFMove(expressions)) };
 }
 
@@ -1541,11 +1541,11 @@ auto Parser::completeTernaryConditional(UniqueRef<AST::Expression>&& predicate)
     CONSUME_TYPE(colon, Colon);
     PARSE(elseExpression, PossibleTernaryConditional);
 
-    AST::CodeLocation predicateLocation = predicate->codeLocation();
+    CodeLocation predicateLocation = predicate->codeLocation();
     Vector<UniqueRef<AST::Expression>> castArguments;
     castArguments.append(WTFMove(predicate));
     auto boolCast = makeUniqueRef<AST::CallExpression>(predicateLocation, "bool"_str, WTFMove(castArguments));
-    AST::CodeLocation location(predicateLocation, (*elseExpression)->codeLocation());
+    CodeLocation location(predicateLocation, (*elseExpression)->codeLocation());
     return { makeUniqueRef<AST::TernaryExpression>(location, WTFMove(boolCast), WTFMove(*bodyExpression), WTFMove(*elseExpression)) };
 }
 
@@ -1567,7 +1567,7 @@ auto Parser::completeAssignment(UniqueRef<AST::Expression>&& left) -> Expected<U
         return Unexpected<Error>(assignmentOperator.error());
 
     PARSE(right, PossibleTernaryConditional);
-    AST::CodeLocation location = { left->codeLocation(), (*right)->codeLocation() };
+    CodeLocation location = { left->codeLocation(), (*right)->codeLocation() };
 
     if (assignmentOperator->type == Token::Type::EqualsSign)
         return { makeUniqueRef<AST::AssignmentExpression>(location, WTFMove(left), WTFMove(*right))};
@@ -1676,7 +1676,7 @@ auto Parser::completePossibleLogicalBinaryOperation(UniqueRef<AST::Expression>&&
         Token::Type::And
         >()) {
         PARSE(next, PossibleRelationalBinaryOperation);
-        AST::CodeLocation location(previous->codeLocation(), (*next)->codeLocation());
+        CodeLocation location(previous->codeLocation(), (*next)->codeLocation());
 
         switch (logicalBinaryOperation->type) {
         case Token::Type::OrOr:
@@ -1730,7 +1730,7 @@ auto Parser::completePossibleRelationalBinaryOperation(UniqueRef<AST::Expression
         Token::Type::NotEqual
         >()) {
         PARSE(next, PossibleShift);
-        AST::CodeLocation location(previous->codeLocation(), (*next)->codeLocation());
+        CodeLocation location(previous->codeLocation(), (*next)->codeLocation());
 
         Vector<UniqueRef<AST::Expression>> callArguments;
         callArguments.append(WTFMove(previous));
@@ -1782,7 +1782,7 @@ auto Parser::completePossibleShift(UniqueRef<AST::Expression>&& previous) -> Exp
         Token::Type::RightShift
         >()) {
         PARSE(next, PossibleAdd);
-        AST::CodeLocation location(previous->codeLocation(), (*next)->codeLocation());
+        CodeLocation location(previous->codeLocation(), (*next)->codeLocation());
 
         Vector<UniqueRef<AST::Expression>> callArguments;
         callArguments.append(WTFMove(previous));
@@ -1817,7 +1817,7 @@ auto Parser::completePossibleAdd(UniqueRef<AST::Expression>&& previous) -> Expec
         Token::Type::Minus
         >()) {
         PARSE(next, PossibleMultiply);
-        AST::CodeLocation location(previous->codeLocation(), (*next)->codeLocation());
+        CodeLocation location(previous->codeLocation(), (*next)->codeLocation());
 
         Vector<UniqueRef<AST::Expression>> callArguments;
         callArguments.append(WTFMove(previous));
@@ -1853,7 +1853,7 @@ auto Parser::completePossibleMultiply(UniqueRef<AST::Expression>&& previous) ->
         Token::Type::Mod
         >()) {
         PARSE(next, PossiblePrefix);
-        AST::CodeLocation location(previous->codeLocation(), (*next)->codeLocation());
+        CodeLocation location(previous->codeLocation(), (*next)->codeLocation());
 
         Vector<UniqueRef<AST::Expression>> callArguments;
         callArguments.append(WTFMove(previous));
@@ -1893,7 +1893,7 @@ auto Parser::parsePossiblePrefix(bool *isEffectful) -> Expected<UniqueRef<AST::E
         Token::Type::Star
     >()) {
         PARSE(next, PossiblePrefix);
-        AST::CodeLocation location(*prefix, (*next)->codeLocation());
+        CodeLocation location(*prefix, (*next)->codeLocation());
 
         switch (prefix->type) {
         case Token::Type::PlusPlus: {
@@ -2011,7 +2011,7 @@ auto Parser::parseCallExpression() -> Expected<UniqueRef<AST::Expression>, Error
     }
 
     CONSUME_TYPE(rightParenthesis, RightParenthesis);
-    AST::CodeLocation location(*name, *rightParenthesis);
+    CodeLocation location(*name, *rightParenthesis);
 
     return { makeUniqueRef<AST::CallExpression>(location, WTFMove(callName), WTFMove(arguments)) };
 }
index f6fae48..b6708b5 100644 (file)
@@ -46,6 +46,7 @@
 #include "WHLSLEffectfulExpressionStatement.h"
 #include "WHLSLEnumerationDefinition.h"
 #include "WHLSLEnumerationMember.h"
+#include "WHLSLError.h"
 #include "WHLSLExpression.h"
 #include "WHLSLFallthrough.h"
 #include "WHLSLFloatLiteral.h"
@@ -106,21 +107,7 @@ public:
         User
     };
 
-    struct Error {
-        Error(String&& error)
-            : error(WTFMove(error))
-        {
-        }
-
-        String error;
-
-        void dump(PrintStream& out) const
-        {
-            out.print(error);
-        }
-    };
-
-    Optional<Error> parse(Program&, StringView, Mode);
+    Expected<void, Error> parse(Program&, StringView, Mode);
 
 private:
     // FIXME: We should not need this
@@ -158,13 +145,13 @@ private:
     Expected<AST::TypeArgument, Error> parseTypeArgument();
     Expected<AST::TypeArguments, Error> parseTypeArguments();
     struct TypeSuffixAbbreviated {
-        AST::CodeLocation location;
+        CodeLocation location;
         Token token;
         Optional<unsigned> numElements;
     };
     Expected<TypeSuffixAbbreviated, Error> parseTypeSuffixAbbreviated();
     struct TypeSuffixNonAbbreviated {
-        AST::CodeLocation location;
+        CodeLocation location;
         Token token;
         Optional<AST::AddressSpace> addressSpace;
         Optional<unsigned> numElements;
index 27d2510..fdf9295 100644 (file)
@@ -135,10 +135,11 @@ private:
     do { \
         dumpASTBetweenEachPassIfNeeded(program, "AST before " # pass); \
         PhaseTimer phaseTimer(#pass, phaseTimes); \
-        if (!pass(__VA_ARGS__)) { \
+        auto result = pass(__VA_ARGS__); \
+        if (!result) { \
             if (dumpPassFailure) \
-                dataLogLn("failed pass: " # pass); \
-            return WTF::nullopt; \
+                dataLogLn("failed pass: " # pass, Lexer::errorString(whlslSource, result.error())); \
+            return makeUnexpected(Lexer::errorString(whlslSource, result.error())); \
         } \
     } while (0)
 
@@ -149,17 +150,18 @@ private:
         pass(__VA_ARGS__); \
     } while (0)
 
-static Optional<Program> prepareShared(PhaseTimes& phaseTimes, String& whlslSource)
+static Expected<Program, String> prepareShared(PhaseTimes& phaseTimes, String& whlslSource)
 {
     Program program;
     Parser parser;
 
     {
         PhaseTimer phaseTimer("parse", phaseTimes);
-        if (auto parseFailure = parser.parse(program, whlslSource, Parser::Mode::User)) {
+        auto parseResult = parser.parse(program, whlslSource, Parser::Mode::User);
+        if (!parseResult) {
             if (dumpPassFailure)
-                dataLogLn("failed to parse the program: ", *parseFailure);
-            return WTF::nullopt;
+                dataLogLn("failed to parse the program: ", Lexer::errorString(whlslSource, parseResult.error()));
+            return makeUnexpected(Lexer::errorString(whlslSource, parseResult.error()));
         }
     }
 
@@ -198,7 +200,7 @@ static Optional<Program> prepareShared(PhaseTimes& phaseTimes, String& whlslSour
     return program;
 }
 
-Optional<RenderPrepareResult> prepare(String& whlslSource, RenderPipelineDescriptor& renderPipelineDescriptor)
+Expected<RenderPrepareResult, String> prepare(String& whlslSource, RenderPipelineDescriptor& renderPipelineDescriptor)
 {
     PhaseTimes phaseTimes;
     Metal::RenderMetalCode generatedCode;
@@ -207,14 +209,14 @@ Optional<RenderPrepareResult> prepare(String& whlslSource, RenderPipelineDescrip
         PhaseTimer phaseTimer("prepare total", phaseTimes);
         auto program = prepareShared(phaseTimes, whlslSource);
         if (!program)
-            return WTF::nullopt;
+            return makeUnexpected(program.error());
 
         Optional<MatchedRenderSemantics> matchedSemantics;
         {
             PhaseTimer phaseTimer("matchSemantics", phaseTimes);
             matchedSemantics = matchSemantics(*program, renderPipelineDescriptor);
             if (!matchedSemantics)
-                return WTF::nullopt;
+                return makeUnexpected(Lexer::errorString(whlslSource, Error("Could not match semantics"_str)));
         }
 
         {
@@ -232,7 +234,7 @@ Optional<RenderPrepareResult> prepare(String& whlslSource, RenderPipelineDescrip
     return result;
 }
 
-Optional<ComputePrepareResult> prepare(String& whlslSource, ComputePipelineDescriptor& computePipelineDescriptor)
+Expected<ComputePrepareResult, String> prepare(String& whlslSource, ComputePipelineDescriptor& computePipelineDescriptor)
 {
     PhaseTimes phaseTimes;
     Metal::ComputeMetalCode generatedCode;
@@ -242,21 +244,21 @@ Optional<ComputePrepareResult> prepare(String& whlslSource, ComputePipelineDescr
         PhaseTimer phaseTimer("prepare total", phaseTimes);
         auto program = prepareShared(phaseTimes, whlslSource);
         if (!program)
-            return WTF::nullopt;
+            return makeUnexpected(program.error());
 
         Optional<MatchedComputeSemantics> matchedSemantics;
         {
             PhaseTimer phaseTimer("matchSemantics", phaseTimes);
             matchedSemantics = matchSemantics(*program, computePipelineDescriptor);
             if (!matchedSemantics)
-                return WTF::nullopt;
+                return makeUnexpected(Lexer::errorString(whlslSource, Error("Could not match semantics"_str)));
         }
 
         {
             PhaseTimer phaseTimer("computeDimensions", phaseTimes);
             computeDimensions = WHLSL::computeDimensions(*program, *matchedSemantics->shader);
             if (!computeDimensions)
-                return WTF::nullopt;
+                return makeUnexpected(Lexer::errorString(whlslSource, Error("Could not match compute dimensions"_str)));
         }
 
         {
index eb2021b..4ecc362 100644 (file)
@@ -27,6 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
+#include "WHLSLError.h"
 #include "WHLSLPipelineDescriptor.h"
 #include <wtf/text/WTFString.h>
 
@@ -34,13 +35,12 @@ namespace WebCore {
 
 namespace WHLSL {
 
-// FIXME: https://bugs.webkit.org/show_bug.cgi?id=195682 Generate descriptive error messages and return them here.
 struct RenderPrepareResult {
     String metalSource;
     String mangledVertexEntryPointName;
     String mangledFragmentEntryPointName;
 };
-Optional<RenderPrepareResult> prepare(String& whlslSource, RenderPipelineDescriptor&);
+Expected<RenderPrepareResult, String> prepare(String& whlslSource, RenderPipelineDescriptor&);
 
 struct ComputeDimensions {
     unsigned width;
@@ -53,7 +53,7 @@ struct ComputePrepareResult {
     String mangledEntryPointName;
     ComputeDimensions computeDimensions;
 };
-Optional<ComputePrepareResult> prepare(String& whlslSource, ComputePipelineDescriptor&);
+Expected<ComputePrepareResult, String> prepare(String& whlslSource, ComputePipelineDescriptor&);
 
 } // namespace WHLSL
 
index 0d89e4d..02fabf2 100644 (file)
@@ -156,7 +156,7 @@ static Optional<AnderCallArgumentResult> anderCallArgument(UniqueRef<AST::Expres
     return wrapAnderCallArgument<AST::MakePointerExpression, AST::PointerType>(expression, expression->resolvedType().clone(), anderFunction, threadAnderFunction);
 }
 
-static Optional<UniqueRef<AST::Expression>> setterCall(AST::PropertyAccessExpression& propertyAccessExpression, AST::FunctionDeclaration* relevantAnder, UniqueRef<AST::Expression>&& newValue, const std::function<UniqueRef<AST::Expression>()>& leftValueFactory, AST::VariableDeclaration* indexVariable)
+static UniqueRef<AST::Expression> setterCall(AST::PropertyAccessExpression& propertyAccessExpression, AST::FunctionDeclaration* relevantAnder, UniqueRef<AST::Expression>&& newValue, const std::function<UniqueRef<AST::Expression>()>& leftValueFactory, AST::VariableDeclaration* indexVariable)
 {
     auto maybeAddIndexArgument = [&](Vector<UniqueRef<AST::Expression>>& arguments) {
         if (!indexVariable)
@@ -216,7 +216,7 @@ static Optional<UniqueRef<AST::Expression>> setterCall(AST::PropertyAccessExpres
     return UniqueRef<AST::Expression>(WTFMove(assignmentExpression));
 }
 
-static Optional<UniqueRef<AST::Expression>> getterCall(AST::PropertyAccessExpression& propertyAccessExpression, AST::FunctionDeclaration* relevantAnder, const std::function<UniqueRef<AST::Expression>()>& leftValueFactory, AST::VariableDeclaration* indexVariable)
+static UniqueRef<AST::Expression> getterCall(AST::PropertyAccessExpression& propertyAccessExpression, AST::FunctionDeclaration* relevantAnder, const std::function<UniqueRef<AST::Expression>()>& leftValueFactory, AST::VariableDeclaration* indexVariable)
 {
     auto maybeAddIndexArgument = [&](Vector<UniqueRef<AST::Expression>>& arguments) {
         if (!indexVariable)
@@ -277,7 +277,7 @@ struct ModificationResult {
     Vector<UniqueRef<AST::Expression>> expressions;
     UniqueRef<AST::Expression> result;
 };
-static Optional<ModifyResult> modify(AST::PropertyAccessExpression& propertyAccessExpression, std::function<Optional<ModificationResult>(Optional<UniqueRef<AST::Expression>>&&)> modification)
+static ModifyResult modify(AST::PropertyAccessExpression& propertyAccessExpression, std::function<ModificationResult(UniqueRef<AST::Expression>&&)> modification)
 {
     // Consider a.b.c.d++;
     // This would get transformed into:
@@ -427,15 +427,12 @@ static Optional<ModifyResult> modify(AST::PropertyAccessExpression& propertyAcce
         AST::FunctionDeclaration* relevantAnder = i == chain.size() - 1 ? propertyAccessExpression.anderFunction() : propertyAccessExpression.threadAnderFunction();
         auto callExpression = getterCall(propertyAccessExpression, relevantAnder, previousLeftValue, indexVariable ? &*indexVariable : nullptr);
 
-        if (!callExpression)
-            return WTF::nullopt;
-
         auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(variableDeclaration));
         ASSERT(variableDeclaration.type());
         variableReference->setType(variableDeclaration.type()->clone());
         variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right?
 
-        auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(propertyAccessExpression.codeLocation(), WTFMove(variableReference), WTFMove(*callExpression));
+        auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(propertyAccessExpression.codeLocation(), WTFMove(variableReference), WTFMove(callExpression));
         assignmentExpression->setType(variableDeclaration.type()->clone());
         assignmentExpression->setTypeAnnotation(AST::RightValue());
 
@@ -449,13 +446,11 @@ static Optional<ModifyResult> modify(AST::PropertyAccessExpression& propertyAcce
 
     // Step 3:
     auto modificationResult = modification(WTFMove(lastGetterCallExpression));
-    if (!modificationResult)
-        return WTF::nullopt;
-    for (size_t i = 0; i < modificationResult->expressions.size(); ++i)
-        expressions.append(WTFMove(modificationResult->expressions[i]));
+    for (size_t i = 0; i < modificationResult.expressions.size(); ++i)
+        expressions.append(WTFMove(modificationResult.expressions[i]));
 
     // Step 4:
-    UniqueRef<AST::Expression> rightValue = WTFMove(modificationResult->result);
+    UniqueRef<AST::Expression> rightValue = WTFMove(modificationResult.result);
     auto expressionType = rightValue->resolvedType().clone();
     for (size_t i = 0; i < chain.size() - 1; ++i) {
         AST::PropertyAccessExpression& propertyAccessExpression = chain[i];
@@ -470,10 +465,7 @@ static Optional<ModifyResult> modify(AST::PropertyAccessExpression& propertyAcce
             return variableReference;
         }, indexVariable ? &*indexVariable : nullptr);
 
-        if (!assignmentExpression)
-            return WTF::nullopt;
-
-        expressions.append(WTFMove(*assignmentExpression));
+        expressions.append(WTFMove(assignmentExpression));
 
         rightValue = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(variableDeclaration));
         ASSERT(variableDeclaration.type());
@@ -497,10 +489,7 @@ static Optional<ModifyResult> modify(AST::PropertyAccessExpression& propertyAcce
             return dereferenceExpression;
         }, indexVariables[indexVariables.size() - 1] ? &*(indexVariables[indexVariables.size() - 1]) : nullptr);
 
-        if (!assignmentExpression)
-            return WTF::nullopt;
-
-        expressions.append(WTFMove(*assignmentExpression));
+        expressions.append(WTFMove(assignmentExpression));
     }
 
     Vector<UniqueRef<AST::VariableDeclaration>> variableDeclarations;
@@ -512,7 +501,7 @@ static Optional<ModifyResult> modify(AST::PropertyAccessExpression& propertyAcce
             variableDeclarations.append(WTFMove(*indexVariable));
     }
 
-    return {{ innerLeftExpression, WTFMove(expressions), WTFMove(variableDeclarations) }};
+    return { innerLeftExpression, WTFMove(expressions), WTFMove(variableDeclarations) };
 }
 
 void PropertyResolver::visit(AST::AssignmentExpression& assignmentExpression)
@@ -528,29 +517,25 @@ void PropertyResolver::visit(AST::AssignmentExpression& assignmentExpression)
 
     checkErrorAndVisit(assignmentExpression.right());
 
-    auto modifyResult = modify(downcast<AST::PropertyAccessExpression>(assignmentExpression.left()), [&](Optional<UniqueRef<AST::Expression>>&&) -> Optional<ModificationResult> {
-        return {{ Vector<UniqueRef<AST::Expression>>(), assignmentExpression.takeRight() }};
+    auto modifyResult = modify(downcast<AST::PropertyAccessExpression>(assignmentExpression.left()), [&](UniqueRef<AST::Expression>&&) -> ModificationResult {
+        return { Vector<UniqueRef<AST::Expression>>(), assignmentExpression.takeRight() };
     });
 
-    if (!modifyResult) {
-        setError();
-        return;
-    }
-    simplifyLeftValue(modifyResult->innerLeftValue);
+    simplifyLeftValue(modifyResult.innerLeftValue);
 
     auto location = assignmentExpression.codeLocation();
-    auto* commaExpression = AST::replaceWith<AST::CommaExpression>(assignmentExpression, location, WTFMove(modifyResult->expressions));
+    auto* commaExpression = AST::replaceWith<AST::CommaExpression>(assignmentExpression, location, WTFMove(modifyResult.expressions));
     commaExpression->setType(WTFMove(type));
     commaExpression->setTypeAnnotation(AST::RightValue());
 
-    for (auto& variableDeclaration : modifyResult->variableDeclarations)
+    for (auto& variableDeclaration : modifyResult.variableDeclarations)
         m_variableDeclarations.append(WTFMove(variableDeclaration));
 }
 
 void PropertyResolver::visit(AST::ReadModifyWriteExpression& readModifyWriteExpression)
 {
     checkErrorAndVisit(readModifyWriteExpression.newValueExpression());
-    if (error())
+    if (hasError())
         return;
 
     auto location = readModifyWriteExpression.codeLocation();
@@ -662,20 +647,18 @@ void PropertyResolver::visit(AST::ReadModifyWriteExpression& readModifyWriteExpr
 
     ASSERT(!readModifyWriteExpression.leftValue().typeAnnotation().isRightValue());
     if (!is<AST::PropertyAccessExpression>(readModifyWriteExpression.leftValue())) {
-        setError();
+        setError(Error("Base of read modify write expression is a right-value.", readModifyWriteExpression.leftValue().codeLocation()));
         return;
     }
-    auto modifyResult = modify(downcast<AST::PropertyAccessExpression>(readModifyWriteExpression.leftValue()), [&](Optional<UniqueRef<AST::Expression>>&& lastGetterCallExpression) -> Optional<ModificationResult> {
+    auto modifyResult = modify(downcast<AST::PropertyAccessExpression>(readModifyWriteExpression.leftValue()), [&](UniqueRef<AST::Expression>&& lastGetterCallExpression) -> ModificationResult {
         Vector<UniqueRef<AST::Expression>> expressions;
-        if (!lastGetterCallExpression)
-            return WTF::nullopt;
 
         {
             auto variableReference = readModifyWriteExpression.oldVariableReference();
             variableReference->setType(readModifyWriteExpression.leftValue().resolvedType().clone());
             variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right?
 
-            auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(leftValueLocation, WTFMove(variableReference), WTFMove(*lastGetterCallExpression));
+            auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(leftValueLocation, WTFMove(variableReference), WTFMove(lastGetterCallExpression));
             assignmentExpression->setType(readModifyWriteExpression.leftValue().resolvedType().clone());
             assignmentExpression->setTypeAnnotation(AST::RightValue());
 
@@ -699,27 +682,23 @@ void PropertyResolver::visit(AST::ReadModifyWriteExpression& readModifyWriteExpr
         variableReference->setType(readModifyWriteExpression.leftValue().resolvedType().clone());
         variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right?
 
-        return {{ WTFMove(expressions),  WTFMove(variableReference) }};
+        return { WTFMove(expressions),  WTFMove(variableReference) };
     });
 
-    if (!modifyResult) {
-        setError();
-        return;
-    }
-    simplifyLeftValue(modifyResult->innerLeftValue);
+    simplifyLeftValue(modifyResult.innerLeftValue);
 
     auto resultExpression = readModifyWriteExpression.takeResultExpression();
     auto type = resultExpression->resolvedType().clone();
-    modifyResult->expressions.append(WTFMove(resultExpression));
+    modifyResult.expressions.append(WTFMove(resultExpression));
 
     UniqueRef<AST::VariableDeclaration> oldVariableDeclaration = readModifyWriteExpression.takeOldValue();
     UniqueRef<AST::VariableDeclaration> newVariableDeclaration = readModifyWriteExpression.takeNewValue();
 
-    auto* commaExpression = AST::replaceWith<AST::CommaExpression>(readModifyWriteExpression, location, WTFMove(modifyResult->expressions));
+    auto* commaExpression = AST::replaceWith<AST::CommaExpression>(readModifyWriteExpression, location, WTFMove(modifyResult.expressions));
     commaExpression->setType(WTFMove(type));
     commaExpression->setTypeAnnotation(AST::RightValue());
 
-    for (auto& variableDeclaration : modifyResult->variableDeclarations)
+    for (auto& variableDeclaration : modifyResult.variableDeclarations)
         m_variableDeclarations.append(WTFMove(variableDeclaration));
     m_variableDeclarations.append(WTFMove(oldVariableDeclaration));
     m_variableDeclarations.append(WTFMove(newVariableDeclaration));
index ba497b3..704afa6 100644 (file)
@@ -54,7 +54,7 @@ private:
 
         auto addResult = m_startedVisiting.add(&functionDefinition);
         if (!addResult.isNewEntry) {
-            setError();
+            setError(Error("Cannot use recursion in the call graph.", functionDefinition.codeLocation()));
             return;
         }
 
@@ -77,11 +77,11 @@ private:
     HashSet<AST::FunctionDefinition*> m_finishedVisiting;
 };
 
-bool checkRecursion(Program& program)
+Expected<void, Error> checkRecursion(Program& program)
 {
     RecursionChecker recursionChecker;
     recursionChecker.Visitor::visit(program);
-    return !recursionChecker.error();
+    return recursionChecker.result();
 }
 
 }
index 885dff0..545f143 100644 (file)
 
 #if ENABLE(WEBGPU)
 
+#include "WHLSLError.h"
+#include <wtf/Expected.h>
+
 namespace WebCore {
 
 namespace WHLSL {
 
 class Program;
 
-bool checkRecursion(Program&);
+Expected<void, Error> checkRecursion(Program&);
 
 }
 
index dfc4854..63abb09 100644 (file)
@@ -57,7 +57,7 @@ do { \
         return; \
     auto resultStartedVisiting = m_startedVisiting.add(t); \
     if (!resultStartedVisiting.isNewEntry) { \
-        setError(); \
+        setError(Error("Cannot declare recursive types.", (t)->codeLocation())); \
         return; \
     } \
 } while (false);
@@ -102,14 +102,14 @@ void RecursiveTypeChecker::visit(AST::ReferenceType&)
 {
 }
 
-bool checkRecursiveTypes(Program& program)
+Expected<void, Error> checkRecursiveTypes(Program& program)
 {
     RecursiveTypeChecker recursiveTypeChecker;
     for (auto& typeDefinition : program.typeDefinitions())
         recursiveTypeChecker.checkErrorAndVisit(typeDefinition);
     for (auto& structureDefinition : program.structureDefinitions())
         recursiveTypeChecker.checkErrorAndVisit(structureDefinition);
-    return !recursiveTypeChecker.error();
+    return recursiveTypeChecker.result();
 }
 
 } // namespace WHLSL
index fc970c7..9d13b53 100644 (file)
@@ -27,6 +27,8 @@
 
 #if ENABLE(WEBGPU)
 
+#include "WHLSLError.h"
+#include <wtf/Expected.h>
 
 namespace WebCore {
 
@@ -34,7 +36,7 @@ namespace WHLSL {
 
 class Program;
 
-bool checkRecursiveTypes(Program&);
+Expected<void, Error> checkRecursiveTypes(Program&);
 
 }
 
index 0481b58..ee17617 100644 (file)
@@ -79,8 +79,9 @@ void includeStandardLibrary(Program& program, Parser& parser, bool parseFullStan
 {
     static NeverDestroyed<String> standardLibrary(decompressAndDecodeStandardLibrary());
     if (parseFullStandardLibrary) {
-        if (auto parseFailure = parser.parse(program, standardLibrary.get(), Parser::Mode::StandardLibrary)) {
-            dataLogLn("failed to parse the (full) standard library: ", *parseFailure);
+        auto parseResult = parser.parse(program, standardLibrary.get(), Parser::Mode::StandardLibrary);
+        if (!parseResult) {
+            dataLogLn("failed to parse the (full) standard library: ", Lexer::errorString(StringView(standardLibrary), parseResult.error()));
             ASSERT_NOT_REACHED();
         }
         return;
@@ -89,8 +90,8 @@ void includeStandardLibrary(Program& program, Parser& parser, bool parseFullStan
     static NeverDestroyed<HashMap<String, SubstringLocation>> standardLibraryFunctionMap(computeStandardLibraryFunctionMap());
 
     auto stringView = StringView(standardLibrary.get()).substring(0, firstFunctionOffsetInStandardLibrary());
-    auto parseFailure = parser.parse(program, stringView, Parser::Mode::StandardLibrary);
-    ASSERT_UNUSED(parseFailure, !parseFailure);
+    auto parseResult = parser.parse(program, stringView, Parser::Mode::StandardLibrary);
+    ASSERT_UNUSED(parseResult, parseResult);
 
     NameFinder nameFinder;
     nameFinder.Visitor::visit(program);
@@ -109,8 +110,9 @@ void includeStandardLibrary(Program& program, Parser& parser, bool parseFullStan
             if (iterator == standardLibraryFunctionMap.get().end())
                 continue;
             auto stringView = StringView(standardLibrary.get()).substring(iterator->value.start, iterator->value.end - iterator->value.start);
-            if (auto parseFailure = parser.parse(program, stringView, Parser::Mode::StandardLibrary)) {
-                dataLogLn("failed to parse the (partial) standard library: ", *parseFailure);
+            auto parseResult = parser.parse(program, stringView, Parser::Mode::StandardLibrary);
+            if (!parseResult) {
+                dataLogLn("failed to parse the (partial) standard library: ", Lexer::errorString(stringView, parseResult.error()));
                 ASSERT_NOT_REACHED();
                 return;
             }
index a4075f2..c46dae9 100644 (file)
@@ -92,7 +92,7 @@ private:
     void visit(AST::DoWhileLoop& doWhileLoop) override
     {
         checkErrorAndVisit(doWhileLoop.body());
-        if (error())
+        if (hasError())
             return;
         auto b = m_stack.takeLast();
         b.remove(Behavior::Break);
@@ -107,7 +107,7 @@ private:
         // so we can just ignore the initialization.
 
         checkErrorAndVisit(forLoop.body());
-        if (error())
+        if (hasError())
             return;
         auto b = m_stack.takeLast();
         b.remove(Behavior::Break);
@@ -119,7 +119,7 @@ private:
     void visit(AST::WhileLoop& whileLoop) override
     {
         checkErrorAndVisit(whileLoop.body());
-        if (error())
+        if (hasError())
             return;
         auto b = m_stack.takeLast();
         b.remove(Behavior::Break);
@@ -143,13 +143,13 @@ private:
         OptionSet<Behavior> reduction = { };
         for (auto& switchCase : switchStatement.switchCases()) {
             checkErrorAndVisit(switchCase);
-            if (error())
+            if (hasError())
                 return;
             auto b = m_stack.takeLast();
             reduction = reduction | b;
         }
         if (reduction.contains(Behavior::Nothing)) {
-            setError();
+            setError(Error("Switch statement must end in a break/fallthrough/return", switchStatement.codeLocation()));
             return;
         }
         reduction.remove(Behavior::Break);
@@ -161,13 +161,13 @@ private:
     void visit(AST::IfStatement& ifStatement) override
     {
         checkErrorAndVisit(ifStatement.body());
-        if (error())
+        if (hasError())
             return;
         auto b = m_stack.takeLast();
         OptionSet<Behavior> bPrime;
         if (ifStatement.elseBody()) {
             checkErrorAndVisit(*ifStatement.elseBody());
-            if (error())
+            if (hasError())
                 return;
             bPrime = m_stack.takeLast();
         } else
@@ -190,22 +190,22 @@ private:
         OptionSet<Behavior> reduction = { };
         for (size_t i = 0; i < block.statements().size() - 1; ++i) {
             checkErrorAndVisit(block.statements()[i]);
-            if (error())
+            if (hasError())
                 return;
             auto b = m_stack.takeLast();
             if (!b.contains(Behavior::Nothing)) {
-                setError();
+                setError(Error("Statement inside an inner block must be reachable.", block.statements()[i]->codeLocation()));
                 return;
             }
             b.remove(Behavior::Nothing);
             if (b.contains(Behavior::Fallthrough)) {
-                setError();
+                setError(Error("Fallthrough must be the last statement in a block.", block.statements()[i]->codeLocation()));
                 return;
             }
             reduction = reduction | b;
         }
         checkErrorAndVisit(block.statements()[block.statements().size() - 1]);
-        if (error())
+        if (hasError())
             return;
         auto b = m_stack.takeLast();
         m_stack.append(reduction | b);
@@ -219,25 +219,25 @@ private:
     Vector<OptionSet<Behavior>> m_stack;
 };
 
-bool checkStatementBehavior(Program& program)
+Expected<void, Error> checkStatementBehavior(Program& program)
 {
     StatementBehaviorChecker statementBehaviorChecker;
     for (auto& functionDefinition : program.functionDefinitions()) {
         statementBehaviorChecker.Visitor::visit(functionDefinition);
-        if (statementBehaviorChecker.error())
-            return false;
+        if (statementBehaviorChecker.hasError())
+            return statementBehaviorChecker.result();
         auto behavior = statementBehaviorChecker.takeFunctionBehavior();
         if (matches(functionDefinition->type(), program.intrinsics().voidType())) {
             behavior.remove(StatementBehaviorChecker::Behavior::Return);
             behavior.remove(StatementBehaviorChecker::Behavior::Nothing);
             if (behavior != OptionSet<StatementBehaviorChecker::Behavior>())
-                return false;
+                return makeUnexpected(Error("Cannot end a void function with a break, continue, or fallthrough."));
         } else {
             if (behavior != StatementBehaviorChecker::Behavior::Return)
-                return false;
+                return makeUnexpected(Error("Non-void functions must return a value on all code paths."));
         }
     }
-    return true;
+    return { };
 }
 
 } // namespace WHLSL
index aecdfe6..1bf1eeb 100644 (file)
 
 #if ENABLE(WEBGPU)
 
+#include "WHLSLError.h"
+#include <wtf/Expected.h>
+
 namespace WebCore {
 
 namespace WHLSL {
 
 class Program;
 
-bool checkStatementBehavior(Program&);
+Expected<void, Error> checkStatementBehavior(Program&);
 
 }
 
index 227c6a0..42eb5ea 100644 (file)
@@ -56,7 +56,7 @@ private:
     Vector<std::reference_wrapper<AST::ArrayType>> m_arrayTypes;
 };
 
-bool synthesizeArrayOperatorLength(Program& program)
+Expected<void, Error> synthesizeArrayOperatorLength(Program& program)
 {
     FindArrayTypes findArrayTypes;
     findArrayTypes.checkErrorAndVisit(program);
@@ -71,9 +71,9 @@ bool synthesizeArrayOperatorLength(Program& program)
         parameters.append(WTFMove(variableDeclaration));
         AST::NativeFunctionDeclaration nativeFunctionDeclaration(AST::FunctionDeclaration(location, AST::AttributeBlock(), WTF::nullopt, AST::TypeReference::wrap(location, program.intrinsics().uintType()), "operator.length"_str, WTFMove(parameters), nullptr, isOperator));
         if (!program.append(WTFMove(nativeFunctionDeclaration)))
-            return false;
+            return makeUnexpected(Error("Cannot synthesize operator.length for array type."));
     }
-    return true;
+    return { };
 }
 
 } // namespace WHLSL
index db77f44..c00f15b 100644 (file)
 
 #if ENABLE(WEBGPU)
 
+#include "WHLSLError.h"
+#include <wtf/Expected.h>
+
 namespace WebCore {
 
 namespace WHLSL {
 
 class Program;
 
-bool synthesizeArrayOperatorLength(Program&);
+Expected<void, Error> synthesizeArrayOperatorLength(Program&);
 
 }
 
index e0bfb67..b793f5a 100644 (file)
@@ -145,7 +145,7 @@ private:
     Vector<std::reference_wrapper<AST::NamedType>> m_namedTypes;
 };
 
-bool synthesizeConstructors(Program& program)
+Expected<void, Error> synthesizeConstructors(Program& program)
 {
     FindAllTypes findAllTypes;
     findAllTypes.checkErrorAndVisit(program);
@@ -158,15 +158,17 @@ bool synthesizeConstructors(Program& program)
         auto& unnamedType = unnamedTypeKey.unnamedType();
         auto location = unnamedType.codeLocation();
 
-        auto variableDeclaration = makeUniqueRef<AST::VariableDeclaration>(location, AST::Qualifiers(), unnamedType.clone(), String(), nullptr, nullptr);
-        AST::VariableDeclarations parameters;
-        parameters.append(WTFMove(variableDeclaration));
-        AST::NativeFunctionDeclaration copyConstructor(AST::FunctionDeclaration(location, AST::AttributeBlock(), WTF::nullopt, unnamedType.clone(), "operator cast"_str, WTFMove(parameters), nullptr, isOperator));
-        program.append(WTFMove(copyConstructor));
+        {
+            auto variableDeclaration = makeUniqueRef<AST::VariableDeclaration>(location, AST::Qualifiers(), unnamedType.clone(), String(), nullptr, nullptr);
+            AST::VariableDeclarations parameters;
+            parameters.append(WTFMove(variableDeclaration));
+            AST::NativeFunctionDeclaration copyConstructor(AST::FunctionDeclaration(location, AST::AttributeBlock(), WTF::nullopt, unnamedType.clone(), "operator cast"_str, WTFMove(parameters), nullptr, isOperator));
+            program.append(WTFMove(copyConstructor));
+        }
 
         AST::NativeFunctionDeclaration defaultConstructor(AST::FunctionDeclaration(location, AST::AttributeBlock(), WTF::nullopt, unnamedType.clone(), "operator cast"_str, AST::VariableDeclarations(), nullptr, isOperator));
         if (!program.append(WTFMove(defaultConstructor)))
-            return false;
+            return makeUnexpected(Error("Could not synthesize default constructor"));
     }
 
     for (auto& namedType : namedTypes) {
@@ -190,9 +192,9 @@ bool synthesizeConstructors(Program& program)
         }
         AST::NativeFunctionDeclaration defaultConstructor(AST::FunctionDeclaration(location, AST::AttributeBlock(), WTF::nullopt, AST::TypeReference::wrap(location, namedType.get()), "operator cast"_str, AST::VariableDeclarations(), nullptr, isOperator));
         if (!program.append(WTFMove(defaultConstructor)))
-            return false;
+            return makeUnexpected(Error("Could not synthesize default constructor"));
     }
-    return true;
+    return { };
 }
 
 } // namespace WHLSL
index 67a0863..7e8124b 100644 (file)
 
 #if ENABLE(WEBGPU)
 
+#include "WHLSLError.h"
+#include <wtf/Expected.h>
+
 namespace WebCore {
 
 namespace WHLSL {
 
 class Program;
 
-bool synthesizeConstructors(Program&);
+Expected<void, Error> synthesizeConstructors(Program&);
 
 }
 
index c0ede86..2e4e8fc 100644 (file)
@@ -36,7 +36,7 @@ namespace WebCore {
 
 namespace WHLSL {
 
-bool synthesizeEnumerationFunctions(Program& program)
+Expected<void, Error> synthesizeEnumerationFunctions(Program& program)
 {
     bool isOperator = true;
     for (auto& enumerationDefinition : program.enumerationDefinitions()) {
@@ -49,7 +49,7 @@ bool synthesizeEnumerationFunctions(Program& program)
             parameters.append(WTFMove(variableDeclaration2));
             AST::NativeFunctionDeclaration nativeFunctionDeclaration(AST::FunctionDeclaration(location, AST::AttributeBlock(), WTF::nullopt, AST::TypeReference::wrap(location, program.intrinsics().boolType()), "operator=="_str, WTFMove(parameters), nullptr, isOperator));
             if (!program.append(WTFMove(nativeFunctionDeclaration)))
-                return false;
+                return makeUnexpected(Error("Cannot create operator== for enum type."));
         }
 
         {
@@ -58,7 +58,7 @@ bool synthesizeEnumerationFunctions(Program& program)
             parameters.append(WTFMove(variableDeclaration));
             AST::NativeFunctionDeclaration nativeFunctionDeclaration(AST::FunctionDeclaration(location, AST::AttributeBlock(), WTF::nullopt, enumerationDefinition->type().clone(), "operator.value"_str, WTFMove(parameters), nullptr, isOperator));
             if (!program.append(WTFMove(nativeFunctionDeclaration)))
-                return false;
+                return makeUnexpected(Error("Cannot create operator.value for enum type."));
         }
 
         {
@@ -67,7 +67,7 @@ bool synthesizeEnumerationFunctions(Program& program)
             parameters.append(WTFMove(variableDeclaration));
             AST::NativeFunctionDeclaration nativeFunctionDeclaration(AST::FunctionDeclaration(location, AST::AttributeBlock(), WTF::nullopt, enumerationDefinition->type().clone(), "operator cast"_str, WTFMove(parameters), nullptr, isOperator));
             if (!program.append(WTFMove(nativeFunctionDeclaration)))
-                return false;
+                return makeUnexpected(Error("Cannot create copy constructor for enum type."));
         }
 
         {
@@ -76,10 +76,10 @@ bool synthesizeEnumerationFunctions(Program& program)
             parameters.append(WTFMove(variableDeclaration));
             AST::NativeFunctionDeclaration nativeFunctionDeclaration(AST::FunctionDeclaration(location, AST::AttributeBlock(), WTF::nullopt, UniqueRef<AST::UnnamedType>(AST::TypeReference::wrap(location, enumerationDefinition)), "operator cast"_str, WTFMove(parameters), nullptr, isOperator));
             if (!program.append(WTFMove(nativeFunctionDeclaration)))
-                return false;
+                return makeUnexpected(Error("Cannot create 'operator cast' for enum type."));
         }
     }
-    return true;
+    return { };
 }
 
 } // namespace WHLSL
index bf1f7ab..5f8b1d8 100644 (file)
 
 #if ENABLE(WEBGPU)
 
+#include "WHLSLError.h"
+#include <wtf/Expected.h>
+
 namespace WebCore {
 
 namespace WHLSL {
 
 class Program;
 
-bool synthesizeEnumerationFunctions(Program&);
+Expected<void, Error> synthesizeEnumerationFunctions(Program&);
 
 }
 
index 543db19..110e12d 100644 (file)
@@ -39,7 +39,7 @@ namespace WebCore {
 
 namespace WHLSL {
 
-bool synthesizeStructureAccessors(Program& program)
+Expected<void, Error> synthesizeStructureAccessors(Program& program)
 {
     bool isOperator = true;
     for (auto& structureDefinition : program.structureDefinitions()) {
@@ -58,10 +58,10 @@ bool synthesizeStructureAccessors(Program& program)
                 || !program.append(createAnder(AST::AddressSpace::Device))
                 || !program.append(createAnder(AST::AddressSpace::Threadgroup))
                 || !program.append(createAnder(AST::AddressSpace::Thread)))
-                return false;
+                return makeUnexpected(Error("Can not create ander"));
         }
     }
-    return true;
+    return { };
 }
 
 } // namespace WHLSL
index 1673162..238fe61 100644 (file)
 
 #if ENABLE(WEBGPU)
 
+#include "WHLSLError.h"
+#include <wtf/Expected.h>
+
 namespace WebCore {
 
 namespace WHLSL {
 
 class Program;
 
-bool synthesizeStructureAccessors(Program&);
+Expected<void, Error> synthesizeStructureAccessors(Program&);
 
 }
 
index 3930e69..19dfcae 100644 (file)
 
 #if ENABLE(WEBGPU)
 
+#include "WHLSLError.h"
 #include "WHLSLFunctionAttribute.h"
 #include "WHLSLSemantic.h"
 #include "WHLSLTypeArgument.h"
+#include <wtf/Expected.h>
 
 namespace WebCore {
 
@@ -178,23 +180,24 @@ public:
     virtual void visit(AST::TernaryExpression&);
     virtual void visit(AST::VariableReference&);
 
-    bool error() const { return m_error; }
+    bool hasError() const { return !m_expectedError; }
+    Expected<void, Error> result() { return m_expectedError; }
 
     template<typename T> void checkErrorAndVisit(T& x)
     {
-        if (!m_error)
+        if (!hasError())
             visit(x);
     }
 
 protected:
-    void setError()
+    void setError(Error error)
     {
-        ASSERT(!m_error);
-        m_error = true;
+        ASSERT(!hasError());
+        m_expectedError = makeUnexpected(error);
     }
 
 private:
-    bool m_error { false }; // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195682 Migrate this to be some sort of descriptive string.
+    Expected<void, Error> m_expectedError;
 };
 
 } // namespace WHLSL
index 77aba60..91a9614 100644 (file)
                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>"; };
+               1CB5FE8822DEBC8B009440E2 /* WHLSLError.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLError.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>"; };
                51FB67DA1AE6B5E400D06C5A /* ContentExtensionStyleSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContentExtensionStyleSheet.h; sourceTree = "<group>"; };
                52131E5A1C4F15610033F802 /* VideoFullscreenInterfaceMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = VideoFullscreenInterfaceMac.mm; sourceTree = "<group>"; };
                5215862C229377B7005925EF /* WHLSLAST.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLAST.h; sourceTree = "<group>"; };
+               522BAB9622E6A36200C54CE9 /* WHLSLCodeLocation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLCodeLocation.h; sourceTree = "<group>"; };
                522DA3D3229E1D390042D151 /* WHLSLGlobalVariableReference.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLGlobalVariableReference.h; sourceTree = "<group>"; };
                522E1A172297D6D400E5D36A /* WHLSLPreserveVariableLifetimes.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLPreserveVariableLifetimes.cpp; sourceTree = "<group>"; };
                522E1A192297D6D400E5D36A /* WHLSLPreserveVariableLifetimes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLPreserveVariableLifetimes.h; sourceTree = "<group>"; };
                                1C840B9721EC400700D0500D /* WHLSLChecker.h */,
                                1C281C6D22B87B9800691C00 /* WHLSLCheckTextureReferences.cpp */,
                                1C281C6E22B87B9800691C00 /* WHLSLCheckTextureReferences.h */,
+                               522BAB9622E6A36200C54CE9 /* WHLSLCodeLocation.h */,
                                1C86CA4B22AA19FF001BF961 /* WHLSLComputeDimensions.cpp */,
                                1C86CA4C22AA19FF001BF961 /* WHLSLComputeDimensions.h */,
+                               1CB5FE8822DEBC8B009440E2 /* WHLSLError.h */,
                                1CA0C2E421EED12A00A11860 /* WHLSLFunctionStageChecker.cpp */,
                                1CA0C2E521EED12A00A11860 /* WHLSLFunctionStageChecker.h */,
                                1C840B9921EC400800D0500D /* WHLSLGatherEntryPointItems.cpp */,
index 0884f27..cd7f26c 100644 (file)
@@ -76,7 +76,7 @@ static Optional<WHLSL::ComputeDimensions> trySetFunctions(const char* const func
 
         auto whlslCompileResult = WHLSL::prepare(whlslSource, *whlslDescriptor);
         if (!whlslCompileResult) {
-            errorScopes.generateError(makeString(functionName, ": WHLSL compilation failed!"));
+            errorScopes.generateError(makeString("WHLSL compilation failed. ", whlslCompileResult.error()));
             return WTF::nullopt;
         }