new file mode 100644
@@ -0,0 +1,308 @@
+# Make-lang.in -- Top level -*- makefile -*- fragment for GCC Rust frontend.
+
+# Copyright (C) 2009-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/>.
+
+# This file provides the language dependent support in the main Makefile.
+
+#RUST_EXES = rust
+
+# Use strict warnings for this front end.
+rust-warn = $(STRICT_WARN)
+
+# Installation name. Useful for cross compilers and used during install.
+GCCRS_INSTALL_NAME := $(shell echo gccrs|sed '$(program_transform_name)')
+GCCRS_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo gccrs|sed '$(program_transform_name)')
+
+# Define the names for selecting rust in LANGUAGES.
+rust: rust1$(exeext)
+
+# Tell GNU make to ignore files by these names if they exist.
+.PHONY: rust
+
+# removed GRS_CFLAGS from here
+
+CFLAGS-rust/rustspec.o += $(DRIVER_DEFINES)
+
+# Create the compiler driver gccrs.
+# A compiler driver is the program that interprets command argument and can be called from the command
+# line - e.g. gcc or g++, and not cc1, which is the actual compiler
+
+# Create driver objects
+GCCRS_D_OBJS = \
+ $(GCC_OBJS) \
+ rust/rustspec.o \
+ $(END)
+
+gccrs$(exeext): $(GCCRS_D_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a $(LIBDEPS)
+ +$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
+ $(GCCRS_D_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a \
+ $(EXTRA_GCC_LIBS) $(LIBS)
+
+# List of host object files used by the rust language - files for translation from the parse tree
+# to GENERIC
+# The compiler proper, not driver
+GRS_OBJS = \
+ rust/rust-lang.o \
+ $(END)
+# removed object files from here
+
+# All language-specific object files for Rust.
+RUST_ALL_OBJS = $(GRS_OBJS) $(RUST_TARGET_OBJS)
+
+rust_OBJS = $(RUST_ALL_OBJS) rust/rustspec.o
+
+# The compiler itself is called rust1 (formerly grs1)
+rust1$(exeext): $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(LIBDEPS)
+ +$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
+ $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(LIBS) $(BACKENDLIBS)
+
+# Build hooks.
+
+lang_checks += check-rust
+lang_checks_parallelized += check-rust
+check_rust_parallelize = 10
+
+# Copies its dependencies into the source directory. This generally should be used for generated files
+# such as Bison output files which are not version-controlled, but should be included in any release
+# tarballs. This target will be executed during a bootstrap if ‘--enable-generated-files-in-srcdir’
+# was specified as a configure option.
+rust.srcextra:
+
+rust.all.cross: gccrs$(exeext)
+
+# idk what this does but someone used it
+rust.start.encap: gccrs$(exeext)
+rust.rest.encap:
+
+# Build generated man pages for the front end from Texinfo manuals (see Man Page Generation), in the
+# build directory. This target is only called if the necessary tools are available, but should ignore
+# errors so as not to stop the build if errors occur; man pages are optional and the tools involved
+# may be installed in a broken way.
+rust.man:
+
+# Copies its dependencies into the source directory. These targets will be executed during a bootstrap
+# if ‘--enable-generated-files-in-srcdir’ was specified as a configure option.
+rust.srcman:
+
+# Clean hooks.
+
+rust.mostlyclean:
+# cd $(srcdir)/rust; rm -f *.o y.tab.h y.tab.c lex.yy.c
+
+rust.clean: rust.mostlyclean
+
+# Builds an etags TAGS file in the language subdirectory in the source tree.
+# TODO: add more directories if I add more
+rust.tags: force
+ cd $(srcdir)/rust; \
+ etags -o TAGS.sub *.y *.l *.cc *.h ast/*.h ast/*.cc lex/*.h lex/*.cc parse/*.h parse/*.cc; \
+ etags --include TAGS.sub --include ../TAGS.sub
+
+# Build documentation hooks.
+
+# Build info documentation for the front end, in the build directory. This target is only called by
+# ‘make bootstrap’ if a suitable version of makeinfo is available, so does not need to check for this,
+# and should fail if an error occurs.
+rust.info:
+
+rust.srcinfo:
+
+# Build DVI documentation for the front end, in the build directory. This should be done using
+# $(TEXI2DVI), with appropriate -I arguments pointing to directories of included files.
+rust.dvi:
+
+# Build PDF documentation for the front end, in the build directory. This should be done using
+# $(TEXI2PDF), with appropriate -I arguments pointing to directories of included files.
+rust.pdf:
+
+doc/rust.info:
+doc/rust.dvi:
+doc/rust.pdf:
+
+# Build HTML documentation for the front end, in the build directory.
+rust.html:
+
+# Install hooks.
+
+# Install everything that is part of the front end, apart from the compiler executables listed in
+# compilers in config-lang.in.
+rust.install-common: installdirs
+# -rm -f $(DESTDIR)$(bindir)/$(GCCRS_INSTALL_NAME)$(exeext)
+# -rm -f $(DESTDIR)$(bindir)/$(GCCRS_TARGET_INSTALL_NAME)$(exeext)
+# $(INSTALL_PROGRAM) gccrs$(exeext) $(DESTDIR)$(bindir)/$(GCCRS_INSTALL_NAME)$(exeext)
+# if test -f $(DESTDIR)$(bindir)$(GCCRS_TARGET_INSTALL_NAME)$(exeext); then \
+# :; \
+# else \
+# cd $(DESTDIR)$(bindir) && \
+# $(LN) $(GCCRS_INSTALL_NAME)$(exeext) $(GCCRS_TARGET_INSTALL_NAME)$(exeext); \
+# fi
+ -rm -f $(DESTDIR)$(bindir)/$(GCCRS_INSTALL_NAME)$(exeext)
+ $(INSTALL_PROGRAM) gccrs$(exeext) $(DESTDIR)$(bindir)/$(GCCRS_INSTALL_NAME)$(exeext)
+ rm -f $(DESTDIR)$(bindir)/$(GCCRS_TARGET_INSTALL_NAME)$(exeext); \
+ ( cd $(DESTDIR)$(bindir) && \
+ $(LN) $(GCCRS_INSTALL_NAME)$(exeext) $(GCCRS_TARGET_INSTALL_NAME)$(exeext) ); \
+
+# Install headers needed for plugins.
+rust.install-plugin:
+
+# Uninstall files installed by installing the compiler. This is currently documented not to be
+# supported, so the hook need not do anything.
+rust.uninstall:
+# -rm -rf $(DESTDIR)/$(bindir)/$(GCCRS_INSTALL_NAME)$(exeext)
+ -rm -f gccrs$(exeext) grs1$(exeext)
+ -rm -f $(RUST_ALL_OBJS)
+# ^those two are a maybe
+
+# Enable selftests for the rust frontend
+selftest-rust: s-selftest-rust
+
+RUST_SELFTEST_FLAGS = -xrs $(SELFTEST_FLAGS)
+RUST_SELFTEST_DEPS = rust1$(exeext) $(SELFTEST_DEPS)
+
+# Run the rust selftests
+s-selftest-rust: $(RUST_SELFTEST_DEPS)
+ $(GCC_FOR_TARGET) $(RUST_SELFTEST_FLAGS)
+ $(STAMP) $@
+
+# Install info documentation for the front end, if it is present in the source directory. This target
+# should have dependencies on info files that should be installed.
+rust.install-info:
+
+rust.install-pdf:
+
+# Install man pages for the front end. This target should ignore errors.
+rust.install-man:
+
+# Stage hooks:
+# The toplevel makefile has already created stage?/rust at this point.
+# Used for handling bootstrap
+
+rust.stage1: stage1-start
+ -mv rust/*$(objext) stage1/rust
+rust.stage2: stage2-start
+ -mv rust/*$(objext) stage2/rust
+rust.stage3: stage3-start
+ -mv rust/*$(objext) stage3/rust
+rust.stage4: stage4-start
+ -mv rust/*$(objext) stage4/rust
+rust.stageprofile: stageprofile-start
+ -mv rust/*$(objext) stageprofile/rust
+rust.stagefeedback: stagefeedback-start
+ -mv rust/*$(objext) stagefeedback/rust
+
+CFLAGS-rust/rust-lang.o += -DDEFAULT_TARGET_VERSION=\"$(version)\" \
+ -DDEFAULT_TARGET_MACHINE=\"$(target_noncanonical)\"
+
+# cross-folder includes - add new folders later
+RUST_INCLUDES = -I $(srcdir)/rust \
+ -I $(srcdir)/rust/lex \
+ -I $(srcdir)/rust/parse \
+ -I $(srcdir)/rust/ast \
+ -I $(srcdir)/rust/analysis \
+ -I $(srcdir)/rust/backend \
+ -I $(srcdir)/rust/expand \
+ -I $(srcdir)/rust/hir/tree \
+ -I $(srcdir)/rust/hir \
+ -I $(srcdir)/rust/resolve \
+ -I $(srcdir)/rust/util \
+ -I $(srcdir)/rust/typecheck \
+ -I $(srcdir)/rust/checks/lints \
+ -I $(srcdir)/rust/checks/errors \
+ -I $(srcdir)/rust/checks/errors/privacy \
+ -I $(srcdir)/rust/util \
+ -I $(srcdir)/rust/metadata
+
+# add files that require cross-folder includes - currently rust-lang.o, rust-lex.o
+CFLAGS-rust/rust-lang.o += $(RUST_INCLUDES)
+CFLAGS-rust/rust-lex.o += $(RUST_INCLUDES)
+CFLAGS-rust/rust-parse.o += $(RUST_INCLUDES)
+CFLAGS-rust/rust-session-manager.o += $(RUST_INCLUDES)
+
+# TODO: possibly find a way to ensure C++11 compilation level here?
+RUST_CXXFLAGS = -std=c++11 -Wno-unused-parameter -Werror=overloaded-virtual
+
+# build all rust/lex files in rust folder, add cross-folder includes
+rust/%.o: rust/lex/%.cc
+ $(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+ $(POSTCOMPILE)
+
+# build all rust/parse files in rust folder, add cross-folder includes
+rust/%.o: rust/parse/%.cc
+ $(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+ $(POSTCOMPILE)
+
+# build rust/ast files in rust folder
+rust/%.o: rust/ast/%.cc
+ $(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+ $(POSTCOMPILE)
+
+# build rust/backend files in rust folder
+rust/%.o: rust/backend/%.cc
+ $(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+ $(POSTCOMPILE)
+
+# build rust/expand files in rust folder
+rust/%.o: rust/expand/%.cc
+ $(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+ $(POSTCOMPILE)
+
+# build rust/util files in rust folder
+rust/%.o: rust/util/%.cc
+ $(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+ $(POSTCOMPILE)
+
+# build rust/hir files in rust folder
+rust/%.o: rust/hir/%.cc
+ $(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+ $(POSTCOMPILE)
+
+# build rust/hir/tree files in rust folder
+rust/%.o: rust/hir/tree/%.cc
+ $(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+ $(POSTCOMPILE)
+
+# build rust/resolve files in rust folder
+rust/%.o: rust/resolve/%.cc
+ $(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+ $(POSTCOMPILE)
+
+# build rust/typecheck files in rust folder
+rust/%.o: rust/typecheck/%.cc
+ $(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+ $(POSTCOMPILE)
+
+# build rust/checks/lints files in rust folder
+rust/%.o: rust/checks/lints/%.cc
+ $(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+ $(POSTCOMPILE)
+
+# build rust/checks/errors files in rust folder
+rust/%.o: rust/checks/errors/%.cc
+ $(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+ $(POSTCOMPILE)
+
+# build privacy pass files in rust folder
+rust/%.o: rust/checks/errors/privacy/%.cc
+ $(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+ $(POSTCOMPILE)
+
+# build rust/metadata files in rust folder
+rust/%.o: rust/metadata/%.cc
+ $(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+ $(POSTCOMPILE)
new file mode 100644
@@ -0,0 +1,30 @@
+# config-lang.in -- Top level configure fragment for gcc Rust frontend.
+
+# Copyright (C) 2009-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/>.
+
+# Configure looks for the existence of this file to auto-config each language.
+# We define several parameters used by configure:
+#
+# language - name of language as it would appear in $(LANGUAGES)
+# compilers - value to add to $(COMPILERS)
+
+language="rust"
+compilers="rust1\$(exeext)"
+build_by_default="no"
+gtfiles="\$(srcdir)/rust/rust-lang.cc"
new file mode 100644
@@ -0,0 +1,26 @@
+/* lang-specs.h -- gcc driver specs for Rust frontend.
+ Copyright (C) 2009-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/>. */
+
+/* This is the contribution to the `default_compilers' array in gcc.cc
+ for the Rust language. */
+
+{".rs", "@rs", 0, 1, 0},
+ {"@rs",
+ "rust1 %i %(cc1_options) %{I*} %{L*} %D %{!fsyntax-only:%(invoke_as)}", 0, 1,
+ 0},
new file mode 100644
@@ -0,0 +1,45 @@
+; Options for the Rust front end.
+; Copyright (C) 2003-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/>.
+
+; See the GCC internals manual for a description of this file's format.
+
+; Please try to keep this file in ASCII collating order.
+
+; Describes command-line options used by this frontend
+
+Language
+Rust
+
+I
+Rust Joined Separate
+; Documented in c.opt
+
+L
+Rust Joined Separate
+; Not documented
+
+Wall
+Rust
+; Documented in c.opt
+
+o
+Rust Joined Separate
+; Documented in common.opt
+
+; This comment is to ensure we retain the blank line above.
new file mode 100644
@@ -0,0 +1,332 @@
+// 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 "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "target.h"
+#include "tree.h"
+#include "gimple-expr.h"
+#include "diagnostic.h"
+#include "opts.h"
+#include "fold-const.h"
+#include "gimplify.h"
+#include "stor-layout.h"
+#include "debug.h"
+#include "convert.h"
+#include "langhooks.h"
+#include "langhooks-def.h"
+#include "options.h"
+#include <mpfr.h>
+
+// Language-dependent contents of a type. GTY() mark used for garbage collector.
+struct GTY (()) lang_type
+{
+ char dummy;
+};
+
+// Language-dependent contents of a decl.
+struct GTY (()) lang_decl
+{
+ char dummy;
+};
+
+// Language-dependent contents of an identifier. This must include a
+// tree_identifier.
+struct GTY (()) lang_identifier
+{
+ struct tree_identifier common;
+};
+
+// The resulting tree type.
+union GTY ((
+ desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
+ chain_next (
+ "CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), "
+ "TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL")))
+ lang_tree_node
+{
+ union tree_node GTY ((tag ("0"), desc ("tree_node_structure (&%h)"))) generic;
+ struct lang_identifier GTY ((tag ("1"))) identifier;
+};
+
+// We don't use language_function.
+struct GTY (()) language_function
+{
+ int dummy;
+};
+
+/* Language hooks. */
+
+tree
+convert (tree type, tree expr)
+{
+ if (type == error_mark_node || expr == error_mark_node
+ || TREE_TYPE (expr) == error_mark_node)
+ return error_mark_node;
+
+ if (type == TREE_TYPE (expr))
+ return expr;
+
+ if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
+ return fold_convert (type, expr);
+
+ switch (TREE_CODE (type))
+ {
+ case VOID_TYPE:
+ case BOOLEAN_TYPE:
+ return fold_convert (type, expr);
+ case INTEGER_TYPE:
+ return fold (convert_to_integer (type, expr));
+ case POINTER_TYPE:
+ return fold (convert_to_pointer (type, expr));
+ case REAL_TYPE:
+ return fold (convert_to_real (type, expr));
+ case COMPLEX_TYPE:
+ return fold (convert_to_complex (type, expr));
+ default:
+ break;
+ }
+
+ gcc_unreachable ();
+}
+
+/* Initial lang hook called (possibly), used for initialisation.
+ * Must call build_common_tree_nodes, set_sizetype, build_common_tree_nodes_2,
+ * and build_common_builtin_nodes, as well as set global variable
+ * void_list_node. Apparently called after option handling? */
+static bool
+grs_langhook_init (void)
+{
+ /* Something to do with this:
+ This allows the code in d-builtins.cc to not have to worry about
+ converting (C signed char *) to (D char *) for string arguments of
+ built-in functions. The parameter (signed_char = false) specifies
+ whether char is signed. */
+ build_common_tree_nodes (false);
+
+ // Creates a new TREE_LIST node with purpose NULL_TREE and value
+ // void_type_node
+ void_list_node = build_tree_list (NULL_TREE, void_type_node);
+
+ // Builds built-ins for middle-end after all front-end built-ins are already
+ // instantiated
+ build_common_builtin_nodes ();
+
+ mpfr_set_default_prec (128);
+
+ using_eh_for_cleanups ();
+
+ return true;
+}
+
+/* The option mask (something to do with options for specific frontends or
+ * something). */
+static unsigned int
+grs_langhook_option_lang_mask (void)
+{
+ return CL_Rust;
+}
+
+/* Initialize the options structure. */
+static void
+grs_langhook_init_options_struct (struct gcc_options * /* opts */)
+{}
+
+/* Main entry point for front-end, apparently. Finds input file names in global
+ * vars in_fnames and num_in_fnames. From this, frontend can take over and do
+ * actual parsing and initial compilation. This function must create a complete
+ * parse tree in a global var, and then return.
+ *
+ * Some consider this the "start of compilation". */
+static void
+grs_langhook_parse_file (void)
+{}
+
+/* Seems to get the exact type for a specific type - e.g. for scalar float with
+ * 32-bit bitsize, it returns float, and for 64-bit bitsize, it returns double.
+ * Used to map RTL nodes to machine modes or something like that. */
+static tree
+grs_langhook_type_for_mode (machine_mode mode, int unsignedp)
+{
+ if (mode == TYPE_MODE (float_type_node))
+ return float_type_node;
+
+ if (mode == TYPE_MODE (double_type_node))
+ return double_type_node;
+
+ if (mode == TYPE_MODE (intQI_type_node)) // quarter integer mode - single byte
+ // treated as integer
+ return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
+ if (mode
+ == TYPE_MODE (intHI_type_node)) // half integer mode - two-byte integer
+ return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
+ if (mode
+ == TYPE_MODE (intSI_type_node)) // single integer mode - four-byte integer
+ return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
+ if (mode
+ == TYPE_MODE (
+ intDI_type_node)) // double integer mode - eight-byte integer
+ return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
+ if (mode
+ == TYPE_MODE (intTI_type_node)) // tetra integer mode - 16-byte integer
+ return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
+
+ if (mode == TYPE_MODE (integer_type_node))
+ return unsignedp ? unsigned_type_node : integer_type_node;
+
+ if (mode == TYPE_MODE (long_integer_type_node))
+ return unsignedp ? long_unsigned_type_node : long_integer_type_node;
+
+ if (mode == TYPE_MODE (long_long_integer_type_node))
+ return unsignedp ? long_long_unsigned_type_node
+ : long_long_integer_type_node;
+
+ if (COMPLEX_MODE_P (mode))
+ {
+ if (mode == TYPE_MODE (complex_float_type_node))
+ return complex_float_type_node;
+ if (mode == TYPE_MODE (complex_double_type_node))
+ return complex_double_type_node;
+ if (mode == TYPE_MODE (complex_long_double_type_node))
+ return complex_long_double_type_node;
+ if (mode == TYPE_MODE (complex_integer_type_node) && !unsignedp)
+ return complex_integer_type_node;
+ }
+ /* gcc_unreachable */
+ return NULL;
+}
+
+// Record a builtin function. We just ignore builtin functions.
+static tree
+grs_langhook_builtin_function (tree decl ATTRIBUTE_UNUSED)
+{
+ return decl;
+}
+
+static bool
+grs_langhook_global_bindings_p (void)
+{
+ return false;
+}
+
+static tree
+grs_langhook_pushdecl (tree decl ATTRIBUTE_UNUSED)
+{
+ gcc_unreachable ();
+ return NULL;
+}
+
+static tree
+grs_langhook_getdecls (void)
+{
+ return NULL;
+}
+
+static bool
+grs_langhook_handle_option (
+ size_t scode ATTRIBUTE_UNUSED, const char *arg ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT value ATTRIBUTE_UNUSED, int kind ATTRIBUTE_UNUSED,
+ location_t loc ATTRIBUTE_UNUSED,
+ const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
+{
+ return false;
+}
+
+static bool
+grs_langhook_post_options (const char **pfilename ATTRIBUTE_UNUSED)
+{
+ /* Returning false means that the backend should be used. */
+ return false;
+}
+
+/* Rust-specific gimplification. May need to gimplify e.g.
+ * CALL_EXPR_STATIC_CHAIN */
+static int
+grs_langhook_gimplify_expr (tree *expr_p ATTRIBUTE_UNUSED,
+ gimple_seq *pre_p ATTRIBUTE_UNUSED,
+ gimple_seq *post_p ATTRIBUTE_UNUSED)
+{
+ return GS_UNHANDLED;
+}
+
+static tree
+grs_langhook_eh_personality (void)
+{
+ return error_mark_node;
+}
+
+/* FIXME: This is a hack to preserve trees that we create from the
+ garbage collector. */
+
+static GTY (()) tree rust_gc_root;
+
+void
+rust_preserve_from_gc (tree t)
+{
+ rust_gc_root = tree_cons (NULL_TREE, t, rust_gc_root);
+}
+
+/* Convert an identifier for use in an error message. */
+
+const char *
+rust_localize_identifier (const char *ident)
+{
+ return identifier_to_locale (ident);
+}
+
+/* The language hooks data structure. This is the main interface between the GCC
+ * front-end and the GCC middle-end/back-end. A list of language hooks could be
+ * found in <gcc>/langhooks.h
+ */
+#undef LANG_HOOKS_NAME
+#undef LANG_HOOKS_INIT
+#undef LANG_HOOKS_OPTION_LANG_MASK
+#undef LANG_HOOKS_INIT_OPTIONS_STRUCT
+#undef LANG_HOOKS_HANDLE_OPTION
+#undef LANG_HOOKS_POST_OPTIONS
+#undef LANG_HOOKS_PARSE_FILE
+#undef LANG_HOOKS_TYPE_FOR_MODE
+#undef LANG_HOOKS_BUILTIN_FUNCTION
+#undef LANG_HOOKS_GLOBAL_BINDINGS_P
+#undef LANG_HOOKS_PUSHDECL
+#undef LANG_HOOKS_GETDECLS
+#undef LANG_HOOKS_WRITE_GLOBALS
+#undef LANG_HOOKS_GIMPLIFY_EXPR
+#undef LANG_HOOKS_EH_PERSONALITY
+
+#define LANG_HOOKS_NAME "GNU Rust"
+#define LANG_HOOKS_INIT grs_langhook_init
+#define LANG_HOOKS_OPTION_LANG_MASK grs_langhook_option_lang_mask
+#define LANG_HOOKS_INIT_OPTIONS_STRUCT grs_langhook_init_options_struct
+#define LANG_HOOKS_HANDLE_OPTION grs_langhook_handle_option
+#define LANG_HOOKS_POST_OPTIONS grs_langhook_post_options
+#define LANG_HOOKS_PARSE_FILE grs_langhook_parse_file
+#define LANG_HOOKS_TYPE_FOR_MODE grs_langhook_type_for_mode
+#define LANG_HOOKS_BUILTIN_FUNCTION grs_langhook_builtin_function
+#define LANG_HOOKS_GLOBAL_BINDINGS_P grs_langhook_global_bindings_p
+#define LANG_HOOKS_PUSHDECL grs_langhook_pushdecl
+#define LANG_HOOKS_GETDECLS grs_langhook_getdecls
+#define LANG_HOOKS_GIMPLIFY_EXPR grs_langhook_gimplify_expr
+#define LANG_HOOKS_EH_PERSONALITY grs_langhook_eh_personality
+
+// Expands all LANG_HOOKS_x of GCC
+struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
+
+#include "gt-rust-rust-lang.h"
+#include "gtype-rust.h"
new file mode 100644
@@ -0,0 +1,285 @@
+/* rustspec.c -- Specific flags and argument handling of the gcc Rust front end.
+ Copyright (C) 2009-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 "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "opts.h"
+
+// satisfy intellisense
+#include "options.h"
+
+/* This bit is set if we saw a `-xfoo' language specification. */
+#define LANGSPEC (1 << 1)
+/* This bit is set if they did `-lc'. */
+#define WITHLIBC (1 << 2)
+/* Skip this option. */
+#define SKIPOPT (1 << 3)
+
+void
+lang_specific_driver (struct cl_decoded_option **in_decoded_options,
+ unsigned int *in_decoded_options_count,
+ int *in_added_libraries)
+{
+ unsigned int i, j;
+
+ /* This is a tristate:
+ -1 means we should not link in librust
+ 0 means we should link in librust if it is needed
+ 1 means librust is needed and should be linked in.
+ 2 means librust is needed and should be linked statically. */
+ int library = 0;
+
+ /* The new argument list will be contained in this. */
+ struct cl_decoded_option *new_decoded_options;
+
+ /* "-lc" if it appears on the command line. */
+ const struct cl_decoded_option *saw_libc = 0;
+
+ /* An array used to flag each argument that needs a bit set for
+ LANGSPEC or WITHLIBC. */
+ int *args;
+
+ /* True if we saw -static. */
+ int static_link = 0;
+
+ /* True if we should add -shared-libgcc to the command-line. */
+ int shared_libgcc = 1;
+
+ /* The total number of arguments with the new stuff. */
+ unsigned int argc;
+
+ /* The argument list. */
+ struct cl_decoded_option *decoded_options;
+
+ /* The number of libraries added in. */
+ int added_libraries;
+
+ /* The total number of arguments with the new stuff. */
+ int num_args = 1;
+
+ /* Whether the -o option was used. */
+ bool saw_opt_o = false;
+
+ /* Whether the -c option was used. Also used for -E, -fsyntax-only,
+ in general anything which implies only compilation and not
+ linking. */
+ bool saw_opt_c = false;
+
+ /* Whether the -S option was used. */
+ bool saw_opt_S = false;
+
+ /* The first input file with an extension of .rs. */
+ const char *first_rust_file = NULL;
+
+ argc = *in_decoded_options_count;
+ decoded_options = *in_decoded_options;
+ added_libraries = *in_added_libraries;
+
+ args = XCNEWVEC (int, argc);
+
+ for (i = 1; i < argc; i++)
+ {
+ const char *arg = decoded_options[i].arg;
+
+ switch (decoded_options[i].opt_index)
+ {
+ case OPT_r:
+ case OPT_nostdlib:
+ case OPT_nodefaultlibs:
+ library = -1;
+ break;
+
+ case OPT_l:
+ if (strcmp (arg, "c") == 0)
+ args[i] |= WITHLIBC;
+ else
+ /* Unrecognized libraries (e.g. -lfoo) may require librust. */
+ library = (library == 0) ? 1 : library;
+ break;
+
+ case OPT_x:
+ if (library == 0 && strcmp (arg, "rust") == 0)
+ library = 1;
+ break;
+
+ case OPT_Xlinker:
+ case OPT_Wl_:
+ /* Arguments that go directly to the linker might be .o files,
+ or something, and so might cause librust to be needed. */
+ if (library == 0)
+ library = 1;
+ break;
+
+ case OPT_c:
+ case OPT_E:
+ case OPT_M:
+ case OPT_MM:
+ case OPT_fsyntax_only:
+ /* Don't specify libraries if we won't link, since that would
+ cause a warning. */
+ saw_opt_c = true;
+ library = -1;
+ break;
+
+ case OPT_S:
+ saw_opt_S = true;
+ library = -1;
+ break;
+
+ case OPT_o:
+ saw_opt_o = true;
+ break;
+
+ case OPT_static:
+ static_link = 1;
+ break;
+
+ case OPT_static_libgcc:
+ shared_libgcc = 0;
+ break;
+
+ case OPT_SPECIAL_input_file:
+ if (library == 0)
+ library = 1;
+
+ if (first_rust_file == NULL)
+ {
+ int len;
+
+ len = strlen (arg);
+ if (len > 3 && strcmp (arg + len - 3, ".rs") == 0)
+ first_rust_file = arg;
+ }
+
+ break;
+ }
+ }
+
+ /* There's no point adding -shared-libgcc if we don't have a shared
+ libgcc. */
+#ifndef ENABLE_SHARED_LIBGCC
+ shared_libgcc = 0;
+#endif
+
+ /* Make sure to have room for the trailing NULL argument. */
+ num_args = argc + shared_libgcc + (library > 0) * 5 + 10;
+ new_decoded_options = XNEWVEC (struct cl_decoded_option, num_args);
+
+ i = 0;
+ j = 0;
+
+ /* Copy the 0th argument, i.e., the name of the program itself. */
+ new_decoded_options[j++] = decoded_options[i++];
+
+ /* NOTE: We start at 1 now, not 0. */
+ while (i < argc)
+ {
+ new_decoded_options[j] = decoded_options[i];
+
+ if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
+ {
+ --j;
+ saw_libc = &decoded_options[i];
+ }
+
+ if ((args[i] & SKIPOPT) != 0)
+ --j;
+
+ i++;
+ j++;
+ }
+
+ /* If we didn't see a -o option, add one. This is because we need
+ the driver to pass all .rs files to rust1. Without a -o option the
+ driver will invoke rust1 separately for each input file. FIXME:
+ This should probably use some other interface to force the driver
+ to set combine_inputs. */
+ if (first_rust_file != NULL && !saw_opt_o)
+ {
+ if (saw_opt_c || saw_opt_S)
+ {
+ const char *base;
+ int baselen;
+ int alen;
+ char *out;
+
+ base = lbasename (first_rust_file);
+ baselen = strlen (base) - 3;
+ alen = baselen + 3;
+ out = XNEWVEC (char, alen);
+ memcpy (out, base, baselen);
+ /* The driver will convert .o to some other suffix (e.g.,
+ .obj) if appropriate. */
+ out[baselen] = '.';
+ if (saw_opt_S)
+ out[baselen + 1] = 's';
+ else
+ out[baselen + 1] = 'o';
+ out[baselen + 2] = '\0';
+ generate_option (OPT_o, out, 1, CL_DRIVER, &new_decoded_options[j]);
+ }
+ else
+ generate_option (OPT_o, "a.out", 1, CL_DRIVER, &new_decoded_options[j]);
+ j++;
+ }
+
+ /* Add `-lrust' if we haven't already done so. */
+ if (library > 0)
+ {
+#ifdef HAVE_LD_STATIC_DYNAMIC
+ if (library > 1 && !static_link)
+ {
+ generate_option (OPT_Wl_, LD_STATIC_OPTION, 1, CL_DRIVER,
+ &new_decoded_options[j]);
+ j++;
+ }
+#endif
+
+#ifdef HAVE_LD_STATIC_DYNAMIC
+ if (library > 1 && !static_link)
+ {
+ generate_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1, CL_DRIVER,
+ &new_decoded_options[j]);
+ j++;
+ }
+#endif
+ }
+
+ if (saw_libc)
+ new_decoded_options[j++] = *saw_libc;
+ if (shared_libgcc && !static_link)
+ generate_option (OPT_shared_libgcc, NULL, 1, CL_DRIVER,
+ &new_decoded_options[j++]);
+
+ *in_decoded_options_count = j;
+ *in_decoded_options = new_decoded_options;
+ *in_added_libraries = added_libraries;
+}
+
+/* Called before linking. Returns 0 on success and -1 on failure. */
+int
+lang_specific_pre_link (void) /* Not used for Rust. */
+{
+ return 0;
+}
+
+/* Number of extra output files that lang_specific_pre_link may generate. */
+int lang_specific_extra_outfiles = 0; /* Not used for Rust. */