string.go raw

   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  
  13  package llvm
  14  
  15  import "fmt"
  16  
  17  func (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  
  51  func (t Type) String() string {
  52  	ts := typeStringer{s: make(map[Type]string)}
  53  	return ts.typeString(t)
  54  }
  55  
  56  type typeStringer struct {
  57  	s map[Type]string
  58  }
  59  
  60  func (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