string.go raw

   1  //go:build !purego
   2  
   3  //===- string.go - Stringer implementation for Type -----------------------===//
   4  //
   5  // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
   6  // See https://llvm.org/LICENSE.txt for license information.
   7  // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
   8  //
   9  //===----------------------------------------------------------------------===//
  10  //
  11  // This file implements the Stringer interface for the Type type.
  12  //
  13  //===----------------------------------------------------------------------===//
  14  
  15  package llvm
  16  
  17  import "fmt"
  18  
  19  func (t TypeKind) String() string {
  20  	switch t {
  21  	case VoidTypeKind:
  22  		return "VoidTypeKind"
  23  	case FloatTypeKind:
  24  		return "FloatTypeKind"
  25  	case DoubleTypeKind:
  26  		return "DoubleTypeKind"
  27  	case X86_FP80TypeKind:
  28  		return "X86_FP80TypeKind"
  29  	case FP128TypeKind:
  30  		return "FP128TypeKind"
  31  	case PPC_FP128TypeKind:
  32  		return "PPC_FP128TypeKind"
  33  	case LabelTypeKind:
  34  		return "LabelTypeKind"
  35  	case IntegerTypeKind:
  36  		return "IntegerTypeKind"
  37  	case FunctionTypeKind:
  38  		return "FunctionTypeKind"
  39  	case StructTypeKind:
  40  		return "StructTypeKind"
  41  	case ArrayTypeKind:
  42  		return "ArrayTypeKind"
  43  	case PointerTypeKind:
  44  		return "PointerTypeKind"
  45  	case VectorTypeKind:
  46  		return "VectorTypeKind"
  47  	case MetadataTypeKind:
  48  		return "MetadataTypeKind"
  49  	}
  50  	panic("unreachable")
  51  }
  52  
  53  func (t Type) String() string {
  54  	ts := typeStringer{s: make(map[Type]string)}
  55  	return ts.typeString(t)
  56  }
  57  
  58  type typeStringer struct {
  59  	s map[Type]string
  60  }
  61  
  62  func (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