Source file src/cmd/compile/internal/ir/val.go

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package ir
     6  
     7  import (
     8  	"go/constant"
     9  
    10  	"cmd/compile/internal/base"
    11  	"cmd/compile/internal/types"
    12  )
    13  
    14  func ConstType(n Node) constant.Kind {
    15  	if n == nil || n.Op() != OLITERAL {
    16  		return constant.Unknown
    17  	}
    18  	return n.Val().Kind()
    19  }
    20  
    21  // IntVal returns v converted to int64.
    22  // Note: if t is uint64, very large values will be converted to negative int64.
    23  func IntVal(t *types.Type, v constant.Value) int64 {
    24  	if t.IsUnsigned() {
    25  		if x, ok := constant.Uint64Val(v); ok {
    26  			return int64(x)
    27  		}
    28  	} else {
    29  		if x, ok := constant.Int64Val(v); ok {
    30  			return x
    31  		}
    32  	}
    33  	base.Fatalf("%v out of range for %v", v, t)
    34  	panic("unreachable")
    35  }
    36  
    37  func AssertValidTypeForConst(t *types.Type, v constant.Value) {
    38  	if !ValidTypeForConst(t, v) {
    39  		base.Fatalf("%v (%v) does not represent %v (%v)", t, t.Kind(), v, v.Kind())
    40  	}
    41  }
    42  
    43  func ValidTypeForConst(t *types.Type, v constant.Value) bool {
    44  	switch v.Kind() {
    45  	case constant.Unknown:
    46  		return OKForConst[t.Kind()]
    47  	case constant.Bool:
    48  		return t.IsBoolean()
    49  	case constant.String:
    50  		return t.IsString()
    51  	case constant.Int:
    52  		return t.IsInteger()
    53  	case constant.Float:
    54  		return t.IsFloat()
    55  	case constant.Complex:
    56  		return t.IsComplex()
    57  	}
    58  
    59  	base.Fatalf("unexpected constant kind: %v", v)
    60  	panic("unreachable")
    61  }
    62  
    63  var OKForConst [types.NTYPE]bool
    64  
    65  // Int64Val returns n as an int64.
    66  // n must be an integer or rune constant.
    67  func Int64Val(n Node) int64 {
    68  	if !IsConst(n, constant.Int) {
    69  		base.Fatalf("Int64Val(%v)", n)
    70  	}
    71  	x, ok := constant.Int64Val(n.Val())
    72  	if !ok {
    73  		base.Fatalf("Int64Val(%v)", n)
    74  	}
    75  	return x
    76  }
    77  
    78  // Uint64Val returns n as a uint64.
    79  // n must be an integer or rune constant.
    80  func Uint64Val(n Node) uint64 {
    81  	if !IsConst(n, constant.Int) {
    82  		base.Fatalf("Uint64Val(%v)", n)
    83  	}
    84  	x, ok := constant.Uint64Val(n.Val())
    85  	if !ok {
    86  		base.Fatalf("Uint64Val(%v)", n)
    87  	}
    88  	return x
    89  }
    90  
    91  // BoolVal returns n as a bool.
    92  // n must be a boolean constant.
    93  func BoolVal(n Node) bool {
    94  	if !IsConst(n, constant.Bool) {
    95  		base.Fatalf("BoolVal(%v)", n)
    96  	}
    97  	return constant.BoolVal(n.Val())
    98  }
    99  
   100  // StringVal returns the value of a literal string Node as a string.
   101  // n must be a string constant.
   102  func StringVal(n Node) string {
   103  	if !IsConst(n, constant.String) {
   104  		base.Fatalf("StringVal(%v)", n)
   105  	}
   106  	return constant.StringVal(n.Val())
   107  }
   108  

View as plain text