@@ -30,12 +30,14 @@ namespace Compile {
30
30
31
31
void
32
32
HIRCompileBase::setup_attributes_on_fndecl (
33
- tree fndecl, bool is_main_entry_point, bool has_visibility ,
33
+ tree fndecl, bool is_main_entry_point, HIR::Visibility &visibility ,
34
34
const HIR::FunctionQualifiers &qualifiers, const AST::AttrVec &attrs)
35
35
{
36
36
// if its the main fn or pub visibility mark its as DECL_PUBLIC
37
37
// please see https://github.com/Rust-GCC/gccrs/pull/137
38
- if (is_main_entry_point || has_visibility)
38
+ bool is_pub
39
+ = visibility.get_vis_type () != HIR::Visibility::PublicVisType::NONE;
40
+ if (is_main_entry_point || is_pub)
39
41
{
40
42
TREE_PUBLIC (fndecl) = 1 ;
41
43
}
@@ -52,19 +54,59 @@ HIRCompileBase::setup_attributes_on_fndecl (
52
54
bool is_inline = attr.get_path ().as_string ().compare (" inline" ) == 0 ;
53
55
if (is_inline)
54
56
{
55
- DECL_DECLARED_INLINE_P (fndecl) = 1 ;
56
-
57
- // do we want to force inline regardless of optimisation level?
58
- // https://gcc.gnu.org/onlinedocs/gcc/Inline.html
59
- //
60
- // /* Add attribute "always_inline": */
61
- // DECL_ATTRIBUTES (fndecl)
62
- // = tree_cons (get_identifier ("always_inline"), NULL,
63
- // DECL_ATTRIBUTES (fndecl));
57
+ handle_inline_attribute_on_fndecl (fndecl, attr);
64
58
}
65
59
}
66
60
}
67
61
62
+ void
63
+ HIRCompileBase::handle_inline_attribute_on_fndecl (tree fndecl,
64
+ const AST::Attribute &attr)
65
+ {
66
+ // simple #[inline]
67
+ if (!attr.has_attr_input ())
68
+ {
69
+ DECL_DECLARED_INLINE_P (fndecl) = 1 ;
70
+ return ;
71
+ }
72
+
73
+ const AST::AttrInput &input = attr.get_attr_input ();
74
+ bool is_token_tree
75
+ = input.get_attr_input_type () == AST::AttrInput::AttrInputType::TOKEN_TREE;
76
+ rust_assert (is_token_tree);
77
+ const auto &option = static_cast <const AST::DelimTokenTree &> (input);
78
+ AST::AttrInputMetaItemContainer *meta_item = option.parse_to_meta_item ();
79
+ if (meta_item->get_items ().size () != 1 )
80
+ {
81
+ rust_error_at (attr.get_locus (), " invalid number of arguments" );
82
+ return ;
83
+ }
84
+
85
+ const std::string inline_option
86
+ = meta_item->get_items ().at (0 )->as_string ();
87
+
88
+ // we only care about NEVER and ALWAYS else its an error
89
+ bool is_always = inline_option.compare (" always" ) == 0 ;
90
+ bool is_never = inline_option.compare (" never" ) == 0 ;
91
+
92
+ // #[inline(never)]
93
+ if (is_never)
94
+ {
95
+ DECL_UNINLINABLE (fndecl) = 1 ;
96
+ }
97
+ // #[inline(always)]
98
+ else if (is_always)
99
+ {
100
+ DECL_DECLARED_INLINE_P (fndecl) = 1 ;
101
+ DECL_ATTRIBUTES (fndecl) = tree_cons (get_identifier (" always_inline" ),
102
+ NULL , DECL_ATTRIBUTES (fndecl));
103
+ }
104
+ else
105
+ {
106
+ rust_error_at (attr.get_locus (), " unknown inline option" );
107
+ }
108
+ }
109
+
68
110
void
69
111
HIRCompileBase::setup_abi_options (tree fndecl, ABI abi)
70
112
{
@@ -278,8 +320,8 @@ HIRCompileBase::compile_function (
278
320
unsigned int flags = 0 ;
279
321
tree fndecl = ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name,
280
322
asm_name, flags, locus);
281
- setup_attributes_on_fndecl (fndecl, is_main_fn, ! visibility. is_error () ,
282
- qualifiers, outer_attrs);
323
+ setup_attributes_on_fndecl (fndecl, is_main_fn, visibility, qualifiers ,
324
+ outer_attrs);
283
325
setup_abi_options (fndecl, fntype->get_abi ());
284
326
285
327
// insert into the context
0 commit comments