1/*
2 * Copyright (C) 2019 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "WHLSLVisitor.h"
28
29#if ENABLE(WEBGPU)
30
31#include "WHLSLArrayReferenceType.h"
32#include "WHLSLArrayType.h"
33#include "WHLSLAssignmentExpression.h"
34#include "WHLSLBaseFunctionAttribute.h"
35#include "WHLSLBaseSemantic.h"
36#include "WHLSLBlock.h"
37#include "WHLSLBooleanLiteral.h"
38#include "WHLSLBreak.h"
39#include "WHLSLBuiltInSemantic.h"
40#include "WHLSLCallExpression.h"
41#include "WHLSLCommaExpression.h"
42#include "WHLSLConstantExpression.h"
43#include "WHLSLContinue.h"
44#include "WHLSLDereferenceExpression.h"
45#include "WHLSLDoWhileLoop.h"
46#include "WHLSLDotExpression.h"
47#include "WHLSLEffectfulExpressionStatement.h"
48#include "WHLSLEnumerationDefinition.h"
49#include "WHLSLEnumerationMember.h"
50#include "WHLSLEnumerationMemberLiteral.h"
51#include "WHLSLExpression.h"
52#include "WHLSLFallthrough.h"
53#include "WHLSLFloatLiteral.h"
54#include "WHLSLForLoop.h"
55#include "WHLSLFunctionAttribute.h"
56#include "WHLSLFunctionDeclaration.h"
57#include "WHLSLFunctionDefinition.h"
58#include "WHLSLIfStatement.h"
59#include "WHLSLIndexExpression.h"
60#include "WHLSLIntegerLiteral.h"
61#include "WHLSLLogicalExpression.h"
62#include "WHLSLLogicalNotExpression.h"
63#include "WHLSLMakeArrayReferenceExpression.h"
64#include "WHLSLMakePointerExpression.h"
65#include "WHLSLNativeFunctionDeclaration.h"
66#include "WHLSLNativeTypeDeclaration.h"
67#include "WHLSLNode.h"
68#include "WHLSLNullLiteral.h"
69#include "WHLSLNumThreadsFunctionAttribute.h"
70#include "WHLSLPointerType.h"
71#include "WHLSLProgram.h"
72#include "WHLSLPropertyAccessExpression.h"
73#include "WHLSLQualifier.h"
74#include "WHLSLReadModifyWriteExpression.h"
75#include "WHLSLReferenceType.h"
76#include "WHLSLResourceSemantic.h"
77#include "WHLSLReturn.h"
78#include "WHLSLSemantic.h"
79#include "WHLSLSpecializationConstantSemantic.h"
80#include "WHLSLStageInOutSemantic.h"
81#include "WHLSLStatement.h"
82#include "WHLSLStructureDefinition.h"
83#include "WHLSLStructureElement.h"
84#include "WHLSLSwitchCase.h"
85#include "WHLSLSwitchStatement.h"
86#include "WHLSLTernaryExpression.h"
87#include "WHLSLTrap.h"
88#include "WHLSLType.h"
89#include "WHLSLTypeArgument.h"
90#include "WHLSLTypeDefinition.h"
91#include "WHLSLTypeReference.h"
92#include "WHLSLUnsignedIntegerLiteral.h"
93#include "WHLSLValue.h"
94#include "WHLSLVariableDeclaration.h"
95#include "WHLSLVariableDeclarationsStatement.h"
96#include "WHLSLVariableReference.h"
97#include "WHLSLWhileLoop.h"
98
99namespace WebCore {
100
101namespace WHLSL {
102
103void Visitor::visit(Program& program)
104{
105 // These visiting functions might add new global statements, so don't use foreach syntax.
106 for (size_t i = 0; i < program.typeDefinitions().size(); ++i)
107 checkErrorAndVisit(program.typeDefinitions()[i]);
108 for (size_t i = 0; i < program.structureDefinitions().size(); ++i)
109 checkErrorAndVisit(program.structureDefinitions()[i]);
110 for (size_t i = 0; i < program.enumerationDefinitions().size(); ++i)
111 checkErrorAndVisit(program.enumerationDefinitions()[i]);
112 for (size_t i = 0; i < program.functionDefinitions().size(); ++i)
113 checkErrorAndVisit(program.functionDefinitions()[i]);
114 for (size_t i = 0; i < program.nativeFunctionDeclarations().size(); ++i)
115 checkErrorAndVisit(program.nativeFunctionDeclarations()[i]);
116 for (size_t i = 0; i < program.nativeTypeDeclarations().size(); ++i)
117 checkErrorAndVisit(program.nativeTypeDeclarations()[i]);
118}
119
120void Visitor::visit(AST::UnnamedType& unnamedType)
121{
122 if (is<AST::TypeReference>(unnamedType))
123 checkErrorAndVisit(downcast<AST::TypeReference>(unnamedType));
124 else if (is<AST::PointerType>(unnamedType))
125 checkErrorAndVisit(downcast<AST::PointerType>(unnamedType));
126 else if (is<AST::ArrayReferenceType>(unnamedType))
127 checkErrorAndVisit(downcast<AST::ArrayReferenceType>(unnamedType));
128 else {
129 ASSERT(is<AST::ArrayType>(unnamedType));
130 checkErrorAndVisit(downcast<AST::ArrayType>(unnamedType));
131 }
132}
133
134void Visitor::visit(AST::NamedType& namedType)
135{
136 if (is<AST::TypeDefinition>(namedType))
137 checkErrorAndVisit(downcast<AST::TypeDefinition>(namedType));
138 else if (is<AST::StructureDefinition>(namedType))
139 checkErrorAndVisit(downcast<AST::StructureDefinition>(namedType));
140 else if (is<AST::EnumerationDefinition>(namedType))
141 checkErrorAndVisit(downcast<AST::EnumerationDefinition>(namedType));
142 else {
143 ASSERT(is<AST::NativeTypeDeclaration>(namedType));
144 checkErrorAndVisit(downcast<AST::NativeTypeDeclaration>(namedType));
145 }
146}
147
148void Visitor::visit(AST::TypeDefinition& typeDefinition)
149{
150 checkErrorAndVisit(typeDefinition.type());
151}
152
153void Visitor::visit(AST::StructureDefinition& structureDefinition)
154{
155 for (auto& structureElement : structureDefinition.structureElements())
156 checkErrorAndVisit(structureElement);
157}
158
159void Visitor::visit(AST::EnumerationDefinition& enumerationDefinition)
160{
161 checkErrorAndVisit(enumerationDefinition.type());
162 for (auto& enumerationMember : enumerationDefinition.enumerationMembers())
163 checkErrorAndVisit(enumerationMember);
164}
165
166void Visitor::visit(AST::FunctionDefinition& functionDefinition)
167{
168 checkErrorAndVisit(static_cast<AST::FunctionDeclaration&>(functionDefinition));
169 checkErrorAndVisit(functionDefinition.block());
170}
171
172void Visitor::visit(AST::NativeFunctionDeclaration& nativeFunctionDeclaration)
173{
174 checkErrorAndVisit(static_cast<AST::FunctionDeclaration&>(nativeFunctionDeclaration));
175}
176
177void Visitor::visit(AST::NativeTypeDeclaration& nativeTypeDeclaration)
178{
179 for (auto& typeArgument : nativeTypeDeclaration.typeArguments())
180 checkErrorAndVisit(typeArgument);
181}
182
183void Visitor::visit(AST::TypeReference& typeReference)
184{
185 for (auto& typeArgument : typeReference.typeArguments())
186 checkErrorAndVisit(typeArgument);
187 if (typeReference.resolvedType() && is<AST::TypeDefinition>(*typeReference.resolvedType())) {
188 auto& typeDefinition = downcast<AST::TypeDefinition>(*typeReference.resolvedType());
189 checkErrorAndVisit(typeDefinition.type());
190 }
191}
192
193void Visitor::visit(AST::PointerType& pointerType)
194{
195 checkErrorAndVisit(static_cast<AST::ReferenceType&>(pointerType));
196}
197
198void Visitor::visit(AST::ArrayReferenceType& arrayReferenceType)
199{
200 checkErrorAndVisit(static_cast<AST::ReferenceType&>(arrayReferenceType));
201}
202
203void Visitor::visit(AST::ArrayType& arrayType)
204{
205 checkErrorAndVisit(arrayType.type());
206}
207
208void Visitor::visit(AST::StructureElement& structureElement)
209{
210 checkErrorAndVisit(structureElement.type());
211 if (structureElement.semantic())
212 checkErrorAndVisit(*structureElement.semantic());
213}
214
215void Visitor::visit(AST::EnumerationMember& enumerationMember)
216{
217 if (enumerationMember.value())
218 checkErrorAndVisit(*enumerationMember.value());
219}
220
221void Visitor::visit(AST::FunctionDeclaration& functionDeclaration)
222{
223 checkErrorAndVisit(functionDeclaration.attributeBlock());
224 checkErrorAndVisit(functionDeclaration.type());
225 for (auto& parameter : functionDeclaration.parameters())
226 checkErrorAndVisit(parameter);
227 if (functionDeclaration.semantic())
228 checkErrorAndVisit(*functionDeclaration.semantic());
229}
230
231void Visitor::visit(AST::TypeArgument& typeArgument)
232{
233 WTF::visit(WTF::makeVisitor([&](AST::ConstantExpression& constantExpression) {
234 checkErrorAndVisit(constantExpression);
235 }, [&](UniqueRef<AST::TypeReference>& typeReference) {
236 checkErrorAndVisit(typeReference);
237 }), typeArgument);
238}
239
240void Visitor::visit(AST::ReferenceType& referenceType)
241{
242 checkErrorAndVisit(referenceType.elementType());
243}
244
245void Visitor::visit(AST::Semantic& semantic)
246{
247 WTF::visit(WTF::makeVisitor([&](AST::BuiltInSemantic& builtInSemantic) {
248 checkErrorAndVisit(builtInSemantic);
249 }, [&](AST::ResourceSemantic& resourceSemantic) {
250 checkErrorAndVisit(resourceSemantic);
251 }, [&](AST::SpecializationConstantSemantic& specializationConstantSemantic) {
252 checkErrorAndVisit(specializationConstantSemantic);
253 }, [&](AST::StageInOutSemantic& stageInOutSemantic) {
254 checkErrorAndVisit(stageInOutSemantic);
255 }), semantic);
256}
257
258void Visitor::visit(AST::ConstantExpression& constantExpression)
259{
260 constantExpression.visit(WTF::makeVisitor([&](AST::IntegerLiteral& integerLiteral) {
261 checkErrorAndVisit(integerLiteral);
262 }, [&](AST::UnsignedIntegerLiteral& unsignedIntegerLiteral) {
263 checkErrorAndVisit(unsignedIntegerLiteral);
264 }, [&](AST::FloatLiteral& floatLiteral) {
265 checkErrorAndVisit(floatLiteral);
266 }, [&](AST::NullLiteral& nullLiteral) {
267 checkErrorAndVisit(nullLiteral);
268 }, [&](AST::BooleanLiteral& booleanLiteral) {
269 checkErrorAndVisit(booleanLiteral);
270 }, [&](AST::EnumerationMemberLiteral& enumerationMemberLiteral) {
271 checkErrorAndVisit(enumerationMemberLiteral);
272 }));
273}
274
275void Visitor::visit(AST::AttributeBlock& attributeBlock)
276{
277 for (auto& functionAttribute : attributeBlock)
278 checkErrorAndVisit(functionAttribute);
279}
280
281void Visitor::visit(AST::BuiltInSemantic&)
282{
283}
284
285void Visitor::visit(AST::ResourceSemantic&)
286{
287}
288
289void Visitor::visit(AST::SpecializationConstantSemantic&)
290{
291}
292
293void Visitor::visit(AST::StageInOutSemantic&)
294{
295}
296
297void Visitor::visit(AST::IntegerLiteral& integerLiteral)
298{
299 checkErrorAndVisit(integerLiteral.type());
300}
301
302void Visitor::visit(AST::UnsignedIntegerLiteral& unsignedIntegerLiteral)
303{
304 checkErrorAndVisit(unsignedIntegerLiteral.type());
305}
306
307void Visitor::visit(AST::FloatLiteral& floatLiteral)
308{
309 checkErrorAndVisit(floatLiteral.type());
310}
311
312void Visitor::visit(AST::NullLiteral& nullLiteral)
313{
314 checkErrorAndVisit(nullLiteral.type());
315}
316
317void Visitor::visit(AST::BooleanLiteral&)
318{
319}
320
321void Visitor::visit(AST::IntegerLiteralType& integerLiteralType)
322{
323 if (integerLiteralType.resolvedType())
324 checkErrorAndVisit(*integerLiteralType.resolvedType());
325 checkErrorAndVisit(integerLiteralType.preferredType());
326}
327
328void Visitor::visit(AST::UnsignedIntegerLiteralType& unsignedIntegerLiteralType)
329{
330 if (unsignedIntegerLiteralType.resolvedType())
331 checkErrorAndVisit(*unsignedIntegerLiteralType.resolvedType());
332 checkErrorAndVisit(unsignedIntegerLiteralType.preferredType());
333}
334
335void Visitor::visit(AST::FloatLiteralType& floatLiteralType)
336{
337 if (floatLiteralType.resolvedType())
338 checkErrorAndVisit(*floatLiteralType.resolvedType());
339 checkErrorAndVisit(floatLiteralType.preferredType());
340}
341
342void Visitor::visit(AST::NullLiteralType& nullLiteralType)
343{
344 if (nullLiteralType.resolvedType())
345 checkErrorAndVisit(*nullLiteralType.resolvedType());
346}
347
348void Visitor::visit(AST::EnumerationMemberLiteral&)
349{
350}
351
352void Visitor::visit(AST::FunctionAttribute& functionAttribute)
353{
354 WTF::visit(WTF::makeVisitor([&](AST::NumThreadsFunctionAttribute& numThreadsFunctionAttribute) {
355 checkErrorAndVisit(numThreadsFunctionAttribute);
356 }), functionAttribute);
357}
358
359void Visitor::visit(AST::NumThreadsFunctionAttribute&)
360{
361}
362
363void Visitor::visit(AST::Block& block)
364{
365 for (auto& statement : block.statements())
366 checkErrorAndVisit(statement);
367}
368
369void Visitor::visit(AST::Statement& statement)
370{
371 if (is<AST::Block>(statement))
372 checkErrorAndVisit(downcast<AST::Block>(statement));
373 else if (is<AST::Break>(statement))
374 checkErrorAndVisit(downcast<AST::Break>(statement));
375 else if (is<AST::Continue>(statement))
376 checkErrorAndVisit(downcast<AST::Continue>(statement));
377 else if (is<AST::DoWhileLoop>(statement))
378 checkErrorAndVisit(downcast<AST::DoWhileLoop>(statement));
379 else if (is<AST::EffectfulExpressionStatement>(statement))
380 checkErrorAndVisit(downcast<AST::EffectfulExpressionStatement>(statement));
381 else if (is<AST::Fallthrough>(statement))
382 checkErrorAndVisit(downcast<AST::Fallthrough>(statement));
383 else if (is<AST::ForLoop>(statement))
384 checkErrorAndVisit(downcast<AST::ForLoop>(statement));
385 else if (is<AST::IfStatement>(statement))
386 checkErrorAndVisit(downcast<AST::IfStatement>(statement));
387 else if (is<AST::Return>(statement))
388 checkErrorAndVisit(downcast<AST::Return>(statement));
389 else if (is<AST::SwitchCase>(statement))
390 checkErrorAndVisit(downcast<AST::SwitchCase>(statement));
391 else if (is<AST::SwitchStatement>(statement))
392 checkErrorAndVisit(downcast<AST::SwitchStatement>(statement));
393 else if (is<AST::Trap>(statement))
394 checkErrorAndVisit(downcast<AST::Trap>(statement));
395 else if (is<AST::VariableDeclarationsStatement>(statement))
396 checkErrorAndVisit(downcast<AST::VariableDeclarationsStatement>(statement));
397 else {
398 ASSERT(is<AST::WhileLoop>(statement));
399 checkErrorAndVisit(downcast<AST::WhileLoop>(statement));
400 }
401}
402
403void Visitor::visit(AST::Break&)
404{
405}
406
407void Visitor::visit(AST::Continue&)
408{
409}
410
411void Visitor::visit(AST::DoWhileLoop& doWhileLoop)
412{
413 checkErrorAndVisit(doWhileLoop.body());
414 checkErrorAndVisit(doWhileLoop.conditional());
415}
416
417void Visitor::visit(AST::Expression& expression)
418{
419 if (is<AST::AssignmentExpression>(expression))
420 checkErrorAndVisit(downcast<AST::AssignmentExpression>(expression));
421 else if (is<AST::BooleanLiteral>(expression))
422 checkErrorAndVisit(downcast<AST::BooleanLiteral>(expression));
423 else if (is<AST::CallExpression>(expression))
424 checkErrorAndVisit(downcast<AST::CallExpression>(expression));
425 else if (is<AST::CommaExpression>(expression))
426 checkErrorAndVisit(downcast<AST::CommaExpression>(expression));
427 else if (is<AST::DereferenceExpression>(expression))
428 checkErrorAndVisit(downcast<AST::DereferenceExpression>(expression));
429 else if (is<AST::FloatLiteral>(expression))
430 checkErrorAndVisit(downcast<AST::FloatLiteral>(expression));
431 else if (is<AST::IntegerLiteral>(expression))
432 checkErrorAndVisit(downcast<AST::IntegerLiteral>(expression));
433 else if (is<AST::LogicalExpression>(expression))
434 checkErrorAndVisit(downcast<AST::LogicalExpression>(expression));
435 else if (is<AST::LogicalNotExpression>(expression))
436 checkErrorAndVisit(downcast<AST::LogicalNotExpression>(expression));
437 else if (is<AST::MakeArrayReferenceExpression>(expression))
438 checkErrorAndVisit(downcast<AST::MakeArrayReferenceExpression>(expression));
439 else if (is<AST::MakePointerExpression>(expression))
440 checkErrorAndVisit(downcast<AST::MakePointerExpression>(expression));
441 else if (is<AST::NullLiteral>(expression))
442 checkErrorAndVisit(downcast<AST::NullLiteral>(expression));
443 else if (is<AST::DotExpression>(expression))
444 checkErrorAndVisit(downcast<AST::DotExpression>(expression));
445 else if (is<AST::IndexExpression>(expression))
446 checkErrorAndVisit(downcast<AST::IndexExpression>(expression));
447 else if (is<AST::ReadModifyWriteExpression>(expression))
448 checkErrorAndVisit(downcast<AST::ReadModifyWriteExpression>(expression));
449 else if (is<AST::TernaryExpression>(expression))
450 checkErrorAndVisit(downcast<AST::TernaryExpression>(expression));
451 else if (is<AST::UnsignedIntegerLiteral>(expression))
452 checkErrorAndVisit(downcast<AST::UnsignedIntegerLiteral>(expression));
453 else if (is<AST::EnumerationMemberLiteral>(expression))
454 checkErrorAndVisit(downcast<AST::EnumerationMemberLiteral>(expression));
455 else {
456 ASSERT(is<AST::VariableReference>(expression));
457 checkErrorAndVisit(downcast<AST::VariableReference>(expression));
458 }
459}
460
461void Visitor::visit(AST::DotExpression& dotExpression)
462{
463 checkErrorAndVisit(static_cast<AST::PropertyAccessExpression&>(dotExpression));
464}
465
466void Visitor::visit(AST::IndexExpression& indexExpression)
467{
468 checkErrorAndVisit(indexExpression.indexExpression());
469 checkErrorAndVisit(static_cast<AST::PropertyAccessExpression&>(indexExpression));
470}
471
472void Visitor::visit(AST::PropertyAccessExpression& expression)
473{
474 checkErrorAndVisit(expression.base());
475}
476
477void Visitor::visit(AST::EffectfulExpressionStatement& effectfulExpressionStatement)
478{
479 checkErrorAndVisit(effectfulExpressionStatement.effectfulExpression());
480}
481
482void Visitor::visit(AST::Fallthrough&)
483{
484}
485
486void Visitor::visit(AST::ForLoop& forLoop)
487{
488 WTF::visit(WTF::makeVisitor([&](AST::VariableDeclarationsStatement& variableDeclarationsStatement) {
489 checkErrorAndVisit(variableDeclarationsStatement);
490 }, [&](UniqueRef<AST::Expression>& expression) {
491 checkErrorAndVisit(expression);
492 }), forLoop.initialization());
493 if (forLoop.condition())
494 checkErrorAndVisit(*forLoop.condition());
495 if (forLoop.increment())
496 checkErrorAndVisit(*forLoop.increment());
497 checkErrorAndVisit(forLoop.body());
498}
499
500void Visitor::visit(AST::IfStatement& ifStatement)
501{
502 checkErrorAndVisit(ifStatement.conditional());
503 checkErrorAndVisit(ifStatement.body());
504 if (ifStatement.elseBody())
505 checkErrorAndVisit(*ifStatement.elseBody());
506}
507
508void Visitor::visit(AST::Return& returnStatement)
509{
510 if (returnStatement.value())
511 checkErrorAndVisit(*returnStatement.value());
512}
513
514void Visitor::visit(AST::SwitchCase& switchCase)
515{
516 if (switchCase.value())
517 checkErrorAndVisit(*switchCase.value());
518 checkErrorAndVisit(switchCase.block());
519}
520
521void Visitor::visit(AST::SwitchStatement& switchStatement)
522{
523 checkErrorAndVisit(switchStatement.value());
524 for (auto& switchCase : switchStatement.switchCases())
525 checkErrorAndVisit(switchCase);
526}
527
528void Visitor::visit(AST::Trap&)
529{
530}
531
532void Visitor::visit(AST::VariableDeclarationsStatement& variableDeclarationsStatement)
533{
534 for (auto& variableDeclaration : variableDeclarationsStatement.variableDeclarations())
535 checkErrorAndVisit(variableDeclaration);
536}
537
538void Visitor::visit(AST::WhileLoop& whileLoop)
539{
540 checkErrorAndVisit(whileLoop.conditional());
541 checkErrorAndVisit(whileLoop.body());
542}
543
544void Visitor::visit(AST::VariableDeclaration& variableDeclaration)
545{
546 if (variableDeclaration.type())
547 checkErrorAndVisit(*variableDeclaration.type());
548 if (variableDeclaration.semantic())
549 checkErrorAndVisit(*variableDeclaration.semantic());
550 if (variableDeclaration.initializer())
551 checkErrorAndVisit(*variableDeclaration.initializer());
552}
553
554void Visitor::visit(AST::AssignmentExpression& assignmentExpression)
555{
556 checkErrorAndVisit(assignmentExpression.left());
557 checkErrorAndVisit(assignmentExpression.right());
558}
559
560void Visitor::visit(AST::CallExpression& callExpression)
561{
562 for (auto& argument : callExpression.arguments())
563 checkErrorAndVisit(argument);
564 if (callExpression.castReturnType())
565 checkErrorAndVisit(*callExpression.castReturnType());
566}
567
568void Visitor::visit(AST::CommaExpression& commaExpression)
569{
570 for (auto& expression : commaExpression.list())
571 checkErrorAndVisit(expression);
572}
573
574void Visitor::visit(AST::DereferenceExpression& dereferenceExpression)
575{
576 checkErrorAndVisit(dereferenceExpression.pointer());
577}
578
579void Visitor::visit(AST::LogicalExpression& logicalExpression)
580{
581 checkErrorAndVisit(logicalExpression.left());
582 checkErrorAndVisit(logicalExpression.right());
583}
584
585void Visitor::visit(AST::LogicalNotExpression& logicalNotExpression)
586{
587 checkErrorAndVisit(logicalNotExpression.operand());
588}
589
590void Visitor::visit(AST::MakeArrayReferenceExpression& makeArrayReferenceExpression)
591{
592 checkErrorAndVisit(makeArrayReferenceExpression.lValue());
593}
594
595void Visitor::visit(AST::MakePointerExpression& makePointerExpression)
596{
597 checkErrorAndVisit(makePointerExpression.lValue());
598}
599
600void Visitor::visit(AST::ReadModifyWriteExpression& readModifyWriteExpression)
601{
602 checkErrorAndVisit(readModifyWriteExpression.lValue());
603 checkErrorAndVisit(readModifyWriteExpression.oldValue());
604 checkErrorAndVisit(readModifyWriteExpression.newValue());
605 if (readModifyWriteExpression.newValueExpression())
606 checkErrorAndVisit(*readModifyWriteExpression.newValueExpression());
607 if (readModifyWriteExpression.resultExpression())
608 checkErrorAndVisit(*readModifyWriteExpression.resultExpression());
609}
610
611void Visitor::visit(AST::TernaryExpression& ternaryExpression)
612{
613 checkErrorAndVisit(ternaryExpression.predicate());
614 checkErrorAndVisit(ternaryExpression.bodyExpression());
615 checkErrorAndVisit(ternaryExpression.elseExpression());
616}
617
618void Visitor::visit(AST::VariableReference&)
619{
620}
621
622} // namespace WHLSL
623
624} // namespace WebCore
625
626#endif // ENABLE(WEBGPU)
627