StringBuilder::append(makeString(...)) is inefficient
[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.flexibleAppend("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.flexibleAppend("typedef ", mangledNameForType(namedType), ' ', baseTypeNameNode.mangledName(), ";\n");
390     } else if (is<PointerTypeNameNode>(baseTypeNameNode)) {
391         auto& pointerType = downcast<PointerTypeNameNode>(baseTypeNameNode);
392         ASSERT(baseTypeNameNode.parent());
393         stringBuilder.flexibleAppend("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.flexibleAppend(
398             "struct ", arrayReferenceType.mangledName(), "{ \n"
399             "    ", toString(arrayReferenceType.addressSpace()), ' ', arrayReferenceType.parent()->mangledName(), "* pointer;\n"
400             "    uint32_t length;\n"
401             "};\n"
402         );
403     } else {
404         auto& arrayType = downcast<ArrayTypeNameNode>(baseTypeNameNode);
405         ASSERT(baseTypeNameNode.parent());
406         stringBuilder.flexibleAppend("typedef array<", arrayType.parent()->mangledName(), ", ", arrayType.numElements(), "> ", arrayType.mangledName(), ";\n");
407     }
408     emittedUnnamedTypes.add(&baseTypeNameNode);
409 }
410
411 void TypeNamer::emitNamedTypeDefinition(AST::NamedType& namedType, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes, StringBuilder& stringBuilder)
412 {
413     if (emittedNamedTypes.contains(&namedType))
414         return;
415     auto iterator = m_dependencyGraph.find(&namedType);
416     ASSERT(iterator != m_dependencyGraph.end());
417     for (auto& baseTypeNameNode : iterator->value)
418         emitUnnamedTypeDefinition(baseTypeNameNode, emittedNamedTypes, emittedUnnamedTypes, stringBuilder);
419     if (is<AST::EnumerationDefinition>(namedType)) {
420         auto& enumerationDefinition = downcast<AST::EnumerationDefinition>(namedType);
421         auto& baseType = enumerationDefinition.type().unifyNode();
422         stringBuilder.flexibleAppend("enum class ", mangledNameForType(enumerationDefinition), " : ", mangledNameForType(downcast<AST::NamedType>(baseType)), " {\n");
423         for (auto& enumerationMember : enumerationDefinition.enumerationMembers())
424             stringBuilder.flexibleAppend("    ", mangledNameForEnumerationMember(enumerationMember), " = ", enumerationMember.get().value(), ",\n");
425         stringBuilder.append("};\n");
426     } else if (is<AST::NativeTypeDeclaration>(namedType)) {
427         // Native types already have definitions. There's nothing to do.
428     } else if (is<AST::StructureDefinition>(namedType)) {
429         auto& structureDefinition = downcast<AST::StructureDefinition>(namedType);
430         stringBuilder.flexibleAppend("struct ", mangledNameForType(structureDefinition), " {\n");
431         for (auto& structureElement : structureDefinition.structureElements())
432             stringBuilder.flexibleAppend("    ", mangledNameForType(structureElement.type()), ' ', mangledNameForStructureElement(structureElement), ";\n");
433         stringBuilder.append("};\n");
434     } else {
435         auto& typeDefinition = downcast<AST::TypeDefinition>(namedType);
436         stringBuilder.flexibleAppend("typedef ", mangledNameForType(typeDefinition.type()), ' ', mangledNameForType(typeDefinition), ";\n");
437     }
438     emittedNamedTypes.add(&namedType);
439 }
440
441 void TypeNamer::emitAllUnnamedTypeDefinitions(Vector<UniqueRef<BaseTypeNameNode>>& nodes, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes, StringBuilder& stringBuilder)
442 {
443     for (auto& node : nodes) {
444         emitUnnamedTypeDefinition(node, emittedNamedTypes, emittedUnnamedTypes, stringBuilder);
445         emitAllUnnamedTypeDefinitions(node->children(), emittedNamedTypes, emittedUnnamedTypes, stringBuilder);
446     }
447 }
448
449 String TypeNamer::metalTypeDefinitions()
450 {
451     HashSet<AST::NamedType*> emittedNamedTypes;
452     HashSet<BaseTypeNameNode*> emittedUnnamedTypes;
453     StringBuilder stringBuilder;
454     for (auto& keyValuePair : m_dependencyGraph)
455         emitNamedTypeDefinition(*keyValuePair.key, emittedNamedTypes, emittedUnnamedTypes, stringBuilder);
456     emitAllUnnamedTypeDefinitions(m_trie, emittedNamedTypes, emittedUnnamedTypes, stringBuilder);
457     return stringBuilder.toString();
458 }
459
460 String TypeNamer::mangledNameForType(AST::UnnamedType& unnamedType)
461 {
462     return find(unnamedType, m_trie).mangledName();
463 }
464
465 String TypeNamer::mangledNameForType(AST::NamedType& namedType)
466 {
467     if (is<AST::NativeTypeDeclaration>(namedType))
468         return mangledNameForType(downcast<AST::NativeTypeDeclaration>(namedType));
469     auto iterator = m_namedTypeMapping.find(&namedType);
470     ASSERT(iterator != m_namedTypeMapping.end());
471     return iterator->value;
472 }
473
474
475 String TypeNamer::mangledNameForEnumerationMember(AST::EnumerationMember& enumerationMember)
476 {
477     auto iterator = m_enumerationMemberMapping.find(&enumerationMember);
478     ASSERT(iterator != m_enumerationMemberMapping.end());
479     return iterator->value;
480 }
481
482 String TypeNamer::mangledNameForStructureElement(AST::StructureElement& structureElement)
483 {
484     auto iterator = m_structureElementMapping.find(&structureElement);
485     ASSERT(iterator != m_structureElementMapping.end());
486     return iterator->value;
487 }
488
489 String TypeNamer::metalTypes()
490 {
491     Visitor::visit(m_program);
492     return makeString(metalTypeDeclarations(), '\n', metalTypeDefinitions());
493 }
494
495 } // namespace Metal
496
497 } // namespace WHLSL
498
499 } // namespace WebCore
500
501 #endif