• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
5package types
6
7import (
8	"cmd/compile/internal/base"
9	"cmd/internal/src"
10)
11
12var basicTypes = [...]struct {
13	name  string
14	etype Kind
15}{
16	{"int8", TINT8},
17	{"int16", TINT16},
18	{"int32", TINT32},
19	{"int64", TINT64},
20	{"uint8", TUINT8},
21	{"uint16", TUINT16},
22	{"uint32", TUINT32},
23	{"uint64", TUINT64},
24	{"float32", TFLOAT32},
25	{"float64", TFLOAT64},
26	{"complex64", TCOMPLEX64},
27	{"complex128", TCOMPLEX128},
28	{"bool", TBOOL},
29	{"string", TSTRING},
30}
31
32var typedefs = [...]struct {
33	name     string
34	etype    Kind
35	sameas32 Kind
36	sameas64 Kind
37}{
38	{"int", TINT, TINT32, TINT64},
39	{"uint", TUINT, TUINT32, TUINT64},
40	{"uintptr", TUINTPTR, TUINT32, TUINT64},
41}
42
43func InitTypes(defTypeName func(sym *Sym, typ *Type) Object) {
44	if PtrSize == 0 {
45		base.Fatalf("InitTypes called before PtrSize was set")
46	}
47
48	SlicePtrOffset = 0
49	SliceLenOffset = RoundUp(SlicePtrOffset+int64(PtrSize), int64(PtrSize))
50	SliceCapOffset = RoundUp(SliceLenOffset+int64(PtrSize), int64(PtrSize))
51	SliceSize = RoundUp(SliceCapOffset+int64(PtrSize), int64(PtrSize))
52
53	// string is same as slice wo the cap
54	StringSize = RoundUp(SliceLenOffset+int64(PtrSize), int64(PtrSize))
55
56	for et := Kind(0); et < NTYPE; et++ {
57		SimType[et] = et
58	}
59
60	Types[TANY] = newType(TANY) // note: an old placeholder type, NOT the new builtin 'any' alias for interface{}
61	Types[TINTER] = NewInterface(nil)
62	CheckSize(Types[TINTER])
63
64	defBasic := func(kind Kind, pkg *Pkg, name string) *Type {
65		typ := newType(kind)
66		obj := defTypeName(pkg.Lookup(name), typ)
67		typ.obj = obj
68		if kind != TANY {
69			CheckSize(typ)
70		}
71		return typ
72	}
73
74	for _, s := range &basicTypes {
75		Types[s.etype] = defBasic(s.etype, BuiltinPkg, s.name)
76	}
77
78	for _, s := range &typedefs {
79		sameas := s.sameas32
80		if PtrSize == 8 {
81			sameas = s.sameas64
82		}
83		SimType[s.etype] = sameas
84
85		Types[s.etype] = defBasic(s.etype, BuiltinPkg, s.name)
86	}
87
88	// We create separate byte and rune types for better error messages
89	// rather than just creating type alias *Sym's for the uint8 and
90	// int32  Hence, (bytetype|runtype).Sym.isAlias() is false.
91	// TODO(gri) Should we get rid of this special case (at the cost
92	// of less informative error messages involving bytes and runes)?
93	// NOTE(rsc): No, the error message quality is important.
94	// (Alternatively, we could introduce an OTALIAS node representing
95	// type aliases, albeit at the cost of having to deal with it everywhere).
96	ByteType = defBasic(TUINT8, BuiltinPkg, "byte")
97	RuneType = defBasic(TINT32, BuiltinPkg, "rune")
98
99	// error type
100	DeferCheckSize()
101	ErrorType = defBasic(TFORW, BuiltinPkg, "error")
102	ErrorType.SetUnderlying(makeErrorInterface())
103	ResumeCheckSize()
104
105	// comparable type (interface)
106	DeferCheckSize()
107	ComparableType = defBasic(TFORW, BuiltinPkg, "comparable")
108	ComparableType.SetUnderlying(makeComparableInterface())
109	ResumeCheckSize()
110
111	// any type (interface)
112	DeferCheckSize()
113	AnyType = defBasic(TFORW, BuiltinPkg, "any")
114	AnyType.SetUnderlying(NewInterface(nil))
115	ResumeCheckSize()
116
117	Types[TUNSAFEPTR] = defBasic(TUNSAFEPTR, UnsafePkg, "Pointer")
118
119	Types[TBLANK] = newType(TBLANK)
120	Types[TNIL] = newType(TNIL)
121
122	// simple aliases
123	SimType[TMAP] = TPTR
124	SimType[TCHAN] = TPTR
125	SimType[TFUNC] = TPTR
126	SimType[TUNSAFEPTR] = TPTR
127
128	for et := TINT8; et <= TUINT64; et++ {
129		IsInt[et] = true
130	}
131	IsInt[TINT] = true
132	IsInt[TUINT] = true
133	IsInt[TUINTPTR] = true
134
135	IsFloat[TFLOAT32] = true
136	IsFloat[TFLOAT64] = true
137
138	IsComplex[TCOMPLEX64] = true
139	IsComplex[TCOMPLEX128] = true
140}
141
142func makeErrorInterface() *Type {
143	sig := NewSignature(FakeRecv(), nil, []*Field{
144		NewField(src.NoXPos, nil, Types[TSTRING]),
145	})
146	method := NewField(src.NoXPos, LocalPkg.Lookup("Error"), sig)
147	return NewInterface([]*Field{method})
148}
149
150// makeComparableInterface makes the predefined "comparable" interface in the
151// built-in package. It has a unique name, but no methods.
152func makeComparableInterface() *Type {
153	return NewInterface(nil)
154}
155