mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen: write_fn_attr()
This commit is contained in:
parent
41dca3ef58
commit
277b7b35d0
158
vlib/v/gen/fn.v
158
vlib/v/gen/fn.v
@ -34,86 +34,12 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl) {
|
|||||||
g.cur_generic_type = 0
|
g.cur_generic_type = 0
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//
|
|
||||||
if is_main && g.pref.is_liveshared {
|
if is_main && g.pref.is_liveshared {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//
|
|
||||||
fn_start_pos := g.out.len
|
fn_start_pos := g.out.len
|
||||||
|
msvc_attrs := g.write_fn_attr()
|
||||||
mut msvc_attrs := ''
|
// Live
|
||||||
match g.attr {
|
|
||||||
'inline' {
|
|
||||||
g.write('inline ')
|
|
||||||
}
|
|
||||||
// since these are supported by GCC, clang and MSVC, we can consider them officially supported.
|
|
||||||
'no_inline' {
|
|
||||||
g.write('__NOINLINE ')
|
|
||||||
}
|
|
||||||
'irq_handler' {
|
|
||||||
g.write('__IRQHANDLER ')
|
|
||||||
}
|
|
||||||
|
|
||||||
// GCC/clang attributes
|
|
||||||
// prefixed by _ to indicate they're for advanced users only and not really supported by V.
|
|
||||||
// source for descriptions: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes
|
|
||||||
|
|
||||||
// The cold attribute on functions is used to inform the compiler that the function is unlikely
|
|
||||||
// to be executed. The function is optimized for size rather than speed and on many targets it
|
|
||||||
// is placed into a special subsection of the text section so all cold functions appear close
|
|
||||||
// together, improving code locality of non-cold parts of program.
|
|
||||||
'_cold' {
|
|
||||||
g.write('__attribute__((cold)) ')
|
|
||||||
}
|
|
||||||
// The constructor attribute causes the function to be called automatically before execution
|
|
||||||
// enters main ().
|
|
||||||
'_constructor' {
|
|
||||||
g.write('__attribute__((constructor)) ')
|
|
||||||
}
|
|
||||||
// The destructor attribute causes the function to be called automatically after main ()
|
|
||||||
// completes or exit () is called.
|
|
||||||
'_destructor' {
|
|
||||||
g.write('__attribute__((destructor)) ')
|
|
||||||
}
|
|
||||||
// Generally, inlining into a function is limited. For a function marked with this attribute,
|
|
||||||
// every call inside this function is inlined, if possible.
|
|
||||||
'_flatten' {
|
|
||||||
g.write('__attribute__((flatten)) ')
|
|
||||||
}
|
|
||||||
// The hot attribute on a function is used to inform the compiler that the function is a hot
|
|
||||||
// spot of the compiled program.
|
|
||||||
'_hot' {
|
|
||||||
g.write('__attribute__((hot)) ')
|
|
||||||
}
|
|
||||||
// This tells the compiler that a function is malloc-like, i.e., that the pointer P returned by
|
|
||||||
// the function cannot alias any other pointer valid when the function returns, and moreover no
|
|
||||||
// pointers to valid objects occur in any storage addressed by P.
|
|
||||||
'_malloc' {
|
|
||||||
g.write('__attribute__((malloc)) ')
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calls to functions whose return value is not affected by changes to the observable state
|
|
||||||
// of the program and that have no observable effects on such state other than to return a
|
|
||||||
// value may lend themselves to optimizations such as common subexpression elimination.
|
|
||||||
// Declaring such functions with the const attribute allows GCC to avoid emitting some calls in
|
|
||||||
// repeated invocations of the function with the same argument values.
|
|
||||||
'_pure' {
|
|
||||||
g.write('__attribute__((const)) ')
|
|
||||||
}
|
|
||||||
|
|
||||||
// windows attributes (msvc/mingw)
|
|
||||||
// prefixed by windows to indicate they're for advanced users only and not really supported by V.
|
|
||||||
|
|
||||||
'windows_stdcall' {
|
|
||||||
msvc_attrs += '__stdcall '
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
// nothing but keep V happy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
is_livefn := g.attr == 'live'
|
is_livefn := g.attr == 'live'
|
||||||
is_livemain := g.pref.is_livemain && is_livefn
|
is_livemain := g.pref.is_livemain && is_livefn
|
||||||
is_liveshared := g.pref.is_liveshared && is_livefn
|
is_liveshared := g.pref.is_liveshared && is_livefn
|
||||||
@ -309,6 +235,7 @@ fn (mut g Gen) write_defer_stmts_when_needed() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fn decl args
|
||||||
fn (mut g Gen) fn_args(args []table.Arg, is_variadic bool) ([]string, []string) {
|
fn (mut g Gen) fn_args(args []table.Arg, is_variadic bool) ([]string, []string) {
|
||||||
mut fargs := []string{}
|
mut fargs := []string{}
|
||||||
mut fargtypes := []string{}
|
mut fargtypes := []string{}
|
||||||
@ -319,7 +246,7 @@ fn (mut g Gen) fn_args(args []table.Arg, is_variadic bool) ([]string, []string)
|
|||||||
arg_type_sym := g.table.get_type_symbol(typ)
|
arg_type_sym := g.table.get_type_symbol(typ)
|
||||||
mut arg_type_name := g.typ(typ) // arg_type_sym.name.replace('.', '__')
|
mut arg_type_name := g.typ(typ) // arg_type_sym.name.replace('.', '__')
|
||||||
// if arg.name == 'xxx' {
|
// if arg.name == 'xxx' {
|
||||||
// println('! ' + arg_type_name)
|
// println('xxx arg type= ' + arg_type_name)
|
||||||
// }
|
// }
|
||||||
is_varg := i == args.len - 1 && is_variadic
|
is_varg := i == args.len - 1 && is_variadic
|
||||||
if is_varg {
|
if is_varg {
|
||||||
@ -774,3 +701,80 @@ fn (mut g Gen) is_gui_app() bool {
|
|||||||
fn (g &Gen) fileis(s string) bool {
|
fn (g &Gen) fileis(s string) bool {
|
||||||
return g.file.path.contains(s)
|
return g.file.path.contains(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut g Gen) write_fn_attr() string{
|
||||||
|
mut msvc_attrs := ''
|
||||||
|
match g.attr {
|
||||||
|
'inline' {
|
||||||
|
g.write('inline ')
|
||||||
|
}
|
||||||
|
// since these are supported by GCC, clang and MSVC, we can consider them officially supported.
|
||||||
|
'no_inline' {
|
||||||
|
g.write('__NOINLINE ')
|
||||||
|
}
|
||||||
|
'irq_handler' {
|
||||||
|
g.write('__IRQHANDLER ')
|
||||||
|
}
|
||||||
|
|
||||||
|
// GCC/clang attributes
|
||||||
|
// prefixed by _ to indicate they're for advanced users only and not really supported by V.
|
||||||
|
// source for descriptions: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes
|
||||||
|
|
||||||
|
// The cold attribute on functions is used to inform the compiler that the function is unlikely
|
||||||
|
// to be executed. The function is optimized for size rather than speed and on many targets it
|
||||||
|
// is placed into a special subsection of the text section so all cold functions appear close
|
||||||
|
// together, improving code locality of non-cold parts of program.
|
||||||
|
'_cold' {
|
||||||
|
g.write('__attribute__((cold)) ')
|
||||||
|
}
|
||||||
|
// The constructor attribute causes the function to be called automatically before execution
|
||||||
|
// enters main ().
|
||||||
|
'_constructor' {
|
||||||
|
g.write('__attribute__((constructor)) ')
|
||||||
|
}
|
||||||
|
// The destructor attribute causes the function to be called automatically after main ()
|
||||||
|
// completes or exit () is called.
|
||||||
|
'_destructor' {
|
||||||
|
g.write('__attribute__((destructor)) ')
|
||||||
|
}
|
||||||
|
// Generally, inlining into a function is limited. For a function marked with this attribute,
|
||||||
|
// every call inside this function is inlined, if possible.
|
||||||
|
'_flatten' {
|
||||||
|
g.write('__attribute__((flatten)) ')
|
||||||
|
}
|
||||||
|
// The hot attribute on a function is used to inform the compiler that the function is a hot
|
||||||
|
// spot of the compiled program.
|
||||||
|
'_hot' {
|
||||||
|
g.write('__attribute__((hot)) ')
|
||||||
|
}
|
||||||
|
// This tells the compiler that a function is malloc-like, i.e., that the pointer P returned by
|
||||||
|
// the function cannot alias any other pointer valid when the function returns, and moreover no
|
||||||
|
// pointers to valid objects occur in any storage addressed by P.
|
||||||
|
'_malloc' {
|
||||||
|
g.write('__attribute__((malloc)) ')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calls to functions whose return value is not affected by changes to the observable state
|
||||||
|
// of the program and that have no observable effects on such state other than to return a
|
||||||
|
// value may lend themselves to optimizations such as common subexpression elimination.
|
||||||
|
// Declaring such functions with the const attribute allows GCC to avoid emitting some calls in
|
||||||
|
// repeated invocations of the function with the same argument values.
|
||||||
|
'_pure' {
|
||||||
|
g.write('__attribute__((const)) ')
|
||||||
|
}
|
||||||
|
|
||||||
|
// windows attributes (msvc/mingw)
|
||||||
|
// prefixed by windows to indicate they're for advanced users only and not really supported by V.
|
||||||
|
|
||||||
|
'windows_stdcall' {
|
||||||
|
msvc_attrs += '__stdcall '
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
// nothing but keep V happy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return msvc_attrs
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user