Re: Buildbot failure in Wildebeest Builder on whole buildset

2022-03-02 Thread Arthur Cohen
rust-debian-arm64 while 
building gccrust.
Full details are available at:
 https://builder.wildebeest.org/buildbot/#builders/58/builds/1710

Buildbot URL: https://builder.wildebeest.org/buildbot/

Worker for this Build: debian-arm64

Build Reason: 
Blamelist: Arthur Cohen 

BUILD FAILED: failed compile (failure)


And the same for all other builders.


... and me: <https://github.com/Rust-GCC/gccrs/issues/987>
"'[...]/gcc/rust/parse/rust-cfg-parser.cc:67: rust_cfg_parser_test:
FAIL: ASSERT_TRUE ((Rust::parse_cfg_option (input, key, value)))'".


I haven't figured out yet why the last commit caused this.


(Same here.)


But it can be replicated when configuring with --enable-checking=yes


That's strange -- isn't some '--enable-checking=[...]' actually the
default for GCC builds?


That causes the selftests to trigger:


At least we can see that the GCC/Rust self-tests are executing!  ;-P


Grüße
  Thomas



make[2]: Entering directory '/home/mark/build/gccrs-obj/gcc'
/home/mark/build/gccrs-obj/./gcc/xgcc -B/home/mark/build/gccrs-obj/./gcc/ -xrs 
-nostdinc /dev/null -S -o /dev/null 
-fself-test=/home/mark/src/gccrs/gcc/testsuite/selftests
rust1: error: unexpected character ‘1’
rust1: error: unexpected character ‘0’
rust1: error: unexpected character ‘0’
rust1: error: unexpected character ‘0’
rust1: error: unexpected character ‘1’
rust1: error: unexpected character ‘0’
rust1: error: unexpected character ‘0’
rust1: error: unexpected character ‘0’
rust1: error: unexpected character ‘e0’
rust1: error: unexpected character ‘d3’
rust1: error: unexpected character ‘89’
/home/mark/src/gccrs/gcc/rust/parse/rust-cfg-parser.cc:68: rust_cfg_parser_test: FAIL: 
ASSERT_EQ ((key), ("key_no_value"))
rust1: internal compiler error: in fail, at selftest.cc:47
0x1cf096b selftest::fail(selftest::location const&, char const*)
   /home/mark/src/gccrs/gcc/selftest.cc:47
0x7bb9a3 selftest::rust_cfg_parser_test()
   /home/mark/src/gccrs/gcc/rust/parse/rust-cfg-parser.cc:68
0x1c143b7 selftest::run_tests()
   /home/mark/src/gccrs/gcc/selftest-run-tests.cc:119
0xf1310b toplev::run_self_tests()
   /home/mark/src/gccrs/gcc/toplev.cc:2217
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
make[2]: *** [/home/mark/src/gccrs/gcc/rust/Make-lang.in:232: s-selftest-rust] 
Error 1
make[2]: Leaving directory '/home/mark/build/gccrs-obj/gcc'

Cheers,

Mark

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

-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955
--
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust

-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955


Thanks a lot,

--
Arthur Cohen 

Toolchain Engineer

Embecosm GmbH

Geschäftsführer: Jeremy Bennett
Niederlassung: Nürnberg
Handelsregister: HR-B 36368
www.embecosm.de

Fürther Str. 27
90429 Nürnberg


Tel.: 091 - 128 707 040
Fax: 091 - 128 707 077


OpenPGP_0x1B3465B044AD9C65.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature
-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


Re: Buildbot failure in Wildebeest Builder on whole buildset

2022-03-02 Thread Arthur Cohen

Hi Thomas, thanks a lot!

On 3/2/22 13:36, Thomas Schwinge wrote:

Hi Arthur!

On 2022-03-02T13:05:30+0100, Arthur Cohen  wrote:

On 3/2/22 11:05, Thomas Schwinge wrote:

On 2022-03-02T10:44:38+0100, I wrote:

On 2022-03-02T09:03:48+, Philip Herron  wrote:

Yet again the build bots are out doing github automation :D. Would you
be able to give Arthur access to the failing buildbot to test his fix?


I suggest as a first step to figure out why your local build aren't
running into this issue.  What does running 'build-gcc/gcc/xgcc -v'
should for you, and 'grep -i checking build-gcc/gcc/auto-host.h'?


We think we know what the issue is. We changed the lexer so we could
give it a buffer instead of a file for macro expansion, but the string
is going out of scope when we set it up.


Ah!  So, "standard C/C++ undefined behavior, memory corruption"...  ;-)


Indeed.  Building GCC with '--enable-valgrind-annotations' and running
the GCC self-test through '-wrapper valgrind,--leak-check=full', we see:

  $ [...]/build-gcc/./gcc/xgcc -B[...]/build-gcc/./gcc/ -xrs -nostdinc 
/dev/null -S -o /dev/null -fself-test=[...]/source-gcc/gcc/testsuite/selftests 
-wrapper valgrind,--leak-check=full
  ==3228208== Memcheck, a memory error detector
  ==3228208== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et 
al.
  ==3228208== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright 
info
  ==3228208== Command: [...]/build-gcc/./gcc/rust1 /dev/null -quiet 
-dumpbase null -mtune=generic -march=x86-64 
-fself-test=[...]/source-gcc/gcc/testsuite/selftests -o /dev/null 
-L[...]/build-gcc/./gcc -L/lib/x86_64-linux-gnu -L/lib/../lib64 
-L/usr/lib/x86_64-linux-gnu
  ==3228208==
  rust1: error: unexpected character ‘1’
  rust1: error: unexpected character ‘0’
  rust1: error: unexpected character ‘0’
  rust1: error: unexpected character ‘0’
  rust1: error: unexpected character ‘1’
  rust1: error: unexpected character ‘0’
  rust1: error: unexpected character ‘0’
  rust1: error: unexpected character ‘0’
  ==3228208== Conditional jump or move depends on uninitialised value(s)
  ==3228208==at 0x983D5E: Rust::Lexer::build_token() (rust-lex.cc:365)
  ==3228208==by 0x987DB4: 
Rust::buffered_queue, 
Rust::Lexer::TokenSource>::peek(int) (rust-lex.h:233)
  ==3228208==by 0x988A46: Rust::parse_cfg_option(std::__cxx11::basic_string, 
std::allocator >&, std::__cxx11::basic_string, std::allocator >&, 
std::__cxx11::basic_string, std::allocator >&) (rust-lex.h:166)
  ==3228208==by 0x988D83: selftest::rust_cfg_parser_test() 
(rust-cfg-parser.cc:67)
  ==3228208==by 0x96C5EE: selftest::run_rust_tests() (rust-lang.cc:457)
  ==3228208==by 0x2527223: selftest::run_tests() 
(selftest-run-tests.cc:119)
  ==3228208==by 0x11C2C29: toplev::run_self_tests() (toplev.cc:2217)
  ==3228208==by 0x96991B: toplev::main(int, char**) (toplev.cc:2317)
  ==3228208==by 0x96BFD6: main (main.cc:39)
  [...]

Before commit 6cf9f8c99c5813a23d7cec473fedf00683f409e4 "Merge #983", that
was "clean" (just some lost memory etc.).


Thanks a lot for this. I thought it was some memory corruption,
considering the lexer was seeing garbage characters. I'm a bit
disappointed my computer and github's CI didn't have the behaviour, but
oh well.


But have you been able to reproduce the issue with Valgrind, per the
instructiosn I've given?  (That's generally useful in GCC development: to
know about '--enable-valgrind-annotations', how to use '-wrapper' for
Valgrind but also GDB, etc.)


I knew about -wrapper but had only used it for gdb! So this is great 
information.


Weirdly, I do not get the behavior on my machine, even under valgrind.

arthur@platypus ~/G/gccrs (lexer-string-lifetime)> build/./gcc/xgcc 
-Bbuild/./gcc/ -xrs -nostdinc /dev/null -S -o /dev/null 
-fself-test=gcc/testsuite/selftests -wrapper valgrind,--leak-check=full

==87067== Memcheck, a memory error detector
==87067== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==87067== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==87067== Command: build/./gcc/rust1 /dev/null -quiet -dumpbase null 
-mtune=generic -march=x86-64 -fself-test=gcc/testsuite/selftests -o 
/dev/null -Lbuild/./gcc -L/lib/../lib64 -L/usr/lib/../lib64

==87067==
--87067-- WARNING: Serious error when reading debug info
--87067-- When reading debug info from 
/home/arthur/Git/gccrs/build/gcc/rust1:

--87067-- Can't make sense of .rodata section mapping
-fself-test: 65613 pass(es) in 7.880207 seconds
==87067==
==87067== HEAP SUMMARY:
==87067== in use at exit: 962,793 bytes in 2,362 blocks
==87067==   total heap usage: 2,032,407 allocs, 2,030,045 frees, 
1,033,564,484 bytes allocated

==87067==
==87067==

Re: Buildbot failure in Wildebeest Builder on whole buildset

2022-03-07 Thread Arthur Cohen

Hi Mark,

On 3/6/22 23:33, Mark Wielaard wrote:

Hi,

On Sun, Mar 06, 2022 at 11:20:56PM +0100, Mark Wielaard wrote:

On Sun, Mar 06, 2022 at 10:01:10PM +, build...@builder.wildebeest.org wrote:

The Buildbot has detected a new failure on builder gccrust-debian-arm64 while 
building gccrust.
Full details are available at:
 https://builder.wildebeest.org/buildbot/#builders/58/builds/1716

Buildbot URL: https://builder.wildebeest.org/buildbot/

Worker for this Build: debian-arm64

Build Reason: 
Blamelist: Arthur Cohen , bors[bot] 
<26634292+bors[bot]@users.noreply.github.com>

BUILD FAILED: failed 'grep unexpected ...' (failure)


And the same for all other arches. The unexpected fails or in the rust.log:

Executing on host: 
/var/lib/buildbot/workers/wildebeest/gccrust-debian-arm64/gccrs-build/gcc/testsuite/rust/../../gccrs
 
-B/var/lib/buildbot/workers/wildebeest/gccrust-debian-arm64/gccrs-build/gcc/testsuite/rust/../../
 
/var/lib/buildbot/workers/wildebeest/gccrust-debian-arm64/gccrs/gcc/testsuite/rust/execute/torture/macros6.rs
   -fdiagnostics-plain-output -O0 -lm  -o ./macros6.exe(timeout = 
300)
spawn -ignore SIGHUP 
/var/lib/buildbot/workers/wildebeest/gccrust-debian-arm64/gccrs-build/gcc/testsuite/rust/../../gccrs
 
-B/var/lib/buildbot/workers/wildebeest/gccrust-debian-arm64/gccrs-build/gcc/testsuite/rust/../../
 
/var/lib/buildbot/workers/wildebeest/gccrust-debian-arm64/gccrs/gcc/testsuite/rust/execute/torture/macros6.rs
 -fdiagnostics-plain-output -O0 -lm -o ./macros6.exe
/var/lib/buildbot/workers/wildebeest/gccrust-debian-arm64/gccrs/gcc/testsuite/rust/execute/torture/macros6.rs:10:13:
 error: Cannot find path 'Foo' in this scope
compiler exited with status 1
FAIL: rust/execute/torture/macros6.rs   -O0  (test for excess errors)
Excess errors:
/var/lib/buildbot/workers/wildebeest/gccrust-debian-arm64/gccrs/gcc/testsuite/rust/execute/torture/macros6.rs:10:13:
 error: Cannot find path 'Foo' in this scope
UNRESOLVED: rust/execute/torture/macros6.rs   -O0  compilation failed to 
produce executable


This seems to have been resolved by a followup commit:


Yes, I felt bad making Philip review an enormous commit and decided to 
instead keep it
split-up despite not all the tests passing. All the commits in that set 
compile, but

they don't all pass some macro tests.



commit 58d1721529e99c7c633615e7491b777a6198ed00 (github/pr/985)
Author: Arthur Cohen 
Date:   Tue Mar 1 10:41:45 2022 +0100

 macroinvocation: Only allow *stmt* visitors when semicoloned

All, except debian-i386, are green again:
https://builder.wildebeest.org/buildbot/#/builders?tags=gccrust

Cheers,

Mark


Hope it's all good,

Kindly,

--
Arthur Cohen 

Toolchain Engineer

Embecosm GmbH

Geschäftsführer: Jeremy Bennett
Niederlassung: Nürnberg
Handelsregister: HR-B 36368
www.embecosm.de

Fürther Str. 27
90429 Nürnberg


Tel.: 091 - 128 707 040
Fax: 091 - 128 707 077


OpenPGP_0x1B3465B044AD9C65.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature
-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


Re: Buildbot failure in Wildebeest Builder on whole buildset

2022-03-07 Thread Arthur Cohen

Hi,

This is due to the lexer's fix not being in yet. I think it should be 
resolved later as soon as bors merges the fix, but I'll check just in case.


Sorry for the noise,

Kindly,

Arthur

On 3/7/22 10:49, build...@builder.wildebeest.org wrote:

The Buildbot has detected a new failure on builder gccrust-debian-arm64 while 
building gccrust.
Full details are available at:
 https://builder.wildebeest.org/buildbot/#builders/58/builds/1720

Buildbot URL: https://builder.wildebeest.org/buildbot/

Worker for this Build: debian-arm64

Build Reason: 
Blamelist: Arthur Cohen , bors[bot] 
<26634292+bors[bot]@users.noreply.github.com>

BUILD FAILED: failed compile (failure)

Sincerely,
  -The BuildbotThe Buildbot has detected a new failure on builder 
gccrust-fedora-x86_64 while building gccrust.
Full details are available at:
 https://builder.wildebeest.org/buildbot/#builders/59/builds/1634

Buildbot URL: https://builder.wildebeest.org/buildbot/

Worker for this Build: fedora-x86_64

Build Reason: 
Blamelist: Arthur Cohen , bors[bot] 
<26634292+bors[bot]@users.noreply.github.com>

BUILD FAILED: failed compile (failure)

Sincerely,
  -The BuildbotThe Buildbot has detected a new failure on builder 
gccrust-fedora-ppc64le while building gccrust.
Full details are available at:
 https://builder.wildebeest.org/buildbot/#builders/60/builds/1645

Buildbot URL: https://builder.wildebeest.org/buildbot/

Worker for this Build: fedora-ppc64le

Build Reason: 
Blamelist: Arthur Cohen , bors[bot] 
<26634292+bors[bot]@users.noreply.github.com>

BUILD FAILED: failed compile (failure)

Sincerely,
  -The BuildbotThe Buildbot has detected a new failure on builder 
gccrust-fedora-ppc64 while building gccrust.
Full details are available at:
 https://builder.wildebeest.org/buildbot/#builders/61/builds/1623

Buildbot URL: https://builder.wildebeest.org/buildbot/

Worker for this Build: fedora-ppc64

Build Reason: 
Blamelist: Arthur Cohen , bors[bot] 
<26634292+bors[bot]@users.noreply.github.com>

BUILD FAILED: failed compile (failure)

Sincerely,
  -The BuildbotThe Buildbot has detected a new failure on builder 
gccrust-fedora-s390x while building gccrust.
Full details are available at:
 https://builder.wildebeest.org/buildbot/#builders/63/builds/1369

Buildbot URL: https://builder.wildebeest.org/buildbot/

Worker for this Build: fedora-s390x

Build Reason: 
Blamelist: Arthur Cohen , bors[bot] 
<26634292+bors[bot]@users.noreply.github.com>

BUILD FAILED: failed compile (failure)

Sincerely,
  -The BuildbotThe Buildbot has detected a new failure on builder 
gccrust-debian-ppc64 while building gccrust.
Full details are available at:
 https://builder.wildebeest.org/buildbot/#builders/64/builds/179

Buildbot URL: https://builder.wildebeest.org/buildbot/

Worker for this Build: debian-ppc64

Build Reason: 
Blamelist: Arthur Cohen , bors[bot] 
<26634292+bors[bot]@users.noreply.github.com>

BUILD FAILED: failed compile (failure)

Sincerely,
  -The Buildbot



OpenPGP_0x1B3465B044AD9C65.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature
-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


Re: Buildbot failure in Wildebeest Builder on whole buildset

2022-03-07 Thread Arthur Cohen

On 3/7/22 15:23, Mark Wielaard wrote:

Hi,

On Mon, 2022-03-07 at 10:57 +0100, Arthur Cohen wrote:

This is due to the lexer's fix not being in yet. I think it should
be
resolved later as soon as bors merges the fix, but I'll check just in
case.


According to:
https://builder.wildebeest.org/buildbot/#/builders?tags=gccrust

It was fixed by:

commit 7a3c935c0f220835c001307944587a84c5af0192
Author: Philip Herron 
Date:   Fri Mar 4 13:45:34 2022 +

 Check if this constant item might already be compiled

Which is slightly odd, because that isn't a lexer fix.
So I suspect the bug is still there, but is hidden again. 


I've checked the master branch, and the lexer is fixed there. I've 
checked out the commit you mentionned, and running git blame on it shows 
that the fix was introduced in 45eac5686867:


commit 45eac568686745af73848f6c238fefcd87e315de (HEAD, 
origin/lexer-string-lifetime, lexer-string-lifetime)

Author: Arthur Cohen 
Date:   Wed Mar 2 15:18:40 2022 +0100

lexer: Add reference and warning documentation

Fixes the -fself-test invalid memory accesses and adds documentation
regarding a possible future fix.

Co-authored-by: tschwinge 
Co-authored-by: philberty 

Which is the proper commit.

I suspect this might be due to bors, our merging bot on github, and me 
asking it to merge multiple pull requests this morning (around 4 or 5). 
Not really sure.


But the bug is fixed and properly placed in the history :)

All the best,

Arthur


OpenPGP_0x1B3465B044AD9C65.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature
-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


Re: Buildbot failure in Wildebeest Builder on whole buildset

2022-03-08 Thread Arthur Cohen

Hi Mark,

On 3/7/22 15:42, Mark Wielaard wrote:

Hi Arthur,

On Mon, 2022-03-07 at 15:32 +0100, Arthur Cohen wrote:

I suspect this might be due to bors, our merging bot on github, and me
asking it to merge multiple pull requests this morning (around 4 or 5).
Not really sure.

But the bug is fixed and properly placed in the history :)


Aha, I see, you are right. For some reason bors adds commits on top of
old commits with a merge instead of doing a simple rebase on top of the
latest commit. Making the git history look like a Christmas tree:
https://code.wildebeest.org/git/mirror/gccrs/log/

Your new commits were indeed on top of a 5 day old commit, so the
buildbot dutifully tested it in context. And that context didn't
include the fix yet.

Would it make sense to tell bors to do a rebase instead of a merge
before pushing to trunk?

Cheers,

Mark


I've checked, and I don't think that bors is able to do that. Since it 
maintains a staging queue containing multiple PRs and then merges it 
onto the main branch if all tests pass, I think the christmas tree is 
unavoidable.


I'd be happy to be proved wrong however.

Kindly,

Arthur


OpenPGP_0x1B3465B044AD9C65.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature
-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


Re: Buildbot failure in Wildebeest Builder on whole buildset

2022-03-22 Thread Arthur Cohen

Hi everyone,

Sorry for the failure! Here's the explanation of why it happened:

I created a pull request for a64a5cf77c9685aa623ec69168e7f50324a102b9:

```
commit a64a5cf77c9685aa623ec69168e7f50324a102b9 
(origin/invalid-macro-match-fix, invalid-macro-match-fix)

Author: Arthur Cohen 
Date:   Fri Mar 18 11:34:39 2022 +0100

macros: Do not propagate parse errors in match repetitions

Since parsing repetitions is very eager, the parser might accumulate
bogus errors by trying to match more repetitions than there are. We can
avoid this by clearing the parsing errors if parsing repetitions
returned a valid result. This should not be an issue for previous
matchers erroring out, as they would immediately return upon 
failure and

not reach inside other match functions.
```

Roughly at the same time, I also created one for the following commit:

```
commit f8c550f7e19c79c98f6d21ad6ce68d615451459a 
(origin/repetition-fragments-must-refer-to-the-same-amount, 
repetition-fragments-must-refer-to-the-same-amount)

Author: Arthur Cohen 
Date:   Fri Mar 18 13:20:09 2022 +0100

macros: Only expand merged repetitions if they contain the same amount
of matches

Forbid merging repetitions if the matched fragments do not contain the
same amount of repetitions
```

The later commit requiring the first one to pass all tests (otherwise, 
some spurious errors were present).


To make Philip's reviewing process easier, I developped the second 
commit while having cherry-picked the first one, but created the pull 
request without it: This way, changes were easier to see and did not 
need as much digging around. Likewise, Philip would not have to review 
the same commit twice.


