compiler: fix type names for generic named structs

Without this change, the compiler would probably have worked just fine
but the generated types would look odd.

You can see in the test case that it now doesn't use `main.Point` but
rather the correct `main.Poin[float32]` etc.
Этот коммит содержится в:
Ayke van Laethem 2022-07-28 13:33:00 +02:00 коммит произвёл Ron Evans
родитель 5078ce382d
коммит 70c52ef1b4
3 изменённых файлов: 158 добавлений и 42 удалений

Просмотреть файл

@ -393,7 +393,7 @@ func (c *compilerContext) makeLLVMType(goType types.Type) llvm.Type {
// in LLVM IR, named structs are implemented as named structs in // in LLVM IR, named structs are implemented as named structs in
// LLVM. This is because it is otherwise impossible to create // LLVM. This is because it is otherwise impossible to create
// self-referencing types such as linked lists. // self-referencing types such as linked lists.
llvmName := typ.Obj().Pkg().Path() + "." + typ.Obj().Name() llvmName := typ.String()
llvmType := c.ctx.StructCreateNamed(llvmName) llvmType := c.ctx.StructCreateNamed(llvmName)
c.llvmTypes.Set(goType, llvmType) // avoid infinite recursion c.llvmTypes.Set(goType, llvmType) // avoid infinite recursion
underlying := c.getLLVMType(st) underlying := c.getLLVMType(st)

3
compiler/testdata/generics.go предоставленный
Просмотреть файл

@ -18,4 +18,7 @@ func Add[T Coord](a, b Point[T]) Point[T] {
func main() { func main() {
var af, bf Point[float32] var af, bf Point[float32]
Add(af, bf) Add(af, bf)
var ai, bi Point[int]
Add(ai, bi)
} }

195
compiler/testdata/generics.ll предоставленный
Просмотреть файл

@ -3,7 +3,8 @@ source_filename = "generics.go"
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20" target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
target triple = "wasm32-unknown-wasi" target triple = "wasm32-unknown-wasi"
%main.Point = type { float, float } %"main.Point[int]" = type { i32, i32 }
%"main.Point[float32]" = type { float, float }
declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0 declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0
@ -18,73 +19,96 @@ entry:
; Function Attrs: nounwind ; Function Attrs: nounwind
define hidden void @main.main(i8* %context) unnamed_addr #1 { define hidden void @main.main(i8* %context) unnamed_addr #1 {
entry: entry:
%bf = alloca %main.Point, align 8 %bi = alloca %"main.Point[int]", align 8
%af = alloca %main.Point, align 8 %ai = alloca %"main.Point[int]", align 8
%af.repack = getelementptr inbounds %main.Point, %main.Point* %af, i32 0, i32 0 %bf = alloca %"main.Point[float32]", align 8
%af = alloca %"main.Point[float32]", align 8
%af.repack = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %af, i32 0, i32 0
store float 0.000000e+00, float* %af.repack, align 8 store float 0.000000e+00, float* %af.repack, align 8
%af.repack1 = getelementptr inbounds %main.Point, %main.Point* %af, i32 0, i32 1 %af.repack1 = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %af, i32 0, i32 1
store float 0.000000e+00, float* %af.repack1, align 4 store float 0.000000e+00, float* %af.repack1, align 4
%0 = bitcast %main.Point* %af to i8* %0 = bitcast %"main.Point[float32]"* %af to i8*
call void @runtime.trackPointer(i8* nonnull %0, i8* undef) #2 call void @runtime.trackPointer(i8* nonnull %0, i8* undef) #2
%bf.repack = getelementptr inbounds %main.Point, %main.Point* %bf, i32 0, i32 0 %bf.repack = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %bf, i32 0, i32 0
store float 0.000000e+00, float* %bf.repack, align 8 store float 0.000000e+00, float* %bf.repack, align 8
%bf.repack2 = getelementptr inbounds %main.Point, %main.Point* %bf, i32 0, i32 1 %bf.repack2 = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %bf, i32 0, i32 1
store float 0.000000e+00, float* %bf.repack2, align 4 store float 0.000000e+00, float* %bf.repack2, align 4
%1 = bitcast %main.Point* %bf to i8* %1 = bitcast %"main.Point[float32]"* %bf to i8*
call void @runtime.trackPointer(i8* nonnull %1, i8* undef) #2 call void @runtime.trackPointer(i8* nonnull %1, i8* undef) #2
%.elt = getelementptr inbounds %main.Point, %main.Point* %af, i32 0, i32 0 %.elt = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %af, i32 0, i32 0
%.unpack = load float, float* %.elt, align 8 %.unpack = load float, float* %.elt, align 8
%.elt3 = getelementptr inbounds %main.Point, %main.Point* %af, i32 0, i32 1 %.elt3 = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %af, i32 0, i32 1
%.unpack4 = load float, float* %.elt3, align 4 %.unpack4 = load float, float* %.elt3, align 4
%.elt5 = getelementptr inbounds %main.Point, %main.Point* %bf, i32 0, i32 0 %.elt5 = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %bf, i32 0, i32 0
%.unpack6 = load float, float* %.elt5, align 8 %.unpack6 = load float, float* %.elt5, align 8
%.elt7 = getelementptr inbounds %main.Point, %main.Point* %bf, i32 0, i32 1 %.elt7 = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %bf, i32 0, i32 1
%.unpack8 = load float, float* %.elt7, align 4 %.unpack8 = load float, float* %.elt7, align 4
%2 = call %main.Point @"main.Add[float32]"(float %.unpack, float %.unpack4, float %.unpack6, float %.unpack8, i8* undef) %2 = call %"main.Point[float32]" @"main.Add[float32]"(float %.unpack, float %.unpack4, float %.unpack6, float %.unpack8, i8* undef)
%ai.repack = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %ai, i32 0, i32 0
store i32 0, i32* %ai.repack, align 8
%ai.repack9 = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %ai, i32 0, i32 1
store i32 0, i32* %ai.repack9, align 4
%3 = bitcast %"main.Point[int]"* %ai to i8*
call void @runtime.trackPointer(i8* nonnull %3, i8* undef) #2
%bi.repack = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %bi, i32 0, i32 0
store i32 0, i32* %bi.repack, align 8
%bi.repack10 = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %bi, i32 0, i32 1
store i32 0, i32* %bi.repack10, align 4
%4 = bitcast %"main.Point[int]"* %bi to i8*
call void @runtime.trackPointer(i8* nonnull %4, i8* undef) #2
%.elt11 = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %ai, i32 0, i32 0
%.unpack12 = load i32, i32* %.elt11, align 8
%.elt13 = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %ai, i32 0, i32 1
%.unpack14 = load i32, i32* %.elt13, align 4
%.elt15 = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %bi, i32 0, i32 0
%.unpack16 = load i32, i32* %.elt15, align 8
%.elt17 = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %bi, i32 0, i32 1
%.unpack18 = load i32, i32* %.elt17, align 4
%5 = call %"main.Point[int]" @"main.Add[int]"(i32 %.unpack12, i32 %.unpack14, i32 %.unpack16, i32 %.unpack18, i8* undef)
ret void ret void
} }
; Function Attrs: nounwind ; Function Attrs: nounwind
define linkonce_odr hidden %main.Point @"main.Add[float32]"(float %a.X, float %a.Y, float %b.X, float %b.Y, i8* %context) unnamed_addr #1 { define linkonce_odr hidden %"main.Point[float32]" @"main.Add[float32]"(float %a.X, float %a.Y, float %b.X, float %b.Y, i8* %context) unnamed_addr #1 {
entry: entry:
%complit = alloca %main.Point, align 8 %complit = alloca %"main.Point[float32]", align 8
%b = alloca %main.Point, align 8 %b = alloca %"main.Point[float32]", align 8
%a = alloca %main.Point, align 8 %a = alloca %"main.Point[float32]", align 8
%a.repack = getelementptr inbounds %main.Point, %main.Point* %a, i32 0, i32 0 %a.repack = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %a, i32 0, i32 0
store float 0.000000e+00, float* %a.repack, align 8 store float 0.000000e+00, float* %a.repack, align 8
%a.repack9 = getelementptr inbounds %main.Point, %main.Point* %a, i32 0, i32 1 %a.repack9 = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %a, i32 0, i32 1
store float 0.000000e+00, float* %a.repack9, align 4 store float 0.000000e+00, float* %a.repack9, align 4
%0 = bitcast %main.Point* %a to i8* %0 = bitcast %"main.Point[float32]"* %a to i8*
call void @runtime.trackPointer(i8* nonnull %0, i8* undef) #2 call void @runtime.trackPointer(i8* nonnull %0, i8* undef) #2
%a.repack10 = getelementptr inbounds %main.Point, %main.Point* %a, i32 0, i32 0 %a.repack10 = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %a, i32 0, i32 0
store float %a.X, float* %a.repack10, align 8 store float %a.X, float* %a.repack10, align 8
%a.repack11 = getelementptr inbounds %main.Point, %main.Point* %a, i32 0, i32 1 %a.repack11 = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %a, i32 0, i32 1
store float %a.Y, float* %a.repack11, align 4 store float %a.Y, float* %a.repack11, align 4
%b.repack = getelementptr inbounds %main.Point, %main.Point* %b, i32 0, i32 0 %b.repack = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %b, i32 0, i32 0
store float 0.000000e+00, float* %b.repack, align 8 store float 0.000000e+00, float* %b.repack, align 8
%b.repack13 = getelementptr inbounds %main.Point, %main.Point* %b, i32 0, i32 1 %b.repack13 = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %b, i32 0, i32 1
store float 0.000000e+00, float* %b.repack13, align 4 store float 0.000000e+00, float* %b.repack13, align 4
%1 = bitcast %main.Point* %b to i8* %1 = bitcast %"main.Point[float32]"* %b to i8*
call void @runtime.trackPointer(i8* nonnull %1, i8* undef) #2 call void @runtime.trackPointer(i8* nonnull %1, i8* undef) #2
%b.repack14 = getelementptr inbounds %main.Point, %main.Point* %b, i32 0, i32 0 %b.repack14 = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %b, i32 0, i32 0
store float %b.X, float* %b.repack14, align 8 store float %b.X, float* %b.repack14, align 8
%b.repack15 = getelementptr inbounds %main.Point, %main.Point* %b, i32 0, i32 1 %b.repack15 = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %b, i32 0, i32 1
store float %b.Y, float* %b.repack15, align 4 store float %b.Y, float* %b.repack15, align 4
%complit.repack = getelementptr inbounds %main.Point, %main.Point* %complit, i32 0, i32 0 %complit.repack = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %complit, i32 0, i32 0
store float 0.000000e+00, float* %complit.repack, align 8 store float 0.000000e+00, float* %complit.repack, align 8
%complit.repack17 = getelementptr inbounds %main.Point, %main.Point* %complit, i32 0, i32 1 %complit.repack17 = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %complit, i32 0, i32 1
store float 0.000000e+00, float* %complit.repack17, align 4 store float 0.000000e+00, float* %complit.repack17, align 4
%2 = bitcast %main.Point* %complit to i8* %2 = bitcast %"main.Point[float32]"* %complit to i8*
call void @runtime.trackPointer(i8* nonnull %2, i8* undef) #2 call void @runtime.trackPointer(i8* nonnull %2, i8* undef) #2
%3 = getelementptr inbounds %main.Point, %main.Point* %complit, i32 0, i32 0 %3 = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %complit, i32 0, i32 0
br i1 false, label %deref.throw, label %deref.next br i1 false, label %deref.throw, label %deref.next
deref.next: ; preds = %entry deref.next: ; preds = %entry
br i1 false, label %deref.throw1, label %deref.next2 br i1 false, label %deref.throw1, label %deref.next2
deref.next2: ; preds = %deref.next deref.next2: ; preds = %deref.next
%4 = getelementptr inbounds %main.Point, %main.Point* %b, i32 0, i32 0 %4 = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %b, i32 0, i32 0
%5 = getelementptr inbounds %main.Point, %main.Point* %a, i32 0, i32 0 %5 = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %a, i32 0, i32 0
%6 = load float, float* %5, align 8 %6 = load float, float* %5, align 8
%7 = load float, float* %4, align 8 %7 = load float, float* %4, align 8
%8 = fadd float %6, %7 %8 = fadd float %6, %7
@ -94,8 +118,8 @@ deref.next4: ; preds = %deref.next2
br i1 false, label %deref.throw5, label %deref.next6 br i1 false, label %deref.throw5, label %deref.next6
deref.next6: ; preds = %deref.next4 deref.next6: ; preds = %deref.next4
%9 = getelementptr inbounds %main.Point, %main.Point* %b, i32 0, i32 1 %9 = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %b, i32 0, i32 1
%10 = getelementptr inbounds %main.Point, %main.Point* %a, i32 0, i32 1 %10 = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %a, i32 0, i32 1
%11 = load float, float* %10, align 4 %11 = load float, float* %10, align 4
%12 = load float, float* %9, align 4 %12 = load float, float* %9, align 4
br i1 false, label %store.throw, label %store.next br i1 false, label %store.throw, label %store.next
@ -105,14 +129,14 @@ store.next: ; preds = %deref.next6
br i1 false, label %store.throw7, label %store.next8 br i1 false, label %store.throw7, label %store.next8
store.next8: ; preds = %store.next store.next8: ; preds = %store.next
%13 = getelementptr inbounds %main.Point, %main.Point* %complit, i32 0, i32 1 %13 = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %complit, i32 0, i32 1
%14 = fadd float %11, %12 %14 = fadd float %11, %12
store float %14, float* %13, align 4 store float %14, float* %13, align 4
%.elt = getelementptr inbounds %main.Point, %main.Point* %complit, i32 0, i32 0 %.elt = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %complit, i32 0, i32 0
%.unpack = load float, float* %.elt, align 8 %.unpack = load float, float* %.elt, align 8
%15 = insertvalue %main.Point undef, float %.unpack, 0 %15 = insertvalue %"main.Point[float32]" undef, float %.unpack, 0
%16 = insertvalue %main.Point %15, float %14, 1 %16 = insertvalue %"main.Point[float32]" %15, float %14, 1
ret %main.Point %16 ret %"main.Point[float32]" %16
deref.throw: ; preds = %entry deref.throw: ; preds = %entry
unreachable unreachable
@ -135,6 +159,95 @@ store.throw7: ; preds = %store.next
declare void @runtime.nilPanic(i8*) #0 declare void @runtime.nilPanic(i8*) #0
; Function Attrs: nounwind
define linkonce_odr hidden %"main.Point[int]" @"main.Add[int]"(i32 %a.X, i32 %a.Y, i32 %b.X, i32 %b.Y, i8* %context) unnamed_addr #1 {
entry:
%complit = alloca %"main.Point[int]", align 8
%b = alloca %"main.Point[int]", align 8
%a = alloca %"main.Point[int]", align 8
%a.repack = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %a, i32 0, i32 0
store i32 0, i32* %a.repack, align 8
%a.repack9 = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %a, i32 0, i32 1
store i32 0, i32* %a.repack9, align 4
%0 = bitcast %"main.Point[int]"* %a to i8*
call void @runtime.trackPointer(i8* nonnull %0, i8* undef) #2
%a.repack10 = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %a, i32 0, i32 0
store i32 %a.X, i32* %a.repack10, align 8
%a.repack11 = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %a, i32 0, i32 1
store i32 %a.Y, i32* %a.repack11, align 4
%b.repack = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %b, i32 0, i32 0
store i32 0, i32* %b.repack, align 8
%b.repack13 = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %b, i32 0, i32 1
store i32 0, i32* %b.repack13, align 4
%1 = bitcast %"main.Point[int]"* %b to i8*
call void @runtime.trackPointer(i8* nonnull %1, i8* undef) #2
%b.repack14 = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %b, i32 0, i32 0
store i32 %b.X, i32* %b.repack14, align 8
%b.repack15 = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %b, i32 0, i32 1
store i32 %b.Y, i32* %b.repack15, align 4
%complit.repack = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %complit, i32 0, i32 0
store i32 0, i32* %complit.repack, align 8
%complit.repack17 = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %complit, i32 0, i32 1
store i32 0, i32* %complit.repack17, align 4
%2 = bitcast %"main.Point[int]"* %complit to i8*
call void @runtime.trackPointer(i8* nonnull %2, i8* undef) #2
%3 = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %complit, i32 0, i32 0
br i1 false, label %deref.throw, label %deref.next
deref.next: ; preds = %entry
br i1 false, label %deref.throw1, label %deref.next2
deref.next2: ; preds = %deref.next
%4 = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %b, i32 0, i32 0
%5 = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %a, i32 0, i32 0
%6 = load i32, i32* %5, align 8
%7 = load i32, i32* %4, align 8
%8 = add i32 %6, %7
br i1 false, label %deref.throw3, label %deref.next4
deref.next4: ; preds = %deref.next2
br i1 false, label %deref.throw5, label %deref.next6
deref.next6: ; preds = %deref.next4
%9 = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %b, i32 0, i32 1
%10 = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %a, i32 0, i32 1
%11 = load i32, i32* %10, align 4
%12 = load i32, i32* %9, align 4
br i1 false, label %store.throw, label %store.next
store.next: ; preds = %deref.next6
store i32 %8, i32* %3, align 8
br i1 false, label %store.throw7, label %store.next8
store.next8: ; preds = %store.next
%13 = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %complit, i32 0, i32 1
%14 = add i32 %11, %12
store i32 %14, i32* %13, align 4
%.elt = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %complit, i32 0, i32 0
%.unpack = load i32, i32* %.elt, align 8
%15 = insertvalue %"main.Point[int]" undef, i32 %.unpack, 0
%16 = insertvalue %"main.Point[int]" %15, i32 %14, 1
ret %"main.Point[int]" %16
deref.throw: ; preds = %entry
unreachable
deref.throw1: ; preds = %deref.next
unreachable
deref.throw3: ; preds = %deref.next2
unreachable
deref.throw5: ; preds = %deref.next4
unreachable
store.throw: ; preds = %deref.next6
unreachable
store.throw7: ; preds = %store.next
unreachable
}
attributes #0 = { "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" } attributes #0 = { "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
attributes #1 = { nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" } attributes #1 = { nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
attributes #2 = { nounwind } attributes #2 = { nounwind }