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  type DynamicType struct {
    46  	miniExpr
    47  
    48  	// RType is an expression that yields a *runtime._type value
    49  	// representing the asserted type.
    50  	//
    51  	// BUG(mdempsky): If ITab is non-nil, RType may be nil.
    52  	RType Node
    53  
    54  	// ITab is an expression that yields a *runtime.itab value
    55  	// representing the asserted type within the assertee expression's
    56  	// original interface type.
    57  	//
    58  	// ITab is only used for assertions (including type switches) from
    59  	// non-empty interface type to a concrete (i.e., non-interface)
    60  	// type. For all other assertions, ITab is nil.
    61  	ITab Node
    62  }
    63  
    64  func NewDynamicType(pos src.XPos, rtype Node) *DynamicType {
    65  	n := &DynamicType{RType: rtype}
    66  	n.pos = pos
    67  	n.op = ODYNAMICTYPE
    68  	return n
    69  }
    70  
    71  // ToStatic returns static type of dt if it is actually static.
    72  func (dt *DynamicType) ToStatic() Node {
    73  	if dt.Typecheck() == 0 {
    74  		base.Fatalf("missing typecheck: %v", dt)
    75  	}
    76  	if dt.RType != nil && dt.RType.Op() == OADDR {
    77  		addr := dt.RType.(*AddrExpr)
    78  		if addr.X.Op() == OLINKSYMOFFSET {
    79  			return TypeNode(dt.Type())
    80  		}
    81  	}
    82  	if dt.ITab != nil && dt.ITab.Op() == OADDR {
    83  		addr := dt.ITab.(*AddrExpr)
    84  		if addr.X.Op() == OLINKSYMOFFSET {
    85  			return TypeNode(dt.Type())
    86  		}
    87  	}
    88  	return nil
    89  }
    90  

View as plain text