Once Philip was done reviewing, I asked bors to rebase both pull 
requests, the second one after the first. Meaning that on the current 
master branch, all tests are passing, since the second commit was 
applied on top of the first. Nonetheless, bors also applies all commits 
when merging, meaning there is a stray 'second commit' without the first 
one, causing the testsuite to fail.


The later commits should resolve the situation.

Next time, I'll wait for the first pull request to be merged and rebase 
the second one on top of it.


Sorry for the noise!

Kindly,

--
Arthur Cohen 

Toolchain Engineer

Embecosm GmbH

Geschäftsführer: Jeremy Bennett
Niederlassung: Nürnberg
Handelsregister: HR-B 36368
www.embecosm.de

Fürther Str. 27
90429 Nürnberg


Tel.: 091 - 128 707 040
Fax: 091 - 128 707 077


OpenPGP_0x1B3465B044AD9C65.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature
-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


Rust frontend patches v3

2022-10-26 Thread arthur . cohen
This is the fixed version of our previous patch set for gccrs - We've adressed
the comments raised in our previous emails.

This patch set does not contain any work that was not previously included, such
as closure support, the constant evaluator port, or the better implementation
of target hooks by Iain Buclaw. They will follow up in subsequent patch sets.

Thanks again to Open Source Security, inc and Embecosm who have accompanied us
for this work.

Many thanks to all of the contributors and our community, who made this
possible.

A very special thanks to Philip Herron, without whose mentoring I would have
never been in a position to send these patches.

You can see the current status of our work on our branch:
https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/devel/rust/master

The patch set contains the following:

[PATCH Rust front-end v3 01/46] Use DW_ATE_UTF for the Rust 'char'
[PATCH Rust front-end v3 02/46] gccrs: Add nessecary hooks for a Rust
[PATCH Rust front-end v3 03/46] gccrs: Add Debug info testsuite
[PATCH Rust front-end v3 04/46] gccrs: Add link cases testsuite
[PATCH Rust front-end v3 05/46] gccrs: Add general compilation test
[PATCH Rust front-end v3 06/46] gccrs: Add execution test cases
[PATCH Rust front-end v3 07/46] gccrs: Add gcc-check-target
[PATCH Rust front-end v3 08/46] gccrs: Add Rust front-end base AST
[PATCH Rust front-end v3 09/46] gccrs: Add definitions of Rust Items
[PATCH Rust front-end v3 10/46] gccrs: Add full definitions of Rust
[PATCH Rust front-end v3 11/46] gccrs: Add Rust AST visitors
[PATCH Rust front-end v3 12/46] gccrs: Add Lexer for Rust front-end
[PATCH Rust front-end v3 13/46] gccrs: Add Parser for Rust front-end
[PATCH Rust front-end v3 14/46] gccrs: Add Parser for Rust front-end
[PATCH Rust front-end v3 15/46] gccrs: Add expansion pass for the
[PATCH Rust front-end v3 16/46] gccrs: Add name resolution pass to
[PATCH Rust front-end v3 17/46] gccrs: Add declarations for Rust HIR
[PATCH Rust front-end v3 18/46] gccrs: Add HIR definitions and
[PATCH Rust front-end v3 19/46] gccrs: Add AST to HIR lowering pass
[PATCH Rust front-end v3 20/46] gccrs: Add wrapper for make_unique
[PATCH Rust front-end v3 21/46] gccrs: Add port of FNV hash used
[PATCH Rust front-end v3 22/46] gccrs: Add Rust ABI enum helpers
[PATCH Rust front-end v3 23/46] gccrs: Add Base62 implementation
[PATCH Rust front-end v3 24/46] gccrs: Add implementation of Optional
[PATCH Rust front-end v3 25/46] gccrs: Add attributes checker
[PATCH Rust front-end v3 26/46] gccrs: Add helpers mappings canonical
[PATCH Rust front-end v3 27/46] gccrs: Add type resolution and trait
[PATCH Rust front-end v3 28/46] gccrs: Add Rust type information
[PATCH Rust front-end v3 29/46] gccrs: Add remaining type system
[PATCH Rust front-end v3 30/46] gccrs: Add unsafe checks for Rust
[PATCH Rust front-end v3 31/46] gccrs: Add const checker
[PATCH Rust front-end v3 32/46] gccrs: Add privacy checks
[PATCH Rust front-end v3 33/46] gccrs: Add dead code scan on HIR
[PATCH Rust front-end v3 34/46] gccrs: Add unused variable scan
[PATCH Rust front-end v3 35/46] gccrs: Add metadata ouptput pass
[PATCH Rust front-end v3 36/46] gccrs: Add base for HIR to GCC
[PATCH Rust front-end v3 37/46] gccrs: Add HIR to GCC GENERIC
[PATCH Rust front-end v3 38/46] gccrs: Add HIR to GCC GENERIC
[PATCH Rust front-end v3 39/46] gccrs: These are wrappers ported from
[PATCH Rust front-end v3 40/46] gccrs: Add GCC Rust front-end
[PATCH Rust front-end v3 41/46] gccrs: Add config-lang.in
[PATCH Rust front-end v3 42/46] gccrs: Add lang-spec.h
[PATCH Rust front-end v3 43/46] gccrs: Add lang.opt
[PATCH Rust front-end v3 44/46] gccrs: Add compiler driver
[PATCH Rust front-end v3 45/46] gccrs: Compiler proper interface
[PATCH Rust front-end v3 46/46] 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 v3 04/46] gccrs: Add link cases testsuite

2022-10-26 Thread arthur . cohen
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 v3 03/46] gccrs: Add Debug info testsuite

2022-10-26 Thread arthur . cohen
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 v3 01/46] Use DW_ATE_UTF for the Rust 'char' type

2022-10-26 Thread arthur . cohen
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.37.2

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


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

2022-10-26 Thread arthur . cohen
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 v3 07/46] gccrs: Add gcc-check-target check-rust

2022-10-26 Thread arthur . cohen
From: Philip Herron 

This allows us to invoke the rust testsuite.

ChangeLog:
* Makefile.def: Add Rust language.
* 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.37.2

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


[PATCH Rust front-end v3 11/46] gccrs: Add Rust AST visitors

2022-10-26 Thread arthur . cohen
From: The Other 

This patch contains the basic framework of our AST visitors, as well as
one aimed at pretty-printing and exporting these AST nodes

