From 0fd43a25304acef59d8d64e82b78d5895e0823ed Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Thu, 14 Apr 2022 08:06:08 +0300 Subject: [PATCH] cgen: use __attribute__((fastcall)) for fn types on cc != msvc (fixes compilation of doc examples) --- vlib/v/gen/c/cgen.v | 18 ++++++++++++++---- vlib/v/gen/c/fn.v | 2 +- vlib/v/parser/fn.v | 6 ++++-- vlib/v/parser/parse_type.v | 6 ++++-- 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index f246f3651e..d940241ccd 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -1345,24 +1345,34 @@ pub fn (mut g Gen) write_fn_typesymbol_declaration(sym ast.TypeSymbol) { fn_name := sym.cname mut call_conv := '' - + mut msvc_call_conv := '' + is_cc_msvc := g.pref.ccompiler == 'msvc' for attr in func.attrs { match attr.name { 'callconv' { - call_conv = '__$attr.arg ' + if is_cc_msvc { + msvc_call_conv = '__$attr.arg ' + } else { + call_conv = '$attr.arg' + } } else {} } } + call_conv_attribute_suffix := if call_conv.len != 0 { + '__attribute__(($call_conv))' + } else { + '' + } - g.type_definitions.write_string('typedef ${g.typ(func.return_type)} ($call_conv*$fn_name)(') + g.type_definitions.write_string('typedef ${g.typ(func.return_type)} ($msvc_call_conv*$fn_name)(') for i, param in func.params { g.type_definitions.write_string(g.typ(param.typ)) if i < func.params.len - 1 { g.type_definitions.write_string(',') } } - g.type_definitions.writeln(');') + g.type_definitions.writeln(')$call_conv_attribute_suffix;') } } diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 1299fdbdcc..02fcfa34a5 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -2153,7 +2153,7 @@ fn (mut g Gen) write_fn_attrs(attrs []ast.Attr) string { '_fastcall' { fn_attrs += '__fastcall ' } - "callconv" { + 'callconv' { fn_attrs += '__$attr.arg ' } 'console' { diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index 8bb8c6e0e2..61036fd606 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -231,10 +231,12 @@ fn (mut p Parser) fn_decl() ast.FnDecl { } 'callconv' { if !fna.has_arg { - p.error_with_pos('callconv attribute is present but its value is missing', p.prev_tok.pos()) + p.error_with_pos('callconv attribute is present but its value is missing', + p.prev_tok.pos()) } if fna.arg !in ['stdcall', 'fastcall', 'cdecl'] { - p.error_with_pos('unsupported calling convention, supported are stdcall, fastcall and cdecl', p.prev_tok.pos()) + p.error_with_pos('unsupported calling convention, supported are stdcall, fastcall and cdecl', + p.prev_tok.pos()) } } else {} diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index ca887856dc..ee42932972 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -234,10 +234,12 @@ pub fn (mut p Parser) parse_fn_type(name string) ast.Type { match attr.name { 'callconv' { if !attr.has_arg { - p.error_with_pos('callconv attribute is present but its value is missing', p.prev_tok.pos()) + p.error_with_pos('callconv attribute is present but its value is missing', + p.prev_tok.pos()) } if attr.arg !in ['stdcall', 'fastcall', 'cdecl'] { - p.error_with_pos('unsupported calling convention, supported are stdcall, fastcall and cdecl', p.prev_tok.pos()) + p.error_with_pos('unsupported calling convention, supported are stdcall, fastcall and cdecl', + p.prev_tok.pos()) } } else {}