b00ab579f6a5dd99f442c40fc38dae8cf22729ed
[WebKit-https.git] / Source / WebCore / Modules / webgpu / WHLSL / Metal / WHLSLTypeNamer.cpp
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 "WHLSLTypeNamer.h"
28
29 #if ENABLE(WEBGPU)
30
31 #include "WHLSLAddressSpace.h"
32 #include "WHLSLArrayReferenceType.h"
33 #include "WHLSLArrayType.h"
34 #include "WHLSLCallExpression.h"
35 #include "WHLSLEnumerationDefinition.h"
36 #include "WHLSLEnumerationMember.h"
37 #include "WHLSLNativeTypeDeclaration.h"
38 #include "WHLSLNativeTypeWriter.h"
39 #include "WHLSLPointerType.h"
40 #include "WHLSLStructureDefinition.h"
41 #include "WHLSLTypeDefinition.h"
42 #include "WHLSLTypeReference.h"
43 #include "WHLSLVisitor.h"
44 #include <algorithm>
45 #include <functional>
46 #include <wtf/FastMalloc.h>
47 #include <wtf/HashMap.h>
48 #include <wtf/HashSet.h>
49 #include <wtf/Optional.h>
50 #include <wtf/UniqueRef.h>
51 #include <wtf/Vector.h>
52 #include <wtf/text/StringBuilder.h>
53 #include <wtf/text/StringConcatenateNumbers.h>
54
55 namespace WebCore {
56
57 namespace WHLSL {
58
59 namespace Metal {
60
61 class BaseTypeNameNode {
62     WTF_MAKE_FAST_ALLOCATED;
63 public:
64     BaseTypeNameNode(BaseTypeNameNode* parent, String&& mangledName)
65         : m_parent(parent)
66         , m_mangledName(mangledName)
67     {
68     }
69     virtual ~BaseTypeNameNode() = default;
70     virtual bool isArrayTypeNameNode() const { return false; }
71     virtual bool isArrayReferenceTypeNameNode() const { return false; }
72     virtual bool isPointerTypeNameNode() const { return false; }
73     virtual bool isReferenceTypeNameNode() const { return false; }
74     Vector<UniqueRef<BaseTypeNameNode>>& children() { return m_children; }
75     void append(UniqueRef<BaseTypeNameNode>&& child)
76     {
77         m_children.append(WTFMove(child));
78     }
79     BaseTypeNameNode* parent() { return m_parent; }
80     const String& mangledName() const { return m_mangledName; }
81
82 private:
83     Vector<UniqueRef<BaseTypeNameNode>> m_children;
84     BaseTypeNameNode* m_parent;
85     String m_mangledName;
86 };
87
88 class ArrayTypeNameNode : public BaseTypeNameNode {
89     WTF_MAKE_FAST_ALLOCATED;
90 public:
91     ArrayTypeNameNode(BaseTypeNameNode* parent, String&& mangledName, unsigned numElements)
92         : BaseTypeNameNode(parent, WTFMove(mangledName))
93         , m_numElements(numElements)
94     {
95     }
96     virtual ~ArrayTypeNameNode() = default;
97     bool isArrayTypeNameNode() const override { return true; }
98     unsigned numElements() const { return m_numElements; }
99
100 private:
101     unsigned m_numElements;
102 };
103
104 class ArrayReferenceTypeNameNode : public BaseTypeNameNode {
105     WTF_MAKE_FAST_ALLOCATED;
106 public:
107     ArrayReferenceTypeNameNode(BaseTypeNameNode* parent, String&& mangledName, AST::AddressSpace addressSpace)
108         : BaseTypeNameNode(parent, WTFMove(mangledName))
109         , m_addressSpace(addressSpace)
110     {
111     }
112     virtual ~ArrayReferenceTypeNameNode() = default;
113     bool isArrayReferenceTypeNameNode() const override { return true; }
114     AST::AddressSpace addressSpace() const { return m_addressSpace; }
115
116 private:
117     AST::AddressSpace m_addressSpace;
118 };
119
120 class PointerTypeNameNode : public BaseTypeNameNode {
121     WTF_MAKE_FAST_ALLOCATED;
122 public:
123     PointerTypeNameNode(BaseTypeNameNode* parent, String&& mangledName, AST::AddressSpace addressSpace)
124         : BaseTypeNameNode(parent, WTFMove(mangledName))
125         , m_addressSpace(addressSpace)
126     {
127     }
128     virtual ~PointerTypeNameNode() = default;
129     bool isPointerTypeNameNode() const override { return true; }
130     AST::AddressSpace addressSpace() const { return m_addressSpace; }
131
132 private:
133     AST::AddressSpace m_addressSpace;
134 };
135
136 class ReferenceTypeNameNode : public BaseTypeNameNode {
137     WTF_MAKE_FAST_ALLOCATED;
138 public:
139     ReferenceTypeNameNode(BaseTypeNameNode* parent, String&& mangledName, AST::NamedType& namedType)
140         : BaseTypeNameNode(parent, WTFMove(mangledName))
141         , m_namedType(namedType)
142     {
143     }
144     virtual ~ReferenceTypeNameNode() = default;
145     bool isReferenceTypeNameNode() const override { return true; }
146     AST::NamedType& namedType() { return m_namedType; }
147
148 private:
149     AST::NamedType& m_namedType;
150 };
151
152 }
153
154 }
155
156 }
157
158 #define SPECIALIZE_TYPE_TRAITS_WHLSL_BASE_TYPE_NAMED_NODE(ToValueTypeName, predicate) \
159 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::WHLSL::Metal::ToValueTypeName) \
160     static bool isType(const WebCore::WHLSL::Metal::BaseTypeNameNode& type) { return type.predicate; } \
161 SPECIALIZE_TYPE_TRAITS_END()
162
163 SPECIALIZE_TYPE_TRAITS_WHLSL_BASE_TYPE_NAMED_NODE(ArrayTypeNameNode, isArrayTypeNameNode())
164
165 SPECIALIZE_TYPE_TRAITS_WHLSL_BASE_TYPE_NAMED_NODE(ArrayReferenceTypeNameNode, isArrayReferenceTypeNameNode())
166
167 SPECIALIZE_TYPE_TRAITS_WHLSL_BASE_TYPE_NAMED_NODE(PointerTypeNameNode, isPointerTypeNameNode())
168
169 SPECIALIZE_TYPE_TRAITS_WHLSL_BASE_TYPE_NAMED_NODE(ReferenceTypeNameNode, isReferenceTypeNameNode())
170
171 namespace WebCore {
172
173 namespace WHLSL {
174
175 namespace Metal {
176
177 TypeNamer::TypeNamer(Program& program)
178     : m_program(program)
179 {
180 }
181
182 TypeNamer::~TypeNamer() = default;
183
184 static Vector<UniqueRef<BaseTypeNameNode>>::iterator findInVector(AST::UnnamedType& unnamedType, Vector<UniqueRef<BaseTypeNameNode>>& types)
185 {
186     return std::find_if(types.begin(), types.end(), [&](BaseTypeNameNode& baseTypeNameNode) -> bool {
187         if (is<AST::TypeReference>(unnamedType) && is<ReferenceTypeNameNode>(baseTypeNameNode)) {
188             auto& resolvedType = downcast<AST::TypeReference>(unnamedType).resolvedType();
189             return &resolvedType == &downcast<ReferenceTypeNameNode>(baseTypeNameNode).namedType();
190         }
191         if (is<AST::PointerType>(unnamedType) && is<PointerTypeNameNode>(baseTypeNameNode))
192             return downcast<AST::PointerType>(unnamedType).addressSpace() == downcast<PointerTypeNameNode>(baseTypeNameNode).addressSpace();
193         if (is<AST::ArrayReferenceType>(unnamedType) && is<ArrayReferenceTypeNameNode>(baseTypeNameNode))
194             return downcast<AST::ArrayReferenceType>(unnamedType).addressSpace() == downcast<ArrayReferenceTypeNameNode>(baseTypeNameNode).addressSpace();
195         if (is<AST::ArrayType>(unnamedType) && is<ArrayTypeNameNode>(baseTypeNameNode))
196             return downcast<AST::ArrayType>(unnamedType).numElements() == downcast<ArrayTypeNameNode>(baseTypeNameNode).numElements();
197         return false;
198     });
199 }
200
201 static BaseTypeNameNode& find(AST::UnnamedType& unnamedType, Vector<UniqueRef<BaseTypeNameNode>>& types)
202 {
203     auto& vectorToSearch = ([&]() -> Vector<UniqueRef<BaseTypeNameNode>>& {
204         if (is<AST::TypeReference>(unnamedType))
205             return types;
206         if (is<AST::PointerType>(unnamedType))
207             return find(downcast<AST::PointerType>(unnamedType).elementType(), types).children();
208         if (is<AST::ArrayReferenceType>(unnamedType))
209             return find(downcast<AST::ArrayReferenceType>(unnamedType).elementType(), types).children();
210         return find(downcast<AST::ArrayType>(unnamedType).type(), types).children();
211     })();
212     auto iterator = findInVector(unnamedType, vectorToSearch);
213     ASSERT(iterator != types.end());
214     return *iterator;
215 }
216
217 void TypeNamer::visit(AST::UnnamedType& unnamedType)
218 {
219     insert(unnamedType, m_trie);
220 }
221
222 void TypeNamer::visit(AST::EnumerationDefinition& enumerationDefinition)
223 {
224     {
225         auto addResult = m_namedTypeMapping.add(&enumerationDefinition, generateNextTypeName());
226         ASSERT_UNUSED(addResult, addResult.isNewEntry);
227     }
228
229     for (auto& enumerationMember : enumerationDefinition.enumerationMembers()) {
230         auto addResult = m_enumerationMemberMapping.add(&static_cast<AST::EnumerationMember&>(enumerationMember), generateNextEnumerationMemberName());
231         ASSERT_UNUSED(addResult, addResult.isNewEntry);
232     }
233
234     Visitor::visit(enumerationDefinition);
235
236     {
237         Vector<std::reference_wrapper<BaseTypeNameNode>> neighbors = { find(enumerationDefinition.type(), m_trie) };
238         auto addResult = m_dependencyGraph.add(&enumerationDefinition, WTFMove(neighbors));
239         ASSERT_UNUSED(addResult, addResult.isNewEntry);
240     }
241 }
242
243 void TypeNamer::visit(AST::NativeTypeDeclaration& nativeTypeDeclaration)
244 {
245     // Native type declarations already have names, and are already declared in Metal.
246     auto addResult = m_dependencyGraph.add(&nativeTypeDeclaration, Vector<std::reference_wrapper<BaseTypeNameNode>>());
247     ASSERT_UNUSED(addResult, addResult.isNewEntry);
248 }
249
250 void TypeNamer::visit(AST::StructureDefinition& structureDefinition)
251 {
252     {
253         auto addResult = m_namedTypeMapping.add(&structureDefinition, generateNextTypeName());
254         ASSERT_UNUSED(addResult, addResult.isNewEntry);
255     }
256     Visitor::visit(structureDefinition);
257     {
258         Vector<std::reference_wrapper<BaseTypeNameNode>> neighbors;
259         for (auto& structureElement : structureDefinition.structureElements()) {
260             auto addResult = m_structureElementMapping.add(&structureElement, generateNextStructureElementName());
261             ASSERT_UNUSED(addResult, addResult.isNewEntry);
262             neighbors.append(find(structureElement.type(), m_trie));
263         }
264         auto addResult = m_dependencyGraph.add(&structureDefinition, WTFMove(neighbors));
265         ASSERT_UNUSED(addResult, addResult.isNewEntry);
266     }
267 }
268
269 void TypeNamer::visit(AST::TypeDefinition& typeDefinition)
270 {
271     {
272         auto addResult = m_namedTypeMapping.add(&typeDefinition, generateNextTypeName());
273         ASSERT_UNUSED(addResult, addResult.isNewEntry);
274     }
275     Visitor::visit(typeDefinition);
276     {
277         Vector<std::reference_wrapper<BaseTypeNameNode>> neighbors = { find(typeDefinition.type(), m_trie) };
278         auto addResult = m_dependencyGraph.add(&typeDefinition, WTFMove(neighbors));
279         ASSERT_UNUSED(addResult, addResult.isNewEntry);
280     }
281 }
282
283 void TypeNamer::visit(AST::Expression& expression)
284 {
285     insert(expression.resolvedType(), m_trie);
286     Visitor::visit(expression);
287 }
288
289 void TypeNamer::visit(AST::CallExpression& callExpression)
290 {
291     for (auto& argument : callExpression.arguments())
292         checkErrorAndVisit(argument);
293 }
294
295 String TypeNamer::mangledNameForType(AST::NativeTypeDeclaration& nativeTypeDeclaration)
296 {
297     return writeNativeType(nativeTypeDeclaration);
298 }
299
300 UniqueRef<BaseTypeNameNode> TypeNamer::createNameNode(AST::UnnamedType& unnamedType, BaseTypeNameNode* parent)
301 {
302     if (is<AST::TypeReference>(unnamedType)) {
303         auto& typeReference = downcast<AST::TypeReference>(unnamedType);
304         return makeUniqueRef<ReferenceTypeNameNode>(parent, generateNextTypeName(), typeReference.resolvedType());
305     }
306     if (is<AST::PointerType>(unnamedType)) {
307         auto& pointerType = downcast<AST::PointerType>(unnamedType);
308         return makeUniqueRef<PointerTypeNameNode>(parent, generateNextTypeName(), pointerType.addressSpace());
309     }
310     if (is<AST::ArrayReferenceType>(unnamedType)) {
311         auto& arrayReferenceType = downcast<AST::ArrayReferenceType>(unnamedType);
312         return makeUniqueRef<ArrayReferenceTypeNameNode>(parent, generateNextTypeName(), arrayReferenceType.addressSpace());
313     }
314     auto& arrayType = downcast<AST::ArrayType>(unnamedType);
315     return makeUniqueRef<ArrayTypeNameNode>(parent, generateNextTypeName(), arrayType.numElements());
316 }
317
318 BaseTypeNameNode* TypeNamer::insert(AST::UnnamedType& unnamedType, Vector<UniqueRef<BaseTypeNameNode>>& types)
319 {
320     Vector<UniqueRef<BaseTypeNameNode>>* vectorToInsertInto { nullptr };
321     BaseTypeNameNode* parent { nullptr };
322     if (is<AST::TypeReference>(unnamedType)) {
323         vectorToInsertInto = &types;
324         parent = nullptr;
325     } else if (is<AST::PointerType>(unnamedType)) {
326         parent = insert(downcast<AST::PointerType>(unnamedType).elementType(), types);
327         vectorToInsertInto = &parent->children();
328     } else if (is<AST::ArrayReferenceType>(unnamedType)) {
329         parent = insert(downcast<AST::ArrayReferenceType>(unnamedType).elementType(), types);
330         vectorToInsertInto = &parent->children();
331     } else {
332         parent = insert(downcast<AST::ArrayType>(unnamedType).type(), types);
333         vectorToInsertInto = &parent->children();
334     }
335     ASSERT(vectorToInsertInto);
336
337     auto iterator = findInVector(unnamedType, *vectorToInsertInto);
338     if (iterator == vectorToInsertInto->end()) {
339         auto result = createNameNode(unnamedType, parent);
340         {
341             auto addResult = m_unnamedTypeMapping.add(&unnamedType, &result);
342             ASSERT_UNUSED(addResult, addResult.isNewEntry);
343         }
344         vectorToInsertInto->append(WTFMove(result));
345         return &vectorToInsertInto->last().get();
346     }
347     m_unnamedTypeMapping.add(&unnamedType, &*iterator);
348     return &*iterator;
349 }
350
351 class MetalTypeDeclarationWriter : public Visitor {
352     WTF_MAKE_FAST_ALLOCATED;
353 public:
354     MetalTypeDeclarationWriter(std::function<String(AST::NamedType&)>&& mangledNameForNamedType)
355         : m_mangledNameForNamedType(WTFMove(mangledNameForNamedType))
356     {
357     }
358
359     String toString() { return m_stringBuilder.toString(); }
360
361 private:
362     void visit(AST::StructureDefinition& structureDefinition)
363     {
364         m_stringBuilder.append(makeString("struct ", m_mangledNameForNamedType(structureDefinition), ";\n"));
365     }
366
367     std::function<String(AST::NamedType&)> m_mangledNameForNamedType;
368     StringBuilder m_stringBuilder;
369 };
370
371 String TypeNamer::metalTypeDeclarations()
372 {
373     MetalTypeDeclarationWriter metalTypeDeclarationWriter([&](AST::NamedType& namedType) -> String {
374         return mangledNameForType(namedType);
375     });
376     metalTypeDeclarationWriter.Visitor::visit(m_program);
377     return metalTypeDeclarationWriter.toString();
378 }
379
380 void TypeNamer::emitUnnamedTypeDefinition(BaseTypeNameNode& baseTypeNameNode, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes, StringBuilder& stringBuilder)
381 {
382     if (emittedUnnamedTypes.contains(&baseTypeNameNode))
383         return;
384     if (baseTypeNameNode.parent())
385         emitUnnamedTypeDefinition(*baseTypeNameNode.parent(), emittedNamedTypes, emittedUnnamedTypes, stringBuilder);
386     if (is<ReferenceTypeNameNode>(baseTypeNameNode)) {
387         auto& namedType = downcast<ReferenceTypeNameNode>(baseTypeNameNode).namedType();
388         emitNamedTypeDefinition(namedType, emittedNamedTypes, emittedUnnamedTypes, stringBuilder);
389         stringBuilder.append(makeString("typedef ", mangledNameForType(namedType), ' ', baseTypeNameNode.mangledName(), ";\n"));
390     } else if (is<PointerTypeNameNode>(baseTypeNameNode)) {
391         auto& pointerType = downcast<PointerTypeNameNode>(baseTypeNameNode);
392         ASSERT(baseTypeNameNode.parent());
393         stringBuilder.append(makeString("typedef ", toString(pointerType.addressSpace()), " ", pointerType.parent()->mangledName(), "* ", pointerType.mangledName(), ";\n"));
394     } else if (is<ArrayReferenceTypeNameNode>(baseTypeNameNode)) {
395         auto& arrayReferenceType = downcast<ArrayReferenceTypeNameNode>(baseTypeNameNode);
396         ASSERT(baseTypeNameNode.parent());
397         stringBuilder.append(makeString("struct ", arrayReferenceType.mangledName(), "{ \n"));
398         stringBuilder.append(makeString("    ", toString(arrayReferenceType.addressSpace()), " ", arrayReferenceType.parent()->mangledName(), "* pointer;\n"));
399         stringBuilder.append("    uint32_t length;\n");
400         stringBuilder.append("};\n");
401     } else {
402         auto& arrayType = downcast<ArrayTypeNameNode>(baseTypeNameNode);
403         ASSERT(baseTypeNameNode.parent());
404         stringBuilder.append(makeString("typedef array<", arrayType.parent()->mangledName(), ", ", arrayType.numElements(), "> ", arrayType.mangledName(), ";\n"));
405     }
406     emittedUnnamedTypes.add(&baseTypeNameNode);
407 }
408
409 void TypeNamer::emitNamedTypeDefinition(AST::NamedType& namedType, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes, StringBuilder& stringBuilder)
410 {
411     if (emittedNamedTypes.contains(&namedType))
412         return;
413     auto iterator = m_dependencyGraph.find(&namedType);
414     ASSERT(iterator != m_dependencyGraph.end());
415     for (auto& baseTypeNameNode : iterator->value)
416         emitUnnamedTypeDefinition(baseTypeNameNode, emittedNamedTypes, emittedUnnamedTypes, stringBuilder);
417     if (is<AST::EnumerationDefinition>(namedType)) {
418         auto& enumerationDefinition = downcast<AST::EnumerationDefinition>(namedType);
419         auto& baseType = enumerationDefinition.type().unifyNode();
420         stringBuilder.append(makeString("enum class ", mangledNameForType(enumerationDefinition), " : ", mangledNameForType(downcast<AST::NamedType>(baseType)), " {\n"));
421         for (auto& enumerationMember : enumerationDefinition.enumerationMembers())
422             stringBuilder.append(makeString("    ", mangledNameForEnumerationMember(enumerationMember), " = ", enumerationMember.get().value(), ",\n"));
423         stringBuilder.append("};\n");
424     } else if (is<AST::NativeTypeDeclaration>(namedType)) {
425         // Native types already have definitions. There's nothing to do.
426     } else if (is<AST::StructureDefinition>(namedType)) {
427         auto& structureDefinition = downcast<AST::StructureDefinition>(namedType);
428         stringBuilder.append(makeString("struct ", mangledNameForType(structureDefinition), " {\n"));
429         for (auto& structureElement : structureDefinition.structureElements())
430             stringBuilder.append(makeString("    ", mangledNameForType(structureElement.type()), ' ', mangledNameForStructureElement(structureElement), ";\n"));
431         stringBuilder.append("};\n");
432     } else {
433         auto& typeDefinition = downcast<AST::TypeDefinition>(namedType);
434         stringBuilder.append(makeString("typedef ", mangledNameForType(typeDefinition.type()), ' ', mangledNameForType(typeDefinition), ";\n"));
435     }
436     emittedNamedTypes.add(&namedType);
437 }
438
439 void TypeNamer::emitAllUnnamedTypeDefinitions(Vector<UniqueRef<BaseTypeNameNode>>& nodes, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes, StringBuilder& stringBuilder)
440 {
441     for (auto& node : nodes) {
442         emitUnnamedTypeDefinition(node, emittedNamedTypes, emittedUnnamedTypes, stringBuilder);
443         emitAllUnnamedTypeDefinitions(node->children(), emittedNamedTypes, emittedUnnamedTypes, stringBuilder);
444     }
445 }
446
447 String TypeNamer::metalTypeDefinitions()
448 {
449     HashSet<AST::NamedType*> emittedNamedTypes;
450     HashSet<BaseTypeNameNode*> emittedUnnamedTypes;
451     StringBuilder stringBuilder;
452     for (auto& keyValuePair : m_dependencyGraph)
453         emitNamedTypeDefinition(*keyValuePair.key, emittedNamedTypes, emittedUnnamedTypes, stringBuilder);
454     emitAllUnnamedTypeDefinitions(m_trie, emittedNamedTypes, emittedUnnamedTypes, stringBuilder);
455     return stringBuilder.toString();
456 }
457
458 String TypeNamer::mangledNameForType(AST::UnnamedType& unnamedType)
459 {
460     return find(unnamedType, m_trie).mangledName();
461 }
462
463 String TypeNamer::mangledNameForType(AST::NamedType& namedType)
464 {
465     if (is<AST::NativeTypeDeclaration>(namedType))
466         return mangledNameForType(downcast<AST::NativeTypeDeclaration>(namedType));
467     auto iterator = m_namedTypeMapping.find(&namedType);
468     ASSERT(iterator != m_namedTypeMapping.end());
469     return iterator->value;
470 }
471
472
473 String TypeNamer::mangledNameForEnumerationMember(AST::EnumerationMember& enumerationMember)
474 {
475     auto iterator = m_enumerationMemberMapping.find(&enumerationMember);
476     ASSERT(iterator != m_enumerationMemberMapping.end());
477     return iterator->value;
478 }
479
480 String TypeNamer::mangledNameForStructureElement(AST::StructureElement& structureElement)
481 {
482     auto iterator = m_structureElementMapping.find(&structureElement);
483     ASSERT(iterator != m_structureElementMapping.end());
484     return iterator->value;
485 }
486
487 String TypeNamer::metalTypes()
488 {
489     Visitor::visit(m_program);
490     StringBuilder stringBuilder;
491     stringBuilder.append(metalTypeDeclarations());
492     stringBuilder.append('\n');
493     stringBuilder.append(metalTypeDefinitions());
494     return stringBuilder.toString();
495 }
496
497 } // namespace Metal
498
499 } // namespace WHLSL
500
501 } // namespace WebCore
502
503 #endif