<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[245613] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/245613">245613</a></dd>
<dt>Author</dt> <dd>sbarati@apple.com</dd>
<dt>Date</dt> <dd>2019-05-21 20:18:03 -0700 (Tue, 21 May 2019)</dd>
</dl>

<h3>Log Message</h3>
<pre>WHLSL: Add an AST dumper
https://bugs.webkit.org/show_bug.cgi?id=198059

Reviewed by Myles Maxfield.

This patch makes it so we can dump the WHLSL program's AST.
This will become useful when we're debugging passes that
transform the AST.

The dumper mostly prints in a style where the dump is almost
valid WHLSL code. E.g, this WHLSL program:
```
int foo(int arg) {
    return arg + 1;
}
```

gets dumped as:
```
int foo(int arg) {
   return operator+(arg, 1);
}
```

This patch also adds a way to dump between each pass, after
parsing, or at the end of all passes. Currently, this is controlled
by a static variable. I'll make these runtime configurable in a follow
up: https://bugs.webkit.org/show_bug.cgi?id=198097

No new tests because this is used for logging.

* Modules/webgpu/WHLSL/AST/WHLSLAST.h: Added.
* Modules/webgpu/WHLSL/AST/WHLSLAddressSpace.h:
(WebCore::WHLSL::AST::toString):
* Modules/webgpu/WHLSL/AST/WHLSLBuiltInSemantic.h:
(WebCore::WHLSL::AST::BuiltInSemantic::toString const):
* Modules/webgpu/WHLSL/AST/WHLSLEntryPointType.h:
(WebCore::WHLSL::AST::toString):
* Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.h:
(WebCore::WHLSL::AST::ResourceSemantic::toString):
* Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp:
(WebCore::WHLSL::Metal::toString): Deleted.
* Modules/webgpu/WHLSL/WHLSLASTDumper.cpp: Added.
(WebCore::WHLSL::ASTDumper::visit):
* Modules/webgpu/WHLSL/WHLSLASTDumper.h: Added.
(WebCore::WHLSL::ASTDumper::toString):
(WebCore::WHLSL::ASTDumper::Indent::Indent):
(WebCore::WHLSL::ASTDumper::bumpIndent):
(WebCore::WHLSL::toString):
(WebCore::WHLSL::dumpAST):
* Modules/webgpu/WHLSL/WHLSLPrepare.cpp:
(WebCore::WHLSL::dumpASTIfNeeded):
(WebCore::WHLSL::dumpASTAfterParsingIfNeeded):
(WebCore::WHLSL::dumpASTBetweenEachPassIfNeeded):
(WebCore::WHLSL::dumpASTAtEndIfNeeded):
(WebCore::WHLSL::prepareShared):
* Modules/webgpu/WHLSL/WHLSLVisitor.cpp:
* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModuleswebgpuWHLSLASTWHLSLAddressSpaceh">trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAddressSpace.h</a></li>
<li><a href="#trunkSourceWebCoreModuleswebgpuWHLSLASTWHLSLBuiltInSemantich">trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBuiltInSemantic.h</a></li>
<li><a href="#trunkSourceWebCoreModuleswebgpuWHLSLASTWHLSLEntryPointTypeh">trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEntryPointType.h</a></li>
<li><a href="#trunkSourceWebCoreModuleswebgpuWHLSLASTWHLSLResourceSemantich">trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.h</a></li>
<li><a href="#trunkSourceWebCoreModuleswebgpuWHLSLMetalWHLSLTypeNamercpp">trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp</a></li>
<li><a href="#trunkSourceWebCoreModuleswebgpuWHLSLWHLSLPreparecpp">trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp</a></li>
<li><a href="#trunkSourceWebCoreModuleswebgpuWHLSLWHLSLVisitorcpp">trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.cpp</a></li>
<li><a href="#trunkSourceWebCoreSourcestxt">trunk/Source/WebCore/Sources.txt</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreModuleswebgpuWHLSLASTWHLSLASTh">trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAST.h</a></li>
<li><a href="#trunkSourceWebCoreModuleswebgpuWHLSLWHLSLASTDumpercpp">trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.cpp</a></li>
<li><a href="#trunkSourceWebCoreModuleswebgpuWHLSLWHLSLASTDumperh">trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (245612 => 245613)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2019-05-22 03:05:35 UTC (rev 245612)
+++ trunk/Source/WebCore/ChangeLog      2019-05-22 03:18:03 UTC (rev 245613)
</span><span class="lines">@@ -1,5 +1,67 @@
</span><span class="cx"> 2019-05-21  Saam barati  <sbarati@apple.com>
</span><span class="cx"> 
</span><ins>+        WHLSL: Add an AST dumper
+        https://bugs.webkit.org/show_bug.cgi?id=198059
+
+        Reviewed by Myles Maxfield.
+
+        This patch makes it so we can dump the WHLSL program's AST.
+        This will become useful when we're debugging passes that
+        transform the AST.
+        
+        The dumper mostly prints in a style where the dump is almost
+        valid WHLSL code. E.g, this WHLSL program:
+        ```
+        int foo(int arg) {
+            return arg + 1;
+        }
+        ```
+        
+        gets dumped as:
+        ```
+        int foo(int arg) {
+           return operator+(arg, 1);
+        }
+        ```
+        
+        This patch also adds a way to dump between each pass, after
+        parsing, or at the end of all passes. Currently, this is controlled
+        by a static variable. I'll make these runtime configurable in a follow
+        up: https://bugs.webkit.org/show_bug.cgi?id=198097
+
+        No new tests because this is used for logging.
+
+        * Modules/webgpu/WHLSL/AST/WHLSLAST.h: Added.
+        * Modules/webgpu/WHLSL/AST/WHLSLAddressSpace.h:
+        (WebCore::WHLSL::AST::toString):
+        * Modules/webgpu/WHLSL/AST/WHLSLBuiltInSemantic.h:
+        (WebCore::WHLSL::AST::BuiltInSemantic::toString const):
+        * Modules/webgpu/WHLSL/AST/WHLSLEntryPointType.h:
+        (WebCore::WHLSL::AST::toString):
+        * Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.h:
+        (WebCore::WHLSL::AST::ResourceSemantic::toString):
+        * Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp:
+        (WebCore::WHLSL::Metal::toString): Deleted.
+        * Modules/webgpu/WHLSL/WHLSLASTDumper.cpp: Added.
+        (WebCore::WHLSL::ASTDumper::visit):
+        * Modules/webgpu/WHLSL/WHLSLASTDumper.h: Added.
+        (WebCore::WHLSL::ASTDumper::toString):
+        (WebCore::WHLSL::ASTDumper::Indent::Indent):
+        (WebCore::WHLSL::ASTDumper::bumpIndent):
+        (WebCore::WHLSL::toString):
+        (WebCore::WHLSL::dumpAST):
+        * Modules/webgpu/WHLSL/WHLSLPrepare.cpp:
+        (WebCore::WHLSL::dumpASTIfNeeded):
+        (WebCore::WHLSL::dumpASTAfterParsingIfNeeded):
+        (WebCore::WHLSL::dumpASTBetweenEachPassIfNeeded):
+        (WebCore::WHLSL::dumpASTAtEndIfNeeded):
+        (WebCore::WHLSL::prepareShared):
+        * Modules/webgpu/WHLSL/WHLSLVisitor.cpp:
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+
+2019-05-21  Saam barati  <sbarati@apple.com>
+
</ins><span class="cx">         WHLSL: Parsing negative int literals parses the positive value instead
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=198096
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebgpuWHLSLASTWHLSLASTh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAST.h (0 => 245613)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAST.h                         (rev 0)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAST.h    2019-05-22 03:18:03 UTC (rev 245613)
</span><span class="lines">@@ -0,0 +1,106 @@
</span><ins>+/*
+ * 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 "WHLSLAddressSpace.h"
+#include "WHLSLArrayReferenceType.h"
+#include "WHLSLArrayType.h"
+#include "WHLSLAssignmentExpression.h"
+#include "WHLSLBaseFunctionAttribute.h"
+#include "WHLSLBaseSemantic.h"
+#include "WHLSLBlock.h"
+#include "WHLSLBooleanLiteral.h"
+#include "WHLSLBreak.h"
+#include "WHLSLBuiltInSemantic.h"
+#include "WHLSLCallExpression.h"
+#include "WHLSLCommaExpression.h"
+#include "WHLSLConstantExpression.h"
+#include "WHLSLContinue.h"
+#include "WHLSLDereferenceExpression.h"
+#include "WHLSLDoWhileLoop.h"
+#include "WHLSLDotExpression.h"
+#include "WHLSLEffectfulExpressionStatement.h"
+#include "WHLSLEntryPointType.h"
+#include "WHLSLEnumerationDefinition.h"
+#include "WHLSLEnumerationMember.h"
+#include "WHLSLEnumerationMemberLiteral.h"
+#include "WHLSLExpression.h"
+#include "WHLSLFallthrough.h"
+#include "WHLSLFloatLiteral.h"
+#include "WHLSLFloatLiteralType.h"
+#include "WHLSLForLoop.h"
+#include "WHLSLFunctionAttribute.h"
+#include "WHLSLFunctionDeclaration.h"
+#include "WHLSLFunctionDefinition.h"
+#include "WHLSLIfStatement.h"
+#include "WHLSLIndexExpression.h"
+#include "WHLSLIntegerLiteral.h"
+#include "WHLSLIntegerLiteralType.h"
+#include "WHLSLLogicalExpression.h"
+#include "WHLSLLogicalNotExpression.h"
+#include "WHLSLMakeArrayReferenceExpression.h"
+#include "WHLSLMakePointerExpression.h"
+#include "WHLSLNamedType.h"
+#include "WHLSLNativeFunctionDeclaration.h"
+#include "WHLSLNativeTypeDeclaration.h"
+#include "WHLSLNode.h"
+#include "WHLSLNullLiteral.h"
+#include "WHLSLNullLiteralType.h"
+#include "WHLSLNumThreadsFunctionAttribute.h"
+#include "WHLSLPointerType.h"
+#include "WHLSLPropertyAccessExpression.h"
+#include "WHLSLQualifier.h"
+#include "WHLSLReadModifyWriteExpression.h"
+#include "WHLSLReferenceType.h"
+#include "WHLSLResolvableType.h"
+#include "WHLSLResourceSemantic.h"
+#include "WHLSLReturn.h"
+#include "WHLSLSemantic.h"
+#include "WHLSLSpecializationConstantSemantic.h"
+#include "WHLSLStageInOutSemantic.h"
+#include "WHLSLStatement.h"
+#include "WHLSLStructureDefinition.h"
+#include "WHLSLStructureElement.h"
+#include "WHLSLSwitchCase.h"
+#include "WHLSLSwitchStatement.h"
+#include "WHLSLTernaryExpression.h"
+#include "WHLSLTrap.h"
+#include "WHLSLType.h"
+#include "WHLSLTypeArgument.h"
+#include "WHLSLTypeDefinition.h"
+#include "WHLSLTypeReference.h"
+#include "WHLSLUnnamedType.h"
+#include "WHLSLUnsignedIntegerLiteral.h"
+#include "WHLSLUnsignedIntegerLiteralType.h"
+#include "WHLSLValue.h"
+#include "WHLSLVariableDeclaration.h"
+#include "WHLSLVariableDeclarationsStatement.h"
+#include "WHLSLVariableReference.h"
+#include "WHLSLWhileLoop.h"
+
+#endif
</ins></span></pre></div>
<a id="trunkSourceWebCoreModuleswebgpuWHLSLASTWHLSLAddressSpaceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAddressSpace.h (245612 => 245613)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAddressSpace.h        2019-05-22 03:05:35 UTC (rev 245612)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAddressSpace.h   2019-05-22 03:18:03 UTC (rev 245613)
</span><span class="lines">@@ -42,6 +42,19 @@
</span><span class="cx">     Thread
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+static ALWAYS_INLINE String toString(AddressSpace addressSpace)
+{
+    switch (addressSpace) {
+    case AddressSpace::Constant:
+        return "constant"_str;
+    case AddressSpace::Device:
+        return "device"_str;
+    case AddressSpace::Threadgroup:
+        return "threadgroup"_str;
+    default:
+        ASSERT(addressSpace == AddressSpace::Thread);
+        return "thread"_str;
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> }
</span><span class="lines">@@ -48,4 +61,6 @@
</span><span class="cx"> 
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+}
+
</ins><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebgpuWHLSLASTWHLSLBuiltInSemantich"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBuiltInSemantic.h (245612 => 245613)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBuiltInSemantic.h     2019-05-22 03:05:35 UTC (rev 245612)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLBuiltInSemantic.h        2019-05-22 03:18:03 UTC (rev 245613)
</span><span class="lines">@@ -81,6 +81,40 @@
</span><span class="cx">         return !(*this == other);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    String toString() const
+    {
+        switch (m_variable) {
+        case Variable::SVInstanceID:
+            return "SVInstanceID";
+        case Variable::SVVertexID:
+            return "SVVertexID";
+        case Variable::PSize:
+            return "PSize";
+        case Variable::SVPosition:
+            return "SVPosition";
+        case Variable::SVIsFrontFace:
+            return "SVIsFrontFace";
+        case Variable::SVSampleIndex:
+            return "SVSampleIndex";
+        case Variable::SVInnerCoverage:
+            return "SVInnerCoverage";
+        case Variable::SVTarget:
+            return "SVTarget";
+        case Variable::SVDepth:
+            return "SVDepth";
+        case Variable::SVCoverage:
+            return "SVCoverage";
+        case Variable::SVDispatchThreadID:
+            return "SVDispatchThreadID";
+        case Variable::SVGroupID:
+            return "SVGroupID";
+        case Variable::SVGroupIndex:
+            return "SVGroupIndex";
+        case Variable::SVGroupThreadID:
+            return "SVGroupThreadID";
+        }
+    }
+
</ins><span class="cx">     bool isAcceptableType(const UnnamedType&, const Intrinsics&) const override;
</span><span class="cx">     bool isAcceptableForShaderItemDirection(ShaderItemDirection, const Optional<EntryPointType>&) const override;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebgpuWHLSLASTWHLSLEntryPointTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEntryPointType.h (245612 => 245613)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEntryPointType.h      2019-05-22 03:05:35 UTC (rev 245612)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLEntryPointType.h 2019-05-22 03:18:03 UTC (rev 245613)
</span><span class="lines">@@ -42,6 +42,16 @@
</span><span class="cx">     // FIXME: Add an entry point type for testing
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+static ALWAYS_INLINE String toString(EntryPointType type)
+{
+    switch (type) {
+    case EntryPointType::Vertex:
+        return "vertex";
+    case EntryPointType::Fragment:
+        return "fragment";
+    case EntryPointType::Compute:
+        return "compute";
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> }
</span><span class="lines">@@ -48,4 +58,6 @@
</span><span class="cx"> 
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+}
+
</ins><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebgpuWHLSLASTWHLSLResourceSemantich"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.h (245612 => 245613)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.h    2019-05-22 03:05:35 UTC (rev 245612)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.h       2019-05-22 03:18:03 UTC (rev 245613)
</span><span class="lines">@@ -58,6 +58,20 @@
</span><span class="cx">     ResourceSemantic(const ResourceSemantic&) = delete;
</span><span class="cx">     ResourceSemantic(ResourceSemantic&&) = default;
</span><span class="cx"> 
</span><ins>+    String toString()
+    {
+        switch (m_mode) {
+        case Mode::UnorderedAccessView:
+            return "UnorderedAccessView";
+        case Mode::Texture:
+            return "Texture";
+        case Mode::Buffer:
+            return "Buffer";
+        case Mode::Sampler:
+            return "Sampler";
+        }
+    }
+
</ins><span class="cx">     Mode mode() const { return m_mode; }
</span><span class="cx">     unsigned index() const { return m_index; }
</span><span class="cx">     unsigned space() const { return m_space; }
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebgpuWHLSLMetalWHLSLTypeNamercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp (245612 => 245613)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp       2019-05-22 03:05:35 UTC (rev 245612)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp  2019-05-22 03:18:03 UTC (rev 245613)
</span><span class="lines">@@ -380,21 +380,6 @@
</span><span class="cx">     return metalTypeDeclarationWriter.toString();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static String toString(AST::AddressSpace addressSpace)
-{
-    switch (addressSpace) {
-    case AST::AddressSpace::Constant:
-        return "constant"_str;
-    case AST::AddressSpace::Device:
-        return "device"_str;
-    case AST::AddressSpace::Threadgroup:
-        return "threadgroup"_str;
-    default:
-        ASSERT(addressSpace == AST::AddressSpace::Thread);
-        return "thread"_str;
-    }
-}
-
</del><span class="cx"> void TypeNamer::emitUnnamedTypeDefinition(BaseTypeNameNode& baseTypeNameNode, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes, StringBuilder& stringBuilder)
</span><span class="cx"> {
</span><span class="cx">     if (emittedUnnamedTypes.contains(&baseTypeNameNode))
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebgpuWHLSLWHLSLASTDumpercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.cpp (0 => 245613)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.cpp                             (rev 0)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.cpp        2019-05-22 03:18:03 UTC (rev 245613)
</span><span class="lines">@@ -0,0 +1,652 @@
</span><ins>+/*
+ * 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.
+ */
+
+#include "config.h"
+#include "WHLSLASTDumper.h"
+
+#if ENABLE(WEBGPU)
+
+#include "WHLSLAST.h"
+#include "WHLSLProgram.h"
+
+namespace WebCore {
+
+namespace WHLSL {
+
+void ASTDumper::visit(Program& program)
+{
+    m_out.println();
+
+    for (size_t i = 0; i < program.nativeTypeDeclarations().size(); ++i)
+        visit(program.nativeTypeDeclarations()[i]);
+    if (program.nativeTypeDeclarations().size())
+        m_out.print("\n\n");
+
+    for (size_t i = 0; i < program.nativeFunctionDeclarations().size(); ++i)
+        visit(program.nativeFunctionDeclarations()[i]);
+    if (program.nativeFunctionDeclarations().size())
+        m_out.print("\n\n");
+
+    for (size_t i = 0; i < program.typeDefinitions().size(); ++i)
+        visit(program.typeDefinitions()[i]);
+    if (program.typeDefinitions().size())
+        m_out.print("\n\n");
+
+    for (size_t i = 0; i < program.structureDefinitions().size(); ++i)
+        visit(program.structureDefinitions()[i]);
+    if (program.structureDefinitions().size())
+        m_out.print("\n\n");
+
+    for (size_t i = 0; i < program.enumerationDefinitions().size(); ++i)
+        visit(program.enumerationDefinitions()[i]);
+    if (program.enumerationDefinitions().size())
+        m_out.print("\n\n");
+
+    for (size_t i = 0; i < program.functionDefinitions().size(); ++i)
+        visit(program.functionDefinitions()[i]);
+
+    m_out.println();
+}
+
+void ASTDumper::visit(AST::UnnamedType& unnamedType)
+{
+    Base::visit(unnamedType);
+}
+
+void ASTDumper::visit(AST::NamedType& namedType)
+{
+    Base::visit(namedType);
+}
+
+void ASTDumper::visit(AST::TypeDefinition& typeDefinition)
+{
+    m_out.print("typedef ", typeDefinition.name(), " = ");
+    visit(typeDefinition.type());
+    m_out.println(";");
+}
+
+void ASTDumper::visit(AST::StructureDefinition& structureDefinition)
+{
+    m_out.println(m_indent, "struct ", structureDefinition.name(), " {");
+    {
+        auto indent = bumpIndent();
+        for (auto& structureElement : structureDefinition.structureElements())
+            visit(structureElement);
+    }
+    m_out.println(m_indent, "}");
+    m_out.println();
+}
+
+void ASTDumper::visit(AST::StructureElement& structureElement)
+{
+    m_out.print(m_indent);
+    visit(structureElement.type());
+    m_out.print(" ", structureElement.name());
+    if (structureElement.semantic())
+        visit(*structureElement.semantic());
+    m_out.println(";");
+}
+
+void ASTDumper::visit(AST::EnumerationDefinition& enumerationDefinition)
+{
+    // FIXME: Test this once we parse enums:
+    // https://bugs.webkit.org/show_bug.cgi?id=198087
+
+    m_out.println(m_indent, "enum ");
+    visit(enumerationDefinition.type());
+    m_out.print(" {");
+
+    {
+        auto indent = bumpIndent();
+        bool once = false;
+        for (auto& enumerationMember : enumerationDefinition.enumerationMembers()) {
+            if (once)
+                m_out.print(", ");
+            m_out.println();
+            m_out.print(m_indent);
+            visit(enumerationMember);
+        }
+    }
+
+    m_out.println();
+    m_out.println(m_indent, "}");
+    m_out.println();
+}
+
+void ASTDumper::visit(AST::EnumerationMember& enumerationMember)
+{
+    m_out.print(enumerationMember.name());
+    if (enumerationMember.value()) {
+        m_out.print(" = ");
+        visit(*enumerationMember.value());
+    }
+}
+
+void ASTDumper::visit(AST::FunctionDefinition& functionDefinition)
+{
+    m_out.print(m_indent);
+    visit(static_cast<AST::FunctionDeclaration&>(functionDefinition));
+    visit(functionDefinition.block());
+    m_out.print("\n\n");
+}
+
+void ASTDumper::visit(AST::NativeFunctionDeclaration& nativeFunctionDeclaration)
+{
+    m_out.print(m_indent);
+    m_out.print("native ");
+    visit(static_cast<AST::FunctionDeclaration&>(nativeFunctionDeclaration));
+    m_out.println();
+}
+
+void ASTDumper::visit(AST::FunctionDeclaration& functionDeclaration)
+{
+    visit(functionDeclaration.attributeBlock());
+    if (functionDeclaration.entryPointType())
+        m_out.print(AST::toString(*functionDeclaration.entryPointType()), " ");
+    visit(functionDeclaration.type());
+    m_out.print(" ", functionDeclaration.name(), "(");
+    bool once = false;
+    for (auto& parameter : functionDeclaration.parameters()) {
+        if (once)
+            m_out.print(", ");
+        once = true;
+        visit(parameter);
+    }
+    m_out.print(")");
+    if (functionDeclaration.semantic())
+        visit(*functionDeclaration.semantic());
+    m_out.print(" ");
+}
+
+void ASTDumper::visit(AST::NativeTypeDeclaration& nativeTypeDeclaration)
+{
+    m_out.print(m_indent, "native typedef ");
+    m_out.print(nativeTypeDeclaration.name());
+    if (nativeTypeDeclaration.typeArguments().size()) {
+        m_out.print("<");
+        bool once = false;
+        for (auto& typeArgument : nativeTypeDeclaration.typeArguments()) {
+            if (once)
+                m_out.print(", ");
+            once = true;
+            visit(typeArgument);
+        }
+        m_out.print(">");
+    }
+    m_out.println(";");
+}
+
+void ASTDumper::visit(AST::TypeReference& typeReference)
+{
+    m_out.print(typeReference.name());
+
+    if (typeReference.typeArguments().size()) {
+        bool once = false;
+        m_out.print("<");
+        for (auto& typeArgument : typeReference.typeArguments()) {
+            if (once)
+                m_out.print(", ");
+            once = true;
+            visit(typeArgument);
+        }
+        m_out.print(">");
+    }
+}
+
+void ASTDumper::visit(AST::PointerType& pointerType)
+{
+    visit(static_cast<AST::ReferenceType&>(pointerType));
+    m_out.print("*");
+}
+
+void ASTDumper::visit(AST::ArrayReferenceType& arrayReferenceType)
+{
+    visit(static_cast<AST::ReferenceType&>(arrayReferenceType));
+    m_out.print("[]");
+}
+
+void ASTDumper::visit(AST::ArrayType& arrayType)
+{
+    visit(arrayType.type());
+    m_out.print("[", arrayType.numElements(), "]");
+}
+
+void ASTDumper::visit(AST::TypeArgument& typeArgument)
+{
+    Base::visit(typeArgument);
+}
+
+void ASTDumper::visit(AST::ReferenceType& referenceType)
+{
+    m_out.print(AST::toString(referenceType.addressSpace()), " ");
+    visit(referenceType.elementType());
+}
+
+void ASTDumper::visit(AST::Semantic& semantic)
+{
+    m_out.print(" : ");
+    WTF::visit(WTF::makeVisitor([&](AST::BuiltInSemantic& builtInSemantic) {
+        visit(builtInSemantic);
+    }, [&](AST::ResourceSemantic& resourceSemantic) {
+        visit(resourceSemantic);
+    }, [&](AST::SpecializationConstantSemantic& specializationConstantSemantic) {
+        visit(specializationConstantSemantic);
+    }, [&](AST::StageInOutSemantic& stageInOutSemantic) {
+        visit(stageInOutSemantic);
+    }), semantic);
+}
+
+void ASTDumper::visit(AST::ConstantExpression& constantExpression)
+{
+    Base::visit(constantExpression);
+}
+
+void ASTDumper::visit(AST::AttributeBlock& attributeBlock)
+{
+    if (attributeBlock.isEmpty())
+        return;
+
+    m_out.print("[");
+    for (auto& functionAttribute : attributeBlock)
+        visit(functionAttribute);
+    m_out.print("] ");
+}
+
+void ASTDumper::visit(AST::BuiltInSemantic& builtInSemantic)
+{
+    m_out.print(builtInSemantic.toString());
+}
+
+void ASTDumper::visit(AST::ResourceSemantic& resourceSemantic)
+{
+    m_out.print(resourceSemantic.toString());
+}
+
+void ASTDumper::visit(AST::SpecializationConstantSemantic&)
+{
+    // FIXME: Handle this when we implement it.
+}
+
+void ASTDumper::visit(AST::StageInOutSemantic& stageInOutSemantic)
+{
+    m_out.print("attribute(", stageInOutSemantic.index(), ")");
+}
+
+void ASTDumper::visit(AST::IntegerLiteral& integerLiteral)
+{
+    m_out.print(integerLiteral.value());
+}
+
+void ASTDumper::visit(AST::UnsignedIntegerLiteral& unsignedIntegerLiteral)
+{
+    m_out.print(unsignedIntegerLiteral.value());
+}
+
+void ASTDumper::visit(AST::FloatLiteral& floatLiteral)
+{
+    m_out.print(floatLiteral.value());
+}
+
+void ASTDumper::visit(AST::NullLiteral& nullLiteral)
+{
+    m_out.print("null");
+    visit(nullLiteral.type());
+}
+
+void ASTDumper::visit(AST::BooleanLiteral& booleanLiteral)
+{
+    if (booleanLiteral.value())
+        m_out.print("true");
+    else
+        m_out.print("false");
+}
+
+void ASTDumper::visit(AST::IntegerLiteralType&)
+{
+}
+
+void ASTDumper::visit(AST::UnsignedIntegerLiteralType&)
+{
+}
+
+void ASTDumper::visit(AST::FloatLiteralType&)
+{
+}
+
+void ASTDumper::visit(AST::NullLiteralType&)
+{
+}
+
+void ASTDumper::visit(AST::EnumerationMemberLiteral&)
+{
+    // FIXME: Handle this when we can parse enums:
+    // https://bugs.webkit.org/show_bug.cgi?id=198087
+}
+
+void ASTDumper::visit(AST::FunctionAttribute& functionAttribute)
+{
+    WTF::visit(WTF::makeVisitor([&](AST::NumThreadsFunctionAttribute& numThreadsFunctionAttribute) {
+        visit(numThreadsFunctionAttribute);
+    }), functionAttribute);
+}
+
+void ASTDumper::visit(AST::NumThreadsFunctionAttribute& numThreadsAttribute)
+{
+    m_out.print("numthreads(", numThreadsAttribute.width(), ", ", numThreadsAttribute.height(), ", ", numThreadsAttribute.depth(), ")");
+}
+
+void ASTDumper::visit(AST::Block& block)
+{
+    m_out.println("{");
+    {
+        auto indent = bumpIndent();
+        for (auto& statement : block.statements()) {
+            m_out.print(m_indent);
+            visit(statement);
+            m_out.println(";");
+        }
+    }
+    m_out.print(m_indent, "}");
+}
+
+void ASTDumper::visit(AST::Statement& statement)
+{
+    Base::visit(statement);
+}
+
+void ASTDumper::visit(AST::Break&)
+{
+    m_out.print("break");
+}
+
+void ASTDumper::visit(AST::Continue&)
+{
+    m_out.print("continue");
+}
+
+void ASTDumper::visit(AST::WhileLoop& whileLoop)
+{
+    m_out.print("while (");
+    visit(whileLoop.conditional());
+    m_out.print(")");
+    visit(whileLoop.body());
+}
+
+void ASTDumper::visit(AST::DoWhileLoop& doWhileLoop)
+{
+    m_out.print("do ");
+    visit(doWhileLoop.body());
+    m_out.print(" while(");
+    visit(doWhileLoop.conditional());
+    m_out.print(")");
+}
+
+void ASTDumper::visit(AST::ForLoop& forLoop)
+{
+    m_out.print("for (");
+    WTF::visit(WTF::makeVisitor([&](AST::VariableDeclarationsStatement& variableDeclarationsStatement) {
+        visit(variableDeclarationsStatement);
+    }, [&](UniqueRef<AST::Expression>& expression) {
+        visit(expression);
+    }), forLoop.initialization());
+    m_out.print("; ");
+    if (forLoop.condition())
+        visit(*forLoop.condition());
+    m_out.print("; ");
+    if (forLoop.increment())
+        visit(*forLoop.increment());
+    m_out.print(") ");
+    visit(forLoop.body());
+}
+
+void ASTDumper::visit(AST::Expression& expression)
+{
+    Base::visit(expression);
+}
+
+void ASTDumper::visit(AST::DotExpression& dotExpression)
+{
+    visit(static_cast<AST::PropertyAccessExpression&>(dotExpression));
+    m_out.print(".", dotExpression.fieldName());
+}
+
+void ASTDumper::visit(AST::IndexExpression& indexExpression)
+{
+    visit(static_cast<AST::PropertyAccessExpression&>(indexExpression));
+    m_out.print("[");
+    visit(indexExpression.indexExpression());
+    m_out.print("]");
+}
+
+void ASTDumper::visit(AST::PropertyAccessExpression& expression)
+{
+    Base::visit(expression);
+}
+
+void ASTDumper::visit(AST::EffectfulExpressionStatement& effectfulExpressionStatement)
+{
+    Base::visit(effectfulExpressionStatement);
+}
+
+void ASTDumper::visit(AST::Fallthrough&)
+{
+    m_out.print("fallthrough");
+}
+
+void ASTDumper::visit(AST::IfStatement& ifStatement)
+{
+    m_out.print("if (");
+    visit(ifStatement.conditional());
+    m_out.print(") ");
+    visit(ifStatement.body());
+    if (ifStatement.elseBody()) {
+        m_out.print(" else ");
+        visit(*ifStatement.elseBody());
+    }
+}
+
+void ASTDumper::visit(AST::Return& returnStatement)
+{
+    m_out.print("return");
+    if (returnStatement.value()) {
+        m_out.print(" ");
+        visit(*returnStatement.value());
+    }
+}
+
+void ASTDumper::visit(AST::Trap&)
+{
+    m_out.print("trap");
+}
+
+void ASTDumper::visit(AST::SwitchStatement& switchStatement)
+{
+    m_out.print("switch (");
+    visit(switchStatement.value());
+    m_out.println(") {");
+    bool once = false;
+    for (auto& switchCase : switchStatement.switchCases()) {
+        if (once)
+            m_out.println();
+        once = true;
+        m_out.print(m_indent);
+        visit(switchCase);
+    }
+    m_out.print("\n", m_indent, "}");
+
+}
+
+void ASTDumper::visit(AST::SwitchCase& switchCase)
+{
+    if (switchCase.value()) {
+        m_out.print("case ");
+        visit(*switchCase.value());
+        m_out.print(": ");
+    } else
+        m_out.print("default: ");
+    visit(switchCase.block());
+}
+
+void ASTDumper::visit(AST::VariableDeclarationsStatement& variableDeclarationsStatement)
+{
+    Base::visit(variableDeclarationsStatement);
+}
+
+void ASTDumper::visit(AST::VariableDeclaration& variableDeclaration)
+{
+    if (variableDeclaration.type()) {
+        visit(*variableDeclaration.type());
+        m_out.print(" ");
+    }
+    m_out.print(variableDeclaration.name());
+    if (variableDeclaration.semantic())
+        visit(*variableDeclaration.semantic());
+    if (variableDeclaration.initializer()) {
+        m_out.print(" = ");
+        visit(*variableDeclaration.initializer());
+    }
+}
+
+void ASTDumper::visit(AST::AssignmentExpression& assignmentExpression)
+{
+    visit(assignmentExpression.left());
+    m_out.print(" = ");
+    visit(assignmentExpression.right());
+}
+
+void ASTDumper::visit(AST::CallExpression& callExpression)
+{
+    m_out.print(callExpression.name(), "(");
+    bool once = false;
+    for (auto& argument : callExpression.arguments()) {
+        if (once)
+            m_out.print(", ");
+        once = true;
+        visit(argument);
+    }
+    m_out.print(")");
+}
+
+void ASTDumper::visit(AST::CommaExpression& commaExpression)
+{
+    m_out.print("(");
+    bool once = false;
+    for (auto& expression : commaExpression.list()) {
+        if (once)
+            m_out.print(", ");
+        once = true;
+        visit(expression);
+    }
+    m_out.print(")");
+}
+
+void ASTDumper::visit(AST::DereferenceExpression& dereferenceExpression)
+{
+    m_out.print("*");
+    visit(dereferenceExpression.pointer());
+}
+
+void ASTDumper::visit(AST::LogicalExpression& logicalExpression)
+{
+    m_out.print("(");
+    visit(logicalExpression.left());
+    switch (logicalExpression.type()) {
+    case AST::LogicalExpression::Type::And:
+        m_out.print(" && ");
+        break;
+    case AST::LogicalExpression::Type::Or:
+        m_out.print(" || ");
+        break;
+    }
+    visit(logicalExpression.right());
+    m_out.print(")");
+}
+
+void ASTDumper::visit(AST::LogicalNotExpression& logicalNotExpression)
+{
+    m_out.print("!(");
+    visit(logicalNotExpression.operand());
+    m_out.print(")");
+}
+
+void ASTDumper::visit(AST::MakeArrayReferenceExpression& makeArrayReferenceExpression)
+{
+    m_out.print("@");
+    visit(makeArrayReferenceExpression.lValue());
+}
+
+void ASTDumper::visit(AST::MakePointerExpression& makePointerExpression)
+{
+    m_out.print("&");
+    visit(makePointerExpression.lValue());
+}
+
+void ASTDumper::visit(AST::ReadModifyWriteExpression& readModifyWriteExpression)
+{
+    auto oldVariable = readModifyWriteExpression.oldVariableReference();
+    auto newVariable = readModifyWriteExpression.newVariableReference();
+
+    m_out.print("(");
+    visit(oldVariable.get());
+    m_out.print(" = ");
+    visit(readModifyWriteExpression.lValue());
+    m_out.print(", ");
+
+    visit(newVariable.get());
+    m_out.print(" = ");
+    visit(*readModifyWriteExpression.newValueExpression());
+    m_out.print(", ");
+
+    visit(readModifyWriteExpression.lValue());
+    m_out.print(" = ");
+    visit(newVariable.get());
+    m_out.print(", ");
+
+    visit(*readModifyWriteExpression.resultExpression());
+    m_out.print(")");
+}
+
+void ASTDumper::visit(AST::TernaryExpression& ternaryExpression)
+{
+    visit(ternaryExpression.predicate());
+    m_out.print(" ? ");
+    visit(ternaryExpression.bodyExpression());
+    m_out.print(" : ");
+    visit(ternaryExpression.elseExpression());
+}
+
+void ASTDumper::visit(AST::VariableReference& variableReference)
+{
+    if (variableReference.name().isEmpty())
+        m_out.print("$(", RawPointer(variableReference.variable()), ")");
+    else
+        m_out.print(variableReference.name());
+}
+
+} // namespace WHLSL
+
+} // namespace WebCore
+
+#endif
</ins></span></pre></div>
<a id="trunkSourceWebCoreModuleswebgpuWHLSLWHLSLASTDumperh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.h (0 => 245613)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.h                               (rev 0)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.h  2019-05-22 03:18:03 UTC (rev 245613)
</span><span class="lines">@@ -0,0 +1,147 @@
</span><ins>+/*
+ * 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 "WHLSLVisitor.h"
+
+#include <wtf/DataLog.h>
+#include <wtf/SetForScope.h>
+#include <wtf/StringPrintStream.h>
+
+namespace WebCore {
+
+namespace WHLSL {
+
+class ASTDumper : Visitor {
+    using Base = Visitor;
+public:
+    void visit(Program&) override;
+
+    String toString() { return m_out.toString(); }
+
+private:
+    void visit(AST::UnnamedType&) override;
+    void visit(AST::NamedType&) override;
+    void visit(AST::TypeDefinition&) override;
+    void visit(AST::StructureDefinition&) override;
+    void visit(AST::EnumerationDefinition&) override;
+    void visit(AST::FunctionDefinition&) override;
+    void visit(AST::NativeFunctionDeclaration&) override;
+    void visit(AST::NativeTypeDeclaration&) override;
+    void visit(AST::TypeReference&) override;
+    void visit(AST::PointerType&) override;
+    void visit(AST::ArrayReferenceType&) override;
+    void visit(AST::ArrayType&) override;
+    void visit(AST::StructureElement&) override;
+    void visit(AST::EnumerationMember&) override;
+    void visit(AST::FunctionDeclaration&) override;
+    void visit(AST::TypeArgument&) override;
+    void visit(AST::ReferenceType&) override;
+    void visit(AST::Semantic&) override;
+    void visit(AST::ConstantExpression&) override;
+    void visit(AST::AttributeBlock&) override;
+    void visit(AST::BuiltInSemantic&) override;
+    void visit(AST::ResourceSemantic&) override;
+    void visit(AST::SpecializationConstantSemantic&) override;
+    void visit(AST::StageInOutSemantic&) override;
+    void visit(AST::IntegerLiteral&) override;
+    void visit(AST::UnsignedIntegerLiteral&) override;
+    void visit(AST::FloatLiteral&) override;
+    void visit(AST::NullLiteral&) override;
+    void visit(AST::BooleanLiteral&) override;
+    void visit(AST::IntegerLiteralType&) override;
+    void visit(AST::UnsignedIntegerLiteralType&) override;
+    void visit(AST::FloatLiteralType&) override;
+    void visit(AST::NullLiteralType&) override;
+    void visit(AST::EnumerationMemberLiteral&) override;
+    void visit(AST::FunctionAttribute&) override;
+    void visit(AST::NumThreadsFunctionAttribute&) override;
+    void visit(AST::Block&) override;
+    void visit(AST::Statement&) override;
+    void visit(AST::Break&) override;
+    void visit(AST::Continue&) override;
+    void visit(AST::DoWhileLoop&) override;
+    void visit(AST::Expression&) override;
+    void visit(AST::DotExpression&) override;
+    void visit(AST::IndexExpression&) override;
+    void visit(AST::PropertyAccessExpression&) override;
+    void visit(AST::EffectfulExpressionStatement&) override;
+    void visit(AST::Fallthrough&) override;
+    void visit(AST::ForLoop&) override;
+    void visit(AST::IfStatement&) override;
+    void visit(AST::Return&) override;
+    void visit(AST::SwitchCase&) override;
+    void visit(AST::SwitchStatement&) override;
+    void visit(AST::Trap&) override;
+    void visit(AST::VariableDeclarationsStatement&) override;
+    void visit(AST::WhileLoop&) override;
+    void visit(AST::VariableDeclaration&) override;
+    void visit(AST::AssignmentExpression&) override;
+    void visit(AST::CallExpression&) override;
+    void visit(AST::CommaExpression&) override;
+    void visit(AST::DereferenceExpression&) override;
+    void visit(AST::LogicalExpression&) override;
+    void visit(AST::LogicalNotExpression&) override;
+    void visit(AST::MakeArrayReferenceExpression&) override;
+    void visit(AST::MakePointerExpression&) override;
+    void visit(AST::ReadModifyWriteExpression&) override;
+    void visit(AST::TernaryExpression&) override;
+    void visit(AST::VariableReference&) override;
+
+    struct Indent {
+        Indent(ASTDumper& dumper)
+            : m_scope(dumper.m_indent, dumper.m_indent + "   ")
+        { }
+        SetForScope<String> m_scope;
+    };
+
+    Indent bumpIndent() { return Indent(*this); }
+
+    friend struct Indent;
+
+    StringPrintStream m_out;
+    String m_indent;
+};
+
+static ALWAYS_INLINE String toString(Program& program)
+{
+    ASTDumper dumper;
+    dumper.visit(program);
+    return dumper.toString();
+}
+
+static ALWAYS_INLINE void dumpAST(Program& program)
+{
+    dataLogLn(toString(program));
+}
+
+} // namespace WHLSL
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGPU)
</ins></span></pre></div>
<a id="trunkSourceWebCoreModuleswebgpuWHLSLWHLSLPreparecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp (245612 => 245613)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp       2019-05-22 03:05:35 UTC (rev 245612)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp  2019-05-22 03:18:03 UTC (rev 245613)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(WEBGPU)
</span><span class="cx"> 
</span><ins>+#include "WHLSLASTDumper.h"
</ins><span class="cx"> #include "WHLSLCheckDuplicateFunctions.h"
</span><span class="cx"> #include "WHLSLChecker.h"
</span><span class="cx"> #include "WHLSLFunctionStageChecker.h"
</span><span class="lines">@@ -52,6 +53,44 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WHLSL {
</span><span class="cx"> 
</span><ins>+static constexpr bool dumpASTBeforeEachPass = false;
+static constexpr bool dumpASTAfterParsing = false;
+static constexpr bool dumpASTAtEnd = false;
+
+static bool dumpASTIfNeeded(bool shouldDump, Program& program, const char* message)
+{
+    if (shouldDump) {
+        dataLogLn(message);
+        dumpAST(program);
+        return true;
+    }
+
+    return false;
+}
+
+static bool dumpASTAfterParsingIfNeeded(Program& program)
+{
+    return dumpASTIfNeeded(dumpASTAfterParsing, program, "AST after parsing");
+}
+
+static bool dumpASTBetweenEachPassIfNeeded(Program& program, const char* message)
+{
+    return dumpASTIfNeeded(dumpASTBeforeEachPass, program, message);
+}
+
+static bool dumpASTAtEndIfNeeded(Program& program)
+{
+    return dumpASTIfNeeded(dumpASTAtEnd, program, "AST at end");
+}
+
+#define RUN_PASS(pass, ...) \
+    do { \
+        dumpASTBetweenEachPassIfNeeded(program, "AST before " # pass); \
+        if (!pass(__VA_ARGS__)) \
+            return WTF::nullopt; \
+    } while (0)
+    
+
</ins><span class="cx"> static Optional<Program> prepareShared(String& whlslSource)
</span><span class="cx"> {
</span><span class="cx">     Program program;
</span><span class="lines">@@ -61,35 +100,31 @@
</span><span class="cx">     ASSERT_UNUSED(failure, !failure);
</span><span class="cx">     if (parser.parse(program, whlslSource, Parser::Mode::User))
</span><span class="cx">         return WTF::nullopt;
</span><ins>+
+    if (!dumpASTBetweenEachPassIfNeeded(program, "AST after parsing"))
+        dumpASTAfterParsingIfNeeded(program);
+
</ins><span class="cx">     NameResolver nameResolver(program.nameContext());
</span><del>-    if (!resolveNamesInTypes(program, nameResolver))
-        return WTF::nullopt;
-    if (!checkRecursiveTypes(program))
-        return WTF::nullopt;
-    if (!synthesizeStructureAccessors(program))
-        return WTF::nullopt;
-    if (!synthesizeEnumerationFunctions(program))
-        return WTF::nullopt;
-    if (!synthesizeArrayOperatorLength(program))
-        return WTF::nullopt;
-    if (!synthesizeConstructors(program))
-        return WTF::nullopt;
-    if (!resolveNamesInFunctions(program, nameResolver))
-        return WTF::nullopt;
-    if (!checkDuplicateFunctions(program))
-        return WTF::nullopt;
</del><ins>+    RUN_PASS(resolveNamesInTypes, program, nameResolver);
+    RUN_PASS(checkRecursiveTypes, program);
+    RUN_PASS(synthesizeStructureAccessors, program);
+    RUN_PASS(synthesizeEnumerationFunctions, program);
+    RUN_PASS(synthesizeArrayOperatorLength, program);
+    RUN_PASS(synthesizeConstructors, program);
+    RUN_PASS(resolveNamesInFunctions, program, nameResolver);
+    RUN_PASS(checkDuplicateFunctions, program);
</ins><span class="cx"> 
</span><del>-    if (!check(program))
-        return WTF::nullopt;
</del><ins>+    RUN_PASS(check, program);
+
</ins><span class="cx">     checkLiteralTypes(program);
</span><span class="cx">     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195788 Resolve properties here
</span><span class="cx">     findHighZombies(program);
</span><del>-    if (!checkStatementBehavior(program))
-        return WTF::nullopt;
-    if (!checkRecursion(program))
-        return WTF::nullopt;
-    if (!checkFunctionStages(program))
-        return WTF::nullopt;
</del><ins>+    RUN_PASS(checkStatementBehavior, program);
+    RUN_PASS(checkRecursion, program);
+    RUN_PASS(checkFunctionStages, program);
+
+    dumpASTAtEndIfNeeded(program);
+
</ins><span class="cx">     return program;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebgpuWHLSLWHLSLVisitorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.cpp (245612 => 245613)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.cpp       2019-05-22 03:05:35 UTC (rev 245612)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.cpp  2019-05-22 03:18:03 UTC (rev 245613)
</span><span class="lines">@@ -28,73 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(WEBGPU)
</span><span class="cx"> 
</span><del>-#include "WHLSLArrayReferenceType.h"
-#include "WHLSLArrayType.h"
-#include "WHLSLAssignmentExpression.h"
-#include "WHLSLBaseFunctionAttribute.h"
-#include "WHLSLBaseSemantic.h"
-#include "WHLSLBlock.h"
-#include "WHLSLBooleanLiteral.h"
-#include "WHLSLBreak.h"
-#include "WHLSLBuiltInSemantic.h"
-#include "WHLSLCallExpression.h"
-#include "WHLSLCommaExpression.h"
-#include "WHLSLConstantExpression.h"
-#include "WHLSLContinue.h"
-#include "WHLSLDereferenceExpression.h"
-#include "WHLSLDoWhileLoop.h"
-#include "WHLSLDotExpression.h"
-#include "WHLSLEffectfulExpressionStatement.h"
-#include "WHLSLEnumerationDefinition.h"
-#include "WHLSLEnumerationMember.h"
-#include "WHLSLEnumerationMemberLiteral.h"
-#include "WHLSLExpression.h"
-#include "WHLSLFallthrough.h"
-#include "WHLSLFloatLiteral.h"
-#include "WHLSLForLoop.h"
-#include "WHLSLFunctionAttribute.h"
-#include "WHLSLFunctionDeclaration.h"
-#include "WHLSLFunctionDefinition.h"
-#include "WHLSLIfStatement.h"
-#include "WHLSLIndexExpression.h"
-#include "WHLSLIntegerLiteral.h"
-#include "WHLSLLogicalExpression.h"
-#include "WHLSLLogicalNotExpression.h"
-#include "WHLSLMakeArrayReferenceExpression.h"
-#include "WHLSLMakePointerExpression.h"
-#include "WHLSLNativeFunctionDeclaration.h"
-#include "WHLSLNativeTypeDeclaration.h"
-#include "WHLSLNode.h"
-#include "WHLSLNullLiteral.h"
-#include "WHLSLNumThreadsFunctionAttribute.h"
-#include "WHLSLPointerType.h"
-#include "WHLSLProgram.h"
-#include "WHLSLPropertyAccessExpression.h"
-#include "WHLSLQualifier.h"
-#include "WHLSLReadModifyWriteExpression.h"
-#include "WHLSLReferenceType.h"
-#include "WHLSLResourceSemantic.h"
-#include "WHLSLReturn.h"
-#include "WHLSLSemantic.h"
-#include "WHLSLSpecializationConstantSemantic.h"
-#include "WHLSLStageInOutSemantic.h"
-#include "WHLSLStatement.h"
-#include "WHLSLStructureDefinition.h"
-#include "WHLSLStructureElement.h"
-#include "WHLSLSwitchCase.h"
-#include "WHLSLSwitchStatement.h"
-#include "WHLSLTernaryExpression.h"
-#include "WHLSLTrap.h"
-#include "WHLSLType.h"
-#include "WHLSLTypeArgument.h"
-#include "WHLSLTypeDefinition.h"
-#include "WHLSLTypeReference.h"
-#include "WHLSLUnsignedIntegerLiteral.h"
-#include "WHLSLValue.h"
-#include "WHLSLVariableDeclaration.h"
-#include "WHLSLVariableDeclarationsStatement.h"
-#include "WHLSLVariableReference.h"
-#include "WHLSLWhileLoop.h"
</del><ins>+#include "WHLSLAST.h"
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreSourcestxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Sources.txt (245612 => 245613)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Sources.txt 2019-05-22 03:05:35 UTC (rev 245612)
+++ trunk/Source/WebCore/Sources.txt    2019-05-22 03:18:03 UTC (rev 245613)
</span><span class="lines">@@ -306,6 +306,7 @@
</span><span class="cx"> 
</span><span class="cx"> Modules/webgpu/GPUCanvasContext.cpp
</span><span class="cx"> Modules/webgpu/NavigatorGPU.cpp
</span><ins>+Modules/webgpu/WHLSL/WHLSLASTDumper.cpp
</ins><span class="cx"> Modules/webgpu/WHLSL/WHLSLInferTypes.cpp
</span><span class="cx"> Modules/webgpu/WHLSL/WHLSLLexer.cpp
</span><span class="cx"> Modules/webgpu/WHLSL/WHLSLParser.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (245612 => 245613)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj   2019-05-22 03:05:35 UTC (rev 245612)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj      2019-05-22 03:18:03 UTC (rev 245613)
</span><span class="lines">@@ -8314,6 +8314,7 @@
</span><span class="cx">          51FB67D91AE6B5E400D06C5A /* ContentExtensionStyleSheet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ContentExtensionStyleSheet.cpp; sourceTree = "<group>"; };
</span><span class="cx">          51FB67DA1AE6B5E400D06C5A /* ContentExtensionStyleSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContentExtensionStyleSheet.h; sourceTree = "<group>"; };
</span><span class="cx">          52131E5A1C4F15610033F802 /* VideoFullscreenInterfaceMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = VideoFullscreenInterfaceMac.mm; sourceTree = "<group>"; };
</span><ins>+               5215862C229377B7005925EF /* WHLSLAST.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLAST.h; sourceTree = "<group>"; };
</ins><span class="cx">           526724F11CB2FDF60075974D /* TextTrackRepresentationCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TextTrackRepresentationCocoa.mm; sourceTree = "<group>"; };
</span><span class="cx">          526724F21CB2FDF60075974D /* TextTrackRepresentationCocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextTrackRepresentationCocoa.h; sourceTree = "<group>"; };
</span><span class="cx">          52B0D4BD1C57FD1E0077CE53 /* PlatformView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformView.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -16997,6 +16998,7 @@
</span><span class="cx">          1CA0C2F621EEDAD200A11860 /* AST */ = {
</span><span class="cx">                  isa = PBXGroup;
</span><span class="cx">                  children = (
</span><ins>+                               5215862C229377B7005925EF /* WHLSLAST.h */,
</ins><span class="cx">                           1C840B9021EC30F900D0500D /* WHLSLAddressSpace.h */,
</span><span class="cx">                          C21BF72521CD89E200227979 /* WHLSLArrayReferenceType.h */,
</span><span class="cx">                          C21BF70921CD89CA00227979 /* WHLSLArrayType.h */,
</span></span></pre>
</div>
</div>

</body>
</html>