4de3ded3465ab74b18cd796cf531808c6b7d46ca
[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     if (auto* result = m_unnamedTypeMapping.get(&unnamedType))
321         return result;
322
323     Vector<UniqueRef<BaseTypeNameNode>>* vectorToInsertInto { nullptr };
324     BaseTypeNameNode* parent { nullptr };
325     if (is<AST::TypeReference>(unnamedType)) {
326         vectorToInsertInto = &types;
327         parent = nullptr;
328     } else if (is<AST::PointerType>(unnamedType)) {
329         parent = insert(downcast<AST::PointerType>(unnamedType).elementType(), types);
330         vectorToInsertInto = &parent->children();
331     } else if (is<AST::ArrayReferenceType>(unnamedType)) {
332         parent = insert(downcast<AST::ArrayReferenceType>(unnamedType).elementType(), types);
333         vectorToInsertInto = &parent->children();
334     } else {
335         parent = insert(downcast<AST::ArrayType>(unnamedType).type(), types);
336         vectorToInsertInto = &parent->children();
337     }
338     ASSERT(vectorToInsertInto);
339
340     auto iterator = findInVector(unnamedType, *vectorToInsertInto);
341     if (iterator == vectorToInsertInto->end()) {
342         auto result = createNameNode(unnamedType, parent);
343         {
344             auto addResult = m_unnamedTypeMapping.add(&unnamedType, &result);
345             ASSERT_UNUSED(addResult, addResult.isNewEntry);
346         }
347         vectorToInsertInto->append(WTFMove(result));
348         return &vectorToInsertInto->last().get();
349     }
350     m_unnamedTypeMapping.add(&unnamedType, &*iterator);
351     return &*iterator;
352 }
353
354 class MetalTypeDeclarationWriter : public Visitor {
355     WTF_MAKE_FAST_ALLOCATED;
356 public:
357     MetalTypeDeclarationWriter(std::function<String(AST::NamedType&)>&& mangledNameForNamedType)
358         : m_mangledNameForNamedType(WTFMove(mangledNameForNamedType))
359     {
360     }
361
362     String toString() { return m_stringBuilder.toString(); }
363
364 private:
365     void visit(AST::StructureDefinition& structureDefinition)
366     {
367         m_stringBuilder.flexibleAppend("struct ", m_mangledNameForNamedType(structureDefinition), ";\n");
368     }
369
370     std::function<String(AST::NamedType&)> m_mangledNameForNamedType;
371     StringBuilder m_stringBuilder;
372 };
373
374 String TypeNamer::metalTypeDeclarations()
375 {
376     MetalTypeDeclarationWriter metalTypeDeclarationWriter([&](AST::NamedType& namedType) -> String {
377         return mangledNameForType(namedType);
378     });
379     metalTypeDeclarationWriter.Visitor::visit(m_program);
380     return metalTypeDeclarationWriter.toString();
381 }
382
383 void TypeNamer::emitUnnamedTypeDefinition(BaseTypeNameNode& baseTypeNameNode, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes, StringBuilder& stringBuilder)
384 {
385     if (emittedUnnamedTypes.contains(&baseTypeNameNode))
386         return;
387     if (baseTypeNameNode.parent())
388         emitUnnamedTypeDefinition(*baseTypeNameNode.parent(), emittedNamedTypes, emittedUnnamedTypes, stringBuilder);
389     if (is<ReferenceTypeNameNode>(baseTypeNameNode)) {
390         auto& namedType = downcast<ReferenceTypeNameNode>(baseTypeNameNode).namedType();
391         emitNamedTypeDefinition(namedType, emittedNamedTypes, emittedUnnamedTypes, stringBuilder);
392         stringBuilder.flexibleAppend("typedef ", mangledNameForType(namedType), ' ', baseTypeNameNode.mangledName(), ";\n");
393     } else if (is<PointerTypeNameNode>(baseTypeNameNode)) {
394         auto& pointerType = downcast<PointerTypeNameNode>(baseTypeNameNode);
395         ASSERT(baseTypeNameNode.parent());
396         stringBuilder.flexibleAppend("typedef ", toString(pointerType.addressSpace()), ' ', pointerType.parent()->mangledName(), "* ", pointerType.mangledName(), ";\n");
397     } else if (is<ArrayReferenceTypeNameNode>(baseTypeNameNode)) {
398         auto& arrayReferenceType = downcast<ArrayReferenceTypeNameNode>(baseTypeNameNode);
399         ASSERT(baseTypeNameNode.parent());
400         stringBuilder.flexibleAppend(
401             "struct ", arrayReferenceType.mangledName(), "{ \n"
402             "    ", toString(arrayReferenceType.addressSpace()), ' ', arrayReferenceType.parent()->mangledName(), "* pointer;\n"
403             "    uint32_t length;\n"
404             "};\n"
405         );
406     } else {
407         auto& arrayType = downcast<ArrayTypeNameNode>(baseTypeNameNode);
408         ASSERT(baseTypeNameNode.parent());
409         stringBuilder.flexibleAppend("typedef array<", arrayType.parent()->mangledName(), ", ", arrayType.numElements(), "> ", arrayType.mangledName(), ";\n");
410     }
411     emittedUnnamedTypes.add(&baseTypeNameNode);
412 }
413
414 void TypeNamer::emitNamedTypeDefinition(AST::NamedType& namedType, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes, StringBuilder& stringBuilder)
415 {
416     if (emittedNamedTypes.contains(&namedType))
417         return;
418     auto iterator = m_dependencyGraph.find(&namedType);
419     ASSERT(iterator != m_dependencyGraph.end());
420     for (auto& baseTypeNameNode : iterator->value)
421         emitUnnamedTypeDefinition(baseTypeNameNode, emittedNamedTypes, emittedUnnamedTypes, stringBuilder);
422     if (is<AST::EnumerationDefinition>(namedType)) {
423         auto& enumerationDefinition = downcast<AST::EnumerationDefinition>(namedType);
424         auto& baseType = enumerationDefinition.type().unifyNode();
425         stringBuilder.flexibleAppend("enum class ", mangledNameForType(enumerationDefinition), " : ", mangledNameForType(downcast<AST::NamedType>(baseType)), " {\n");
426         for (auto& enumerationMember : enumerationDefinition.enumerationMembers())
427             stringBuilder.flexibleAppend("    ", mangledNameForEnumerationMember(enumerationMember), " = ", enumerationMember.get().value(), ",\n");
428         stringBuilder.append("};\n");
429     } else if (is<AST::NativeTypeDeclaration>(namedType)) {
430         // Native types already have definitions. There's nothing to do.
431     } else if (is<AST::StructureDefinition>(namedType)) {
432         auto& structureDefinition = downcast<AST::StructureDefinition>(namedType);
433         stringBuilder.flexibleAppend("struct ", mangledNameForType(structureDefinition), " {\n");
434         for (auto& structureElement : structureDefinition.structureElements())
435             stringBuilder.flexibleAppend("    ", mangledNameForType(structureElement.type()), ' ', mangledNameForStructureElement(structureElement), ";\n");
436         stringBuilder.append("};\n");
437     } else {
438         auto& typeDefinition = downcast<AST::TypeDefinition>(namedType);
439         stringBuilder.flexibleAppend("typedef ", mangledNameForType(typeDefinition.type()), ' ', mangledNameForType(typeDefinition), ";\n");
440     }
441     emittedNamedTypes.add(&namedType);
442 }
443
444 void TypeNamer::emitAllUnnamedTypeDefinitions(Vector<UniqueRef<BaseTypeNameNode>>& nodes, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes, StringBuilder& stringBuilder)
445 {
446     for (auto& node : nodes) {
447         emitUnnamedTypeDefinition(node, emittedNamedTypes, emittedUnnamedTypes, stringBuilder);
448         emitAllUnnamedTypeDefinitions(node->children(), emittedNamedTypes, emittedUnnamedTypes, stringBuilder);
449     }
450 }
451
452 String TypeNamer::metalTypeDefinitions()
453 {
454     HashSet<AST::NamedType*> emittedNamedTypes;
455     HashSet<BaseTypeNameNode*> emittedUnnamedTypes;
456     StringBuilder stringBuilder;
457     for (auto& keyValuePair : m_dependencyGraph)
458         emitNamedTypeDefinition(*keyValuePair.key, emittedNamedTypes, emittedUnnamedTypes, stringBuilder);
459     emitAllUnnamedTypeDefinitions(m_trie, emittedNamedTypes, emittedUnnamedTypes, stringBuilder);
460     return stringBuilder.toString();
461 }
462
463 String TypeNamer::mangledNameForType(AST::UnnamedType& unnamedType)
464 {
465     return find(unnamedType, m_trie).mangledName();
466 }
467
468 String TypeNamer::mangledNameForType(AST::NamedType& namedType)
469 {
470     if (is<AST::NativeTypeDeclaration>(namedType))
471         return mangledNameForType(downcast<AST::NativeTypeDeclaration>(namedType));
472     auto iterator = m_namedTypeMapping.find(&namedType);
473     ASSERT(iterator != m_namedTypeMapping.end());
474     return iterator->value;
475 }
476
477
478 String TypeNamer::mangledNameForEnumerationMember(AST::EnumerationMember& enumerationMember)
479 {
480     auto iterator = m_enumerationMemberMapping.find(&enumerationMember);
481     ASSERT(iterator != m_enumerationMemberMapping.end());
482     return iterator->value;
483 }
484
485 String TypeNamer::mangledNameForStructureElement(AST::StructureElement& structureElement)
486 {
487     auto iterator = m_structureElementMapping.find(&structureElement);
488     ASSERT(iterator != m_structureElementMapping.end());
489     return iterator->value;
490 }
491
492 String TypeNamer::metalTypes()
493 {
494     Visitor::visit(m_program);
495     return makeString(metalTypeDeclarations(), '\n', metalTypeDefinitions());
496 }
497
498 } // namespace Metal
499
500 } // namespace WHLSL
501
502 } // namespace WebCore
503
504 #endif