[PATCH Rust front-end v2 02/37] gccrs: Add nessecary hooks for a Rust front-end testsuite

2022-08-24 Thread herron . philip
From: Philip Herron 

This copy's over code from other front-end testsuites to enable testing
for the rust front-end specifically.

Co-authored-by: Marc Poulhiès 
Co-authored-by: Thomas Schwinge 
---
 gcc/testsuite/lib/rust-dg.exp |  49 +
 gcc/testsuite/lib/rust.exp| 186 ++
 2 files changed, 235 insertions(+)
 create mode 100644 gcc/testsuite/lib/rust-dg.exp
 create mode 100644 gcc/testsuite/lib/rust.exp

diff --git a/gcc/testsuite/lib/rust-dg.exp b/gcc/testsuite/lib/rust-dg.exp
new file mode 100644
index 000..a8a2ac0c8eb
--- /dev/null
+++ b/gcc/testsuite/lib/rust-dg.exp
@@ -0,0 +1,49 @@
+# Copyright (C) 1997-2022 Free Software Foundation, Inc.
+
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program 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
+# .
+
+load_lib gcc-dg.exp
+
+# Define rust callbacks for dg.exp.
+
+proc rust-dg-test { prog do_what extra_tool_flags } {
+return [gcc-dg-test-1 rust_target_compile $prog $do_what $extra_tool_flags]
+}
+
+proc rust-dg-prune { system text } {
+return [gcc-dg-prune $system $text]
+}
+
+# Utility routines.
+
+#
+# rust_load -- wrapper around default rust_load to handle tests that
+# require program arguments passed to them.
+#
+
+if { [info procs rust_load] != [list] \
+  && [info procs prev_rust_load] == [list] } {
+rename rust_load prev_rust_load
+
+proc rust_load { program args } {
+   global RUST_EXECUTE_ARGS
+   if [info exists RUST_EXECUTE_ARGS] then {
+   set args [concat "{$RUST_EXECUTE_ARGS}"]
+   }
+   set result [eval [list prev_rust_load $program] $args ]
+   return $result
+}
+}
+
diff --git a/gcc/testsuite/lib/rust.exp b/gcc/testsuite/lib/rust.exp
new file mode 100644
index 000..6993c976304
--- /dev/null
+++ b/gcc/testsuite/lib/rust.exp
@@ -0,0 +1,186 @@
+# Copyright (C) 2012-2022 Free Software Foundation, Inc.
+
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program 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
+# .
+
+#
+# rust support library routines
+#
+
+load_lib prune.exp
+load_lib gcc-defs.exp
+load_lib timeout.exp
+load_lib target-libpath.exp
+
+#
+# RUST_UNDER_TEST is the compiler under test.
+#
+
+set rust_compile_options ""
+
+
+#
+# rust_include_flags -- include flags for the gcc tree structure
+#
+
+proc rust_include_flags { paths } {
+global srcdir
+global TESTING_IN_BUILD_TREE
+
+set flags ""
+
+if { [is_remote host] || ![info exists TESTING_IN_BUILD_TREE] } {
+   return "${flags}"
+}
+
+set gccpath ${paths}
+
+return "$flags"
+}
+
+#
+# rust_link_flags -- linker flags for the gcc tree structure
+#
+
+proc rust_link_flags { paths } {
+global srcdir
+global ld_library_path
+global RUST_UNDER_TEST
+global shlib_ext
+global SHARED_OPTION
+
+set gccpath ${paths}
+set libio_dir ""
+set flags ""
+set ld_library_path "."
+set shlib_ext [get_shlib_extension]
+set SHARED_OPTION ""
+verbose "shared lib extension: $shlib_ext"
+
+set_ld_library_path_env_vars
+
+return "$flags"
+}
+
+#
+# rust_init -- called at the start of each subdir of tests
+#
+
+proc rust_init { args } {
+global subdir
+global rust_initialized
+global base_dir
+global tmpdir
+global libdir
+global gluefile wrap_flags
+global objdir srcdir
+global ALWAYS_RUSTFLAGS
+global TOOL_EXECUTABLE TOOL_OPTIONS
+global RUST_UNDER_TEST
+global TESTING_IN_BUILD_TREE
+global TEST_ALWAYS_FLAGS
+global gcc_warning_prefix
+global gcc_error_prefix
+
+# We set LC_ALL and LANG to C so that we get the same error messages as 
expected.
+setenv LC_ALL C
+setenv LANG C
+
+if ![info exists RUST_UNDER_TEST] then {
+   if [info exists TOOL_EXECUTABLE] {
+   set RUST_UNDER_TEST $TOOL_EXECUTABLE
+   } else {
+   if { [is_remot

[PATCH Rust front-end v2 04/37] gccrs: Add link cases testsuite

2022-08-24 Thread herron . philip
From: Philip Herron 

This testsuite is heavily inspired from the lto testsuite which uses a
pattern that each file is compiled to an object file and finally linked
together. Since rust does not have headers/prototypes we rely on the
ordering here so that all files numbered greater than zero get compiled to
object files first leaving the _0 file free to test the 'extern crate' and
use keywords to force testing of the compiler to read metadata from the
other 'crates'.
---
 gcc/testsuite/rust/link/generic_function_0.rs |   7 +
 gcc/testsuite/rust/link/generic_function_1.rs |   3 +
 gcc/testsuite/rust/link/link.exp  | 172 ++
 gcc/testsuite/rust/link/simple_function_0.rs  |   8 +
 gcc/testsuite/rust/link/simple_function_1.rs  |   3 +
 gcc/testsuite/rust/link/trait_import_0.rs |  19 ++
 gcc/testsuite/rust/link/trait_import_1.rs |   6 +
 7 files changed, 218 insertions(+)
 create mode 100644 gcc/testsuite/rust/link/generic_function_0.rs
 create mode 100644 gcc/testsuite/rust/link/generic_function_1.rs
 create mode 100644 gcc/testsuite/rust/link/link.exp
 create mode 100644 gcc/testsuite/rust/link/simple_function_0.rs
 create mode 100644 gcc/testsuite/rust/link/simple_function_1.rs
 create mode 100644 gcc/testsuite/rust/link/trait_import_0.rs
 create mode 100644 gcc/testsuite/rust/link/trait_import_1.rs

diff --git a/gcc/testsuite/rust/link/generic_function_0.rs 
b/gcc/testsuite/rust/link/generic_function_0.rs
new file mode 100644
index 000..58b8eb13db6
--- /dev/null
+++ b/gcc/testsuite/rust/link/generic_function_0.rs
@@ -0,0 +1,7 @@
+extern crate generic_function_1;
+use generic_function_1::generic_function;
+
+fn main() -> i32 {
+let a = generic_function(123);
+a - 123
+}
diff --git a/gcc/testsuite/rust/link/generic_function_1.rs 
b/gcc/testsuite/rust/link/generic_function_1.rs
new file mode 100644
index 000..8fb0788e388
--- /dev/null
+++ b/gcc/testsuite/rust/link/generic_function_1.rs
@@ -0,0 +1,3 @@
+pub fn generic_function(a: X) -> X {
+a
+}
diff --git a/gcc/testsuite/rust/link/link.exp b/gcc/testsuite/rust/link/link.exp
new file mode 100644
index 000..8b2e93ceab6
--- /dev/null
+++ b/gcc/testsuite/rust/link/link.exp
@@ -0,0 +1,172 @@
+# Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+# This program 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 of the License, or
+# (at your option) any later version.
+# 
+# This program 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
+# .
+
+# Execute tests, torture testing.
+
+# Load support procs.
+load_lib rust-dg.exp
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+set saved-dg-do-what-default ${dg-do-what-default}
+
+set dg-do-what-default "assemble"
+
+# rs-obj -- compile to an object file
+#
+# SOURCE is the source file
+# DEST is the object file
+# OPTALL is the list of compiler options to use with all tests
+# OPTFILE is the list of compiler options to use with this file
+# OPTSTR is the options to print with test messages
+# XFAILDATA is the xfail data to be passed to the compiler
+proc rs-obj { source dest optall optfile optstr xfaildata } {
+global tool
+global compiler_conditional_xfail_data
+
+# Set up the options for compiling this file.
+set options ""
+lappend options "additional_flags=$optall $optfile"
+
+set compiler_conditional_xfail_data $xfaildata
+set comp_output [${tool}_target_compile "$source" "$dest" object $options]
+}
+
+# rs-execute -- compile multi-file tests
+#
+# SRC1 is the full pathname of the main file of the testcase.
+# SID identifies a test suite in the names of temporary files.
+proc rs-execute-1 { src1 } {
+global srcdir tmpdir
+
+# Get extra flags for this test from the primary source file, and
+# process other dg-* options that this suite supports.  Warn about
+# unsupported flags.
+verbose "rs-execute: $src1" 1
+set compile_type "run"
+set compile_xfail(0) "" 
+
+# Set up the names of the other source files.
+set dir [file dirname $src1]
+set base [file rootname $src1]
+set base [string range $base [string length $dir] end]
+regsub "_0" $base "" base
+regsub "/" $base "" base
+set src_list $src1
+set i 1
+set done 0
+while { !$done } {
+   set names [glob -nocomplain -types f -- "${dir}/${base}_${i}.*"]
+   if { [llength ${names}] > 1 } {
+   warning "rs-link-execute: more than one file matched 
${dir}/${base}_${i}.*"
+   }
+   if { [llength ${names}] == 1 } {
+   

[PATCH Rust front-end v2 01/37] Use DW_ATE_UTF for the Rust 'char' type

2022-08-24 Thread herron . philip
From: Tom Tromey 

The Rust 'char' type should use the DWARF DW_ATE_UTF encoding.
---
 gcc/dwarf2out.cc | 23 ++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index e3920c898f5..a8bccbabca4 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -5600,6 +5600,16 @@ is_fortran (const_tree decl)
   return is_fortran ();
 }
 
+/* Return TRUE if the language is Rust.  */
+
+static inline bool
+is_rust ()
+{
+  unsigned int lang = get_AT_unsigned (comp_unit_die (), DW_AT_language);
+
+  return lang == DW_LANG_Rust || lang == DW_LANG_Rust_old;
+}
+
 /* Return TRUE if the language is Ada.  */
 
 static inline bool
@@ -13231,7 +13241,11 @@ base_type_die (tree type, bool reverse)
}
   if (TYPE_STRING_FLAG (type))
{
- if (TYPE_UNSIGNED (type))
+ if ((dwarf_version >= 4 || !dwarf_strict)
+ && is_rust ()
+ && int_size_in_bytes (type) == 4)
+   encoding = DW_ATE_UTF;
+ else if (TYPE_UNSIGNED (type))
encoding = DW_ATE_unsigned_char;
  else
encoding = DW_ATE_signed_char;
@@ -25201,6 +25215,13 @@ gen_compile_unit_die (const char *filename)
 }
   else if (strcmp (language_string, "GNU F77") == 0)
 language = DW_LANG_Fortran77;
+  else if (strcmp (language_string, "GNU Rust") == 0)
+{
+  if (dwarf_version >= 5 || !dwarf_strict)
+   language = DW_LANG_Rust;
+  else
+   language = DW_LANG_Rust_old;
+}
   else if (dwarf_version >= 3 || !dwarf_strict)
 {
   if (strcmp (language_string, "GNU Ada") == 0)
-- 
2.25.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[PATCH Rust front-end v2 09/37] gccrs: Add Lexer for Rust front-end

2022-08-24 Thread herron . philip
From: The Other 

The lexer is refered to as a ManagedTokenSource within the parser, this
lexer does not currently support unicode but serves as a starting point
to do so.

Co-authored-by: Philip Herron 
Co-authored-by: Arthur Cohen 
Co-authored-by: Mark Wielaard 
---
 gcc/rust/lex/rust-codepoint.h  |   46 +
 gcc/rust/lex/rust-lex.cc   | 2729 
 gcc/rust/lex/rust-lex.h|  271 
 gcc/rust/lex/rust-token.cc |  135 ++
 gcc/rust/lex/rust-token.h  |  455 ++
 gcc/rust/rust-buffered-queue.h |  204 +++
 6 files changed, 3840 insertions(+)
 create mode 100644 gcc/rust/lex/rust-codepoint.h
 create mode 100644 gcc/rust/lex/rust-lex.cc
 create mode 100644 gcc/rust/lex/rust-lex.h
 create mode 100644 gcc/rust/lex/rust-token.cc
 create mode 100644 gcc/rust/lex/rust-token.h
 create mode 100644 gcc/rust/rust-buffered-queue.h

diff --git a/gcc/rust/lex/rust-codepoint.h b/gcc/rust/lex/rust-codepoint.h
new file mode 100644
index 000..22da080bbb2
--- /dev/null
+++ b/gcc/rust/lex/rust-codepoint.h
@@ -0,0 +1,46 @@
+// 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
+// .
+
+#ifndef RUST_CODEPOINT_H
+#define RUST_CODEPOINT_H
+
+#include 
+
+namespace Rust {
+struct Codepoint
+{
+  uint32_t value;
+
+  // Creates a zero codepoint.
+  Codepoint () : value (0) {}
+
+  // Creates a codepoint from an encoded UTF-8 value.
+  Codepoint (uint32_t value) : value (value) {}
+
+  static Codepoint eof () { return Codepoint (UINT32_MAX); }
+  bool is_eof () const { return value == UINT32_MAX; }
+
+  // Returns a C++ string containing string value of codepoint.
+  std::string as_string ();
+
+  bool operator== (Codepoint other) const { return value == other.value; }
+  bool operator!= (Codepoint other) const { return !operator== (other); }
+};
+} // namespace Rust
+
+#endif
diff --git a/gcc/rust/lex/rust-lex.cc b/gcc/rust/lex/rust-lex.cc
new file mode 100644
index 000..70e6b50209f
--- /dev/null
+++ b/gcc/rust/lex/rust-lex.cc
@@ -0,0 +1,2729 @@
+// 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
+// .
+
+#include "rust-lex.h"
+
+#include "rust-system.h"  // for rust_assert and rust_unreachable
+#include "rust-diagnostics.h" // for rust_error_at
+#include "rust-linemap.h"
+#include "rust-session-manager.h"
+#include "safe-ctype.h"
+
+namespace Rust {
+// TODO: move to separate compilation unit?
+// overload += for uint32_t to allow 32-bit encoded utf-8 to be added
+std::string &
+operator+= (std::string &str, Codepoint char32)
+{
+  if (char32.value < 0x80)
+{
+  str += static_cast (char32.value);
+}
+  else if (char32.value < (0x1F + 1) << (1 * 6))
+{
+  str += static_cast (0xC0 | ((char32.value >> 6) & 0x1F));
+  str += static_cast (0x80 | ((char32.value >> 0) & 0x3F));
+}
+  else if (char32.value < (0x0F + 1) << (2 * 6))
+{
+  str += static_cast (0xE0 | ((char32.value >> 12) & 0x0F));
+  str += static_cast (0x80 | ((char32.value >> 6) & 0x3F));
+  str += static_cast (0x80 | ((char32.value >> 0) & 0x3F));
+}
+  else if (char32.value < (0x07 + 1) << (3 * 6))
+{
+  str += static_cast (0xF0 | ((char32.value >> 18) & 0x07));
+  str += static_cast (0x80 | ((char32.value >> 12) & 0x3F));
+  str += static_cast (0x80 | ((char32.value >> 6) & 0x3F));
+  str += static_cast (0x80 | ((char32.value >> 0) & 0x3F));
+}
+  else
+{
+  rust_debug ("Invalid unicode codepoint found: '%u' ", char32.value);
+}
+  return str;
+}
+
+std::string
+Codepoint::as_string ()
+{
+  std::string str;
+
+  // str += Codepoint (value);
+  str += *this;
+
+  return str;
+}
+
+/* Includes all allowable

Rust frontend patches v2

2022-08-24 Thread herron . philip
This is the 2nd patch set for gccrs, since v1 we have dropped the changes
for target hooks which are not nessecary for us right now. This now
focuses directly on the front-end the only patch that affects GCC now is a
tweak to debug info. Note we are close to merging our port of the C++
constexpr code into our front-end but this patch set does not include this
yet.

Thanks to Open Source Security, inc and Embecosm for sponsoring this work.
Special thanks to all of those who have contributed thus far.

See our branch over on 
https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/devel/rust/master

We are currently testing on every commit the following systems:

- Debian i386 - all tests passing
- Debian testing-x86_64 - all tests passing
- Fedora arm64 - all tests passing
- Fedora X86_64 - all tests passing
- OpenSUSE Leap X86_64 - all tests passing
- OpenSUSE tw X86_64 - all tests passing
- Rawhide X86_64 - all tests passing
- macos x86_64 - all tests passing
- Debian ppc64 - some tests failing
- Fedora ppc64le - some tests failing
- Fedora s390x - some tests failing

The patch set is as follows:

[PATCH Rust front-end v2 01/37] Use DW_ATE_UTF for the Rust 'char'
[PATCH Rust front-end v2 02/37] gccrs: Add nessecary hooks for a Rust
[PATCH Rust front-end v2 03/37] gccrs: Add Debug info testsuite
[PATCH Rust front-end v2 04/37] gccrs: Add link cases testsuite
[PATCH Rust front-end v2 05/37] gccrs: Add general compilation test
[PATCH Rust front-end v2 06/37] gccrs: Add execution test cases
[PATCH Rust front-end v2 07/37] gccrs: Add gcc-check-target
[PATCH Rust front-end v2 08/37] gccrs: Add the Rust front-end AST
[PATCH Rust front-end v2 09/37] gccrs: Add Lexer for Rust front-end
[PATCH Rust front-end v2 10/37] gccrs: Add Parser for Rust front-end
[PATCH Rust front-end v2 11/37] gccrs: Add expansion pass for the
[PATCH Rust front-end v2 12/37] gccrs: Add name resolution pass to
[PATCH Rust front-end v2 13/37] gccrs: Add second intermedite
[PATCH Rust front-end v2 14/37] gccrs: Add AST to HIR lowering pass
[PATCH Rust front-end v2 15/37] gccrs: Add wrapper for make_unique
[PATCH Rust front-end v2 16/37] gccrs: Add port of FNV hash used
[PATCH Rust front-end v2 17/37] gccrs: Add Rust ABI enum helpers
[PATCH Rust front-end v2 18/37] gccrs: Add Base62 implementation
[PATCH Rust front-end v2 19/37] gccrs: Add implementation of Optional
[PATCH Rust front-end v2 20/37] gccrs: Add attributes checker
[PATCH Rust front-end v2 21/37] gccrs: Add helpers mappings canonical
[PATCH Rust front-end v2 22/37] gccrs: Add type resolution and trait
[PATCH Rust front-end v2 23/37] gccrs: Add unsafe checks for Rust
[PATCH Rust front-end v2 24/37] gccrs: Add const checker
[PATCH Rust front-end v2 25/37] gccrs: Add privacy checks
[PATCH Rust front-end v2 26/37] gccrs: Add dead code scan on HIR
[PATCH Rust front-end v2 27/37] gccrs: Add unused variable scan
[PATCH Rust front-end v2 28/37] gccrs: Add metadata ouptput pass
[PATCH Rust front-end v2 29/37] gccrs: HIR to GCC GENERIC lowering
[PATCH Rust front-end v2 30/37] gccrs: These are wrappers ported from
[PATCH Rust front-end v2 31/37] gccrs: Add GCC Rust front-end
[PATCH Rust front-end v2 32/37] gccrs: Add config-lang.in
[PATCH Rust front-end v2 33/37] gccrs: add lang-spec.h
[PATCH Rust front-end v2 34/37] gccrs: add lang.opt
[PATCH Rust front-end v2 35/37] gccrs: add compiler driver
[PATCH Rust front-end v2 36/37] gccrs: compiler proper interface
[PATCH Rust front-end v2 37/37] gccrs: Add README, CONTRIBUTING and

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[PATCH Rust front-end v2 03/37] gccrs: Add Debug info testsuite

2022-08-24 Thread herron . philip
From: Philip Herron 

This testsuite is specifically about testcases which scan the asm debug
info for results.

Co-authored-by: Tom Tromey 
---
 gcc/testsuite/rust/debug/chartype.rs  | 10 ++
 .../rust/debug/custom_link_section.rs | 13 
 gcc/testsuite/rust/debug/debug.exp| 33 +++
 gcc/testsuite/rust/debug/i8u8.rs  | 12 +++
 gcc/testsuite/rust/debug/lang.rs  |  6 
 gcc/testsuite/rust/debug/no_mangle.rs | 17 ++
 gcc/testsuite/rust/debug/oldlang.rs   |  6 
 gcc/testsuite/rust/debug/tuple.rs |  8 +
 gcc/testsuite/rust/debug/win64-abi.rs | 11 +++
 9 files changed, 116 insertions(+)
 create mode 100644 gcc/testsuite/rust/debug/chartype.rs
 create mode 100644 gcc/testsuite/rust/debug/custom_link_section.rs
 create mode 100644 gcc/testsuite/rust/debug/debug.exp
 create mode 100644 gcc/testsuite/rust/debug/i8u8.rs
 create mode 100644 gcc/testsuite/rust/debug/lang.rs
 create mode 100644 gcc/testsuite/rust/debug/no_mangle.rs
 create mode 100644 gcc/testsuite/rust/debug/oldlang.rs
 create mode 100644 gcc/testsuite/rust/debug/tuple.rs
 create mode 100644 gcc/testsuite/rust/debug/win64-abi.rs

diff --git a/gcc/testsuite/rust/debug/chartype.rs 
b/gcc/testsuite/rust/debug/chartype.rs
new file mode 100644
index 000..69e7ab0b17f
--- /dev/null
+++ b/gcc/testsuite/rust/debug/chartype.rs
@@ -0,0 +1,10 @@
+// 'char' should use DW_ATE_UTF
+fn main () {
+let c = 'x';
+// { dg-do compile }
+// Use -w to avoid warnings about the unused variables
+// DW_ATE_UTF entered in DWARF 4.
+// { dg-options "-w -gdwarf-4 -dA" }
+// DW_ATE_UTF = 0x10
+// { dg-final { scan-assembler "0x10\[ \t]\[^\n\r]* DW_AT_encoding" } } */
+}
diff --git a/gcc/testsuite/rust/debug/custom_link_section.rs 
b/gcc/testsuite/rust/debug/custom_link_section.rs
new file mode 100644
index 000..142f3513136
--- /dev/null
+++ b/gcc/testsuite/rust/debug/custom_link_section.rs
@@ -0,0 +1,13 @@
+#[link_section = ".universe"]
+fn not_in_text() -> i32 {
+42
+}
+
+fn main() -> i32 {
+// { dg-do compile }
+// { dg-options "-gdwarf-5 -dA -w" }
+not_in_text();
+// { dg-final { scan-assembler ".universe" } } */
+
+0
+}
diff --git a/gcc/testsuite/rust/debug/debug.exp 
b/gcc/testsuite/rust/debug/debug.exp
new file mode 100644
index 000..c71b5930d90
--- /dev/null
+++ b/gcc/testsuite/rust/debug/debug.exp
@@ -0,0 +1,33 @@
+# Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+# This program 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 of the License, or
+# (at your option) any later version.
+# 
+# This program 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
+# .
+
+# Debugging tests.
+
+# Load support procs.
+load_lib rust-dg.exp
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+set saved-dg-do-what-default ${dg-do-what-default}
+
+set dg-do-what-default "compile"
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.rs]] "" ""
+set dg-do-what-default ${saved-dg-do-what-default}
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/rust/debug/i8u8.rs b/gcc/testsuite/rust/debug/i8u8.rs
new file mode 100644
index 000..1cd21a4a8ff
--- /dev/null
+++ b/gcc/testsuite/rust/debug/i8u8.rs
@@ -0,0 +1,12 @@
+// i8 and u8 types should not have the DWARF 'char' encoding.
+fn main () {
+let x : i8 = 5;
+let y : u8 = 7;
+// { dg-do compile }
+// Use -w to avoid warnings about the unused variables
+// { dg-options "-w -g -dA" }
+// DW_ATE_signed_char = 6
+// { dg-final { scan-assembler-not "0x6\[ \t]\[^\n\r]* DW_AT_encoding" } } */
+// DW_ATE_unsigned_char = 8
+// { dg-final { scan-assembler-not "0x8\[ \t]\[^\n\r]* DW_AT_encoding" } } */
+}
diff --git a/gcc/testsuite/rust/debug/lang.rs b/gcc/testsuite/rust/debug/lang.rs
new file mode 100644
index 000..12e0b587a02
--- /dev/null
+++ b/gcc/testsuite/rust/debug/lang.rs
@@ -0,0 +1,6 @@
+fn main () {
+// { dg-do compile }
+// { dg-options "-gdwarf-5 -dA" }
+// DW_LANG_Rust is 0x1c
+// { dg-final { scan-assembler "0x1c\[ \t]\[^\n\r]* DW_AT_language" } } */
+}
diff --git a/gcc/testsuite/rust/debug/no_mangle.rs 
b/gcc/testsuite/rust/debug/no_mangle.rs
new file mode 100644
index 000..0cef40482f4
--- /dev/null
+++ b/gcc/testsuite/rust/debug/no_mangle.rs
@@ -0,0 +1,17 @@
+#[no_mangle]
+fn do_not_mangle() -> i32 {
+0 
+}
+
+fn please_mangle() {}
+
+fn main() {
+// { dg-do compile }
+// { dg-options "-gdwarf-5 -dA" }
+let _ = do_not_mangle();
+please_mangle();
+// look for 

[PATCH Rust front-end v2 07/37] gccrs: Add gcc-check-target check-rust

2022-08-24 Thread herron . philip
From: Philip Herron 

This allows us to invoke the rust testsuite.

ChangeLog:
* Makefile.def: Add autogen target
* Makefile.in: regenerate via autogen
---
 Makefile.def | 1 +
 Makefile.in  | 8 
 2 files changed, 9 insertions(+)

diff --git a/Makefile.def b/Makefile.def
index 3291b126b26..821016af3a2 100644
--- a/Makefile.def
+++ b/Makefile.def
@@ -681,6 +681,7 @@ languages = { language=go;  gcc-check-target=check-go;
 languages = { language=d;  gcc-check-target=check-d;
lib-check-target=check-target-libphobos; };
 languages = { language=jit;gcc-check-target=check-jit; };
+languages = { language=rust;   gcc-check-target=check-rust; };
 
 // Toplevel bootstrap
 bootstrap_stage = { id=1 ; };
diff --git a/Makefile.in b/Makefile.in
index 1919dfee829..9ed2c0dec52 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -60583,6 +60583,14 @@ check-gcc-jit:
(cd gcc && $(MAKE) $(GCC_FLAGS_TO_PASS) check-jit);
 check-jit: check-gcc-jit
 
+.PHONY: check-gcc-rust check-rust
+check-gcc-rust:
+   r=`${PWD_COMMAND}`; export r; \
+   s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+   $(HOST_EXPORTS) \
+   (cd gcc && $(MAKE) $(GCC_FLAGS_TO_PASS) check-rust);
+check-rust: check-gcc-rust
+
 
 # The gcc part of install-no-fixedincludes, which relies on an intimate
 # knowledge of how a number of gcc internal targets (inter)operate.  Delegate.
-- 
2.25.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[PATCH Rust front-end v2 16/37] gccrs: Add port of FNV hash used during legacy symbol mangling

2022-08-24 Thread herron . philip
From: Philip Herron 

This hash was ported from the go runime as we needed a hash for the legacy
symbol mangling system. Which means all symbols in Rust contain a hash of
some metadata for uniqueness on generic functions.
---
 gcc/rust/util/fnv-hash.h | 95 
 1 file changed, 95 insertions(+)
 create mode 100644 gcc/rust/util/fnv-hash.h

diff --git a/gcc/rust/util/fnv-hash.h b/gcc/rust/util/fnv-hash.h
new file mode 100644
index 000..78e54c99411
--- /dev/null
+++ b/gcc/rust/util/fnv-hash.h
@@ -0,0 +1,95 @@
+// 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
+// .
+
+#ifndef RUST_FNV_HASH_H
+#define RUST_FNV_HASH_H
+
+namespace Rust {
+namespace Hash {
+
+const uint64_t offset128Lower = 0x62b821756295c58d;
+const uint64_t offset128Higher = 0x6c62272e07bb0142;
+const uint64_t prime128Lower = 0x13b;
+const uint64_t prime128Shift = 24;
+
+// ported from https://github.com/golang/go/blob/master/src/hash/fnv/fnv.go
+class FNV128
+{
+public:
+  FNV128 () { reset (); }
+
+  void reset ()
+  {
+buf[0] = offset128Higher;
+buf[1] = offset128Lower;
+  }
+
+  void write (const unsigned char *in, size_t len)
+  {
+for (size_t i = 0; i < len; i++)
+  {
+   unsigned char c = in[i];
+
+   // 
https://stackoverflow.com/questions/28868367/getting-the-high-part-of-64-bit-integer-multiplication
+   uint64_t a = prime128Lower;
+   uint64_t b = buf[1];
+
+   uint64_t a_lo = (uint32_t) a;
+   uint64_t a_hi = a >> 32;
+   uint64_t b_lo = (uint32_t) b;
+   uint64_t b_hi = b >> 32;
+
+   uint64_t a_x_b_hi = a_hi * b_hi;
+   uint64_t a_x_b_mid = a_hi * b_lo;
+   uint64_t b_x_a_mid = b_hi * a_lo;
+   uint64_t a_x_b_lo = a_lo * b_lo;
+
+   uint64_t carry_bit
+ = ((uint64_t) (uint32_t) a_x_b_mid + (uint64_t) (uint32_t) b_x_a_mid
++ (a_x_b_lo >> 32))
+   >> 32;
+
+   uint64_t multhi
+ = a_x_b_hi + (a_x_b_mid >> 32) + (b_x_a_mid >> 32) + carry_bit;
+
+   uint64_t s0 = multhi; // high
+   uint64_t s1 = prime128Lower * buf[1]; // low
+
+   s0 += buf[1] << (prime128Shift + prime128Lower * buf[0]);
+
+   // Update the values
+   buf[1] = s1;
+   buf[0] = s0;
+   buf[1] ^= (uint64_t) c;
+  }
+  }
+
+  void sum (uint64_t *hi, uint64_t *lo) const
+  {
+*hi = buf[0];
+*lo = buf[1];
+  }
+
+private:
+  uint64_t buf[2];
+};
+
+} // namespace Hash
+} // namespace Rust
+
+#endif // RUST_FNV_HASH_H
-- 
2.25.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[PATCH Rust front-end v2 17/37] gccrs: Add Rust ABI enum helpers

2022-08-24 Thread herron . philip
From: Philip Herron 

This is a simple helper over an enum of possible ABI options in Rust.
---
 gcc/rust/util/rust-abi.cc | 72 +++
 gcc/rust/util/rust-abi.h  | 45 
 2 files changed, 117 insertions(+)
 create mode 100644 gcc/rust/util/rust-abi.cc
 create mode 100644 gcc/rust/util/rust-abi.h

diff --git a/gcc/rust/util/rust-abi.cc b/gcc/rust/util/rust-abi.cc
new file mode 100644
index 000..6477c3790af
--- /dev/null
+++ b/gcc/rust/util/rust-abi.cc
@@ -0,0 +1,72 @@
+// 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
+// .
+
+#include "rust-abi.h"
+
+namespace Rust {
+
+Rust::ABI
+get_abi_from_string (const std::string &abi)
+{
+  if (abi.compare ("rust") == 0)
+return Rust::ABI::RUST;
+  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;
+  else if (abi.compare ("sysv64") == 0)
+return Rust::ABI::SYSV64;
+  else if (abi.compare ("win64") == 0)
+return Rust::ABI::WIN64;
+
+  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::SYSV64:
+  return "sysv64";
+case Rust::ABI::WIN64:
+  return "win64";
+
+case Rust::ABI::UNKNOWN:
+  return "unknown";
+}
+  return "unknown";
+}
+
+} // namespace Rust
diff --git a/gcc/rust/util/rust-abi.h b/gcc/rust/util/rust-abi.h
new file mode 100644
index 000..d794cc35fb3
--- /dev/null
+++ b/gcc/rust/util/rust-abi.h
@@ -0,0 +1,45 @@
+// 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
+// .
+
+#ifndef RUST_ABI_OPTIONS_H
+#define RUST_ABI_OPTIONS_H
+
+#include "rust-system.h"
+
+namespace Rust {
+
+enum ABI
+{
+  UNKNOWN,
+  RUST,
+  INTRINSIC,
+  C,
+  CDECL,
+  STDCALL,
+  FASTCALL,
+  WIN64,
+  SYSV64
+};
+
+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
-- 
2.25.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[PATCH Rust front-end v2 18/37] gccrs: Add Base62 implementation

2022-08-24 Thread herron . philip
From: Arthur Cohen 

Used for V0 symbol mangling scheme which.
---
 gcc/rust/util/rust-base62.cc | 46 
 gcc/rust/util/rust-base62.h  | 34 ++
 2 files changed, 80 insertions(+)
 create mode 100644 gcc/rust/util/rust-base62.cc
 create mode 100644 gcc/rust/util/rust-base62.h

diff --git a/gcc/rust/util/rust-base62.cc b/gcc/rust/util/rust-base62.cc
new file mode 100644
index 000..bdab23338c3
--- /dev/null
+++ b/gcc/rust/util/rust-base62.cc
@@ -0,0 +1,46 @@
+// 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
+// .
+
+#include "rust-base62.h"
+
+namespace Rust {
+
+std::string
+base62_integer (uint64_t value)
+{
+  const static std::string base_64
+= "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@$";
+  std::string buffer (128, '\0');
+  size_t idx = 0;
+  size_t base = 62;
+
+  do
+{
+  buffer[idx] = base_64[(value % base)];
+  idx++;
+  value = value / base;
+}
+  while (value != 0);
+
+  std::reverse (buffer.begin (), buffer.begin () + idx);
+  return buffer.substr (0, idx);
+}
+
+} // namespace Rust
+
+// FIXME: Add unit testing using the selftest framework
diff --git a/gcc/rust/util/rust-base62.h b/gcc/rust/util/rust-base62.h
new file mode 100644
index 000..fa610d3e5a4
--- /dev/null
+++ b/gcc/rust/util/rust-base62.h
@@ -0,0 +1,34 @@
+// 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
+// .
+
+#ifndef RUST_BASE62_H
+#define RUST_BASE62_H
+
+#include "rust-system.h"
+
+namespace Rust {
+
+/**
+ * Get the Base62 representation of an integer
+ */
+std::string
+base62_integer (uint64_t value);
+
+} // namespace Rust
+
+#endif /* !RUST_BASE62_H */
-- 
2.25.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[PATCH Rust front-end v2 19/37] gccrs: Add implementation of Optional

2022-08-24 Thread herron . philip
From: Arthur Cohen 

Add an Optional class to improve error handling
---
 gcc/rust/util/rust-optional-test.cc | 111 +++
 gcc/rust/util/rust-optional.h   | 278 
 2 files changed, 389 insertions(+)
 create mode 100644 gcc/rust/util/rust-optional-test.cc
 create mode 100644 gcc/rust/util/rust-optional.h

diff --git a/gcc/rust/util/rust-optional-test.cc 
b/gcc/rust/util/rust-optional-test.cc
new file mode 100644
index 000..9d5b4ba5735
--- /dev/null
+++ b/gcc/rust/util/rust-optional-test.cc
@@ -0,0 +1,111 @@
+// 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
+// .
+
+#include "rust-optional.h"
+
+#include "config.h"
+#include "selftest.h"
+
+#if CHECKING_P
+
+static void
+rust_optional_create ()
+{
+  auto opt = Rust::Optional::some (15);
+
+  ASSERT_TRUE (opt.is_some ());
+  ASSERT_EQ (opt.get (), 15);
+
+  Rust::Optional const_opt = Rust::Optional::some (15);
+  const int &value = const_opt.get ();
+
+  ASSERT_EQ (value, 15);
+}
+
+static void
+rust_optional_operators ()
+{
+  auto opt = Rust::Optional::some (15);
+
+  // as bool
+  ASSERT_TRUE (opt);
+
+  // deref
+  ASSERT_EQ (*opt, 15);
+
+  class Methodable
+  {
+  public:
+int method () { return 15; }
+  };
+
+  auto m_opt = Rust::Optional::some (Methodable ());
+  ASSERT_EQ (m_opt->method (), 15);
+}
+
+static void
+rust_optional_take ()
+{
+  auto opt = Rust::Optional::some (15);
+  auto value = opt.take ();
+
+  ASSERT_EQ (value, 15);
+  ASSERT_TRUE (opt.is_none ());
+}
+
+static void
+rust_optional_map ()
+{
+  auto opt = Rust::Optional::some (15);
+  auto twice = opt.map ([] (int value) { return value * 2; });
+
+  ASSERT_FALSE (opt);
+  ASSERT_TRUE (twice);
+  ASSERT_EQ (*twice, 30);
+}
+
+static void
+rust_optional_reference ()
+{
+  auto value = std::vector ();
+  value.emplace_back ("rust");
+  value.emplace_back ("+");
+  value.emplace_back ("gcc");
+  value.emplace_back ("=");
+  value.emplace_back ("<3");
+
+  auto opt = Rust::Optional &>::some (value);
+
+  ASSERT_EQ (opt->at (0), "rust");
+  ASSERT_EQ (opt->at (2), "gcc");
+}
+
+#endif /* #if CHECKING_P */
+
+void
+rust_optional_test ()
+{
+#if CHECKING_P
+  rust_optional_create ();
+  rust_optional_operators ();
+  rust_optional_take ();
+  rust_optional_map ();
+  rust_optional_reference ();
+
+#endif /* #if CHECKING_P */
+}
diff --git a/gcc/rust/util/rust-optional.h b/gcc/rust/util/rust-optional.h
new file mode 100644
index 000..56465400250
--- /dev/null
+++ b/gcc/rust/util/rust-optional.h
@@ -0,0 +1,278 @@
+// 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
+// .
+
+#ifndef RUST_OPTIONAL_H
+#define RUST_OPTIONAL_H
+
+#include "config.h"
+#include "rust-system.h"
+
+#include "selftest.h"
+
+namespace Rust {
+
+/**
+ * Tagged union to try and simulate a sum type. This is safer and more 
ergonomic
+ * than one of the two alternatives we're currently using in the compiler:
+ *
+ * 1. Storing a raw pointer, which can be `nullptr` or valid
+ *
+ * This is wildly unsafe, and usable in conjunction with local references, 
stack
+ * variables, or pointers managed elsewhere, which can cause crashes, hard to
+ * debug issues or undefined behavior. Likewise, if you do not check for the
+ * pointer's validity, this will cause a crash.
+ *
+ * 2. Storing an extra boolean alongside the object
+ *
+ * This causes implementors to use a "dummy object": Either an empty version or
+ * an error version. But what happens if what you really wanted to store was
+ * the empty or error version? You can also easily incorporate logic bugs if 
you
+ * forget to check for the associated boolean.
+ *
+ * The `Optional` type has the same "

[PATCH Rust front-end v2 28/37] gccrs: Add metadata ouptput pass

2022-08-24 Thread herron . philip
From: Philip Herron 

Extern crates statements to tell the front-end to look for another library.
The mechanism here is heavily inspired from gccgo, so when we compile a
library for example we invoke:

  gccrs -g -O2 -frust-crate=mylib -c src/lib.rs -o src/mylib.o

All going well this object file will now contain extra data inside
.rust-export section inside the object file which will be preserved inside
archives and shared objects. When we have another application which uses
this library 'mylib'.

  extern crate mylib;
  use mylib::foo;

  fn main() {
foo();
  }

We compile using:

  gcc -g -O2 -frust-crate=test -c src/main.rs -o src/main.o

When the extern crate line is hit the front-end will look for mylib.o,
libmylib.a, mylib.rox. If it finds a raw object file it will read the
.rust-export section directly from the object for the public metadata
such as public functions, types constants etc. If it fails to find an
object it might find .rox which is the objdump of the .rust-export to a
raw file, it might even find libmylib.a and read the export directly out
of the archive file reusing code from gccgo to do so.

The full compiler pipeline is reused here, so the metatadata is actually
just real rust code. The benifit here is that Rust supports exporting,
macros and generics so this requires the name-resolution and type info
all to be generated and inserted into the apropriate context classes. Since
the metadata is real rust code it means we can reuse the full pipeline to
generate the code as nessecary. So for the simple case of a public struct
we simply emit the AST dump of this struct directly into the metadata. If
its a non-generic public function we emit and extern rust abi block for
that function. If its a trait we can simply emit the trait with the public
memebers. Generics are more complicated since we need to emit the function
fully for it to be compiled correctly this still needs tests to be added.
The hardest part is non generic impl blocks which is still a WIP.

To finally link the two crates together you run:

  gcc -g -O2 -o rust-program.exe src/main.o src/mylib.o
---
 gcc/rust/metadata/rust-export-metadata.cc | 385 ++
 gcc/rust/metadata/rust-export-metadata.h  |  85 +++
 gcc/rust/metadata/rust-extern-crate.cc| 173 +
 gcc/rust/metadata/rust-extern-crate.h |  55 ++
 gcc/rust/metadata/rust-import-archive.cc  | 885 ++
 gcc/rust/metadata/rust-imports.cc | 441 +++
 gcc/rust/metadata/rust-imports.h  | 257 +++
 gcc/rust/rust-object-export.cc| 177 +
 gcc/rust/rust-object-export.h |  33 +
 9 files changed, 2491 insertions(+)
 create mode 100644 gcc/rust/metadata/rust-export-metadata.cc
 create mode 100644 gcc/rust/metadata/rust-export-metadata.h
 create mode 100644 gcc/rust/metadata/rust-extern-crate.cc
 create mode 100644 gcc/rust/metadata/rust-extern-crate.h
 create mode 100644 gcc/rust/metadata/rust-import-archive.cc
 create mode 100644 gcc/rust/metadata/rust-imports.cc
 create mode 100644 gcc/rust/metadata/rust-imports.h
 create mode 100644 gcc/rust/rust-object-export.cc
 create mode 100644 gcc/rust/rust-object-export.h

diff --git a/gcc/rust/metadata/rust-export-metadata.cc 
b/gcc/rust/metadata/rust-export-metadata.cc
new file mode 100644
index 000..4856bc26149
--- /dev/null
+++ b/gcc/rust/metadata/rust-export-metadata.cc
@@ -0,0 +1,385 @@
+// 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
+// .
+
+#include "rust-export-metadata.h"
+#include "rust-hir-visitor.h"
+#include "rust-hir-full.h"
+#include "rust-hir-map.h"
+#include "rust-ast-dump.h"
+#include "rust-abi.h"
+#include "rust-object-export.h"
+
+#include "md5.h"
+
+namespace Rust {
+namespace Metadata {
+
+static const std::string extension_path = ".rox";
+
+ExportContext::ExportContext () : mappings (Analysis::Mappings::get ()) {}
+
+ExportContext::~ExportContext () {}
+
+void
+ExportContext::push_module_scope (const HIR::Module &module)
+{
+  module_stack.push_back (module);
+}
+
+const HIR::Module &
+ExportContext::pop_module_scope ()
+{
+  rust_assert (!module_stack.empty ());
+  const HIR::Module &poped = module_stack.back ();
+  module_stack.pop_back ();
+  return poped;
+}
+
+void
+ExportContext::emit_trait (const HIR::Trait &trait)
+{
+  // lookup the AST node for th

[PATCH Rust front-end v2 15/37] gccrs: Add wrapper for make_unique

2022-08-24 Thread herron . philip
From: Philip Herron 

This is a wrapper for make_unique we can likely get rid of this as there
are other implementations available or simply keep using the unique_ptr
constructor.
---
 gcc/rust/util/rust-make-unique.h | 35 
 1 file changed, 35 insertions(+)
 create mode 100644 gcc/rust/util/rust-make-unique.h

diff --git a/gcc/rust/util/rust-make-unique.h b/gcc/rust/util/rust-make-unique.h
new file mode 100644
index 000..f33f9125f89
--- /dev/null
+++ b/gcc/rust/util/rust-make-unique.h
@@ -0,0 +1,35 @@
+// 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
+// .
+
+#ifndef RUST_MAKE_UNIQUE_H
+#define RUST_MAKE_UNIQUE_H
+
+#include 
+
+namespace Rust {
+
+template 
+std::unique_ptr
+make_unique (Ts &&... params)
+{
+  return std::unique_ptr (new T (std::forward (params)...));
+}
+
+} // namespace Rust
+
+#endif // RUST_MAKE_UNIQUE_H
-- 
2.25.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[PATCH Rust front-end v2 21/37] gccrs: Add helpers mappings canonical path and lang items

2022-08-24 Thread herron . philip
From: Philip Herron 

These are various helper classes used in the compiler pipeline.
---
 gcc/rust/util/rust-canonical-path.h   | 195 +
 gcc/rust/util/rust-common.h   |  53 ++
 gcc/rust/util/rust-hir-map.cc | 980 ++
 gcc/rust/util/rust-hir-map.h  | 356 ++
 gcc/rust/util/rust-identifier.h   |  49 ++
 gcc/rust/util/rust-lang-item.h| 377 ++
 gcc/rust/util/rust-mapping-common.h   |  85 +++
 gcc/rust/util/rust-stacked-contexts.h |  86 +++
 8 files changed, 2181 insertions(+)
 create mode 100644 gcc/rust/util/rust-canonical-path.h
 create mode 100644 gcc/rust/util/rust-common.h
 create mode 100644 gcc/rust/util/rust-hir-map.cc
 create mode 100644 gcc/rust/util/rust-hir-map.h
 create mode 100644 gcc/rust/util/rust-identifier.h
 create mode 100644 gcc/rust/util/rust-lang-item.h
 create mode 100644 gcc/rust/util/rust-mapping-common.h
 create mode 100644 gcc/rust/util/rust-stacked-contexts.h

diff --git a/gcc/rust/util/rust-canonical-path.h 
b/gcc/rust/util/rust-canonical-path.h
new file mode 100644
index 000..54cc0390849
--- /dev/null
+++ b/gcc/rust/util/rust-canonical-path.h
@@ -0,0 +1,195 @@
+// 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
+// .
+
+#ifndef RUST_CANONICAL_PATH
+#define RUST_CANONICAL_PATH
+
+#include "rust-system.h"
+#include "rust-mapping-common.h"
+
+namespace Rust {
+namespace Resolver {
+
+// https://doc.rust-lang.org/reference/paths.html#canonical-paths
+//
+// struct X - path X
+// impl X { fn test - path X::test }
+//
+// struct X - path X
+//
+// impl X   { fn test - path X::test}
+// impl X { fn test - path X::test }
+// impl X { fn test - path X::test }
+//
+// pub trait Trait { // ::a::Trait
+//   fn f(&self); // ::a::Trait::f
+// }
+//
+// impl Trait for Struct {
+//fn f(&self) {} // <::a::Struct as ::a::Trait>::f
+// }
+class CanonicalPath
+{
+public:
+  CanonicalPath (const CanonicalPath &other) : segs (other.segs) {}
+
+  CanonicalPath &operator= (const CanonicalPath &other)
+  {
+segs = other.segs;
+return *this;
+  }
+
+  static CanonicalPath new_seg (NodeId id, const std::string &path)
+  {
+rust_assert (!path.empty ());
+return CanonicalPath ({std::pair (id, path)},
+ UNKNOWN_CREATENUM);
+  }
+
+  static CanonicalPath
+  trait_impl_projection_seg (NodeId id, const CanonicalPath &trait_seg,
+const CanonicalPath &impl_type_seg)
+  {
+return CanonicalPath::new_seg (id, "<" + impl_type_seg.get () + " as "
++ trait_seg.get () + ">");
+  }
+
+  std::string get () const
+  {
+std::string buf;
+for (size_t i = 0; i < segs.size (); i++)
+  {
+   bool have_more = (i + 1) < segs.size ();
+   const std::string &seg = segs.at (i).second;
+   buf += seg + (have_more ? "::" : "");
+  }
+return buf;
+  }
+
+  static CanonicalPath get_big_self (NodeId id)
+  {
+return CanonicalPath::new_seg (id, "Self");
+  }
+
+  static CanonicalPath create_empty ()
+  {
+return CanonicalPath ({}, UNKNOWN_CREATENUM);
+  }
+
+  bool is_empty () const { return segs.size () == 0; }
+
+  CanonicalPath append (const CanonicalPath &other) const
+  {
+rust_assert (!other.is_empty ());
+if (is_empty ())
+  return CanonicalPath (other.segs, crate_num);
+
+std::vector> copy (segs);
+for (auto &s : other.segs)
+  copy.push_back (s);
+
+return CanonicalPath (copy, crate_num);
+  }
+
+  // if we have the path A::B::C this will give a callback for each segment
+  // including the prefix, example:
+  //
+  // path:
+  //   A::B::C
+  //
+  // iterate:
+  //   A
+  //   A::B
+  //   A::B::C
+  void iterate (std::function cb) const
+  {
+std::vector> buf;
+for (auto &seg : segs)
+  {
+   buf.push_back (seg);
+   if (!cb (CanonicalPath (buf, crate_num)))
+ return;
+  }
+  }
+
+  // if we have the path A::B::C this will give a callback for each segment
+  // example:
+  //
+  // path:
+  //   A::B::C
+  //
+  // iterate:
+  //   A
+  //  B
+  // C
+  void iterate_segs (std::function cb) const
+  {
+for (auto &seg : segs)
+  {
+   std::vector> buf;
+   buf.push_back ({seg.first, seg.second});
+   if (!cb (CanonicalPath (buf, crate_num)))

[PATCH Rust front-end v2 20/37] gccrs: Add attributes checker

2022-08-24 Thread herron . philip
From: Arthur Cohen 

The attribute checker is responsible for checking the validity of various
attributes including built-in ones. It is currently unfinished and will
receive some modifications, as well as become the host of some existing
code in the compiler which needs to be refactored. One of its
responsibilities is to make sure that arguments given to built-in
attributes are correct, or contain the correct type of information. This
visitor also checks that an attribute is allowed to be used in the current
particular context.
---
 gcc/rust/util/rust-attributes.cc | 839 +++
 gcc/rust/util/rust-attributes.h  | 270 ++
 2 files changed, 1109 insertions(+)
 create mode 100644 gcc/rust/util/rust-attributes.cc
 create mode 100644 gcc/rust/util/rust-attributes.h

diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
new file mode 100644
index 000..bf4bb2fbfe9
--- /dev/null
+++ b/gcc/rust/util/rust-attributes.cc
@@ -0,0 +1,839 @@
+// 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
+// .
+
+#include "rust-attributes.h"
+#include "rust-ast.h"
+#include "rust-ast-full.h"
+#include "rust-diagnostics.h"
+#include "safe-ctype.h"
+
+namespace Rust {
+namespace Analysis {
+
+// 
https://doc.rust-lang.org/stable/nightly-rustc/src/rustc_feature/builtin_attrs.rs.html#248
+static const BuiltinAttrDefinition __definitions[] = {
+  {"inline", CODE_GENERATION},
+  {"cold", CODE_GENERATION},
+  {"cfg", EXPANSION},
+  {"cfg_attr", EXPANSION},
+  {"deprecated", STATIC_ANALYSIS},
+  {"allow", STATIC_ANALYSIS},
+  {"doc", HIR_LOWERING},
+  {"must_use", STATIC_ANALYSIS},
+  {"lang", HIR_LOWERING},
+  {"link_section", CODE_GENERATION},
+  {"no_mangle", CODE_GENERATION},
+  {"repr", CODE_GENERATION},
+  {"path", EXPANSION},
+};
+
+BuiltinAttributeMappings *
+BuiltinAttributeMappings::get ()
+{
+  static BuiltinAttributeMappings *instance = nullptr;
+  if (instance == nullptr)
+instance = new BuiltinAttributeMappings ();
+
+  return instance;
+}
+
+const BuiltinAttrDefinition &
+BuiltinAttributeMappings::lookup_builtin (const std::string &attr_name) const
+{
+  auto it = mappings.find (attr_name);
+  if (it == mappings.end ())
+return BuiltinAttrDefinition::error_node ();
+
+  return it->second;
+}
+
+BuiltinAttributeMappings::BuiltinAttributeMappings ()
+{
+  size_t ndefinitions = sizeof (__definitions) / sizeof 
(BuiltinAttrDefinition);
+  for (size_t i = 0; i < ndefinitions; i++)
+{
+  const BuiltinAttrDefinition &def = __definitions[i];
+  mappings.insert ({def.name, def});
+}
+}
+
+AttributeChecker::AttributeChecker () {}
+
+void
+AttributeChecker::go (AST::Crate &crate)
+{
+  check_attributes (crate.get_inner_attrs ());
+
+  for (auto &item : crate.items)
+item->accept_vis (*this);
+}
+
+static bool
+is_builtin (const AST::Attribute &attribute, BuiltinAttrDefinition &builtin)
+{
+  auto &segments = attribute.get_path ().get_segments ();
+
+  // Builtin attributes always have a single segment. This avoids us creating
+  // strings all over the place and performing a linear search in the builtins
+  // map
+  if (segments.size () != 1)
+return false;
+
+  builtin = BuiltinAttributeMappings::get ()->lookup_builtin (
+segments.at (0).get_segment_name ());
+
+  return !builtin.is_error ();
+}
+
+/**
+ * Check that the string given to #[doc(alias = ...)] or #[doc(alias(...))] is
+ * valid.
+ *
+ * This means no whitespace characters other than spaces and no quoting
+ * characters.
+ */
+static void
+check_doc_alias (const std::string &alias_input, const Location &locus)
+{
+  // FIXME: The locus here is for the whole attribute. Can we get the locus
+  // of the alias input instead?
+  for (auto c : alias_input)
+if ((ISSPACE (c) && c != ' ') || c == '\'' || c == '\"')
+  {
+   auto to_print = std::string (1, c);
+   switch (c)
+ {
+ case '\n':
+   to_print = "\\n";
+   break;
+ case '\t':
+   to_print = "\\t";
+   break;
+ default:
+   break;
+ }
+   rust_error_at (locus,
+  "invalid character used in %<#[doc(alias)]%> input: %qs",
+  to_print.c_str ());
+  }
+
+  if (alias_input.empty ())
+return;
+
+  if (alias_input.front 

[PATCH Rust front-end v2 23/37] gccrs: Add unsafe checks for Rust

2022-08-24 Thread herron . philip
From: Arthur Cohen 

The UnsafeChecker visitor verifies that unsafe actions are only performed
in unsafe contexts. Otherwise, an error should be reported to the user and
the compilation pipeline should be halted. These contexts, which include
unsafe blocks or unsafe functions, are allowed to perform more actions
than regular safe Rust code. These actions currently include:

- Dereferencing raw pointers
- Calls to unsafe functions
- Use of inline assembly
- Use of mutable static
- Use of extern static
- Access to a union's field
- Call to functions with #[target(feature)] attribute
- Initializing type with rustc_layout_scalar_valid_range attribute
- Mutation of layout constrained field
- Borrow of layout constrained field
---
 gcc/rust/checks/errors/rust-unsafe-checker.cc | 963 ++
 gcc/rust/checks/errors/rust-unsafe-checker.h  | 191 
 2 files changed, 1154 insertions(+)
 create mode 100644 gcc/rust/checks/errors/rust-unsafe-checker.cc
 create mode 100644 gcc/rust/checks/errors/rust-unsafe-checker.h

diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc 
b/gcc/rust/checks/errors/rust-unsafe-checker.cc
new file mode 100644
index 000..e3f32539562
--- /dev/null
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc
@@ -0,0 +1,963 @@
+// 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
+// .
+
+#include "rust-unsafe-checker.h"
+#include "rust-hir.h"
+#include "rust-hir-expr.h"
+#include "rust-hir-stmt.h"
+#include "rust-hir-item.h"
+
+namespace Rust {
+namespace HIR {
+
+UnsafeChecker::UnsafeChecker ()
+  : context (*Resolver::TypeCheckContext::get ()),
+resolver (*Resolver::Resolver::get ()),
+mappings (*Analysis::Mappings::get ())
+{}
+
+void
+UnsafeChecker::go (HIR::Crate &crate)
+{
+  for (auto &item : crate.items)
+item->accept_vis (*this);
+}
+
+static void
+check_static_mut (HIR::Item *maybe_static, Location locus)
+{
+  if (maybe_static->get_hir_kind () == Node::BaseKind::VIS_ITEM)
+{
+  auto item = static_cast (maybe_static);
+  if (item->get_item_kind () == Item::ItemKind::Static)
+   {
+ auto static_item = static_cast (item);
+ if (static_item->is_mut ())
+   rust_error_at (
+ locus, "use of mutable static requires unsafe function or block");
+   }
+}
+}
+
+static void
+check_extern_static (HIR::ExternalItem *maybe_static, Location locus)
+{
+  if (maybe_static->get_extern_kind () == ExternalItem::ExternKind::Static)
+rust_error_at (locus,
+  "use of extern static requires unsafe function or block");
+}
+
+void
+UnsafeChecker::check_use_of_static (HirId node_id, Location locus)
+{
+  if (unsafe_context.is_in_context ())
+return;
+
+  auto maybe_static_mut = mappings.lookup_hir_item (node_id);
+
+  HirId extern_block;
+  auto maybe_extern_static
+= mappings.lookup_hir_extern_item (node_id, &extern_block);
+
+  if (maybe_static_mut)
+check_static_mut (maybe_static_mut, locus);
+
+  if (maybe_extern_static)
+check_extern_static (static_cast (maybe_extern_static),
+locus);
+}
+
+static void
+check_unsafe_call (HIR::Function *fn, Location locus, const std::string &kind)
+{
+  if (fn->get_qualifiers ().is_unsafe ())
+rust_error_at (locus, "call to unsafe %s requires unsafe function or 
block",
+  kind.c_str ());
+}
+
+static bool
+is_safe_intrinsic (const std::string &fn_name)
+{
+  static const std::unordered_set safe_intrinsics = {
+"abort",
+"size_of",
+"min_align_of",
+"needs_drop",
+"caller_location",
+"add_with_overflow",
+"sub_with_overflow",
+"mul_with_overflow",
+"wrapping_add",
+"wrapping_sub",
+"wrapping_mul",
+"saturating_add",
+"saturating_sub",
+"rotate_left",
+"rotate_right",
+"ctpop",
+"ctlz",
+"cttz",
+"bswap",
+"bitreverse",
+"discriminant_value",
+"type_id",
+"likely",
+"unlikely",
+"ptr_guaranteed_eq",
+"ptr_guaranteed_ne",
+"minnumf32",
+"minnumf64",
+"maxnumf32",
+"rustc_peek",
+"maxnumf64",
+"type_name",
+"forget",
+"black_box",
+"variant_count",
+  };
+
+  return safe_intrinsics.find (fn_name) != safe_intrinsics.end ();
+}
+
+static void
+check_extern_call (HIR::ExternalItem *maybe_fn, HIR::ExternBlock *paren

[PATCH Rust front-end v2 24/37] gccrs: Add const checker

2022-08-24 Thread herron . philip
From: Arthur Cohen 

Similarly to the unsafe checker, constant evaluation can only be performed
in a few contexts and include restrictions on the Rust language. Should
the user fail to uphold those conditions, errors will be reported and the
compilation pipeline interrupted.

These contexts are as follow:

- Array type length expressions
- Array repeat length expressions
- Constants
- Statics
- Enum discriminants
- Const generic arguments

In these contexts, the user is restricted to calling only functions marked
as `const` or perform arithmetic operations only on certain types, among
other restrictions.
---
 gcc/rust/checks/errors/rust-const-checker.cc | 844 +++
 gcc/rust/checks/errors/rust-const-checker.h  | 189 +
 2 files changed, 1033 insertions(+)
 create mode 100644 gcc/rust/checks/errors/rust-const-checker.cc
 create mode 100644 gcc/rust/checks/errors/rust-const-checker.h

diff --git a/gcc/rust/checks/errors/rust-const-checker.cc 
b/gcc/rust/checks/errors/rust-const-checker.cc
new file mode 100644
index 000..35c61fe03f0
--- /dev/null
+++ b/gcc/rust/checks/errors/rust-const-checker.cc
@@ -0,0 +1,844 @@
+// 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
+// .
+
+#include "rust-const-checker.h"
+#include "rust-hir.h"
+#include "rust-hir-expr.h"
+#include "rust-hir-stmt.h"
+#include "rust-hir-item.h"
+
+namespace Rust {
+namespace HIR {
+
+ConstChecker::ConstChecker ()
+  : resolver (*Resolver::Resolver::get ()),
+mappings (*Analysis::Mappings::get ())
+{}
+
+void
+ConstChecker::go (HIR::Crate &crate)
+{
+  for (auto &item : crate.items)
+item->accept_vis (*this);
+}
+
+bool
+ConstChecker::is_const_extern_fn (HIR::ExternalFunctionItem &fn)
+{
+  // FIXME: Is it really how we want to handle `rustc_const_stable`
+  // and `rustc_const_unstable`?
+  // TODO: Add these attributes to the attribute check and handle
+  // `stable` and `unstable` as well
+  return std::any_of (
+fn.get_outer_attrs ().begin (), fn.get_outer_attrs ().end (),
+[] (const AST::Attribute &attr) {
+  // `starts_with` in C++11...
+  return attr.get_path ().as_string ().rfind ("rustc_const_", 0) == 0;
+});
+}
+
+void
+ConstChecker::visit (Lifetime &lifetime)
+{}
+
+void
+ConstChecker::visit (LifetimeParam &lifetime_param)
+{}
+
+void
+ConstChecker::visit (PathInExpression &path)
+{}
+
+void
+ConstChecker::visit (TypePathSegment &segment)
+{}
+
+void
+ConstChecker::visit (TypePathSegmentGeneric &segment)
+{}
+
+void
+ConstChecker::visit (TypePathSegmentFunction &segment)
+{}
+
+void
+ConstChecker::visit (TypePath &path)
+{}
+
+void
+ConstChecker::visit (QualifiedPathInExpression &path)
+{}
+
+void
+ConstChecker::visit (QualifiedPathInType &path)
+{}
+
+void
+ConstChecker::visit (LiteralExpr &expr)
+{}
+
+void
+ConstChecker::visit (BorrowExpr &expr)
+{
+  expr.get_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (DereferenceExpr &expr)
+{
+  expr.get_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (ErrorPropagationExpr &expr)
+{
+  expr.get_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (NegationExpr &expr)
+{
+  expr.get_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (ArithmeticOrLogicalExpr &expr)
+{
+  expr.get_lhs ()->accept_vis (*this);
+  expr.get_rhs ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (ComparisonExpr &expr)
+{
+  expr.get_lhs ()->accept_vis (*this);
+  expr.get_rhs ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (LazyBooleanExpr &expr)
+{
+  expr.get_lhs ()->accept_vis (*this);
+  expr.get_rhs ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (TypeCastExpr &expr)
+{
+  expr.get_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (AssignmentExpr &expr)
+{
+  expr.get_lhs ()->accept_vis (*this);
+  expr.get_rhs ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (CompoundAssignmentExpr &expr)
+{
+  expr.get_left_expr ()->accept_vis (*this);
+  expr.get_right_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (GroupedExpr &expr)
+{
+  expr.get_expr_in_parens ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (ArrayElemsValues &elems)
+{
+  for (auto &elem : elems.get_values ())
+elem->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (ArrayElemsCopied &elems)
+{
+  elems.get_elem_to_copy ()->accept_

[PATCH Rust front-end v2 25/37] gccrs: Add privacy checks

2022-08-24 Thread herron . philip
From: Arthur Cohen 

This pass is responsible for resolving the privacy of items and verifying
that access to these items is performed within the limits of that privacy.
By default, items in Rust are private and only public to the current
module and its submodules. However, the user can annotate an item with
various qualifiers such as `pub` to publicly expose an item. Furthermore,
a module path can be given to `pub` to restrict an item's privacy to a
certain module: These paths need to be resolved and later on checked by
the privacy error reporter.
---
 .../errors/privacy/rust-privacy-check.cc  |  63 ++
 .../errors/privacy/rust-privacy-check.h   |  44 +
 .../errors/privacy/rust-privacy-common.h  |  67 ++
 .../checks/errors/privacy/rust-privacy-ctx.cc |  93 +++
 .../checks/errors/privacy/rust-privacy-ctx.h  |  79 ++
 .../errors/privacy/rust-privacy-reporter.cc   | 753 ++
 .../errors/privacy/rust-privacy-reporter.h| 173 
 .../privacy/rust-pub-restricted-visitor.cc| 182 +
 .../privacy/rust-pub-restricted-visitor.h | 120 +++
 .../errors/privacy/rust-reachability.cc   | 236 ++
 .../checks/errors/privacy/rust-reachability.h |  87 ++
 .../privacy/rust-visibility-resolver.cc   | 245 ++
 .../errors/privacy/rust-visibility-resolver.h | 103 +++
 13 files changed, 2245 insertions(+)
 create mode 100644 gcc/rust/checks/errors/privacy/rust-privacy-check.cc
 create mode 100644 gcc/rust/checks/errors/privacy/rust-privacy-check.h
 create mode 100644 gcc/rust/checks/errors/privacy/rust-privacy-common.h
 create mode 100644 gcc/rust/checks/errors/privacy/rust-privacy-ctx.cc
 create mode 100644 gcc/rust/checks/errors/privacy/rust-privacy-ctx.h
 create mode 100644 gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
 create mode 100644 gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
 create mode 100644 
gcc/rust/checks/errors/privacy/rust-pub-restricted-visitor.cc
 create mode 100644 gcc/rust/checks/errors/privacy/rust-pub-restricted-visitor.h
 create mode 100644 gcc/rust/checks/errors/privacy/rust-reachability.cc
 create mode 100644 gcc/rust/checks/errors/privacy/rust-reachability.h
 create mode 100644 gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc
 create mode 100644 gcc/rust/checks/errors/privacy/rust-visibility-resolver.h

diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-check.cc 
b/gcc/rust/checks/errors/privacy/rust-privacy-check.cc
new file mode 100644
index 000..9664d62f65c
--- /dev/null
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-check.cc
@@ -0,0 +1,63 @@
+// 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
+// .
+
+#include "rust-privacy-check.h"
+#include "rust-reachability.h"
+#include "rust-hir-type-check.h"
+#include "rust-hir-map.h"
+#include "rust-name-resolver.h"
+#include "rust-visibility-resolver.h"
+#include "rust-pub-restricted-visitor.h"
+#include "rust-privacy-reporter.h"
+
+extern bool
+saw_errors (void);
+
+namespace Rust {
+namespace Privacy {
+
+void
+Resolver::resolve (HIR::Crate &crate)
+{
+  PrivacyContext ctx;
+  auto mappings = Analysis::Mappings::get ();
+  auto resolver = Rust::Resolver::Resolver::get ();
+  auto ty_ctx = ::Rust::Resolver::TypeCheckContext::get ();
+
+  VisibilityResolver (*mappings, *resolver).go (crate);
+  PubRestrictedVisitor (*mappings).go (crate);
+  PrivacyReporter (*mappings, *resolver, *ty_ctx).go (crate);
+
+  auto visitor = ReachabilityVisitor (ctx, *ty_ctx);
+
+  const auto &items = crate.items;
+
+  for (auto &item : items)
+{
+  if (item->get_hir_kind () == HIR::Node::VIS_ITEM)
+   {
+ auto vis_item = static_cast (item.get ());
+ vis_item->accept_vis (visitor);
+   }
+}
+
+  if (saw_errors ())
+return;
+}
+} // namespace Privacy
+} // namespace Rust
diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-check.h 
b/gcc/rust/checks/errors/privacy/rust-privacy-check.h
new file mode 100644
index 000..290b5eacb6c
--- /dev/null
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-check.h
@@ -0,0 +1,44 @@
+// 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 Foundat

[PATCH Rust front-end v2 27/37] gccrs: Add unused variable scan

2022-08-24 Thread herron . philip
From: Philip Herron 

This is a simple walk_tree which acts on the monomorphized code. By walking
the compiled translation unit of functions.
---
 gcc/rust/checks/lints/rust-lint-unused-var.cc | 98 +++
 gcc/rust/checks/lints/rust-lint-unused-var.h  | 36 +++
 2 files changed, 134 insertions(+)
 create mode 100644 gcc/rust/checks/lints/rust-lint-unused-var.cc
 create mode 100644 gcc/rust/checks/lints/rust-lint-unused-var.h

diff --git a/gcc/rust/checks/lints/rust-lint-unused-var.cc 
b/gcc/rust/checks/lints/rust-lint-unused-var.cc
new file mode 100644
index 000..d4317e53280
--- /dev/null
+++ b/gcc/rust/checks/lints/rust-lint-unused-var.cc
@@ -0,0 +1,98 @@
+// Copyright (C) 2021-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
+// .
+
+#include "rust-lint-unused-var.h"
+#include "print-tree.h"
+
+namespace Rust {
+namespace Analysis {
+
+static void
+check_decl (tree *t)
+{
+  rust_assert (TREE_CODE (*t) == VAR_DECL || TREE_CODE (*t) == PARM_DECL
+  || TREE_CODE (*t) == CONST_DECL);
+
+  tree var_name = DECL_NAME (*t);
+  const char *var_name_ptr = IDENTIFIER_POINTER (var_name);
+  bool starts_with_under_score = strncmp (var_name_ptr, "_", 1) == 0;
+
+  bool is_constant = TREE_CODE (*t) == CONST_DECL;
+  // if (!is_constant)
+  //   {
+  // debug_tree (*t);
+  // rust_debug ("found var-decl: used %s artifical %s underscore %s name
+  // %s",
+  // TREE_USED (*t) ? "true" : "false",
+  // DECL_ARTIFICIAL (*t) ? "true" : "false",
+  // starts_with_under_score ? "true" : "false", var_name_ptr);
+  //   }
+
+  if (!TREE_USED (*t) && !DECL_ARTIFICIAL (*t) && !starts_with_under_score)
+{
+  warning_at (DECL_SOURCE_LOCATION (*t),
+ is_constant ? OPT_Wunused_const_variable_
+ : OPT_Wunused_variable,
+ "unused name %qE", *t);
+}
+}
+
+static tree
+unused_var_walk_fn (tree *t, int *walk_subtrees, void *closure)
+{
+  switch (TREE_CODE (*t))
+{
+case VAR_DECL:
+case CONST_DECL:
+  check_decl (t);
+  break;
+
+default:
+  break;
+}
+  return NULL_TREE;
+}
+
+void
+UnusedVariables::Lint (Compile::Context &ctx)
+{
+  for (auto &fndecl : ctx.get_func_decls ())
+{
+  for (tree p = DECL_ARGUMENTS (fndecl); p != NULL_TREE; p = DECL_CHAIN 
(p))
+   {
+ check_decl (&p);
+   }
+
+  walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl),
+   &unused_var_walk_fn, &ctx);
+}
+
+  for (auto &var : ctx.get_var_decls ())
+{
+  tree t = ctx.get_backend ()->var_expression (var, Location ());
+  check_decl (&t);
+}
+
+  for (auto &const_decl : ctx.get_const_decls ())
+{
+  check_decl (&const_decl);
+}
+}
+
+} // namespace Analysis
+} // namespace Rust
diff --git a/gcc/rust/checks/lints/rust-lint-unused-var.h 
b/gcc/rust/checks/lints/rust-lint-unused-var.h
new file mode 100644
index 000..6fabfeff01b
--- /dev/null
+++ b/gcc/rust/checks/lints/rust-lint-unused-var.h
@@ -0,0 +1,36 @@
+// Copyright (C) 2021-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
+// .
+
+#ifndef RUST_LINT_UNUSED_VAR
+#define RUST_LINT_UNUSED_VAR
+
+#include "rust-compile-context.h"
+
+namespace Rust {
+namespace Analysis {
+
+class UnusedVariables
+{
+public:
+  static void Lint (Compile::Context &ctx);
+};
+
+} // namespace Analysis
+} // namespace Rust
+
+#endif // RUST_LINT_UNUSED_VAR
-- 
2.25.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[PATCH Rust front-end v2 30/37] gccrs: These are wrappers ported from reusing gccgo

2022-08-24 Thread herron . philip
From: Philip Herron 

The wrappers over linemap and location will eventually disappear here but
served as a useful starting point for us. We have wrappers over the
diagnostics system which we might be able to get rid of as well.
---
 gcc/rust/rust-diagnostics.cc | 244 +++
 gcc/rust/rust-diagnostics.h  | 154 +++
 gcc/rust/rust-gcc-diagnostics.cc |  84 +++
 gcc/rust/rust-linemap.cc | 229 +
 gcc/rust/rust-linemap.h  | 163 +
 gcc/rust/rust-location.h | 105 +
 gcc/rust/rust-system.h   |  86 +++
 7 files changed, 1065 insertions(+)
 create mode 100644 gcc/rust/rust-diagnostics.cc
 create mode 100644 gcc/rust/rust-diagnostics.h
 create mode 100644 gcc/rust/rust-gcc-diagnostics.cc
 create mode 100644 gcc/rust/rust-linemap.cc
 create mode 100644 gcc/rust/rust-linemap.h
 create mode 100644 gcc/rust/rust-location.h
 create mode 100644 gcc/rust/rust-system.h

diff --git a/gcc/rust/rust-diagnostics.cc b/gcc/rust/rust-diagnostics.cc
new file mode 100644
index 000..c2d3e4ee8be
--- /dev/null
+++ b/gcc/rust/rust-diagnostics.cc
@@ -0,0 +1,244 @@
+// rust-diagnostics.cc -- GCC implementation of rust diagnostics interface.
+// Copyright (C) 2016-2022 Free Software Foundation, Inc.
+// Contributed by Than McIntosh, Google.
+
+// 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
+// .
+
+#include "rust-system.h"
+#include "rust-diagnostics.h"
+
+static std::string
+mformat_value ()
+{
+  return std::string (xstrerror (errno));
+}
+
+// Rewrite a format string to expand any extensions not
+// supported by sprintf(). See comments in rust-diagnostics.h
+// for list of supported format specifiers.
+
+static std::string
+expand_format (const char *fmt)
+{
+  std::stringstream ss;
+  for (const char *c = fmt; *c; ++c)
+{
+  if (*c != '%')
+   {
+ ss << *c;
+ continue;
+   }
+  c++;
+  switch (*c)
+   {
+ case '\0': {
+   // malformed format string
+   rust_unreachable ();
+ }
+ case '%': {
+   ss << "%";
+   break;
+ }
+ case 'm': {
+   ss << mformat_value ();
+   break;
+ }
+ case '<': {
+   ss << rust_open_quote ();
+   break;
+ }
+ case '>': {
+   ss << rust_close_quote ();
+   break;
+ }
+ case 'q': {
+   ss << rust_open_quote ();
+   c++;
+   if (*c == 'm')
+ {
+   ss << mformat_value ();
+ }
+   else
+ {
+   ss << "%" << *c;
+ }
+   ss << rust_close_quote ();
+   break;
+ }
+ default: {
+   ss << "%" << *c;
+ }
+   }
+}
+  return ss.str ();
+}
+
+// Expand message format specifiers, using a combination of
+// expand_format above to handle extensions (ex: %m, %q) and vasprintf()
+// to handle regular printf-style formatting. A pragma is being used here to
+// suppress this warning:
+//
+//   warning: function ‘std::__cxx11::string expand_message(const char*,
+//   __va_list_tag*)’ might be a candidate for ‘gnu_printf’ format attribute
+//   [-Wsuggest-attribute=format]
+//
+// What appears to be happening here is that the checker is deciding that
+// because of the call to vasprintf() (which has attribute gnu_printf), the
+// calling function must need to have attribute gnu_printf as well, even
+// though there is already an attribute declaration for it.
+
+static std::string
+expand_message (const char *fmt, va_list ap) RUST_ATTRIBUTE_GCC_DIAG (1, 0);
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
+
+static std::string
+expand_message (const char *fmt, va_list ap)
+{
+  char *mbuf = 0;
+  std::string expanded_fmt = expand_format (fmt);
+  int nwr = vasprintf (&mbuf, expanded_fmt.c_str (), ap);
+  if (nwr == -1)
+{
+  // memory allocation failed
+  rust_be_error_at (Linemap::unknown_location (),
+   "memory allocation failed in vasprintf");
+  rust_assert (0);
+}
+  std::string rval = std::string (mbuf);
+  free (mbuf);
+  return rval;
+}
+
+#pragma GCC diagnostic pop
+
+static const char *cached_open_quote = NULL;
+s

[PATCH Rust front-end v2 33/37] gccrs: add lang-spec.h

2022-08-24 Thread herron . philip
From: Philip Herron 

This specifies the extensions of the Rust language.
---
 gcc/rust/lang-specs.h | 26 ++
 1 file changed, 26 insertions(+)
 create mode 100644 gcc/rust/lang-specs.h

diff --git a/gcc/rust/lang-specs.h b/gcc/rust/lang-specs.h
new file mode 100644
index 000..9b14a559dd6
--- /dev/null
+++ b/gcc/rust/lang-specs.h
@@ -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
+   .  */
+
+/* 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},
-- 
2.25.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[PATCH Rust front-end v2 26/37] gccrs: Add dead code scan on HIR

2022-08-24 Thread herron . philip
From: Thomas Young 

In order to find dead code we use a depth first search and keep liveness
variables, after type resolution. In this case, if a function is unused
and it calls another function the 2nd function is now unused since the
caller is not used etc. The algorithm is a depth first search.
---
 .../checks/lints/rust-lint-marklive-base.h|  45 +++
 gcc/rust/checks/lints/rust-lint-marklive.cc   | 282 
 gcc/rust/checks/lints/rust-lint-marklive.h| 308 ++
 .../checks/lints/rust-lint-scan-deadcode.h| 154 +
 4 files changed, 789 insertions(+)
 create mode 100644 gcc/rust/checks/lints/rust-lint-marklive-base.h
 create mode 100644 gcc/rust/checks/lints/rust-lint-marklive.cc
 create mode 100644 gcc/rust/checks/lints/rust-lint-marklive.h
 create mode 100644 gcc/rust/checks/lints/rust-lint-scan-deadcode.h

diff --git a/gcc/rust/checks/lints/rust-lint-marklive-base.h 
b/gcc/rust/checks/lints/rust-lint-marklive-base.h
new file mode 100644
index 000..97c068188b1
--- /dev/null
+++ b/gcc/rust/checks/lints/rust-lint-marklive-base.h
@@ -0,0 +1,45 @@
+// Copyright (C) 2021-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
+// .
+
+#ifndef RUST_HIR_LIVENESS_BASE
+#define RUST_HIR_LIVENESS_BASE
+
+#include "rust-diagnostics.h"
+#include "rust-lint-marklive.h"
+#include "rust-lint-marklive-base.h"
+#include "rust-hir-visitor.h"
+#include "rust-hir-map.h"
+
+namespace Rust {
+namespace Analysis {
+
+class MarkLiveBase : public HIR::HIRFullVisitorBase
+{
+public:
+  virtual ~MarkLiveBase () {}
+
+protected:
+  MarkLiveBase () : mappings (Analysis::Mappings::get ()) {}
+
+  Analysis::Mappings *mappings;
+};
+
+} // namespace Analysis
+} // namespace Rust
+
+#endif
diff --git a/gcc/rust/checks/lints/rust-lint-marklive.cc 
b/gcc/rust/checks/lints/rust-lint-marklive.cc
new file mode 100644
index 000..245632b4b4c
--- /dev/null
+++ b/gcc/rust/checks/lints/rust-lint-marklive.cc
@@ -0,0 +1,282 @@
+// Copyright (C) 2021-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
+// .
+
+// The idea is that all reachable symbols are live, codes called
+// from live codes are live, and everything else is dead.
+
+#include "rust-lint-marklive.h"
+#include "rust-hir-full.h"
+#include "rust-name-resolver.h"
+
+namespace Rust {
+namespace Analysis {
+
+// This class trys to find the live symbols which can be used as
+// seeds in MarkLive
+//
+// 1. TODO: explicit live
+//- Attribute like #[allow(dead_code)]
+//- Attribute like #[lang=".."], it's not a intra-crate item.
+// 2. TODO: foreign item
+class FindEntryPoint : public MarkLiveBase
+{
+  using Rust::Analysis::MarkLiveBase::visit;
+
+public:
+  static std::vector find (HIR::Crate &crate)
+  {
+FindEntryPoint findEntryPoint;
+for (auto it = crate.items.begin (); it != crate.items.end (); it++)
+  {
+   it->get ()->accept_vis (findEntryPoint);
+  }
+return findEntryPoint.getEntryPoint ();
+  }
+
+  // TODO not only fn main can be a entry point.
+  void visit (HIR::Function &function) override
+  {
+if (function.get_function_name () == "main")
+  {
+   entryPoints.push_back (function.get_mappings ().get_hirid ());
+  }
+  }
+
+private:
+  FindEntryPoint () : MarkLiveBase () {}
+  std::vector entryPoints;
+  std::vector getEntryPoint () { return entryPoints; }
+};
+
+std::set
+MarkLive::Analysis (HIR::Crate &crate)
+{
+  MarkLive marklive (FindEntryPoint::find (crate));
+  marklive.go (crate);
+
+  return marklive.liveSymbols;
+}
+
+// pop a live symbol from worklist every iteration,
+// if it's a function then walk the function body, and
+// 1. save all the live symbols in worklist which is
+//visi

[PATCH Rust front-end v2 32/37] gccrs: Add config-lang.in

2022-08-24 Thread herron . philip
From: Philip Herron 

This was a copy paste from gccgo front-end, we do not use any of the
target_libs yet but we will need these when we support the libpanic crate.
---
 gcc/rust/config-lang.in | 34 ++
 1 file changed, 34 insertions(+)
 create mode 100644 gcc/rust/config-lang.in

diff --git a/gcc/rust/config-lang.in b/gcc/rust/config-lang.in
new file mode 100644
index 000..d2ff376032a
--- /dev/null
+++ b/gcc/rust/config-lang.in
@@ -0,0 +1,34 @@
+# 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
+# .
+
+# 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"
+
+target_libs="target-libffi target-libbacktrace"
+
+gtfiles="\$(srcdir)/rust/rust-lang.cc"
-- 
2.25.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[PATCH Rust front-end v2 35/37] gccrs: add compiler driver

2022-08-24 Thread herron . philip
From: Philip Herron 

Our compiler driver is pretty simple so far, the key piece to enforce is
that a compilation unit in Rust is the whole crate so the process for
compiling rust means pointing the compiler at the main entry point such as
src/lib.rs or src/main.rs where the expansion pass takes over loading the
other source files to include them in the crate.
---
 gcc/rust/rustspec.cc | 191 +++
 1 file changed, 191 insertions(+)
 create mode 100644 gcc/rust/rustspec.cc

diff --git a/gcc/rust/rustspec.cc b/gcc/rust/rustspec.cc
new file mode 100644
index 000..b05f8ae5454
--- /dev/null
+++ b/gcc/rust/rustspec.cc
@@ -0,0 +1,191 @@
+/* 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
+.  */
+
+#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;
+
+  /* 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;
+
+  /* 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_l:
+ if (strcmp (arg, "c") == 0)
+   args[i] |= WITHLIBC;
+ 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 (first_rust_file == NULL)
+   {
+ int len;
+
+ len = strlen (arg);
+ if (len > 3 && strcmp (arg + len - 3, ".rs") == 0)
+   first_rust_file = arg;
+   }
+ else
+   {
+ // FIXME: ARTHUR: Do we want to error here? If there's already one
+ // file?
+ // How do we error here? Do we want to instead just handle that in
+ // the session manager?
+   }
+
+ 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 * 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))
+   {
+ --j;
+ saw_libc = &decoded_options[i];
+   }
+
+  if ((args[i] & SKIPOPT) != 0)
+   --j

[PATCH Rust front-end v2 37/37] gccrs: Add README, CONTRIBUTING and compiler logo

2022-08-24 Thread herron . philip
From: Philip Herron 

We still need to write out documentation section but these README's will
help in the mean time.
---
 gcc/rust/CONTRIBUTING.md | 130 +++
 gcc/rust/README.md   | 264 +++
 gcc/rust/logo.png| Bin 0 -> 70864 bytes
 3 files changed, 394 insertions(+)
 create mode 100644 gcc/rust/CONTRIBUTING.md
 create mode 100644 gcc/rust/README.md
 create mode 100644 gcc/rust/logo.png

diff --git a/gcc/rust/CONTRIBUTING.md b/gcc/rust/CONTRIBUTING.md
new file mode 100644
index 000..20e499c29e1
--- /dev/null
+++ b/gcc/rust/CONTRIBUTING.md
@@ -0,0 +1,130 @@
+## How to contribute to GCC Rust
+
+ **Did you find a bug?**
+
+* **Ensure the bug was not already reported** by searching on GitHub under 
[Issues](https://github.com/Rust-GCC/gccrs/issues).
+
+* If you're unable to find an open issue addressing the problem, [open a new 
one](https://github.com/Rust-GCC/gccrs/issues/new). 
+  Be sure to include a **title and clear description**, as much relevant 
information as possible, and a **code sample** 
+  or an **executable test case** demonstrating the expected behavior that is 
not occurring.
+
+ **Do you want to submit a patch?**
+
+* Open a new GitHub pull request with the patch.
+
+* Ensure the PR description clearly describes the problem and solution. 
Include the relevant issue number if applicable.
+
+* Before submitting, GCC development requires copyright assignment or the 
Developer's Certificate of Origin sign-off.
+   Please see the [Contributing to GCC](https://gcc.gnu.org/contribute.html) 
guide or [Developer's Certificate of Origin (DCO) 
Sign-off](https://gcc.gnu.org/dco.html) guide.
+
+* Patches sent to the [`gcc-rust` mailing 
list](https://gcc.gnu.org/mailman/listinfo/gcc-rust) are likewise welcome.
+These will be imported into a GitHub PR to follow the normal review process, 
+and the link to the GitHub PR sent to the submitter.
+
+ **Do you intend to add a new feature or change an existing one?**
+
+* Suggest your change in the [Zulip](https://gcc-rust.zulipchat.com/) and 
start writing code.
+
+* Do not open an issue on GitHub until you have collected positive feedback 
about the change. 
+  GitHub issues are primarily intended for bug reports and fixes.
+
+ **Do you have questions about the source code?**
+
+* Ask any question about how to use GCCRS in 
[Zulip](https://gcc-rust.zulipchat.com/).
+
+### **PR Policy**
+
+* The PR policy: Everything has to go through a PR
+  - An exception to this rule will be the merge commits of updating the repo 
against upstream GCC
+
+* Reviewers/Maintainers of the project (aka people who have bors rights) 
should be pinged for reviews/questions.
+
+* A PR can have one or several commits (split should have a technical/logical 
reason, ie. no fixup-ish commit)
+
+* Avoid PR's with merge commit unless there's a good reason
+
+* Where possible please add test cases to `gcc/testsuite/rust/` for all PRs. 
+  Some issues may not be testable via dejagnu/automation such as debug dump 
changes.
+
+* Follow the [GCC coding style](https://gcc.gnu.org/codingconventions.html) 
(see `clang-format` below).
+
+* PRs won't be merged until the build and tests pass.
+
+* Please take the time to create good git commit messages. 
+  See the existing format of them in the git log or refer to something like: 
https://chris.beams.io/posts/git-commit/
+
+ Running `clang-format` locally
+
+* on all files using python scripts
+... corresponding to what the _Clang Format Lint_ 
(`.github/workflows/clang-format.yml`) 
+is doing, with `clang-format-10` being available locally, and avoiding the 
Docker overhead.
+
+```shell
+$ wget 
'https://github.com/DoozyX/clang-format-lint-action/raw/v0.11/run-clang-format.py'
+$ cp contrib/clang-format .clang-format
+$ python3 run-clang-format.py --clang-format-executable clang-format-10 
--recursive --extensions h,cc gcc/rust/
+```
+
+* on a given patch using python scripts
+See the [clang-format 
documentation](https://clang.llvm.org/docs/ClangFormat.html#script-for-patch-reformatting)
 :
+
+$ git diff -U0 --no-color HEAD^ | clang-format-diff.py -i -p1
+
+* using `git` interface
+
+At least on Debian and its derivative, each `clang-format` packages also comes
+with `git-clang-format` command that can be used easily. It applies on staged
+changes, and any modification can be seen as unstaged changes:
+
+```diff
+$ git diff --cached
+diff --git a/gcc/rust/rust-abi.h b/gcc/rust/rust-abi.h
+index bd3043295ce..9559374ce60 100644
+--- a/gcc/rust/rust-abi.h
 b/gcc/rust/rust-abi.h
+@@ -22,10 +22,10 @@ namespace Rust {
+ enum ABI
+ {
+   UNKNOWN,
+-  RUST,
++ RUST,
+   INTRINSIC,
+   C,
+-  CDECL,
++ CDECL,
+   STDCALL,
+   FASTCALL,
+ };
+ 
+gccrs/gcc/rust on  dkm/clang_format [$!+?]
+❯ git clang-format
+changed files:
+gcc/rust/rust-abi.h
+ 
+gccrs/gcc/rust on  dkm/clang_format [$!+?]
+$ git diff rust-abi.h
+diff --git a/gcc/rust/rust-abi.h

[PATCH Rust front-end v2 34/37] gccrs: add lang.opt

2022-08-24 Thread herron . philip
From: Philip Herron 

We have some rust specific langugage options note -fwrapv is enabled by
default in the code. We are trying to respect options such as
-Wunused-result which we get by porting over c++ no-discard for rust's
must-use attribute, so we have enabled these by default directly here.
---
 gcc/rust/lang.opt | 118 ++
 1 file changed, 118 insertions(+)
 create mode 100644 gcc/rust/lang.opt

diff --git a/gcc/rust/lang.opt b/gcc/rust/lang.opt
new file mode 100644
index 000..1f6855ede1d
--- /dev/null
+++ b/gcc/rust/lang.opt
@@ -0,0 +1,118 @@
+; 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
+; .
+
+; 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
+
+Wunused-variable
+Rust Var(warn_unused_variable) Init(1) Warning
+; documented in common.opt
+
+Wunused-const-variable
+Rust Warning Alias(Wunused-const-variable=, 2, 0)
+Warn when a const variable is unused.
+
+Wunused-const-variable=
+Rust Joined RejectNegative UInteger Var(warn_unused_const_variable) Init(1) 
Warning LangEnabledBy(Rust,Wunused-variable, 1, 0) IntegerRange(0, 2)
+Warn when a const variable is unused.
+
+Wunused-result
+Rust Var(warn_unused_result) Init(1) Warning
+Warn if a caller of a function, marked with attribute warn_unused_result, does 
not use its return value.
+
+frust-crate=
+Rust Joined RejectNegative
+-frust-crate= Set the crate name for the compilation
+
+frust-debug
+Rust Var(flag_rust_debug)
+Dump various Rust front end internals.
+
+frust-dump-
+Rust Joined RejectNegative
+-frust-dump- Dump Rust frontend internal information.
+
+frust-max-recursion-depth=
+Rust RejectNegative Type(int) Var(rust_max_recursion_depth) Init(64)
+-frust-max-recursion-depth=integer
+
+frust-mangling=
+Rust Joined RejectNegative Enum(frust_mangling) Var(flag_rust_mangling)
+-frust-mangling=[legacy|v0] Choose which version to use for name mangling
+
+Enum
+Name(frust_mangling) Type(int) UnknownError(unknown rust mangling option %qs)
+
+EnumValue
+Enum(frust_mangling) String(legacy) Value(0)
+
+EnumValue
+Enum(frust_mangling) String(v0) Value(1)
+
+frust-cfg=
+Rust Joined RejectNegative
+-frust-cfg= Set a config expansion option
+
+frust-edition=
+Rust Joined RejectNegative Enum(frust_edition) Var(flag_rust_edition)
+-frust-edition=[2015|2018|2021] Choose which edition to use when 
compiling rust code
+
+Enum
+Name(frust_edition) Type(int) UnknownError(unknown rust edition %qs)
+
+EnumValue
+Enum(frust_edition) String(2015) Value(0)
+
+EnumValue
+Enum(frust_edition) String(2018) Value(1)
+
+EnumValue
+Enum(frust_edition) String(2021) Value(2)
+
+frust-embed-metadata
+Rust Var(flag_rust_embed_metadata)
+Flag to enable embeding metadata directly into object files
+
+frust-metadata-output=
+Rust Joined RejectNegative
+-frust-metadata-output=  Path to output crate metadata
+
+o
+Rust Joined Separate
+; Documented in common.opt
+
+; This comment is to ensure we retain the blank line above.
-- 
2.25.1

-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[PATCH Rust front-end v2 31/37] gccrs: Add GCC Rust front-end Make-lang.in

2022-08-24 Thread herron . philip
From: Philip Herron 

This is the Makefile for our front-end.
---
 gcc/rust/Make-lang.in | 400 ++
 1 file changed, 400 insertions(+)
 create mode 100644 gcc/rust/Make-lang.in

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
new file mode 100644
index 000..f687cc2f667
--- /dev/null
+++ b/gcc/rust/Make-lang.in
@@ -0,0 +1,400 @@
+# 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
+# .
+
+# 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 \
+rust/rust-object-export.o \
+rust/rust-linemap.o \
+rust/rust-gcc-diagnostics.o \
+rust/rust-diagnostics.o \
+rust/rust-gcc.o \
+rust/rust-token.o \
+rust/rust-lex.o \
+rust/rust-cfg-parser.o \
+rust/rust-parse.o \
+rust/rust-ast-full-test.o \
+rust/rust-ast-dump.o \
+rust/rust-hir-dump.o \
+rust/rust-session-manager.o \
+rust/rust-compile.o \
+rust/rust-mangle.o \
+rust/rust-compile-resolve-path.o \
+rust/rust-macro-expand.o \
+rust/rust-attribute-visitor.o \
+rust/rust-macro-invoc-lexer.o \
+rust/rust-macro-substitute-ctx.o \
+rust/rust-macro-builtins.o \
+rust/rust-hir-full-test.o \
+rust/rust-hir-map.o \
+rust/rust-attributes.o \
+rust/rust-abi.o \
+rust/rust-ast-lower.o \
+rust/rust-ast-lower-base.o \
+rust/rust-ast-lower-pattern.o \
+rust/rust-ast-lower-item.o \
+rust/rust-name-resolver.o \
+rust/rust-ast-resolve.o \
+rust/rust-ast-resolve-base.o \
+rust/rust-ast-resolve-item.o \
+rust/rust-ast-resolve-pattern.o \
+rust/rust-ast-resolve-expr.o \
+rust/rust-ast-resolve-type.o \
+rust/rust-ast-resolve-path.o \
+rust/rust-ast-resolve-stmt.o \
+rust/rust-ast-resolve-struct-expr-field.o \
+rust/rust-hir-type-check.o \
+rust/rust-privacy-check.o \
+rust/rust-privacy-ctx.o \
+rust/rust-reachability.o \
+rust/rust-visibility-resolver.o \
+rust/rust-pub-restricted-visitor.o \
+rust/rust-privacy-reporter.o \
+rust/rust-tyty.o \
+rust/rust-tyty-call.o \
+rust/rust-tyctx.o \
+rust/rust-tyty-bounds.o \
+rust/rust-hir-type-check-util.o \
+rust/rust-hir-trait-resolve.o \
+rust/rust-hir-type-check-toplevel.o \
+rust/rust-hir-type-check-item.o \
+rust/rust-hir-type-check-type.o \
+rust/rust-hir-type-check-struct.o \
+rust/rust-hir-type-check-pattern.o \
+rust/rust-hir-type-check-expr.o \
+rust/rust-hir-type-check-stmt.o \
+rust/rust-hir-type-check-enumitem.o \
+rust/rust-hir-type-check-implitem.o \
+rust/rust-hir-dot-operator.o \
+rust/rust-coercion.o \
+rust/rust-casts.o \
+rust/rust-hir-type-check-base.o \
+rust/rust-autoderef.o \
+rust/rust-substitution-mapper.o \
+rust/rust-const-checker.o \
+rust/rust-lint-marklive.o \
+rust/rust-lint-unused-var.o \
+rust/rust-hir-type-check-path.o \
+rust/r

[PATCH Rust front-end v2 36/37] gccrs: compiler proper interface kicks off the pipeline

2022-08-24 Thread herron . philip
From: Philip Herron 

This is a wrapper to get out of C land in the rust-lang.cc and into our
class hierarchy for the rust front-end. We expect that the front-end only
support one source file input as the expansion pass will attempt to resolve
that relative pass and parse accordingly.

The main missing piece here is that we are using saw_errors() to return
early which is unnecessary but as our error handling has been improving
over time we will start to take advantage of error node in our type system
as well as error_mark_node from GCC. The caveat being that our lints/checks
expect no errors and will throw an assertion.
---
 gcc/rust/rust-lang.cc|  452 
 gcc/rust/rust-session-manager.cc | 1189 ++
 gcc/rust/rust-session-manager.h  |  358 +
 3 files changed, 1999 insertions(+)
 create mode 100644 gcc/rust/rust-lang.cc
 create mode 100644 gcc/rust/rust-session-manager.cc
 create mode 100644 gcc/rust/rust-session-manager.h

diff --git a/gcc/rust/rust-lang.cc b/gcc/rust/rust-lang.cc
new file mode 100644
index 000..c9af790f66b
--- /dev/null
+++ b/gcc/rust/rust-lang.cc
@@ -0,0 +1,452 @@
+// 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
+// .
+
+#include "rust-diagnostics.h"
+#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 "selftest.h"
+#include "rust-cfg-parser.h"
+#include "rust-privacy-ctx.h"
+#include "rust-ast-resolve-item.h"
+#include "rust-optional.h"
+
+#include 
+// note: header files must be in this order or else forward declarations don't
+// work properly. Kinda dumb system, but have to live with it. clang-format
+// seems to mess it up
+/* Order: config, system, coretypes, target, tree, gimple-expr, diagnostic,
+ * opts, fold-const, gimplify, stor-layout, debug, convert, langhooks,
+ * langhooks-def */
+
+// FIXME: test saving intellisense
+#include "options.h"
+
+// version check to stop compiling if c++ isn't c++11 or higher
+#if __cplusplus < 201103
+#error 
\
+  "GCC Rust frontend requires C++11 or higher. You can compile the g++ 
frontend first and then compile the Rust frontend using that."
+#endif
+// TODO: is this best way to do it? Is it allowed? (should be)
+
+/* General TODOs:
+ *  - convert all copies of expensive-to-copy (deep copy) AST objects into
+ * moves, if possible. Don't remove clone functionality - it may be required 
for
+ * e.g. HIR conversion.
+ */
+
+#include "rust-system.h"
+#include "rust-session-manager.h"
+
+// Language-dependent contents of a type. GTY() mark used for garbage 
collector.
+struct GTY (()) lang_type
+{
+};
+
+// Language-dependent contents of a decl.
+struct GTY (()) lang_decl
+{
+};
+
+// 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
+{
+};
+
+// has to be in same compilation unit as session, so here for now
+void
+rust_add_target_info (const char *key, const char *value)
+{
+  sorry ("TODO");
+
+  Rust::Session::get_instance ().options.target_data.insert_key_value_pair (
+key, value);
+}
+
+/* Language hooks.  */
+
+/* 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

Re: [PATCH Rust front-end v2 01/37] Use DW_ATE_UTF for the Rust 'char' type

2022-08-24 Thread Jason Merrill via Gcc-rust

On 8/24/22 04:59, herron.phi...@googlemail.com wrote:

From: Tom Tromey 

The Rust 'char' type should use the DWARF DW_ATE_UTF encoding.


The DWARF changes are OK.


---
  gcc/dwarf2out.cc | 23 ++-
  1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index e3920c898f5..a8bccbabca4 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -5600,6 +5600,16 @@ is_fortran (const_tree decl)
return is_fortran ();
  }
  
+/* Return TRUE if the language is Rust.  */

+
+static inline bool
+is_rust ()
+{
+  unsigned int lang = get_AT_unsigned (comp_unit_die (), DW_AT_language);
+
+  return lang == DW_LANG_Rust || lang == DW_LANG_Rust_old;
+}
+
  /* Return TRUE if the language is Ada.  */
  
  static inline bool

@@ -13231,7 +13241,11 @@ base_type_die (tree type, bool reverse)
}
if (TYPE_STRING_FLAG (type))
{
- if (TYPE_UNSIGNED (type))
+ if ((dwarf_version >= 4 || !dwarf_strict)
+ && is_rust ()
+ && int_size_in_bytes (type) == 4)
+   encoding = DW_ATE_UTF;
+ else if (TYPE_UNSIGNED (type))
encoding = DW_ATE_unsigned_char;
  else
encoding = DW_ATE_signed_char;
@@ -25201,6 +25215,13 @@ gen_compile_unit_die (const char *filename)
  }
else if (strcmp (language_string, "GNU F77") == 0)
  language = DW_LANG_Fortran77;
+  else if (strcmp (language_string, "GNU Rust") == 0)
+{
+  if (dwarf_version >= 5 || !dwarf_strict)
+   language = DW_LANG_Rust;
+  else
+   language = DW_LANG_Rust_old;
+}
else if (dwarf_version >= 3 || !dwarf_strict)
  {
if (strcmp (language_string, "GNU Ada") == 0)


--
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust