]>
git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/rust/backend/rust-compile-extern.h
b42878eb64faf5c6eec1bcb3f9a25de380d2945c
1 // Copyright (C) 2020-2023 Free Software Foundation, Inc.
3 // This file is part of GCC.
5 // GCC is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation; either version 3, or (at your option) any later
10 // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 // You should have received a copy of the GNU General Public License
16 // along with GCC; see the file COPYING3. If not see
17 // <http://www.gnu.org/licenses/>.
19 #ifndef RUST_COMPILE_EXTERN_ITEM
20 #define RUST_COMPILE_EXTERN_ITEM
22 #include "rust-compile-base.h"
23 #include "rust-compile-intrinsic.h"
28 class CompileExternItem
: public HIRCompileBase
,
29 public HIR::HIRExternalItemVisitor
32 static tree
compile (HIR::ExternalItem
*item
, Context
*ctx
,
33 TyTy::BaseType
*concrete
= nullptr,
34 bool is_query_mode
= false,
35 Location ref_locus
= Location ())
37 CompileExternItem
compiler (ctx
, concrete
, ref_locus
);
38 item
->accept_vis (compiler
);
40 if (is_query_mode
&& compiler
.reference
== error_mark_node
)
41 rust_internal_error_at (ref_locus
, "failed to compile extern item: %s",
42 item
->as_string ().c_str ());
44 return compiler
.reference
;
47 void visit (HIR::ExternalStaticItem
&item
) override
49 // check if its already been compiled
50 Bvariable
*lookup
= ctx
->get_backend ()->error_variable ();
51 if (ctx
->lookup_var_decl (item
.get_mappings ().get_hirid (), &lookup
))
53 reference
= ctx
->get_backend ()->var_expression (lookup
, ref_locus
);
57 TyTy::BaseType
*resolved_type
= nullptr;
58 bool ok
= ctx
->get_tyctx ()->lookup_type (item
.get_mappings ().get_hirid (),
62 std::string name
= item
.get_item_name ();
63 // FIXME this is assuming C ABI
64 std::string asm_name
= name
;
66 tree type
= TyTyResolveCompile::compile (ctx
, resolved_type
);
67 bool is_external
= true;
68 bool is_hidden
= false;
69 bool in_unique_section
= false;
71 Bvariable
*static_global
72 = ctx
->get_backend ()->global_variable (name
, asm_name
, type
, is_external
,
73 is_hidden
, in_unique_section
,
75 ctx
->insert_var_decl (item
.get_mappings ().get_hirid (), static_global
);
76 ctx
->push_var (static_global
);
78 reference
= ctx
->get_backend ()->var_expression (static_global
, ref_locus
);
81 void visit (HIR::ExternalFunctionItem
&function
) override
83 TyTy::BaseType
*fntype_tyty
;
84 if (!ctx
->get_tyctx ()->lookup_type (function
.get_mappings ().get_hirid (),
87 rust_fatal_error (function
.get_locus (),
88 "failed to lookup function type");
92 rust_assert (fntype_tyty
->get_kind () == TyTy::TypeKind::FNDEF
);
93 TyTy::FnType
*fntype
= static_cast<TyTy::FnType
*> (fntype_tyty
);
94 if (fntype
->has_subsititions_defined ())
96 // we cant do anything for this only when it is used and a concrete type
98 if (concrete
== nullptr)
102 rust_assert (concrete
->get_kind () == TyTy::TypeKind::FNDEF
);
103 fntype
= static_cast<TyTy::FnType
*> (concrete
);
107 // items can be forward compiled which means we may not need to invoke this
108 // code. We might also have already compiled this generic function as well.
109 tree lookup
= NULL_TREE
;
110 if (ctx
->lookup_function_decl (fntype
->get_ty_ref (), &lookup
,
111 fntype
->get_id (), fntype
))
113 reference
= address_expression (lookup
, ref_locus
);
117 if (fntype
->has_subsititions_defined ())
119 // override the Hir Lookups for the substituions in this context
120 fntype
->override_context ();
123 if (fntype
->get_abi () == ABI::INTRINSIC
)
125 Intrinsics
compile (ctx
);
126 tree fndecl
= compile
.compile (fntype
);
127 ctx
->insert_function_decl (fntype
, fndecl
);
131 tree compiled_fn_type
= TyTyResolveCompile::compile (ctx
, fntype
);
132 std::string ir_symbol_name
= function
.get_item_name ();
133 std::string asm_name
= function
.get_item_name ();
134 if (fntype
->get_abi () == ABI::RUST
)
136 // then we need to get the canonical path of it and mangle it
137 const Resolver::CanonicalPath
*canonical_path
= nullptr;
138 bool ok
= ctx
->get_mappings ()->lookup_canonical_path (
139 function
.get_mappings ().get_nodeid (), &canonical_path
);
142 ir_symbol_name
= canonical_path
->get () + fntype
->subst_as_string ();
143 asm_name
= ctx
->mangle_item (fntype
, *canonical_path
);
146 const unsigned int flags
= Backend::function_is_declaration
;
148 = ctx
->get_backend ()->function (compiled_fn_type
, ir_symbol_name
,
149 asm_name
, flags
, function
.get_locus ());
150 TREE_PUBLIC (fndecl
) = 1;
151 setup_abi_options (fndecl
, fntype
->get_abi ());
153 ctx
->insert_function_decl (fntype
, fndecl
);
155 reference
= address_expression (fndecl
, ref_locus
);
159 CompileExternItem (Context
*ctx
, TyTy::BaseType
*concrete
, Location ref_locus
)
160 : HIRCompileBase (ctx
), concrete (concrete
), reference (error_mark_node
),
161 ref_locus (ref_locus
)
164 TyTy::BaseType
*concrete
;
169 } // namespace Compile
172 #endif // RUST_COMPILE_EXTERN_ITEM