1//===- string.go - Stringer implementation for Type -----------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the Stringer interface for the Type type.
10//
11//===----------------------------------------------------------------------===//
12
13package llvm
14
15import "fmt"
16
17func (t TypeKind) String() string {
18	switch t {
19	case VoidTypeKind:
20		return "VoidTypeKind"
21	case FloatTypeKind:
22		return "FloatTypeKind"
23	case DoubleTypeKind:
24		return "DoubleTypeKind"
25	case X86_FP80TypeKind:
26		return "X86_FP80TypeKind"
27	case FP128TypeKind:
28		return "FP128TypeKind"
29	case PPC_FP128TypeKind:
30		return "PPC_FP128TypeKind"
31	case LabelTypeKind:
32		return "LabelTypeKind"
33	case IntegerTypeKind:
34		return "IntegerTypeKind"
35	case FunctionTypeKind:
36		return "FunctionTypeKind"
37	case StructTypeKind:
38		return "StructTypeKind"
39	case ArrayTypeKind:
40		return "ArrayTypeKind"
41	case PointerTypeKind:
42		return "PointerTypeKind"
43	case MetadataTypeKind:
44		return "MetadataTypeKind"
45	case VectorTypeKind:
46		return "VectorTypeKind"
47	case ScalableVectorTypeKind:
48		return "ScalableVectorTypeKind"
49	}
50	panic("unreachable")
51}
52
53func (t Type) String() string {
54	ts := typeStringer{s: make(map[Type]string)}
55	return ts.typeString(t)
56}
57
58type typeStringer struct {
59	s map[Type]string
60}
61
62func (ts *typeStringer) typeString(t Type) string {
63	if s, ok := ts.s[t]; ok {
64		return s
65	}
66
67	k := t.TypeKind()
68	s := k.String()
69	s = s[:len(s)-len("Kind")]
70
71	switch k {
72	case ArrayTypeKind:
73		s += fmt.Sprintf("(%v[%v])", ts.typeString(t.ElementType()), t.ArrayLength())
74	case PointerTypeKind:
75		s += fmt.Sprintf("(%v)", ts.typeString(t.ElementType()))
76	case FunctionTypeKind:
77		params := t.ParamTypes()
78		s += "("
79		if len(params) > 0 {
80			s += fmt.Sprintf("%v", ts.typeString(params[0]))
81			for i := 1; i < len(params); i++ {
82				s += fmt.Sprintf(", %v", ts.typeString(params[i]))
83			}
84		}
85		s += fmt.Sprintf("):%v", ts.typeString(t.ReturnType()))
86	case StructTypeKind:
87		if name := t.StructName(); name != "" {
88			ts.s[t] = "%" + name
89			s = fmt.Sprintf("%%%s: %s", name, s)
90		}
91		etypes := t.StructElementTypes()
92		s += "("
93		if n := len(etypes); n > 0 {
94			s += ts.typeString(etypes[0])
95			for i := 1; i < n; i++ {
96				s += fmt.Sprintf(", %v", ts.typeString(etypes[i]))
97			}
98		}
99		s += ")"
100	case IntegerTypeKind:
101		s += fmt.Sprintf("(%d bits)", t.IntTypeWidth())
102	}
103
104	ts.s[t] = s
105	return s
106}
107