aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/rust/Make-lang.in2
-rw-r--r--gcc/rust/backend/rust-compile-base.cc92
-rw-r--r--gcc/rust/backend/rust-compile-base.h6
-rw-r--r--gcc/rust/backend/rust-compile-extern.h11
-rw-r--r--gcc/rust/backend/rust-compile-implitem.h17
-rw-r--r--gcc/rust/backend/rust-compile-item.h24
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.h4
-rw-r--r--gcc/rust/rust-backend.h69
-rw-r--r--gcc/rust/rust-gcc.cc61
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-implitem.h20
-rw-r--r--gcc/rust/util/rust-abi.cc64
-rw-r--r--gcc/rust/util/rust-abi.h (renamed from gcc/rust/rust-abi.h)8
12 files changed, 214 insertions, 164 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index d2f7962..2d74595 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -75,6 +75,7 @@ GRS_OBJS = \
rust/rust-macro-expand.o \
rust/rust-hir-full-test.o \
rust/rust-hir-map.o \
+ rust/rust-abi.o \
rust/rust-ast-lower.o \
rust/rust-ast-lower-pattern.o \
rust/rust-ast-resolve.o \
@@ -99,6 +100,7 @@ GRS_OBJS = \
rust/rust-compile-expr.o \
rust/rust-compile-type.o \
rust/rust-constexpr.o \
+ rust/rust-compile-base.o \
$(END)
# removed object files from here
diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc
new file mode 100644
index 0000000..82a38e7
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -0,0 +1,92 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-compile-base.h"
+#include "stringpool.h"
+
+namespace Rust {
+namespace Compile {
+
+void
+HIRCompileBase::setup_attributes_on_fndecl (
+ tree fndecl, bool is_main_entry_point, bool has_visibility,
+ const HIR::FunctionQualifiers &qualifiers, const AST::AttrVec &attrs)
+{
+ // if its the main fn or pub visibility mark its as DECL_PUBLIC
+ // please see https://github.com/Rust-GCC/gccrs/pull/137
+ if (is_main_entry_point || has_visibility)
+ {
+ TREE_PUBLIC (fndecl) = 1;
+ }
+
+ // is it a const fn
+ if (qualifiers.is_const ())
+ {
+ TREE_READONLY (fndecl) = 1;
+ }
+
+ // is it inline?
+ for (const auto &attr : attrs)
+ {
+ bool is_inline = attr.get_path ().as_string ().compare ("inline") == 0;
+ if (is_inline)
+ {
+ DECL_DECLARED_INLINE_P (fndecl) = 1;
+
+ // do we want to force inline regardless of optimisation level?
+ // https://gcc.gnu.org/onlinedocs/gcc/Inline.html
+ //
+ // /* Add attribute "always_inline": */
+ // DECL_ATTRIBUTES (fndecl)
+ // = tree_cons (get_identifier ("always_inline"), NULL,
+ // DECL_ATTRIBUTES (fndecl));
+ }
+ }
+}
+
+void
+HIRCompileBase::setup_abi_options (tree fndecl, ABI abi)
+{
+ switch (abi)
+ {
+ case Rust::ABI::RUST:
+ case Rust::ABI::INTRINSIC:
+ case Rust::ABI::C:
+ case Rust::ABI::CDECL:
+ DECL_ATTRIBUTES (fndecl)
+ = tree_cons (get_identifier ("cdecl"), NULL, DECL_ATTRIBUTES (fndecl));
+ break;
+
+ case Rust::ABI::STDCALL:
+ DECL_ATTRIBUTES (fndecl) = tree_cons (get_identifier ("stdcall"), NULL,
+ DECL_ATTRIBUTES (fndecl));
+ break;
+
+ case Rust::ABI::FASTCALL:
+ DECL_ATTRIBUTES (fndecl) = tree_cons (get_identifier ("fastcall"), NULL,
+ DECL_ATTRIBUTES (fndecl));
+
+ break;
+
+ default:
+ break;
+ }
+}
+
+} // namespace Compile
+} // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h
index 902bedc..f318e81 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -71,6 +71,12 @@ protected:
tree resolve_deref_adjustment (Resolver::Adjustment &adjustment,
tree expression, Location locus);
+
+ static void setup_attributes_on_fndecl (
+ tree fndecl, bool is_main_entry_point, bool has_visibility,
+ const HIR::FunctionQualifiers &qualifiers, const AST::AttrVec &attrs);
+
+ static void setup_abi_options (tree fndecl, ABI abi);
};
} // namespace Compile
diff --git a/gcc/rust/backend/rust-compile-extern.h b/gcc/rust/backend/rust-compile-extern.h
index 507865a..143b240 100644
--- a/gcc/rust/backend/rust-compile-extern.h
+++ b/gcc/rust/backend/rust-compile-extern.h
@@ -125,19 +125,16 @@ public:
}
tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
- compiled_fn_type
- = ctx->get_backend ()->specify_abi_attribute (compiled_fn_type,
- fntype->get_abi ());
-
- const unsigned int flags
- = Backend::function_is_declaration | Backend::function_is_visible;
-
std::string ir_symbol_name = function.get_item_name ();
std::string asm_name = function.get_item_name ();
+ const unsigned int flags = Backend::function_is_declaration;
tree fndecl
= ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name,
asm_name, flags, function.get_locus ());
+ TREE_PUBLIC (fndecl) = 1;
+ setup_abi_options (fndecl, fntype->get_abi ());
+
ctx->insert_function_decl (fntype, fndecl);
}
diff --git a/gcc/rust/backend/rust-compile-implitem.h b/gcc/rust/backend/rust-compile-implitem.h
index d646c83..9320276 100644
--- a/gcc/rust/backend/rust-compile-implitem.h
+++ b/gcc/rust/backend/rust-compile-implitem.h
@@ -133,13 +133,6 @@ public:
// convert to the actual function type
tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
- unsigned int flags = 0;
-
- // if its the main fn or pub visibility mark its as DECL_PUBLIC
- // please see https://github.com/Rust-GCC/gccrs/pull/137
- if (function.has_visibility ())
- flags |= Backend::function_is_visible;
-
const Resolver::CanonicalPath *canonical_path = nullptr;
bool ok = ctx->get_mappings ()->lookup_canonical_path (
function.get_mappings ().get_crate_num (),
@@ -150,9 +143,13 @@ public:
= canonical_path->get () + fntype->subst_as_string ();
std::string asm_name = ctx->mangle_item (fntype, *canonical_path);
+ unsigned int flags = 0;
tree fndecl
= ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name,
asm_name, flags, function.get_locus ());
+ setup_attributes_on_fndecl (fndecl, false, function.has_visibility (),
+ function.get_qualifiers (),
+ function.get_outer_attrs ());
ctx->insert_function_decl (fntype, fndecl);
// setup the params
@@ -395,9 +392,7 @@ public:
// convert to the actual function type
tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
-
HIR::TraitFunctionDecl &function = func.get_decl ();
- unsigned int flags = 0;
const Resolver::CanonicalPath *canonical_path = nullptr;
bool ok = ctx->get_mappings ()->lookup_canonical_path (
@@ -408,9 +403,13 @@ public:
std::string fn_identifier = canonical_path->get ();
std::string asm_name = ctx->mangle_item (fntype, *canonical_path);
+ unsigned int flags = 0;
tree fndecl
= ctx->get_backend ()->function (compiled_fn_type, fn_identifier,
asm_name, flags, func.get_locus ());
+ setup_attributes_on_fndecl (fndecl, false, false,
+ func.get_decl ().get_qualifiers (),
+ func.get_outer_attrs ());
ctx->insert_function_decl (fntype, fndecl);
// setup the params
diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h
index 73f6967..70b5415 100644
--- a/gcc/rust/backend/rust-compile-item.h
+++ b/gcc/rust/backend/rust-compile-item.h
@@ -144,9 +144,9 @@ public:
NULL, constant.get_locus ());
tree fndecl
- = ctx->get_backend ()->function (compiled_fn_type, ident, "",
- Backend::function_read_only,
+ = ctx->get_backend ()->function (compiled_fn_type, ident, "", 0,
constant.get_locus ());
+ TREE_READONLY (fndecl) = 1;
tree enclosing_scope = NULL_TREE;
HIR::BlockExpr *function_body
@@ -255,18 +255,6 @@ public:
tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
- unsigned int flags = 0;
- bool is_main_fn = function.get_function_name ().compare ("main") == 0;
-
- // if its the main fn or pub visibility mark its as DECL_PUBLIC
- // please see https://github.com/Rust-GCC/gccrs/pull/137
- if (is_main_fn || function.has_visibility ())
- flags |= Backend::function_is_visible;
-
- // is it a const function?
- if (function.get_qualifiers ().is_const ())
- flags |= Backend::function_read_only;
-
const Resolver::CanonicalPath *canonical_path = nullptr;
bool ok = ctx->get_mappings ()->lookup_canonical_path (
function.get_mappings ().get_crate_num (),
@@ -275,19 +263,25 @@ public:
std::string ir_symbol_name
= canonical_path->get () + fntype->subst_as_string ();
-
std::string asm_name = function.get_function_name ();
// we don't mangle the main fn since we haven't implemented the main shim
// yet
+ bool is_main_fn = function.get_function_name ().compare ("main") == 0;
if (!is_main_fn)
{
asm_name = ctx->mangle_item (fntype, *canonical_path);
}
+ unsigned int flags = 0;
tree fndecl
= ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name,
asm_name, flags, function.get_locus ());
+ setup_attributes_on_fndecl (fndecl, is_main_fn, function.has_visibility (),
+ function.get_qualifiers (),
+ function.get_outer_attrs ());
+
+ // insert into the context
ctx->insert_function_decl (fntype, fndecl);
// setup the params
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index c245a56..5fdf806 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -2262,6 +2262,8 @@ public:
}
std::vector<FunctionParam> &get_function_params () { return function_params; }
+
+ const FunctionQualifiers &get_qualifiers () const { return qualifiers; }
};
// Actual trait item function declaration within traits
@@ -2339,6 +2341,8 @@ public:
return TraitItemKind::FUNC;
}
+ AST::AttrVec get_outer_attrs () const { return outer_attrs; }
+
protected:
// Clone function implementation as (not pure) virtual method
TraitItemFunc *clone_trait_item_impl () const override
diff --git a/gcc/rust/rust-backend.h b/gcc/rust/rust-backend.h
index 03b6cb4..2a7691c 100644
--- a/gcc/rust/rust-backend.h
+++ b/gcc/rust/rust-backend.h
@@ -27,8 +27,6 @@
#include "rust-linemap.h"
#include "rust-diagnostics.h"
#include "operator.h"
-#include "rust-abi.h"
-
#include "tree.h"
extern bool
@@ -74,49 +72,6 @@ public:
virtual void debug (tree) = 0;
virtual void debug (Bvariable *) = 0;
- static Rust::ABI get_abi_from_string (const std::string &abi, Location locus)
- {
- if (abi.compare ("rust") == 0)
- return Rust::ABI::C;
- else if (abi.compare ("rust-intrinsic") == 0)
- return Rust::ABI::INTRINSIC;
- else if (abi.compare ("C") == 0)
- return Rust::ABI::C;
- else if (abi.compare ("cdecl") == 0)
- return Rust::ABI::CDECL;
- else if (abi.compare ("stdcall") == 0)
- return Rust::ABI::STDCALL;
- else if (abi.compare ("fastcall") == 0)
- return Rust::ABI::FASTCALL;
-
- rust_error_at (locus, "unknown abi specified");
-
- return Rust::ABI::UNKNOWN;
- }
-
- static std::string get_string_from_abi (Rust::ABI abi)
- {
- switch (abi)
- {
- case Rust::ABI::RUST:
- return "rust";
- case Rust::ABI::INTRINSIC:
- return "rust-intrinsic";
- case Rust::ABI::C:
- return "C";
- case Rust::ABI::CDECL:
- return "cdecl";
- case Rust::ABI::STDCALL:
- return "stdcall";
- case Rust::ABI::FASTCALL:
- return "fastcall";
-
- case Rust::ABI::UNKNOWN:
- return "unknown";
- }
- return "unknown";
- }
-
virtual tree get_identifier_node (const std::string &str) = 0;
// Types.
@@ -681,35 +636,21 @@ public:
// Bit flags to pass to the function method.
- // Set if the function should be visible outside of the current
- // compilation unit.
- static const unsigned int function_is_visible = 1 << 0;
-
// Set if this is a function declaration rather than a definition;
// the definition will be in another compilation unit.
- static const unsigned int function_is_declaration = 1 << 1;
+ static const unsigned int function_is_declaration = 1 << 0;
// Set if the function should never be inlined because they call
// recover and must be visible for correct panic recovery.
- static const unsigned int function_is_uninlinable = 1 << 2;
+ static const unsigned int function_is_uninlinable = 1 << 1;
// Set if the function does not return. This is set for the
// implementation of panic.
- static const unsigned int function_does_not_return = 1 << 3;
+ static const unsigned int function_does_not_return = 1 << 2;
// Set if the function should be put in a unique section if
// possible. This is used for field tracking.
- static const unsigned int function_in_unique_section = 1 << 4;
-
- // Set if the function should be available for inlining in the
- // backend, but should not be emitted as a standalone function. Any
- // call to the function that is not inlined should be treated as a
- // call to a function defined in a different compilation unit. This
- // is like a C99 function marked inline but not extern.
- static const unsigned int function_only_inline = 1 << 5;
-
- // const function
- static const unsigned int function_read_only = 1 << 6;
+ static const unsigned int function_in_unique_section = 1 << 3;
// Declare or define a function of FNTYPE.
// NAME is the Go name of the function. ASM_NAME, if not the empty
@@ -721,8 +662,6 @@ public:
Location)
= 0;
- virtual tree specify_abi_attribute (tree type, Rust::ABI abi) = 0;
-
// Create a statement that runs all deferred calls for FUNCTION. This should
// be a statement that looks like this in C++:
// finish:
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 13cfe23..62c9d80 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -160,10 +160,6 @@ public:
tree immutable_type (tree);
- tree specify_abi_attribute (tree, Rust::ABI);
-
- tree insert_type_attribute (tree, const std::string &);
-
tree function_type (const typed_identifier &,
const std::vector<typed_identifier> &,
const std::vector<typed_identifier> &, tree,
@@ -769,52 +765,6 @@ Gcc_backend::immutable_type (tree base)
return constified;
}
-// ABI
-
-tree
-Gcc_backend::specify_abi_attribute (tree type, Rust::ABI abi)
-{
- std::string abi_string;
- switch (abi)
- {
- case Rust::ABI::UNKNOWN:
- return error_type ();
-
- case Rust::ABI::RUST:
- case Rust::ABI::INTRINSIC:
- case Rust::ABI::C:
- case Rust::ABI::CDECL:
- abi_string = "cdecl";
- break;
-
- case Rust::ABI::STDCALL:
- abi_string = "stdcall";
- break;
- case Rust::ABI::FASTCALL:
- abi_string = "fastcall";
- break;
- }
-
- return insert_type_attribute (type, abi_string);
-}
-
-tree
-Gcc_backend::insert_type_attribute (tree type, const std::string &attrname)
-{
- tree ident = get_identifier (attrname.c_str ());
-
- tree attribs = NULL_TREE;
- tree old_attrs = TYPE_ATTRIBUTES (type);
- if (old_attrs)
- attribs = merge_type_attributes (old_attrs,
- tree_cons (ident, NULL_TREE, NULL_TREE));
- else
- attribs = tree_cons (ident, NULL_TREE, NULL_TREE);
-
- tree res = build_type_attribute_variant (type, attribs);
- return res;
-}
-
// Make a function type.
tree
@@ -2965,8 +2915,7 @@ Gcc_backend::function (tree functype, const std::string &name,
= build_decl (location.gcc_location (), FUNCTION_DECL, id, functype);
if (!asm_name.empty ())
SET_DECL_ASSEMBLER_NAME (decl, get_identifier_from_string (asm_name));
- if ((flags & function_is_visible) != 0)
- TREE_PUBLIC (decl) = 1;
+
if ((flags & function_is_declaration) != 0)
DECL_EXTERNAL (decl) = 1;
else
@@ -2985,14 +2934,6 @@ Gcc_backend::function (tree functype, const std::string &name,
TREE_THIS_VOLATILE (decl) = 1;
if ((flags & function_in_unique_section) != 0)
resolve_unique_section (decl, 0, 1);
- if ((flags & function_only_inline) != 0)
- {
- TREE_PUBLIC (decl) = 1;
- DECL_EXTERNAL (decl) = 1;
- DECL_DECLARED_INLINE_P (decl) = 1;
- }
- if ((flags & function_read_only) != 0)
- TREE_READONLY (decl) = 1;
rust_preserve_from_gc (decl);
return decl;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.h b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
index 10d4ea8..b5c0dbc 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
@@ -126,14 +126,18 @@ public:
CanonicalPath::new_seg (function.get_mappings ().get_nodeid (),
function.get_item_name ()),
function.get_locus ()};
- auto fnType
- = new TyTy::FnType (function.get_mappings ().get_hirid (),
- function.get_mappings ().get_defid (),
- function.get_item_name (), ident, flags,
- ::Backend::get_abi_from_string (parent.get_abi (),
- parent.get_locus ()),
- std::move (params), ret_type,
- std::move (substitutions));
+
+ auto abi = get_abi_from_string (parent.get_abi ());
+ if (abi == ABI::UNKNOWN)
+ {
+ rust_error_at (parent.get_locus (), "unknown abi");
+ }
+
+ auto fnType = new TyTy::FnType (function.get_mappings ().get_hirid (),
+ function.get_mappings ().get_defid (),
+ function.get_item_name (), ident, flags,
+ abi, std::move (params), ret_type,
+ std::move (substitutions));
context->insert_type (function.get_mappings (), fnType);
}
diff --git a/gcc/rust/util/rust-abi.cc b/gcc/rust/util/rust-abi.cc
new file mode 100644
index 0000000..c27e382
--- /dev/null
+++ b/gcc/rust/util/rust-abi.cc
@@ -0,0 +1,64 @@
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-abi.h"
+
+namespace Rust {
+
+Rust::ABI
+get_abi_from_string (const std::string &abi)
+{
+ if (abi.compare ("rust") == 0)
+ return Rust::ABI::C;
+ else if (abi.compare ("rust-intrinsic") == 0)
+ return Rust::ABI::INTRINSIC;
+ else if (abi.compare ("C") == 0)
+ return Rust::ABI::C;
+ else if (abi.compare ("cdecl") == 0)
+ return Rust::ABI::CDECL;
+ else if (abi.compare ("stdcall") == 0)
+ return Rust::ABI::STDCALL;
+ else if (abi.compare ("fastcall") == 0)
+ return Rust::ABI::FASTCALL;
+
+ return Rust::ABI::UNKNOWN;
+}
+
+std::string
+get_string_from_abi (Rust::ABI abi)
+{
+ switch (abi)
+ {
+ case Rust::ABI::RUST:
+ return "rust";
+ case Rust::ABI::INTRINSIC:
+ return "rust-intrinsic";
+ case Rust::ABI::C:
+ return "C";
+ case Rust::ABI::CDECL:
+ return "cdecl";
+ case Rust::ABI::STDCALL:
+ return "stdcall";
+ case Rust::ABI::FASTCALL:
+ return "fastcall";
+
+ case Rust::ABI::UNKNOWN:
+ return "unknown";
+ }
+ return "unknown";
+}
+
+} // namespace Rust
diff --git a/gcc/rust/rust-abi.h b/gcc/rust/util/rust-abi.h
index bd30432..04224ee 100644
--- a/gcc/rust/rust-abi.h
+++ b/gcc/rust/util/rust-abi.h
@@ -17,6 +17,8 @@
#ifndef RUST_ABI_OPTIONS_H
#define RUST_ABI_OPTIONS_H
+#include <string>
+
namespace Rust {
enum ABI
@@ -30,6 +32,12 @@ enum ABI
FASTCALL,
};
+extern Rust::ABI
+get_abi_from_string (const std::string &abi);
+
+extern std::string
+get_string_from_abi (Rust::ABI abi);
+
} // namespace Rust
#endif // RUST_ABI_OPTIONS_H