Co-authored-by: Philip Herron 
Co-authored-by: Arthur Cohen 
---
 gcc/rust/ast/rust-ast-dump.cc| 1089 ++
 gcc/rust/ast/rust-ast-dump.h |  246 ++
 gcc/rust/ast/rust-ast-visitor.h  |  234 ++
 gcc/rust/ast/rust-cond-compilation.h |  249 ++
 4 files changed, 1818 insertions(+)
 create mode 100644 gcc/rust/ast/rust-ast-dump.cc
 create mode 100644 gcc/rust/ast/rust-ast-dump.h
 create mode 100644 gcc/rust/ast/rust-ast-visitor.h
 create mode 100644 gcc/rust/ast/rust-cond-compilation.h

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
new file mode 100644
index 000..ad9ad0b7de7
--- /dev/null
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -0,0 +1,1089 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-ast-dump.h"
+
+namespace Rust {
+namespace AST {
+
+Indent::Indent () : tabs (0) {}
+
+std::ostream &
+operator<< (std::ostream &stream, const Indent &indent)
+{
+  return stream << std::string (indent.tabs, '\t');
+}
+
+void
+Indent::increment ()
+{
+  tabs++;
+}
+
+void
+Indent::decrement ()
+{
+  rust_assert (tabs != 0);
+  tabs--;
+}
+
+Dump::Dump (std::ostream &stream) : stream (stream), indentation (Indent ()) {}
+
+void
+Dump::go (AST::Crate &crate)
+{
+  for (auto &item : crate.items)
+{
+  stream << indentation;
+  item->accept_vis (*this);
+  stream << "\n";
+}
+}
+
+void
+Dump::go (AST::Item &item)
+{
+  item.accept_vis (*this);
+}
+
+void
+Dump::format_function_param (FunctionParam ¶m)
+{
+  param.get_pattern ()->accept_vis (*this);
+  stream << ": ";
+  param.get_type ()->accept_vis (*this);
+}
+
+void
+Dump::emit_attrib (const Attribute &attrib)
+{
+  stream << "#";
+  stream << "[";
+
+  for (size_t i = 0; i < attrib.get_path ().get_segments ().size (); i++)
+{
+  const auto &seg = attrib.get_path ().get_segments ().at (i);
+  bool has_next = (i + 1) < attrib.get_path ().get_segments ().size ();
+
+  stream << seg.get_segment_name ();
+  if (has_next)
+   stream << "::";
+}
+
+  if (attrib.has_attr_input ())
+{
+  stream << " = ";
+
+  bool is_literal = attrib.get_attr_input ().get_attr_input_type ()
+   == AST::AttrInput::AttrInputType::LITERAL;
+  if (is_literal)
+   {
+ auto &literal
+   = static_cast (attrib.get_attr_input ());
+ const auto &value = literal.get_literal ().as_string ();
+
+ stream << "\"" << value << "\"";
+   }
+  else
+   {
+ stream << "FIXME";
+   }
+}
+
+  stream << "]";
+}
+
+void
+Dump::visit (Token &tok)
+{}
+
+void
+Dump::visit (DelimTokenTree &delim_tok_tree)
+{}
+
+void
+Dump::visit (AttrInputMetaItemContainer &input)
+{}
+
+void
+Dump::visit (IdentifierExpr &ident_expr)
+{
+  stream << ident_expr.get_ident ();
+}
+
+void
+Dump::visit (Lifetime &lifetime)
+{}
+
+void
+Dump::visit (LifetimeParam &lifetime_param)
+{}
+
+void
+Dump::visit (ConstGenericParam &lifetime_param)
+{}
+
+// rust-path.h
+void
+Dump::visit (PathInExpression &path)
+{}
+
+void
+Dump::visit (TypePathSegment &segment)
+{}
+
+void
+Dump::visit (TypePathSegmentGeneric &segment)
+{}
+
+void
+Dump::visit (TypePathSegmentFunction &segment)
+{}
+
+void
+Dump::visit (TypePath &path)
+{
+  stream << path.as_string ();
+}
+
+void
+Dump::visit (QualifiedPathInExpression &path)
+{}
+
+void
+Dump::visit (QualifiedPathInType &path)
+{}
+
+// rust-expr.h
+void
+Dump::visit (LiteralExpr &expr)
+{
+  stream << expr.as_string ();
+}
+
+void
+Dump::visit (AttrInputLiteral &attr_input)
+{}
+
+void
+Dump::visit (MetaItemLitExpr &meta_item)
+{}
+
+void
+Dump::visit (MetaItemPathLit &meta_item)
+{}
+
+void
+Dump::visit (BorrowExpr &expr)
+{}
+
+void
+Dump::visit (DereferenceExpr &expr)
+{}

[PATCH Rust front-end v3 12/46] gccrs: Add Lexer for Rust front-end

2022-10-26 Thread arthur . cohen
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   | 2728 
 gcc/rust/lex/rust-lex.h|  271 
 gcc/rust/lex/rust-token.cc |  134 ++
 gcc/rust/lex/rust-token.h  |  450 ++
 gcc/rust/rust-buffered-queue.h |  204 +++
 6 files changed, 3833 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..1a9f0ca7a21
--- /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
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_CODEPOINT_H
+#define RUST_CODEPOINT_H
+
+#include "rust-system.h"
+
+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..82949f5fe5f
--- /dev/null
+++ b/gcc/rust/lex/rust-lex.cc
@@ -0,0 +1,2728 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-system.h"
+#include "rust-lex.h"
+#include "rust-diagnostics.h"
+#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);
+}
+ 

[PATCH Rust front-end v3 09/46] gccrs: Add definitions of Rust Items in AST data structures

2022-10-26 Thread arthur . cohen
From: The Other 

This adds the proper definitions of our AST Item nodes.

Co-authored-by: Philip Herron 
---
 gcc/rust/ast/rust-item.h | 4382 ++
 1 file changed, 4382 insertions(+)
 create mode 100644 gcc/rust/ast/rust-item.h

diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
new file mode 100644
index 000..4987674cba1
--- /dev/null
+++ b/gcc/rust/ast/rust-item.h
@@ -0,0 +1,4382 @@
+// 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_AST_ITEM_H
+#define RUST_AST_ITEM_H
+
+#include "rust-ast.h"
+#include "rust-path.h"
+#include "rust-common.h"
+
+namespace Rust {
+namespace AST {
+// forward decls
+class BlockExpr;
+class TypePath;
+
+// TODO: inline?
+/*struct AbiName {
+std::string abi_name;
+// Technically is meant to be STRING_LITERAL
+
+  public:
+// Returns whether abi name is empty, i.e. doesn't exist.
+bool is_empty() const {
+   return abi_name.empty();
+}
+
+AbiName(std::string name) : abi_name(std::move(name)) {}
+
+// Empty AbiName constructor
+AbiName() {}
+};*/
+
+// A type generic parameter (as opposed to a lifetime generic parameter)
+class TypeParam : public GenericParam
+{
+  // bool has_outer_attribute;
+  // std::unique_ptr outer_attr;
+  Attribute outer_attr;
+
+  Identifier type_representation;
+
+  // bool has_type_param_bounds;
+  // TypeParamBounds type_param_bounds;
+  std::vector>
+type_param_bounds; // inlined form
+
+  // bool has_type;
+  std::unique_ptr type;
+
+  Location locus;
+
+public:
+  Identifier get_type_representation () const { return type_representation; }
+
+  // Returns whether the type of the type param has been specified.
+  bool has_type () const { return type != nullptr; }
+
+  // Returns whether the type param has type param bounds.
+  bool has_type_param_bounds () const { return !type_param_bounds.empty (); }
+
+  // Returns whether the type param has an outer attribute.
+  bool has_outer_attribute () const { return !outer_attr.is_empty (); }
+
+  TypeParam (Identifier type_representation, Location locus = Location (),
+std::vector> type_param_bounds
+= std::vector> (),
+std::unique_ptr type = nullptr,
+Attribute outer_attr = Attribute::create_empty ())
+: GenericParam (Analysis::Mappings::get ()->get_next_node_id ()),
+  outer_attr (std::move (outer_attr)),
+  type_representation (std::move (type_representation)),
+  type_param_bounds (std::move (type_param_bounds)),
+  type (std::move (type)), locus (locus)
+  {}
+
+  // Copy constructor uses clone
+  TypeParam (TypeParam const &other)
+: GenericParam (other.node_id), outer_attr (other.outer_attr),
+  type_representation (other.type_representation), locus (other.locus)
+  {
+// guard to prevent null pointer dereference
+if (other.type != nullptr)
+  type = other.type->clone_type ();
+
+type_param_bounds.reserve (other.type_param_bounds.size ());
+for (const auto &e : other.type_param_bounds)
+  type_param_bounds.push_back (e->clone_type_param_bound ());
+  }
+
+  // Overloaded assignment operator to clone
+  TypeParam &operator= (TypeParam const &other)
+  {
+type_representation = other.type_representation;
+outer_attr = other.outer_attr;
+locus = other.locus;
+node_id = other.node_id;
+
+// guard to prevent null pointer dereference
+if (other.type != nullptr)
+  type = other.type->clone_type ();
+else
+  type = nullptr;
+
+type_param_bounds.reserve (other.type_param_bounds.size ());
+for (const auto &e : other.type_param_bounds)
+  type_param_bounds.push_back (e->clone_type_param_bound ());
+
+return *this;
+  }
+
+  // move constructors
+  TypeParam (TypeParam &&other) = default;
+  TypeParam &operator= (TypeParam &&other) = default;
+
+  std::string as_string () const override;
+
+  Location get_locus () const override final { return locus; }
+
+  Kind get_kind () const override final { return Kind::Type; }
+
+  void accept_vis (ASTVisitor &vis) override;
+
+  // TODO: is this better? Or is a "vis_block" better?
+  std::unique_ptr &get_type ()
+  {
+rust_assert (type != nullptr);
+return type;
+  }
+
+  // TODO: mutable getter seems kinda dodgy
+  std::vector> &get_t

[PATCH Rust front-end v3 24/46] gccrs: Add implementation of Optional

2022-10-26 Thread arthur . cohen
From: Arthur Cohen 

Add an Optional class to improve error handling
---
 gcc/rust/util/rust-optional-test.cc | 110 +++
 gcc/rust/util/rust-optional.h   | 278 
 2 files changed, 388 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..43fa175fa40
--- /dev/null
+++ b/gcc/rust/util/rust-optional-test.cc
@@ -0,0 +1,110 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-system.h"
+#include "rust-optional.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
+// <http://www.gnu.org/licenses/>.
+
+#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 w

[PATCH Rust front-end v3 18/46] gccrs: Add HIR definitions and visitor framework

2022-10-26 Thread arthur . cohen
From: Philip Herron 

This patch implements the classes mentionned in the previous HIR patch,
as well as a set of visitor frameworks used in handling that HIR.
---
 gcc/rust/hir/tree/rust-hir-full-decls.h |  232 +
 gcc/rust/hir/tree/rust-hir-full-test.cc | 5292 +++
 gcc/rust/hir/tree/rust-hir-full.h   |   30 +
 gcc/rust/hir/tree/rust-hir-visitor.h|  493 +++
 gcc/rust/hir/tree/rust-hir.h|  921 
 5 files changed, 6968 insertions(+)
 create mode 100644 gcc/rust/hir/tree/rust-hir-full-decls.h
 create mode 100644 gcc/rust/hir/tree/rust-hir-full-test.cc
 create mode 100644 gcc/rust/hir/tree/rust-hir-full.h
 create mode 100644 gcc/rust/hir/tree/rust-hir-visitor.h
 create mode 100644 gcc/rust/hir/tree/rust-hir.h

diff --git a/gcc/rust/hir/tree/rust-hir-full-decls.h 
b/gcc/rust/hir/tree/rust-hir-full-decls.h
new file mode 100644
index 000..2798ba9fd84
--- /dev/null
+++ b/gcc/rust/hir/tree/rust-hir-full-decls.h
@@ -0,0 +1,232 @@
+// 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_HIR_FULL_DECLS_H
+#define RUST_HIR_FULL_DECLS_H
+
+namespace Rust {
+namespace HIR {
+
+struct Literal;
+class Stmt;
+class Item;
+class Expr;
+class ExprWithoutBlock;
+class Pattern;
+class Type;
+class TypeNoBounds;
+class TypeParamBound;
+class Lifetime;
+class GenericParam;
+class LifetimeParam;
+
+class TraitItem;
+class ImplItem;
+struct Crate;
+class PathExpr;
+
+// rust-path.h
+class PathIdentSegment;
+struct GenericArgsBinding;
+struct GenericArgs;
+class PathExprSegment;
+class PathPattern;
+class PathInExpression;
+class TypePathSegment;
+class TypePathSegmentGeneric;
+struct TypePathFunction;
+class TypePathSegmentFunction;
+class TypePath;
+struct QualifiedPathType;
+class QualifiedPathInExpression;
+class QualifiedPathInType;
+
+// rust-expr.h
+class ExprWithBlock;
+class LiteralExpr;
+class AttrInputLiteral;
+class OperatorExpr;
+class BorrowExpr;
+class DereferenceExpr;
+class ErrorPropagationExpr;
+class NegationExpr;
+class ArithmeticOrLogicalExpr;
+class ComparisonExpr;
+class LazyBooleanExpr;
+class TypeCastExpr;
+class AssignmentExpr;
+class CompoundAssignmentExpr;
+class GroupedExpr;
+class ArrayElems;
+class ArrayElemsValues;
+class ArrayElemsCopied;
+class ArrayExpr;
+class ArrayIndexExpr;
+class TupleExpr;
+class TupleIndexExpr;
+class StructExpr;
+class StructExprStruct;
+struct StructBase;
+class StructExprField;
+class StructExprFieldIdentifier;
+class StructExprFieldWithVal;
+class StructExprFieldIdentifierValue;
+class StructExprFieldIndexValue;
+class StructExprStructFields;
+class StructExprStructBase;
+class CallExpr;
+class MethodCallExpr;
+class FieldAccessExpr;
+struct ClosureParam;
+class ClosureExpr;
+class ClosureExprInner;
+class BlockExpr;
+class ClosureExprInnerTyped;
+class ContinueExpr;
+class BreakExpr;
+class RangeExpr;
+class RangeFromToExpr;
+class RangeFromExpr;
+class RangeToExpr;
+class RangeFullExpr;
+class RangeFromToInclExpr;
+class RangeToInclExpr;
+class ReturnExpr;
+class UnsafeBlockExpr;
+class LoopLabel;
+class BaseLoopExpr;
+class LoopExpr;
+class WhileLoopExpr;
+class WhileLetLoopExpr;
+class ForLoopExpr;
+class IfExpr;
+class IfExprConseqElse;
+class IfExprConseqIf;
+class IfLetExpr;
+class IfExprConseqIfLet;
+class IfLetExprConseqElse;
+class IfLetExprConseqIf;
+class IfLetExprConseqIfLet;
+struct MatchArm;
+// class MatchCase;
+// class MatchCaseBlockExpr;
+// class MatchCaseExpr;
+struct MatchCase;
+class MatchExpr;
+class AwaitExpr;
+class AsyncBlockExpr;
+
+// rust-stmt.h
+class EmptyStmt;
+class LetStmt;
+class ExprStmt;
+class ExprStmtWithoutBlock;
+class ExprStmtWithBlock;
+
+// rust-item.h
+class TypeParam;
+class ConstGenericParam;
+class WhereClauseItem;
+class LifetimeWhereClauseItem;
+class TypeBoundWhereClauseItem;
+struct WhereClause;
+struct SelfParam;
+struct FunctionQualifiers;
+struct FunctionParam;
+struct Visibility;
+class VisItem;
+class Module;
+class ExternCrate;
+class UseTree;
+class UseTreeGlob;
+class UseTreeList;
+class UseTreeRebind;
+class UseDeclaration;
+class Function;
+class TypeAlias;
+class Struct;
+struct StructField;
+class StructStruct;
+struct TupleField;
+class TupleStruct;
+class EnumItem;
+class EnumItemTuple;
+class EnumItemStruct;
+class EnumItemDiscriminant;
+class Enum;
+class Union;
+class Constant

[PATCH Rust front-end v3 22/46] gccrs: Add Rust ABI enum helpers

2022-10-26 Thread arthur . cohen
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.37.2

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


[PATCH Rust front-end v3 23/46] gccrs: Add Base62 implementation

2022-10-26 Thread arthur . cohen
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
+// <http://www.gnu.org/licenses/>.
+
+#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
+// <http://www.gnu.org/licenses/>.
+
+#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.37.2

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


[PATCH Rust front-end v3 20/46] gccrs: Add wrapper for make_unique

2022-10-26 Thread arthur . cohen
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..7b79e625ff1
--- /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 "rust-system.h"
+
+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.37.2

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


[PATCH Rust front-end v3 31/46] gccrs: Add const checker

2022-10-26 Thread arthur . cohen
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
+// <http://www.gnu.org/licenses/>.
+
+#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);
+}

[PATCH Rust front-end v3 35/46] gccrs: Add metadata ouptput pass

2022-10-26 Thread arthur . cohen
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| 176 +
 gcc/rust/rust-object-export.h |  33 +
 9 files changed, 2490 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 v3 25/46] gccrs: Add attributes checker

2022-10-26 Thread arthur . cohen
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..b73e9534414
--- /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
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-system.h"
+#include "rust-attributes.h"
+#include "rust-ast.h"
+#include "rust-ast-full.h"
+#include "rust-diagnostics.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'

[PATCH Rust front-end v3 26/46] gccrs: Add helpers mappings canonical path and lang items

2022-10-26 Thread arthur . cohen
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 v3 21/46] gccrs: Add port of FNV hash used during legacy symbol mangling

2022-10-26 Thread arthur . cohen
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.37.2

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


[PATCH Rust front-end v3 32/46] gccrs: Add privacy checks

2022-10-26 Thread arthur . cohen
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   | 771 ++
 .../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, 2263 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
+// <http://www.gnu.org/licenses/>.
+
+#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

[PATCH Rust front-end v3 38/46] gccrs: Add HIR to GCC GENERIC lowering entry point

2022-10-26 Thread arthur . cohen
From: Philip Herron 

This patch contains the entry point and utilities used for the lowering
of HIR nodes to `tree`s. It also contains a constant evaluator, ported
over from the C++ frontend.

Co-authored-by: David Faust 
Co-authored-by: Faisal Abbas <90.abbasfai...@gmail.com>
---
 gcc/rust/backend/rust-compile-context.cc | 146 
 gcc/rust/backend/rust-compile-context.h  | 343 ++
 gcc/rust/backend/rust-compile.cc | 414 +
 gcc/rust/backend/rust-compile.h  |  47 +++
 gcc/rust/backend/rust-constexpr.cc   | 441 +++
 gcc/rust/backend/rust-constexpr.h|  31 ++
 6 files changed, 1422 insertions(+)
 create mode 100644 gcc/rust/backend/rust-compile-context.cc
 create mode 100644 gcc/rust/backend/rust-compile-context.h
 create mode 100644 gcc/rust/backend/rust-compile.cc
 create mode 100644 gcc/rust/backend/rust-compile.h
 create mode 100644 gcc/rust/backend/rust-constexpr.cc
 create mode 100644 gcc/rust/backend/rust-constexpr.h

diff --git a/gcc/rust/backend/rust-compile-context.cc 
b/gcc/rust/backend/rust-compile-context.cc
new file mode 100644
index 000..cb2addf6c21
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-context.cc
@@ -0,0 +1,146 @@
+// 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-compile-context.h"
+#include "rust-compile-type.h"
+
+namespace Rust {
+namespace Compile {
+
+Context::Context (::Backend *backend)
+  : backend (backend), resolver (Resolver::Resolver::get ()),
+tyctx (Resolver::TypeCheckContext::get ()),
+mappings (Analysis::Mappings::get ()), mangler (Mangler ())
+{
+  setup_builtins ();
+}
+
+void
+Context::setup_builtins ()
+{
+  auto builtins = resolver->get_builtin_types ();
+  for (auto it = builtins.begin (); it != builtins.end (); it++)
+{
+  HirId ref;
+  bool ok = tyctx->lookup_type_by_node_id ((*it)->get_node_id (), &ref);
+  rust_assert (ok);
+
+  TyTy::BaseType *lookup;
+  ok = tyctx->lookup_type (ref, &lookup);
+  rust_assert (ok);
+
+  TyTyResolveCompile::compile (this, lookup);
+}
+}
+
+hashval_t
+Context::type_hasher (tree type)
+{
+  inchash::hash hstate;
+
+  hstate.add_int (TREE_CODE (type));
+
+  if (TYPE_NAME (type))
+{
+  hashval_t record_name_hash
+   = IDENTIFIER_HASH_VALUE (DECL_NAME (TYPE_NAME (type)));
+  hstate.add_object (record_name_hash);
+}
+
+  for (tree t = TYPE_ATTRIBUTES (type); t; t = TREE_CHAIN (t))
+/* Just the identifier is adequate to distinguish.  */
+hstate.add_object (IDENTIFIER_HASH_VALUE (TREE_PURPOSE (t)));
+
+  switch (TREE_CODE (type))
+{
+case METHOD_TYPE:
+  hstate.add_object (TYPE_HASH (TYPE_METHOD_BASETYPE (type)));
+  /* FALLTHROUGH. */
+case FUNCTION_TYPE:
+  for (tree t = TYPE_ARG_TYPES (type); t; t = TREE_CHAIN (t))
+   if (TREE_VALUE (t) != error_mark_node)
+ hstate.add_object (TYPE_HASH (TREE_VALUE (t)));
+  break;
+
+case OFFSET_TYPE:
+  hstate.add_object (TYPE_HASH (TYPE_OFFSET_BASETYPE (type)));
+  break;
+
+  case ARRAY_TYPE: {
+   if (TYPE_DOMAIN (type))
+ hstate.add_object (TYPE_HASH (TYPE_DOMAIN (type)));
+   if (!AGGREGATE_TYPE_P (TREE_TYPE (type)))
+ {
+   unsigned typeless = TYPE_TYPELESS_STORAGE (type);
+   hstate.add_object (typeless);
+ }
+  }
+  break;
+
+  case INTEGER_TYPE: {
+   tree t = TYPE_MAX_VALUE (type);
+   if (!t)
+ t = TYPE_MIN_VALUE (type);
+   for (int i = 0; i < TREE_INT_CST_NUNITS (t); i++)
+ hstate.add_object (TREE_INT_CST_ELT (t, i));
+   break;
+  }
+
+case REAL_TYPE:
+  case FIXED_POINT_TYPE: {
+   unsigned prec = TYPE_PRECISION (type);
+   hstate.add_object (prec);
+   break;
+  }
+
+case VECTOR_TYPE:
+  hstate.add_poly_int (TYPE_VECTOR_SUBPARTS (type));
+  break;
+
+case RECORD_TYPE:
+case UNION_TYPE:
+  case QUAL_UNION_TYPE: {
+   for (tree t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t))
+ {
+   hashval_t name_hash = IDENTIFIER_HASH_VALUE (DECL_NAME (t));
+   hashval_t type_hash = type_hasher (TREE_TYPE (t));
+   hstate.add_object (name_hash);
+   hstate.add_object (type_hash);
+ }
+  }
+  

[PATCH Rust front-end v3 30/46] gccrs: Add unsafe checks for Rust

2022-10-26 Thread arthur . cohen
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
+// <http://www.gnu.org/licenses/>.
+
+#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",
+&

[PATCH Rust front-end v3 39/46] gccrs: These are wrappers ported from reusing gccgo

2022-10-26 Thread arthur . cohen
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 v3 40/46] gccrs: Add GCC Rust front-end Make-lang.in

2022-10-26 Thread arthur . cohen
From: Philip Herron 

This is the Makefile for our front-end.
---
 gcc/rust/Make-lang.in | 399 ++
 1 file changed, 399 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..a62e793a29d
--- /dev/null
+++ b/gcc/rust/Make-lang.in
@@ -0,0 +1,399 @@
+# 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 v3 42/46] gccrs: Add lang-spec.h

2022-10-26 Thread arthur . cohen
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..eed28b1eb06
--- /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", "@rust", 0, 1, 0},
+  {"@rust",
+   "rust1 %i %(cc1_options) %{I*} %{L*} %D %{!fsyntax-only:%(invoke_as)}", 0, 
1,
+   0},
-- 
2.37.2

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


[PATCH Rust front-end v3 43/46] gccrs: Add lang.opt

2022-10-26 Thread arthur . cohen
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..1130999d277
--- /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) 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) Warning 
LangEnabledBy(Rust,Wunused-variable, 1, 0) IntegerRange(0, 2)
+Warn when a const variable is unused.
+
+Wunused-result
+Rust Var(warn_unused_result) 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.37.2

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


[PATCH Rust front-end v3 44/46] gccrs: Add compiler driver

2022-10-26 Thread arthur . cohen
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 v3 28/46] gccrs: Add Rust type information

2022-10-26 Thread arthur . cohen
From: Philip Herron 

Contains abstractions over Rust's types, used when performing the
HIR's type-resolution.
---
 gcc/rust/typecheck/rust-tyty.cc | 2885 +++
 gcc/rust/typecheck/rust-tyty.h  | 2533 +++
 2 files changed, 5418 insertions(+)
 create mode 100644 gcc/rust/typecheck/rust-tyty.cc
 create mode 100644 gcc/rust/typecheck/rust-tyty.h

diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
new file mode 100644
index 000..3c2c6786940
--- /dev/null
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -0,0 +1,2885 @@
+// 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-tyty.h"
+#include "rust-tyty-visitor.h"
+#include "rust-tyty-call.h"
+#include "rust-hir-type-check-expr.h"
+#include "rust-hir-type-check-type.h"
+#include "rust-tyty-rules.h"
+#include "rust-tyty-cmp.h"
+#include "rust-hir-map.h"
+#include "rust-substitution-mapper.h"
+#include "rust-hir-trait-ref.h"
+#include "rust-hir-type-bounds.h"
+
+namespace Rust {
+namespace TyTy {
+
+std::string
+TypeKindFormat::to_string (TypeKind kind)
+{
+  switch (kind)
+{
+case TypeKind::INFER:
+  return "Infer";
+
+case TypeKind::ADT:
+  return "ADT";
+
+case TypeKind::STR:
+  return "STR";
+
+case TypeKind::REF:
+  return "REF";
+
+case TypeKind::POINTER:
+  return "POINTER";
+
+case TypeKind::PARAM:
+  return "PARAM";
+
+case TypeKind::ARRAY:
+  return "ARRAY";
+
+case TypeKind::SLICE:
+  return "SLICE";
+
+case TypeKind::FNDEF:
+  return "FnDef";
+
+case TypeKind::FNPTR:
+  return "FnPtr";
+
+case TypeKind::TUPLE:
+  return "Tuple";
+
+case TypeKind::BOOL:
+  return "Bool";
+
+case TypeKind::CHAR:
+  return "Char";
+
+case TypeKind::INT:
+  return "Int";
+
+case TypeKind::UINT:
+  return "Uint";
+
+case TypeKind::FLOAT:
+  return "Float";
+
+case TypeKind::USIZE:
+  return "Usize";
+
+case TypeKind::ISIZE:
+  return "Isize";
+
+case TypeKind::NEVER:
+  return "Never";
+
+case TypeKind::PLACEHOLDER:
+  return "Placeholder";
+
+case TypeKind::PROJECTION:
+  return "Projection";
+
+case TypeKind::DYNAMIC:
+  return "Dynamic";
+
+case TypeKind::CLOSURE:
+  return "Closure";
+
+case TypeKind::ERROR:
+  return "ERROR";
+}
+  gcc_unreachable ();
+}
+
+bool
+is_primitive_type_kind (TypeKind kind)
+{
+  switch (kind)
+{
+case TypeKind::BOOL:
+case TypeKind::CHAR:
+case TypeKind::INT:
+case TypeKind::UINT:
+case TypeKind::ISIZE:
+case TypeKind::USIZE:
+case TypeKind::FLOAT:
+case TypeKind::NEVER:
+case TypeKind::STR:
+  return true;
+default:
+  return false;
+}
+}
+
+bool
+BaseType::satisfies_bound (const TypeBoundPredicate &predicate) const
+{
+  const Resolver::TraitReference *query = predicate.get ();
+  for (auto &bound : specified_bounds)
+{
+  const Resolver::TraitReference *item = bound.get ();
+  bool found = item->get_mappings ().get_defid ()
+  == query->get_mappings ().get_defid ();
+  if (found)
+   return true;
+}
+
+  auto probed = Resolver::TypeBoundsProbe::Probe (this);
+  for (auto &b : probed)
+{
+  const Resolver::TraitReference *bound = b.first;
+  bool found = bound->get_mappings ().get_defid ()
+  == query->get_mappings ().get_defid ();
+  if (found)
+   return true;
+}
+
+  return false;
+}
+
+bool
+BaseType::bounds_compatible (const BaseType &other, Location locus,
+bool emit_error) const
+{
+  std::vector>
+unsatisfied_bounds;
+  for (auto &bound : get_specified_bounds ())
+{
+  if (!other.satisfies_bound (bound))
+   unsatisfied_bounds.push_back (bound);
+}
+
+  // lets emit a single error for this
+  if (unsatisfied_bounds.size () > 0)
+{
+  RichLocation r (locus);
+  std::string missing_preds;
+  for (size_t i = 0; i < unsatisfied_bounds.size (); i++)
+   {
+ const TypeBoundPredicate &pred = unsatisfied_bounds.at (i);
+ r.add_range (pred.get_locus ());
+ missing_preds += pred.get_name ();
+
+ bool have_next = (i + 1) < unsatisfied_bounds.size ();
+  

[PATCH Rust front-end v3 33/46] gccrs: Add dead code scan on HIR

2022-10-26 Thread arthur . cohen
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 v3 41/46] gccrs: Add config-lang.in

2022-10-26 Thread arthur . cohen
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.37.2

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


[PATCH Rust front-end v3 34/46] gccrs: Add unused variable scan

2022-10-26 Thread arthur . cohen
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.37.2

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


[PATCH Rust front-end v3 45/46] gccrs: Compiler proper interface kicks off the pipeline

2022-10-26 Thread arthur . cohen
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|  456 
 gcc/rust/rust-session-manager.cc | 1189 ++
 gcc/rust/rust-session-manager.h  |  358 +
 3 files changed, 2003 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..f6557474c8c
--- /dev/null
+++ b/gcc/rust/rust-lang.cc
@@ -0,0 +1,456 @@
+// 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-system.h"
+#include "rust-diagnostics.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-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 this:
+   This allows the code in d-builtin

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

2022-10-26 Thread arthur . cohen
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

Re: [PATCH Rust front-end v3 35/46] gccrs: Add metadata ouptput pass

2022-10-27 Thread Arthur Cohen

On 10/26/22 23:04, David Malcolm wrote:

%{On Wed, 2022-10-26 at 10:18 +0200, arthur.co...@embecosm.com wrote:

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:



[...snip...]


+  rust_error_at (Location (),
+    "expected metadata-output path to have base file
name of: "
+    "%<%s%> got %<%s%>",
+    expected_file_name.c_str (), path_base_name);


I can't comment on the patch in depth, but does rust_error_at call into
GCC's regular diagnostics?

If so, "%qs" is a more idiomatic way to express printing a string
argument in quotes (and bold), rather than "%<%s%>", though IIRC they
do the same thing (unless I'm missing something?).


I also believe that they do the same thing. We have some %<%s%> 
left-over from previous, more complex format strings, so good catch and 
thank you for noticing. I'll fix them up.



This shows up in a few places in this patch, and might affect other
patches in the kit - though it's a minor nitpick, of course.

Dave



OpenPGP_0x1B3465B044AD9C65.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature
-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


Re: [PATCH Rust front-end v3 40/46] gccrs: Add GCC Rust front-end Make-lang.in

2022-10-27 Thread Arthur Cohen

(...snip...)


+RUST_SELFTEST_FLAGS = -xrs $(SELFTEST_FLAGS)


I've noticed that this patch contains a typo which prevents self-tests 
from running properly. This should be `-xrust`, not `-xrs`. I assume 
there will be some other review comments, so that will be fixed in a v4 
of the patches.


Sorry about the annoyance.

(...snip...)

Kindly,

--
Arthur Cohen 

Toolchain Engineer

Embecosm GmbH

Geschäftsführer: Jeremy Bennett
Niederlassung: Nürnberg
Handelsregister: HR-B 36368
www.embecosm.de

Fürther Str. 27
90429 Nürnberg


Tel.: 091 - 128 707 040
Fax: 091 - 128 707 077


OpenPGP_0x1B3465B044AD9C65.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature
-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


Re: Rust frontend patches v3

2022-10-28 Thread Arthur Cohen

Hi David,

On 10/26/22 23:15, David Malcolm wrote:

On Wed, 2022-10-26 at 10:17 +0200, arthur.co...@embecosm.com wrote:

This is the fixed version of our previous patch set for gccrs - We've
adressed
the comments raised in our previous emails.


[...snip...]

(Caveat: I'm not a global reviewer)

Sorry if this is answered in the docs in the patch kit, but a high-
level question: what's the interaction between gccrs and gcc's garbage
collector?  Are the only GC-managed objects (such as trees) either (a)
created near the end of the gccrs, or (b) common globals created at
initialization and with GTY roots? 


We only create trees at the last point of our compilation pipeline, 
before directly writing them to the backend. This then calls a 
`write_global_definitions` method, that we ported over directly from the 
Go frontend. Among other things, this method has the role of preserving 
trees from the GC using `go_preserve_from_gc()` (or 
`rust_preserve_from_gc()` in our case).


Elsewhere in our pipeline, we never call any garbage-collection routines 
or GC-related functions.



Are there any points where a collection happen within gccrs?  Or is almost 
everything stored using
gccrs's own data structures, and are these managed in the regular (non-
GC) heap?


This is correct. We have an AST representation, implemented using unique 
pointers, which is then lowered to an HIR, also using unique pointers.



I skimmed the patches and see that gccrs uses e.g. std::vector,
std::unique_ptr, std::map, and std::string; this seems reasonable to
me, but it got me thinking about memory management strategies.

I see various std::map e.g. in Rust::Compile::Context; so e.g.
is the GC guaranteed never to collect whilst this is live?


This is a really interesting question, and I hope the answer is yes! But 
I'm unsure as to how to enforce that, as I am not too familiar with the 
GCC GC. I'm hoping someone else will weigh in. As I said, we do not do 
anything particular with the GC during the execution of our 
`CompileCrate` visitor, so hopefully it shouldn't run.



Hope this is constructive
Dave



Thanks a lot for the input,

All the best,

Arthur






OpenPGP_0x1B3465B044AD9C65.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature
-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


Re: Rust frontend patches v3

2022-10-28 Thread Arthur Cohen



On 10/28/22 15:06, David Malcolm wrote:

On Fri, 2022-10-28 at 13:48 +0200, Arthur Cohen wrote:

Hi David,

On 10/26/22 23:15, David Malcolm wrote:

On Wed, 2022-10-26 at 10:17 +0200, arthur.co...@embecosm.com wrote:

This is the fixed version of our previous patch set for gccrs -
We've
adressed
the comments raised in our previous emails.


[...snip...]

(Caveat: I'm not a global reviewer)

Sorry if this is answered in the docs in the patch kit, but a high-
level question: what's the interaction between gccrs and gcc's
garbage
collector?  Are the only GC-managed objects (such as trees) either
(a)
created near the end of the gccrs, or (b) common globals created at
initialization and with GTY roots?


We only create trees at the last point of our compilation pipeline,
before directly writing them to the backend. This then calls a
`write_global_definitions` method, that we ported over directly from
the
Go frontend. Among other things, this method has the role of
preserving
trees from the GC using `go_preserve_from_gc()` (or
`rust_preserve_from_gc()` in our case).

Elsewhere in our pipeline, we never call any garbage-collection
routines
or GC-related functions.


Are there any points where a collection happen within gccrs?  Or is
almost everything stored using
gccrs's own data structures, and are these managed in the regular
(non-
GC) heap?


This is correct. We have an AST representation, implemented using
unique
pointers, which is then lowered to an HIR, also using unique
pointers.


I skimmed the patches and see that gccrs uses e.g. std::vector,
std::unique_ptr, std::map, and std::string; this seems reasonable
to
me, but it got me thinking about memory management strategies.

I see various std::map e.g. in Rust::Compile::Context; so
e.g.
is the GC guaranteed never to collect whilst this is live?


This is a really interesting question, and I hope the answer is yes!
But
I'm unsure as to how to enforce that, as I am not too familiar with
the
GCC GC. I'm hoping someone else will weigh in. As I said, we do not
do
anything particular with the GC during the execution of our
`CompileCrate` visitor, so hopefully it shouldn't run.


I'm guessing that almost all of gccrs testing so far has been on
relatively small examples, so that even if the GC considers collecting,
the memory usage might not have exceeded the threshold for actually
doing the mark-and-sweep collection, and so no collection has been
happening during your testing.

In case you haven't tried yet, you might want to try adding:
   --param=ggc-min-expand=0 --param=ggc-min-heapsize=0
which IIRC forces the GC to actually do its mark-and-sweep collection
at every potential point where it might collect.


That's very helpful, thanks a lot. I've ran our testsuite with these and 
found no issues, but we might consider adding that to our CI setup to 
make sure.


Kindly,

Arthur


I use these params in libgccjit's test suite; it massively slows things
down, but it makes any GC misuse crash immediately even on minimal test
cases, rather than hiding problems until you have a big (and thus
nasty) test case.

Hope this is helpful
Dave





Hope this is constructive
Dave



Thanks a lot for the input,

All the best,

Arthur








OpenPGP_0x1B3465B044AD9C65.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature
-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


Re: Rust frontend patches v3

2022-11-15 Thread Arthur Cohen

Hi Richard,

On 11/10/22 11:52, Richard Biener wrote:

On Wed, Oct 26, 2022 at 10:16 AM  wrote:


This is the fixed version of our previous patch set for gccrs - We've adressed
the comments raised in our previous emails.

This patch set does not contain any work that was not previously included, such
as closure support, the constant evaluator port, or the better implementation
of target hooks by Iain Buclaw. They will follow up in subsequent patch sets.

Thanks again to Open Source Security, inc and Embecosm who have accompanied us
for this work.

Many thanks to all of the contributors and our community, who made this
possible.

A very special thanks to Philip Herron, without whose mentoring I would have
never been in a position to send these patches.

You can see the current status of our work on our branch:
https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/devel/rust/master

The patch set contains the following:


Can you mark the patches that have been reviewed/approved?  Can you
maybe either split the series or organize it in a way to separate the
pieces touching common parts of GCC from the gcc/rust/ parts?
Can you separate testsuite infrastructure from actual tests, can
you mark/separate target specific changes?  And for those (then small)
changes CC the appropriate maintainers?


Thanks a lot for all the feedback. I'll apply the required changes and 
make sure the patchset(s) are a bit easier to review.


All the best,

Arthur



Thanks,
Richard.


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



--
Arthur Cohen 

Toolchain Engineer

Embecosm GmbH

Geschäftsführer: Jeremy Bennett
Niederlassung: Nürnberg
Handelsregister: HR-B 36368
www.embecosm.de

Fürther Str. 27
90429 Nürnberg


Tel.: 091 - 128 707 040
Fax: 091 - 128 707 077


OpenPGP_0x1B3465B044AD9C65.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature
-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


Re: [PATCH Rust front-end v3 38/46] gccrs: Add HIR to GCC GENERIC lowering entry point

2022-11-15 Thread Arthur Cohen



On 11/9/22 14:53, Richard Biener wrote:

On Wed, Oct 26, 2022 at 10:37 AM  wrote:


From: Philip Herron 

This patch contains the entry point and utilities used for the lowering
of HIR nodes to `tree`s. It also contains a constant evaluator, ported
over from the C++ frontend.

Co-authored-by: David Faust 
Co-authored-by: Faisal Abbas <90.abbasfai...@gmail.com>
---
  gcc/rust/backend/rust-compile-context.cc | 146 
  gcc/rust/backend/rust-compile-context.h  | 343 ++
  gcc/rust/backend/rust-compile.cc | 414 +
  gcc/rust/backend/rust-compile.h  |  47 +++
  gcc/rust/backend/rust-constexpr.cc   | 441 +++
  gcc/rust/backend/rust-constexpr.h|  31 ++
  6 files changed, 1422 insertions(+)
  create mode 100644 gcc/rust/backend/rust-compile-context.cc
  create mode 100644 gcc/rust/backend/rust-compile-context.h
  create mode 100644 gcc/rust/backend/rust-compile.cc
  create mode 100644 gcc/rust/backend/rust-compile.h
  create mode 100644 gcc/rust/backend/rust-constexpr.cc
  create mode 100644 gcc/rust/backend/rust-constexpr.h

diff --git a/gcc/rust/backend/rust-compile-context.cc 
b/gcc/rust/backend/rust-compile-context.cc
new file mode 100644
index 000..cb2addf6c21
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-context.cc
@@ -0,0 +1,146 @@
+// 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-compile-context.h"
+#include "rust-compile-type.h"
+
+namespace Rust {
+namespace Compile {
+
+Context::Context (::Backend *backend)
+  : backend (backend), resolver (Resolver::Resolver::get ()),
+tyctx (Resolver::TypeCheckContext::get ()),
+mappings (Analysis::Mappings::get ()), mangler (Mangler ())
+{
+  setup_builtins ();
+}
+
+void
+Context::setup_builtins ()
+{
+  auto builtins = resolver->get_builtin_types ();
+  for (auto it = builtins.begin (); it != builtins.end (); it++)
+{
+  HirId ref;
+  bool ok = tyctx->lookup_type_by_node_id ((*it)->get_node_id (), &ref);
+  rust_assert (ok);
+
+  TyTy::BaseType *lookup;
+  ok = tyctx->lookup_type (ref, &lookup);
+  rust_assert (ok);
+
+  TyTyResolveCompile::compile (this, lookup);
+}
+}
+
+hashval_t
+Context::type_hasher (tree type)
+{
+  inchash::hash hstate;
+
+  hstate.add_int (TREE_CODE (type));
+
+  if (TYPE_NAME (type))
+{
+  hashval_t record_name_hash
+   = IDENTIFIER_HASH_VALUE (DECL_NAME (TYPE_NAME (type)));
+  hstate.add_object (record_name_hash);
+}


The following does look a bit like type_hash_canon_hash.  I'll probably see what
we use tree type hashing for, just wondering here.


+  for (tree t = TYPE_ATTRIBUTES (type); t; t = TREE_CHAIN (t))
+/* Just the identifier is adequate to distinguish.  */
+hstate.add_object (IDENTIFIER_HASH_VALUE (TREE_PURPOSE (t)));
+
+  switch (TREE_CODE (type))
+{
+case METHOD_TYPE:
+  hstate.add_object (TYPE_HASH (TYPE_METHOD_BASETYPE (type)));
+  /* FALLTHROUGH. */
+case FUNCTION_TYPE:
+  for (tree t = TYPE_ARG_TYPES (type); t; t = TREE_CHAIN (t))
+   if (TREE_VALUE (t) != error_mark_node)
+ hstate.add_object (TYPE_HASH (TREE_VALUE (t)));
+  break;
+
+case OFFSET_TYPE:
+  hstate.add_object (TYPE_HASH (TYPE_OFFSET_BASETYPE (type)));
+  break;
+
+  case ARRAY_TYPE: {


GCC coding conventions would say the { goes to the next line and indented.
The rust FE might intentionally diverge from that standard, if so a
pointer in some
README in rust/ would be helpful.


This is not our intention. We would like to stick to the GCC coding 
convention, and use a `.clang-format` file to do so and apply it before 
merging any code. However it clearly has some limitations. I'll be on 
the lookout for these patterns and fix them by hand, or try and figure 
out how to edit the clang-format file.



+   if (TYPE_DOMAIN (type))
+ hstate.add_object (TYPE_HASH (TYPE_DOMAIN (type)));
+   if (!AGGREGATE_TYPE_P (TREE_TYPE (type)))
+ {
+   unsigned typeless = TYPE_TYPELESS_STORAGE (type);
+   hstate.add_object (typeless);
+ }
+  }
+  break;
+
+  case INTEGER_TYPE: {
+   tree t = TYPE_MAX_VALUE (type);
+   if (!t)
+ t = TYPE_MIN_VALUE (type);
+   for (int i = 0; i < TREE_INT_

Re: [PATCH Rust front-end v3 38/46] gccrs: Add HIR to GCC GENERIC lowering entry point

2022-11-29 Thread Arthur Cohen

Hi Richard,

(...)


+
+  unsigned HOST_WIDE_INT ltype_length
+= wi::ext (wi::to_offset (TYPE_MAX_VALUE (ltype_domain))
+- wi::to_offset (TYPE_MIN_VALUE (ltype_domain)) + 1,


TYPE_MIN_VALUE is not checked to be constant, also the correct
check would be to use TREE_CODE (..) == INTEGER_CST, in
the GCC middle-end an expression '1 + 2' (a PLUS_EXPR) would
be TREE_CONSTANT but wi::to_offset would ICE.


+  TYPE_PRECISION (TREE_TYPE (ltype_domain)),
+  TYPE_SIGN (TREE_TYPE (ltype_domain)))
+   .to_uhwi ();


.to_uhwi will just truncate if the value doesn't fit, the same result as
above is achieved with

   unsigned HOST_WIDE_INT ltype_length
  = TREE_INT_CST_LOW (TYPE_MAX_VALUE (..))
- TREE_INT_CST_LOW (TYPE_MIN_VALUE (...)) + 1;

so it appears you wanted to be "more correct" here (but if I see
correctly you fail on that attempt)?



I've made the changes you proposed and noticed failure on our 32-bit CI.

I've had a look at the values in detail, and it seems that truncating 
was the expected behavior.


On our 64 bit CI, with a testcase containing an array of zero elements, 
we get the following values:


TREE_INT_CST_LOW(TYPE_MAX_VALUE(...)) = 18446744073709551615;
TREE_INT_CST_LOW(TYPE_MIN_VALUE(...)) = 0;

Adding 1 to the result of the substraction results in an overflow, 
wrapping back to zero.


With the -m32 flag, we get the following values:

TREE_INT_CST_LOW(TYPE_MAX_VALUE(...)) = 4294967295;
TREE_INT_CST_LOW(TYPE_MIN_VALUE(...)) = 0;

The addition of 1 does not overflow the unsigned HOST_WIDE_INT type and 
we end up with 4294967296 as the length of our array.


I am not sure on how to fix this behavior, and whether or not it is the 
expected one, nor am I familiar enough with the tree API to reproduce 
the original behavior. Any input is welcome.


In the meantime, I'll revert those changes and probably keep the 
existing code in the patches if that's okay with you.



Overall this part of the rust frontend looks OK.  Take the comments as
suggestions (for future
enhancements).


Which seems to be the case :)

The v4 of patches, which contains a lot of fixes for the issues you 
mentioned, will be sent soon.


All the best,

Arthur


OpenPGP_0x1B3465B044AD9C65.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature
-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


December community call

2022-12-02 Thread arthur . cohen
Hi everyone, We're trying a new slot for the monthly community call which  
should hopefully allow even more people to join. Feel free to answer with a  
better time and we'll try to work towards that, or bring back the second  
monthly call for US timezones. All the best


December community call
Monday 12 Dec 2022 ⋅ 11am – 12pm
Central European Time - Paris



https://meet.jit.si/gccrs-community-call-december

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


Invitation: December community call @ Mon 12 Dec 2022 11am - 12pm (CET) (gcc-rust@gcc.gnu.org)

2022-12-02 Thread arthur . cohen
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:REQUEST
BEGIN:VEVENT
DTSTART:20221212T10Z
DTEND:20221212T11Z
DTSTAMP:20221202T111250Z
ORGANIZER;CN=gccrs:mailto:7060a0923ffebd3cb52b1afef35a28ff7b64f05962c9af84c
 23b1847f1f5f...@group.calendar.google.com
UID:73jobcni5rchcoqmd49r30g...@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=
 TRUE;CN=gcc-rust@gcc.gnu.org;X-NUM-GUESTS=0:mailto:gcc-rust@gcc.gnu.org
X-GOOGLE-CONFERENCE:https://meet.google.com/ycu-ehnr-xdr
X-MICROSOFT-CDO-OWNERAPPTID:1846180395
CREATED:20221202T110331Z
DESCRIPTION:https://meet.jit.si/gccrs-community-call-december";>htt
 ps://meet.jit.si/gccrs-community-call-december\n\n-::~:~::~:~:~:~:~:~:~
 :~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~::~:~::-\nJoin wi
 th Google Meet: https://meet.google.com/ycu-ehnr-xdr\nOr dial: (FR) +33 1 8
 7 40 18 13 PIN: 708094785#\nMore phone numbers: https://tel.meet/ycu-ehnr-x
 dr?pin=2973778670084&hs=7\n\nLearn more about Meet at: https://support.goog
 le.com/a/users/answer/9282720\n\nPlease do not edit this section.\n-::~:~::
 ~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~::~:
 ~::-
LAST-MODIFIED:20221202T111249Z
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:December community call
TRANSP:OPAQUE
BEGIN:VALARM
ACTION:DISPLAY
DESCRIPTION:This is an event reminder
TRIGGER:-P0DT0H30M0S
END:VALARM
BEGIN:VALARM
ACTION:DISPLAY
DESCRIPTION:This is an event reminder
TRIGGER:-P0DT1H0M0S
END:VALARM
END:VEVENT
END:VCALENDAR


invite.ics
Description: application/ics
-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


Rust front-end patches v4

2022-12-06 Thread arthur . cohen
This patchset contains the fixed version of our most recent patchset. We
have fixed most of the issues noted in the previous round of reviews, and are
keeping some for later as they would otherwise create too many conflicts with
our updated development branch.

Similarly to the previous round of patches, this patchset does not contain any
new features - only fixes for the reviews of the v3. New features will follow
shortly once that first patchset is merged.

Once again, thank you to all the contributors who made this possible and
especially to Philip Herron for his dedication to the project.

You can see the current status of our work on our branch:
https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/devel/rust/master

Patch status table:

An 'x' in the first column indicates a patch has been reviewed.
One in the second column indicates that a patch has been approved.

|0001-Use-DW_ATE_UTF-for-the-Rust-char-type.patch   |x|x|
|0002-gccrs-Add-necessary-hooks-for-a-Rust-front-end-tests.patch|x|x|
|0003-gccrs-Add-Debug-info-testsuite.patch  | | |
|0004-gccrs-Add-link-cases-testsuite.patch  | | |
|0005-gccrs-Add-general-compilation-test-cases.patch| | |
|0006-gccrs-Add-execution-test-cases.patch  | | |
|0007-gccrs-Add-gcc-check-target-check-rust.patch   |x| |
|0008-gccrs-Add-Rust-front-end-base-AST-data-structures.patch   | | |
|0009-gccrs-Add-definitions-of-Rust-Items-in-AST-data-stru.patch| | |
|0010-gccrs-Add-full-definitions-of-Rust-AST-data-structur.patch| | |
|0011-gccrs-Add-Rust-AST-visitors.patch | | |
|0012-gccrs-Add-Lexer-for-Rust-front-end.patch  |x| |
|0013-gccrs-Add-Parser-for-Rust-front-end-pt.1.patch| | |
|0014-gccrs-Add-Parser-for-Rust-front-end-pt.2.patch| | |
|0015-gccrs-Add-expansion-pass-for-the-Rust-front-end.patch | | |
|0016-gccrs-Add-name-resolution-pass-to-the-Rust-front-end.patch| | |
|0017-gccrs-Add-declarations-for-Rust-HIR.patch | | |
|0018-gccrs-Add-HIR-definitions-and-visitor-framework.patch | | |
|0019-gccrs-Add-AST-to-HIR-lowering-pass.patch  | | |
|0020-gccrs-Add-wrapper-for-make_unique.patch   | | |
|0021-gccrs-Add-port-of-FNV-hash-used-during-legacy-symbol.patch| | |
|0022-gccrs-Add-Rust-ABI-enum-helpers.patch | | |
|0023-gccrs-Add-Base62-implementation.patch | | |
|0024-gccrs-Add-implementation-of-Optional.patch| | |
|0025-gccrs-Add-attributes-checker.patch| | |
|0026-gccrs-Add-helpers-mappings-canonical-path-and-lang-i.patch| | |
|0027-gccrs-Add-type-resolution-and-trait-solving-pass.patch| | |
|0028-gccrs-Add-Rust-type-information.patch | | |
|0029-gccrs-Add-remaining-type-system-transformations.patch | | |
|0030-gccrs-Add-unsafe-checks-for-Rust.patch| | |
|0031-gccrs-Add-const-checker.patch | | |
|0032-gccrs-Add-privacy-checks.patch| | |
|0033-gccrs-Add-dead-code-scan-on-HIR.patch | | |
|0034-gccrs-Add-unused-variable-scan.patch  | | |
|0035-gccrs-Add-metadata-output-pass.patch  | | |
|0036-gccrs-Add-base-for-HIR-to-GCC-GENERIC-lowering.patch  | | |
|0037-gccrs-Add-HIR-to-GCC-GENERIC-lowering-for-all-nodes.patch |x|x|
|0038-gccrs-Add-HIR-to-GCC-GENERIC-lowering-entry-point.patch   |x|x|
|0039-gccrs-These-are-wrappers-ported-from-reusing-gccgo.patch  | | |
|0040-gccrs-Add-GCC-Rust-front-end-Make-lang.in.patch   |x| |
|0041-gccrs-Add-config-lang.in.patch|x|x|
|0042-gccrs-Add-lang-spec.h.patch   | | |
|0043-gccrs-Add-lang.opt.patch  |x| |
|0044-gccrs-Add-compiler-driver.patch   | | |
|0045-gccrs-Compiler-proper-interface-kicks-off-the-pipeli.patch| | |
|0046-gccrs-Add-README-CONTRIBUTING-and-compiler-logo.patch | | |

Patches 34 to 39 and 44 to 45 interact with common GCC APIs:

0034-gccrs-Add-unused-variable-scan.patch
0035-gccrs-Add-metadata-output-pass.patch
0036-gccrs-Add-base-for-HIR-to-GCC-GENERIC-lowering.patch
0037-gccrs-Add-HIR-to-GCC-GENERIC-lowering-for-all-nodes.patch 
0038-gccrs-Add-HIR-to-GCC-GENERIC-lowering-entry-point.patch 
0039-gccrs-These-are-wrappers-ported-from-reusing-gccgo.patch
0044-gccrs-Add-compiler-driver.patch 
0045-gccrs-Compiler-proper-interface-kicks-off-the-pipeli.patch

Patch 02 and 07 contain test infrastructure changes:

0002-gccrs-Add-necessary-hooks-for-a-Rust-front-end-tests.patch
0007-gccrs-Add-gcc-check-target-check-rust.patch

Patch 03 to 06 contain Rust test cases:

0003-gccrs-Add-Debug-info-testsuite.patch
0004-gccrs-Add-link-cases-testsuite.patch
0005-gccrs-Add-general-compilation-test-cases.patch
0006-gccrs-Add-execution-test-cases.patch

Patch

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

2022-12-06 Thread arthur . cohen
From: Tom Tromey 

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

Co-authored-by: Mark Wielaard 
Co-authored-by: Marc Poulhiès 
---
 gcc/dwarf2out.cc | 19 ++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index e3920c898f5..0d8dd4f1767 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -5600,6 +5600,17 @@ is_fortran (const_tree decl)
   return is_fortran ();
 }
 
+/* Return TRUE if the language is Rust.
+   Note, returns FALSE for dwarf_version < 5 && dwarf_strict. */
+
+static inline bool
+is_rust ()
+{
+  unsigned int lang = get_AT_unsigned (comp_unit_die (), DW_AT_language);
+
+  return lang == DW_LANG_Rust;
+}
+
 /* Return TRUE if the language is Ada.  */
 
 static inline bool
@@ -13231,7 +13242,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;
@@ -25226,6 +25241,8 @@ gen_compile_unit_die (const char *filename)
{
  if (strcmp (language_string, "GNU Go") == 0)
language = DW_LANG_Go;
+ else if (strcmp (language_string, "GNU Rust") == 0)
+   language = DW_LANG_Rust;
}
 }
   /* Use a degraded Fortran setting in strict DWARF2 so is_fortran works.  */
-- 
2.38.1

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


[PATCH Rust front-end v4 02/46] gccrs: Add necessary hooks for a Rust front-end testsuite

2022-12-06 Thread arthur . cohen
From: Philip Herron 

This copies 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 v4 04/46] gccrs: Add link cases testsuite

2022-12-06 Thread arthur . cohen
From: Philip Herron 

This testsuite is heavily inspired from the LTO testsuite that uses a
pattern where 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. This leaves 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 v4 07/46] gccrs: Add gcc-check-target check-rust

2022-12-06 Thread arthur . cohen
From: Philip Herron 

This allows us to invoke the rust testsuite.

ChangeLog:
* Makefile.def: Add Rust language.
* 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.38.1

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


[PATCH Rust front-end v4 03/46] gccrs: Add Debug info testsuite

2022-12-06 Thread arthur . cohen
From: Philip Herron 

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

Co-authored-by: Tom Tromey 
Co-authored-by: Mark Wielaard 
Co-authored-by: Marc Poulhiès 
---
 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" }
+  

[PATCH Rust front-end v4 12/46] gccrs: Add Lexer for Rust front-end

2022-12-06 Thread arthur . cohen
From: The Other 

The lexer is referred 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   | 2728 
 gcc/rust/lex/rust-lex.h|  271 
 gcc/rust/lex/rust-token.cc |  134 ++
 gcc/rust/lex/rust-token.h  |  450 ++
 gcc/rust/rust-buffered-queue.h |  204 +++
 6 files changed, 3833 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..1a9f0ca7a21
--- /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
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_CODEPOINT_H
+#define RUST_CODEPOINT_H
+
+#include "rust-system.h"
+
+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..82949f5fe5f
--- /dev/null
+++ b/gcc/rust/lex/rust-lex.cc
@@ -0,0 +1,2728 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-system.h"
+#include "rust-lex.h"
+#include "rust-diagnostics.h"
+#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);

[PATCH Rust front-end v4 21/46] gccrs: Add port of FNV hash used during legacy symbol mangling

2022-12-06 Thread arthur . cohen
From: Philip Herron 

This hash was ported from the Go runtime, as we needed a hash for the legacy
symbol mangling system. 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.38.1

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


[PATCH Rust front-end v4 11/46] gccrs: Add Rust AST visitors

2022-12-06 Thread arthur . cohen
From: The Other 

This patch contains the basic framework of our AST visitors, as well as
one aimed at pretty-printing and exporting these AST nodes.

Co-authored-by: Philip Herron 
Co-authored-by: Arthur Cohen 
---
 gcc/rust/ast/rust-ast-dump.cc| 1089 ++
 gcc/rust/ast/rust-ast-dump.h |  246 ++
 gcc/rust/ast/rust-ast-visitor.h  |  234 ++
 gcc/rust/ast/rust-cond-compilation.h |  249 ++
 4 files changed, 1818 insertions(+)
 create mode 100644 gcc/rust/ast/rust-ast-dump.cc
 create mode 100644 gcc/rust/ast/rust-ast-dump.h
 create mode 100644 gcc/rust/ast/rust-ast-visitor.h
 create mode 100644 gcc/rust/ast/rust-cond-compilation.h

diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
new file mode 100644
index 000..ad9ad0b7de7
--- /dev/null
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -0,0 +1,1089 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-ast-dump.h"
+
+namespace Rust {
+namespace AST {
+
+Indent::Indent () : tabs (0) {}
+
+std::ostream &
+operator<< (std::ostream &stream, const Indent &indent)
+{
+  return stream << std::string (indent.tabs, '\t');
+}
+
+void
+Indent::increment ()
+{
+  tabs++;
+}
+
+void
+Indent::decrement ()
+{
+  rust_assert (tabs != 0);
+  tabs--;
+}
+
+Dump::Dump (std::ostream &stream) : stream (stream), indentation (Indent ()) {}
+
+void
+Dump::go (AST::Crate &crate)
+{
+  for (auto &item : crate.items)
+{
+  stream << indentation;
+  item->accept_vis (*this);
+  stream << "\n";
+}
+}
+
+void
+Dump::go (AST::Item &item)
+{
+  item.accept_vis (*this);
+}
+
+void
+Dump::format_function_param (FunctionParam ¶m)
+{
+  param.get_pattern ()->accept_vis (*this);
+  stream << ": ";
+  param.get_type ()->accept_vis (*this);
+}
+
+void
+Dump::emit_attrib (const Attribute &attrib)
+{
+  stream << "#";
+  stream << "[";
+
+  for (size_t i = 0; i < attrib.get_path ().get_segments ().size (); i++)
+{
+  const auto &seg = attrib.get_path ().get_segments ().at (i);
+  bool has_next = (i + 1) < attrib.get_path ().get_segments ().size ();
+
+  stream << seg.get_segment_name ();
+  if (has_next)
+   stream << "::";
+}
+
+  if (attrib.has_attr_input ())
+{
+  stream << " = ";
+
+  bool is_literal = attrib.get_attr_input ().get_attr_input_type ()
+   == AST::AttrInput::AttrInputType::LITERAL;
+  if (is_literal)
+   {
+ auto &literal
+   = static_cast (attrib.get_attr_input ());
+ const auto &value = literal.get_literal ().as_string ();
+
+ stream << "\"" << value << "\"";
+   }
+  else
+   {
+ stream << "FIXME";
+   }
+}
+
+  stream << "]";
+}
+
+void
+Dump::visit (Token &tok)
+{}
+
+void
+Dump::visit (DelimTokenTree &delim_tok_tree)
+{}
+
+void
+Dump::visit (AttrInputMetaItemContainer &input)
+{}
+
+void
+Dump::visit (IdentifierExpr &ident_expr)
+{
+  stream << ident_expr.get_ident ();
+}
+
+void
+Dump::visit (Lifetime &lifetime)
+{}
+
+void
+Dump::visit (LifetimeParam &lifetime_param)
+{}
+
+void
+Dump::visit (ConstGenericParam &lifetime_param)
+{}
+
+// rust-path.h
+void
+Dump::visit (PathInExpression &path)
+{}
+
+void
+Dump::visit (TypePathSegment &segment)
+{}
+
+void
+Dump::visit (TypePathSegmentGeneric &segment)
+{}
+
+void
+Dump::visit (TypePathSegmentFunction &segment)
+{}
+
+void
+Dump::visit (TypePath &path)
+{
+  stream << path.as_string ();
+}
+
+void
+Dump::visit (QualifiedPathInExpression &path)
+{}
+
+void
+Dump::visit (QualifiedPathInType &path)
+{}
+
+// rust-expr.h
+void
+Dump::visit (LiteralExpr &expr)
+{
+  stream << expr.as_string ();
+}
+
+void
+Dump::visit (AttrInputLiteral &attr_input)
+{}
+
+void
+Dump::visit (MetaItemLitExpr &meta_item)
+{}
+
+void
+Dump::visit (MetaItemPathLit &meta_item)
+{}
+
+void
+Dump::visit (BorrowExpr &expr)
+{}
+
+void
+Dump::visit (DereferenceExpr &expr)
+{}

[PATCH Rust front-end v4 09/46] gccrs: Add definitions of Rust Items in AST data structures

2022-12-06 Thread arthur . cohen
From: The Other 

This adds the proper definitions of our AST Item nodes.

Co-authored-by: Philip Herron 
---
 gcc/rust/ast/rust-item.h | 4382 ++
 1 file changed, 4382 insertions(+)
 create mode 100644 gcc/rust/ast/rust-item.h

diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
new file mode 100644
index 000..4987674cba1
--- /dev/null
+++ b/gcc/rust/ast/rust-item.h
@@ -0,0 +1,4382 @@
+// 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_AST_ITEM_H
+#define RUST_AST_ITEM_H
+
+#include "rust-ast.h"
+#include "rust-path.h"
+#include "rust-common.h"
+
+namespace Rust {
+namespace AST {
+// forward decls
+class BlockExpr;
+class TypePath;
+
+// TODO: inline?
+/*struct AbiName {
+std::string abi_name;
+// Technically is meant to be STRING_LITERAL
+
+  public:
+// Returns whether abi name is empty, i.e. doesn't exist.
+bool is_empty() const {
+   return abi_name.empty();
+}
+
+AbiName(std::string name) : abi_name(std::move(name)) {}
+
+// Empty AbiName constructor
+AbiName() {}
+};*/
+
+// A type generic parameter (as opposed to a lifetime generic parameter)
+class TypeParam : public GenericParam
+{
+  // bool has_outer_attribute;
+  // std::unique_ptr outer_attr;
+  Attribute outer_attr;
+
+  Identifier type_representation;
+
+  // bool has_type_param_bounds;
+  // TypeParamBounds type_param_bounds;
+  std::vector>
+type_param_bounds; // inlined form
+
+  // bool has_type;
+  std::unique_ptr type;
+
+  Location locus;
+
+public:
+  Identifier get_type_representation () const { return type_representation; }
+
+  // Returns whether the type of the type param has been specified.
+  bool has_type () const { return type != nullptr; }
+
+  // Returns whether the type param has type param bounds.
+  bool has_type_param_bounds () const { return !type_param_bounds.empty (); }
+
+  // Returns whether the type param has an outer attribute.
+  bool has_outer_attribute () const { return !outer_attr.is_empty (); }
+
+  TypeParam (Identifier type_representation, Location locus = Location (),
+std::vector> type_param_bounds
+= std::vector> (),
+std::unique_ptr type = nullptr,
+Attribute outer_attr = Attribute::create_empty ())
+: GenericParam (Analysis::Mappings::get ()->get_next_node_id ()),
+  outer_attr (std::move (outer_attr)),
+  type_representation (std::move (type_representation)),
+  type_param_bounds (std::move (type_param_bounds)),
+  type (std::move (type)), locus (locus)
+  {}
+
+  // Copy constructor uses clone
+  TypeParam (TypeParam const &other)
+: GenericParam (other.node_id), outer_attr (other.outer_attr),
+  type_representation (other.type_representation), locus (other.locus)
+  {
+// guard to prevent null pointer dereference
+if (other.type != nullptr)
+  type = other.type->clone_type ();
+
+type_param_bounds.reserve (other.type_param_bounds.size ());
+for (const auto &e : other.type_param_bounds)
+  type_param_bounds.push_back (e->clone_type_param_bound ());
+  }
+
+  // Overloaded assignment operator to clone
+  TypeParam &operator= (TypeParam const &other)
+  {
+type_representation = other.type_representation;
+outer_attr = other.outer_attr;
+locus = other.locus;
+node_id = other.node_id;
+
+// guard to prevent null pointer dereference
+if (other.type != nullptr)
+  type = other.type->clone_type ();
+else
+  type = nullptr;
+
+type_param_bounds.reserve (other.type_param_bounds.size ());
+for (const auto &e : other.type_param_bounds)
+  type_param_bounds.push_back (e->clone_type_param_bound ());
+
+return *this;
+  }
+
+  // move constructors
+  TypeParam (TypeParam &&other) = default;
+  TypeParam &operator= (TypeParam &&other) = default;
+
+  std::string as_string () const override;
+
+  Location get_locus () const override final { return locus; }
+
+  Kind get_kind () const override final { return Kind::Type; }
+
+  void accept_vis (ASTVisitor &vis) override;
+
+  // TODO: is this better? Or is a "vis_block" better?
+  std::unique_ptr &get_type ()
+  {
+rust_assert (type != nullptr);
+return type;
+  }
+
+  // TODO: mutable getter seems kinda dodgy
+  std::vector> &get_t

[PATCH Rust front-end v4 18/46] gccrs: Add HIR definitions and visitor framework

2022-12-06 Thread arthur . cohen
From: Philip Herron 

This patch implements the classes mentioned in the previous HIR patch,
as well as a set of visitor frameworks used in handling that HIR.
---
 gcc/rust/hir/tree/rust-hir-full-decls.h |  232 +
 gcc/rust/hir/tree/rust-hir-full-test.cc | 5292 +++
 gcc/rust/hir/tree/rust-hir-full.h   |   30 +
 gcc/rust/hir/tree/rust-hir-visitor.h|  493 +++
 gcc/rust/hir/tree/rust-hir.h|  921 
 5 files changed, 6968 insertions(+)
 create mode 100644 gcc/rust/hir/tree/rust-hir-full-decls.h
 create mode 100644 gcc/rust/hir/tree/rust-hir-full-test.cc
 create mode 100644 gcc/rust/hir/tree/rust-hir-full.h
 create mode 100644 gcc/rust/hir/tree/rust-hir-visitor.h
 create mode 100644 gcc/rust/hir/tree/rust-hir.h

diff --git a/gcc/rust/hir/tree/rust-hir-full-decls.h 
b/gcc/rust/hir/tree/rust-hir-full-decls.h
new file mode 100644
index 000..2798ba9fd84
--- /dev/null
+++ b/gcc/rust/hir/tree/rust-hir-full-decls.h
@@ -0,0 +1,232 @@
+// 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_HIR_FULL_DECLS_H
+#define RUST_HIR_FULL_DECLS_H
+
+namespace Rust {
+namespace HIR {
+
+struct Literal;
+class Stmt;
+class Item;
+class Expr;
+class ExprWithoutBlock;
+class Pattern;
+class Type;
+class TypeNoBounds;
+class TypeParamBound;
+class Lifetime;
+class GenericParam;
+class LifetimeParam;
+
+class TraitItem;
+class ImplItem;
+struct Crate;
+class PathExpr;
+
+// rust-path.h
+class PathIdentSegment;
+struct GenericArgsBinding;
+struct GenericArgs;
+class PathExprSegment;
+class PathPattern;
+class PathInExpression;
+class TypePathSegment;
+class TypePathSegmentGeneric;
+struct TypePathFunction;
+class TypePathSegmentFunction;
+class TypePath;
+struct QualifiedPathType;
+class QualifiedPathInExpression;
+class QualifiedPathInType;
+
+// rust-expr.h
+class ExprWithBlock;
+class LiteralExpr;
+class AttrInputLiteral;
+class OperatorExpr;
+class BorrowExpr;
+class DereferenceExpr;
+class ErrorPropagationExpr;
+class NegationExpr;
+class ArithmeticOrLogicalExpr;
+class ComparisonExpr;
+class LazyBooleanExpr;
+class TypeCastExpr;
+class AssignmentExpr;
+class CompoundAssignmentExpr;
+class GroupedExpr;
+class ArrayElems;
+class ArrayElemsValues;
+class ArrayElemsCopied;
+class ArrayExpr;
+class ArrayIndexExpr;
+class TupleExpr;
+class TupleIndexExpr;
+class StructExpr;
+class StructExprStruct;
+struct StructBase;
+class StructExprField;
+class StructExprFieldIdentifier;
+class StructExprFieldWithVal;
+class StructExprFieldIdentifierValue;
+class StructExprFieldIndexValue;
+class StructExprStructFields;
+class StructExprStructBase;
+class CallExpr;
+class MethodCallExpr;
+class FieldAccessExpr;
+struct ClosureParam;
+class ClosureExpr;
+class ClosureExprInner;
+class BlockExpr;
+class ClosureExprInnerTyped;
+class ContinueExpr;
+class BreakExpr;
+class RangeExpr;
+class RangeFromToExpr;
+class RangeFromExpr;
+class RangeToExpr;
+class RangeFullExpr;
+class RangeFromToInclExpr;
+class RangeToInclExpr;
+class ReturnExpr;
+class UnsafeBlockExpr;
+class LoopLabel;
+class BaseLoopExpr;
+class LoopExpr;
+class WhileLoopExpr;
+class WhileLetLoopExpr;
+class ForLoopExpr;
+class IfExpr;
+class IfExprConseqElse;
+class IfExprConseqIf;
+class IfLetExpr;
+class IfExprConseqIfLet;
+class IfLetExprConseqElse;
+class IfLetExprConseqIf;
+class IfLetExprConseqIfLet;
+struct MatchArm;
+// class MatchCase;
+// class MatchCaseBlockExpr;
+// class MatchCaseExpr;
+struct MatchCase;
+class MatchExpr;
+class AwaitExpr;
+class AsyncBlockExpr;
+
+// rust-stmt.h
+class EmptyStmt;
+class LetStmt;
+class ExprStmt;
+class ExprStmtWithoutBlock;
+class ExprStmtWithBlock;
+
+// rust-item.h
+class TypeParam;
+class ConstGenericParam;
+class WhereClauseItem;
+class LifetimeWhereClauseItem;
+class TypeBoundWhereClauseItem;
+struct WhereClause;
+struct SelfParam;
+struct FunctionQualifiers;
+struct FunctionParam;
+struct Visibility;
+class VisItem;
+class Module;
+class ExternCrate;
+class UseTree;
+class UseTreeGlob;
+class UseTreeList;
+class UseTreeRebind;
+class UseDeclaration;
+class Function;
+class TypeAlias;
+class Struct;
+struct StructField;
+class StructStruct;
+struct TupleField;
+class TupleStruct;
+class EnumItem;
+class EnumItemTuple;
+class EnumItemStruct;
+class EnumItemDiscriminant;
+class Enum;
+class Union;
+class ConstantI

[PATCH Rust front-end v4 24/46] gccrs: Add implementation of Optional

2022-12-06 Thread arthur . cohen
From: Arthur Cohen 

This adds an Optional class to improve error handling.
---
 gcc/rust/util/rust-optional-test.cc | 110 +++
 gcc/rust/util/rust-optional.h   | 278 
 2 files changed, 388 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..43fa175fa40
--- /dev/null
+++ b/gcc/rust/util/rust-optional-test.cc
@@ -0,0 +1,110 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-system.h"
+#include "rust-optional.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
+// <http://www.gnu.org/licenses/>.
+
+#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 real

[PATCH Rust front-end v4 23/46] gccrs: Add Base62 implementation

2022-12-06 Thread arthur . cohen
From: Arthur Cohen 

Used for V0 symbol mangling scheme which is still in development.
---
 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
+// <http://www.gnu.org/licenses/>.
+
+#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
+// <http://www.gnu.org/licenses/>.
+
+#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.38.1

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


[PATCH Rust front-end v4 25/46] gccrs: Add attributes checker

2022-12-06 Thread arthur . cohen
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..b73e9534414
--- /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
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-system.h"
+#include "rust-attributes.h"
+#include "rust-ast.h"
+#include "rust-ast-full.h"
+#include "rust-diagnostics.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'

[PATCH Rust front-end v4 33/46] gccrs: Add dead code scan on HIR

2022-12-06 Thread arthur . cohen
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 v4 30/46] gccrs: Add unsafe checks for Rust

2022-12-06 Thread arthur . cohen
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
+// <http://www.gnu.org/licenses/>.
+
+#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",
+&

[PATCH Rust front-end v4 26/46] gccrs: Add helpers mappings canonical path and lang items

2022-12-06 Thread arthur . cohen
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 v4 31/46] gccrs: Add const checker

2022-12-06 Thread arthur . cohen
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
+// <http://www.gnu.org/licenses/>.
+
+#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);
+}

[PATCH Rust front-end v4 28/46] gccrs: Add Rust type information

2022-12-06 Thread arthur . cohen
From: Philip Herron 

Contains abstractions over Rust's types, used when performing the
HIR's type-resolution.
---
 gcc/rust/typecheck/rust-tyty.cc | 2885 +++
 gcc/rust/typecheck/rust-tyty.h  | 2533 +++
 2 files changed, 5418 insertions(+)
 create mode 100644 gcc/rust/typecheck/rust-tyty.cc
 create mode 100644 gcc/rust/typecheck/rust-tyty.h

diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
new file mode 100644
index 000..3c2c6786940
--- /dev/null
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -0,0 +1,2885 @@
+// 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-tyty.h"
+#include "rust-tyty-visitor.h"
+#include "rust-tyty-call.h"
+#include "rust-hir-type-check-expr.h"
+#include "rust-hir-type-check-type.h"
+#include "rust-tyty-rules.h"
+#include "rust-tyty-cmp.h"
+#include "rust-hir-map.h"
+#include "rust-substitution-mapper.h"
+#include "rust-hir-trait-ref.h"
+#include "rust-hir-type-bounds.h"
+
+namespace Rust {
+namespace TyTy {
+
+std::string
+TypeKindFormat::to_string (TypeKind kind)
+{
+  switch (kind)
+{
+case TypeKind::INFER:
+  return "Infer";
+
+case TypeKind::ADT:
+  return "ADT";
+
+case TypeKind::STR:
+  return "STR";
+
+case TypeKind::REF:
+  return "REF";
+
+case TypeKind::POINTER:
+  return "POINTER";
+
+case TypeKind::PARAM:
+  return "PARAM";
+
+case TypeKind::ARRAY:
+  return "ARRAY";
+
+case TypeKind::SLICE:
+  return "SLICE";
+
+case TypeKind::FNDEF:
+  return "FnDef";
+
+case TypeKind::FNPTR:
+  return "FnPtr";
+
+case TypeKind::TUPLE:
+  return "Tuple";
+
+case TypeKind::BOOL:
+  return "Bool";
+
+case TypeKind::CHAR:
+  return "Char";
+
+case TypeKind::INT:
+  return "Int";
+
+case TypeKind::UINT:
+  return "Uint";
+
+case TypeKind::FLOAT:
+  return "Float";
+
+case TypeKind::USIZE:
+  return "Usize";
+
+case TypeKind::ISIZE:
+  return "Isize";
+
+case TypeKind::NEVER:
+  return "Never";
+
+case TypeKind::PLACEHOLDER:
+  return "Placeholder";
+
+case TypeKind::PROJECTION:
+  return "Projection";
+
+case TypeKind::DYNAMIC:
+  return "Dynamic";
+
+case TypeKind::CLOSURE:
+  return "Closure";
+
+case TypeKind::ERROR:
+  return "ERROR";
+}
+  gcc_unreachable ();
+}
+
+bool
+is_primitive_type_kind (TypeKind kind)
+{
+  switch (kind)
+{
+case TypeKind::BOOL:
+case TypeKind::CHAR:
+case TypeKind::INT:
+case TypeKind::UINT:
+case TypeKind::ISIZE:
+case TypeKind::USIZE:
+case TypeKind::FLOAT:
+case TypeKind::NEVER:
+case TypeKind::STR:
+  return true;
+default:
+  return false;
+}
+}
+
+bool
+BaseType::satisfies_bound (const TypeBoundPredicate &predicate) const
+{
+  const Resolver::TraitReference *query = predicate.get ();
+  for (auto &bound : specified_bounds)
+{
+  const Resolver::TraitReference *item = bound.get ();
+  bool found = item->get_mappings ().get_defid ()
+  == query->get_mappings ().get_defid ();
+  if (found)
+   return true;
+}
+
+  auto probed = Resolver::TypeBoundsProbe::Probe (this);
+  for (auto &b : probed)
+{
+  const Resolver::TraitReference *bound = b.first;
+  bool found = bound->get_mappings ().get_defid ()
+  == query->get_mappings ().get_defid ();
+  if (found)
+   return true;
+}
+
+  return false;
+}
+
+bool
+BaseType::bounds_compatible (const BaseType &other, Location locus,
+bool emit_error) const
+{
+  std::vector>
+unsatisfied_bounds;
+  for (auto &bound : get_specified_bounds ())
+{
+  if (!other.satisfies_bound (bound))
+   unsatisfied_bounds.push_back (bound);
+}
+
+  // lets emit a single error for this
+  if (unsatisfied_bounds.size () > 0)
+{
+  RichLocation r (locus);
+  std::string missing_preds;
+  for (size_t i = 0; i < unsatisfied_bounds.size (); i++)
+   {
+ const TypeBoundPredicate &pred = unsatisfied_bounds.at (i);
+ r.add_range (pred.get_locus ());
+ missing_preds += pred.get_name ();
+
+ bool have_next = (i + 1) < unsatisfied_bounds.size ();
+  

[PATCH Rust front-end v4 20/46] gccrs: Add wrapper for make_unique

2022-12-06 Thread arthur . cohen
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..7b79e625ff1
--- /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 "rust-system.h"
+
+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.38.1

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


[PATCH Rust front-end v4 22/46] gccrs: Add Rust ABI enum helpers

2022-12-06 Thread arthur . cohen
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.38.1

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


[PATCH Rust front-end v4 34/46] gccrs: Add unused variable scan

2022-12-06 Thread arthur . cohen
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.38.1

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


[PATCH Rust front-end v4 35/46] gccrs: Add metadata output pass

2022-12-06 Thread arthur . cohen
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 necessary. 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| 176 +
 gcc/rust/rust-object-export.h |  33 +
 9 files changed, 2490 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 v4 40/46] gccrs: Add GCC Rust front-end Make-lang.in

2022-12-06 Thread arthur . cohen
From: Philip Herron 

This is the Makefile for our front-end.
---
 gcc/rust/Make-lang.in | 402 ++
 1 file changed, 402 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..f3a03a3199d
--- /dev/null
+++ b/gcc/rust/Make-lang.in
@@ -0,0 +1,402 @@
+# 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)
+# ..., with the exception of '-Wunused-parameter'; waiting for
+#  "bootstrap build failure".
+rust-warn += -Wno-unused-parameter
+
+# 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/ru

[PATCH Rust front-end v4 42/46] gccrs: Add lang-spec.h

2022-12-06 Thread arthur . cohen
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..eed28b1eb06
--- /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", "@rust", 0, 1, 0},
+  {"@rust",
+   "rust1 %i %(cc1_options) %{I*} %{L*} %D %{!fsyntax-only:%(invoke_as)}", 0, 
1,
+   0},
-- 
2.38.1

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


[PATCH Rust front-end v4 43/46] gccrs: Add lang.opt

2022-12-06 Thread arthur . cohen
From: Philip Herron 

We have some Rust-specific language options. Note that -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++'s 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..1130999d277
--- /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) 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) Warning 
LangEnabledBy(Rust,Wunused-variable, 1, 0) IntegerRange(0, 2)
+Warn when a const variable is unused.
+
+Wunused-result
+Rust Var(warn_unused_result) 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.38.1

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


[PATCH Rust front-end v4 32/46] gccrs: Add privacy checks

2022-12-06 Thread arthur . cohen
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   | 771 ++
 .../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, 2263 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
+// <http://www.gnu.org/licenses/>.
+
+#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

[PATCH Rust front-end v4 41/46] gccrs: Add config-lang.in

2022-12-06 Thread arthur . cohen
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.38.1

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


[PATCH Rust front-end v4 38/46] gccrs: Add HIR to GCC GENERIC lowering entry point

2022-12-06 Thread arthur . cohen
From: Philip Herron 

This patch contains the entry point and utilities used for the lowering
of HIR nodes to `tree`s. It also contains a constant evaluator, ported
over from the C++ frontend.

Co-authored-by: David Faust 
Co-authored-by: Faisal Abbas <90.abbasfai...@gmail.com>
---
 gcc/rust/backend/rust-compile-context.cc | 146 
 gcc/rust/backend/rust-compile-context.h  | 343 ++
 gcc/rust/backend/rust-compile.cc | 414 ++
 gcc/rust/backend/rust-compile.h  |  47 +++
 gcc/rust/backend/rust-constexpr.cc   | 433 +++
 gcc/rust/backend/rust-constexpr.h|  31 ++
 6 files changed, 1414 insertions(+)
 create mode 100644 gcc/rust/backend/rust-compile-context.cc
 create mode 100644 gcc/rust/backend/rust-compile-context.h
 create mode 100644 gcc/rust/backend/rust-compile.cc
 create mode 100644 gcc/rust/backend/rust-compile.h
 create mode 100644 gcc/rust/backend/rust-constexpr.cc
 create mode 100644 gcc/rust/backend/rust-constexpr.h

diff --git a/gcc/rust/backend/rust-compile-context.cc 
b/gcc/rust/backend/rust-compile-context.cc
new file mode 100644
index 000..cb2addf6c21
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-context.cc
@@ -0,0 +1,146 @@
+// 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-compile-context.h"
+#include "rust-compile-type.h"
+
+namespace Rust {
+namespace Compile {
+
+Context::Context (::Backend *backend)
+  : backend (backend), resolver (Resolver::Resolver::get ()),
+tyctx (Resolver::TypeCheckContext::get ()),
+mappings (Analysis::Mappings::get ()), mangler (Mangler ())
+{
+  setup_builtins ();
+}
+
+void
+Context::setup_builtins ()
+{
+  auto builtins = resolver->get_builtin_types ();
+  for (auto it = builtins.begin (); it != builtins.end (); it++)
+{
+  HirId ref;
+  bool ok = tyctx->lookup_type_by_node_id ((*it)->get_node_id (), &ref);
+  rust_assert (ok);
+
+  TyTy::BaseType *lookup;
+  ok = tyctx->lookup_type (ref, &lookup);
+  rust_assert (ok);
+
+  TyTyResolveCompile::compile (this, lookup);
+}
+}
+
+hashval_t
+Context::type_hasher (tree type)
+{
+  inchash::hash hstate;
+
+  hstate.add_int (TREE_CODE (type));
+
+  if (TYPE_NAME (type))
+{
+  hashval_t record_name_hash
+   = IDENTIFIER_HASH_VALUE (DECL_NAME (TYPE_NAME (type)));
+  hstate.add_object (record_name_hash);
+}
+
+  for (tree t = TYPE_ATTRIBUTES (type); t; t = TREE_CHAIN (t))
+/* Just the identifier is adequate to distinguish.  */
+hstate.add_object (IDENTIFIER_HASH_VALUE (TREE_PURPOSE (t)));
+
+  switch (TREE_CODE (type))
+{
+case METHOD_TYPE:
+  hstate.add_object (TYPE_HASH (TYPE_METHOD_BASETYPE (type)));
+  /* FALLTHROUGH. */
+case FUNCTION_TYPE:
+  for (tree t = TYPE_ARG_TYPES (type); t; t = TREE_CHAIN (t))
+   if (TREE_VALUE (t) != error_mark_node)
+ hstate.add_object (TYPE_HASH (TREE_VALUE (t)));
+  break;
+
+case OFFSET_TYPE:
+  hstate.add_object (TYPE_HASH (TYPE_OFFSET_BASETYPE (type)));
+  break;
+
+  case ARRAY_TYPE: {
+   if (TYPE_DOMAIN (type))
+ hstate.add_object (TYPE_HASH (TYPE_DOMAIN (type)));
+   if (!AGGREGATE_TYPE_P (TREE_TYPE (type)))
+ {
+   unsigned typeless = TYPE_TYPELESS_STORAGE (type);
+   hstate.add_object (typeless);
+ }
+  }
+  break;
+
+  case INTEGER_TYPE: {
+   tree t = TYPE_MAX_VALUE (type);
+   if (!t)
+ t = TYPE_MIN_VALUE (type);
+   for (int i = 0; i < TREE_INT_CST_NUNITS (t); i++)
+ hstate.add_object (TREE_INT_CST_ELT (t, i));
+   break;
+  }
+
+case REAL_TYPE:
+  case FIXED_POINT_TYPE: {
+   unsigned prec = TYPE_PRECISION (type);
+   hstate.add_object (prec);
+   break;
+  }
+
+case VECTOR_TYPE:
+  hstate.add_poly_int (TYPE_VECTOR_SUBPARTS (type));
+  break;
+
+case RECORD_TYPE:
+case UNION_TYPE:
+  case QUAL_UNION_TYPE: {
+   for (tree t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t))
+ {
+   hashval_t name_hash = IDENTIFIER_HASH_VALUE (DECL_NAME (t));
+   hashval_t type_hash = type_hasher (TREE_TYPE (t));
+   hstate.add_object (name_hash);
+   hstate.add_object (type_hash);
+ }
+  }
+ 

[PATCH Rust front-end v4 39/46] gccrs: These are wrappers ported from reusing gccgo

2022-12-06 Thread arthur . cohen
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 v4 45/46] gccrs: Compiler proper interface kicks off the pipeline

2022-12-06 Thread arthur . cohen
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|  456 
 gcc/rust/rust-session-manager.cc | 1189 ++
 gcc/rust/rust-session-manager.h  |  358 +
 3 files changed, 2003 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..241a9b4dae3
--- /dev/null
+++ b/gcc/rust/rust-lang.cc
@@ -0,0 +1,456 @@
+// 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-system.h"
+#include "rust-diagnostics.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-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 this:
+   This allows the code in d-builtin

[PATCH Rust front-end v4 44/46] gccrs: Add compiler driver

2022-12-06 Thread arthur . cohen
From: Philip Herron 

Our compiler driver is fairly 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)
+   --

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

2022-12-06 Thread arthur . cohen
From: Philip Herron 

We still need to write out a documentation section, but these READMEs will
help in the meantime.
---
 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.

Re: Rust front-end patches v4

2022-12-06 Thread Arthur Cohen



On 12/6/22 12:09, John Paul Adrian Glaubitz wrote:

On 12/6/22 12:03, Richard Biener via Gcc-rust wrote:

On Tue, Dec 6, 2022 at 11:11 AM  wrote:


This patchset contains the fixed version of our most recent patchset. We
have fixed most of the issues noted in the previous round of reviews, 
and are
keeping some for later as they would otherwise create too many 
conflicts with

our updated development branch.

Similarly to the previous round of patches, this patchset does not 
contain any
new features - only fixes for the reviews of the v3. New features 
will follow

shortly once that first patchset is merged.

Once again, thank you to all the contributors who made this possible and
especially to Philip Herron for his dedication to the project.


Thanks a lot - this is OK to merge now, thanks for your patience and I'm
looking forward for the future improvements.


Woohooo, finally. Congratulations to everyone involved in this massive 
effort

and thanks a lot for this huge step forward for the Rust community.


Thank you!



Can't wait to see this becoming available in the distributions :D.

I will make sure we get the frontend enabled in Debian as soon as possible.


Haha, I appreciate the enthusiasm :) Please note however that despite 
the language being in, the compiler is still at an extremely early 
stage. We are still not able to properly compile Rust code in the 
version that we target, 1.49.


To do anything meaningful with the language, you will also need the core 
library, which again, we cannot compile yet in its 1.49 version.


This is very much an extremely experimental compiler and will still get 
a lot of changes in the coming weeks and months up until the release.




Adrian



--
Arthur Cohen 

Toolchain Engineer

Embecosm GmbH

Geschäftsführer: Jeremy Bennett
Niederlassung: Nürnberg
Handelsregister: HR-B 36368
www.embecosm.de

Fürther Str. 27
90429 Nürnberg


Tel.: 091 - 128 707 040
Fax: 091 - 128 707 077


OpenPGP_0x1B3465B044AD9C65.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature
-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[committed] MAINTAINERS: Add myself as Rust front-end maintainer

2022-12-07 Thread arthur . cohen
From: Arthur Cohen 

Changelog:
* MAINTAINERS: Add Arthur Cohen as Rust front-end maintainer.
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 55c5ef95806..d2eea049667 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -165,6 +165,7 @@ D front end Iain Buclaw 

 go Ian Lance Taylor
 objective-c/c++Mike Stump  
 objective-c/c++Iain Sandoe 
+Rust   Arthur Cohen
 
Various Maintainers
 
-- 
2.38.1

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


Re: Rust Developer

2022-12-12 Thread Arthur Cohen

Hi there :) Nice to meet you!

This mailing list is focused on the development of gccrs, an alternative 
Rust compiler (https://github.com/rust-GCC/gccrs)


We don't really focus on web front-end development nor can we compile 
your project yet :D


All the best,

Arthur


OpenPGP_0x1B3465B044AD9C65.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature
-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


Re: Rust front-end patches v4

2022-12-13 Thread Arthur Cohen
roper-interface-kicks-off-the-pipeli.patch

Patch 02 and 07 contain test infrastructure changes:

0002-gccrs-Add-necessary-hooks-for-a-Rust-front-end-tests.patch
0007-gccrs-Add-gcc-check-target-check-rust.patch

Patch 03 to 06 contain Rust test cases:

0003-gccrs-Add-Debug-info-testsuite.patch
0004-gccrs-Add-link-cases-testsuite.patch
0005-gccrs-Add-general-compilation-test-cases.patch
0006-gccrs-Add-execution-test-cases.patch

Patches 08 to 46 contain 'gcc/rust/' specific changes which will be hard
to review for someone not familiar with the codebase. These changes include
various transformations on our HIR, or checks specific to the Rust programming
language.




--
Arthur Cohen 

Toolchain Engineer

Embecosm GmbH

Geschäftsführer: Jeremy Bennett
Niederlassung: Nürnberg
Handelsregister: HR-B 36368
www.embecosm.de

Fürther Str. 27
90429 Nürnberg


Tel.: 091 - 128 707 040
Fax: 091 - 128 707 077


OpenPGP_0x1B3465B044AD9C65.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature
-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


Re: Rust front-end patches v4

2022-12-13 Thread Arthur Cohen
We've also added one more commit, which only affects files inside the 
Rust front-end folder. This commit adds an experimental flag, which 
blocks the compilation of Rust code when not used. We hope this helps 
indicate to users that the compiler is not yet ready, but can still be 
experimented with :)


We plan on removing that flag as soon as possible, but in the meantime, 
we think it will help not creating divide within the Rust ecosystem, as 
well as not waste Rust crate maintainers' time.


Thanks again,

Arthur

On 12/13/22 14:26, Arthur Cohen wrote:

Hi everyone,

I have pushed the commits onto master. Thanks again for all the reviews 
and support.


Thank you, and congratulations, to all the contributors.

All the best,

Arthur

On 12/6/22 12:03, Richard Biener via Gcc-rust wrote:

On Tue, Dec 6, 2022 at 11:11 AM  wrote:


This patchset contains the fixed version of our most recent patchset. We
have fixed most of the issues noted in the previous round of reviews, 
and are
keeping some for later as they would otherwise create too many 
conflicts with

our updated development branch.

Similarly to the previous round of patches, this patchset does not 
contain any
new features - only fixes for the reviews of the v3. New features 
will follow

shortly once that first patchset is merged.

Once again, thank you to all the contributors who made this possible and
especially to Philip Herron for his dedication to the project.


Thanks a lot - this is OK to merge now, thanks for your patience and I'm
looking forward for the future improvements.

Thanks,
Richard.


You can see the current status of our work on our branch:
https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/devel/rust/master

Patch status table:

An 'x' in the first column indicates a patch has been reviewed.
One in the second column indicates that a patch has been approved.

|0001-Use-DW_ATE_UTF-for-the-Rust-char-type.patch   |x|x|
|0002-gccrs-Add-necessary-hooks-for-a-Rust-front-end-tests.patch|x|x|
|0003-gccrs-Add-Debug-info-testsuite.patch  | | |
|0004-gccrs-Add-link-cases-testsuite.patch  | | |
|0005-gccrs-Add-general-compilation-test-cases.patch    | | |
|0006-gccrs-Add-execution-test-cases.patch  | | |
|0007-gccrs-Add-gcc-check-target-check-rust.patch   |x| |
|0008-gccrs-Add-Rust-front-end-base-AST-data-structures.patch   | | |
|0009-gccrs-Add-definitions-of-Rust-Items-in-AST-data-stru.patch| | |
|0010-gccrs-Add-full-definitions-of-Rust-AST-data-structur.patch| | |
|0011-gccrs-Add-Rust-AST-visitors.patch | | |
|0012-gccrs-Add-Lexer-for-Rust-front-end.patch  |x| |
|0013-gccrs-Add-Parser-for-Rust-front-end-pt.1.patch    | | |
|0014-gccrs-Add-Parser-for-Rust-front-end-pt.2.patch    | | |
|0015-gccrs-Add-expansion-pass-for-the-Rust-front-end.patch | | |
|0016-gccrs-Add-name-resolution-pass-to-the-Rust-front-end.patch| | |
|0017-gccrs-Add-declarations-for-Rust-HIR.patch | | |
|0018-gccrs-Add-HIR-definitions-and-visitor-framework.patch | | |
|0019-gccrs-Add-AST-to-HIR-lowering-pass.patch  | | |
|0020-gccrs-Add-wrapper-for-make_unique.patch   | | |
|0021-gccrs-Add-port-of-FNV-hash-used-during-legacy-symbol.patch| | |
|0022-gccrs-Add-Rust-ABI-enum-helpers.patch | | |
|0023-gccrs-Add-Base62-implementation.patch | | |
|0024-gccrs-Add-implementation-of-Optional.patch    | | |
|0025-gccrs-Add-attributes-checker.patch    | | |
|0026-gccrs-Add-helpers-mappings-canonical-path-and-lang-i.patch| | |
|0027-gccrs-Add-type-resolution-and-trait-solving-pass.patch    | | |
|0028-gccrs-Add-Rust-type-information.patch | | |
|0029-gccrs-Add-remaining-type-system-transformations.patch | | |
|0030-gccrs-Add-unsafe-checks-for-Rust.patch    | | |
|0031-gccrs-Add-const-checker.patch | | |
|0032-gccrs-Add-privacy-checks.patch    | | |
|0033-gccrs-Add-dead-code-scan-on-HIR.patch | | |
|0034-gccrs-Add-unused-variable-scan.patch  | | |
|0035-gccrs-Add-metadata-output-pass.patch  | | |
|0036-gccrs-Add-base-for-HIR-to-GCC-GENERIC-lowering.patch  | | |
|0037-gccrs-Add-HIR-to-GCC-GENERIC-lowering-for-all-nodes.patch |x|x|
|0038-gccrs-Add-HIR-to-GCC-GENERIC-lowering-entry-point.patch   |x|x|
|0039-gccrs-These-are-wrappers-ported-from-reusing-gccgo.patch  | | |
|0040-gccrs-Add-GCC-Rust-front-end-Make-lang.in.patch   |x| |
|0041-gccrs-Add-config-lang.in.patch    |x|x|
|0042-gccrs-Add-lang-spec.h.patch   | | |
|0043-gccrs-Add-lang.opt.patch  |x| |
|0044-gccrs-Add-compiler-driver.patch   | | |
|0045-gccrs-

Re: Rust front-end patches v4

2022-12-13 Thread Arthur Cohen

Hi Martin,

On 12/13/22 14:30, Martin Liška wrote:

On 12/13/22 14:26, Arthur Cohen wrote:

Thank you, and congratulations, to all the contributors.


We thank you!! Congratulations.


Thank you :)


I have one question: do you have a list of supported architectures Rust FE
can support right now?


You can have a look at what architectures we support on our github 
repository: https://github.com/Rust-GCC/gccrs


We pass our own testsuite on i386, x86_64 and arm64. As mentioned by 
Mark, the other architectures currently fail due to two testcases which 
do not work properly on big-endian systems, and one unsupported 
test-case on PowerPC 64bits.


It shouldn't be too hard to fix these failures, and I am working on it.

We've also got contributions from Iain Buclaw, which will help 
supporting more target-specific features. These will be upstreamed soon, 
as we update GCC's master with our current development branch.


> What are you plans for GCC 13.1 release?

We aim to be able to compile the entirety of Rust's core library, 
libcore 1.49, before the release of GCC 13.1. There aren't too many 
features left, and we hope to get to them quickly. We also want to 
integrate at least part of a borrow-checker to gccrs, as soon as possible.


This will surely unearth a lot of bugs for us to fix in time for April :)


Cheers,
Martin



All the best,

Arthur




Kindly,

--
Arthur Cohen 

Toolchain Engineer

Embecosm GmbH

Geschäftsführer: Jeremy Bennett
Niederlassung: Nürnberg
Handelsregister: HR-B 36368
www.embecosm.de

Fürther Str. 27
90429 Nürnberg


Tel.: 091 - 128 707 040
Fax: 091 - 128 707 077


OpenPGP_0x1B3465B044AD9C65.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature
-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


Re: [PATCH] rust: Fix up aarch64-linux bootstrap [PR106072]

2022-12-14 Thread Arthur Cohen

Hi Jakub,

On 12/14/22 10:14, Jakub Jelinek via Gcc-rust wrote:

Hi!

Bootstrap fails on aarch64-linux and some other arches with:
.../gcc/rust/parse/rust-parse-impl.h: In member function ‘Rust::AST::ClosureParam 
Rust::Parser::parse_closure_param() [with 
ManagedTokenSource = Rust::Lexer]’:
.../gcc/rust/parse/rust-parse-impl.h:8916:49: error: ‘this’ pointer is null 
[-Werror=nonnull]
The problem is that while say on x86_64-linux the side-effects in the
arguments are evaluated from last argument to first, on aarch64-linux
it is the other way around, from first to last.  The C++ I believe even
in C++17 makes the evaluation of those side-effects unordered
(indeterminately sequenced with no interleaving), so that is fine.
But, when the call in return statement is evaluated from first to
last, std::move (pattern) happens before pattern->get_locus () and
the former will make pattern (std::unique_ptr) a wrapper object around
nullptr, so dereferencing it later to call get_locus () on it is invalid.

The following patch fixes that, ok for trunk?

2022-12-14  Jakub Jelinek  

PR rust/106072
* parse/rust-parse-impl.h (parse_closure_param): Store
pattern->get_locus () in a temporary before std::move (pattern) is
invoked.

--- gcc/rust/parse/rust-parse-impl.h.jj 2022-12-13 16:50:12.708093521 +0100
+++ gcc/rust/parse/rust-parse-impl.h2022-12-14 09:50:31.73932 +0100
@@ -8912,8 +8912,9 @@ Parser::parse_closur
}
  }
  
-  return AST::ClosureParam (std::move (pattern), pattern->get_locus (),

-   std::move (type), std::move (outer_attrs));
+  Location loc = pattern->get_locus ();
+  return AST::ClosureParam (std::move (pattern), loc, std::move (type),
+   std::move (outer_attrs));
  }
  
  // Parses a grouped or tuple expression (disambiguates).


Jakub



Thanks :) this looks good to me. We already have that issue fixed in our 
upstream dev branch, by this PR:


https://github.com/Rust-GCC/gccrs/pull/1619

but we have yet to update GCC's master with our upstream dev branch, so 
in the meantime feel free to apply your patch. When I'll get to updating 
master, I'm expecting these kinds of tiny conflicts and we'll deal with 
them.


Thanks a lot for working on this and sorry that my tardiness in updating 
has caused a duplication of efforts.


All the best,

--
Arthur Cohen 

Toolchain Engineer

Embecosm GmbH

Geschäftsführer: Jeremy Bennett
Niederlassung: Nürnberg
Handelsregister: HR-B 36368
www.embecosm.de

Fürther Str. 27
90429 Nürnberg


Tel.: 091 - 128 707 040
Fax: 091 - 128 707 077


OpenPGP_0x1B3465B044AD9C65.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature
-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


Re: [PATCH] testsuite: Add support for Rust and Modula-2 effective target tests

2022-12-15 Thread Arthur Cohen

Hi Jakub,

On 12/15/22 13:23, Jakub Jelinek wrote:

Hi!

This patch allows magic comments also for Rust and Modula-2
for effective target tests etc. and fixes up the Assembly entry
- it is a glob, so /* Assembly can match /whatever Assembly and
not just /* Assembly.

Tested on x86_64-linux with
make check-g++ RUNTESTFLAGS=i386.exp=pr35513*
and verifying it still uses *.S extension for the property_1_needed
effective target test.

Ok for trunk?

2022-12-15  Jakub Jelinek  

* lib/target-supports.exp (check_compile): Add support for
Rust and Modula-2.  Use \* rather than * for /* comment for
Assembly.

--- gcc/testsuite/lib/target-supports.exp.jj2022-11-30 10:29:42.217698938 
+0100
+++ gcc/testsuite/lib/target-supports.exp   2022-12-15 13:08:47.941221943 
+0100
@@ -36,7 +36,9 @@
  # "! Fortran" for Fortran code,
  # "/* ObjC", for ObjC
  # "// ObjC++" for ObjC++
-# and "// Go" for Go
+# "// Go" for Go
+# "// Rust" for Rust
+# and "(* Modula-2" for Modula-2
  # If the tool is ObjC/ObjC++ then we overide the extension to .m/.mm to
  # allow for ObjC/ObjC++ specific flags.
  
@@ -58,13 +60,15 @@ proc check_compile {basename type conten

set options ""
  }
  switch -glob -- $contents {
-   "*/* Assembly*" { set src ${basename}[pid].S }
+   "*/\* Assembly*" { set src ${basename}[pid].S }
"*! Fortran*" { set src ${basename}[pid].f90 }
"*// C++*" { set src ${basename}[pid].cc }
"*// D*" { set src ${basename}[pid].d }
"*// ObjC++*" { set src ${basename}[pid].mm }
"*/* ObjC*" { set src ${basename}[pid].m }
"*// Go*" { set src ${basename}[pid].go }
+   "*// Rust*" { set src ${basename}[pid].rs }
+   "*(\* Modula-2*" { set src ${basename}[pid].mod }
default {
switch -- $tool {
"objc" { set src ${basename}[pid].m }

Jakub



LGTM :)

Thank you,

Arthur


OpenPGP_0x1B3465B044AD9C65.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature
-- 
Gcc-rust mailing list
Gcc-rust@gcc.gnu.org
https://gcc.gnu.org/mailman/listinfo/gcc-rust


[COMMITTED] gccrs: session-manager: Add ast-pretty-expanded dump

2023-01-31 Thread Arthur Cohen
gcc/rust/ChangeLog:

* rust-session-manager.cc (Session::compile_crate): Allow the dump of 
prettified AST
(Session::dump_ast_pretty): New
* rust-session-manager.h: Add new output file for pretty AST dump

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/rust-session-manager.cc | 10 --
 gcc/rust/rust-session-manager.h  |  2 +-
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 2b33ddfa601..157f5099155 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -58,6 +58,7 @@ namespace Rust {
 const char *kLexDumpFile = "gccrs.lex.dump";
 const char *kASTDumpFile = "gccrs.ast.dump";
 const char *kASTPrettyDumpFile = "gccrs.ast-pretty.dump";
+const char *kASTPrettyDumpFileExpanded = "gccrs.ast-pretty-expanded.dump";
 const char *kASTExpandedDumpFile = "gccrs.ast-expanded.dump";
 const char *kHIRDumpFile = "gccrs.hir.dump";
 const char *kHIRPrettyDumpFile = "gccrs.hir-pretty.dump";
@@ -531,6 +532,7 @@ Session::compile_crate (const char *filename)
   // dump AST with expanded stuff
   rust_debug ("BEGIN POST-EXPANSION AST DUMP");
   dump_ast_expanded (parser, parsed_crate);
+  dump_ast_pretty (parsed_crate, true);
   rust_debug ("END POST-EXPANSION AST DUMP");
 }
 
@@ -832,10 +834,14 @@ Session::dump_ast (Parser &parser, AST::Crate 
&crate) const
 }
 
 void
-Session::dump_ast_pretty (AST::Crate &crate) const
+Session::dump_ast_pretty (AST::Crate &crate, bool expanded) const
 {
   std::ofstream out;
-  out.open (kASTPrettyDumpFile);
+  if (expanded)
+out.open (kASTPrettyDumpFileExpanded);
+  else
+out.open (kASTPrettyDumpFile);
+
   if (out.fail ())
 {
   rust_error_at (Linemap::unknown_location (), "cannot open %s:%m; 
ignored",
diff --git a/gcc/rust/rust-session-manager.h b/gcc/rust/rust-session-manager.h
index 055aea6b7e6..db915991809 100644
--- a/gcc/rust/rust-session-manager.h
+++ b/gcc/rust/rust-session-manager.h
@@ -319,7 +319,7 @@ private:
 
   void dump_lex (Parser &parser) const;
   void dump_ast (Parser &parser, AST::Crate &crate) const;
-  void dump_ast_pretty (AST::Crate &crate) const;
+  void dump_ast_pretty (AST::Crate &crate, bool expanded = false) const;
   void dump_ast_expanded (Parser &parser, AST::Crate &crate) const;
   void dump_hir (HIR::Crate &crate) const;
   void dump_hir_pretty (HIR::Crate &crate) const;
-- 
2.39.1

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


[COMMITTED] gccrs: Desugar double borrows into two HIR:BorrowExpr's

2023-01-31 Thread Arthur Cohen
From: Philip Herron 

We simply hit a gcc_unreachable() on double borrows but it seems reasonable
to just desugar the AST into a borrow of a borrow to foo. Instead of a
borrow expression with a flag to be respected.

Fixes #1506

gcc/rust/ChangeLog:

* hir/rust-ast-lower-expr.h: Lower double borrow expressions to two
`HIR::BorrowExpr`s.
* hir/tree/rust-hir-expr.h: Remove `is_double_borrow` field from
`HIR::BorrowExpr`.
* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Remove
call to `gcc_unreachable` on double borrow expressions.

gcc/testsuite/ChangeLog:

* rust/compile/torture/issue-1506.rs: New test.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/hir/rust-ast-lower-expr.h| 27 ---
 gcc/rust/hir/tree/rust-hir-expr.h |  5 ++--
 .../typecheck/rust-hir-type-check-expr.cc |  6 -
 .../rust/compile/torture/issue-1506.rs|  3 +++
 4 files changed, 28 insertions(+), 13 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/torture/issue-1506.rs

diff --git a/gcc/rust/hir/rust-ast-lower-expr.h 
b/gcc/rust/hir/rust-ast-lower-expr.h
index 92773b6f3a1..b0ab409646d 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.h
+++ b/gcc/rust/hir/rust-ast-lower-expr.h
@@ -643,10 +643,29 @@ public:
   mappings->get_next_hir_id (crate_num),
   UNKNOWN_LOCAL_DEFID);
 
-translated = new HIR::BorrowExpr (
-  mapping, std::unique_ptr (borrow_lvalue),
-  expr.get_is_mut () ? Mutability::Mut : Mutability::Imm,
-  expr.get_is_double_borrow (), expr.get_outer_attrs (), expr.get_locus 
());
+HIR::BorrowExpr *borrow_expr
+  = new HIR::BorrowExpr (mapping,
+std::unique_ptr (borrow_lvalue),
+expr.get_is_mut () ? Mutability::Mut
+   : Mutability::Imm,
+expr.get_outer_attrs (), expr.get_locus ());
+
+if (expr.get_is_double_borrow ())
+  {
+   NodeId artifical_bouble_borrow_id = mappings->get_next_node_id ();
+   Analysis::NodeMapping mapping (crate_num, artifical_bouble_borrow_id,
+  mappings->get_next_hir_id (crate_num),
+  UNKNOWN_LOCAL_DEFID);
+
+   borrow_expr
+ = new HIR::BorrowExpr (mapping,
+std::unique_ptr (borrow_expr),
+expr.get_is_mut () ? Mutability::Mut
+   : Mutability::Imm,
+expr.get_outer_attrs (), expr.get_locus ());
+  }
+
+translated = borrow_expr;
   }
 
   void visit (AST::DereferenceExpr &expr) override
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h 
b/gcc/rust/hir/tree/rust-hir-expr.h
index 5a1e9768526..564d5215724 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -192,10 +192,10 @@ public:
 
   BorrowExpr (Analysis::NodeMapping mappings,
  std::unique_ptr borrow_lvalue, Mutability mut,
- bool is_double_borrow, AST::AttrVec outer_attribs, Location locus)
+ AST::AttrVec outer_attribs, Location locus)
 : OperatorExpr (std::move (mappings), std::move (borrow_lvalue),
std::move (outer_attribs), locus),
-  mut (mut), double_borrow (is_double_borrow)
+  mut (mut)
   {}
 
   void accept_vis (HIRFullVisitor &vis) override;
@@ -203,7 +203,6 @@ public:
 
   Mutability get_mut () const { return mut; }
   bool is_mut () const { return mut == Mutability::Mut; }
-  bool get_is_double_borrow () const { return double_borrow; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 41c8cd1f19b..c415ae98a7a 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -1209,12 +1209,6 @@ TypeCheckExpr::visit (HIR::BorrowExpr &expr)
}
 }
 
-  if (expr.get_is_double_borrow ())
-{
-  // FIXME double_reference
-  gcc_unreachable ();
-}
-
   infered = new TyTy::ReferenceType (expr.get_mappings ().get_hirid (),
 TyTy::TyVar (resolved_base->get_ref ()),
 expr.get_mut ());
diff --git a/gcc/testsuite/rust/compile/torture/issue-1506.rs 
b/gcc/testsuite/rust/compile/torture/issue-1506.rs
new file mode 100644
index 000..a38f23144ed
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/issue-1506.rs
@@ -0,0 +1,3 @@
+pub fn main() {
+let _: &i32 = 1;
+}
-- 
2.39.1

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


[COMMITTED] gccrs: builtins: Add add_overflow builtin and refactor class

2023-01-31 Thread Arthur Cohen
gcc/rust/ChangeLog:

* backend/rust-builtins.h: Refactor builtin context class and add
overflow builtins.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/backend/rust-builtins.h | 51 ++--
 1 file changed, 36 insertions(+), 15 deletions(-)

diff --git a/gcc/rust/backend/rust-builtins.h b/gcc/rust/backend/rust-builtins.h
index 2bfa6c6cdf7..5cd84010723 100644
--- a/gcc/rust/backend/rust-builtins.h
+++ b/gcc/rust/backend/rust-builtins.h
@@ -18,8 +18,9 @@
 #define RUST_BUILTINS_H
 
 #include "rust-system.h"
-#include "tree.h"
+#include "rust-tree.h"
 #include "langhooks.h"
+#include "tree.h"
 
 namespace Rust {
 namespace Compile {
@@ -99,16 +100,34 @@ private:
 
   BuiltinsContext () { setup (); }
 
-  void setup ()
+  void setup_overflow_fns ()
+  {
+tree overflow_type
+  = build_varargs_function_type_list (boolean_type_node, NULL_TREE);
+
+define_builtin ("add_overflow", BUILT_IN_ADD_OVERFLOW,
+   "__builtin_add_overflow", "add_overflow", overflow_type, 0);
+define_builtin ("sub_overflow", BUILT_IN_SUB_OVERFLOW,
+   "__builtin_sub_overflow", "sub_overflow", overflow_type, 0);
+define_builtin ("mul_overflow", BUILT_IN_MUL_OVERFLOW,
+   "__builtin_mul_overflow", "mul_overflow", overflow_type, 0);
+  }
+
+  void setup_math_fns ()
   {
 tree math_function_type_f32
   = build_function_type_list (float_type_node, float_type_node, NULL_TREE);
 
 define_builtin ("sinf32", BUILT_IN_SINF, "__builtin_sinf", "sinf",
math_function_type_f32, builtin_const);
-
 define_builtin ("sqrtf32", BUILT_IN_SQRTF, "__builtin_sqrtf", "sqrtf",
math_function_type_f32, builtin_const);
+  }
+
+  void setup ()
+  {
+setup_math_fns ();
+setup_overflow_fns ();
 
 define_builtin ("unreachable", BUILT_IN_UNREACHABLE,
"__builtin_unreachable", NULL,
@@ -132,6 +151,16 @@ private:
   0);
   }
 
+  static void handle_flags (tree decl, int flags)
+  {
+if (flags & builtin_const)
+  TREE_READONLY (decl) = 1;
+if (flags & builtin_noreturn)
+  TREE_READONLY (decl) = 1;
+if (flags & builtin_novops)
+  DECL_IS_NOVOPS (decl) = 1;
+  }
+
   // Define a builtin function.  BCODE is the builtin function code
   // defined by builtins.def.  NAME is the name of the builtin function.
   // LIBNAME is the name of the corresponding library function, and is
@@ -144,24 +173,16 @@ private:
   {
 tree decl = add_builtin_function (name, fntype, bcode, BUILT_IN_NORMAL,
  libname, NULL_TREE);
-if ((flags & builtin_const) != 0)
-  TREE_READONLY (decl) = 1;
-if ((flags & builtin_noreturn) != 0)
-  TREE_THIS_VOLATILE (decl) = 1;
-if ((flags & builtin_novops) != 0)
-  DECL_IS_NOVOPS (decl) = 1;
+handle_flags (decl, flags);
 set_builtin_decl (bcode, decl, true);
+
 this->builtin_functions_[name] = decl;
 if (libname != NULL)
   {
decl = add_builtin_function (libname, fntype, bcode, BUILT_IN_NORMAL,
 NULL, NULL_TREE);
-   if ((flags & builtin_const) != 0)
- TREE_READONLY (decl) = 1;
-   if ((flags & builtin_noreturn) != 0)
- TREE_THIS_VOLATILE (decl) = 1;
-   if ((flags & builtin_novops) != 0)
- DECL_IS_NOVOPS (decl) = 1;
+   handle_flags (decl, flags);
+
this->builtin_functions_[libname] = decl;
   }
 
-- 
2.39.1

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


[COMMITTED] gccrs: rustc_attrs: Allow `rustc_inherit_overflow_checks` as a builtin..

2023-01-31 Thread Arthur Cohen
..attribute. We cannot yet handle this attribute, but we should not reject it 
either

gcc/rust/ChangeLog:

* util/rust-attributes.cc: Add `rustc_inherit_overflow_checks` to list
of builtin attributes.

gcc/testsuite/ChangeLog:

* rust/compile/rustc_attr1.rs: New test.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/util/rust-attributes.cc  | 32 ---
 gcc/testsuite/rust/compile/rustc_attr1.rs | 13 +
 2 files changed, 30 insertions(+), 15 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/rustc_attr1.rs

diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index 2cefdb247d1..9db77b40dfb 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -26,21 +26,23 @@ 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},
-};
+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},
+ // From now on, these are reserved by the compiler and gated through
+ // #![feature(rustc_attrs)]
+ {"rustc_inherit_overflow_checks", CODE_GENERATION}};
 
 BuiltinAttributeMappings *
 BuiltinAttributeMappings::get ()
diff --git a/gcc/testsuite/rust/compile/rustc_attr1.rs 
b/gcc/testsuite/rust/compile/rustc_attr1.rs
new file mode 100644
index 000..4bc7d5e3553
--- /dev/null
+++ b/gcc/testsuite/rust/compile/rustc_attr1.rs
@@ -0,0 +1,13 @@
+// { dg-additional-options "-w" }
+
+#![feature(rustc_attrs)]
+
+pub struct NotI8(i8);
+
+impl NotI8 {
+#[inline]
+#[rustc_inherit_overflow_checks]
+pub fn add(self, other: NotI8) -> NotI8 {
+NotI8(self.0 + other.0)
+}
+}
-- 
2.39.1

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


[COMMITTED] gccrs: backend: Add overflow checks to every arithmetic operation

2023-01-31 Thread Arthur Cohen
gcc/rust/ChangeLog:

* backend/rust-compile-expr.cc (CompileExpr::visit): Insert overflow
checks logic.
(CompileExpr::array_copied_expr): Insert overflow checks logic.
* backend/rust-compile-item.cc (CompileItem::visit): Insert overflow
checks logic.
* backend/rust-compile-type.cc (TyTyResolveCompile::visit): Insert
overflow checks logic.
* rust-gcc.cc (Gcc_backend::arithmetic_or_logical_expression): 
Differentiate
existing function from `arithmetic_or_logical_expression_checked`.
This function does insert perform overflow checks.
(Gcc_backend::arithmetic_or_logical_expression_checked): New
function.
(is_overflowing_expr): New function. Check if an expression is an
overflowing one (ADD, SUB, MUL).
(fetch_overflow_builtins): New function.
* rust-backend.h: Declare `arithmetic_or_logical_expression_checked` in
abstract `Backend` class.

gcc/testsuite/ChangeLog:

* rust/debug/win64-abi.rs: Fix assertion to take into account
overflow builtins
* rust/compile/torture/macro-issue1426.rs: Moved to...
* rust/execute/torture/macro-issue1426.rs: ...here.
* rust/execute/torture/overflow1.rs: New test.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/backend/rust-compile-expr.cc |  55 +--
 gcc/rust/backend/rust-compile-item.cc |   6 +
 gcc/rust/backend/rust-compile-type.cc |   4 +
 gcc/rust/rust-backend.h   |  19 ++-
 gcc/rust/rust-gcc.cc  | 140 --
 gcc/testsuite/rust/debug/win64-abi.rs |   8 +-
 .../torture/macro-issue1426.rs|   9 +-
 .../rust/execute/torture/overflow1.rs |  20 +++
 8 files changed, 223 insertions(+), 38 deletions(-)
 rename gcc/testsuite/rust/{compile => execute}/torture/macro-issue1426.rs (68%)
 create mode 100644 gcc/testsuite/rust/execute/torture/overflow1.rs

diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index 9db14a238a7..ea146731cbe 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -26,6 +26,7 @@
 #include "rust-compile-block.h"
 #include "rust-compile-implitem.h"
 #include "rust-constexpr.h"
+#include "rust-gcc.h"
 
 #include "fold-const.h"
 #include "realmpfr.h"
@@ -146,9 +147,26 @@ CompileExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
   return;
 }
 
-  translated
-= ctx->get_backend ()->arithmetic_or_logical_expression (op, lhs, rhs,
-expr.get_locus ());
+  if (ctx->in_fn () && !ctx->const_context_p ())
+{
+  auto receiver_tmp = NULL_TREE;
+  auto receiver
+   = ctx->get_backend ()->temporary_variable (ctx->peek_fn ().fndecl,
+  NULL_TREE, TREE_TYPE (lhs),
+  lhs, true, expr.get_locus (),
+  &receiver_tmp);
+  auto check
+   = ctx->get_backend ()->arithmetic_or_logical_expression_checked (
+ op, lhs, rhs, expr.get_locus (), receiver);
+
+  ctx->add_statement (check);
+  translated = receiver->get_tree (expr.get_locus ());
+}
+  else
+{
+  translated = ctx->get_backend ()->arithmetic_or_logical_expression (
+   op, lhs, rhs, expr.get_locus ());
+}
 }
 
 void
@@ -176,13 +194,27 @@ CompileExpr::visit (HIR::CompoundAssignmentExpr &expr)
   return;
 }
 
-  auto operator_expr
-= ctx->get_backend ()->arithmetic_or_logical_expression (op, lhs, rhs,
-expr.get_locus ());
-  tree assignment
-= ctx->get_backend ()->assignment_statement (lhs, operator_expr,
-expr.get_locus ());
-  ctx->add_statement (assignment);
+  if (ctx->in_fn () && !ctx->const_context_p ())
+{
+  auto tmp = NULL_TREE;
+  auto receiver
+   = ctx->get_backend ()->temporary_variable (ctx->peek_fn ().fndecl,
+  NULL_TREE, TREE_TYPE (lhs),
+  lhs, true, expr.get_locus (),
+  &tmp);
+  auto check
+   = ctx->get_backend ()->arithmetic_or_logical_expression_checked (
+ op, lhs, rhs, expr.get_locus (), receiver);
+  ctx->add_statement (check);
+
+  translated = ctx->get_backend ()->assignment_statement (
+   lhs, receiver->get_tree (expr.get_locus ()), expr.get_locus ());
+}
+  else
+{
+  translated = ctx->get_backend ()->arithmetic_or_logical_expression (
+   op, lhs, rhs, expr.get_locus ());
+}
 }
 
 void
@@ -2383,7 +2415,10 @@ CompileExpr::array_copied_expr (Location expr_locus,
   return error_mark_node;
 }
 
+  ctx->push_const_c

[COMMITTED] gccrs: dump: Add AST debugging using the AST::Dump class

2023-01-31 Thread Arthur Cohen
gcc/rust/ChangeLog:

* ast/rust-ast-dump.h: Add shorthand `AST::Dump::debug` function to
dump an AST node on `stderr`.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/ast/rust-ast-dump.h | 16 
 1 file changed, 16 insertions(+)

diff --git a/gcc/rust/ast/rust-ast-dump.h b/gcc/rust/ast/rust-ast-dump.h
index 4fa4db9265f..955dbc0bebc 100644
--- a/gcc/rust/ast/rust-ast-dump.h
+++ b/gcc/rust/ast/rust-ast-dump.h
@@ -52,6 +52,22 @@ public:
   void go (AST::Crate &crate);
   void go (AST::Item &item);
 
+  /**
+   * Use the AST Dump as a debugging tool
+   */
+  template  static void debug (T &instance)
+  {
+auto dump = Dump (std::cerr);
+
+std::cerr << '\n';
+instance.accept_vis (dump);
+std::cerr << '\n';
+  }
+  template  static void debug (std::unique_ptr &instance)
+  {
+debug (*instance);
+  }
+
 private:
   std::ostream &stream;
   Indent indentation;
-- 
2.39.1

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


[COMMITTED] gccrs: transcriber: Do not infinite loop if the current parsed node is an error

2023-01-31 Thread Arthur Cohen
gcc/rust/ChangeLog:

* expand/rust-macro-expand.cc (parse_many): Return early from parsing
loop if we encounter an error, and emit that error in the meantime.

Co-authored-by: philberty 

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/expand/rust-macro-expand.cc | 8 
 1 file changed, 8 insertions(+)

diff --git a/gcc/rust/expand/rust-macro-expand.cc 
b/gcc/rust/expand/rust-macro-expand.cc
index df258bd96ec..ed1b838c987 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -731,6 +731,14 @@ parse_many (Parser &parser, TokenId 
&delimiter,
break;
 
   auto node = parse_fn ();
+  if (node.is_error ())
+   {
+ for (auto err : parser.get_errors ())
+   err.emit_error ();
+
+ return AST::ASTFragment::create_error ();
+   }
+
   nodes.emplace_back (std::move (node));
 }
 
-- 
2.39.1

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


[COMMITTED] gccrs: ast: Only expand expressions and types if the kind is right

2023-01-31 Thread Arthur Cohen
gcc/rust/ChangeLog:

* ast/rust-ast.h: Add assertions and accessors for fragment nodes.
* expand/rust-attribute-visitor.cc (AttrVisitor::visit): Fix expansion
context typo when visiting `InherentImpl` items.
(AttrVisitor::maybe_expand_expr): Use new Fragment accessor to fetch
properly typed node.
(AttrVisitor::maybe_expand_type): Likewise.
* expand/rust-macro-expand.cc (transcribe_type): Emit parse errors
when trying to parse a type.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/ast/rust-ast.h   | 15 +++
 gcc/rust/expand/rust-attribute-visitor.cc | 11 +++
 gcc/rust/expand/rust-macro-expand.cc  |  4 +++-
 3 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 213208efb56..58fe2674479 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -24,6 +24,7 @@
 #include "rust-hir-map.h"
 #include "rust-token.h"
 #include "rust-location.h"
+#include "rust-diagnostics.h"
 
 namespace Rust {
 // TODO: remove typedefs and make actual types for these
@@ -1868,6 +1869,10 @@ private:
*/
 
   bool is_single_fragment () const { return nodes.size () == 1; }
+  bool is_single_fragment (SingleASTNode::NodeType expected) const
+  {
+return is_single_fragment () && nodes[0].get_kind () == expected;
+  }
 
   bool is_single_fragment_kind (SingleASTNode::NodeType kind) const
   {
@@ -1913,6 +1918,16 @@ public:
 
   bool should_expand () const { return !is_error (); }
 
+  bool is_expression_fragment () const
+  {
+return is_single_fragment (SingleASTNode::NodeType::EXPRESSION);
+  }
+
+  bool is_type_fragment () const
+  {
+return is_single_fragment (SingleASTNode::NodeType::TYPE);
+  }
+
   std::unique_ptr take_expression_fragment ()
   {
 rust_assert (is_single_fragment_kind 
(SingleASTNode::NodeType::EXPRESSION));
diff --git a/gcc/rust/expand/rust-attribute-visitor.cc 
b/gcc/rust/expand/rust-attribute-visitor.cc
index 15aedbfa668..673f0432a30 100644
--- a/gcc/rust/expand/rust-attribute-visitor.cc
+++ b/gcc/rust/expand/rust-attribute-visitor.cc
@@ -2662,7 +2662,7 @@ AttrVisitor::visit (AST::InherentImpl &impl)
   for (auto ¶m : impl.get_generic_params ())
 param->accept_vis (*this);
 
-  expander.push_context (MacroExpander::ContextType::TYPE);
+  expander.push_context (MacroExpander::ContextType::ITEM);
 
   auto &type = impl.get_type ();
   type->accept_vis (*this);
@@ -2706,7 +2706,7 @@ AttrVisitor::visit (AST::TraitImpl &impl)
   for (auto ¶m : impl.get_generic_params ())
 param->accept_vis (*this);
 
-  expander.push_context (MacroExpander::ContextType::TYPE);
+  expander.push_context (MacroExpander::ContextType::ITEM);
 
   auto &type = impl.get_type ();
   type->accept_vis (*this);
@@ -3427,11 +3427,13 @@ AttrVisitor::visit (AST::BareFunctionType &type)
 
   // no where clause, apparently
 }
+
 void
 AttrVisitor::maybe_expand_expr (std::unique_ptr &expr)
 {
   auto final_fragment = expand_macro_fragment_recursive ();
-  if (final_fragment.should_expand ())
+  if (final_fragment.should_expand ()
+  && final_fragment.is_expression_fragment ())
 expr = final_fragment.take_expression_fragment ();
 }
 
@@ -3439,7 +3441,8 @@ void
 AttrVisitor::maybe_expand_type (std::unique_ptr &type)
 {
   auto final_fragment = expand_macro_fragment_recursive ();
-  if (final_fragment.should_expand ())
+  if (final_fragment.should_expand () && final_fragment.is_type_fragment ())
 type = final_fragment.take_type_fragment ();
 }
+
 } // namespace Rust
diff --git a/gcc/rust/expand/rust-macro-expand.cc 
b/gcc/rust/expand/rust-macro-expand.cc
index ed1b838c987..c68faba86ad 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -864,7 +864,9 @@ transcribe_expression (Parser &parser)
 static AST::ASTFragment
 transcribe_type (Parser &parser)
 {
-  auto type = parser.parse_type ();
+  auto type = parser.parse_type (true);
+  for (auto err : parser.get_errors ())
+err.emit_error ();
 
   return AST::ASTFragment ({std::move (type)});
 }
-- 
2.39.1

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


[COMMITTED] gccrs: ast: Add better assertion on AST fragments

2023-01-31 Thread Arthur Cohen
gcc/rust/ChangeLog:

* ast/rust-ast.h: Improve assertions within ASTFragment API.

Co-authored-by: philberty 

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/ast/rust-ast.h | 47 ++---
 1 file changed, 39 insertions(+), 8 deletions(-)

diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 58fe2674479..9e1b8b11373 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -1819,7 +1819,7 @@ public:
 return true;
   }
 
-  std::string as_string ()
+  std::string as_string () const
   {
 switch (kind)
   {
@@ -1869,14 +1869,45 @@ private:
*/
 
   bool is_single_fragment () const { return nodes.size () == 1; }
-  bool is_single_fragment (SingleASTNode::NodeType expected) const
+
+  bool is_single_fragment_of_kind (SingleASTNode::NodeType expected) const
   {
 return is_single_fragment () && nodes[0].get_kind () == expected;
   }
 
-  bool is_single_fragment_kind (SingleASTNode::NodeType kind) const
+  void assert_single_fragment (SingleASTNode::NodeType expected) const
   {
-return is_single_fragment () && nodes[0].get_kind () == kind;
+static const std::map str_map = {
+  {SingleASTNode::NodeType::IMPL, "impl"},
+  {SingleASTNode::NodeType::ITEM, "item"},
+  {SingleASTNode::NodeType::TYPE, "type"},
+  {SingleASTNode::NodeType::EXPRESSION, "expr"},
+  {SingleASTNode::NodeType::STMT, "stmt"},
+  {SingleASTNode::NodeType::EXTERN, "extern"},
+  {SingleASTNode::NodeType::TRAIT, "trait"},
+  {SingleASTNode::NodeType::TRAIT_IMPL, "trait impl"},
+};
+
+auto actual = nodes[0].get_kind ();
+auto fail = false;
+
+if (!is_single_fragment ())
+  {
+   rust_error_at (Location (), "fragment is not single");
+   fail = true;
+  }
+
+if (actual != expected)
+  {
+   rust_error_at (
+ Location (),
+ "invalid fragment operation: expected %qs node, got %qs node",
+ str_map.find (expected)->second,
+ str_map.find (nodes[0].get_kind ())->second);
+   fail = true;
+  }
+
+rust_assert (!fail);
   }
 
 public:
@@ -1920,23 +1951,23 @@ public:
 
   bool is_expression_fragment () const
   {
-return is_single_fragment (SingleASTNode::NodeType::EXPRESSION);
+return is_single_fragment_of_kind (SingleASTNode::NodeType::EXPRESSION);
   }
 
   bool is_type_fragment () const
   {
-return is_single_fragment (SingleASTNode::NodeType::TYPE);
+return is_single_fragment_of_kind (SingleASTNode::NodeType::TYPE);
   }
 
   std::unique_ptr take_expression_fragment ()
   {
-rust_assert (is_single_fragment_kind 
(SingleASTNode::NodeType::EXPRESSION));
+assert_single_fragment (SingleASTNode::NodeType::EXPRESSION);
 return nodes[0].take_expr ();
   }
 
   std::unique_ptr take_type_fragment ()
   {
-rust_assert (is_single_fragment_kind (SingleASTNode::NodeType::TYPE));
+assert_single_fragment (SingleASTNode::NodeType::TYPE);
 return nodes[0].take_type ();
   }
 
-- 
2.39.1

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


[COMMITTED] gccrs: Create canonical process of compiling constant items

2023-01-31 Thread Arthur Cohen
From: Philip Herron 

In order to compile a block expression constant, the simplest way for us
was to reuse what code we have and to generate an artifical function which
does not get added to the translation unit. The constant then becomes
a CALL_EXPR to this artifical function which we can pass to the constexpr
evaluator to resolve the result of this artifical 'CALL_EXPR'.

Before this patch we seperated the difference between block expressions
and non block expressions in constants. So for non block expressions we
simply compiled them as if it was a simple constant but this is not
guaranteed to be the case in rust, for example coercion sites can generate
temporaries during autoderef which we let the constant evaluator resolve
for us. This makes all constants handled in the same way to simplify the
logic here.

gcc/rust/ChangeLog:

* backend/rust-compile-base.cc: Improve compilation pipeline and 
simplify
function.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/backend/rust-compile-base.cc | 103 ++
 1 file changed, 55 insertions(+), 48 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-base.cc 
b/gcc/rust/backend/rust-compile-base.cc
index e1506b377ce..568abf9ca2c 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -652,65 +652,72 @@ HIRCompileBase::compile_constant_item (
   bool is_block_expr
 = const_value_expr->get_expression_type () == HIR::Expr::ExprType::Block;
 
-  // compile the expression
-  tree folded_expr = error_mark_node;
-  if (!is_block_expr)
-{
-  tree value = CompileExpr::Compile (const_value_expr, ctx);
-  folded_expr = fold_expr (value);
-}
-  else
-{
-  // in order to compile a block expr we want to reuse as much existing
-  // machineary that we already have. This means the best approach is to
-  // make a _fake_ function with a block so it can hold onto temps then
-  // use our constexpr code to fold it completely or error_mark_node
-  Backend::typed_identifier receiver;
-  tree compiled_fn_type = ctx->get_backend ()->function_type (
-   receiver, {}, {Backend::typed_identifier ("_", const_type, locus)},
-   NULL, locus);
-
-  tree fndecl
-   = ctx->get_backend ()->function (compiled_fn_type, ident, "", 0, locus);
-  TREE_READONLY (fndecl) = 1;
+  // in order to compile a block expr we want to reuse as much existing
+  // machineary that we already have. This means the best approach is to
+  // make a _fake_ function with a block so it can hold onto temps then
+  // use our constexpr code to fold it completely or error_mark_node
+  Backend::typed_identifier receiver;
+  tree compiled_fn_type = ctx->get_backend ()->function_type (
+receiver, {}, {Backend::typed_identifier ("_", const_type, locus)}, NULL,
+locus);
+
+  tree fndecl
+= ctx->get_backend ()->function (compiled_fn_type, ident, "", 0, locus);
+  TREE_READONLY (fndecl) = 1;
+
+  tree enclosing_scope = NULL_TREE;
 
-  tree enclosing_scope = NULL_TREE;
+  Location start_location = const_value_expr->get_locus ();
+  Location end_location = const_value_expr->get_locus ();
+  if (is_block_expr)
+{
   HIR::BlockExpr *function_body
= static_cast (const_value_expr);
-  Location start_location = function_body->get_locus ();
-  Location end_location = function_body->get_end_locus ();
+  start_location = function_body->get_locus ();
+  end_location = function_body->get_end_locus ();
+}
 
-  tree code_block
-   = ctx->get_backend ()->block (fndecl, enclosing_scope, {},
- start_location, end_location);
-  ctx->push_block (code_block);
+  tree code_block = ctx->get_backend ()->block (fndecl, enclosing_scope, {},
+   start_location, end_location);
+  ctx->push_block (code_block);
 
-  bool address_is_taken = false;
-  tree ret_var_stmt = NULL_TREE;
-  Bvariable *return_address
-   = ctx->get_backend ()->temporary_variable (fndecl, code_block,
-  const_type, NULL,
-  address_is_taken, locus,
-  &ret_var_stmt);
+  bool address_is_taken = false;
+  tree ret_var_stmt = NULL_TREE;
+  Bvariable *return_address
+= ctx->get_backend ()->temporary_variable (fndecl, code_block, const_type,
+  NULL, address_is_taken, locus,
+  &ret_var_stmt);
 
-  ctx->add_statement (ret_var_stmt);
-  ctx->push_fn (fndecl, return_address);
+  ctx->add_statement (ret_var_stmt);
+  ctx->push_fn (fndecl, return_address);
 
+  if (is_block_expr)
+{
+  HIR::BlockExpr *function_body
+   = static_cast (const_value_expr);
   compile_function_body (ctx, fndecl, *function_body, true);
- 

  1   2   3   4   5   6   7   8   9   10   >