Source file src/cmd/compile/internal/ir/type.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  	"cmd/compile/internal/base"
     9  	"cmd/compile/internal/types"
    10  	"cmd/internal/src"
    11  )
    12  
    13  // Calling TypeNode converts a *types.Type to a Node shell.
    14  
    15  // A typeNode is a Node wrapper for type t.
    16  type typeNode struct {
    17  	miniNode
    18  	typ *types.Type
    19  }
    20  
    21  func newTypeNode(typ *types.Type) *typeNode {
    22  	n := &typeNode{typ: typ}
    23  	n.pos = src.NoXPos
    24  	n.op = OTYPE
    25  	n.SetTypecheck(1)
    26  	return n
    27  }
    28  
    29  func (n *typeNode) Type() *types.Type { return n.typ }
    30  func (n *typeNode) Sym() *types.Sym   { return n.typ.Sym() }
    31  
    32  // TypeNode returns the Node representing the type t.
    33  func TypeNode(t *types.Type) Node {
    34  	if n := t.Obj(); n != nil {
    35  		if n.Type() != t {
    36  			base.Fatalf("type skew: %v has type %v, but expected %v", n, n.Type(), t)
    37  		}
    38  		return n.(*Name)
    39  	}
    40  	return newTypeNode(t)
    41  }
    42  
    43  // A DynamicType represents a type expression whose exact type must be
    44  // computed dynamically.
    45  //
    46  // TODO(adonovan): I think "dynamic" is a misnomer here; it's really a
    47  // type with free type parameters that needs to be instantiated to obtain
    48  // a ground type for which an rtype can exist.
    49  type DynamicType struct {
    50  	miniExpr
    51  
    52  	// RType is an expression that yields a *runtime._type value
    53  	// representing the asserted type.
    54  	//
    55  	// BUG(mdempsky): If ITab is non-nil, RType may be nil.
    56  	RType Node
    57  
    58  	// ITab is an expression that yields a *runtime.itab value
    59  	// representing the asserted type within the assertee expression's
    60  	// original interface type.
    61  	//
    62  	// ITab is only used for assertions (including type switches) from
    63  	// non-empty interface type to a concrete (i.e., non-interface)
    64  	// type. For all other assertions, ITab is nil.
    65  	ITab Node
    66  }
    67  
    68  func NewDynamicType(pos src.XPos, rtype Node) *DynamicType {
    69  	n := &DynamicType{RType: rtype}
    70  	n.pos = pos
    71  	n.op = ODYNAMICTYPE
    72  	return n
    73  }
    74  
    75  // ToStatic returns static type of dt if it is actually static.
    76  func (dt *DynamicType) ToStatic() Node {
    77  	if dt.Typecheck() == 0 {
    78  		base.Fatalf("missing typecheck: %v", dt)
    79  	}
    80  	if dt.RType != nil && dt.RType.Op() == OADDR {
    81  		addr := dt.RType.(*AddrExpr)
    82  		if addr.X.Op() == OLINKSYMOFFSET {
    83  			return TypeNode(dt.Type())
    84  		}
    85  	}
    86  	if dt.ITab != nil && dt.ITab.Op() == OADDR {
    87  		addr := dt.ITab.(*AddrExpr)
    88  		if addr.X.Op() == OLINKSYMOFFSET {
    89  			return TypeNode(dt.Type())
    90  		}
    91  	}
    92  	return nil
    93  }
    94  

View as plain text