diff options
author | Ayke van Laethem <[email protected]> | 2023-03-24 00:23:03 +0100 |
---|---|---|
committer | Ron Evans <[email protected]> | 2024-09-23 09:41:44 +0100 |
commit | 37460ad60af2601a0412426c229663443c8d8eaa (patch) | |
tree | 0800550e161710c78f91fd8ffc5ef63aec60f59d /compiler | |
parent | dcca47f1f6088ea2565468e4a93a96e4308af480 (diff) | |
download | tinygo-37460ad60af2601a0412426c229663443c8d8eaa.tar.gz tinygo-37460ad60af2601a0412426c229663443c8d8eaa.zip |
compiler: support pragmas on generic functions
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/symbol.go | 8 | ||||
-rw-r--r-- | compiler/testdata/pragma.go | 16 | ||||
-rw-r--r-- | compiler/testdata/pragma.ll | 13 |
3 files changed, 35 insertions, 2 deletions
diff --git a/compiler/symbol.go b/compiler/symbol.go index 29f009520..32eb55107 100644 --- a/compiler/symbol.go +++ b/compiler/symbol.go @@ -250,10 +250,14 @@ func (c *compilerContext) getFunctionInfo(f *ssa.Function) functionInfo { // parsePragmas is used by getFunctionInfo to parse function pragmas such as // //export or //go:noinline. func (c *compilerContext) parsePragmas(info *functionInfo, f *ssa.Function) { - if f.Syntax() == nil { + syntax := f.Syntax() + if f.Origin() != nil { + syntax = f.Origin().Syntax() + } + if syntax == nil { return } - if decl, ok := f.Syntax().(*ast.FuncDecl); ok && decl.Doc != nil { + if decl, ok := syntax.(*ast.FuncDecl); ok && decl.Doc != nil { for _, comment := range decl.Doc.List { text := comment.Text if strings.HasPrefix(text, "//export ") { diff --git a/compiler/testdata/pragma.go b/compiler/testdata/pragma.go index fa1d4b0e9..1f6badf7f 100644 --- a/compiler/testdata/pragma.go +++ b/compiler/testdata/pragma.go @@ -48,6 +48,22 @@ func inlineFunc() { func noinlineFunc() { } +type Int interface { + int8 | int16 +} + +// Same for generic functions (but the compiler may miss the pragma due to it +// being generic). +// +//go:noinline +func noinlineGenericFunc[T Int]() { +} + +func useGeneric() { + // Make sure the generic function above is instantiated. + noinlineGenericFunc[int8]() +} + // This function should have the specified section. // //go:section .special_function_section diff --git a/compiler/testdata/pragma.ll b/compiler/testdata/pragma.ll index 3ee4078f1..28e678359 100644 --- a/compiler/testdata/pragma.ll +++ b/compiler/testdata/pragma.ll @@ -48,6 +48,19 @@ entry: ret void } +; Function Attrs: nounwind +define hidden void @main.useGeneric(ptr %context) unnamed_addr #2 { +entry: + call void @"main.noinlineGenericFunc[int8]"(ptr undef) + ret void +} + +; Function Attrs: noinline nounwind +define linkonce_odr hidden void @"main.noinlineGenericFunc[int8]"(ptr %context) unnamed_addr #5 { +entry: + ret void +} + ; Function Attrs: noinline nounwind define hidden void @main.functionInSection(ptr %context) unnamed_addr #5 section ".special_function_section" { entry: |