mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-15 16:33:40 +00:00
compiler: add support for GODEBUG=gotypesalias=1
Since we now require Go 1.22, this became a lot simpler (since we can now refer to `types.Alias` and `types.Unalias`).
This commit is contained in:
committed by
Ron Evans
parent
3f4f4e0ead
commit
2e043c7fbc
+21
-1
@@ -389,7 +389,7 @@ func (c *compilerContext) getLLVMType(goType types.Type) llvm.Type {
|
|||||||
// makeLLVMType creates a LLVM type for a Go type. Don't call this, use
|
// makeLLVMType creates a LLVM type for a Go type. Don't call this, use
|
||||||
// getLLVMType instead.
|
// getLLVMType instead.
|
||||||
func (c *compilerContext) makeLLVMType(goType types.Type) llvm.Type {
|
func (c *compilerContext) makeLLVMType(goType types.Type) llvm.Type {
|
||||||
switch typ := goType.(type) {
|
switch typ := types.Unalias(goType).(type) {
|
||||||
case *types.Array:
|
case *types.Array:
|
||||||
elemType := c.getLLVMType(typ.Elem())
|
elemType := c.getLLVMType(typ.Elem())
|
||||||
return llvm.ArrayType(elemType, int(typ.Len()))
|
return llvm.ArrayType(elemType, int(typ.Len()))
|
||||||
@@ -497,6 +497,21 @@ func (c *compilerContext) createDIType(typ types.Type) llvm.Metadata {
|
|||||||
llvmType := c.getLLVMType(typ)
|
llvmType := c.getLLVMType(typ)
|
||||||
sizeInBytes := c.targetData.TypeAllocSize(llvmType)
|
sizeInBytes := c.targetData.TypeAllocSize(llvmType)
|
||||||
switch typ := typ.(type) {
|
switch typ := typ.(type) {
|
||||||
|
case *types.Alias:
|
||||||
|
// Implement types.Alias just like types.Named: by treating them like a
|
||||||
|
// C typedef.
|
||||||
|
temporaryMDNode := c.dibuilder.CreateReplaceableCompositeType(llvm.Metadata{}, llvm.DIReplaceableCompositeType{
|
||||||
|
Tag: dwarf.TagTypedef,
|
||||||
|
SizeInBits: sizeInBytes * 8,
|
||||||
|
AlignInBits: uint32(c.targetData.ABITypeAlignment(llvmType)) * 8,
|
||||||
|
})
|
||||||
|
c.ditypes[typ] = temporaryMDNode
|
||||||
|
md := c.dibuilder.CreateTypedef(llvm.DITypedef{
|
||||||
|
Type: c.getDIType(types.Unalias(typ)), // TODO: use typ.Rhs in Go 1.23
|
||||||
|
Name: typ.String(),
|
||||||
|
})
|
||||||
|
temporaryMDNode.ReplaceAllUsesWith(md)
|
||||||
|
return md
|
||||||
case *types.Array:
|
case *types.Array:
|
||||||
return c.dibuilder.CreateArrayType(llvm.DIArrayType{
|
return c.dibuilder.CreateArrayType(llvm.DIArrayType{
|
||||||
SizeInBits: sizeInBytes * 8,
|
SizeInBits: sizeInBytes * 8,
|
||||||
@@ -859,6 +874,11 @@ func (c *compilerContext) createPackage(irbuilder llvm.Builder, pkg *ssa.Package
|
|||||||
// Interfaces don't have concrete methods.
|
// Interfaces don't have concrete methods.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if _, isalias := member.Type().(*types.Alias); isalias {
|
||||||
|
// Aliases don't need to be redefined, since they just refer to
|
||||||
|
// an already existing type whose methods will be defined.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
// Named type. We should make sure all methods are created.
|
// Named type. We should make sure all methods are created.
|
||||||
// This includes both functions with pointer receivers and those
|
// This includes both functions with pointer receivers and those
|
||||||
|
|||||||
@@ -122,6 +122,9 @@ func (c *compilerContext) pkgPathPtr(pkgpath string) llvm.Value {
|
|||||||
// This function returns a pointer to the 'kind' field (which might not be the
|
// This function returns a pointer to the 'kind' field (which might not be the
|
||||||
// first field in the struct).
|
// first field in the struct).
|
||||||
func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
|
func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
|
||||||
|
// Resolve alias types: alias types are resolved at compile time.
|
||||||
|
typ = types.Unalias(typ)
|
||||||
|
|
||||||
ms := c.program.MethodSets.MethodSet(typ)
|
ms := c.program.MethodSets.MethodSet(typ)
|
||||||
hasMethodSet := ms.Len() != 0
|
hasMethodSet := ms.Len() != 0
|
||||||
_, isInterface := typ.Underlying().(*types.Interface)
|
_, isInterface := typ.Underlying().(*types.Interface)
|
||||||
@@ -512,7 +515,7 @@ var basicTypeNames = [...]string{
|
|||||||
// interface lowering pass to assign type codes as expected by the reflect
|
// interface lowering pass to assign type codes as expected by the reflect
|
||||||
// package. See getTypeCodeNum.
|
// package. See getTypeCodeNum.
|
||||||
func getTypeCodeName(t types.Type) (string, bool) {
|
func getTypeCodeName(t types.Type) (string, bool) {
|
||||||
switch t := t.(type) {
|
switch t := types.Unalias(t).(type) {
|
||||||
case *types.Named:
|
case *types.Named:
|
||||||
if t.Obj().Parent() != t.Obj().Pkg().Scope() {
|
if t.Obj().Parent() != t.Obj().Pkg().Scope() {
|
||||||
return "named:" + t.String() + "$local", true
|
return "named:" + t.String() + "$local", true
|
||||||
@@ -942,7 +945,7 @@ func signature(sig *types.Signature) string {
|
|||||||
// normalization around `byte` vs `uint8` for example.
|
// normalization around `byte` vs `uint8` for example.
|
||||||
func typestring(t types.Type) string {
|
func typestring(t types.Type) string {
|
||||||
// See: https://github.com/golang/go/blob/master/src/go/types/typestring.go
|
// See: https://github.com/golang/go/blob/master/src/go/types/typestring.go
|
||||||
switch t := t.(type) {
|
switch t := types.Unalias(t).(type) {
|
||||||
case *types.Array:
|
case *types.Array:
|
||||||
return "[" + strconv.FormatInt(t.Len(), 10) + "]" + typestring(t.Elem())
|
return "[" + strconv.FormatInt(t.Len(), 10) + "]" + typestring(t.Elem())
|
||||||
case *types.Basic:
|
case *types.Basic:
|
||||||
|
|||||||
+1
-3
@@ -248,7 +248,7 @@ func (b *builder) createMapIteratorNext(rangeVal ssa.Value, llvmRangeVal, it llv
|
|||||||
// can be compared with runtime.memequal. Note that padding bytes are undef
|
// can be compared with runtime.memequal. Note that padding bytes are undef
|
||||||
// and can alter two "equal" structs being equal when compared with memequal.
|
// and can alter two "equal" structs being equal when compared with memequal.
|
||||||
func hashmapIsBinaryKey(keyType types.Type) bool {
|
func hashmapIsBinaryKey(keyType types.Type) bool {
|
||||||
switch keyType := keyType.(type) {
|
switch keyType := keyType.Underlying().(type) {
|
||||||
case *types.Basic:
|
case *types.Basic:
|
||||||
return keyType.Info()&(types.IsBoolean|types.IsInteger) != 0
|
return keyType.Info()&(types.IsBoolean|types.IsInteger) != 0
|
||||||
case *types.Pointer:
|
case *types.Pointer:
|
||||||
@@ -263,8 +263,6 @@ func hashmapIsBinaryKey(keyType types.Type) bool {
|
|||||||
return true
|
return true
|
||||||
case *types.Array:
|
case *types.Array:
|
||||||
return hashmapIsBinaryKey(keyType.Elem())
|
return hashmapIsBinaryKey(keyType.Elem())
|
||||||
case *types.Named:
|
|
||||||
return hashmapIsBinaryKey(keyType.Underlying())
|
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,9 +67,6 @@
|
|||||||
# has `md5sum`).
|
# has `md5sum`).
|
||||||
export MD5SUM=md5sum
|
export MD5SUM=md5sum
|
||||||
|
|
||||||
# Work around #4819, missing support for generic type aliases.
|
|
||||||
export GODEBUG=gotypesalias=0
|
|
||||||
|
|
||||||
# Ugly hack to make the Clang resources directory available.
|
# Ugly hack to make the Clang resources directory available.
|
||||||
export GOFLAGS="\"-ldflags=-X github.com/tinygo-org/tinygo/goenv.clangResourceDir=${llvmPackages_20.clang.cc.lib}/lib/clang/20\" -tags=llvm20"
|
export GOFLAGS="\"-ldflags=-X github.com/tinygo-org/tinygo/goenv.clangResourceDir=${llvmPackages_20.clang.cc.lib}/lib/clang/20\" -tags=llvm20"
|
||||||
'';
|
'';
|
||||||
|
|||||||
Reference in New Issue
Block a user