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