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 VectorTypeKind:
44		return "VectorTypeKind"
45	case MetadataTypeKind:
46		return "MetadataTypeKind"
47	}
48	panic("unreachable")
49}
50
51func (t Type) String() string {
52	ts := typeStringer{s: make(map[Type]string)}
53	return ts.typeString(t)
54}
55
56type typeStringer struct {
57	s map[Type]string
58}
59
60func (ts *typeStringer) typeString(t Type) string {
61	if s, ok := ts.s[t]; ok {
62		return s
63	}
64
65	k := t.TypeKind()
66	s := k.String()
67	s = s[:len(s)-len("Kind")]
68
69	switch k {
70	case ArrayTypeKind:
71		s += fmt.Sprintf("(%v[%v])", ts.typeString(t.ElementType()), t.ArrayLength())
72	case PointerTypeKind:
73		s += fmt.Sprintf("(%v)", ts.typeString(t.ElementType()))
74	case FunctionTypeKind:
75		params := t.ParamTypes()
76		s += "("
77		if len(params) > 0 {
78			s += fmt.Sprintf("%v", ts.typeString(params[0]))
79			for i := 1; i < len(params); i++ {
80				s += fmt.Sprintf(", %v", ts.typeString(params[i]))
81			}
82		}
83		s += fmt.Sprintf("):%v", ts.typeString(t.ReturnType()))
84	case StructTypeKind:
85		if name := t.StructName(); name != "" {
86			ts.s[t] = "%" + name
87			s = fmt.Sprintf("%%%s: %s", name, s)
88		}
89		etypes := t.StructElementTypes()
90		s += "("
91		if n := len(etypes); n > 0 {
92			s += ts.typeString(etypes[0])
93			for i := 1; i < n; i++ {
94				s += fmt.Sprintf(", %v", ts.typeString(etypes[i]))
95			}
96		}
97		s += ")"
98	case IntegerTypeKind:
99		s += fmt.Sprintf("(%d bits)", t.IntTypeWidth())
100	}
101
102	ts.s[t] = s
103	return s
104}
105