[gcc r15-2472] omp-offload.cc: Fix value-expr handling of 'declare target link' vars [PR115637]

2024-08-01 Thread Tobias Burnus via Gcc-cvs
https://gcc.gnu.org/g:c99cdcab4f1c497a872cf552138fd8ea27e9a5eb

commit r15-2472-gc99cdcab4f1c497a872cf552138fd8ea27e9a5eb
Author: Tobias Burnus 
Date:   Thu Aug 1 09:06:32 2024 +0200

omp-offload.cc: Fix value-expr handling of 'declare target link' vars 
[PR115637]

As the PR and included testcase shows, replacing 'arr2' by its value 
expression
'*arr2$13$linkptr' failed for
  MEM  [(c_char * {ref-all})&arr2]
which left 'arr2' in the code as unknown symbol. Now expand the value 
expression
already in pass_omp_target_link::execute's process_link_var_op 
walk_gimple_stmt
walk - and don't rely on gimple_regimplify_operands.

PR middle-end/115637

gcc/ChangeLog:

* gimplify.cc (gimplify_body): Fix macro name in the comment.
* omp-offload.cc (find_link_var_op): Rename to ...
(process_link_var_op): ... this. Replace value expr.
(pass_omp_target_link::execute): Update walk_gimple_stmt call.

libgomp/ChangeLog:

* testsuite/libgomp.fortran/declare-target-link.f90: Uncomment
now working code.

Co-authored-by: Richard Biener info = *tp = unshare_expr (DECL_VALUE_EXPR (t));
   *walk_subtrees = 0;
-  return t;
+  return NULL_TREE;
 }
 
   return NULL_TREE;
@@ -2924,7 +2926,10 @@ pass_omp_target_link::execute (function *fun)
  gimple_call_set_arg (gsi_stmt (gsi), 1, null_pointer_node);
  update_stmt (gsi_stmt (gsi));
}
- if (walk_gimple_stmt (&gsi, NULL, find_link_var_op, NULL))
+ struct walk_stmt_info wi;
+ memset (&wi, 0, sizeof (wi));
+ walk_gimple_stmt (&gsi, NULL, process_link_var_op, &wi);
+ if (wi.info)
gimple_regimplify_operands (gsi_stmt (gsi), &gsi);
}
 }
diff --git a/libgomp/testsuite/libgomp.fortran/declare-target-link.f90 
b/libgomp/testsuite/libgomp.fortran/declare-target-link.f90
index 2ce212d114fa..44c67f925bda 100644
--- a/libgomp/testsuite/libgomp.fortran/declare-target-link.f90
+++ b/libgomp/testsuite/libgomp.fortran/declare-target-link.f90
@@ -1,5 +1,7 @@
 ! { dg-additional-options "-Wall" }
+
 ! PR fortran/115559
+! PR middle-end/115637
 
 module m
integer :: A
@@ -73,24 +75,19 @@ contains
 !$omp target map(from:res)
   res = run_device1()
 !$omp end target
-print *, res
-! FIXME: arr2 not link mapped -> PR115637
-! if (res /= -11436) stop 5
-if (res /= -11546) stop 5 ! FIXME
+! print *, res
+if (res /= -11436) stop 5
   end
   integer function run_device1()
 !$omp declare target
 integer :: i
 run_device1 = -99
-! FIXME: arr2 not link mapped -> PR115637
-!   arr2 = [11,22,33,44]
+arr2 = [11,22,33,44]
 if (any (arr(10:50) /= [(i, i=10,50)])) then
   run_device1 = arr(11)
   return
 end if
-! FIXME: -> PR115637
-! run_device1 = sum(arr(10:13) + arr2)
-run_device1 = sum(arr(10:13) ) ! FIXME
+run_device1 = sum(arr(10:13) + arr2)
 do i = 10, 50
   arr(i) = 3 - 10 * arr(i)
 end do


[gcc r15-2473] i386: Fix up *_vinsert_0 [PR115981]

2024-08-01 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:df2b444a233e93b987adec76655ab89589b3fa10

commit r15-2473-gdf2b444a233e93b987adec76655ab89589b3fa10
Author: Jakub Jelinek 
Date:   Thu Aug 1 10:32:54 2024 +0200

i386: Fix up *_vinsert_0 [PR115981]

The r14-537 change started canonicalizing VEC_MERGE operands based on
swap_commutative_operands_p or if they have the same precedence least
significant bit of the third operand.
The *_vinsert_0 pattern was
added for combine matching and no longer triggers after that change,
as it used the reg_or_0_operand as the first operand and VEC_DUPLICATE
as the second.
Now, reg_or_0_operand could be a REG, SUBREG of object or CONST_VECTOR.
REG has commutative_operand_precedence -1 or -2, SUBREG of object -3,
CONST_VECTOR -4, while VEC_DUPLICATE has 0, so VEC_DUPLICATE will always
go first and REG, SUBREG or CONST_VECTOR second.

This patch swaps the operands so that it matches again.

2024-08-01  Jakub Jelinek  

PR target/115981
* config/i386/sse.md
(*_vinsert_0): Swap the
first two VEC_MERGE operands, renumber match_operands and test
for 0xF or 0x3 rather than 0xFFF0 or 0xFC immediate.

* gcc.target/i386/avx512dq-pr90991-1.c: Add tests for no separate
zero extension instructions.
* gcc.target/i386/avx512dq-pr90991-2.c: Likewise.

Diff:
---
 gcc/config/i386/sse.md | 42 +++---
 gcc/testsuite/gcc.target/i386/avx512dq-pr90991-1.c |  3 ++
 gcc/testsuite/gcc.target/i386/avx512dq-pr90991-2.c |  3 ++
 3 files changed, 27 insertions(+), 21 deletions(-)

diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index f54e966bdbb2..baaec6897496 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -19692,47 +19692,47 @@
 (define_insn "*_vinsert_0"
   [(set (match_operand:AVX512_VEC 0 "register_operand" "=v,x,Yv")
(vec_merge:AVX512_VEC
- (match_operand:AVX512_VEC 1 "reg_or_0_operand" "v,C,C")
  (vec_duplicate:AVX512_VEC
-   (match_operand: 2 "nonimmediate_operand" 
"vm,xm,vm"))
+   (match_operand: 1 "nonimmediate_operand" 
"vm,xm,vm"))
+ (match_operand:AVX512_VEC 2 "reg_or_0_operand" "v,C,C")
  (match_operand:SI 3 "const_int_operand")))]
   "TARGET_AVX512F
&& (INTVAL (operands[3])
-   == (GET_MODE_UNIT_SIZE (mode) == 4 ? 0xFFF0 : 0xFC))"
+   == (GET_MODE_UNIT_SIZE (mode) == 4 ? 0xF : 0x3))"
 {
   if (which_alternative == 0)
-return "vinsert\t{$0, %2, %1, %0|%0, %1, %2, 0}";
+return "vinsert\t{$0, %1, %2, %0|%0, %2, %1, 0}";
   bool egpr_used = (TARGET_APX_EGPR
-   && x86_extended_rex2reg_mentioned_p (operands[2]));
-  const char *align_templ = egpr_used ? "vmovaps\t{%2, %x0|%x0, %2}"
- : "vmovdqa\t{%2, %x0|%x0, %2}";
-  const char *unalign_templ = egpr_used ? "vmovups\t{%2, %x0|%x0, %2}"
-   : "vmovdqu\t{%2, %x0|%x0, %2}";
+   && x86_extended_rex2reg_mentioned_p (operands[1]));
+  const char *align_templ = egpr_used ? "vmovaps\t{%1, %x0|%x0, %1}"
+ : "vmovdqa\t{%1, %x0|%x0, %1}";
+  const char *unalign_templ = egpr_used ? "vmovups\t{%1, %x0|%x0, %1}"
+   : "vmovdqu\t{%1, %x0|%x0, %1}";
   switch (mode)
 {
 case E_V8DFmode:
-  if (misaligned_operand (operands[2], mode))
-   return "vmovupd\t{%2, %x0|%x0, %2}";
+  if (misaligned_operand (operands[1], mode))
+   return "vmovupd\t{%1, %x0|%x0, %1}";
   else
-   return "vmovapd\t{%2, %x0|%x0, %2}";
+   return "vmovapd\t{%1, %x0|%x0, %1}";
 case E_V16SFmode:
-  if (misaligned_operand (operands[2], mode))
-   return "vmovups\t{%2, %x0|%x0, %2}";
+  if (misaligned_operand (operands[1], mode))
+   return "vmovups\t{%1, %x0|%x0, %1}";
   else
-   return "vmovaps\t{%2, %x0|%x0, %2}";
+   return "vmovaps\t{%1, %x0|%x0, %1}";
 case E_V8DImode:
-  if (misaligned_operand (operands[2], mode))
-   return which_alternative == 2 ? "vmovdqu64\t{%2, %x0|%x0, %2}"
+  if (misaligned_operand (operands[1], mode))
+   return which_alternative == 2 ? "vmovdqu64\t{%1, %x0|%x0, %1}"
  : unalign_templ;
   else
-   return which_alternative == 2 ? "vmovdqa64\t{%2, %x0|%x0, %2}"
+   return which_alternative == 2 ? "vmovdqa64\t{%1, %x0|%x0, %1}"
  : align_templ;
 case E_V16SImode:
-  if (misaligned_operand (operands[2], mode))
-   return which_alternative == 2 ? "vmovdqu32\t{%2, %x0|%x0, %2}"
+  if (misaligned_operand (operands[1], mode))
+   return which_alternative == 2 ? "vmovdqu32\t{%1, %x0|%x0, %1}"
  : unalign_templ;
   else
-   return which_alternative == 2 ? "vmovdqa32\t{%2,

[gcc r15-2474] AVR: Tweak register pressure for const_fixed compares against "M".

2024-08-01 Thread Georg-Johann Lay via Gcc-cvs
https://gcc.gnu.org/g:d0504847970d89d5dd7bd689ca8f7bf82fedf522

commit r15-2474-gd0504847970d89d5dd7bd689ca8f7bf82fedf522
Author: Georg-Johann Lay 
Date:   Thu Aug 1 09:58:48 2024 +0200

AVR: Tweak register pressure for const_fixed compares against "M".

When comparing a 16-bit or 32-bit integer against a constant in
the range 0...0xff, constraint M is used because no scratch reg
is needed in that case.  Same can be done for fixed-point compares.

gcc/
* config/avr/constraints.md (YMM): New constraint.
* config/avr/avr.md (cmp3, *cmp3)
(cbranch4_insn): Allow YMM where M is allowed.

Diff:
---
 gcc/config/avr/avr.md | 28 ++--
 gcc/config/avr/constraints.md |  7 +++
 2 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index 91a306f25228..02d0a4156513 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -6568,9 +6568,9 @@
 ;; "cmpha3" "cmpuha3"
 (define_insn "cmp3"
   [(set (reg:CC REG_CC)
-(compare:CC (match_operand:ALL2 0 "register_operand"  "!w  ,r  ,r,d ,r 
 ,d,r")
-(match_operand:ALL2 1 "nonmemory_operand"  "Y00,Y00,r,s ,s 
 ,M,n Ynn")))
-   (clobber (match_scratch:QI 2   "=X  ,X  
,X,&d,&d ,X,&d"))]
+(compare:CC (match_operand:ALL2 0 "register_operand"  "!w  ,r  ,r,d ,r 
,d,r")
+(match_operand:ALL2 1 "nonmemory_operand"  "Y00,Y00,r,s ,s 
,M YMM,n Ynn")))
+   (clobber (match_scratch:QI 2   "=X  ,X  
,X,&d,&d,X,&d"))]
   "reload_completed"
   {
 switch (which_alternative)
@@ -6635,9 +6635,9 @@
 ;; "*cmpsa" "*cmpusa"
 (define_insn "*cmp"
   [(set (reg:CC REG_CC)
-(compare:CC (match_operand:ALL4 0 "register_operand"  "r  ,r ,d,r ,r")
-(match_operand:ALL4 1 "nonmemory_operand" "Y00,r ,M,M ,n 
Ynn")))
-   (clobber (match_scratch:QI 2  "=X  ,X 
,X,&d,&d"))]
+(compare:CC (match_operand:ALL4 0 "register_operand"  "r  ,r ,d,r")
+(match_operand:ALL4 1 "nonmemory_operand" "Y00,r ,M YMM,n 
Ynn")))
+   (clobber (match_scratch:QI 2  "=X  ,X ,X
,&d"))]
   "reload_completed"
   {
 if (0 == which_alternative)
@@ -6647,8 +6647,8 @@
 
 return avr_out_compare (insn, operands, NULL);
   }
-  [(set_attr "length" "4,4,4,5,8")
-   (set_attr "adjust_len" "tstsi,*,compare,compare,compare")])
+  [(set_attr "length" "4,4,4,8")
+   (set_attr "adjust_len" "tstsi,*,compare,compare")])
 
 
 ;; A helper for avr_pass_ifelse::avr_rest_of_handle_ifelse().
@@ -6727,11 +6727,11 @@
   [(set (pc)
 (if_then_else
  (match_operator 0 "ordered_comparison_operator"
-   [(match_operand:ALL4 1 "register_operand"  "r  ,r,d,r ,r")
-(match_operand:ALL4 2 "nonmemory_operand" "Y00,r,M,M ,n Ynn")])
+   [(match_operand:ALL4 1 "register_operand"  "r  ,r,d ,r")
+(match_operand:ALL4 2 "nonmemory_operand" "Y00,r,M YMM ,n Ynn")])
  (label_ref (match_operand 3))
  (pc)))
-   (clobber (match_scratch:QI 4  "=X  ,X,X,&d,&d"))]
+   (clobber (match_scratch:QI 4  "=X  ,X,X ,&d"))]
""
"#"
"reload_completed"
@@ -6772,11 +6772,11 @@
   [(set (pc)
 (if_then_else
  (match_operator 0 "ordered_comparison_operator"
-   [(match_operand:ALL2 1 "register_operand" "!w  ,r  ,r,d ,r ,d,r")
-(match_operand:ALL2 2 "nonmemory_operand" "Y00,Y00,r,s ,s ,M,n 
Ynn")])
+   [(match_operand:ALL2 1 "register_operand" "!w  ,r  ,r,d ,r ,d
,r")
+(match_operand:ALL2 2 "nonmemory_operand" "Y00,Y00,r,s ,s ,M YMM,n 
Ynn")])
  (label_ref (match_operand 3))
  (pc)))
-   (clobber (match_scratch:QI 4  "=X  ,X  ,X,&d,&d,X,&d"))]
+   (clobber (match_scratch:QI 4  "=X  ,X  ,X,&d,&d,X
,&d"))]
""
"#"
"reload_completed"
diff --git a/gcc/config/avr/constraints.md b/gcc/config/avr/constraints.md
index 35448614aa7a..963e23a4d9ed 100644
--- a/gcc/config/avr/constraints.md
+++ b/gcc/config/avr/constraints.md
@@ -313,6 +313,13 @@
   (and (match_code "const_fixed")
(match_test "IN_RANGE (INTVAL (avr_to_int_mode (op)), -63, 63)")))
 
+;; Similar to "M", but for CONST_FIXED.
+
+(define_constraint "YMM"
+  "Fixed-point constant in the range 0 @dots{} 0xff when viewed as CONST_INT."
+  (and (match_code "const_fixed")
+   (match_test "IN_RANGE (INTVAL (avr_to_int_mode (op)), 0, 0xff)")))
+
 (define_constraint "Yil"
   "Memory in the lower half of the I/O space."
   (and (match_code "mem")


[gcc r15-2475] AVR: Tweak unsigned comparisons against 256 resp. 65536.

2024-08-01 Thread Georg-Johann Lay via Gcc-cvs
https://gcc.gnu.org/g:3e4c47d1088417db599a0793a6d93707228e4f70

commit r15-2475-g3e4c47d1088417db599a0793a6d93707228e4f70
Author: Georg-Johann Lay 
Date:   Thu Aug 1 10:21:53 2024 +0200

AVR: Tweak unsigned comparisons against 256 resp. 65536.

u16 >= 256 can be performed by testing the hi8 part against 0.
u32 >= 65536 can be performed by testing the high word against 0.
The optimization is performed in split2 after register allocation
because the register allocator likely spills for subregs.

gcc/
* config/avr/avr.md (cbranch4_insn): Split to a test of the
high part against 0 if possible.

Diff:
---
 gcc/config/avr/avr.md | 36 ++--
 1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index 02d0a4156513..fce5349bbe5f 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -6742,7 +6742,23 @@
  (if_then_else (match_op_dup 0
  [(reg:CC REG_CC) (const_int 0)])
(label_ref (match_dup 3))
-   (pc)))])
+   (pc)))]
+   {
+ // Unsigned >= 65536 and < 65536 can be performed by testing the
+ // high word against 0.
+ if ((GET_CODE (operands[0]) == LTU
+  || GET_CODE (operands[0]) == GEU)
+ && const_operand (operands[2], mode)
+ && INTVAL (avr_to_int_mode (operands[2])) == 65536)
+   {
+ // "cmphi3" of the high word against 0.
+ operands[0] = copy_rtx (operands[0]);
+ PUT_CODE (operands[0], GET_CODE (operands[0]) == GEU ? NE : EQ);
+ operands[1] = simplify_gen_subreg (HImode, operands[1], mode, 
2);
+ operands[2] = const0_rtx;
+ operands[4] = gen_rtx_SCRATCH (QImode);
+   }
+   })
 
 ;; "cbranchpsi4_insn"
 (define_insn_and_split "cbranchpsi4_insn"
@@ -6787,7 +6803,23 @@
  (if_then_else (match_op_dup 0
  [(reg:CC REG_CC) (const_int 0)])
(label_ref (match_dup 3))
-   (pc)))])
+   (pc)))]
+   {
+ // Unsigned >= 256 and < 256 can be performed by testing the
+ // high byte against 0.
+ if ((GET_CODE (operands[0]) == LTU
+  || GET_CODE (operands[0]) == GEU)
+ && const_operand (operands[2], mode)
+ && INTVAL (avr_to_int_mode (operands[2])) == 256)
+   {
+ rtx_code code = GET_CODE (operands[0]) == GEU ? NE : EQ;
+ rtx hi8 = simplify_gen_subreg (QImode, operands[1], mode, 1);
+ rtx cmp = gen_rtx_fmt_ee (code, VOIDmode, cc_reg_rtx, const0_rtx);
+ emit (gen_cmpqi3 (hi8, const0_rtx));
+ emit (gen_branch (operands[3], cmp));
+ DONE;
+   }
+   })
 
 ;; Combiner pattern to compare sign- or zero-extended register against
 ;; a wider register, like comparing uint8_t against uint16_t.


[gcc/devel/omp/gcc-14] omp-offload.cc: Fix value-expr handling of 'declare target link' vars [PR115637]

2024-08-01 Thread Tobias Burnus via Gcc-cvs
https://gcc.gnu.org/g:7543bfda00d7ea4b7f451da8d891d8ad0faade4c

commit 7543bfda00d7ea4b7f451da8d891d8ad0faade4c
Author: Tobias Burnus 
Date:   Thu Aug 1 10:36:43 2024 +0200

omp-offload.cc: Fix value-expr handling of 'declare target link' vars 
[PR115637]

As the PR and included testcase shows, replacing 'arr2' by its value 
expression
'*arr2$13$linkptr' failed for
  MEM  [(c_char * {ref-all})&arr2]
which left 'arr2' in the code as unknown symbol. Now expand the value 
expression
already in pass_omp_target_link::execute's process_link_var_op 
walk_gimple_stmt
walk - and don't rely on gimple_regimplify_operands.

PR middle-end/115637

gcc/ChangeLog:

* gimplify.cc (gimplify_body): Fix macro name in the comment.
* omp-offload.cc (find_link_var_op): Rename to ...
(process_link_var_op): ... this. Replace value expr.
(pass_omp_target_link::execute): Update walk_gimple_stmt call.

libgomp/ChangeLog:

* testsuite/libgomp.fortran/declare-target-link.f90: Uncomment
now working code.

Co-authored-by: Richard Biener 
+
+   Backported from master:
+   2024-08-01  Tobias Burnus  
+   Richard Biener  
 
* doc/tm.texi.in (TARGET_VECTORIZE_PREFER_GATHER_SCATTER): Remove
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index b91e098c280e..a4b1ae89cf51 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -20750,7 +20750,7 @@ gimplify_body (tree fndecl, bool do_parms)
   DECL_SAVED_TREE (fndecl) = NULL_TREE;
 
   /* If we had callee-copies statements, insert them at the beginning
- of the function and clear DECL_VALUE_EXPR_P on the parameters.  */
+ of the function and clear DECL_HAS_VALUE_EXPR_P on the parameters.  */
   if (!gimple_seq_empty_p (parm_stmts))
 {
   tree parm;
diff --git a/gcc/omp-offload.cc b/gcc/omp-offload.cc
index e3af1e21cdf4..b7003a9a95b6 100644
--- a/gcc/omp-offload.cc
+++ b/gcc/omp-offload.cc
@@ -3365,8 +3365,9 @@ public:
 /* Callback for walk_gimple_stmt used to scan for link var operands.  */
 
 static tree
-find_link_var_op (tree *tp, int *walk_subtrees, void *)
+process_link_var_op (tree *tp, int *walk_subtrees, void *data)
 {
+  struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
   tree t = *tp;
 
   if (VAR_P (t)
@@ -3374,8 +3375,9 @@ find_link_var_op (tree *tp, int *walk_subtrees, void *)
   && is_global_var (t)
   && lookup_attribute ("omp declare target link", DECL_ATTRIBUTES (t)))
 {
+  wi->info = *tp = unshare_expr (DECL_VALUE_EXPR (t));
   *walk_subtrees = 0;
-  return t;
+  return NULL_TREE;
 }
 
   return NULL_TREE;
@@ -3405,7 +3407,10 @@ pass_omp_target_link::execute (function *fun)
  gimple_call_set_arg (gsi_stmt (gsi), 1, null_pointer_node);
  update_stmt (gsi_stmt (gsi));
}
- if (walk_gimple_stmt (&gsi, NULL, find_link_var_op, NULL))
+ struct walk_stmt_info wi;
+ memset (&wi, 0, sizeof (wi));
+ walk_gimple_stmt (&gsi, NULL, process_link_var_op, &wi);
+ if (wi.info)
gimple_regimplify_operands (gsi_stmt (gsi), &gsi);
}
 }
diff --git a/libgomp/ChangeLog.omp b/libgomp/ChangeLog.omp
index 73cbc896ad16..d02bbb14e876 100644
--- a/libgomp/ChangeLog.omp
+++ b/libgomp/ChangeLog.omp
@@ -1,3 +1,13 @@
+2024-08-01  Tobias Burnus  
+
+   Backported from master:
+   2024-08-01  Tobias Burnus  
+   Richard Biener  
 
Backported from master:
diff --git a/libgomp/testsuite/libgomp.fortran/declare-target-link.f90 
b/libgomp/testsuite/libgomp.fortran/declare-target-link.f90
index 2ce212d114fa..44c67f925bda 100644
--- a/libgomp/testsuite/libgomp.fortran/declare-target-link.f90
+++ b/libgomp/testsuite/libgomp.fortran/declare-target-link.f90
@@ -1,5 +1,7 @@
 ! { dg-additional-options "-Wall" }
+
 ! PR fortran/115559
+! PR middle-end/115637
 
 module m
integer :: A
@@ -73,24 +75,19 @@ contains
 !$omp target map(from:res)
   res = run_device1()
 !$omp end target
-print *, res
-! FIXME: arr2 not link mapped -> PR115637
-! if (res /= -11436) stop 5
-if (res /= -11546) stop 5 ! FIXME
+! print *, res
+if (res /= -11436) stop 5
   end
   integer function run_device1()
 !$omp declare target
 integer :: i
 run_device1 = -99
-! FIXME: arr2 not link mapped -> PR115637
-!   arr2 = [11,22,33,44]
+arr2 = [11,22,33,44]
 if (any (arr(10:50) /= [(i, i=10,50)])) then
   run_device1 = arr(11)
   return
 end if
-! FIXME: -> PR115637
-! run_device1 = sum(arr(10:13) + arr2)
-run_device1 = sum(arr(10:13) ) ! FIXME
+run_device1 = sum(arr(10:13) + arr2)
 do i = 10, 50
   arr(i) = 3 - 10 * arr(i)
 end do


[gcc/devel/omp/gcc-14] (12 commits) Merge branch 'releases/gcc-14' into devel/omp/gcc-14

2024-08-01 Thread Tobias Burnus via Gcc-cvs
The branch 'devel/omp/gcc-14' was updated to point to:

 84efccbc61d0... Merge branch 'releases/gcc-14' into devel/omp/gcc-14

It previously pointed to:

 7543bfda00d7... omp-offload.cc: Fix value-expr handling of 'declare target 

Diff:

Summary of changes (added commits):
---

  84efccb... Merge branch 'releases/gcc-14' into devel/omp/gcc-14
  04696df... Update ChangeLog and version files for release (*)
  0f4eb65... Daily bump. (*)
  10323e2... Daily bump. (*)
  ee6c5af... x86: Don't enable APX_F in 32-bit mode (*)
  7c688e0... Daily bump. (*)
  da7f0be... c++: wrong error initializing empty class [PR115900] (*)
  a7f1b00... tree-optimization/116057 - wrong code with CCP and vector C (*)
  61cb0c8... testsuite: Fix up consteval-prop21.C for 32-bit targets [PR (*)
  9662299... c++: if consteval and consteval propagation [PR115583] (*)
  56d5f8a... c++: consteval propagation and templates [PR115986] (*)
  f30caf1... c++: ICE with concept, local class, and lambda [PR115561] (*)

(*) This commit already exists in another branch.
Because the reference `refs/heads/devel/omp/gcc-14' matches
your hooks.email-new-commits-only configuration,
no separate email is sent for this commit.


[gcc/devel/omp/gcc-14] Merge branch 'releases/gcc-14' into devel/omp/gcc-14

2024-08-01 Thread Tobias Burnus via Libstdc++-cvs
https://gcc.gnu.org/g:84efccbc61d08eca9ccb86fd45ac7106c14c7b89

commit 84efccbc61d08eca9ccb86fd45ac7106c14c7b89
Merge: 7543bfda00d7 04696df09633
Author: Tobias Burnus 
Date:   Thu Aug 1 11:09:11 2024 +0200

Merge branch 'releases/gcc-14' into devel/omp/gcc-14

Merge up to r14-10526-g04696df09633ba (1st August 2024).
That's the 'GCC 14.2.0 released.' commit.

Diff:

 ChangeLog  |  4 ++
 c++tools/ChangeLog |  4 ++
 config/ChangeLog   |  4 ++
 contrib/ChangeLog  |  4 ++
 contrib/header-tools/ChangeLog |  4 ++
 contrib/reghunt/ChangeLog  |  4 ++
 contrib/regression/ChangeLog   |  4 ++
 fixincludes/ChangeLog  |  4 ++
 gcc/BASE-VER   |  2 +-
 gcc/ChangeLog  | 40 +++
 gcc/DATESTAMP  |  2 +-
 gcc/ada/ChangeLog  |  4 ++
 gcc/analyzer/ChangeLog |  4 ++
 gcc/c-family/ChangeLog |  4 ++
 gcc/c/ChangeLog|  4 ++
 gcc/config/i386/driver-i386.cc |  3 +-
 gcc/config/i386/i386-options.cc|  3 +-
 gcc/cp/ChangeLog   | 39 +++
 gcc/cp/constexpr.cc| 21 +---
 gcc/cp/cp-gimplify.cc  |  4 ++
 gcc/cp/semantics.cc|  2 +-
 gcc/d/ChangeLog|  4 ++
 gcc/fortran/ChangeLog  |  4 ++
 gcc/go/ChangeLog   |  4 ++
 gcc/jit/ChangeLog  |  4 ++
 gcc/lto/ChangeLog  |  4 ++
 gcc/m2/ChangeLog   |  4 ++
 gcc/objc/ChangeLog |  4 ++
 gcc/objcp/ChangeLog|  4 ++
 gcc/po/ChangeLog   |  4 ++
 gcc/rust/ChangeLog |  4 ++
 gcc/testsuite/ChangeLog| 69 ++
 gcc/testsuite/g++.dg/cpp23/consteval-if13.C| 17 +++
 gcc/testsuite/g++.dg/cpp2a/concepts-lambda21.C | 69 ++
 gcc/testsuite/g++.dg/cpp2a/consteval-prop21.C  | 23 +
 gcc/testsuite/g++.dg/cpp2a/constexpr-init23.C  | 22 
 gcc/testsuite/gcc.dg/torture/pr116057.c| 20 
 gcc/testsuite/gcc.target/i386/pr115978-1.c | 22 
 gcc/testsuite/gcc.target/i386/pr115978-2.c |  6 +++
 gcc/tree-ssa-ccp.cc| 11 
 gnattools/ChangeLog|  4 ++
 gotools/ChangeLog  |  4 ++
 include/ChangeLog  |  4 ++
 libada/ChangeLog   |  4 ++
 libatomic/ChangeLog|  4 ++
 libbacktrace/ChangeLog |  4 ++
 libcc1/ChangeLog   |  4 ++
 libcody/ChangeLog  |  4 ++
 libcpp/ChangeLog   |  4 ++
 libcpp/po/ChangeLog|  4 ++
 libdecnumber/ChangeLog |  4 ++
 libffi/ChangeLog   |  4 ++
 libgcc/ChangeLog   |  4 ++
 libgcc/config/avr/libf7/ChangeLog  |  4 ++
 libgcc/config/libbid/ChangeLog |  4 ++
 libgfortran/ChangeLog  |  4 ++
 libgm2/ChangeLog   |  4 ++
 libgomp/ChangeLog  | 11 +---
 libgomp/ChangeLog.omp  | 10 
 libgrust/ChangeLog |  4 ++
 libiberty/ChangeLog|  4 ++
 libitm/ChangeLog   |  4 ++
 libobjc/ChangeLog  |  4 ++
 libphobos/ChangeLog|  4 ++
 libquadmath/ChangeLog  |  4 ++
 libsanitizer/ChangeLog |  4 ++
 libssp/ChangeLog   |  4 ++
 libstdc++-v3/ChangeLog |  4 ++
 libvtv/ChangeLog   |  4 ++
 lto-plugin/ChangeLog   |  4 ++
 maintainer-scripts/ChangeLog   |  4 ++
 zlib/ChangeLog |  4 ++
 72 files changed, 584 insertions(+), 20 deletions(-)

diff --cc libgomp/ChangeLog.omp
index d02bbb14e876,..bda7382a3b45
mode 100644,00..100644
--- a/libgomp/ChangeLog.omp
+++ b/libgomp/ChangeLog.omp
@@@ -1,834 -1,0 +1,844 @@@
 +2024-08-01  Tobias Burnus  
 +
 +  Backported from master:
 +  2024-08-01  Tobias Burnus  
 +  Richard Biener  
 +
 +  Backported from master:
 +  2024-07-29  Tobias Burnus  
 +
 +  PR 

[gcc r14-10527] Bump BASE-VER.

2024-08-01 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:fb2f72db27b96fba73ed525d1e14a141663f82cc

commit r14-10527-gfb2f72db27b96fba73ed525d1e14a141663f82cc
Author: Jakub Jelinek 
Date:   Thu Aug 1 11:17:40 2024 +0200

Bump BASE-VER.

2024-08-01  Jakub Jelinek  

* BASE-VER: Set to 14.2.1.

Diff:
---
 gcc/BASE-VER | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/BASE-VER b/gcc/BASE-VER
index 07ea9fa43814..dab6a80f4a88 100644
--- a/gcc/BASE-VER
+++ b/gcc/BASE-VER
@@ -1 +1 @@
-14.2.0
+14.2.1


[gcc r14-10528] i386: Fix up *_vinsert_0 [PR115981]

2024-08-01 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:973097d801a30385cd39a570624eefa7547f8ff3

commit r14-10528-g973097d801a30385cd39a570624eefa7547f8ff3
Author: Jakub Jelinek 
Date:   Thu Aug 1 10:32:54 2024 +0200

i386: Fix up *_vinsert_0 [PR115981]

The r14-537 change started canonicalizing VEC_MERGE operands based on
swap_commutative_operands_p or if they have the same precedence least
significant bit of the third operand.
The *_vinsert_0 pattern was
added for combine matching and no longer triggers after that change,
as it used the reg_or_0_operand as the first operand and VEC_DUPLICATE
as the second.
Now, reg_or_0_operand could be a REG, SUBREG of object or CONST_VECTOR.
REG has commutative_operand_precedence -1 or -2, SUBREG of object -3,
CONST_VECTOR -4, while VEC_DUPLICATE has 0, so VEC_DUPLICATE will always
go first and REG, SUBREG or CONST_VECTOR second.

This patch swaps the operands so that it matches again.

2024-08-01  Jakub Jelinek  

PR target/115981
* config/i386/sse.md
(*_vinsert_0): Swap the
first two VEC_MERGE operands, renumber match_operands and test
for 0xF or 0x3 rather than 0xFFF0 or 0xFC immediate.

* gcc.target/i386/avx512dq-pr90991-1.c: Add tests for no separate
zero extension instructions.
* gcc.target/i386/avx512dq-pr90991-2.c: Likewise.

(cherry picked from commit df2b444a233e93b987adec76655ab89589b3fa10)

Diff:
---
 gcc/config/i386/sse.md | 42 +++---
 gcc/testsuite/gcc.target/i386/avx512dq-pr90991-1.c |  3 ++
 gcc/testsuite/gcc.target/i386/avx512dq-pr90991-2.c |  3 ++
 3 files changed, 27 insertions(+), 21 deletions(-)

diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 1bf50726e830..073aae293d4c 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -19124,47 +19124,47 @@
 (define_insn "*_vinsert_0"
   [(set (match_operand:AVX512_VEC 0 "register_operand" "=v,x,Yv")
(vec_merge:AVX512_VEC
- (match_operand:AVX512_VEC 1 "reg_or_0_operand" "v,C,C")
  (vec_duplicate:AVX512_VEC
-   (match_operand: 2 "nonimmediate_operand" 
"vm,xm,vm"))
+   (match_operand: 1 "nonimmediate_operand" 
"vm,xm,vm"))
+ (match_operand:AVX512_VEC 2 "reg_or_0_operand" "v,C,C")
  (match_operand:SI 3 "const_int_operand")))]
   "TARGET_AVX512F
&& (INTVAL (operands[3])
-   == (GET_MODE_UNIT_SIZE (mode) == 4 ? 0xFFF0 : 0xFC))"
+   == (GET_MODE_UNIT_SIZE (mode) == 4 ? 0xF : 0x3))"
 {
   if (which_alternative == 0)
-return "vinsert\t{$0, %2, %1, %0|%0, %1, %2, 0}";
+return "vinsert\t{$0, %1, %2, %0|%0, %2, %1, 0}";
   bool egpr_used = (TARGET_APX_EGPR
-   && x86_extended_rex2reg_mentioned_p (operands[2]));
-  const char *align_templ = egpr_used ? "vmovaps\t{%2, %x0|%x0, %2}"
- : "vmovdqa\t{%2, %x0|%x0, %2}";
-  const char *unalign_templ = egpr_used ? "vmovups\t{%2, %x0|%x0, %2}"
-   : "vmovdqu\t{%2, %x0|%x0, %2}";
+   && x86_extended_rex2reg_mentioned_p (operands[1]));
+  const char *align_templ = egpr_used ? "vmovaps\t{%1, %x0|%x0, %1}"
+ : "vmovdqa\t{%1, %x0|%x0, %1}";
+  const char *unalign_templ = egpr_used ? "vmovups\t{%1, %x0|%x0, %1}"
+   : "vmovdqu\t{%1, %x0|%x0, %1}";
   switch (mode)
 {
 case E_V8DFmode:
-  if (misaligned_operand (operands[2], mode))
-   return "vmovupd\t{%2, %x0|%x0, %2}";
+  if (misaligned_operand (operands[1], mode))
+   return "vmovupd\t{%1, %x0|%x0, %1}";
   else
-   return "vmovapd\t{%2, %x0|%x0, %2}";
+   return "vmovapd\t{%1, %x0|%x0, %1}";
 case E_V16SFmode:
-  if (misaligned_operand (operands[2], mode))
-   return "vmovups\t{%2, %x0|%x0, %2}";
+  if (misaligned_operand (operands[1], mode))
+   return "vmovups\t{%1, %x0|%x0, %1}";
   else
-   return "vmovaps\t{%2, %x0|%x0, %2}";
+   return "vmovaps\t{%1, %x0|%x0, %1}";
 case E_V8DImode:
-  if (misaligned_operand (operands[2], mode))
-   return which_alternative == 2 ? "vmovdqu64\t{%2, %x0|%x0, %2}"
+  if (misaligned_operand (operands[1], mode))
+   return which_alternative == 2 ? "vmovdqu64\t{%1, %x0|%x0, %1}"
  : unalign_templ;
   else
-   return which_alternative == 2 ? "vmovdqa64\t{%2, %x0|%x0, %2}"
+   return which_alternative == 2 ? "vmovdqa64\t{%1, %x0|%x0, %1}"
  : align_templ;
 case E_V16SImode:
-  if (misaligned_operand (operands[2], mode))
-   return which_alternative == 2 ? "vmovdqu32\t{%2, %x0|%x0, %2}"
+  if (misaligned_operand (operands[1], mode))
+   return which_alternative == 2 ? "vmovdqu32\t{%1, %x0|%x0, %1}"
  : unal

[gcc/devel/omp/gcc-14] Merge branch 'releases/gcc-14' into devel/omp/gcc-14

2024-08-01 Thread Tobias Burnus via Gcc-cvs
https://gcc.gnu.org/g:3d3c4425604c8917a8dc10f935453ebe82660016

commit 3d3c4425604c8917a8dc10f935453ebe82660016
Merge: 84efccbc61d0 973097d801a3
Author: Tobias Burnus 
Date:   Thu Aug 1 12:24:03 2024 +0200

Merge branch 'releases/gcc-14' into devel/omp/gcc-14

Merge up to r14-10528-g973097d801a303 (1st Aug 2024).
This includes one additional fix + the post-release bump to version 4.2.1.

Diff:

 gcc/BASE-VER   |  2 +-
 gcc/config/i386/sse.md | 42 +++---
 gcc/testsuite/gcc.target/i386/avx512dq-pr90991-1.c |  3 ++
 gcc/testsuite/gcc.target/i386/avx512dq-pr90991-2.c |  3 ++
 4 files changed, 28 insertions(+), 22 deletions(-)


[gcc r15-2476] Add TARGET_MODE_CAN_TRANSFER_BITS

2024-08-01 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:b3974356b0981c7caf9694fe4c2faad902169c00

commit r15-2476-gb3974356b0981c7caf9694fe4c2faad902169c00
Author: Richard Biener 
Date:   Mon Jul 29 13:06:52 2024 +0200

Add TARGET_MODE_CAN_TRANSFER_BITS

The following adds a target hook to specify whether regs of MODE can be
used to transfer bits.  The hook is supposed to be used for value-numbering
to decide whether a value loaded in such mode can be punned to another
mode instead of re-loading the value in the other mode and for SRA to
decide whether MODE is suitable as container holding a value to be
used in different modes.

* target.def (mode_can_transfer_bits): New target hook.
* target.h (mode_can_transfer_bits): New function wrapping the
hook and providing default behavior.
* doc/tm.texi.in: Update.
* doc/tm.texi: Re-generate.

Diff:
---
 gcc/doc/tm.texi| 11 +++
 gcc/doc/tm.texi.in |  2 ++
 gcc/target.def | 13 +
 gcc/target.h   | 16 
 4 files changed, 42 insertions(+)

diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index c7535d07f4dd..cc33084ed322 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -4545,6 +4545,17 @@ is either a declaration of type int or accessed by 
dereferencing
 a pointer to int.
 @end deftypefn
 
+@deftypefn {Target Hook} bool TARGET_MODE_CAN_TRANSFER_BITS (machine_mode 
@var{mode})
+Define this to return false if the mode @var{mode} cannot be used
+for memory copying of @code{GET_MODE_SIZE (mode)} units.  This might be
+because a register class allowed for @var{mode} has registers that do
+not transparently transfer every bit pattern or because the load or
+store patterns available for @var{mode} have this issue.
+
+The default is to assume modes with the same precision as size are fine
+to be used.
+@end deftypefn
+
 @deftypefn {Target Hook} machine_mode TARGET_TRANSLATE_MODE_ATTRIBUTE 
(machine_mode @var{mode})
 Define this hook if during mode attribute processing, the port should
 translate machine_mode @var{mode} to another mode.  For example, rs6000's
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 64cea3b1edaf..8af3f4145058 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -3455,6 +3455,8 @@ stack.
 
 @hook TARGET_REF_MAY_ALIAS_ERRNO
 
+@hook TARGET_MODE_CAN_TRANSFER_BITS
+
 @hook TARGET_TRANSLATE_MODE_ATTRIBUTE
 
 @hook TARGET_SCALAR_MODE_SUPPORTED_P
diff --git a/gcc/target.def b/gcc/target.def
index 3de1aad4c84d..1d0ea6f30caf 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -3363,6 +3363,19 @@ a pointer to int.",
  bool, (ao_ref *ref),
  default_ref_may_alias_errno)
 
+DEFHOOK
+(mode_can_transfer_bits,
+ "Define this to return false if the mode @var{mode} cannot be used\n\
+for memory copying of @code{GET_MODE_SIZE (mode)} units.  This might be\n\
+because a register class allowed for @var{mode} has registers that do\n\
+not transparently transfer every bit pattern or because the load or\n\
+store patterns available for @var{mode} have this issue.\n\
+\n\
+The default is to assume modes with the same precision as size are fine\n\
+to be used.",
+ bool, (machine_mode mode),
+ NULL)
+
 /* Support for named address spaces.  */
 #undef HOOK_PREFIX
 #define HOOK_PREFIX "TARGET_ADDR_SPACE_"
diff --git a/gcc/target.h b/gcc/target.h
index c1f99b97b864..837651d273af 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -312,6 +312,22 @@ estimated_poly_value (poly_int64 x,
 return targetm.estimated_poly_value (x, kind);
 }
 
+/* Return true when MODE can be used to copy GET_MODE_BITSIZE bits
+   unchanged.  */
+
+inline bool
+mode_can_transfer_bits (machine_mode mode)
+{
+  if (mode == BLKmode)
+return true;
+  if (maybe_ne (GET_MODE_BITSIZE (mode),
+   GET_MODE_UNIT_PRECISION (mode) * GET_MODE_NUNITS (mode)))
+return false;
+  if (targetm.mode_can_transfer_bits)
+return targetm.mode_can_transfer_bits (mode);
+  return true;
+}
+
 #ifdef GCC_TM_H
 
 #ifndef CUMULATIVE_ARGS_MAGIC


[gcc r15-2478] tree-optimization/114659 - VN and FP to int punning

2024-08-01 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:ed03af4ef3b9ad0bd3b7c5c678c02253e5cb9e0f

commit r15-2478-ged03af4ef3b9ad0bd3b7c5c678c02253e5cb9e0f
Author: Richard Biener 
Date:   Sun Jul 21 11:56:07 2024 +0200

tree-optimization/114659 - VN and FP to int punning

The following addresses another case where x87 FP loads mangle the
bit representation and thus are not suitable for a representative
in other types.  VN was value-numbering a later integer load of 'x'
as the same as a former float load of 'x'.

We can use the new TARGET_MODE_CAN_TRANSFER_BITS hook to identify
problematic modes and enforce strict compatibility for those in
the reference comparison, improving the handling of modes with
padding in visit_reference_op_load.

PR tree-optimization/114659
* tree-ssa-sccvn.cc (visit_reference_op_load): Do not
prevent punning from modes with padding here, but ...
(vn_reference_eq): ... ensure this here, also honoring
types with modes that cannot act as bit container.

* gcc.target/i386/pr114659.c: New testcase.

Diff:
---
 gcc/testsuite/gcc.target/i386/pr114659.c | 62 
 gcc/tree-ssa-sccvn.cc| 11 +++---
 2 files changed, 66 insertions(+), 7 deletions(-)

diff --git a/gcc/testsuite/gcc.target/i386/pr114659.c 
b/gcc/testsuite/gcc.target/i386/pr114659.c
new file mode 100644
index ..e1e24d55687d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr114659.c
@@ -0,0 +1,62 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+int
+my_totalorderf (float const *x, float const *y)
+{
+  int xs = __builtin_signbit (*x);
+  int ys = __builtin_signbit (*y);
+  if (!xs != !ys)
+return xs;
+
+  int xn = __builtin_isnan (*x);
+  int yn = __builtin_isnan (*y);
+  if (!xn != !yn)
+return !xn == !xs;
+  if (!xn)
+return *x <= *y;
+
+  unsigned int extended_sign = -!!xs;
+  union { unsigned int i; float f; } xu = {0}, yu = {0};
+  __builtin_memcpy (&xu.f, x, sizeof (float));
+  __builtin_memcpy (&yu.f, y, sizeof (float));
+  return (xu.i ^ extended_sign) <= (yu.i ^ extended_sign);
+}
+
+static float
+positive_NaNf ()
+{
+  float volatile nan = 0.0f / 0.0f;
+  return (__builtin_signbit (nan) ? - nan : nan);
+}
+
+typedef union { float value; unsigned int word[1]; } memory_float;
+
+static memory_float
+construct_memory_SNaNf (float quiet_value)
+{
+  memory_float m;
+  m.value = quiet_value;
+  m.word[0] ^= (unsigned int) 1 << 22;
+  m.word[0] |= (unsigned int) 1;
+  return m;
+}
+
+memory_float x[7] =
+  {
+{ 0 },
+{ 1e-5 },
+{ 1 },
+{ 1e37 },
+{ 1.0f / 0.0f },
+  };
+
+int
+main ()
+{
+  x[5] = construct_memory_SNaNf (positive_NaNf ());
+  x[6] = (memory_float) { positive_NaNf () };
+  if (! my_totalorderf (&x[5].value, &x[6].value))
+__builtin_abort ();
+  return 0;
+}
diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index dc377fa16ce6..0639ba426ff5 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -837,6 +837,9 @@ vn_reference_eq (const_vn_reference_t const vr1, 
const_vn_reference_t const vr2)
TYPE_VECTOR_SUBPARTS (vr2->type)))
return false;
 }
+  else if (TYPE_MODE (vr1->type) != TYPE_MODE (vr2->type)
+  && !mode_can_transfer_bits (TYPE_MODE (vr1->type)))
+return false;
 
   i = 0;
   j = 0;
@@ -5814,13 +5817,7 @@ visit_reference_op_load (tree lhs, tree op, gimple *stmt)
   if (result
   && !useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (op)))
 {
-  /* Avoid the type punning in case the result mode has padding where
-the op we lookup has not.  */
-  if (TYPE_MODE (TREE_TYPE (result)) != BLKmode
- && maybe_lt (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (result))),
-  GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (op)
-   result = NULL_TREE;
-  else if (CONSTANT_CLASS_P (result))
+  if (CONSTANT_CLASS_P (result))
result = const_unop (VIEW_CONVERT_EXPR, TREE_TYPE (op), result);
   else
{


[gcc r15-2477] [x86] implement TARGET_MODE_CAN_TRANSFER_BITS

2024-08-01 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:c71646436a55afdd36948d7e7292b3bd5de04e1a

commit r15-2477-gc71646436a55afdd36948d7e7292b3bd5de04e1a
Author: Richard Biener 
Date:   Mon Jul 29 13:10:18 2024 +0200

[x86] implement TARGET_MODE_CAN_TRANSFER_BITS

The following implements the hook, excluding x87 modes for scalar
and complex float modes.

* config/i386/i386.cc (TARGET_MODE_CAN_TRANSFER_BITS): Define.
(ix86_mode_can_transfer_bits): New function.

Diff:
---
 gcc/config/i386/i386.cc | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 77c441893b40..8f289b5bc228 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -26105,6 +26105,25 @@ ix86_have_ccmp ()
   return (bool) TARGET_APX_CCMP;
 }
 
+/* Implement TARGET_MODE_CAN_TRANSFER_BITS.  */
+static bool
+ix86_mode_can_transfer_bits (machine_mode mode)
+{
+  if (GET_MODE_CLASS (mode) == MODE_FLOAT
+  || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
+switch (GET_MODE_INNER (mode))
+  {
+  case SFmode:
+  case DFmode:
+   /* These suffer from normalization upon load when not using SSE.  */
+   return !(ix86_fpmath & FPMATH_387);
+  default:
+   return true;
+  }
+
+  return true;
+}
+
 /* Target-specific selftests.  */
 
 #if CHECKING_P
@@ -26951,6 +26970,9 @@ ix86_libgcc_floating_mode_supported_p
 #undef TARGET_HAVE_CCMP
 #define TARGET_HAVE_CCMP ix86_have_ccmp
 
+#undef TARGET_MODE_CAN_TRANSFER_BITS
+#define TARGET_MODE_CAN_TRANSFER_BITS ix86_mode_can_transfer_bits
+
 static bool
 ix86_libc_has_fast_function (int fcode ATTRIBUTE_UNUSED)
 {


[gcc/devel/omp/gcc-14] (3 commits) Merge branch 'releases/gcc-14' into devel/omp/gcc-14

2024-08-01 Thread Tobias Burnus via Gcc-cvs
The branch 'devel/omp/gcc-14' was updated to point to:

 3d3c4425604c... Merge branch 'releases/gcc-14' into devel/omp/gcc-14

It previously pointed to:

 84efccbc61d0... Merge branch 'releases/gcc-14' into devel/omp/gcc-14

Diff:

Summary of changes (added commits):
---

  3d3c442... Merge branch 'releases/gcc-14' into devel/omp/gcc-14
  973097d... i386: Fix up *_vinsert

[gcc r15-2479] Rust: Make 'tree'-level 'MAIN_NAME_P' work

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:5f9e88211c6ad939cfec017a66e663d686c9c3ab

commit r15-2479-g5f9e88211c6ad939cfec017a66e663d686c9c3ab
Author: Thomas Schwinge 
Date:   Wed Apr 12 11:47:01 2023 +0200

Rust: Make 'tree'-level 'MAIN_NAME_P' work

'gcc/tree.h':

#define main_identifier_node
global_trees[TI_MAIN_IDENTIFIER]
#define MAIN_NAME_P(NODE) \
  (IDENTIFIER_NODE_CHECK (NODE) == main_identifier_node)

..., which is not initialized by default, but has to be set up by every 
front
end individually.  'MAIN_NAME_P' enables certain code optimizations, but is
especially also relevant for back ends that emit additional program entry 
setup
code for 'main'.

gcc/rust/
* backend/rust-compile-base.cc (HIRCompileBase::compile_function):
For 'main', initialize 'main_identifier_node'.

Diff:
---
 gcc/rust/backend/rust-compile-base.cc | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/gcc/rust/backend/rust-compile-base.cc 
b/gcc/rust/backend/rust-compile-base.cc
index 984492f6607c..4d6f0275b004 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -657,6 +657,12 @@ HIRCompileBase::compile_function (
 
   // we don't mangle the main fn since we haven't implemented the main shim
   bool is_main_fn = fn_name.compare ("main") == 0;
+  if (is_main_fn)
+{
+  rust_assert (!main_identifier_node);
+  /* So that 'MAIN_NAME_P' works.  */
+  main_identifier_node = get_identifier (ir_symbol_name.c_str ());
+}
   std::string asm_name = fn_name;
 
   unsigned int flags = 0;


[gcc r15-2480] gccrs: Fix false positive for top-level AltPattern

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:8319fa7847d90c87fe6a4e78b1079d13dbe05d62

commit r15-2480-g8319fa7847d90c87fe6a4e78b1079d13dbe05d62
Author: Owen Avery 
Date:   Sun Feb 18 00:19:25 2024 -0500

gccrs: Fix false positive for top-level AltPattern

gcc/rust/ChangeLog:

* hir/rust-ast-lower-pattern.cc
(ASTLoweringPattern::visit):
Reset is_let_top_level while visiting GroupedPattern.

gcc/testsuite/ChangeLog:

* rust/compile/let_alt.rs: Check for false positive.

Signed-off-by: Owen Avery 

Diff:
---
 gcc/rust/hir/rust-ast-lower-pattern.cc | 1 +
 gcc/testsuite/rust/compile/let_alt.rs  | 1 +
 2 files changed, 2 insertions(+)

diff --git a/gcc/rust/hir/rust-ast-lower-pattern.cc 
b/gcc/rust/hir/rust-ast-lower-pattern.cc
index a2228488ad2a..d534b8295176 100644
--- a/gcc/rust/hir/rust-ast-lower-pattern.cc
+++ b/gcc/rust/hir/rust-ast-lower-pattern.cc
@@ -276,6 +276,7 @@ ASTLoweringPattern::visit (AST::RangePattern &pattern)
 void
 ASTLoweringPattern::visit (AST::GroupedPattern &pattern)
 {
+  is_let_top_level = false;
   pattern.get_pattern_in_parens ()->accept_vis (*this);
 }
 
diff --git a/gcc/testsuite/rust/compile/let_alt.rs 
b/gcc/testsuite/rust/compile/let_alt.rs
index a2735bdbe770..ff16e6428ff1 100644
--- a/gcc/testsuite/rust/compile/let_alt.rs
+++ b/gcc/testsuite/rust/compile/let_alt.rs
@@ -1,4 +1,5 @@
 fn main() {
 let _a | _a = 12;
 // { dg-error "top level or-patterns are not allowed for .let. bindings" 
"" { target *-*-* } .-1 }
+let (_b | _b) = 12;
 }


[gcc r15-2481] gccrs: minor cleanup in langhook.type_for_mode

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:a58f7df1475c4e8bb744a79bfa36293ff7fb20bb

commit r15-2481-ga58f7df1475c4e8bb744a79bfa36293ff7fb20bb
Author: Marc Poulhiès 
Date:   Mon Feb 19 22:52:29 2024 +0100

gccrs: minor cleanup in langhook.type_for_mode

gcc/rust/ChangeLog:

* rust-lang.cc (grs_langhook_type_for_mode): simplify code for
xImode. Add missing long_double_type_node.

Signed-off-by: Marc Poulhiès 

Diff:
---
 gcc/rust/rust-lang.cc | 39 +++
 1 file changed, 15 insertions(+), 24 deletions(-)

diff --git a/gcc/rust/rust-lang.cc b/gcc/rust/rust-lang.cc
index 4c2ef108bced..a1f5fe3978df 100644
--- a/gcc/rust/rust-lang.cc
+++ b/gcc/rust/rust-lang.cc
@@ -169,38 +169,29 @@ static tree
 grs_langhook_type_for_mode (machine_mode mode, int unsignedp)
 {
   // TODO: change all this later to match rustc types
-  if (mode == TYPE_MODE (float_type_node))
-return float_type_node;
-
-  if (mode == TYPE_MODE (double_type_node))
-return double_type_node;
-
-  if (mode == TYPE_MODE (intQI_type_node)) // quarter integer mode - single 
byte
-  // treated as integer
+  if (mode == QImode)
 return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
-  if (mode
-  == TYPE_MODE (intHI_type_node)) // half integer mode - two-byte integer
+
+  if (mode == HImode)
 return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
-  if (mode
-  == TYPE_MODE (intSI_type_node)) // single integer mode - four-byte 
integer
+
+  if (mode == SImode)
 return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
-  if (mode
-  == TYPE_MODE (
-   intDI_type_node)) // double integer mode - eight-byte integer
+
+  if (mode == DImode)
 return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
-  if (mode
-  == TYPE_MODE (intTI_type_node)) // tetra integer mode - 16-byte integer
+
+  if (mode == TYPE_MODE (intTI_type_node))
 return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
 
-  if (mode == TYPE_MODE (integer_type_node))
-return unsignedp ? unsigned_type_node : integer_type_node;
+  if (mode == TYPE_MODE (float_type_node))
+return float_type_node;
 
-  if (mode == TYPE_MODE (long_integer_type_node))
-return unsignedp ? long_unsigned_type_node : long_integer_type_node;
+  if (mode == TYPE_MODE (double_type_node))
+return double_type_node;
 
-  if (mode == TYPE_MODE (long_long_integer_type_node))
-return unsignedp ? long_long_unsigned_type_node
-: long_long_integer_type_node;
+  if (mode == TYPE_MODE (long_double_type_node))
+return long_double_type_node;
 
   if (COMPLEX_MODE_P (mode))
 {


[gcc r15-2482] gccrs: fmt: Start working on format_args!() parser

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:473feb033d5ccb139f8af8e0e54193b176d1cd93

commit r15-2482-g473feb033d5ccb139f8af8e0e54193b176d1cd93
Author: Arthur Cohen 
Date:   Thu Nov 9 18:32:52 2023 +0100

gccrs: fmt: Start working on format_args!() parser

This commit adds a base class for parsing the various constructs of a
Rust format string, according to the grammar in the reference:

https://doc.rust-lang.org/std/fmt/index.html#syntax

gcc/rust/ChangeLog:

* Make-lang.in: Compile rust-fmt object
* ast/rust-fmt.cc: New file.
* ast/rust-fmt.h: New file.

Diff:
---
 gcc/rust/Make-lang.in|   1 +
 gcc/rust/ast/rust-fmt.cc |  96 ++
 gcc/rust/ast/rust-fmt.h  | 133 +++
 3 files changed, 230 insertions(+)

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index e437c32e3471..c0df49a7fee8 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -100,6 +100,7 @@ GRS_OBJS = \
 rust/rust-proc-macro-invoc-lexer.o \
 rust/rust-macro-substitute-ctx.o \
 rust/rust-macro-builtins.o \
+   rust/rust-fmt.o \
 rust/rust-hir.o \
 rust/rust-hir-map.o \
 rust/rust-attributes.o \
diff --git a/gcc/rust/ast/rust-fmt.cc b/gcc/rust/ast/rust-fmt.cc
new file mode 100644
index ..9f9ba48f0c3a
--- /dev/null
+++ b/gcc/rust/ast/rust-fmt.cc
@@ -0,0 +1,96 @@
+// Copyright (C) 2020-2023 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-fmt.h"
+
+namespace Rust {
+tl::expected
+Fmt::parse_fmt_string (Fmt::Input input)
+{
+  return Fmt ();
+}
+
+tl::expected>, Fmt::Error>
+Fmt::maybe_format (Fmt::Input input)
+{
+  tl::optional none = tl::nullopt;
+
+  return Fmt::Result (input, none);
+}
+
+tl::expected, Fmt::Error>
+Fmt::format (Input input)
+{
+  return Fmt::Result (input, Format ());
+}
+
+tl::expected, Fmt::Error>
+Fmt::argument (Input input)
+{
+  return Fmt::Result (input, Argument ());
+}
+
+tl::expected, Fmt::Error>
+Fmt::format_spec (Input input)
+{
+  return Fmt::Result (input, FormatSpec ());
+}
+
+tl::expected, Fmt::Error>
+Fmt::fill (Input input)
+{
+  return Fmt::Result (input, Fill ());
+}
+
+tl::expected, Fmt::Error>
+Fmt::align (Input input)
+{
+  switch (input[0])
+{
+case '<':
+  return Fmt::Result (input.substr (1), Align::Left);
+case '^':
+  return Fmt::Result (input.substr (1), Align::Top);
+case '>':
+  return Fmt::Result (input.substr (1), Align::Right);
+default:
+  // TODO: Store the character here
+  // TODO: Can we have proper error locations?
+  // TODO: Maybe we should use a Rust::Literal string instead of a string
+  return tl::make_unexpected (Error::Align);
+}
+}
+
+tl::expected, Fmt::Error>
+Fmt::sign (Input input)
+{
+  switch (input[0])
+{
+case '+':
+  return Fmt::Result (input.substr (1), Sign::Plus);
+case '-':
+  return Fmt::Result (input.substr (1), Sign::Minus);
+default:
+  // TODO: Store the character here
+  // TODO: Can we have proper error locations?
+  // TODO: Maybe we should use a Rust::Literal string instead of a string
+  return tl::make_unexpected (Error::Sign);
+}
+}
+
+} // namespace Rust
diff --git a/gcc/rust/ast/rust-fmt.h b/gcc/rust/ast/rust-fmt.h
new file mode 100644
index ..f3dd53da9791
--- /dev/null
+++ b/gcc/rust/ast/rust-fmt.h
@@ -0,0 +1,133 @@
+// Copyright (C) 2020-2023 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_FMT_H
+#define RUST_FMT_H
+
+#include "expected.h"
+#include "optional.h"
+#include "rust-ast.h"
+#include "rust-system.h"
+
+namespace Rust {
+
+/**
+ * Thi

[gcc r15-2484] gccrs: Add 'gcc/rust/Make-lang.in:LIBFORMAT_PARSER'

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:2340894554334a310b891a1d9e9d5e3f502357ac

commit r15-2484-g2340894554334a310b891a1d9e9d5e3f502357ac
Author: Thomas Schwinge 
Date:   Wed Feb 28 22:51:24 2024 +0100

gccrs: Add 'gcc/rust/Make-lang.in:LIBFORMAT_PARSER'

... to avoid verbatim repetition.

gcc/rust/
* Make-lang.in (LIBPROC_MACRO_INTERNAL): New.
(RUST_LIBDEPS, crab1$(exeext), rust/libformat_parser.a): Use it.

Diff:
---
 gcc/rust/Make-lang.in | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 8ac0d1d19736..bcf424e6c185 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -212,6 +212,9 @@ RUST_ALL_OBJS = $(GRS_OBJS) $(RUST_TARGET_OBJS)
 rust_OBJS = $(RUST_ALL_OBJS) rust/rustspec.o
 
 LIBPROC_MACRO_INTERNAL = 
../libgrust/libproc_macro_internal/libproc_macro_internal.a
+LIBFORMAT_PARSER = rust/libformat_parser.a
+
+RUST_LIBDEPS = $(LIBDEPS) $(LIBPROC_MACRO_INTERNAL) $(LIBFORMAT_PARSER)
 
 
 RUST_LIBDEPS = $(LIBDEPS) $(LIBPROC_MACRO_INTERNAL)
@@ -220,7 +223,7 @@ RUST_LIBDEPS = $(LIBDEPS) $(LIBPROC_MACRO_INTERNAL)
 crab1$(exeext): $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(RUST_LIBDEPS) 
$(rust.prev)
@$(call LINK_PROGRESS,$(INDEX.rust),start)
+$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
- $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(LIBS) 
$(LIBPROC_MACRO_INTERNAL) rust/libformat_parser.a  $(BACKENDLIBS)
+ $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(LIBS) 
$(LIBPROC_MACRO_INTERNAL) $(LIBFORMAT_PARSER) $(BACKENDLIBS)
@$(call LINK_PROGRESS,$(INDEX.rust),end)
 
 # Build hooks.
@@ -411,9 +414,10 @@ rust/%.o: rust/lex/%.cc
 %.toml: 
echo $@
 
-rust/libformat_parser.a: $(srcdir)/../libgrust/libformat_parser/Cargo.toml 
$(wildcard $(srcdir)/../libgrust/libformat_parser/src/*.rs)
-   cargo build --manifest-path 
$(srcdir)/../libgrust/libformat_parser/Cargo.toml --release # FIXME: Not always 
release, right?
-   cp 
$(srcdir)/../libgrust/libformat_parser/target/release/liblibformat_parser.a $@
+# TODO: Improve `cargo` invocation with host specific flags, possibly creating 
a $(CARGO) variable?
+$(LIBFORMAT_PARSER): $(srcdir)/../libgrust/libformat_parser/Cargo.toml 
$(wildcard $(srcdir)/../libgrust/libformat_parser/src/*.rs)
+   cd $(srcdir)/../libgrust/libformat_parser && cargo build --offline  # 
FIXME: Not always release, right?
+   cp 
$(srcdir)/../libgrust/libformat_parser/target/debug/liblibformat_parser.a $@
 
 # build all rust/parse files in rust folder, add cross-folder includes
 rust/%.o: rust/parse/%.cc


[gcc r15-2483] gccrs: libgrust: Add format_parser library

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:6fef4d6ffcab0fec8518adcb05458cba5dbeac25

commit r15-2483-g6fef4d6ffcab0fec8518adcb05458cba5dbeac25
Author: Arthur Cohen 
Date:   Tue Apr 23 13:38:58 2024 +0200

gccrs: libgrust: Add format_parser library

Compile libformat_parser and link to it.

gcc/rust/ChangeLog:

* Make-lang.in: Compile libformat_parser.
* ast/rust-fmt.cc: New FFI definitions.
* ast/rust-fmt.h: Likewise.
* expand/rust-macro-builtins.cc 
(MacroBuiltin::format_args_handler): Call
into libformat_parser.
* expand/rust-macro-builtins.h: Define format_args!() handler 
proper.

libgrust/ChangeLog:

* libformat_parser/Cargo.lock: New file.
* libformat_parser/Cargo.toml: New file.
* libformat_parser/generic_format_parser/Cargo.toml: New file.
* libformat_parser/generic_format_parser/src/lib.rs: New file.
* libformat_parser/src/bin.rs: New file.
* libformat_parser/src/lib.rs: New file.

Diff:
---
 gcc/rust/Make-lang.in  |   11 +-
 gcc/rust/ast/rust-fmt.cc   |   77 +-
 gcc/rust/ast/rust-fmt.h|  189 ++--
 gcc/rust/expand/rust-macro-builtins.cc |   12 +-
 gcc/rust/expand/rust-macro-builtins.h  |3 +
 libgrust/libformat_parser/Cargo.lock   |   30 +
 libgrust/libformat_parser/Cargo.toml   |   21 +
 .../generic_format_parser/Cargo.toml   |9 +
 .../generic_format_parser/src/lib.rs   | 1102 
 libgrust/libformat_parser/src/bin.rs   |7 +
 libgrust/libformat_parser/src/lib.rs   |   41 +
 11 files changed, 1349 insertions(+), 153 deletions(-)

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index c0df49a7fee8..8ac0d1d19736 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -54,6 +54,8 @@ GCCRS_D_OBJS = \
rust/rustspec.o \
$(END)
 
+LIBS += -ldl -lpthread
+
 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 \
@@ -218,7 +220,7 @@ RUST_LIBDEPS = $(LIBDEPS) $(LIBPROC_MACRO_INTERNAL)
 crab1$(exeext): $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(RUST_LIBDEPS) 
$(rust.prev)
@$(call LINK_PROGRESS,$(INDEX.rust),start)
+$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
- $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(LIBS) 
$(LIBPROC_MACRO_INTERNAL) $(BACKENDLIBS)
+ $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(LIBS) 
$(LIBPROC_MACRO_INTERNAL) rust/libformat_parser.a  $(BACKENDLIBS)
@$(call LINK_PROGRESS,$(INDEX.rust),end)
 
 # Build hooks.
@@ -406,6 +408,13 @@ rust/%.o: rust/lex/%.cc
$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
$(POSTCOMPILE)
 
+%.toml: 
+   echo $@
+
+rust/libformat_parser.a: $(srcdir)/../libgrust/libformat_parser/Cargo.toml 
$(wildcard $(srcdir)/../libgrust/libformat_parser/src/*.rs)
+   cargo build --manifest-path 
$(srcdir)/../libgrust/libformat_parser/Cargo.toml --release # FIXME: Not always 
release, right?
+   cp 
$(srcdir)/../libgrust/libformat_parser/target/release/liblibformat_parser.a $@
+
 # build all rust/parse files in rust folder, add cross-folder includes
 rust/%.o: rust/parse/%.cc
$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
diff --git a/gcc/rust/ast/rust-fmt.cc b/gcc/rust/ast/rust-fmt.cc
index 9f9ba48f0c3a..559b1c8b5795 100644
--- a/gcc/rust/ast/rust-fmt.cc
+++ b/gcc/rust/ast/rust-fmt.cc
@@ -19,78 +19,23 @@
 #include "rust-fmt.h"
 
 namespace Rust {
-tl::expected
-Fmt::parse_fmt_string (Fmt::Input input)
-{
-  return Fmt ();
-}
+namespace Fmt {
 
-tl::expected>, Fmt::Error>
-Fmt::maybe_format (Fmt::Input input)
+Pieces
+Pieces::collect (const std::string &to_parse)
 {
-  tl::optional none = tl::nullopt;
+  auto piece_slice = collect_pieces (to_parse.c_str ());
 
-  return Fmt::Result (input, none);
-}
+  rust_debug ("[ARTHUR] %p, %lu", (void *) piece_slice.ptr, piece_slice.len);
 
-tl::expected, Fmt::Error>
-Fmt::format (Input input)
-{
-  return Fmt::Result (input, Format ());
-}
+  // this performs multiple copies, can we avoid them maybe?
+  auto pieces
+= std::vector (piece_slice.ptr, piece_slice.ptr + piece_slice.len);
 
-tl::expected, Fmt::Error>
-Fmt::argument (Input input)
-{
-  return Fmt::Result (input, Argument ());
-}
+  rust_debug ("[ARTHUR] %p, %lu", (void *) pieces.data (), pieces.size ());
 
-tl::expected, Fmt::Error>
-Fmt::format_spec (Input input)
-{
-  return Fmt::Result (input, FormatSpec ());
-}
-
-tl::expected, Fmt::Error>
-Fmt::fill (Input input)
-{
-  return Fmt::Result (input, Fill ());
-}
-
-tl::expected, Fmt::Error>
-Fmt::align (Input input)
-{
-  switch (input[0])
-{
-case '<':
-  return Fmt::Result (input.substr (1), Align::Left);
-   

[gcc r15-2487] Rust: Move 'libformat_parser' build into the GCC build directory

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:acf10f83abbf57846583ac6feef3f62982f0da5d

commit r15-2487-gacf10f83abbf57846583ac6feef3f62982f0da5d
Author: Thomas Schwinge 
Date:   Wed Feb 28 23:26:39 2024 +0100

Rust: Move 'libformat_parser' build into the GCC build directory

Fixes #2883.

gcc/rust/ChangeLog:
* Make-lang.in (LIBFORMAT_PARSER): Point to the GCC build
directory.
* ($(LIBFORMAT_PARSER)): Build in the GCC build directory.

Diff:
---
 gcc/rust/Make-lang.in | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 497a3c76166e..b3301f5ce6fa 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -212,7 +212,8 @@ RUST_ALL_OBJS = $(GRS_OBJS) $(RUST_TARGET_OBJS)
 rust_OBJS = $(RUST_ALL_OBJS) rust/rustspec.o
 
 LIBPROC_MACRO_INTERNAL = 
../libgrust/libproc_macro_internal/libproc_macro_internal.a
-LIBFORMAT_PARSER = 
$(srcdir)/../libgrust/libformat_parser/target/debug/liblibformat_parser.a
+LIBFORMAT_PARSER_D = rust/libformat_parser
+LIBFORMAT_PARSER = $(LIBFORMAT_PARSER_D)/debug/liblibformat_parser.a
 
 RUST_LIBDEPS = $(LIBDEPS) $(LIBPROC_MACRO_INTERNAL) $(LIBFORMAT_PARSER)
 
@@ -416,7 +417,13 @@ rust/%.o: rust/lex/%.cc
 
 # TODO: Improve `cargo` invocation with host specific flags, possibly creating 
a $(CARGO) variable?
 $(LIBFORMAT_PARSER): $(srcdir)/../libgrust/libformat_parser/Cargo.toml 
$(wildcard $(srcdir)/../libgrust/libformat_parser/src/*.rs)
-   cd $(srcdir)/../libgrust/libformat_parser && cargo build --offline  # 
FIXME: Not always release, right?
+   cargo \
+ --config $(srcdir)/../libgrust/libformat_parser/.cargo/config \
+ build \
+   --offline \
+   --target-dir $(LIBFORMAT_PARSER_D) \
+   --manifest-path $(srcdir)/../libgrust/libformat_parser/Cargo.toml \
+   # FIXME: Not always '--release', right?
 
 # build all rust/parse files in rust folder, add cross-folder includes
 rust/%.o: rust/parse/%.cc


[gcc r15-2488] Rust: Move 'libformat_parser' build into libgrust

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:8e284d026e8b234d2eb9b2ffa5ab3348dbe656be

commit r15-2488-g8e284d026e8b234d2eb9b2ffa5ab3348dbe656be
Author: Thomas Schwinge 
Date:   Thu Feb 29 08:44:49 2024 +0100

Rust: Move 'libformat_parser' build into libgrust

Addresses #2883.

contrib/
* gcc_update (files_and_dependencies): Update for
'libformat_parser' in libgrust.
gcc/rust/
* Make-lang.in (LIBFORMAT_PARSER): Point to 'libformat_parser'
build in libgrust.
(%.toml:, $(LIBFORMAT_PARSER):): Remove.
libgrust/
* libformat_parser/Makefile.am: New.
* Makefile.am [!TARGET_LIBRARY] (SUBDIRS): Add 'libformat_parser'.
* configure.ac: Handle it.
(TARGET_LIBRARY): New 'AM_CONDITIONAL'.
* libformat_parser/Makefile.in: Generate.
* Makefile.in: Regenerate.
* configure: Likewise.

Diff:
---
 contrib/gcc_update|   1 +
 gcc/rust/Make-lang.in |  16 +-
 libgrust/Makefile.am  |   6 +-
 libgrust/Makefile.in  |   5 +-
 libgrust/configure|  22 +-
 libgrust/configure.ac |   3 +
 libgrust/libformat_parser/Makefile.am |  13 +
 libgrust/libformat_parser/Makefile.in | 441 ++
 8 files changed, 487 insertions(+), 20 deletions(-)

diff --git a/contrib/gcc_update b/contrib/gcc_update
index fac86d0e33e4..417e0483b3f3 100755
--- a/contrib/gcc_update
+++ b/contrib/gcc_update
@@ -158,6 +158,7 @@ libgomp/config.h.in: libgomp/configure.ac libgomp/aclocal.m4
 libgrust/Makefile.in: libgrust/Makefile.am libgrust/aclocal.m4
 libgrust/aclocal.m4: libgrust/configure.ac
 libgrust/configure: libgrust/configure.ac libgrust/aclocal.m4
+libgrust/libformat_parser/Makefile.in: libgrust/libformat_parser/Makefile.am 
libgrust/aclocal.m4
 libgrust/libproc_macro_internal/Makefile.in: 
libgrust/libproc_macro_internal/Makefile.am libgrust/aclocal.m4
 libitm/aclocal.m4: libitm/configure.ac libitm/acinclude.m4
 libitm/Makefile.in: libitm/Makefile.am libitm/aclocal.m4
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index b3301f5ce6fa..baf55161d78f 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -212,8 +212,7 @@ RUST_ALL_OBJS = $(GRS_OBJS) $(RUST_TARGET_OBJS)
 rust_OBJS = $(RUST_ALL_OBJS) rust/rustspec.o
 
 LIBPROC_MACRO_INTERNAL = 
../libgrust/libproc_macro_internal/libproc_macro_internal.a
-LIBFORMAT_PARSER_D = rust/libformat_parser
-LIBFORMAT_PARSER = $(LIBFORMAT_PARSER_D)/debug/liblibformat_parser.a
+LIBFORMAT_PARSER = ../libgrust/libformat_parser/debug/liblibformat_parser.a
 
 RUST_LIBDEPS = $(LIBDEPS) $(LIBPROC_MACRO_INTERNAL) $(LIBFORMAT_PARSER)
 
@@ -412,19 +411,6 @@ rust/%.o: rust/lex/%.cc
$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
$(POSTCOMPILE)
 
-%.toml: 
-   echo $@
-
-# TODO: Improve `cargo` invocation with host specific flags, possibly creating 
a $(CARGO) variable?
-$(LIBFORMAT_PARSER): $(srcdir)/../libgrust/libformat_parser/Cargo.toml 
$(wildcard $(srcdir)/../libgrust/libformat_parser/src/*.rs)
-   cargo \
- --config $(srcdir)/../libgrust/libformat_parser/.cargo/config \
- build \
-   --offline \
-   --target-dir $(LIBFORMAT_PARSER_D) \
-   --manifest-path $(srcdir)/../libgrust/libformat_parser/Cargo.toml \
-   # FIXME: Not always '--release', right?
-
 # build all rust/parse files in rust folder, add cross-folder includes
 rust/%.o: rust/parse/%.cc
$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
diff --git a/libgrust/Makefile.am b/libgrust/Makefile.am
index 5b38c8842cb4..7a4512cae96b 100644
--- a/libgrust/Makefile.am
+++ b/libgrust/Makefile.am
@@ -11,7 +11,11 @@ TOP_GCCDIR := $(shell cd $(top_srcdir) && cd .. && pwd)
 GCC_DIR = $(TOP_GCCDIR)/gcc
 RUST_SRC = $(GCC_DIR)/rust
 
-SUBDIRS = libproc_macro_internal
+SUBDIRS =
+if !TARGET_LIBRARY
+SUBDIRS += libformat_parser
+endif
+SUBDIRS += libproc_macro_internal
 
 RUST_BUILDDIR := $(shell pwd)
 
diff --git a/libgrust/Makefile.in b/libgrust/Makefile.in
index d065584d196f..6665f8da738f 100644
--- a/libgrust/Makefile.in
+++ b/libgrust/Makefile.in
@@ -88,6 +88,7 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
+@TARGET_LIBRARY_FALSE@am__append_1 = libformat_parser
 subdir = .
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
@@ -165,7 +166,7 @@ am__define_uniq_tagged_files = \
 ETAGS = etags
 CTAGS = ctags
 CSCOPE = cscope
-DIST_SUBDIRS = $(SUBDIRS)
+DIST_SUBDIRS = libformat_parser libproc_macro_internal
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
@@ -308,7 +309,7 @@ AM_CFLAGS = -I $(srcdir)/../libgcc -I 
$(MULTIBUILDTOP)../../gcc/include
 TOP_GCCDIR := $(shell cd $(top_srcdir) && cd .. && pwd)
 GCC_DIR = $(TOP_GCCDIR)/gcc
 RUST_SRC = $(GCC_DIR)/rust
-SUBDIRS

[gcc r15-2489] gccrs: libformat_parser: Add FFI safe interface

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:8647682e5a2d670e287382307f54922b46157a40

commit r15-2489-g8647682e5a2d670e287382307f54922b46157a40
Author: Arthur Cohen 
Date:   Mon Jan 29 16:13:24 2024 +0100

gccrs: libformat_parser: Add FFI safe interface

libgrust/ChangeLog:

* libformat_parser/generic_format_parser/src/lib.rs: Add generic
library.
* libformat_parser/src/lib.rs: Add base for FFI interface.

Diff:
---
 .../generic_format_parser/src/lib.rs   |   2 +-
 libgrust/libformat_parser/src/lib.rs   | 301 -
 2 files changed, 298 insertions(+), 5 deletions(-)

diff --git a/libgrust/libformat_parser/generic_format_parser/src/lib.rs 
b/libgrust/libformat_parser/generic_format_parser/src/lib.rs
index f42c9d8dffbb..87a20dc18c56 100644
--- a/libgrust/libformat_parser/generic_format_parser/src/lib.rs
+++ b/libgrust/libformat_parser/generic_format_parser/src/lib.rs
@@ -1099,4 +1099,4 @@ fn unescape_string(string: &str) -> 
Option {
 // rustc_index::static_assert_size!(Piece<'_>, 16);
 
 // #[cfg(test)]
-// mod tests;
\ No newline at end of file
+// mod tests;
diff --git a/libgrust/libformat_parser/src/lib.rs 
b/libgrust/libformat_parser/src/lib.rs
index e6dc16eeb498..49821e7cd2f4 100644
--- a/libgrust/libformat_parser/src/lib.rs
+++ b/libgrust/libformat_parser/src/lib.rs
@@ -5,8 +5,298 @@
 
 use std::ffi::CStr;
 
-// TODO: Use rustc's version here #3
-use generic_format_parser::Piece;
+mod ffi {
+use std::ops::Deref;
+
+// Note: copied from rustc_span
+/// Range inside of a `Span` used for diagnostics when we only have access 
to relative positions.
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+#[repr(C)]
+pub struct InnerSpan {
+pub start: usize,
+pub end: usize,
+}
+
+// impl InnerSpan {
+// pub fn new(start: usize, end: usize) -> InnerSpan {
+// InnerSpan { start, end }
+// }
+// }
+
+/// The location and before/after width of a character whose width has 
changed from its source code
+/// representation
+#[derive(Copy, Clone, PartialEq, Eq)]
+#[repr(C)]
+pub struct InnerWidthMapping {
+/// Index of the character in the source
+pub position: usize,
+/// The inner width in characters
+pub before: usize,
+/// The transformed width in characters
+pub after: usize,
+}
+
+// impl InnerWidthMapping {
+// pub fn new(position: usize, before: usize, after: usize) -> 
InnerWidthMapping {
+// InnerWidthMapping {
+// position,
+// before,
+// after,
+// }
+// }
+// }
+
+/// Whether the input string is a literal. If yes, it contains the inner 
width mappings.
+#[derive(Clone, PartialEq, Eq)]
+#[repr(C)]
+enum InputStringKind {
+NotALiteral,
+Literal {
+width_mappings: Vec,
+},
+}
+
+/// The type of format string that we are parsing.
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+#[repr(C)]
+pub enum ParseMode {
+/// A normal format string as per `format_args!`.
+Format,
+/// An inline assembly template string for `asm!`.
+InlineAsm,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+struct InnerOffset(usize);
+
+/// A piece is a portion of the format string which represents the next 
part
+/// to emit. These are emitted as a stream by the `Parser` class.
+#[derive(Clone, Debug, PartialEq)]
+#[repr(C)]
+pub enum Piece<'a> {
+/// A literal string which should directly be emitted
+String(&'a str),
+/// This describes that formatting should process the next argument (as
+/// specified inside) for emission.
+NextArgument(Box>),
+}
+
+/// Representation of an argument specification.
+#[derive(Copy, Clone, Debug, PartialEq)]
+#[repr(C)]
+pub struct Argument<'a> {
+/// Where to find this argument
+pub position: Position<'a>,
+/// The span of the position indicator. Includes any whitespace in 
implicit
+/// positions (`{  }`).
+pub position_span: InnerSpan,
+/// How to format the argument
+pub format: FormatSpec<'a>,
+}
+
+/// Specification for the formatting of an argument in the format string.
+#[derive(Copy, Clone, Debug, PartialEq)]
+#[repr(C)]
+pub struct FormatSpec<'a> {
+/// Optionally specified character to fill alignment with.
+pub fill: Option,
+/// Span of the optionally specified fill character.
+pub fill_span: Option,
+/// Optionally specified alignment.
+pub align: Alignment,
+/// The `+` or `-` flag.
+pub sign: Option,
+/// The `#` flag.
+pub alternate: bool,
+/// The `0` flag.
+pub zero_pad: bool,
+/// The `x` or `X` flag. (Only for 

[gcc r15-2490] gccrs: libformat_parser: Start experimenting with cbindgen

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:6a7d0e5dc62be70561a3ecfd9d5b202e72e4886e

commit r15-2490-g6a7d0e5dc62be70561a3ecfd9d5b202e72e4886e
Author: Arthur Cohen 
Date:   Mon Jan 29 16:14:13 2024 +0100

gccrs: libformat_parser: Start experimenting with cbindgen

libgrust/ChangeLog:

* libformat_parser/cbindgen.toml: New file.
* libformat_parser/libformat-parser.h: New file.

gcc/rust/ChangeLog:

* ast/rust-fmt.h: Add remaining FFI types.

Diff:
---
 gcc/rust/ast/rust-fmt.h  |   4 +-
 libgrust/libformat_parser/cbindgen.toml  |   0
 libgrust/libformat_parser/libformat-parser.h | 224 +++
 3 files changed, 226 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/ast/rust-fmt.h b/gcc/rust/ast/rust-fmt.h
index 0050977358f1..27c1c3625d3e 100644
--- a/gcc/rust/ast/rust-fmt.h
+++ b/gcc/rust/ast/rust-fmt.h
@@ -92,11 +92,11 @@ struct FormatSpec
   /// The `x` or `X` flag. (Only for `Debug`.)
   tl::optional debug_hex;
   /// The integer precision to use.
-  // Count <'a> precision;
+  Count precision;
   /// The span of the precision formatting flag (for diagnostics).
   tl::optional precision_span;
   /// The string width requested for the resulting format.
-  // Count <'a> width;
+  Count width;
   /// The span of the width formatting flag (for diagnostics).
   tl::optional width_span;
   /// The descriptor string representing the name of the format desired for
diff --git a/libgrust/libformat_parser/cbindgen.toml 
b/libgrust/libformat_parser/cbindgen.toml
new file mode 100644
index ..e69de29bb2d1
diff --git a/libgrust/libformat_parser/libformat-parser.h 
b/libgrust/libformat_parser/libformat-parser.h
new file mode 100644
index ..a4bc8a754944
--- /dev/null
+++ b/libgrust/libformat_parser/libformat-parser.h
@@ -0,0 +1,224 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/// Enum of alignments which are supported.
+enum class Alignment
+{
+  /// The value will be aligned to the left.
+  AlignLeft,
+  /// The value will be aligned to the right.
+  AlignRight,
+  /// The value will be aligned in the center.
+  AlignCenter,
+  /// The value will take on a default alignment.
+  AlignUnknown,
+};
+
+/// Enum for the debug hex flags.
+enum class DebugHex
+{
+  /// The `x` flag in `{:x?}`.
+  Lower,
+  /// The `X` flag in `{:X?}`.
+  Upper,
+};
+
+/// Enum for the sign flags.
+enum class Sign
+{
+  /// The `+` flag.
+  Plus,
+  /// The `-` flag.
+  Minus,
+};
+
+template  struct Box;
+
+template  struct Option;
+
+/// Enum describing where an argument for a format can be located.
+struct Position
+{
+  enum class Tag
+  {
+/// The argument is implied to be located at an index
+ArgumentImplicitlyIs,
+/// The argument is located at a specific index given in the format,
+ArgumentIs,
+/// The argument has a name.
+ArgumentNamed,
+  };
+
+  struct ArgumentImplicitlyIs_Body
+  {
+uintptr_t _0;
+  };
+
+  struct ArgumentIs_Body
+  {
+uintptr_t _0;
+  };
+
+  struct ArgumentNamed_Body
+  {
+const str *_0;
+  };
+
+  Tag tag;
+  union
+  {
+ArgumentImplicitlyIs_Body argument_implicitly_is;
+ArgumentIs_Body argument_is;
+ArgumentNamed_Body argument_named;
+  };
+};
+
+/// Range inside of a `Span` used for diagnostics when we only have access to
+/// relative positions.
+struct InnerSpan
+{
+  uintptr_t start;
+  uintptr_t end;
+};
+
+/// A count is used for the precision and width parameters of an integer, and
+/// can reference either an argument or a literal integer.
+struct Count
+{
+  enum class Tag
+  {
+/// The count is specified explicitly.
+CountIs,
+/// The count is specified by the argument with the given name.
+CountIsName,
+/// The count is specified by the argument at the given index.
+CountIsParam,
+/// The count is specified by a star (like in `{:.*}`) that refers to the
+/// argument at the given index.
+CountIsStar,
+/// The count is implied and cannot be explicitly specified.
+CountImplied,
+  };
+
+  struct CountIs_Body
+  {
+uintptr_t _0;
+  };
+
+  struct CountIsName_Body
+  {
+const str *_0;
+InnerSpan _1;
+  };
+
+  struct CountIsParam_Body
+  {
+uintptr_t _0;
+  };
+
+  struct CountIsStar_Body
+  {
+uintptr_t _0;
+  };
+
+  Tag tag;
+  union
+  {
+CountIs_Body count_is;
+CountIsName_Body count_is_name;
+CountIsParam_Body count_is_param;
+CountIsStar_Body count_is_star;
+  };
+};
+
+/// Specification for the formatting of an argument in the format string.
+struct FormatSpec
+{
+  /// Optionally specified character to fill alignment with.
+  Option fill;
+  /// Span of the optionally specified fill character.
+  Option fill_span;
+  /// Optionally specified alignment.
+  Alignment align;
+  /// The `+` or `-` flag.
+  Option sign;
+  /// The `#` flag.
+  bool alternate;
+  /// The `0` flag.
+  bool zero_pad;
+  /// The `x` or `X` flag. (Only for `Debug`.)
+  Op

[gcc r15-2486] Rust: Don't cache 'libformat_parser.a'

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:96a5c5bd28e069116321d471b685c16f7d1df636

commit r15-2486-g96a5c5bd28e069116321d471b685c16f7d1df636
Author: Thomas Schwinge 
Date:   Wed Feb 28 23:02:19 2024 +0100

Rust: Don't cache 'libformat_parser.a'

gcc/rust/
* Make-lang.in (LIBFORMAT_PARSER): Point to the actual build 
artifact.
($(LIBFORMAT_PARSER)): Don't cache it.

Diff:
---
 gcc/rust/Make-lang.in | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index bcf424e6c185..497a3c76166e 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -212,7 +212,7 @@ RUST_ALL_OBJS = $(GRS_OBJS) $(RUST_TARGET_OBJS)
 rust_OBJS = $(RUST_ALL_OBJS) rust/rustspec.o
 
 LIBPROC_MACRO_INTERNAL = 
../libgrust/libproc_macro_internal/libproc_macro_internal.a
-LIBFORMAT_PARSER = rust/libformat_parser.a
+LIBFORMAT_PARSER = 
$(srcdir)/../libgrust/libformat_parser/target/debug/liblibformat_parser.a
 
 RUST_LIBDEPS = $(LIBDEPS) $(LIBPROC_MACRO_INTERNAL) $(LIBFORMAT_PARSER)
 
@@ -417,7 +417,6 @@ rust/%.o: rust/lex/%.cc
 # TODO: Improve `cargo` invocation with host specific flags, possibly creating 
a $(CARGO) variable?
 $(LIBFORMAT_PARSER): $(srcdir)/../libgrust/libformat_parser/Cargo.toml 
$(wildcard $(srcdir)/../libgrust/libformat_parser/src/*.rs)
cd $(srcdir)/../libgrust/libformat_parser && cargo build --offline  # 
FIXME: Not always release, right?
-   cp 
$(srcdir)/../libgrust/libformat_parser/target/debug/liblibformat_parser.a $@
 
 # build all rust/parse files in rust folder, add cross-folder includes
 rust/%.o: rust/parse/%.cc


[gcc r15-2491] gccrs: libformat_parser: Update header and remove old interface

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:d6332141d714888b53c1973f2d89ee24e422cb62

commit r15-2491-gd6332141d714888b53c1973f2d89ee24e422cb62
Author: Arthur Cohen 
Date:   Mon Jan 29 22:06:39 2024 +0100

gccrs: libformat_parser: Update header and remove old interface

gcc/rust/ChangeLog:

* ast/rust-fmt.cc (Pieces::collect): Use new Pieces API.
* ast/rust-fmt.h: Update interface with new FFI bindings.

libgrust/ChangeLog:

* libformat_parser/src/lib.rs: Add IntoFFI trait.
* libformat_parser/libformat-parser.h: Removed.

Diff:
---
 gcc/rust/ast/rust-fmt.cc |  10 +-
 gcc/rust/ast/rust-fmt.h  | 199 ++--
 libgrust/libformat_parser/libformat-parser.h | 224 ---
 libgrust/libformat_parser/src/lib.rs |  56 +--
 4 files changed, 200 insertions(+), 289 deletions(-)

diff --git a/gcc/rust/ast/rust-fmt.cc b/gcc/rust/ast/rust-fmt.cc
index 559b1c8b5795..a7c4341c52db 100644
--- a/gcc/rust/ast/rust-fmt.cc
+++ b/gcc/rust/ast/rust-fmt.cc
@@ -17,6 +17,7 @@
 // .
 
 #include "rust-fmt.h"
+#include "rust-diagnostics.h"
 
 namespace Rust {
 namespace Fmt {
@@ -26,13 +27,12 @@ Pieces::collect (const std::string &to_parse)
 {
   auto piece_slice = collect_pieces (to_parse.c_str ());
 
-  rust_debug ("[ARTHUR] %p, %lu", (void *) piece_slice.ptr, piece_slice.len);
+  rust_debug ("[ARTHUR] %p, %lu", (const void *) piece_slice.base_ptr,
+ piece_slice.len);
 
   // this performs multiple copies, can we avoid them maybe?
-  auto pieces
-= std::vector (piece_slice.ptr, piece_slice.ptr + piece_slice.len);
-
-  rust_debug ("[ARTHUR] %p, %lu", (void *) pieces.data (), pieces.size ());
+  // auto pieces = std::vector (piece_slice.base_ptr,
+  //piece_slice.base_ptr + piece_slice.len);
 
   return Pieces{};
 }
diff --git a/gcc/rust/ast/rust-fmt.h b/gcc/rust/ast/rust-fmt.h
index 27c1c3625d3e..7ec9a2a199dd 100644
--- a/gcc/rust/ast/rust-fmt.h
+++ b/gcc/rust/ast/rust-fmt.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2020-2023 Free Software Foundation, Inc.
+// Copyright (C) 2023-2024 Free Software Foundation, Inc.
 
 // This file is part of GCC.
 
@@ -19,9 +19,10 @@
 #ifndef RUST_FMT_H
 #define RUST_FMT_H
 
-#include "rust-diagnostics.h"
 #include "rust-system.h"
 
+// FIXME: How to encode Option?
+
 namespace Rust {
 namespace Fmt {
 
@@ -30,116 +31,220 @@ struct RustHamster
   // hehe
 };
 
-struct InnerSpan
+/// Enum of alignments which are supported.
+enum class Alignment
 {
+  /// The value will be aligned to the left.
+  AlignLeft,
+  /// The value will be aligned to the right.
+  AlignRight,
+  /// The value will be aligned in the center.
+  AlignCenter,
+  /// The value will take on a default alignment.
+  AlignUnknown,
 };
 
-struct Count
+/// Enum for the debug hex flags.
+enum class DebugHex
 {
-  enum class Kind
-  {
-Is,
-IsName,
-IsParam,
-IsStar,
-Implied
-  } kind;
-
-  union
-  {
-size_t is;
-std::pair is_name;
-size_t is_param;
-size_t is_star;
-  } data;
+  /// The `x` flag in `{:x?}`.
+  Lower,
+  /// The `X` flag in `{:X?}`.
+  Upper,
 };
 
-struct DebugHex
+/// Enum for the sign flags.
+enum class Sign
 {
+  /// The `+` flag.
+  Plus,
+  /// The `-` flag.
+  Minus,
 };
 
-struct Sign
+/// Enum describing where an argument for a format can be located.
+struct Position
 {
-};
+  enum class Tag
+  {
+/// The argument is implied to be located at an index
+ArgumentImplicitlyIs,
+/// The argument is located at a specific index given in the format,
+ArgumentIs,
+/// The argument has a name.
+ArgumentNamed,
+  };
 
-struct Alignment
-{
+  struct ArgumentImplicitlyIs_Body
+  {
+size_t _0;
+  };
+
+  struct ArgumentIs_Body
+  {
+size_t _0;
+  };
+
+  struct ArgumentNamed_Body
+  {
+RustHamster _0;
+  };
+
+  Tag tag;
+  union
+  {
+ArgumentImplicitlyIs_Body argument_implicitly_is;
+ArgumentIs_Body argument_is;
+ArgumentNamed_Body argument_named;
+  };
 };
 
-struct RustString
+/// Range inside of a `Span` used for diagnostics when we only have access to
+/// relative positions.
+struct InnerSpan
 {
-  // hehe
+  size_t start;
+  size_t end;
 };
 
-struct Position
+/// A count is used for the precision and width parameters of an integer, and
+/// can reference either an argument or a literal integer.
+struct Count
 {
+  enum class Tag
+  {
+/// The count is specified explicitly.
+CountIs,
+/// The count is specified by the argument with the given name.
+CountIsName,
+/// The count is specified by the argument at the given index.
+CountIsParam,
+/// The count is specified by a star (like in `{:.*}`) that refers to the
+/// argument at the given index.
+CountIsStar,
+/// The count is implied and cannot be explicitly specified.
+CountImplied,
+  };
+
+  struct CountIs_Body
+  {
+size_t _0;
+  };
+
+  struct CountIs

[gcc r15-2492] gccrs: libformat_parser: Send boxed values across FFI properly

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:6e04e69bff8e92a8df0f7663f9f7d3aac1b7fd31

commit r15-2492-g6e04e69bff8e92a8df0f7663f9f7d3aac1b7fd31
Author: Arthur Cohen 
Date:   Tue Jan 30 01:48:13 2024 +0100

gccrs: libformat_parser: Send boxed values across FFI properly

gcc/rust/ChangeLog:

* ast/rust-fmt.cc (Pieces::~Pieces): Call libformat_parser's release
function in destructor.
* ast/rust-fmt.h (struct PieceSlice): Add capacity.
(destroy_pieces): New.
(struct Pieces): Add destructor.

libgrust/ChangeLog:

* libformat_parser/src/lib.rs: Leak Boxes properly for C++ to
see them, add memory release function.

Diff:
---
 gcc/rust/ast/rust-fmt.cc |  4 +-
 gcc/rust/ast/rust-fmt.h  |  9 
 libgrust/libformat_parser/src/lib.rs | 94 ++--
 3 files changed, 58 insertions(+), 49 deletions(-)

diff --git a/gcc/rust/ast/rust-fmt.cc b/gcc/rust/ast/rust-fmt.cc
index a7c4341c52db..f6ee8a209137 100644
--- a/gcc/rust/ast/rust-fmt.cc
+++ b/gcc/rust/ast/rust-fmt.cc
@@ -34,8 +34,10 @@ Pieces::collect (const std::string &to_parse)
   // auto pieces = std::vector (piece_slice.base_ptr,
   //piece_slice.base_ptr + piece_slice.len);
 
-  return Pieces{};
+  return Pieces (piece_slice);
 }
 
+Pieces::~Pieces () { destroy_pieces (slice); }
+
 } // namespace Fmt
 } // namespace Rust
diff --git a/gcc/rust/ast/rust-fmt.h b/gcc/rust/ast/rust-fmt.h
index 7ec9a2a199dd..50aeff6433ee 100644
--- a/gcc/rust/ast/rust-fmt.h
+++ b/gcc/rust/ast/rust-fmt.h
@@ -237,6 +237,7 @@ struct PieceSlice
 {
   const Piece *base_ptr;
   size_t len;
+  size_t cap;
 };
 
 extern "C" {
@@ -244,11 +245,19 @@ extern "C" {
 PieceSlice
 collect_pieces (const char *input);
 
+void destroy_pieces (PieceSlice);
+
 } // extern "C"
 
 struct Pieces
 {
   static Pieces collect (const std::string &to_parse);
+  ~Pieces ();
+
+private:
+  Pieces (PieceSlice slice) : slice (slice) {}
+
+  PieceSlice slice;
 };
 
 } // namespace Fmt
diff --git a/libgrust/libformat_parser/src/lib.rs 
b/libgrust/libformat_parser/src/lib.rs
index 4bbc468c7557..9b2bffed05d4 100644
--- a/libgrust/libformat_parser/src/lib.rs
+++ b/libgrust/libformat_parser/src/lib.rs
@@ -3,21 +3,17 @@
 // what's the plan? Have a function return something that can be constructed 
into a vector?
 // or an iterator?
 
-use std::ffi::CStr;
+use std::{ffi::CStr, mem};
 
-trait IntoFFI {
-type Output;
-
-fn into_ffi(&self) -> Self::Output;
+trait IntoFFI {
+fn into_ffi(self) -> T;
 }
 
-impl IntoFFI for Option
+impl IntoFFI<*const T> for Option
 where
 T: Sized,
 {
-type Output = *const T;
-
-fn into_ffi(&self) -> Self::Output {
+fn into_ffi(self) -> *const T {
 match self.as_ref() {
 None => std::ptr::null(),
 Some(r) => r as *const T,
@@ -40,12 +36,6 @@ mod ffi {
 pub end: usize,
 }
 
-// impl InnerSpan {
-// pub fn new(start: usize, end: usize) -> InnerSpan {
-// InnerSpan { start, end }
-// }
-// }
-
 /// The location and before/after width of a character whose width has 
changed from its source code
 /// representation
 #[derive(Copy, Clone, PartialEq, Eq)]
@@ -59,35 +49,27 @@ mod ffi {
 pub after: usize,
 }
 
-// impl InnerWidthMapping {
-// pub fn new(position: usize, before: usize, after: usize) -> 
InnerWidthMapping {
-// InnerWidthMapping {
-// position,
-// before,
-// after,
-// }
-// }
+// TODO: Not needed for now?
+// /// Whether the input string is a literal. If yes, it contains the 
inner width mappings.
+// #[derive(Clone, PartialEq, Eq)]
+// #[repr(C)]
+// enum InputStringKind {
+// NotALiteral,
+// Literal {
+// width_mappings: Vec,
+// },
 // }
 
-/// Whether the input string is a literal. If yes, it contains the inner 
width mappings.
-#[derive(Clone, PartialEq, Eq)]
-#[repr(C)]
-enum InputStringKind {
-NotALiteral,
-Literal {
-width_mappings: Vec,
-},
-}
-
-/// The type of format string that we are parsing.
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-#[repr(C)]
-pub enum ParseMode {
-/// A normal format string as per `format_args!`.
-Format,
-/// An inline assembly template string for `asm!`.
-InlineAsm,
-}
+// TODO: Not needed for now?
+// /// The type of format string that we are parsing.
+// #[derive(Copy, Clone, Debug, Eq, PartialEq)]
+// #[repr(C)]
+// pub enum ParseMode {
+// /// A normal format string as per `format_args!`.
+// Format,
+// /// An inline assembly template string for `asm!`.
+// InlineAsm,
+// }
 
 #[derive(Copy, Clone)]
 #[repr(C)]
@@ -102,7 +84,13 @@ mod ffi {
 S

[gcc r15-2493] gccrs: format_args: Parse format string properly

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:d72a8e93083fd89ab73015ff9f4bf00ddb923cf7

commit r15-2493-gd72a8e93083fd89ab73015ff9f4bf00ddb923cf7
Author: Arthur Cohen 
Date:   Tue Jan 30 16:16:36 2024 +0100

gccrs: format_args: Parse format string properly

gcc/rust/ChangeLog:

* expand/rust-macro-builtins.cc (MacroBuiltin::format_args_handler):
Construct string to parser properly.

Diff:
---
 gcc/rust/expand/rust-macro-builtins.cc | 19 ++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/expand/rust-macro-builtins.cc 
b/gcc/rust/expand/rust-macro-builtins.cc
index 0e57406f10f8..19ea91094539 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -947,7 +947,24 @@ tl::optional
 MacroBuiltin::format_args_handler (location_t invoc_locus,
   AST::MacroInvocData &invoc)
 {
-  Fmt::Pieces::collect ("heyo this {is} what I {} want to {3}, {parse}");
+  auto fmt_expr
+= parse_single_string_literal (BuiltinMacro::FormatArgs,
+  invoc.get_delim_tok_tree (), invoc_locus,
+  invoc.get_expander ());
+
+  if (!fmt_expr)
+return AST::Fragment::create_error ();
+
+  // if it is not a literal, it's an eager macro invocation - return it
+  if (!fmt_expr->is_literal ())
+{
+  auto token_tree = invoc.get_delim_tok_tree ();
+  return AST::Fragment ({AST::SingleASTNode (std::move (fmt_expr))},
+   token_tree.to_token_stream ());
+}
+
+  auto format_string = fmt_expr->as_string ();
+  auto pieces = Fmt::Pieces::collect (format_string);
 
   return AST::Fragment::create_empty ();
 }


[gcc r15-2494] gccrs: format_args: Parse entire token invocation

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:827231aac4d0532dd74863f72c11462cecd02abb

commit r15-2494-g827231aac4d0532dd74863f72c11462cecd02abb
Author: Arthur Cohen 
Date:   Wed Feb 7 12:46:16 2024 +0100

gccrs: format_args: Parse entire token invocation

gcc/rust/ChangeLog:

* expand/rust-macro-builtins.cc (MacroBuiltin::format_args_handler):
Transform entire invocation token stream into string for the parser.

Diff:
---
 gcc/rust/expand/rust-macro-builtins.cc | 40 +++---
 1 file changed, 22 insertions(+), 18 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-builtins.cc 
b/gcc/rust/expand/rust-macro-builtins.cc
index 19ea91094539..2af05a5e3777 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -16,6 +16,8 @@
 // along with GCC; see the file COPYING3.  If not see
 // .
 
+#include "libproc_macro_internal/tokenstream.h"
+#include "rust-token-converter.h"
 #include "rust-system.h"
 #include "rust-macro-builtins.h"
 #include "rust-ast-fragment.h"
@@ -947,24 +949,26 @@ tl::optional
 MacroBuiltin::format_args_handler (location_t invoc_locus,
   AST::MacroInvocData &invoc)
 {
-  auto fmt_expr
-= parse_single_string_literal (BuiltinMacro::FormatArgs,
-  invoc.get_delim_tok_tree (), invoc_locus,
-  invoc.get_expander ());
-
-  if (!fmt_expr)
-return AST::Fragment::create_error ();
-
-  // if it is not a literal, it's an eager macro invocation - return it
-  if (!fmt_expr->is_literal ())
-{
-  auto token_tree = invoc.get_delim_tok_tree ();
-  return AST::Fragment ({AST::SingleASTNode (std::move (fmt_expr))},
-   token_tree.to_token_stream ());
-}
-
-  auto format_string = fmt_expr->as_string ();
-  auto pieces = Fmt::Pieces::collect (format_string);
+  auto tokens = invoc.get_delim_tok_tree ().to_token_stream ();
+  tokens.erase (tokens.begin ());
+  tokens.pop_back ();
+
+  std::stringstream stream;
+  for (const auto &tok : tokens)
+stream << tok->as_string () << ' ';
+
+  rust_debug ("[ARTHU]: `%s`", stream.str ().c_str ());
+
+  // FIXME: We need to handle this
+  // // if it is not a literal, it's an eager macro invocation - return it
+  // if (!fmt_expr->is_literal ())
+  //   {
+  // auto token_tree = invoc.get_delim_tok_tree ();
+  // return AST::Fragment ({AST::SingleASTNode (std::move (fmt_expr))},
+  //   token_tree.to_token_stream ());
+  //   }
+
+  auto pieces = Fmt::Pieces::collect (stream.str ());
 
   return AST::Fragment::create_empty ();
 }


[gcc r15-2495] gccrs: rust-fmt: Store parsed string in Pieces struct

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:0f9668507c9843a773af794ed8d0b0de3fa8b5cf

commit r15-2495-g0f9668507c9843a773af794ed8d0b0de3fa8b5cf
Author: Arthur Cohen 
Date:   Tue Feb 13 16:31:25 2024 +0100

gccrs: rust-fmt: Store parsed string in Pieces struct

gcc/rust/ChangeLog:

* ast/rust-fmt.cc (Pieces::collect): Fix signature to take ownership
of the given string.
* ast/rust-fmt.h (struct Pieces): Store parsed string in the struct.

libgrust/ChangeLog:

* libformat_parser/src/lib.rs: Add debug prompt.

Diff:
---
 gcc/rust/ast/rust-fmt.cc | 4 ++--
 gcc/rust/ast/rust-fmt.h  | 7 +--
 libgrust/libformat_parser/src/lib.rs | 1 +
 3 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/ast/rust-fmt.cc b/gcc/rust/ast/rust-fmt.cc
index f6ee8a209137..511e94740c5e 100644
--- a/gcc/rust/ast/rust-fmt.cc
+++ b/gcc/rust/ast/rust-fmt.cc
@@ -23,7 +23,7 @@ namespace Rust {
 namespace Fmt {
 
 Pieces
-Pieces::collect (const std::string &to_parse)
+Pieces::collect (std::string &&to_parse)
 {
   auto piece_slice = collect_pieces (to_parse.c_str ());
 
@@ -34,7 +34,7 @@ Pieces::collect (const std::string &to_parse)
   // auto pieces = std::vector (piece_slice.base_ptr,
   //piece_slice.base_ptr + piece_slice.len);
 
-  return Pieces (piece_slice);
+  return Pieces (piece_slice, std::move (to_parse));
 }
 
 Pieces::~Pieces () { destroy_pieces (slice); }
diff --git a/gcc/rust/ast/rust-fmt.h b/gcc/rust/ast/rust-fmt.h
index 50aeff6433ee..0bf9695bb6d2 100644
--- a/gcc/rust/ast/rust-fmt.h
+++ b/gcc/rust/ast/rust-fmt.h
@@ -251,13 +251,16 @@ void destroy_pieces (PieceSlice);
 
 struct Pieces
 {
-  static Pieces collect (const std::string &to_parse);
+  static Pieces collect (std::string &&to_parse);
   ~Pieces ();
 
 private:
-  Pieces (PieceSlice slice) : slice (slice) {}
+  Pieces (PieceSlice slice, std::string &&to_parse)
+: slice (slice), to_parse (std::move (to_parse))
+  {}
 
   PieceSlice slice;
+  std::string to_parse;
 };
 
 } // namespace Fmt
diff --git a/libgrust/libformat_parser/src/lib.rs 
b/libgrust/libformat_parser/src/lib.rs
index 9b2bffed05d4..eb3e1060e5d8 100644
--- a/libgrust/libformat_parser/src/lib.rs
+++ b/libgrust/libformat_parser/src/lib.rs
@@ -340,6 +340,7 @@ pub struct PieceSlice {
 pub extern "C" fn collect_pieces(input: *const libc::c_char) -> PieceSlice {
 // FIXME: Add comment
 let str = unsafe { CStr::from_ptr(input) };
+dbg!(str);
 
 // FIXME: No unwrap
 let pieces: Vec> = 
rust::collect_pieces(str.to_str().unwrap())


[gcc r15-2497] gccrs: format-parser: Add `is_some_and` method for Option

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:433fbb156898c256c38a9ee137a51a42fe9177ee

commit r15-2497-g433fbb156898c256c38a9ee137a51a42fe9177ee
Author: Arthur Cohen 
Date:   Mon Feb 26 11:55:47 2024 +0100

gccrs: format-parser: Add `is_some_and` method for Option

Workaround for Ubuntu 18.04, since we still use it for the GCC 4.8 CI.
The default Rust package is 1.65 (and unlikely to change I assume?),
but the generic format parser library uses `is_some_and` which was
introduced in 1.70. So this is a simple reimplementation, directly taken
from the standard library sources.

libgrust/ChangeLog:

* libformat_parser/generic_format_parser/src/lib.rs: Add 
IsSomeAnd
trait, impl it for Option.

Diff:
---
 .../libformat_parser/generic_format_parser/src/lib.rs| 16 
 1 file changed, 16 insertions(+)

diff --git a/libgrust/libformat_parser/generic_format_parser/src/lib.rs 
b/libgrust/libformat_parser/generic_format_parser/src/lib.rs
index 6a366177f252..8062bf9e5cec 100644
--- a/libgrust/libformat_parser/generic_format_parser/src/lib.rs
+++ b/libgrust/libformat_parser/generic_format_parser/src/lib.rs
@@ -22,6 +22,22 @@ fn is_id_continue(c: char) -> bool {
 unicode_xid::UnicodeXID::is_xid_continue(c)
 }
 
+// Workaround for Ubuntu 18.04. The default Rust package is 1.65 (and unlikely 
to change I assume?), but the
+// generic format parser library uses `is_some_and` which was introduced in 
1.70. So this is a reimplementation,
+// directly taken from the standard library sources
+trait IsSomeAnd {
+fn is_some_and(self, f: impl FnOnce(T) -> bool) -> bool;
+}
+
+impl IsSomeAnd for Option {
+fn is_some_and(self, f: impl FnOnce(T) -> bool) -> bool {
+match self {
+None => false,
+Some(x) => f(x),
+}
+}
+}
+
 // use rustc_lexer::unescape;
 pub use Alignment::*;
 pub use Count::*;


[gcc r15-2496] gccrs: libformat_parser: Fix Rust warnings.

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:f7dafa7d4bba993a32f8883967babddf8510772c

commit r15-2496-gf7dafa7d4bba993a32f8883967babddf8510772c
Author: Arthur Cohen 
Date:   Thu Feb 15 13:11:26 2024 +0100

gccrs: libformat_parser: Fix Rust warnings.

libgrust/ChangeLog:

* libformat_parser/generic_format_parser/src/lib.rs: Remove
unused deprecated attribute and unused import.
* libformat_parser/src/lib.rs: Remove unused import.

Diff:
---
 libgrust/libformat_parser/generic_format_parser/src/lib.rs | 2 --
 libgrust/libformat_parser/src/lib.rs   | 2 +-
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/libgrust/libformat_parser/generic_format_parser/src/lib.rs 
b/libgrust/libformat_parser/generic_format_parser/src/lib.rs
index 87a20dc18c56..6a366177f252 100644
--- a/libgrust/libformat_parser/generic_format_parser/src/lib.rs
+++ b/libgrust/libformat_parser/generic_format_parser/src/lib.rs
@@ -14,12 +14,10 @@
 // WARNING: We want to be able to build this crate with a stable compiler,
 //  so no `#![feature]` attributes should be added!
 
-#[deprecated(note = "Use a proper lexer function for this")]
 fn is_id_start(c: char) -> bool {
 c == '_' || unicode_xid::UnicodeXID::is_xid_start(c)
 }
 
-#[deprecated(note = "Use a proper lexer function for this")]
 fn is_id_continue(c: char) -> bool {
 unicode_xid::UnicodeXID::is_xid_continue(c)
 }
diff --git a/libgrust/libformat_parser/src/lib.rs 
b/libgrust/libformat_parser/src/lib.rs
index eb3e1060e5d8..c164578a1039 100644
--- a/libgrust/libformat_parser/src/lib.rs
+++ b/libgrust/libformat_parser/src/lib.rs
@@ -3,7 +3,7 @@
 // what's the plan? Have a function return something that can be constructed 
into a vector?
 // or an iterator?
 
-use std::{ffi::CStr, mem};
+use std::ffi::CStr;
 
 trait IntoFFI {
 fn into_ffi(self) -> T;


[gcc r15-2498] gccrs: Adjust error checks to match name resolution 2.0

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:53ccef0387e2c55016132b8cc600176f8ac9abef

commit r15-2498-g53ccef0387e2c55016132b8cc600176f8ac9abef
Author: Owen Avery 
Date:   Fri Feb 23 10:20:55 2024 -0500

gccrs: Adjust error checks to match name resolution 2.0

gcc/testsuite/ChangeLog:

* rust/compile/bad_stmt_enums.rs: Adjust redefinition error.
* rust/compile/bad_toplevel_enums.rs: Likewise.
* rust/compile/redef_error1.rs: Likewise.
* rust/compile/redef_error3.rs: Likewise.
* rust/compile/redef_error4.rs: Likewise.
* rust/compile/redef_error6.rs: Likewise.

Signed-off-by: Owen Avery 

Diff:
---
 gcc/testsuite/rust/compile/bad_stmt_enums.rs | 6 +++---
 gcc/testsuite/rust/compile/bad_toplevel_enums.rs | 6 +++---
 gcc/testsuite/rust/compile/redef_error1.rs   | 2 +-
 gcc/testsuite/rust/compile/redef_error3.rs   | 2 +-
 gcc/testsuite/rust/compile/redef_error4.rs   | 2 +-
 gcc/testsuite/rust/compile/redef_error6.rs   | 2 +-
 6 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/gcc/testsuite/rust/compile/bad_stmt_enums.rs 
b/gcc/testsuite/rust/compile/bad_stmt_enums.rs
index 7b09a94fd274..b83137f96b8d 100644
--- a/gcc/testsuite/rust/compile/bad_stmt_enums.rs
+++ b/gcc/testsuite/rust/compile/bad_stmt_enums.rs
@@ -5,17 +5,17 @@ fn main ()
   Alpha { alpha: i32 },
   pub Beta (u8),
   pub Gamma,
-  Gamma { gamma: u32 } // { dg-error "redefined" }
+  Gamma { gamma: u32 } // { dg-error "defined multiple times" }
 }
 
   struct EE2 { }
-  enum EE2 { } // { dg-error "redefined" }
+  enum EE2 { } // { dg-error "defined multiple times" }
 
   enum EE1
 {
   pub Alpha,
   Beta = 41,
-  Beta = 42, // { dg-error "redefined" }
+  Beta = 42, // { dg-error "defined multiple times" }
   pub Gamma = 3,
   D,
 }
diff --git a/gcc/testsuite/rust/compile/bad_toplevel_enums.rs 
b/gcc/testsuite/rust/compile/bad_toplevel_enums.rs
index b655e30a93da..137095bf00cb 100644
--- a/gcc/testsuite/rust/compile/bad_toplevel_enums.rs
+++ b/gcc/testsuite/rust/compile/bad_toplevel_enums.rs
@@ -3,17 +3,17 @@ pub enum E
   pub A { a: i32 },
   B (u8),
   pub C,
-  B // { dg-error "redefined" }
+  B // { dg-error "defined multiple times" }
 }
 
 enum E2 { }
-struct E2 { } // { dg-error "redefined" }
+struct E2 { } // { dg-error "defined multiple times" }
 
 enum E1
 {
   A,
   pub B = 42,
   C = 3,
-  A { a: u8 }, // { dg-error "redefined" }
+  A { a: u8 }, // { dg-error "defined multiple times" }
   pub D
 }
diff --git a/gcc/testsuite/rust/compile/redef_error1.rs 
b/gcc/testsuite/rust/compile/redef_error1.rs
index ae51e36c87f4..5a85f1e50fee 100644
--- a/gcc/testsuite/rust/compile/redef_error1.rs
+++ b/gcc/testsuite/rust/compile/redef_error1.rs
@@ -3,6 +3,6 @@ struct S1 {
 y: f64,
 }
 
-struct S1(i32, bool); // { dg-error "redefined multiple times" }
+struct S1(i32, bool); // { dg-error "defined multiple times" }
 
 fn main() {}
diff --git a/gcc/testsuite/rust/compile/redef_error3.rs 
b/gcc/testsuite/rust/compile/redef_error3.rs
index a4bf1ed3d8ce..cc1cceba8bba 100644
--- a/gcc/testsuite/rust/compile/redef_error3.rs
+++ b/gcc/testsuite/rust/compile/redef_error3.rs
@@ -2,7 +2,7 @@ fn test() -> bool {
 true
 }
 
-fn test() -> i32 { // { dg-error "redefined multiple times" }
+fn test() -> i32 { // { dg-error "defined multiple times" }
 123
 }
 
diff --git a/gcc/testsuite/rust/compile/redef_error4.rs 
b/gcc/testsuite/rust/compile/redef_error4.rs
index a250c0ac00e2..3faebb75abeb 100644
--- a/gcc/testsuite/rust/compile/redef_error4.rs
+++ b/gcc/testsuite/rust/compile/redef_error4.rs
@@ -9,7 +9,7 @@ impl Foo {
 test()
 }
 
-fn test() -> bool { // { dg-error "redefined multiple times" }
+fn test() -> bool { // { dg-error "defined multiple times" }
 true
 }
 }
diff --git a/gcc/testsuite/rust/compile/redef_error6.rs 
b/gcc/testsuite/rust/compile/redef_error6.rs
index 664c6ae9894c..f7f688b5f369 100644
--- a/gcc/testsuite/rust/compile/redef_error6.rs
+++ b/gcc/testsuite/rust/compile/redef_error6.rs
@@ -5,7 +5,7 @@ impl Foo {
 123
 }
 
-fn test(self) -> i32 { // { dg-error "redefined multiple times" }
+fn test(self) -> i32 { // { dg-error "defined multiple times" }
 self.0
 }
 }


[gcc r15-2499] gccrs: Fix small FixMe task in rust macro builtins

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:5d30562dcfa59d86210976c92d187f0d86f64be4

commit r15-2499-g5d30562dcfa59d86210976c92d187f0d86f64be4
Author: jjasmine 
Date:   Fri Feb 23 13:06:14 2024 -0800

gccrs: Fix small FixMe task in rust macro builtins

gcc/rust/ChangeLog:

* expand/rust-macro-builtins.cc: Change BuiltinMacro in
builtin_macro_from_string to tl::optional<>
* expand/rust-macro-builtins.h (enum class): Change BuiltinMacro
in builtin_macro_from_string to tl::optional<>
* resolve/rust-early-name-resolver.cc (EarlyNameResolver::visit):
Resolved wrong type dependency of builtin_macro_from_string

Signed-off-by: jjasmine 

Diff:
---
 gcc/rust/expand/rust-macro-builtins.cc   | 3 +--
 gcc/rust/expand/rust-macro-builtins.h| 2 +-
 gcc/rust/resolve/rust-early-name-resolver.cc | 2 +-
 3 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-builtins.cc 
b/gcc/rust/expand/rust-macro-builtins.cc
index 2af05a5e3777..f103759acdd7 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -126,8 +126,7 @@ std::unordered_map
 {"Hash", MacroBuiltin::proc_macro_builtin},
 };
 
-// FIXME: This should return an tl::optional
-BuiltinMacro
+tl::optional
 builtin_macro_from_string (const std::string &identifier)
 {
   auto macro = MacroBuiltin::builtins.lookup (identifier);
diff --git a/gcc/rust/expand/rust-macro-builtins.h 
b/gcc/rust/expand/rust-macro-builtins.h
index f9ab3fc3698e..1d6b30b59332 100644
--- a/gcc/rust/expand/rust-macro-builtins.h
+++ b/gcc/rust/expand/rust-macro-builtins.h
@@ -75,7 +75,7 @@ enum class BuiltinMacro
   Hash,
 };
 
-BuiltinMacro
+tl::optional
 builtin_macro_from_string (const std::string &identifier);
 
 /**
diff --git a/gcc/rust/resolve/rust-early-name-resolver.cc 
b/gcc/rust/resolve/rust-early-name-resolver.cc
index 422dd92e4620..d70f9ca9806e 100644
--- a/gcc/rust/resolve/rust-early-name-resolver.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver.cc
@@ -497,7 +497,7 @@ EarlyNameResolver::visit (AST::MacroInvocation &invoc)
 {
   auto builtin_kind
= builtin_macro_from_string (rules_def->get_rule_name ().as_string ());
-  invoc.map_to_builtin (builtin_kind);
+  invoc.map_to_builtin (builtin_kind.value ());
 }
 
   auto attributes = rules_def->get_outer_attrs ();


[gcc r15-2500] gccrs: lang-items: Cleanup parsing and lookups of lang items.

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:3c04d95309692746ca36b1cdb4242d0984dd1473

commit r15-2500-g3c04d95309692746ca36b1cdb4242d0984dd1473
Author: Arthur Cohen 
Date:   Tue Feb 27 13:35:50 2024 +0100

gccrs: lang-items: Cleanup parsing and lookups of lang items.

gcc/rust/ChangeLog:

* Make-lang.in: Compile new rust-lang-item.o.
* util/rust-lang-item.h: Split into header and source.
* util/rust-lang-item.cc: Cleanup parsing of lang items by using a 
hashmap
and returning optional values, cleanup handling of exhaustive lang 
item
lookups.
* hir/rust-ast-lower-base.cc 
(ASTLoweringBase::handle_lang_item_attribute): Use
new optional API.

Diff:
---
 gcc/rust/Make-lang.in   |   1 +
 gcc/rust/hir/rust-ast-lower-base.cc |  13 +-
 gcc/rust/util/rust-lang-item.cc | 191 ++
 gcc/rust/util/rust-lang-item.h  | 508 +---
 4 files changed, 206 insertions(+), 507 deletions(-)

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index baf55161d78f..af5d775a3a60 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -203,6 +203,7 @@ GRS_OBJS = \
 rust/rust-dir-owner.o \
 rust/rust-unicode.o \
 rust/rust-punycode.o \
+   rust/rust-lang-item.o \
 $(END)
 # removed object files from here
 
diff --git a/gcc/rust/hir/rust-ast-lower-base.cc 
b/gcc/rust/hir/rust-ast-lower-base.cc
index 3ff0f52e0c65..815b98f9f0a5 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -789,13 +789,12 @@ ASTLoweringBase::handle_lang_item_attribute (const 
ItemWrapper &item,
   auto &literal = static_cast (attr.get_attr_input 
());
   const auto &lang_item_type_str = literal.get_literal ().as_string ();
   auto lang_item_type = Analysis::RustLangItem::Parse (lang_item_type_str);
-  if (lang_item_type == Analysis::RustLangItem::ItemType::UNKNOWN)
-{
-  rust_error_at (attr.get_locus (), "unknown lang item");
-  return;
-}
-  mappings->insert_lang_item (lang_item_type,
- item.get_mappings ().get_defid ());
+
+  if (lang_item_type)
+mappings->insert_lang_item (*lang_item_type,
+   item.get_mappings ().get_defid ());
+  else
+rust_error_at (attr.get_locus (), "unknown lang item");
 }
 
 bool
diff --git a/gcc/rust/util/rust-lang-item.cc b/gcc/rust/util/rust-lang-item.cc
new file mode 100644
index ..9fe212d412d2
--- /dev/null
+++ b/gcc/rust/util/rust-lang-item.cc
@@ -0,0 +1,191 @@
+// Copyright (C) 2020-2024 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-lang-item.h"
+#include "rust-system.h"
+
+namespace Rust {
+namespace Analysis {
+
+const BiMap
+  Rust::Analysis::RustLangItem::lang_items = {{
+{"add", ADD},
+{"sub", SUBTRACT},
+{"mul", MULTIPLY},
+{"div", DIVIDE},
+{"rem", REMAINDER},
+{"bitand", BITAND},
+{"bitor", BITOR},
+{"bitxor", BITXOR},
+{"shl", SHL},
+{"shr", SHR},
+{"neg", NEGATION},
+{"not", NOT},
+{"add_assign", ADD_ASSIGN},
+{"sub_assign", SUB_ASSIGN},
+{"mul_assign", MUL_ASSIGN},
+{"div_assign", DIV_ASSIGN},
+{"rem_assign", REM_ASSIGN},
+{"bitand_assign", BITAND_ASSIGN},
+{"bitor_assign", BITOR_ASSIGN},
+{"bitxor_assign", BITXOR_ASSIGN},
+{"shl_assign", SHL_ASSIGN},
+{"shr_assign", SHR_ASSIGN},
+{"deref", DEREF},
+{"deref_mut", DEREF_MUT},
+{"index", INDEX},
+{"index_mut", INDEX_MUT},
+{"RangeFull", RANGE_FULL},
+{"Range", RANGE},
+{"RangeFrom", RANGE_FROM},
+{"RangeTo", RANGE_TO},
+{"RangeInclusive", RANGE_INCLUSIVE},
+{"RangeToInclusive", RANGE_TO_INCLUSIVE},
+{"phantom_data", PHANTOM_DATA},
+{"fn", FN},
+{"fn_mut", FN_MUT},
+{"fn_once", FN_ONCE},
+{"fn_once_output", FN_ONCE_OUTPUT},
+{"copy", COPY},
+{"clone", CLONE},
+{"sized", SIZED},
+{"slice_alloc", SLICE_ALLOC},
+{"slice_u8_alloc", SLICE_U8_ALLOC},
+{"str_alloc", STR_ALLOC},
+{"array", ARRAY},
+{"bool", BOOL},
+{"char", CHAR},
+{"f32", F32},
+{"f64", F64},
+{"i8", I8},
+{"i16", I16},
+{"i32", I32},
+{"i64", I64},
+{"i128", I128},
+{"isize", ISIZE},
+{"u8", U8},
+{"u16", U16},
+{"u32", U32

[gcc r15-2501] gccrs: lang-items: Make lang items enum stronger, rename class, cleanup ns.

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:bf6d216f818daa9bb63f5770165beeca7666a3c6

commit r15-2501-gbf6d216f818daa9bb63f5770165beeca7666a3c6
Author: Arthur Cohen 
Date:   Tue Feb 27 14:39:22 2024 +0100

gccrs: lang-items: Make lang items enum stronger, rename class, cleanup ns.

gcc/rust/ChangeLog:

* util/rust-lang-item.h (class RustLangItem): Renamed to...
(class LangItem): ...this. Rename ItemType enum to Kind
* util/rust-lang-item.cc: Rename methods to use new class name.
* backend/rust-compile-expr.cc (CompileExpr::visit): Use new 
lang-item API.
(CompileExpr::resolve_operator_overload): Likewise.
* backend/rust-compile-expr.h: Likewise.
* hir/rust-ast-lower-base.cc 
(ASTLoweringBase::handle_lang_item_attribute): Likewise.
* typecheck/rust-autoderef.cc (Adjuster::try_deref_type): Likewise.
(AutoderefCycle::cycle): Likewise.
* typecheck/rust-autoderef.h: Likewise.
* typecheck/rust-hir-type-bounds.h: Likewise.
* typecheck/rust-hir-type-check-base.cc 
(TypeCheckBase::get_marker_predicate): Likewise.
* typecheck/rust-hir-type-check-base.h: Likewise.
* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): 
Likewise.
* typecheck/rust-hir-type-check-expr.h: Likewise.
* typecheck/rust-hir-type-check-type.cc 
(TypeResolveGenericParam::visit): Likewise.
* typecheck/rust-tyty-bounds.cc 
(TypeBoundsProbe::assemble_sized_builtin): Likewise.
(TypeBoundsProbe::assemble_builtin_candidate): Likewise.
(TypeCheckBase::get_predicate_from_bound): Likewise.
* typecheck/rust-tyty.cc (ClosureType::setup_fn_once_output): 
Likewise.
* util/rust-hir-map.cc (Mappings::get_lang_item): Likewise.
(Mappings::lookup_trait_item_lang_item): Likewise.
* util/rust-hir-map.h: Likewise.

Diff:
---
 gcc/rust/backend/rust-compile-expr.cc  |  24 ++-
 gcc/rust/backend/rust-compile-expr.h   |   8 +-
 gcc/rust/hir/rust-ast-lower-base.cc|   2 +-
 gcc/rust/typecheck/rust-autoderef.cc   |  22 +--
 gcc/rust/typecheck/rust-autoderef.h|   5 +-
 gcc/rust/typecheck/rust-hir-type-bounds.h  |   2 +-
 gcc/rust/typecheck/rust-hir-type-check-base.cc |   3 +-
 gcc/rust/typecheck/rust-hir-type-check-base.h  |   5 +-
 gcc/rust/typecheck/rust-hir-type-check-expr.cc |  72 
 gcc/rust/typecheck/rust-hir-type-check-expr.h  |   7 +-
 gcc/rust/typecheck/rust-hir-type-check-type.cc |   3 +-
 gcc/rust/typecheck/rust-tyty-bounds.cc |  12 +-
 gcc/rust/typecheck/rust-tyty.cc|   5 +-
 gcc/rust/util/rust-hir-map.cc  |   7 +-
 gcc/rust/util/rust-hir-map.h   |  13 +-
 gcc/rust/util/rust-lang-item.cc| 218 -
 gcc/rust/util/rust-lang-item.h |  31 ++--
 17 files changed, 213 insertions(+), 226 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index 596b848849ec..65de24bf9d8c 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -150,7 +150,7 @@ CompileExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
   if (is_op_overload)
 {
   auto lang_item_type
-   = Analysis::RustLangItem::OperatorToLangItem (expr.get_expr_type ());
+   = LangItem::OperatorToLangItem (expr.get_expr_type ());
   translated = resolve_operator_overload (lang_item_type, expr, lhs, rhs,
  expr.get_lhs ().get (),
  expr.get_rhs ().get ());
@@ -193,9 +193,8 @@ CompileExpr::visit (HIR::CompoundAssignmentExpr &expr)
 expr.get_mappings ().get_hirid (), &fntype);
   if (is_op_overload)
 {
-  auto lang_item_type
-   = Analysis::RustLangItem::CompoundAssignmentOperatorToLangItem (
- expr.get_expr_type ());
+  auto lang_item_type = LangItem::CompoundAssignmentOperatorToLangItem (
+   expr.get_expr_type ());
   auto compound_assignment
= resolve_operator_overload (lang_item_type, expr, lhs, rhs,
 expr.get_lhs ().get (),
@@ -244,8 +243,7 @@ CompileExpr::visit (HIR::NegationExpr &expr)
 expr.get_mappings ().get_hirid (), &fntype);
   if (is_op_overload)
 {
-  auto lang_item_type
-   = Analysis::RustLangItem::NegationOperatorToLangItem (op);
+  auto lang_item_type = LangItem::NegationOperatorToLangItem (op);
   translated
= resolve_operator_overload (lang_item_type, expr, negated_expr,
 nullptr, expr.get_expr ().get (), nullptr);
@@ -836,7 +834,7 @@ CompileExpr::visit (HIR::DereferenceExpr &expr)
 expr.get_mappings ().get_hirid (), &fntype);
   if (is_op_overload)
 {
-  auto lang_item_type = Analysis::RustLangItem::ItemTyp

[gcc r15-2502] gccrs: extern-types: Declare external types in name resolver.

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:cac2e9715a7d35d869962a724cd4e0834a8d4438

commit r15-2502-gcac2e9715a7d35d869962a724cd4e0834a8d4438
Author: Arthur Cohen 
Date:   Tue Feb 20 14:53:32 2024 +0100

gccrs: extern-types: Declare external types in name resolver.

gcc/rust/ChangeLog:

* resolve/rust-ast-resolve-implitem.h: Declare external types as new
types.

Diff:
---
 gcc/rust/resolve/rust-ast-resolve-implitem.h | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/gcc/rust/resolve/rust-ast-resolve-implitem.h 
b/gcc/rust/resolve/rust-ast-resolve-implitem.h
index fabc25817f5b..4f4d2893f832 100644
--- a/gcc/rust/resolve/rust-ast-resolve-implitem.h
+++ b/gcc/rust/resolve/rust-ast-resolve-implitem.h
@@ -228,6 +228,25 @@ public:
 mappings->insert_module_child_item (current_module, decl);
   }
 
+  void visit (AST::ExternalTypeItem &type) override
+  {
+auto decl = CanonicalPath::new_seg (type.get_node_id (),
+   type.get_identifier ().as_string ());
+auto path = prefix.append (decl);
+
+resolver->get_type_scope ().insert (
+  path, type.get_node_id (), type.get_locus (), false, Rib::ItemType::Type,
+  [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
+   rich_location r (line_table, type.get_locus ());
+   r.add_range (locus);
+
+   rust_error_at (r, "redefined multiple times");
+  });
+
+NodeId current_module = resolver->peek_current_module_scope ();
+mappings->insert_module_child_item (current_module, decl);
+  }
+
 private:
   ResolveToplevelExternItem (const CanonicalPath &prefix)
 : ResolverBase (), prefix (prefix)


[gcc r15-2503] gccrs: hir: Add ExternalTypeItem node

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:26e77295e77e5e008e0aa43837edd293ca12179e

commit r15-2503-g26e77295e77e5e008e0aa43837edd293ca12179e
Author: Arthur Cohen 
Date:   Tue Feb 20 15:45:35 2024 +0100

gccrs: hir: Add ExternalTypeItem node

gcc/rust/ChangeLog:

* hir/tree/rust-hir-item.h (class ExternalTypeItem): New class.
* hir/tree/rust-hir.cc (ExternalTypeItem::as_string): Likewise.
* backend/rust-compile-extern.h: Add base for handling 
HIR::ExternalTypeItem
node.
* checks/errors/borrowck/rust-bir-builder-struct.h: Likewise.
* checks/errors/borrowck/rust-function-collector.h: Likewise.
* checks/errors/rust-const-checker.cc (ConstChecker::visit): 
Likewise.
* checks/errors/rust-const-checker.h: Likewise.
* checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit): 
Likewise.
* checks/errors/rust-unsafe-checker.h: Likewise.
* hir/rust-ast-lower-extern.h: Likewise.
* hir/rust-hir-dump.cc (Dump::visit): Likewise.
* hir/rust-hir-dump.h: Likewise.
* hir/tree/rust-hir-full-decls.h (class ExternalTypeItem): Likewise.
* hir/tree/rust-hir-visitor.h: Likewise.
(ExternalTypeItem::accept_vis): Likewise.
* typecheck/rust-hir-type-check-implitem.cc 
(TypeCheckTopLevelExternItem::visit): Likewise.
* typecheck/rust-hir-type-check-implitem.h: Likewise.

Diff:
---
 gcc/rust/backend/rust-compile-extern.h |   7 ++
 .../errors/borrowck/rust-bir-builder-struct.h  |   1 +
 .../errors/borrowck/rust-function-collector.h  |   1 +
 gcc/rust/checks/errors/rust-const-checker.cc   |   4 +
 gcc/rust/checks/errors/rust-const-checker.h|   1 +
 gcc/rust/checks/errors/rust-unsafe-checker.cc  |   4 +
 gcc/rust/checks/errors/rust-unsafe-checker.h   |   1 +
 gcc/rust/hir/rust-ast-lower-extern.h   |   5 +
 gcc/rust/hir/rust-hir-dump.cc  |  10 ++
 gcc/rust/hir/rust-hir-dump.h   |   1 +
 gcc/rust/hir/tree/rust-hir-full-decls.h|   1 +
 gcc/rust/hir/tree/rust-hir-item.h  |  39 ++-
 gcc/rust/hir/tree/rust-hir-visitor.h   |   3 +
 gcc/rust/hir/tree/rust-hir.cc  |  25 
 gcc/rust/typecheck/rust-hir-type-check-implitem.cc | 129 +
 gcc/rust/typecheck/rust-hir-type-check-implitem.h  |   1 +
 16 files changed, 230 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-extern.h 
b/gcc/rust/backend/rust-compile-extern.h
index 778553e5b373..b17ac954167c 100644
--- a/gcc/rust/backend/rust-compile-extern.h
+++ b/gcc/rust/backend/rust-compile-extern.h
@@ -22,6 +22,8 @@
 #include "rust-compile-base.h"
 #include "rust-compile-intrinsic.h"
 #include "rust-compile-type.h"
+#include "rust-diagnostics.h"
+#include "rust-hir-full-decls.h"
 
 namespace Rust {
 namespace Compile {
@@ -152,6 +154,11 @@ public:
 reference = address_expression (fndecl, ref_locus);
   }
 
+  void visit (HIR::ExternalTypeItem &type) override
+  {
+rust_sorry_at (type.get_locus (), "extern types are not supported yet");
+  }
+
 private:
   CompileExternItem (Context *ctx, TyTy::BaseType *concrete,
 location_t ref_locus)
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h 
b/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
index d6390392d7fb..6a990e25c43c 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
@@ -189,6 +189,7 @@ protected:
   void visit (HIR::ImplBlock &impl) override { rust_unreachable (); }
   void visit (HIR::ExternalStaticItem &item) override { rust_unreachable (); }
   void visit (HIR::ExternalFunctionItem &item) override { rust_unreachable (); 
}
+  void visit (HIR::ExternalTypeItem &item) override { rust_unreachable (); }
   void visit (HIR::ExternBlock &block) override { rust_unreachable (); }
   void visit (HIR::LiteralPattern &pattern) override { rust_unreachable (); }
   void visit (HIR::IdentifierPattern &pattern) override { rust_unreachable (); 
}
diff --git a/gcc/rust/checks/errors/borrowck/rust-function-collector.h 
b/gcc/rust/checks/errors/borrowck/rust-function-collector.h
index b19bfdf855e7..18f2f5e11d1f 100644
--- a/gcc/rust/checks/errors/borrowck/rust-function-collector.h
+++ b/gcc/rust/checks/errors/borrowck/rust-function-collector.h
@@ -155,6 +155,7 @@ public:
   void visit (HIR::ImplBlock &impl) override {}
   void visit (HIR::ExternalStaticItem &item) override {}
   void visit (HIR::ExternalFunctionItem &item) override {}
+  void visit (HIR::ExternalTypeItem &item) override {}
   void visit (HIR::ExternBlock &block) override {}
   void visit (HIR::LiteralPattern &pattern) override {}
   void visit (HIR::IdentifierPattern &pattern) override {}
diff --git a/gcc/rust/checks/errors/rust-const-checker.cc 
b/gcc/rus

[gcc r15-2504] gccrs: extern-types: Lower to HIR::ExternalTypeItem properly

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:07fc78500f6fbd365aebf98cfd9b8c7760f6692b

commit r15-2504-g07fc78500f6fbd365aebf98cfd9b8c7760f6692b
Author: Arthur Cohen 
Date:   Tue Feb 20 16:22:20 2024 +0100

gccrs: extern-types: Lower to HIR::ExternalTypeItem properly

gcc/rust/ChangeLog:

* hir/rust-ast-lower-extern.h: Lower to HIR::ExternalTypeItem nodes.
* hir/tree/rust-hir-item.h (class ExternalTypeItem): Create private
visibility by default as extern types have no visibility - add a 
comment
about the correctness of this.

Diff:
---
 gcc/rust/hir/rust-ast-lower-extern.h |  9 -
 gcc/rust/hir/tree/rust-hir-item.h| 10 --
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/hir/rust-ast-lower-extern.h 
b/gcc/rust/hir/rust-ast-lower-extern.h
index e495b16632d2..f9e067c8e95b 100644
--- a/gcc/rust/hir/rust-ast-lower-extern.h
+++ b/gcc/rust/hir/rust-ast-lower-extern.h
@@ -22,6 +22,7 @@
 #include "rust-ast-lower-base.h"
 #include "rust-ast-lower-type.h"
 #include "rust-ast-lower.h"
+#include "rust-hir-full-decls.h"
 
 namespace Rust {
 namespace HIR {
@@ -116,7 +117,13 @@ public:
 
   void visit (AST::ExternalTypeItem &type) override
   {
-rust_sorry_at (type.get_locus (), "extern types are not implemented yet");
+auto crate_num = mappings->get_current_crate ();
+Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
+  mappings->get_next_hir_id (crate_num),
+  mappings->get_next_localdef_id (crate_num));
+
+translated = new HIR::ExternalTypeItem (mapping, type.get_identifier (),
+   type.get_locus ());
   }
 
 private:
diff --git a/gcc/rust/hir/tree/rust-hir-item.h 
b/gcc/rust/hir/tree/rust-hir-item.h
index 40093a2ad939..3bd0102d4dcf 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -3152,16 +3152,20 @@ protected:
 
 class ExternalTypeItem : public ExternalItem
 {
+public:
   ExternalTypeItem (Analysis::NodeMapping mappings, Identifier item_name,
-   Visibility vis, AST::AttrVec outer_attrs, location_t locus)
+   location_t locus)
 : ExternalItem (std::move (mappings), std::move (item_name),
-   std::move (vis), std::move (outer_attrs), locus)
+   Visibility (Visibility::PRIVATE),
+   /* FIXME: Is that correct? */
+   {}, locus)
   {}
 
   ExternalTypeItem (ExternalTypeItem const &other) : ExternalItem (other) {}
 
   ExternalTypeItem (ExternalTypeItem &&other) = default;
   ExternalTypeItem &operator= (ExternalTypeItem &&other) = default;
+  ExternalTypeItem &operator= (ExternalTypeItem const &other) = default;
 
   std::string as_string () const override;
 
@@ -3171,6 +3175,8 @@ class ExternalTypeItem : public ExternalItem
   ExternKind get_extern_kind () override { return ExternKind::Type; }
 
 protected:
+  /* Use covariance to implement clone function as returning this object
+   * rather than base */
   ExternalTypeItem *clone_external_item_impl () const override
   {
 return new ExternalTypeItem (*this);


[gcc r15-2505] gccrs: Make DefaultResolver visit more of the AST

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:2509160eb12d950be2be260bd208cd354fe71def

commit r15-2505-g2509160eb12d950be2be260bd208cd354fe71def
Author: Owen Avery 
Date:   Wed Feb 28 17:42:49 2024 -0500

gccrs: Make DefaultResolver visit more of the AST

gcc/rust/ChangeLog:

* resolve/rust-default-resolver.cc
(DefaultResolver::visit): Visit inner AST nodes of ClosureExprInner,
ClosureExprInnerTyped, IfExpr, IfExprConseqElse, MatchExpr,
PathInExpression, EnumItemTuple, EnumItemStruct, and
EnumItemDiscriminant.
* ast/rust-item.h
(EnumItemDiscriminant::has_expr): New function.

Signed-off-by: Owen Avery 

Diff:
---
 gcc/rust/ast/rust-item.h  |   2 +
 gcc/rust/resolve/rust-default-resolver.cc | 105 +-
 2 files changed, 91 insertions(+), 16 deletions(-)

diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 0911719b7163..44963ba386e7 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -2081,6 +2081,8 @@ public:
 
   void accept_vis (ASTVisitor &vis) override;
 
+  bool has_expr () { return expression != nullptr; }
+
   // TODO: is this better? Or is a "vis_block" better?
   std::unique_ptr &get_expr ()
   {
diff --git a/gcc/rust/resolve/rust-default-resolver.cc 
b/gcc/rust/resolve/rust-default-resolver.cc
index 9f7fda4adaaf..28f04a108393 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -177,12 +177,43 @@ DefaultResolver::visit (AST::StructExprFieldIndexValue &)
 {}
 
 void
-DefaultResolver::visit (AST::ClosureExprInner &)
-{}
+DefaultResolver::visit (AST::ClosureExprInner &expr)
+{
+  if (expr.is_marked_for_strip ())
+return;
+
+  for (auto ¶m : expr.get_params ())
+{
+  if (param.is_error ())
+   continue;
+
+  param.get_pattern ()->accept_vis (*this);
+  if (param.has_type_given ())
+   param.get_type ()->accept_vis (*this);
+}
+
+  expr.get_definition_expr ()->accept_vis (*this);
+}
 
 void
-DefaultResolver::visit (AST::ClosureExprInnerTyped &)
-{}
+DefaultResolver::visit (AST::ClosureExprInnerTyped &expr)
+{
+  if (expr.is_marked_for_strip ())
+return;
+
+  for (auto ¶m : expr.get_params ())
+{
+  if (param.is_error ())
+   continue;
+
+  param.get_pattern ()->accept_vis (*this);
+  if (param.has_type_given ())
+   param.get_type ()->accept_vis (*this);
+}
+
+  expr.get_definition_block ()->accept_vis (*this);
+  expr.get_return_type ()->accept_vis (*this);
+}
 
 void
 DefaultResolver::visit (AST::ContinueExpr &expr)
@@ -230,11 +261,18 @@ DefaultResolver::visit (AST::WhileLetLoopExpr &expr)
 
 void
 DefaultResolver::visit (AST::IfExpr &expr)
-{}
+{
+  expr.get_condition_expr ()->accept_vis (*this);
+  expr.get_if_block ()->accept_vis (*this);
+}
 
 void
-DefaultResolver::visit (AST::IfExprConseqElse &)
-{}
+DefaultResolver::visit (AST::IfExprConseqElse &expr)
+{
+  expr.get_condition_expr ()->accept_vis (*this);
+  expr.get_if_block ()->accept_vis (*this);
+  expr.get_else_block ()->accept_vis (*this);
+}
 
 void
 DefaultResolver::visit (AST::IfLetExpr &expr)
@@ -246,7 +284,20 @@ DefaultResolver::visit (AST::IfLetExprConseqElse &)
 
 void
 DefaultResolver::visit (AST::MatchExpr &expr)
-{}
+{
+  if (expr.is_marked_for_strip ())
+return;
+
+  expr.get_scrutinee_expr ()->accept_vis (*this);
+  for (auto &arm : expr.get_match_cases ())
+{
+  arm.get_expr ()->accept_vis (*this);
+  for (auto &pat : arm.get_arm ().get_patterns ())
+   pat->accept_vis (*this);
+  if (arm.get_arm ().has_match_arm_guard ())
+   arm.get_arm ().get_guard_expr ()->accept_vis (*this);
+}
+}
 
 void
 DefaultResolver::visit (AST::AwaitExpr &expr)
@@ -277,8 +328,21 @@ DefaultResolver::visit (AST::ConstGenericParam &)
 {}
 
 void
-DefaultResolver::visit (AST::PathInExpression &)
-{}
+DefaultResolver::visit (AST::PathInExpression &expr)
+{
+  for (auto &seg : expr.get_segments ())
+if (seg.has_generic_args ())
+  {
+   auto &args = seg.get_generic_args ();
+   for (auto &arg : args.get_generic_args ())
+ arg.accept_vis (*this);
+   for (auto &arg : args.get_binding_args ())
+ if (!arg.is_error ())
+   arg.get_type ()->accept_vis (*this);
+   for (auto &arg : args.get_lifetime_args ())
+ arg.accept_vis (*this);
+  }
+}
 
 void
 DefaultResolver::visit (AST::TypePathSegmentGeneric &)
@@ -373,16 +437,25 @@ DefaultResolver::visit (AST::EnumItem &)
 {}
 
 void
-DefaultResolver::visit (AST::EnumItemTuple &)
-{}
+DefaultResolver::visit (AST::EnumItemTuple &item)
+{
+  for (auto &field : item.get_tuple_fields ())
+field.get_field_type ()->accept_vis (*this);
+}
 
 void
-DefaultResolver::visit (AST::EnumItemStruct &)
-{}
+DefaultResolver::visit (AST::EnumItemStruct &item)
+{
+  for (auto &field : item.get_struct_fields ())
+field.get_field_type ()->accept_vis (*this);
+}

[gcc r15-2506] gccrs: ast: Add base nodes for FormatArgs

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:194883fba01c8866403556dc134b75202c0d76ce

commit r15-2506-g194883fba01c8866403556dc134b75202c0d76ce
Author: Arthur Cohen 
Date:   Thu Feb 15 20:58:48 2024 +0100

gccrs: ast: Add base nodes for FormatArgs

This commit adds a base for creating AST FormatArgs nodes after expanding
invocations of `format_args!()`. These nodes will then be expanded to
the proper runtime function calls (to core::fmt::rt) during the AST
lowering.

gcc/rust/ChangeLog:

* ast/rust-builtin-ast-nodes.h: New file.
* ast/rust-ast-full-decls.h (class FormatArgs): Declare new class.
* ast/rust-ast-collector.cc: Handle FormatArgs nodes properly.
* ast/rust-ast-collector.h: Likewise.
* ast/rust-ast-full.h: Likewise.
* ast/rust-ast-visitor.cc: Likewise.
* ast/rust-ast-visitor.h: Likewise.
* ast/rust-ast.cc: Likewise.
* ast/rust-ast.h: Likewise.
* expand/rust-derive.h: Likewise.
* hir/rust-ast-lower-base.cc: Likewise.
* hir/rust-ast-lower-base.h: Likewise.
* hir/rust-ast-lower-expr.cc: Likewise.
* hir/rust-ast-lower-expr.h: Likewise.
* resolve/rust-ast-resolve-base.cc: Likewise.
* resolve/rust-ast-resolve-base.h: Likewise.

Diff:
---
 gcc/rust/ast/rust-ast-collector.cc|   8 ++
 gcc/rust/ast/rust-ast-collector.h |   2 +
 gcc/rust/ast/rust-ast-full-decls.h|   3 +
 gcc/rust/ast/rust-ast-full.h  |   1 +
 gcc/rust/ast/rust-ast-visitor.cc  |   6 ++
 gcc/rust/ast/rust-ast-visitor.h   |   5 ++
 gcc/rust/ast/rust-ast.cc  |   6 ++
 gcc/rust/ast/rust-ast.h   |   1 +
 gcc/rust/ast/rust-builtin-ast-nodes.h | 129 ++
 gcc/rust/expand/rust-derive.h |   1 +
 gcc/rust/hir/rust-ast-lower-base.cc   |   5 ++
 gcc/rust/hir/rust-ast-lower-base.h|   3 +
 gcc/rust/hir/rust-ast-lower-expr.cc   |   8 ++
 gcc/rust/hir/rust-ast-lower-expr.h|   4 +
 gcc/rust/resolve/rust-ast-resolve-base.cc |   6 ++
 gcc/rust/resolve/rust-ast-resolve-base.h  |   3 +
 16 files changed, 191 insertions(+)

diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index 181f1b100be9..b8ec62367bcf 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -16,6 +16,8 @@
 // along with GCC; see the file COPYING3.  If not see
 // .
 #include "rust-ast-collector.h"
+#include "rust-ast.h"
+#include "rust-diagnostics.h"
 #include "rust-item.h"
 #include "rust-keyword-values.h"
 
@@ -2805,5 +2807,11 @@ TokenCollector::visit (BareFunctionType &type)
 }
 }
 
+void
+TokenCollector::visit (AST::FormatArgs &fmt)
+{
+  rust_sorry_at (0, "unimplemented format_args!() visitor");
+}
+
 } // namespace AST
 } // namespace Rust
diff --git a/gcc/rust/ast/rust-ast-collector.h 
b/gcc/rust/ast/rust-ast-collector.h
index cf97c185a26f..ec695ef5b314 100644
--- a/gcc/rust/ast/rust-ast-collector.h
+++ b/gcc/rust/ast/rust-ast-collector.h
@@ -398,6 +398,8 @@ public:
   void visit (SliceType &type);
   void visit (InferredType &type);
   void visit (BareFunctionType &type);
+
+  void visit (FormatArgs &fmt);
 };
 } // namespace AST
 
diff --git a/gcc/rust/ast/rust-ast-full-decls.h 
b/gcc/rust/ast/rust-ast-full-decls.h
index c96bbfb07d96..8d5c8dbc8213 100644
--- a/gcc/rust/ast/rust-ast-full-decls.h
+++ b/gcc/rust/ast/rust-ast-full-decls.h
@@ -267,6 +267,9 @@ class SliceType;
 class InferredType;
 struct MaybeNamedParam;
 class BareFunctionType;
+
+// rust-builtin-ast-nodes.h
+class FormatArgs;
 } // namespace AST
 } // namespace Rust
 
diff --git a/gcc/rust/ast/rust-ast-full.h b/gcc/rust/ast/rust-ast-full.h
index f2152193a135..ebd38f2520c4 100644
--- a/gcc/rust/ast/rust-ast-full.h
+++ b/gcc/rust/ast/rust-ast-full.h
@@ -28,5 +28,6 @@
 #include "rust-stmt.h"
 #include "rust-type.h"
 #include "rust-macro.h"
+#include "rust-builtin-ast-nodes.h"
 
 #endif
diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index 27b9aa47d99c..c72e2d72f6d2 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -1395,6 +1395,12 @@ DefaultASTVisitor::visit (AST::BareFunctionType &type)
 visit (type.get_return_type ());
 }
 
+void
+DefaultASTVisitor::visit (AST::FormatArgs &)
+{
+  // FIXME: Do we have anything to do? any subnodes to visit? Probably, right?
+}
+
 void
 DefaultASTVisitor::visit (AST::VariadicParam ¶m)
 {
diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h
index 6c9715eb0775..c5c9a025ba6e 100644
--- a/gcc/rust/ast/rust-ast-visitor.h
+++ b/gcc/rust/ast/rust-ast-visitor.h
@@ -229,6 +229,9 @@ public:
   virtual void visit (InferredType &type) = 0;
   virtual void visit (BareFunctionType &type) = 0;
 
+  // special AST nodes for certain builtin macros such as

[gcc r15-2507] gccrs: macro-builtins: Add newline generic format_args!() handler

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:6d8765d0719018730dea2d118a1fc0ca87c8960a

commit r15-2507-g6d8765d0719018730dea2d118a1fc0ca87c8960a
Author: Arthur Cohen 
Date:   Fri Feb 16 16:19:27 2024 +0100

gccrs: macro-builtins: Add newline generic format_args!() handler

gcc/rust/ChangeLog:

* expand/rust-macro-builtins.cc (format_args_maker): New function.
(try_expand_many_expr): Add comment about reworking function.
(MacroBuiltin::format_args_handler): Add newline parameter.
* expand/rust-macro-builtins.h: Likewise.

Diff:
---
 gcc/rust/expand/rust-macro-builtins.cc | 69 ++
 gcc/rust/expand/rust-macro-builtins.h  |  4 +-
 2 files changed, 65 insertions(+), 8 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-builtins.cc 
b/gcc/rust/expand/rust-macro-builtins.cc
index f103759acdd7..9e6716c59755 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -17,6 +17,8 @@
 // .
 
 #include "libproc_macro_internal/tokenstream.h"
+#include "rust-ast-full-decls.h"
+#include "rust-builtin-ast-nodes.h"
 #include "rust-token-converter.h"
 #include "rust-system.h"
 #include "rust-macro-builtins.h"
@@ -78,6 +80,14 @@ const BiMap 
MacroBuiltin::builtins = {{
 
 }};
 
+AST::MacroTranscriberFunc
+format_args_maker (AST::FormatArgs::Newline nl)
+{
+  return [nl] (location_t loc, AST::MacroInvocData &invoc) {
+return MacroBuiltin::format_args_handler (loc, invoc, nl);
+  };
+}
+
 std::unordered_map
   MacroBuiltin::builtin_transcribers = {
 {"assert", MacroBuiltin::assert_handler},
@@ -92,10 +102,10 @@ std::unordered_map
 {"env", MacroBuiltin::env_handler},
 {"cfg", MacroBuiltin::cfg_handler},
 {"include", MacroBuiltin::include_handler},
-{"format_args", MacroBuiltin::format_args_handler},
+{"format_args", format_args_maker (AST::FormatArgs::Newline::No)},
+{"format_args_nl", format_args_maker (AST::FormatArgs::Newline::Yes)},
 /* Unimplemented macro builtins */
 {"option_env", MacroBuiltin::sorry},
-{"format_args_nl", MacroBuiltin::sorry},
 {"concat_idents", MacroBuiltin::sorry},
 {"module_path", MacroBuiltin::sorry},
 {"asm", MacroBuiltin::sorry},
@@ -286,6 +296,8 @@ try_expand_many_expr (Parser &parser,
and return the LiteralExpr for it. Allow for an optional trailing comma,
but otherwise enforce that these are the only tokens.  */
 
+// FIXME(Arthur): This function needs a rework - it should not emit errors, it
+// should probably be smaller
 std::unique_ptr
 parse_single_string_literal (BuiltinMacro kind,
 AST::DelimTokenTree &invoc_token_tree,
@@ -946,17 +958,31 @@ MacroBuiltin::stringify_handler (location_t invoc_locus,
 
 tl::optional
 MacroBuiltin::format_args_handler (location_t invoc_locus,
-  AST::MacroInvocData &invoc)
+  AST::MacroInvocData &invoc,
+  AST::FormatArgs::Newline nl)
 {
+  // Remove the delimiters from the macro invocation:
+  // the invoc data for `format_args!(fmt, arg1, arg2)` is `(fmt, arg1, arg2)`,
+  // so we pop the front and back to remove the parentheses (or curly brackets,
+  // or brackets)
   auto tokens = invoc.get_delim_tok_tree ().to_token_stream ();
   tokens.erase (tokens.begin ());
   tokens.pop_back ();
 
-  std::stringstream stream;
-  for (const auto &tok : tokens)
-stream << tok->as_string () << ' ';
+  auto append_newline = nl == AST::FormatArgs::Newline::Yes ? true : false;
+  auto fmt_arg
+= parse_single_string_literal (append_newline ? BuiltinMacro::FormatArgsNl
+ : BuiltinMacro::FormatArgs,
+  invoc.get_delim_tok_tree (), invoc_locus,
+  invoc.get_expander ());
 
-  rust_debug ("[ARTHU]: `%s`", stream.str ().c_str ());
+  if (!fmt_arg->is_literal ())
+{
+  rust_sorry_at (
+   invoc_locus,
+   "cannot yet use eager macro invocations as format strings");
+  return AST::Fragment::create_empty ();
+}
 
   // FIXME: We need to handle this
   // // if it is not a literal, it's an eager macro invocation - return it
@@ -967,8 +993,37 @@ MacroBuiltin::format_args_handler (location_t invoc_locus,
   //   token_tree.to_token_stream ());
   //   }
 
+  auto fmt_str = static_cast (*fmt_arg.get ());
+
+  // Switch on the format string to know if the string is raw or cooked
+  switch (fmt_str.get_lit_type ())
+{
+// case AST::Literal::RAW_STRING:
+case AST::Literal::STRING:
+  break;
+case AST::Literal::CHAR:
+case AST::Literal::BYTE:
+case AST::Literal::BYTE_STRING:
+case AST::Literal::INT:
+case AST::Literal::FLOAT:
+case AST::Literal::BOOL:
+case AST::Literal::ERROR:
+  rust_unreachable ();
+}
+
+  std::stringstream stream;
+  for (const auto &tok : token

[gcc r15-2509] gccrs: format-args: Fix Rust interface and add input parsing.

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:68cb878c1dab0636da4f686d6c8f5d4fa3b66e3b

commit r15-2509-g68cb878c1dab0636da4f686d6c8f5d4fa3b66e3b
Author: Arthur Cohen 
Date:   Fri Feb 16 18:27:22 2024 +0100

gccrs: format-args: Fix Rust interface and add input parsing.

gcc/rust/ChangeLog:

* ast/rust-ast.cc: Make FormatArgs inherit from AST::Expr
* ast/rust-builtin-ast-nodes.h: Improve FormatArg* nodes and 
helpers.
* ast/rust-fmt.cc (Pieces::collect): Fix interface to match FFI 
function.
* ast/rust-fmt.h (collect_pieces): Likewise.
(struct Pieces): Add append_newline parameter.
* expand/rust-macro-builtins.cc: Add proper parsing of format_args
input.
* hir/rust-ast-lower-base.cc: Include diagnostics header.

libgrust/ChangeLog:

* libformat_parser/src/lib.rs: Switch interface to use more parser
parameters.
* libformat_parser/src/bin.rs: Use new interface.

Diff:
---
 gcc/rust/ast/rust-ast.cc   |  51 +
 gcc/rust/ast/rust-builtin-ast-nodes.h  | 133 ++--
 gcc/rust/ast/rust-fmt.cc   |  38 ++-
 gcc/rust/ast/rust-fmt.h|  21 +++-
 gcc/rust/expand/rust-macro-builtins.cc | 182 +
 gcc/rust/hir/rust-ast-lower-base.cc|   1 +
 libgrust/libformat_parser/src/bin.rs   |   5 +-
 libgrust/libformat_parser/src/lib.rs   |  63 
 8 files changed, 416 insertions(+), 78 deletions(-)

diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index 5d571b466222..f3dabc6cd0fe 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "rust-ast.h"
 #include "optional.h"
+#include "rust-builtin-ast-nodes.h"
 #include "rust-system.h"
 #include "rust-ast-full.h"
 #include "rust-diagnostics.h"
@@ -5054,6 +5055,56 @@ FormatArgs::accept_vis (ASTVisitor &vis)
   vis.visit (*this);
 }
 
+std::string
+FormatArgs::as_string () const
+{
+  // FIXME(Arthur): Improve
+  return "FormatArgs";
+}
+
+location_t
+FormatArgs::get_locus () const
+{
+  rust_unreachable ();
+}
+
+bool
+FormatArgs::is_expr_without_block () const
+{
+  return false;
+}
+
+void
+FormatArgs::mark_for_strip ()
+{
+  marked_for_strip = true;
+}
+
+bool
+FormatArgs::is_marked_for_strip () const
+{
+  return marked_for_strip;
+}
+
+std::vector &
+FormatArgs::get_outer_attrs ()
+{
+  rust_unreachable ();
+}
+
+void FormatArgs::set_outer_attrs (std::vector)
+{
+  rust_unreachable ();
+}
+
+Expr *
+FormatArgs::clone_expr_impl () const
+{
+  std::cerr << "[ARTHUR] cloning FormatArgs! " << std::endl;
+
+  return new FormatArgs (*this);
+}
+
 } // namespace AST
 
 std::ostream &
diff --git a/gcc/rust/ast/rust-builtin-ast-nodes.h 
b/gcc/rust/ast/rust-builtin-ast-nodes.h
index 3998fbfb4a7e..6e267173a557 100644
--- a/gcc/rust/ast/rust-builtin-ast-nodes.h
+++ b/gcc/rust/ast/rust-builtin-ast-nodes.h
@@ -59,9 +59,17 @@ namespace AST {
 //  └─┘  └─┘
 //  positions (could be names, numbers, empty, or `*`)
 
+// FIXME: Merge with the class below this one?
 class FormatArgumentKind
 {
 public:
+  enum class Kind
+  {
+Normal,
+Named,
+Captured,
+  } kind;
+
   Identifier &get_ident ()
   {
 rust_assert (kind == Kind::Captured || kind == Kind::Named);
@@ -69,25 +77,90 @@ public:
 return ident.value ();
   }
 
-private:
-  enum class Kind
+  FormatArgumentKind (Kind kind, tl::optional ident)
+: kind (kind), ident (ident)
+  {}
+
+  FormatArgumentKind (const FormatArgumentKind &other)
   {
-Normal,
-Named,
-Captured,
-  } kind;
+kind = other.kind;
+ident = other.ident;
+  }
+
+  FormatArgumentKind operator= (const FormatArgumentKind &other)
+  {
+kind = other.kind;
+ident = other.ident;
 
+return *this;
+  }
+
+private:
   tl::optional ident;
 };
 
 class FormatArgument
 {
+public:
+  static FormatArgument normal (std::unique_ptr expr)
+  {
+return FormatArgument (FormatArgumentKind::Kind::Normal, tl::nullopt,
+  std::move (expr));
+  }
+
+  static FormatArgument named (Identifier ident, std::unique_ptr expr)
+  {
+return FormatArgument (FormatArgumentKind::Kind::Named, ident,
+  std::move (expr));
+  }
+
+  static FormatArgument captured (Identifier ident, std::unique_ptr expr)
+  {
+return FormatArgument (FormatArgumentKind::Kind::Captured, ident,
+  std::move (expr));
+  }
+
+  FormatArgument (const FormatArgument &other)
+: kind (other.kind), expr (other.expr->clone_expr ())
+  {}
+
+  FormatArgument operator= (const FormatArgument &other)
+  {
+kind = other.kind;
+expr = other.expr->clone_expr ();
+
+return *this;
+  }
+
+private:
+  FormatArgument (FormatArgumentKind::Kind kind, tl::optional 
ident,
+ std::unique_ptr expr)
+: kind

[gcc r15-2508] gccrs: parser: Add peek(n) method to parser

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:d9fa4153c83d3a4e4099530a450c7e511b1b24ec

commit r15-2508-gd9fa4153c83d3a4e4099530a450c7e511b1b24ec
Author: Arthur Cohen 
Date:   Mon Feb 19 20:41:50 2024 +0100

gccrs: parser: Add peek(n) method to parser

gcc/rust/ChangeLog:

* parse/rust-parse.h: New method.

Diff:
---
 gcc/rust/parse/rust-parse.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h
index 1614d19e4a5b..8c8bf96eb8d0 100644
--- a/gcc/rust/parse/rust-parse.h
+++ b/gcc/rust/parse/rust-parse.h
@@ -725,6 +725,7 @@ public:
   const ManagedTokenSource &get_token_source () const { return lexer; }
 
   const_TokenPtr peek_current_token () { return lexer.peek_token (0); }
+  const_TokenPtr peek (int n) { return lexer.peek_token (n); }
 
 private:
   // The token source (usually lexer) associated with the parser.


[gcc r15-2510] gccrs: lower: Add base for lowering FormatArgs nodes

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:5151b289ad4090072a12fb6ac6219c035118eb32

commit r15-2510-g5151b289ad4090072a12fb6ac6219c035118eb32
Author: Arthur Cohen 
Date:   Thu Feb 22 14:59:17 2024 +0100

gccrs: lower: Add base for lowering FormatArgs nodes

gcc/rust/ChangeLog:

* Make-lang.in: Compile the new source file.
* ast/rust-ast-collector.cc (TokenCollector::visit): Error out when
visiting FormatArgs nodes.
* resolve/rust-ast-resolve-base.cc (ResolverBase::visit): Likewise.
* hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Likewise.
* ast/rust-ast.cc (FormatArgs::get_locus): New.
* ast/rust-builtin-ast-nodes.h: Improve FormatArgs API.
* ast/rust-fmt.cc (Pieces::~Pieces): Cleanup.
(Pieces::Pieces): Likewise.
* ast/rust-fmt.h (struct Pieces): Add pieces_vector member.
* hir/rust-ast-lower-format-args.cc: New file.
* hir/rust-ast-lower-format-args.h: New file.

Diff:
---
 gcc/rust/Make-lang.in  |  1 +
 gcc/rust/ast/rust-ast-collector.cc |  3 ++-
 gcc/rust/ast/rust-ast.cc   |  2 +-
 gcc/rust/ast/rust-builtin-ast-nodes.h  | 32 ++-
 gcc/rust/ast/rust-fmt.cc   | 39 +++-
 gcc/rust/ast/rust-fmt.h| 13 --
 gcc/rust/hir/rust-ast-lower-expr.cc|  7 -
 gcc/rust/hir/rust-ast-lower-format-args.cc | 41 ++
 gcc/rust/hir/rust-ast-lower-format-args.h  | 40 +
 gcc/rust/resolve/rust-ast-resolve-base.cc  |  3 ++-
 10 files changed, 127 insertions(+), 54 deletions(-)

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index af5d775a3a60..f166b02340d7 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -118,6 +118,7 @@ GRS_OBJS = \
 rust/rust-ast-lower-expr.o \
 rust/rust-ast-lower-type.o \
 rust/rust-ast-lower-stmt.o \
+rust/rust-ast-lower-format-args.o \
 rust/rust-rib.o \
 rust/rust-name-resolution-context.o \
 rust/rust-default-resolver.o \
diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index b8ec62367bcf..c0e8e774824a 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -2810,7 +2810,8 @@ TokenCollector::visit (BareFunctionType &type)
 void
 TokenCollector::visit (AST::FormatArgs &fmt)
 {
-  rust_sorry_at (0, "unimplemented format_args!() visitor");
+  rust_sorry_at (fmt.get_locus (), "%s:%u: unimplemented FormatArgs visitor",
+__FILE__, __LINE__);
 }
 
 } // namespace AST
diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index f3dabc6cd0fe..fbd795f67180 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -5065,7 +5065,7 @@ FormatArgs::as_string () const
 location_t
 FormatArgs::get_locus () const
 {
-  rust_unreachable ();
+  return loc;
 }
 
 bool
diff --git a/gcc/rust/ast/rust-builtin-ast-nodes.h 
b/gcc/rust/ast/rust-builtin-ast-nodes.h
index 6e267173a557..780d1a9d4e94 100644
--- a/gcc/rust/ast/rust-builtin-ast-nodes.h
+++ b/gcc/rust/ast/rust-builtin-ast-nodes.h
@@ -184,48 +184,32 @@ public:
 
   FormatArgs (location_t loc, Fmt::Pieces &&template_str,
  FormatArguments &&arguments)
-: loc (loc), template_str (std::move (template_str)),
+: loc (loc), template_pieces (std::move (template_str)),
   arguments (std::move (arguments))
   {}
 
-  FormatArgs (FormatArgs &&other)
-: loc (std::move (other.loc)),
-  template_str (std::move (other.template_str)),
-  arguments (std::move (other.arguments))
-  {
-std::cerr << "[ARTHUR] moving FormatArgs" << std::endl;
-  }
-
-  // FIXME: This might be invalid - we are reusing the same memory allocated
-  // on the Rust side for `other`. This is probably valid as long as we only
-  // ever read that memory and never write to it.
-  FormatArgs (const FormatArgs &other)
-: loc (other.loc), template_str (other.template_str),
-  arguments (other.arguments)
-  {
-std::cerr << "[ARTHUR] copying FormatArgs" << std::endl;
-  }
-
-  // FormatArgs &operator= (const FormatArgs &other) = default;
-  //   : template_str (other.template_str), arguments (other.arguments)
-  // {}
+  FormatArgs (FormatArgs &&other) = default;
+  FormatArgs (const FormatArgs &other) = default;
+  FormatArgs &operator= (const FormatArgs &other) = default;
 
   void accept_vis (AST::ASTVisitor &vis) override;
 
+  const Fmt::Pieces &get_template () const { return template_pieces; }
+  virtual location_t get_locus () const override;
+
 private:
   location_t loc;
   // FIXME: This probably needs to be a separate type - it is one in rustc's
   // expansion of format_args!(). There is extra handling associated with it.
   // we can maybe do that in rust-fmt.cc? in collect_pieces()? like do the
   // transformation into something we can handle better

[gcc r15-2511] gccrs: format-args: Add documentation for future expansion of function

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:3f4374ccfaad01cfbe8c37ea8c41cce403e070f9

commit r15-2511-g3f4374ccfaad01cfbe8c37ea8c41cce403e070f9
Author: Arthur Cohen 
Date:   Fri Mar 1 15:37:45 2024 +0100

gccrs: format-args: Add documentation for future expansion of function

gcc/rust/ChangeLog:

* expand/rust-macro-builtins.cc 
(MacroBuiltin::format_args_handler): Add
documentation regarding future tasks.

Diff:
---
 gcc/rust/expand/rust-macro-builtins.cc | 26 +-
 1 file changed, 5 insertions(+), 21 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-builtins.cc 
b/gcc/rust/expand/rust-macro-builtins.cc
index b42d1ec9367f..e4ca0d8ba3ba 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -1052,23 +1052,7 @@ MacroBuiltin::format_args_handler (location_t 
invoc_locus,
 {
   auto input = format_args_parse_arguments (invoc);
 
-  // auto fmt_arg
-  //   // FIXME: this eneds to be split up into a smaller function
-  //   = parse_single_string_literal (append_newline ?
-  //   BuiltinMacro::FormatArgsNl
-  // : BuiltinMacro::FormatArgs,
-  //  invoc.get_delim_tok_tree (), invoc_locus,
-  //  invoc.get_expander ());
-
-  //  if (!fmt_arg->is_literal ())
-  //{
-  //  rust_sorry_at (
-  // invoc_locus,
-  // "cannot yet use eager macro invocations as format strings");
-  //  return AST::Fragment::create_empty ();
-  //}
-
-  // FIXME: We need to handle this
+  // TODO(Arthur): We need to handle this
   // // if it is not a literal, it's an eager macro invocation - return it
   // if (!fmt_expr->is_literal ())
   //   {
@@ -1077,10 +1061,10 @@ MacroBuiltin::format_args_handler (location_t 
invoc_locus,
   //   token_tree.to_token_stream ());
   //   }
 
-  // auto fmt_str = static_cast (*fmt_arg.get ());
-
-  // Switch on the format string to know if the string is raw or cooked
-  // switch (fmt_str.get_lit_type ())
+  // TODO(Arthur): Handle this as well - raw strings are special for the
+  // format_args parser auto fmt_str = static_cast
+  // (*fmt_arg.get ()); Switch on the format string to know if the string is 
raw
+  // or cooked switch (fmt_str.get_lit_type ())
   //   {
   //   // case AST::Literal::RAW_STRING:
   //   case AST::Literal::STRING:


[gcc r15-2512] gccrs: Add error emitting when we can't resolve id expr

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:399645909b86db885fbd491d3b75007dc110b6b3

commit r15-2512-g399645909b86db885fbd491d3b75007dc110b6b3
Author: jjasmine 
Date:   Fri Mar 1 05:31:15 2024 -0500

gccrs: Add error emitting when we can't resolve id expr

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Add error 
emitting

Diff:
---
 gcc/rust/resolve/rust-late-name-resolver-2.0.cc | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index f9731a451a3a..8717c51e34ae 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -130,7 +130,10 @@ Late::visit (AST::IdentifierExpr &expr)
 resolved = label;
   else if (value)
 resolved = value;
-  // TODO: else emit error?
+  else {
+  rust_error_at(expr.get_locus (), "could not resolve identifier 
expression: %qs", expr.get_ident ().as_string ().c_str ());
+  return;
+  }
 
   ctx.map_usage (expr.get_node_id (), *resolved);


[gcc r15-2513] gccrs: Add curly brackets, formatted clang

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:38aa479b0333b66057553635952cadeafb6c89d1

commit r15-2513-g38aa479b0333b66057553635952cadeafb6c89d1
Author: jjasmine 
Date:   Fri Mar 1 16:40:17 2024 -0500

gccrs: Add curly brackets, formatted clang

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Add error 
emitting

Diff:
---
 gcc/rust/resolve/rust-late-name-resolver-2.0.cc | 17 -
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index 8717c51e34ae..e5a4f2348712 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -127,13 +127,20 @@ Late::visit (AST::IdentifierExpr &expr)
   auto value = ctx.values.get (expr.get_ident ());
 
   if (label)
-resolved = label;
+{
+  resolved = label;
+}
   else if (value)
-resolved = value;
-  else {
-  rust_error_at(expr.get_locus (), "could not resolve identifier 
expression: %qs", expr.get_ident ().as_string ().c_str ());
+{
+  resolved = value;
+}
+  else
+{
+  rust_error_at (expr.get_locus (),
+"could not resolve identifier expression: %qs",
+expr.get_ident ().as_string ().c_str ());
   return;
-  }
+}
 
   ctx.map_usage (expr.get_node_id (), *resolved);


[gcc r15-2514] gccrs: Ensure TupleStructPattern and TuplePattern have items

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:ebbf7bedbabc2a52fd0cd2b97611eb5d9bf02086

commit r15-2514-gebbf7bedbabc2a52fd0cd2b97611eb5d9bf02086
Author: Owen Avery 
Date:   Tue Feb 27 16:34:23 2024 -0500

gccrs: Ensure TupleStructPattern and TuplePattern have items

Note that instances of both classes which have been
moved from will have (items == nullptr).

gcc/rust/ChangeLog:

* ast/rust-pattern.h
(class TupleStructPattern): Assert that items != nullptr.
(class TuplePattern): Likewise.
(TupleStructPattern::has_items): Remove.
(TuplePattern::has_tuple_pattern_items): Likewise.
* parse/rust-parse-impl.h
(Parser::parse_ident_leading_pattern):
Prevent construction of TupleStructPattern with
(items == nullptr).
(Parser::parse_pattern_no_alt): Likewise.
* ast/rust-ast-collector.cc
(TokenCollector::visit): Remove usage of
TupleStructPattern::has_items.
* ast/rust-ast-visitor.cc
(DefaultASTVisitor::visit): Likewise.
* resolve/rust-early-name-resolver.cc
(EarlyNameResolver::visit): Likewise.

gcc/testsuite/ChangeLog:

* rust/compile/pattern-struct.rs: Fix test.

Signed-off-by: Owen Avery 

Diff:
---
 gcc/rust/ast/rust-ast-collector.cc   |  3 +-
 gcc/rust/ast/rust-ast-visitor.cc |  3 +-
 gcc/rust/ast/rust-pattern.h  | 46 ++--
 gcc/rust/parse/rust-parse-impl.h | 16 --
 gcc/rust/resolve/rust-early-name-resolver.cc | 10 --
 gcc/testsuite/rust/compile/pattern-struct.rs |  2 +-
 6 files changed, 26 insertions(+), 54 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index c0e8e774824a..744d0eb9d289 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -2503,8 +2503,7 @@ TokenCollector::visit (TupleStructPattern &pattern)
 {
   visit (pattern.get_path ());
   push (Rust::Token::make (LEFT_PAREN, pattern.get_locus ()));
-  if (pattern.has_items ())
-visit (pattern.get_items ());
+  visit (pattern.get_items ());
   push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
 }
 
diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index c72e2d72f6d2..697c27263098 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -1225,8 +1225,7 @@ void
 DefaultASTVisitor::visit (AST::TupleStructPattern &pattern)
 {
   visit (pattern.get_path ());
-  if (pattern.has_items ())
-visit (pattern.get_items ());
+  visit (pattern.get_items ());
 }
 
 void
diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h
index 6a90b5361758..96f09355fae0 100644
--- a/gcc/rust/ast/rust-pattern.h
+++ b/gcc/rust/ast/rust-pattern.h
@@ -1123,22 +1123,22 @@ class TupleStructPattern : public Pattern
 public:
   std::string as_string () const override;
 
-  // Returns whether the pattern has tuple struct items.
-  bool has_items () const { return items != nullptr; }
-
   TupleStructPattern (PathInExpression tuple_struct_path,
  std::unique_ptr items)
 : path (std::move (tuple_struct_path)), items (std::move (items)),
   node_id (Analysis::Mappings::get ()->get_next_node_id ())
-  {}
+  {
+rust_assert (this->items != nullptr);
+  }
 
   // Copy constructor required to clone
   TupleStructPattern (TupleStructPattern const &other) : path (other.path)
   {
 // guard to protect from null dereference
+rust_assert (other.items != nullptr);
+
 node_id = other.node_id;
-if (other.items != nullptr)
-  items = other.items->clone_tuple_struct_items ();
+items = other.items->clone_tuple_struct_items ();
   }
 
   // Operator overload assignment operator to clone
@@ -1148,10 +1148,9 @@ public:
 node_id = other.node_id;
 
 // guard to protect from null dereference
-if (other.items != nullptr)
-  items = other.items->clone_tuple_struct_items ();
-else
-  items = nullptr;
+rust_assert (other.items != nullptr);
+
+items = other.items->clone_tuple_struct_items ();
 
 return *this;
   }
@@ -1164,7 +1163,11 @@ public:
 
   void accept_vis (ASTVisitor &vis) override;
 
-  std::unique_ptr &get_items () { return items; }
+  std::unique_ptr &get_items ()
+  {
+rust_assert (items != nullptr);
+return items;
+  }
 
   PathInExpression &get_path () { return path; }
   const PathInExpression &get_path () const { return path; }
@@ -1358,7 +1361,6 @@ protected:
 // AST node representing a tuple pattern
 class TuplePattern : public Pattern
 {
-  // bool has_tuple_pattern_items;
   std::unique_ptr items;
   location_t locus;
   NodeId node_id;
@@ -1366,21 +1368,21 @@ class TuplePattern : public Pattern
 public:
   std::string as_string () const override;
 
-  // Returns true if the tuple pattern has items
-  boo

[gcc r15-2515] gccrs: Clean BiMap to use tl::optional for lookups

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:8c642618265162c28a9de83ba4df12318023fda7

commit r15-2515-g8c642618265162c28a9de83ba4df12318023fda7
Author: Sourabh Jaiswal 
Date:   Fri Mar 1 19:46:23 2024 +0800

gccrs: Clean BiMap to use tl::optional for lookups

gcc/rust/Changelog:

* expand/rust-expand-visitor.cc
(ExpandVisitor::expand_inner_items): Adjust to use has_value ()
(ExpandVisitor::expand_inner_stmts): Likewise
* expand/rust-macro-builtins.cc (builtin_macro_from_string): 
Likewise
(make_macro_path_str): Likewise
* util/rust-hir-map.cc (Mappings::insert_macro_def): Likewise
* util/rust-lang-item.cc (LangItem::Parse): Adjust to return 
tl::optional
(LangItem::toString) Likewise
* util/rust-token-converter.cc (handle_suffix): Adjust to use 
value.or ()
(from_literal) Likewise
* util/bi-map.h (BiMap::lookup): Adjust to use tl::optional for
lookups

Signed-off-by: Sourabh Jaiswal 

Diff:
---
 gcc/rust/expand/rust-expand-visitor.cc |  8 
 gcc/rust/expand/rust-macro-builtins.cc |  8 
 gcc/rust/util/bi-map.h | 22 +++---
 gcc/rust/util/rust-hir-map.cc  |  2 +-
 gcc/rust/util/rust-lang-item.cc|  6 ++
 gcc/rust/util/rust-token-converter.cc  |  5 ++---
 6 files changed, 28 insertions(+), 23 deletions(-)

diff --git a/gcc/rust/expand/rust-expand-visitor.cc 
b/gcc/rust/expand/rust-expand-visitor.cc
index 6ca63115195b..bd49fd910929 100644
--- a/gcc/rust/expand/rust-expand-visitor.cc
+++ b/gcc/rust/expand/rust-expand-visitor.cc
@@ -186,11 +186,11 @@ ExpandVisitor::expand_inner_items (
{
  auto maybe_builtin = MacroBuiltin::builtins.lookup (
to_derive.get ().as_string ());
- if (MacroBuiltin::builtins.is_iter_ok (maybe_builtin))
+ if (maybe_builtin.has_value ())
{
  auto new_item
= builtin_derive_item (*item, current,
-  maybe_builtin->second);
+  maybe_builtin.value ());
  // this inserts the derive *before* the item - is it a
  // problem?
  it = items.insert (it, std::move (new_item));
@@ -272,11 +272,11 @@ ExpandVisitor::expand_inner_stmts (AST::BlockExpr &expr)
{
  auto maybe_builtin = MacroBuiltin::builtins.lookup (
to_derive.get ().as_string ());
- if (MacroBuiltin::builtins.is_iter_ok (maybe_builtin))
+ if (maybe_builtin.has_value ())
{
  auto new_item
= builtin_derive_item (item, current,
-  maybe_builtin->second);
+  maybe_builtin.value ());
  // this inserts the derive *before* the item - is it a
  // problem?
  it = stmts.insert (it, std::move (new_item));
diff --git a/gcc/rust/expand/rust-macro-builtins.cc 
b/gcc/rust/expand/rust-macro-builtins.cc
index e4ca0d8ba3ba..8cf32051c7aa 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -142,9 +142,9 @@ tl::optional
 builtin_macro_from_string (const std::string &identifier)
 {
   auto macro = MacroBuiltin::builtins.lookup (identifier);
-  rust_assert (MacroBuiltin::builtins.is_iter_ok (macro));
+  rust_assert (macro.has_value ());
 
-  return macro->second;
+  return macro;
 }
 
 namespace {
@@ -152,9 +152,9 @@ std::string
 make_macro_path_str (BuiltinMacro kind)
 {
   auto str = MacroBuiltin::builtins.lookup (kind);
-  rust_assert (MacroBuiltin::builtins.is_iter_ok (str));
+  rust_assert (str.has_value ());
 
-  return str->second;
+  return str.value ();
 }
 
 static std::vector>
diff --git a/gcc/rust/util/bi-map.h b/gcc/rust/util/bi-map.h
index ff26c833811c..bc4f5800fb1d 100644
--- a/gcc/rust/util/bi-map.h
+++ b/gcc/rust/util/bi-map.h
@@ -24,9 +24,6 @@
 // very simple bi-directional hashmap
 template  class BiMap
 {
-  using v_iter = typename std::unordered_map::const_iterator;
-  using k_iter = typename std::unordered_map::const_iterator;
-
 public:
   BiMap (std::unordered_map &&original) : map (std::move (original))
   {
@@ -34,11 +31,22 @@ public:
   rmap.insert ({kv.second, kv.first});
   }
 
-  const v_iter lookup (const K &key) const { return map.find (key); }
-  const k_iter lookup (const V &key) const { return rmap.find (key); }
+  const tl::optional lookup (const K &key) const
+  {
+auto itr = map.find (key);
+if (itr == map.end ())
+  return tl::nullopt;
+
+return itr->second;
+  }
+  

[gcc r15-2516] gccrs: Add support for external functions

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:709db9bb630dd9bc01248414971ab4be82fc22b2

commit r15-2516-g709db9bb630dd9bc01248414971ab4be82fc22b2
Author: 0xn4utilus 
Date:   Sun Feb 25 05:32:26 2024 +0530

gccrs: Add support for external functions

gcc/rust/ChangeLog:

* ast/rust-ast.cc (Function::Function): Add `is_external_function` 
field.
(Function::operator=): Likewise.
* ast/rust-ast.h: New constructor for ExternalItem.
* ast/rust-item.h (class Function): Add `is_external_function`
field. Update `get_node_id`.
* ast/rust-macro.h: Update copy constructor.

Signed-off-by: 0xn4utilus 

Diff:
---
 gcc/rust/ast/rust-ast.cc  |  9 ++---
 gcc/rust/ast/rust-ast.h   |  4 +++-
 gcc/rust/ast/rust-item.h  | 41 +
 gcc/rust/ast/rust-macro.h |  9 +
 4 files changed, 43 insertions(+), 20 deletions(-)

diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index fbd795f67180..5d661989904b 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -1061,9 +1061,11 @@ Union::as_string () const
 }
 
 Function::Function (Function const &other)
-  : VisItem (other), qualifiers (other.qualifiers),
-function_name (other.function_name), where_clause (other.where_clause),
-locus (other.locus), is_default (other.is_default)
+  : VisItem (other), ExternalItem (other.get_node_id ()),
+qualifiers (other.qualifiers), function_name (other.function_name),
+where_clause (other.where_clause), locus (other.locus),
+is_default (other.is_default),
+is_external_function (other.is_external_function)
 {
   // guard to prevent null dereference (always required)
   if (other.return_type != nullptr)
@@ -1095,6 +1097,7 @@ Function::operator= (Function const &other)
   // outer_attrs = other.outer_attrs;
   locus = other.locus;
   is_default = other.is_default;
+  is_external_function = other.is_external_function;
 
   // guard to prevent null dereference (always required)
   if (other.return_type != nullptr)
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index c4d5858dd636..92faaf297f9d 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -1695,6 +1695,8 @@ class ExternalItem : public Visitable
 public:
   ExternalItem () : node_id (Analysis::Mappings::get ()->get_next_node_id ()) 
{}
 
+  ExternalItem (NodeId node_id) : node_id (node_id) {}
+
   virtual ~ExternalItem () {}
 
   // Unique pointer custom clone function
@@ -1708,7 +1710,7 @@ public:
   virtual void mark_for_strip () = 0;
   virtual bool is_marked_for_strip () const = 0;
 
-  NodeId get_node_id () const { return node_id; }
+  virtual NodeId get_node_id () const { return node_id; }
 
 protected:
   // Clone function implementation as pure virtual method
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 44963ba386e7..573888bea5aa 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -1289,7 +1289,7 @@ protected:
 class LetStmt;
 
 // Rust function declaration AST node
-class Function : public VisItem, public AssociatedItem
+class Function : public VisItem, public AssociatedItem, public ExternalItem
 {
   FunctionQualifiers qualifiers;
   Identifier function_name;
@@ -1300,6 +1300,7 @@ class Function : public VisItem, public AssociatedItem
   tl::optional> function_body;
   location_t locus;
   bool is_default;
+  bool is_external_function;
 
 public:
   std::string as_string () const override;
@@ -1330,16 +1331,17 @@ public:
std::unique_ptr return_type, WhereClause where_clause,
tl::optional> function_body,
Visibility vis, std::vector outer_attrs,
-   location_t locus, bool is_default = false)
+   location_t locus, bool is_default = false,
+   bool is_external_function = false)
 : VisItem (std::move (vis), std::move (outer_attrs)),
-  qualifiers (std::move (qualifiers)),
+  ExternalItem (Stmt::node_id), qualifiers (std::move (qualifiers)),
   function_name (std::move (function_name)),
   generic_params (std::move (generic_params)),
   function_params (std::move (function_params)),
   return_type (std::move (return_type)),
   where_clause (std::move (where_clause)),
   function_body (std::move (function_body)), locus (locus),
-  is_default (is_default)
+  is_default (is_default), is_external_function (is_external_function)
   {}
 
   // TODO: add constructor with less fields
@@ -1364,6 +1366,8 @@ public:
   && function_params.back ()->is_variadic ();
   }
 
+  bool is_external () const { return is_external_function; }
+
   // Invalid if block is null, so base stripping on that.
   void mark_for_strip () override { function_body = nullptr; }
   bool is_marked_for_strip () const override
@@ -1422,6 +1426,9 @@ public:
 return function_params[0];
   }
 
+  // ExternalItem::node_id is same as Stmt::node_id
+  NodeId get_node_id () const 

[gcc r15-2517] gccrs: Add get_pattern_kind to Pattern

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:c1ccc7c098dafac076862c25dff6e059f616b31a

commit r15-2517-gc1ccc7c098dafac076862c25dff6e059f616b31a
Author: 0xn4utilus 
Date:   Sun Feb 25 06:20:51 2024 +0530

gccrs: Add get_pattern_kind to Pattern

gcc/rust/ChangeLog:

* ast/rust-ast.h: Add Kind Enum to
Pattern.
* ast/rust-macro.h: Add get_pattern_kind().
* ast/rust-path.h: Likewise.
* ast/rust-pattern.h: Likewise.

Signed-off-by: 0xn4utilus 

Diff:
---
 gcc/rust/ast/rust-ast.h | 20 
 gcc/rust/ast/rust-macro.h   |  5 +
 gcc/rust/ast/rust-path.h|  2 ++
 gcc/rust/ast/rust-pattern.h | 33 +
 4 files changed, 60 insertions(+)

diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 92faaf297f9d..edf726b1ffec 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -1360,12 +1360,32 @@ protected:
 class Pattern : public Visitable
 {
 public:
+  enum class Kind
+  {
+Literal,
+Identifier,
+Wildcard,
+Rest,
+Range,
+Reference,
+Struct,
+TupleStruct,
+Tuple,
+Grouped,
+Slice,
+Alt,
+Path,
+MacroInvocation,
+  };
+
   // Unique pointer custom clone function
   std::unique_ptr clone_pattern () const
   {
 return std::unique_ptr (clone_pattern_impl ());
   }
 
+  virtual Kind get_pattern_kind () = 0;
+
   // possible virtual methods: is_refutable()
 
   virtual ~Pattern () {}
diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h
index bfdebfc42032..5b9ff3f22c88 100644
--- a/gcc/rust/ast/rust-macro.h
+++ b/gcc/rust/ast/rust-macro.h
@@ -610,6 +610,11 @@ public:
 
   std::string as_string () const override;
 
+  Pattern::Kind get_pattern_kind () override
+  {
+return Pattern::Kind::MacroInvocation;
+  }
+
   /**
* The default constructor you should use. Whenever we parse a macro call, we
* cannot possibly know whether or not this call refers to a builtin macro or
diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index ccac6303bb4b..bd3012b1bed3 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -578,6 +578,8 @@ public:
   // TODO: this seems kinda dodgy
   std::vector &get_segments () { return segments; }
   const std::vector &get_segments () const { return segments; 
}
+
+  Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Path; }
 };
 
 /* AST node representing a path-in-expression pattern (path that allows
diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h
index 96f09355fae0..365f3b7f69d2 100644
--- a/gcc/rust/ast/rust-pattern.h
+++ b/gcc/rust/ast/rust-pattern.h
@@ -55,6 +55,8 @@ public:
 
   const Literal &get_literal () const { return lit; }
 
+  Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Literal; }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
* than base */
@@ -149,6 +151,11 @@ public:
 
   NodeId get_node_id () const override { return node_id; }
 
+  Pattern::Kind get_pattern_kind () override
+  {
+return Pattern::Kind::Identifier;
+  }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
* than base */
@@ -177,6 +184,8 @@ public:
 
   NodeId get_node_id () const override { return node_id; }
 
+  Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Wildcard; 
}
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
* than base */
@@ -204,6 +213,8 @@ public:
 
   NodeId get_node_id () const override final { return node_id; }
 
+  Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Rest; }
+
 protected:
   RestPattern *clone_pattern_impl () const override
   {
@@ -431,6 +442,8 @@ public:
 
   NodeId get_node_id () const override { return node_id; }
 
+  Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Range; }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
* than base */
@@ -499,6 +512,11 @@ public:
 
   NodeId get_node_id () const override { return node_id; }
 
+  Pattern::Kind get_pattern_kind () override
+  {
+return Pattern::Kind::Reference;
+  }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
* than base */
@@ -934,6 +952,8 @@ public:
 
   NodeId get_node_id () const override { return node_id; }
 
+  Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Struct; }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
* than base */
@@ -1174,6 +1194,11 @@ public:
 
   NodeId get_node_id () const override { return node_id; }
 
+  Pattern::Kind get_pattern_kind () override
+  {
+return Pattern::Kind::TupleStruct;
+  }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
* than base */
@@ -1

[gcc r15-2518] gccrs: Unify ASTValidation::visit for ExternalFunctionItem and Function

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:bbc1dfcc57f2042163e558428b855dca38e24e88

commit r15-2518-gbbc1dfcc57f2042163e558428b855dca38e24e88
Author: 0xn4utilus 
Date:   Sun Feb 25 19:03:55 2024 +0530

gccrs: Unify ASTValidation::visit for ExternalFunctionItem and Function

gcc/rust/ChangeLog:

* checks/errors/rust-ast-validation.cc (ASTValidation::visit):
Add external function validation support. Add ErrorCode::E0130.
* parse/rust-parse-impl.h (Parser::parse_function): Parse
external functions from `parse_function`.
(Parser::parse_external_item): Clang format.
(Parser::parse_pattern): Clang format.
* parse/rust-parse.h: Add default parameter
`is_external` in `parse_function`.

Signed-off-by: 0xn4utilus 

Diff:
---
 gcc/rust/checks/errors/rust-ast-validation.cc | 62 +--
 gcc/rust/parse/rust-parse-impl.h  |  9 ++--
 gcc/rust/parse/rust-parse.h   |  3 +-
 3 files changed, 57 insertions(+), 17 deletions(-)

diff --git a/gcc/rust/checks/errors/rust-ast-validation.cc 
b/gcc/rust/checks/errors/rust-ast-validation.cc
index bf70ca5d96f9..f5a97b0d350a 100644
--- a/gcc/rust/checks/errors/rust-ast-validation.cc
+++ b/gcc/rust/checks/errors/rust-ast-validation.cc
@@ -122,23 +122,61 @@ ASTValidation::visit (AST::Function &function)
   function.get_self_param ()->get_locus (),
   "% parameter is only allowed in associated functions");
 
-  if (!function.has_body ())
+  if (function.is_external ())
 {
-  if (context.back () == Context::INHERENT_IMPL
- || context.back () == Context::TRAIT_IMPL)
+  if (function.has_body ())
+   rust_error_at (function.get_locus (), "cannot have a body");
+
+  auto ¶ms = function.get_function_params ();
+
+  if (params.size () == 1 && function.is_variadic ())
rust_error_at (function.get_locus (),
-  "associated function in % without body");
-  else if (context.back () != Context::TRAIT)
-   rust_error_at (function.get_locus (), "free function without a body");
+  "C-variadic function must be declared with at least one "
+  "named argument");
+
+  for (auto it = params.begin (); it != params.end (); it++)
+   {
+ if (it->get ()->is_variadic () && it + 1 != params.end ())
+   rust_error_at (
+ it->get ()->get_locus (),
+ "%<...%> must be the last argument of a C-variadic function");
+
+ // if functional parameter
+ if (!it->get ()->is_self () && !it->get ()->is_variadic ())
+   {
+ auto param = static_cast (it->get ());
+ auto kind = param->get_pattern ()->get_pattern_kind ();
+
+ if (kind != AST::Pattern::Kind::Identifier
+ && kind != AST::Pattern::Kind::Wildcard)
+   rust_error_at (it->get ()->get_locus (), ErrorCode::E0130,
+  "pattern not allowed in foreign function");
+   }
+   }
 }
 
-  auto &function_params = function.get_function_params ();
-  for (auto it = function_params.begin (); it != function_params.end (); it++)
+  else
 {
-  if (it->get ()->is_variadic ())
-   rust_error_at (it->get ()->get_locus (),
-  "only foreign or % functions may "
-  "be C-variadic");
+  if (!function.has_body ())
+   {
+ if (context.back () == Context::INHERENT_IMPL
+ || context.back () == Context::TRAIT_IMPL)
+   rust_error_at (function.get_locus (),
+  "associated function in % without body");
+ else if (context.back () != Context::TRAIT)
+   rust_error_at (function.get_locus (),
+  "free function without a body");
+   }
+  auto &function_params = function.get_function_params ();
+  for (auto it = function_params.begin (); it != function_params.end ();
+  it++)
+   {
+ if (it->get ()->is_variadic ())
+   rust_error_at (
+ it->get ()->get_locus (),
+ "only foreign or % functions may "
+ "be C-variadic");
+   }
 }
 
   AST::ContextualASTVisitor::visit (function);
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index 9d9722e97142..c8a87a11766f 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -2908,7 +2908,8 @@ Parser::parse_use_tree ()
 template 
 std::unique_ptr
 Parser::parse_function (AST::Visibility vis,
-   AST::AttrVec outer_attrs)
+   AST::AttrVec outer_attrs,
+   bool is_external)
 {
   location_t locus = lexer.peek_token ()->get_locus ();
   // Get qualifiers for function if they exist
@@ -2992,7 +2993,7 @@ Parser::parse_function 
(AST

[gcc r15-2519] gccrs: Update resolver to use `AST::Function` instead of `AST::ExternalFunctionItem`

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:293ac1ba6157c060bc053288b7ed0ae03622fe07

commit r15-2519-g293ac1ba6157c060bc053288b7ed0ae03622fe07
Author: 0xn4utilus 
Date:   Mon Feb 26 04:39:43 2024 +0530

gccrs: Update resolver to use `AST::Function` instead of 
`AST::ExternalFunctionItem`

gcc/rust/ChangeLog:

* checks/errors/rust-feature-gate.cc (FeatureGate::visit):
Check if function is_external or not.
* hir/rust-ast-lower-extern.h: Use AST::Function
instead of AST::ExternalFunctionItem.
* parse/rust-parse-impl.h (Parser::parse_external_item):
Likewise.
(Parser::parse_pattern): Fix clang format.
* resolve/rust-ast-resolve-implitem.h: Likewise.
* resolve/rust-ast-resolve-item.cc (ResolveExternItem::visit):
Likewise.
* resolve/rust-ast-resolve-item.h: Likewise.
* resolve/rust-default-resolver.cc (DefaultResolver::visit):
Check if param has_pattern before using get_pattern.

Signed-off-by: 0xn4utilus 

Diff:
---
 gcc/rust/checks/errors/rust-feature-gate.cc  |  3 ++-
 gcc/rust/hir/rust-ast-lower-extern.h | 23 ++-
 gcc/rust/parse/rust-parse-impl.h |  7 ---
 gcc/rust/resolve/rust-ast-resolve-implitem.h |  4 ++--
 gcc/rust/resolve/rust-ast-resolve-item.cc| 16 ++--
 gcc/rust/resolve/rust-ast-resolve-item.h |  2 +-
 gcc/rust/resolve/rust-default-resolver.cc|  3 ++-
 7 files changed, 39 insertions(+), 19 deletions(-)

diff --git a/gcc/rust/checks/errors/rust-feature-gate.cc 
b/gcc/rust/checks/errors/rust-feature-gate.cc
index 3c943022f05e..33bbfa1ec51b 100644
--- a/gcc/rust/checks/errors/rust-feature-gate.cc
+++ b/gcc/rust/checks/errors/rust-feature-gate.cc
@@ -131,7 +131,8 @@ FeatureGate::visit (AST::MacroRulesDefinition &rules_def)
 void
 FeatureGate::visit (AST::Function &function)
 {
-  check_rustc_attri (function.get_outer_attrs ());
+  if (!function.is_external ())
+check_rustc_attri (function.get_outer_attrs ());
 }
 
 void
diff --git a/gcc/rust/hir/rust-ast-lower-extern.h 
b/gcc/rust/hir/rust-ast-lower-extern.h
index f9e067c8e95b..ad7d75422d68 100644
--- a/gcc/rust/hir/rust-ast-lower-extern.h
+++ b/gcc/rust/hir/rust-ast-lower-extern.h
@@ -65,7 +65,7 @@ public:
   item.get_outer_attrs (), item.get_locus ());
   }
 
-  void visit (AST::ExternalFunctionItem &function) override
+  void visit (AST::Function &function) override
   {
 std::vector > where_clause_items;
 HIR::WhereClause where_clause (std::move (where_clause_items));
@@ -88,12 +88,25 @@ public:
 std::vector function_params;
 for (auto it = begin; it != end; it++)
   {
+   auto param = static_cast (it->get ());
+
+   if (param->is_variadic () || param->is_self ())
+ continue;
+   auto param_kind = param->get_pattern ()->get_pattern_kind ();
+
+   rust_assert (param_kind == AST::Pattern::Kind::Identifier
+|| param_kind == AST::Pattern::Kind::Wildcard);
+   auto param_ident = static_cast (
+ param->get_pattern ().get ());
+   Identifier param_name = param_kind == AST::Pattern::Kind::Identifier
+ ? param_ident->get_ident ()
+ : std::string ("_");
+
HIR::Type *param_type
- = ASTLoweringType::translate (it->get_type ().get ());
-   Identifier param_name = it->get_name ();
+ = ASTLoweringType::translate (param->get_type ().get ());
 
auto crate_num = mappings->get_current_crate ();
-   Analysis::NodeMapping mapping (crate_num, it->get_node_id (),
+   Analysis::NodeMapping mapping (crate_num, param->get_node_id (),
   mappings->get_next_hir_id (crate_num),
   mappings->get_next_localdef_id (
 crate_num));
@@ -109,7 +122,7 @@ public:
   mappings->get_next_localdef_id (crate_num));
 
 translated = new HIR::ExternalFunctionItem (
-  mapping, function.get_identifier (), std::move (generic_params),
+  mapping, function.get_function_name (), std::move (generic_params),
   std::unique_ptr (return_type), std::move (where_clause),
   std::move (function_params), is_variadic, std::move (vis),
   function.get_outer_attrs (), function.get_locus ());
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index c8a87a11766f..26b24150f7a1 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -6165,8 +6165,7 @@ Parser::parse_external_item ()
   std::move (outer_attrs), locus));
   }
 case FN_KW:
-  return parse_external_function_item (std::move (vis),
-  std::move (outer_attrs));
+  return parse_function (std::move (vis), std::move (outer_attr

[gcc r15-2520] gccrs: Remove dead code associated with `AST::ExternalFunctionItem`

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:b2a6d975722e778e3ea0c58b1ad78fbe001d849b

commit r15-2520-gb2a6d975722e778e3ea0c58b1ad78fbe001d849b
Author: 0xn4utilus 
Date:   Wed Feb 28 19:35:30 2024 +0530

gccrs: Remove dead code associated with `AST::ExternalFunctionItem`

gcc/rust/ChangeLog:

* ast/rust-ast-collector.cc (TokenCollector::visit):
Remove dead code.
* ast/rust-ast-collector.h: Likewise.
* ast/rust-ast-full-decls.h (class ExternalFunctionItem):
Likewise.
* ast/rust-ast-visitor.cc (DefaultASTVisitor::visit):
Likewise.
* ast/rust-ast-visitor.h: Likewise.
* ast/rust-ast.cc (ExternalFunctionItem::as_string): Likewise.
(ExternalFunctionItem::accept_vis): Likewise.
* checks/errors/rust-ast-validation.cc (ASTValidation::visit):
Likewise.
* checks/errors/rust-ast-validation.h: Likewise.
* checks/errors/rust-feature-gate.h: Likewise.
* expand/rust-cfg-strip.cc (CfgStrip::visit):
Likewise.
* expand/rust-cfg-strip.h: Likewise.
* expand/rust-derive.h: Likewise.
* expand/rust-expand-visitor.cc (ExpandVisitor::visit):
Likewise.
* expand/rust-expand-visitor.h: Likewise.
* hir/rust-ast-lower-base.cc (ASTLoweringBase::visit):
Likewise.
* hir/rust-ast-lower-base.h: Likewise.
* metadata/rust-export-metadata.cc (ExportContext::emit_function):
Likewise.
* parse/rust-parse-impl.h: Likewise.
* parse/rust-parse.h: Likewise.
* resolve/rust-ast-resolve-base.cc (ResolverBase::visit):
Likewise.
* resolve/rust-ast-resolve-base.h: Likewise.
* resolve/rust-default-resolver.cc (DefaultResolver::visit):
Likewise.
* resolve/rust-default-resolver.h: Likewise.
* util/rust-attributes.cc (AttributeChecker::visit): Likewise.
* util/rust-attributes.h: Likewise.

gcc/testsuite/ChangeLog:

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

Signed-off-by: 0xn4utilus 

Diff:
---
 gcc/rust/ast/rust-ast-collector.cc | 25 
 gcc/rust/ast/rust-ast-collector.h  |  1 -
 gcc/rust/ast/rust-ast-full-decls.h |  1 -
 gcc/rust/ast/rust-ast-visitor.cc   | 18 --
 gcc/rust/ast/rust-ast-visitor.h|  2 -
 gcc/rust/ast/rust-ast.cc   | 69 --
 gcc/rust/checks/errors/rust-ast-validation.cc  | 19 --
 gcc/rust/checks/errors/rust-ast-validation.h   |  1 -
 gcc/rust/checks/errors/rust-feature-gate.h |  1 -
 gcc/rust/expand/rust-cfg-strip.cc  | 56 --
 gcc/rust/expand/rust-cfg-strip.h   |  1 -
 gcc/rust/expand/rust-derive.h  |  1 -
 gcc/rust/expand/rust-expand-visitor.cc | 17 --
 gcc/rust/expand/rust-expand-visitor.h  |  1 -
 gcc/rust/hir/rust-ast-lower-base.cc|  3 -
 gcc/rust/hir/rust-ast-lower-base.h |  1 -
 gcc/rust/metadata/rust-export-metadata.cc  | 41 +
 gcc/rust/parse/rust-parse-impl.h   | 62 ---
 gcc/rust/parse/rust-parse.h|  2 -
 gcc/rust/resolve/rust-ast-resolve-base.cc  |  4 --
 gcc/rust/resolve/rust-ast-resolve-base.h   |  1 -
 gcc/rust/resolve/rust-default-resolver.cc  |  4 --
 gcc/rust/resolve/rust-default-resolver.h   |  1 -
 gcc/rust/util/rust-attributes.cc   |  4 --
 gcc/rust/util/rust-attributes.h|  1 -
 .../rust/compile/extern_func_with_body.rs  |  5 ++
 26 files changed, 7 insertions(+), 335 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index 744d0eb9d289..eb03dccaf849 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -2084,31 +2084,6 @@ TokenCollector::visit (ExternalStaticItem &item)
   push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
 }
 
-void
-TokenCollector::visit (ExternalFunctionItem &function)
-{
-  visit_items_as_lines (function.get_outer_attrs ());
-  visit (function.get_visibility ());
-
-  auto id = function.get_identifier ().as_string ();
-
-  push (Rust::Token::make (FN_KW, function.get_locus ()));
-  push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
-  if (function.has_generics ())
-visit (function.get_generic_params ());
-  push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
-
-  visit_items_joined_by_separator (function.get_function_params ());
-
-  push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
-  if (function.has_return_type ())
-{
-  push (Rust::Token::make (RETURN_TYPE, UNDEF_LOCATION));
-  visit 

[gcc r15-2521] gccrs: Placate clang-format re 'gcc/rust/backend/rust-tree.cc'

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:240b7c888450868b6c8c6fe7be855432d161c08f

commit r15-2521-g240b7c888450868b6c8c6fe7be855432d161c08f
Author: Thomas Schwinge 
Date:   Tue Mar 12 09:36:43 2024 +0100

gccrs: Placate clang-format re 'gcc/rust/backend/rust-tree.cc'

Reformat the upstream GCC commit f4a2ae2338962208b8039f154f5912402e94c378
"Change MODE_BITSIZE to MODE_PRECISION for MODE_VECTOR_BOOL" change to
'gcc/rust/backend/rust-tree.cc' to clang-format's liking.

gcc/rust/
* backend/rust-tree.cc (c_common_type_for_mode): Placate 
clang-format.

Diff:
---
 gcc/rust/backend/rust-tree.cc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc
index 2a5ffcbf8956..cdb79095da88 100644
--- a/gcc/rust/backend/rust-tree.cc
+++ b/gcc/rust/backend/rust-tree.cc
@@ -5371,8 +5371,8 @@ c_common_type_for_mode (machine_mode mode, int unsignedp)
   else if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL
   && valid_vector_subparts_p (GET_MODE_NUNITS (mode)))
 {
-  unsigned int elem_bits
-   = vector_element_size (GET_MODE_PRECISION (mode), GET_MODE_NUNITS 
(mode));
+  unsigned int elem_bits = vector_element_size (GET_MODE_PRECISION (mode),
+   GET_MODE_NUNITS (mode));
   tree bool_type = build_nonstandard_boolean_type (elem_bits);
   return build_vector_type_for_mode (bool_type, mode);
 }


[gcc r15-2522] gccrs: Replace reference to unique pointer with reference

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:68ec9f41ae49f14f510720a4e8dafbd49a279c58

commit r15-2522-g68ec9f41ae49f14f510720a4e8dafbd49a279c58
Author: Pierre-Emmanuel Patry 
Date:   Wed Feb 21 16:45:18 2024 +0100

gccrs: Replace reference to unique pointer with reference

Reference to unique pointers are a known anti pattern, only the element
shall be taken by reference instead of the whole wrapper.

gcc/rust/ChangeLog:

* ast/rust-item.h: Change getter function prototype to return a
reference directly instead of a reference to the wrapper type.
* checks/errors/rust-ast-validation.cc (ASTValidation::visit): Fix
the code to accept references instead.
* hir/rust-ast-lower-base.cc (ASTLoweringBase::lower_self): Change
function implementation to return a reference.
* hir/rust-ast-lower-base.h: Accept a reference instead of a unique
pointer reference.
* resolve/rust-ast-resolve-item.cc (ResolveItem::visit): Adapt the 
code
to a reference instead of a unique pointer.

Signed-off-by: Pierre-Emmanuel Patry 

Diff:
---
 gcc/rust/ast/rust-item.h  |  8 
 gcc/rust/checks/errors/rust-ast-validation.cc |  2 +-
 gcc/rust/hir/rust-ast-lower-base.cc   | 24 
 gcc/rust/hir/rust-ast-lower-base.h|  2 +-
 gcc/rust/resolve/rust-ast-resolve-item.cc | 19 +--
 5 files changed, 27 insertions(+), 28 deletions(-)

diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 573888bea5aa..d09f45500629 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -1415,15 +1415,15 @@ public:
 return return_type;
   }
 
-  std::unique_ptr &get_self_param ()
+  Param &get_self_param ()
   {
 rust_assert (has_self_param ());
-return function_params[0];
+return *function_params[0];
   }
-  const std::unique_ptr &get_self_param () const
+  const Param &get_self_param () const
   {
 rust_assert (has_self_param ());
-return function_params[0];
+return *function_params[0];
   }
 
   // ExternalItem::node_id is same as Stmt::node_id
diff --git a/gcc/rust/checks/errors/rust-ast-validation.cc 
b/gcc/rust/checks/errors/rust-ast-validation.cc
index d1edb890ae61..d58920878893 100644
--- a/gcc/rust/checks/errors/rust-ast-validation.cc
+++ b/gcc/rust/checks/errors/rust-ast-validation.cc
@@ -100,7 +100,7 @@ ASTValidation::visit (AST::Function &function)
   && context.back () != Context::INHERENT_IMPL
   && function.has_self_param ())
 rust_error_at (
-  function.get_self_param ()->get_locus (),
+  function.get_self_param ().get_locus (),
   "% parameter is only allowed in associated functions");
 
   if (function.is_external ())
diff --git a/gcc/rust/hir/rust-ast-lower-base.cc 
b/gcc/rust/hir/rust-ast-lower-base.cc
index ff6ef25a3488..652530ae7a50 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -648,31 +648,31 @@ ASTLoweringBase::lower_generic_args (AST::GenericArgs 
&args)
 }
 
 HIR::SelfParam
-ASTLoweringBase::lower_self (std::unique_ptr ¶m)
+ASTLoweringBase::lower_self (AST::Param ¶m)
 {
-  rust_assert (param->is_self ());
+  rust_assert (param.is_self ());
 
-  auto self = static_cast (param.get ());
+  auto self = static_cast (param);
   auto crate_num = mappings->get_current_crate ();
-  Analysis::NodeMapping mapping (crate_num, self->get_node_id (),
+  Analysis::NodeMapping mapping (crate_num, self.get_node_id (),
 mappings->get_next_hir_id (crate_num),
 mappings->get_next_localdef_id (crate_num));
 
-  if (self->has_type ())
+  if (self.has_type ())
 {
-  HIR::Type *type = ASTLoweringType::translate (self->get_type ().get ());
+  HIR::Type *type = ASTLoweringType::translate (self.get_type ().get ());
   return HIR::SelfParam (mapping, std::unique_ptr (type),
-self->get_is_mut (), self->get_locus ());
+self.get_is_mut (), self.get_locus ());
 }
-  else if (!self->get_has_ref ())
+  else if (!self.get_has_ref ())
 {
   return HIR::SelfParam (mapping, std::unique_ptr (nullptr),
-self->get_is_mut (), self->get_locus ());
+self.get_is_mut (), self.get_locus ());
 }
 
-  AST::Lifetime l = self->get_lifetime ();
-  return HIR::SelfParam (mapping, lower_lifetime (l), self->get_is_mut (),
-self->get_locus ());
+  AST::Lifetime l = self.get_lifetime ();
+  return HIR::SelfParam (mapping, lower_lifetime (l), self.get_is_mut (),
+self.get_locus ());
 }
 
 HIR::Type *
diff --git a/gcc/rust/hir/rust-ast-lower-base.h 
b/gcc/rust/hir/rust-ast-lower-base.h
index c19e9c03b5f2..c01c7c857678 100644
--- a/gcc/rust/hir/rust-ast-lower-base.h
+++ b/gcc/rust/hir/rust-ast-lower-bas

[gcc r15-2524] gccrs: macro: Use MacroInvocation's node_id in ExternalItem constructor.

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:f15d40d237f8dd248241df8ee324eb0e7cb825a5

commit r15-2524-gf15d40d237f8dd248241df8ee324eb0e7cb825a5
Author: Arthur Cohen 
Date:   Tue Mar 19 13:12:20 2024 +0100

gccrs: macro: Use MacroInvocation's node_id in ExternalItem constructor.

gcc/rust/ChangeLog:

* ast/rust-macro.h: Use proper node id instead of the one in the 
base
Expr class - which is uninitialized.

Diff:
---
 gcc/rust/ast/rust-macro.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h
index 5b9ff3f22c88..507e595e3790 100644
--- a/gcc/rust/ast/rust-macro.h
+++ b/gcc/rust/ast/rust-macro.h
@@ -727,7 +727,7 @@ private:
   {}
 
   MacroInvocation (const MacroInvocation &other)
-: TraitItem (other.locus), ExternalItem (Expr::node_id),
+: TraitItem (other.locus), ExternalItem (other.node_id),
   outer_attrs (other.outer_attrs), locus (other.locus),
   node_id (other.node_id), invoc_data (other.invoc_data),
   is_semi_coloned (other.is_semi_coloned), kind (other.kind),


[gcc r15-2525] gccrs: format-args: Add base for expanding FormatArgs nodes

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:5ed71ad2a2f394afc9d66aee0c30476879292cab

commit r15-2525-g5ed71ad2a2f394afc9d66aee0c30476879292cab
Author: Arthur Cohen 
Date:   Thu Feb 29 13:01:32 2024 +0100

gccrs: format-args: Add base for expanding FormatArgs nodes

gcc/rust/ChangeLog:

* Make-lang.in: Add new object.
* hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Remove calls 
to
FormatArgsLowering.
* expand/rust-expand-format-args.cc: New file.
* expand/rust-expand-format-args.h: New file.

Diff:
---
 gcc/rust/Make-lang.in  |  1 +
 gcc/rust/expand/rust-expand-format-args.cc | 43 ++
 gcc/rust/expand/rust-expand-format-args.h  | 32 ++
 gcc/rust/hir/rust-ast-lower-expr.cc|  4 ---
 4 files changed, 76 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index f166b02340d7..cbb9da0fe43b 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -205,6 +205,7 @@ GRS_OBJS = \
 rust/rust-unicode.o \
 rust/rust-punycode.o \
rust/rust-lang-item.o \
+   rust/rust-expand-format-args.o \
 $(END)
 # removed object files from here
 
diff --git a/gcc/rust/expand/rust-expand-format-args.cc 
b/gcc/rust/expand/rust-expand-format-args.cc
new file mode 100644
index ..52249cb17e3d
--- /dev/null
+++ b/gcc/rust/expand/rust-expand-format-args.cc
@@ -0,0 +1,43 @@
+// Copyright (C) 2024 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-expand-format-args.h"
+#include "rust-builtin-ast-nodes.h"
+
+namespace Rust {
+
+tl::optional
+expand_format_args (AST::FormatArgs &fmt)
+{
+  for (const auto &node : fmt.get_template ().get_pieces ())
+{
+  switch (node.tag)
+   {
+   case Fmt::Piece::Tag::String:
+ // rust_debug ("[ARTHUR]: %s", node.string._0.c_str ());
+
+   case Fmt::Piece::Tag::NextArgument:
+ rust_debug ("[ARTHUR]: NextArgument");
+ break;
+   }
+}
+
+  return tl::nullopt;
+}
+
+} // namespace Rust
diff --git a/gcc/rust/expand/rust-expand-format-args.h 
b/gcc/rust/expand/rust-expand-format-args.h
new file mode 100644
index ..1481f3605ed8
--- /dev/null
+++ b/gcc/rust/expand/rust-expand-format-args.h
@@ -0,0 +1,32 @@
+// Copyright (C) 2024 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_EXPAND_FORMAT_ARGS_H
+#define RUST_EXPAND_FORMAT_ARGS_H
+
+#include "optional.h"
+#include "rust-ast-fragment.h"
+
+namespace Rust {
+
+tl::optional
+expand_format_args (AST::FormatArgs &fmt);
+
+} // namespace Rust
+
+#endif //! RUST_EXPAND_FORMAT_ARGS_H
diff --git a/gcc/rust/hir/rust-ast-lower-expr.cc 
b/gcc/rust/hir/rust-ast-lower-expr.cc
index 6944db9b9ccf..c414643bb915 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.cc
+++ b/gcc/rust/hir/rust-ast-lower-expr.cc
@@ -19,7 +19,6 @@
 #include "rust-ast-lower-expr.h"
 #include "rust-ast-lower-base.h"
 #include "rust-ast-lower-block.h"
-#include "rust-ast-lower-format-args.h"
 #include "rust-ast-lower-struct-field-expr.h"
 #include "rust-ast-lower-pattern.h"
 #include "rust-ast-lower-type.h"
@@ -824,9 +823,6 @@ ASTLoweringExpr::visit (AST::ClosureExprInnerTyped &expr)
 void
 ASTLoweringExpr::visit (AST::FormatArgs &fmt)
 {
-  // Lowering FormatArgs is complex, and this file is already very long
-  translated = FormatArgsLowering ().go (fmt);
-
   rust_sorry_at (fmt.get_locus (),
 "FormatArgs lowering is not implemented yet");
 }


[gcc r15-2526] gccrs: format-args: Start storing string in Rust memory

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:9b540c4299a6567d0e7642a4664dc76291dc8cbc

commit r15-2526-g9b540c4299a6567d0e7642a4664dc76291dc8cbc
Author: Arthur Cohen 
Date:   Thu Feb 22 16:26:40 2024 +0100

gccrs: format-args: Start storing string in Rust memory

gcc/rust/ChangeLog:

* ast/rust-fmt.cc (ffi::RustHamster::to_string): New.
(Pieces::collect): Adapt to use new handle API.
(Pieces::~Pieces): Likewise.
(Pieces::Pieces): Likewise.
(Pieces::operator=): Likewise.
* ast/rust-fmt.h (struct RustString): Add members.
(struct FormatArgsHandle): New.
(clone_pieces): Adapt for new FFI API.
(destroy_pieces): Likewise.
(struct Pieces): Store new FormatArgsHandle type.
* expand/rust-expand-format-args.cc (expand_format_args): Use proper
namespace.
* resolve/rust-ast-resolve-base.cc (ResolverBase::visit): FormatArgs
nodes are already resolved, so do nothing.

libgrust/ChangeLog:

* libformat_parser/src/lib.rs: Use new Handle struct and expose it.

Diff:
---
 gcc/rust/ast/rust-fmt.cc   |  32 +
 gcc/rust/ast/rust-fmt.h|  46 +
 gcc/rust/expand/rust-expand-format-args.cc |   4 +-
 gcc/rust/resolve/rust-ast-resolve-base.cc  |   5 +-
 libgrust/libformat_parser/src/lib.rs   | 105 ++---
 5 files changed, 133 insertions(+), 59 deletions(-)

diff --git a/gcc/rust/ast/rust-fmt.cc b/gcc/rust/ast/rust-fmt.cc
index b82e089fc41d..fda02e530fd1 100644
--- a/gcc/rust/ast/rust-fmt.cc
+++ b/gcc/rust/ast/rust-fmt.cc
@@ -22,44 +22,48 @@
 namespace Rust {
 namespace Fmt {
 
+std::string
+ffi::RustHamster::to_string () const
+{
+  return std::string (ptr, len);
+}
+
 Pieces
-Pieces::collect (std::string &&to_parse, bool append_newline)
+Pieces::collect (const std::string &to_parse, bool append_newline)
 {
-  auto piece_slice = collect_pieces (to_parse.c_str (), append_newline);
+  auto handle = ffi::collect_pieces (to_parse.c_str (), append_newline);
 
   // this performs multiple copies, can we avoid them maybe?
   // TODO: Instead of just creating a vec of, basically, `ffi::Piece`s, we
   // should transform them into the proper C++ type which we can work with. so
   // transform all the strings into C++ strings? all the Option into
   // tl::optional?
-  auto pieces = std::vector (piece_slice.base_ptr,
-   piece_slice.base_ptr + piece_slice.len);
+  auto pieces_vector = std::vector (handle.piece_slice.base_ptr,
+   handle.piece_slice.base_ptr
+ + handle.piece_slice.len);
 
-  return Pieces (std::move (pieces), piece_slice, std::move (to_parse));
+  return Pieces (handle, std::move (pieces_vector));
 }
 
-Pieces::~Pieces () { destroy_pieces (slice); }
+Pieces::~Pieces () { ffi::destroy_pieces (handle); }
 
-Pieces::Pieces (const Pieces &other)
-  : pieces_vector (other.pieces_vector), to_parse (other.to_parse)
+Pieces::Pieces (const Pieces &other) : pieces_vector (other.pieces_vector)
 {
-  slice = clone_pieces (other.slice.base_ptr, other.slice.len, 
other.slice.cap);
+  handle = ffi::clone_pieces (other.handle);
 }
 
 Pieces &
 Pieces::operator= (const Pieces &other)
 {
-  slice = clone_pieces (other.slice.base_ptr, other.slice.len, 
other.slice.cap);
-  to_parse = other.to_parse;
+  handle = ffi::clone_pieces (other.handle);
+  pieces_vector = other.pieces_vector;
 
   return *this;
 }
 
 Pieces::Pieces (Pieces &&other)
   : pieces_vector (std::move (other.pieces_vector)),
-slice (
-  clone_pieces (other.slice.base_ptr, other.slice.len, other.slice.cap)),
-to_parse (std::move (other.to_parse))
+handle (clone_pieces (other.handle))
 {}
 
 } // namespace Fmt
diff --git a/gcc/rust/ast/rust-fmt.h b/gcc/rust/ast/rust-fmt.h
index ba412f9958c5..6a0c116b841b 100644
--- a/gcc/rust/ast/rust-fmt.h
+++ b/gcc/rust/ast/rust-fmt.h
@@ -20,15 +20,21 @@
 #define RUST_FMT_H
 
 #include "rust-system.h"
+#include 
 
 // FIXME: How to encode Option?
 
 namespace Rust {
 namespace Fmt {
 
+namespace ffi {
+
 struct RustHamster
 {
-  // hehe
+  const char *ptr;
+  size_t len;
+
+  std::string to_string () const;
 };
 
 /// Enum of alignments which are supported.
@@ -240,21 +246,36 @@ struct PieceSlice
   size_t cap;
 };
 
+struct RustString
+{
+  const unsigned char *ptr;
+  size_t len;
+  size_t cap;
+};
+
+struct FormatArgsHandle
+{
+  PieceSlice piece_slice;
+  RustString rust_string;
+};
+
 extern "C" {
 
-PieceSlice
+FormatArgsHandle
 collect_pieces (const char *input, bool append_newline);
 
-PieceSlice
-clone_pieces (const Piece *base_ptr, size_t len, size_t cap);
+FormatArgsHandle
+clone_pieces (const FormatArgsHandle &);
 
-void destroy_pieces (PieceSlice);
+void destroy_pieces (FormatArgsHandle);
 
 } // extern "C"
 
+} // namespace ffi
+
 s

[gcc r15-2527] gccrs: format-args: Add basic expansion of unnamed Display::fmt arguments.

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:444b41bf06c36af3f8659a5057dae454aac90156

commit r15-2527-g444b41bf06c36af3f8659a5057dae454aac90156
Author: Arthur Cohen 
Date:   Thu Feb 29 14:53:05 2024 +0100

gccrs: format-args: Add basic expansion of unnamed Display::fmt arguments.

gcc/rust/ChangeLog:

* ast/rust-ast-builder.h: Rename AST::AstBuilder -> AST::Builder
* ast/rust-ast-builder.cc: Likewise.
* expand/rust-derive.cc: Use new AST::Builder name.
* expand/rust-derive.h: Likewise.
* ast/rust-builtin-ast-nodes.h: Add required getters.
* expand/rust-expand-format-args.cc (format_arg): New.
(get_trait_name): New.
(expand_format_args): Properly expand basic format_args!() 
invocations.
* expand/rust-expand-format-args.h (expand_format_args): Fix 
signature.
* expand/rust-macro-builtins.cc (MacroBuiltin::format_args_handler):
Call into expand_format_args().

Diff:
---
 gcc/rust/ast/rust-ast-builder.cc   |  66 --
 gcc/rust/ast/rust-ast-builder.h|  51 +-
 gcc/rust/ast/rust-builtin-ast-nodes.h  |   5 ++
 gcc/rust/expand/rust-derive.cc |   2 +-
 gcc/rust/expand/rust-derive.h  |   2 +-
 gcc/rust/expand/rust-expand-format-args.cc | 107 +++--
 gcc/rust/expand/rust-expand-format-args.h  |   5 +-
 gcc/rust/expand/rust-macro-builtins.cc |  23 +--
 8 files changed, 205 insertions(+), 56 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index 0d5218c6381d..1138d3dc2b2c 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -17,53 +17,73 @@
 // .
 
 #include "rust-ast-builder.h"
+#include "rust-ast-full-decls.h"
 #include "rust-ast-full.h"
+#include "rust-expr.h"
+#include "rust-token.h"
+#include "rust-make-unique.h"
 
 namespace Rust {
 namespace AST {
 
 std::unique_ptr
-AstBuilder::call (std::unique_ptr &&path,
- std::vector> &&args)
+Builder::literal_string (std::string &&content) const
+{
+  return std::unique_ptr (
+new AST::LiteralExpr (std::move (content), Literal::LitType::STRING,
+ PrimitiveCoreType::CORETYPE_STR, {}, loc));
+}
+
+std::unique_ptr
+Builder::call (std::unique_ptr &&path,
+  std::vector> &&args) const
 {
   return std::unique_ptr (
 new CallExpr (std::move (path), std::move (args), {}, loc));
 }
 
 std::unique_ptr
-AstBuilder::identifier (std::string name)
+Builder::array (std::vector> &&members) const
+{
+  auto elts = Rust::make_unique (std::move (members), loc);
+
+  return std::unique_ptr (new ArrayExpr (std::move (elts), {}, {}, loc));
+}
+
+std::unique_ptr
+Builder::identifier (std::string name) const
 {
   return std::unique_ptr (new IdentifierExpr (name, {}, loc));
 }
 
 std::unique_ptr
-AstBuilder::tuple_idx (std::string receiver, int idx)
+Builder::tuple_idx (std::string receiver, int idx) const
 {
   return std::unique_ptr (
 new TupleIndexExpr (identifier (receiver), idx, {}, loc));
 }
 
 FunctionQualifiers
-AstBuilder::fn_qualifiers ()
+Builder::fn_qualifiers () const
 {
   return FunctionQualifiers (loc, Async::No, Const::No, Unsafety::Normal);
 }
 
 PathExprSegment
-AstBuilder::path_segment (std::string seg)
+Builder::path_segment (std::string seg) const
 {
   return PathExprSegment (PathIdentSegment (seg, loc), loc);
 }
 
 std::unique_ptr
-AstBuilder::type_path_segment (std::string seg)
+Builder::type_path_segment (std::string seg) const
 {
   return std::unique_ptr (
 new TypePathSegment (seg, false, loc));
 }
 
 std::unique_ptr
-AstBuilder::single_type_path (std::string type)
+Builder::single_type_path (std::string type) const
 {
   auto segments = std::vector> ();
   segments.emplace_back (type_path_segment (type));
@@ -72,7 +92,7 @@ AstBuilder::single_type_path (std::string type)
 }
 
 PathInExpression
-AstBuilder::path_in_expression (std::vector &&segments)
+Builder::path_in_expression (std::vector &&segments) const
 {
   auto path_segments = std::vector ();
   for (auto &seg : segments)
@@ -82,8 +102,8 @@ AstBuilder::path_in_expression (std::vector 
&&segments)
 }
 
 std::unique_ptr
-AstBuilder::block (std::vector> &&stmts,
-  std::unique_ptr &&tail_expr)
+Builder::block (std::vector> &&stmts,
+   std::unique_ptr &&tail_expr) const
 {
   return std::unique_ptr (new BlockExpr (std::move (stmts),
   std::move (tail_expr), {}, {},
@@ -91,8 +111,8 @@ AstBuilder::block (std::vector> 
&&stmts,
 }
 
 std::unique_ptr
-AstBuilder::let (std::unique_ptr pattern, std::unique_ptr type,
-std::unique_ptr init)
+Builder::let (std::unique_ptr pattern, std::unique_ptr type,
+ std::unique_ptr init) const
 {
   return std::unique_ptr (new LetStmt (std::move (pattern),

[gcc r15-2528] gccrs: format-args: Add basic test case

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:d0e8bf92395be8c4b5f059f93006655b63e1367e

commit r15-2528-gd0e8bf92395be8c4b5f059f93006655b63e1367e
Author: Arthur Cohen 
Date:   Thu Feb 29 16:09:23 2024 +0100

gccrs: format-args: Add basic test case

gcc/testsuite/ChangeLog:

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

Diff:
---
 .../rust/compile/format_args_basic_expansion.rs| 47 ++
 1 file changed, 47 insertions(+)

diff --git a/gcc/testsuite/rust/compile/format_args_basic_expansion.rs 
b/gcc/testsuite/rust/compile/format_args_basic_expansion.rs
new file mode 100644
index ..40bcd3c1433e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/format_args_basic_expansion.rs
@@ -0,0 +1,47 @@
+#![feature(rustc_attrs)]
+
+#[rustc_builtin_macro]
+macro_rules! format_args {
+() => {};
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+pub mod core {
+pub mod fmt {
+pub struct Formatter;
+pub struct Result;
+
+pub struct Arguments<'a>;
+
+impl<'a> Arguments<'a> {
+pub fn new_v1(_: &'a [&'static str], _: &'a [ArgumentV1<'a>]) -> 
Arguments<'a> {
+Arguments
+}
+}
+
+pub struct ArgumentV1<'a>;
+
+impl<'a> ArgumentV1<'a> {
+pub fn new<'b, T>(_: &'b T, _: fn(&T, &mut Formatter) -> Result) 
-> ArgumentV1 {
+ArgumentV1
+}
+}
+
+pub trait Display {
+fn fmt(&self, _: &mut Formatter) -> Result;
+}
+
+impl Display for i32 {
+fn fmt(&self, _: &mut Formatter) -> Result {
+// { dg-warning "unused name .self." "" { target *-*-* } .-1 }
+Result
+}
+}
+}
+}
+
+fn main() {
+let _formatted = format_args!("hello {}", 15);
+}


[gcc r15-2529] gccrs: format-args: Only pass the format string to the parser.

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:302ad5de0792978683f3599e13fdf0a75dacc051

commit r15-2529-g302ad5de0792978683f3599e13fdf0a75dacc051
Author: Arthur Cohen 
Date:   Thu Mar 7 14:57:54 2024 +0100

gccrs: format-args: Only pass the format string to the parser.

This fixes an issue we had where the generated code ended with more static
pieces than its rustc counterpart.

gcc/rust/ChangeLog:

* expand/rust-macro-builtins.cc (struct FormatArgsInput): Store the 
format_str
as a string instead of an AST::Expr.
(format_args_parse_arguments): Transform format_expr into a format 
string
properly - add note for handling eager macro invocations later on.
(MacroBuiltin::format_args_handler): Parse the correct input, append
newline to format_str if necessary.

Diff:
---
 gcc/rust/expand/rust-macro-builtins.cc | 37 --
 1 file changed, 22 insertions(+), 15 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-builtins.cc 
b/gcc/rust/expand/rust-macro-builtins.cc
index 112713a4f976..a33a57752dad 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -18,6 +18,7 @@
 
 #include "expected.h"
 #include "libproc_macro_internal/tokenstream.h"
+#include "optional.h"
 #include "rust-ast-full-decls.h"
 #include "rust-builtin-ast-nodes.h"
 #include "rust-expand-format-args.h"
@@ -961,7 +962,7 @@ MacroBuiltin::stringify_handler (location_t invoc_locus,
 
 struct FormatArgsInput
 {
-  std::unique_ptr format_str;
+  std::string format_str;
   AST::FormatArguments args;
   // bool is_literal?
 };
@@ -985,12 +986,18 @@ format_args_parse_arguments (AST::MacroInvocData &invoc)
 
   auto args = AST::FormatArguments ();
   auto last_token_id = macro_end_token (invoc.get_delim_tok_tree (), parser);
-  std::unique_ptr format_str = nullptr;
+  std::unique_ptr format_expr = nullptr;
 
   // TODO: Handle the case where we're not parsing a string literal (macro
   // invocation for e.g.)
   if (parser.peek_current_token ()->get_id () == STRING_LITERAL)
-format_str = parser.parse_literal_expr ();
+format_expr = parser.parse_literal_expr ();
+
+  // TODO(Arthur): Clean this up - if we haven't parsed a string literal but a
+  // macro invocation, what do we do here? return a tl::unexpected?
+  auto format_str = static_cast (*format_expr)
+ .get_literal ()
+ .as_string ();
 
   // TODO: Allow implicit captures ONLY if the the first arg is a string 
literal
   // and not a macro invocation
@@ -1053,6 +1060,13 @@ MacroBuiltin::format_args_handler (location_t 
invoc_locus,
 {
   auto input = format_args_parse_arguments (invoc);
 
+  if (!input)
+{
+  rust_error_at (invoc_locus,
+"could not parse arguments to %");
+  return tl::nullopt;
+}
+
   // TODO(Arthur): We need to handle this
   // // if it is not a literal, it's an eager macro invocation - return it
   // if (!fmt_expr->is_literal ())
@@ -1080,20 +1094,13 @@ MacroBuiltin::format_args_handler (location_t 
invoc_locus,
   // rust_unreachable ();
   //   }
 
-  // Remove the delimiters from the macro invocation:
-  // the invoc data for `format_args!(fmt, arg1, arg2)` is `(fmt, arg1, arg2)`,
-  // so we pop the front and back to remove the parentheses (or curly brackets,
-  // or brackets)
-  auto tokens = invoc.get_delim_tok_tree ().to_token_stream ();
-  tokens.erase (tokens.begin ());
-  tokens.pop_back ();
+  bool append_newline = nl == AST::FormatArgs::Newline::Yes;
 
-  std::stringstream stream;
-  for (const auto &tok : tokens)
-stream << tok->as_string () << ' ';
+  auto fmt_str = std::move (input->format_str);
+  if (append_newline)
+fmt_str += '\n';
 
-  auto append_newline = nl == AST::FormatArgs::Newline::Yes ? true : false;
-  auto pieces = Fmt::Pieces::collect (stream.str (), append_newline);
+  auto pieces = Fmt::Pieces::collect (fmt_str, append_newline);
 
   // TODO:
   // do the transformation into an AST::FormatArgs node


[gcc r15-2530] gccrs: TyTy: add common SubstitutionRef API

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:54d8f97ee172d8a7dd434d44fdbfbd1666de8b34

commit r15-2530-g54d8f97ee172d8a7dd434d44fdbfbd1666de8b34
Author: Jakub Dupak 
Date:   Fri Feb 2 12:11:45 2024 +0100

gccrs: TyTy: add common SubstitutionRef API

gcc/rust/ChangeLog:

* typecheck/rust-tyty-subst.cc (SubstitutionRef::get_arg_at):
Add unified API.

Signed-off-by: Jakub Dupak 

Diff:
---
 gcc/rust/typecheck/rust-tyty-subst.cc | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/gcc/rust/typecheck/rust-tyty-subst.cc 
b/gcc/rust/typecheck/rust-tyty-subst.cc
index 5a753566d48a..71d41d6f7960 100644
--- a/gcc/rust/typecheck/rust-tyty-subst.cc
+++ b/gcc/rust/typecheck/rust-tyty-subst.cc
@@ -589,6 +589,17 @@ SubstitutionRef::get_used_arguments () const
   return used_arguments;
 }
 
+tl::optional
+SubstitutionRef::get_arg_at (size_t i) const
+{
+  auto param_ty = get_substs ().at (i).get_param_ty ();
+  SubstitutionArg arg = SubstitutionArg::error ();
+  get_used_arguments ().get_argument_for_symbol (param_ty, &arg);
+  if (arg.is_error ())
+return tl::nullopt;
+  return arg;
+}
+
 const RegionConstraints &
 SubstitutionRef::get_region_constraints () const
 {


[gcc r15-2531] gccrs: TyTy: Variance analysis module

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:d8cd08d30e0d9bfa02f29493352bac041659df7f

commit r15-2531-gd8cd08d30e0d9bfa02f29493352bac041659df7f
Author: Jakub Dupak 
Date:   Fri Feb 2 14:09:38 2024 +0100

gccrs: TyTy: Variance analysis module

gcc/rust/ChangeLog:

* Make-lang.in: Add new .cc file.
* rust-session-manager.cc (Session::compile_crate): Run
analysis.
* typecheck/rust-tyty-variance-analysis-private.h: New file.
* typecheck/rust-tyty-variance-analysis.cc: New file.
* typecheck/rust-tyty-variance-analysis.h: New file.
* typecheck/rust-typecheck-context.cc
(TypeCheckContext::get_variance_analysis_ctx):
Variance analysis context.
* typecheck/rust-hir-type-check.h (TypeCheckItem::visit):
Variance analysis context.

Signed-off-by: Jakub Dupak 

Diff:
---
 gcc/rust/Make-lang.in  |   1 +
 gcc/rust/rust-session-manager.cc   |   3 +
 gcc/rust/typecheck/rust-hir-type-check.h   |   6 +
 gcc/rust/typecheck/rust-typecheck-context.cc   |   6 +
 .../rust-tyty-variance-analysis-private.h  | 304 
 gcc/rust/typecheck/rust-tyty-variance-analysis.cc  | 541 +
 gcc/rust/typecheck/rust-tyty-variance-analysis.h   | 114 +
 7 files changed, 975 insertions(+)

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index cbb9da0fe43b..67df843349f2 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -147,6 +147,7 @@ GRS_OBJS = \
 rust/rust-tyty-util.o \
 rust/rust-tyty-call.o \
 rust/rust-tyty-subst.o \
+rust/rust-tyty-variance-analysis.o \
 rust/rust-typecheck-context.o \
 rust/rust-tyty-bounds.o \
 rust/rust-hir-trait-resolve.o \
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 62c47b2e6de3..ea99d019f64f 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -48,6 +48,7 @@
 #include "rust-attribute-values.h"
 #include "rust-borrow-checker.h"
 #include "rust-ast-validation.h"
+#include "rust-tyty-variance-analysis.h"
 
 #include "input.h"
 #include "selftest.h"
@@ -652,6 +653,8 @@ Session::compile_crate (const char *filename)
   // type resolve
   Resolver::TypeResolution::Resolve (hir);
 
+  Resolver::TypeCheckContext::get ()->get_variance_analysis_ctx ().solve ();
+
   if (saw_errors ())
 return;
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check.h 
b/gcc/rust/typecheck/rust-hir-type-check.h
index 52c84fc44354..c32fa4e84871 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.h
+++ b/gcc/rust/typecheck/rust-hir-type-check.h
@@ -24,6 +24,7 @@
 #include "rust-hir-trait-reference.h"
 #include "rust-autoderef.h"
 #include "rust-tyty-region.h"
+#include "rust-tyty-variance-analysis.h"
 
 #include 
 
@@ -233,6 +234,8 @@ public:
 
   void compute_inference_variables (bool error);
 
+  TyTy::VarianceAnalysis::CrateCtx &get_variance_analysis_ctx ();
+
 private:
   TypeCheckContext ();
 
@@ -272,6 +275,9 @@ private:
   std::set querys_in_progress;
   std::set trait_queries_in_progress;
 
+  // variance analysis
+  TyTy::VarianceAnalysis::CrateCtx variance_analysis_ctx;
+
   /** Used to resolve (interned) lifetime names to their bounding scope. */
   class LifetimeResolver
   {
diff --git a/gcc/rust/typecheck/rust-typecheck-context.cc 
b/gcc/rust/typecheck/rust-typecheck-context.cc
index 9059e0261b32..ab0093a273b4 100644
--- a/gcc/rust/typecheck/rust-typecheck-context.cc
+++ b/gcc/rust/typecheck/rust-typecheck-context.cc
@@ -617,6 +617,12 @@ TypeCheckContext::compute_inference_variables (bool error)
   });
 }
 
+TyTy::VarianceAnalysis::CrateCtx &
+TypeCheckContext::get_variance_analysis_ctx ()
+{
+  return variance_analysis_ctx;
+}
+
 // TypeCheckContextItem
 
 TypeCheckContextItem::Item::Item (HIR::Function *item) : item (item) {}
diff --git a/gcc/rust/typecheck/rust-tyty-variance-analysis-private.h 
b/gcc/rust/typecheck/rust-tyty-variance-analysis-private.h
new file mode 100644
index ..ab8c039238eb
--- /dev/null
+++ b/gcc/rust/typecheck/rust-tyty-variance-analysis-private.h
@@ -0,0 +1,304 @@
+#ifndef RUST_TYTY_VARIANCE_ANALYSIS_PRIVATE_H
+#define RUST_TYTY_VARIANCE_ANALYSIS_PRIVATE_H
+
+#include "rust-tyty-variance-analysis.h"
+
+#include "rust-tyty-visitor.h"
+
+namespace Rust {
+namespace TyTy {
+namespace VarianceAnalysis {
+
+using SolutionIndex = uint32_t;
+
+/** Term descibing variance relations. */
+struct Term
+{
+  enum Kind : uint8_t
+  {
+CONST,
+REF,
+TRANSFORM,
+  };
+
+  Kind kind;
+  union
+  {
+struct
+{
+  Term *lhs;
+  Term *rhs;
+} transform;
+SolutionIndex ref;
+Variance const_val;
+  };
+
+  Term () {}
+
+  Term (Variance variance) : kind (CONST), const_val (variance) {}
+
+  WARN_UNUSED_RESULT bool is_const () const { return kind == CONST; }
+
+  static Term make_ref (SolutionIndex index);
+
+  static Term ma

[gcc r15-2532] gccrs: TyTy: Collect variance info from types

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:a7b1a89da13b70fa81e12a4dc873c96ce38e1327

commit r15-2532-ga7b1a89da13b70fa81e12a4dc873c96ce38e1327
Author: Jakub Dupak 
Date:   Fri Feb 2 14:12:13 2024 +0100

gccrs: TyTy: Collect variance info from types

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit):
Collect variance info from types.

Signed-off-by: Jakub Dupak 

Diff:
---
 gcc/rust/typecheck/rust-hir-type-check-item.cc | 17 +
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc 
b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index 16b4906a3569..4bbd28021a02 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -25,6 +25,7 @@
 #include "rust-hir-trait-resolve.h"
 #include "rust-substitution-mapper.h"
 #include "rust-type-util.h"
+#include "rust-tyty-variance-analysis.h"
 
 namespace Rust {
 namespace Resolver {
@@ -204,7 +205,7 @@ TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
   TyTy::ADTType::ReprOptions repr
 = parse_repr_options (attrs, struct_decl.get_locus ());
 
-  TyTy::BaseType *type = new TyTy::ADTType (
+  auto *type = new TyTy::ADTType (
 struct_decl.get_mappings ().get_hirid (), mappings->get_next_hir_id (),
 struct_decl.get_identifier ().as_string (), ident,
 TyTy::ADTType::ADTKind::TUPLE_STRUCT, std::move (variants),
@@ -215,6 +216,8 @@ TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
 
   context->insert_type (struct_decl.get_mappings (), type);
   infered = type;
+
+  context->get_variance_analysis_ctx ().add_type_constraints (*type);
 }
 
 void
@@ -266,7 +269,7 @@ TypeCheckItem::visit (HIR::StructStruct &struct_decl)
   TyTy::ADTType::ReprOptions repr
 = parse_repr_options (attrs, struct_decl.get_locus ());
 
-  TyTy::BaseType *type = new TyTy::ADTType (
+  auto *type = new TyTy::ADTType (
 struct_decl.get_mappings ().get_hirid (), mappings->get_next_hir_id (),
 struct_decl.get_identifier ().as_string (), ident,
 TyTy::ADTType::ADTKind::STRUCT_STRUCT, std::move (variants),
@@ -277,6 +280,8 @@ TypeCheckItem::visit (HIR::StructStruct &struct_decl)
 
   context->insert_type (struct_decl.get_mappings (), type);
   infered = type;
+
+  context->get_variance_analysis_ctx ().add_type_constraints (*type);
 }
 
 void
@@ -307,7 +312,7 @@ TypeCheckItem::visit (HIR::Enum &enum_decl)
   RustIdent ident{*canonical_path, enum_decl.get_locus ()};
 
   // multi variant ADT
-  TyTy::BaseType *type
+  auto *type
 = new TyTy::ADTType (enum_decl.get_mappings ().get_hirid (),
 mappings->get_next_hir_id (),
 enum_decl.get_identifier ().as_string (), ident,
@@ -316,6 +321,8 @@ TypeCheckItem::visit (HIR::Enum &enum_decl)
 
   context->insert_type (enum_decl.get_mappings (), type);
   infered = type;
+
+  context->get_variance_analysis_ctx ().add_type_constraints (*type);
 }
 
 void
@@ -363,7 +370,7 @@ TypeCheckItem::visit (HIR::Union &union_decl)
  TyTy::VariantDef::VariantType::STRUCT, nullptr,
  std::move (fields)));
 
-  TyTy::BaseType *type
+  auto *type
 = new TyTy::ADTType (union_decl.get_mappings ().get_hirid (),
 mappings->get_next_hir_id (),
 union_decl.get_identifier ().as_string (), ident,
@@ -372,6 +379,8 @@ TypeCheckItem::visit (HIR::Union &union_decl)
 
   context->insert_type (union_decl.get_mappings (), type);
   infered = type;
+
+  context->get_variance_analysis_ctx ().add_type_constraints (*type);
 }
 
 void


[gcc r15-2533] gccrs: Store visibility properly in ExternalTypeItem

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:8c0b6506cb42f2ba5fcea63fbc56994486d3c3ab

commit r15-2533-g8c0b6506cb42f2ba5fcea63fbc56994486d3c3ab
Author: jjasmine 
Date:   Sat Mar 9 17:16:34 2024 -0500

gccrs: Store visibility properly in ExternalTypeItem

Fix issue 2897

gcc/rust/ChangeLog:

* hir/rust-ast-lower-extern.h: Add translate_visiblity
* hir/tree/rust-hir-item.h: Fix constructor of ExternalTypeItem

Diff:
---
 gcc/rust/hir/rust-ast-lower-extern.h | 4 +++-
 gcc/rust/hir/tree/rust-hir-item.h| 4 ++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/hir/rust-ast-lower-extern.h 
b/gcc/rust/hir/rust-ast-lower-extern.h
index e92acdc44a1f..bd889e244b01 100644
--- a/gcc/rust/hir/rust-ast-lower-extern.h
+++ b/gcc/rust/hir/rust-ast-lower-extern.h
@@ -133,8 +133,10 @@ public:
   mappings->get_next_hir_id (crate_num),
   mappings->get_next_localdef_id (crate_num));
 
+HIR::Visibility vis = translate_visibility (type.get_visibility ());
+
 translated = new HIR::ExternalTypeItem (mapping, type.get_identifier (),
-   type.get_locus ());
+   vis, type.get_locus ());
   }
 
 private:
diff --git a/gcc/rust/hir/tree/rust-hir-item.h 
b/gcc/rust/hir/tree/rust-hir-item.h
index 3bd0102d4dcf..7e0c8c6ffca9 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -3154,9 +3154,9 @@ class ExternalTypeItem : public ExternalItem
 {
 public:
   ExternalTypeItem (Analysis::NodeMapping mappings, Identifier item_name,
-   location_t locus)
+   Visibility vis, location_t locus)
 : ExternalItem (std::move (mappings), std::move (item_name),
-   Visibility (Visibility::PRIVATE),
+   Visibility (std::move (vis)),
/* FIXME: Is that correct? */
{}, locus)
   {}


[gcc r15-2534] gccrs: Fix typo

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:01c16d734b2883c648341cf5c0fdc41cc87bf2ba

commit r15-2534-g01c16d734b2883c648341cf5c0fdc41cc87bf2ba
Author: Guillaume Gomez 
Date:   Tue Mar 5 20:24:30 2024 +0100

gccrs: Fix typo

gcc/rust/ChangeLog:

* expand/rust-derive.cc (DeriveVisitor::derive): Fix typo

Diff:
---
 gcc/rust/expand/rust-derive.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/rust/expand/rust-derive.cc b/gcc/rust/expand/rust-derive.cc
index 4177004eccf2..e6778fea9729 100644
--- a/gcc/rust/expand/rust-derive.cc
+++ b/gcc/rust/expand/rust-derive.cc
@@ -45,7 +45,7 @@ DeriveVisitor::derive (Item &item, const Attribute &attr,
 case BuiltinMacro::PartialOrd:
 case BuiltinMacro::Hash:
 default:
-  rust_sorry_at (attr.get_locus (), "uninmplemented builtin derive macro");
+  rust_sorry_at (attr.get_locus (), "unimplemented builtin derive macro");
   return nullptr;
 };
 }


[gcc r15-2536] gccrs: Placate clang-format re 'gcc/rust/lex/rust-lex.cc'

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:6e8b12530f1c0821de4b3d0d1d3ca7cefb55b65f

commit r15-2536-g6e8b12530f1c0821de4b3d0d1d3ca7cefb55b65f
Author: Thomas Schwinge 
Date:   Sun Mar 24 23:08:12 2024 +0100

gccrs: Placate clang-format re 'gcc/rust/lex/rust-lex.cc'

Reformat the upstream GCC commit 61644aea34c4623d16273ff705f8b8b1ff2d87f0
"gccrs: tokenize Unicode identifiers" change to 'gcc/rust/lex/rust-lex.cc'
to clang-format's liking.

gcc/rust/
* lex/rust-lex.cc (is_identifier_start): Placate clang-format.

Diff:
---
 gcc/rust/lex/rust-lex.cc | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/lex/rust-lex.cc b/gcc/rust/lex/rust-lex.cc
index bf6bf4c84466..9c2203160cd4 100644
--- a/gcc/rust/lex/rust-lex.cc
+++ b/gcc/rust/lex/rust-lex.cc
@@ -128,7 +128,8 @@ is_non_decimal_int_literal_separator (uint32_t character)
 bool
 is_identifier_start (uint32_t codepoint)
 {
-  return (cpp_check_xid_property (codepoint) & CPP_XID_START) || codepoint == 
'_';
+  return (cpp_check_xid_property (codepoint) & CPP_XID_START)
+|| codepoint == '_';
 }
 
 bool


[gcc r15-2535] gccrs: Split up rust-macro-builtins.cc

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:98e0a660e78298d232767f51a0ff9c794e66d1e1

commit r15-2535-g98e0a660e78298d232767f51a0ff9c794e66d1e1
Author: jjasmine 
Date:   Sun Feb 25 03:10:37 2024 -0800

gccrs: Split up rust-macro-builtins.cc

Fixes issue #2855

gcc/rust/ChangeLog:

* Make-lang.in: add new .o builds for new .cc files
* expand/rust-cfg-strip.h (RUST_CFG_STRIP_H): Add include guards
for rust-cfg-strip
* expand/rust-macro-builtins.cc (make_macro_path_str): moved to new 
respective files
(make_token): moved to new respective files
(make_string): moved to new respective files
(macro_end_token): moved to new respective files
(try_extract_string_literal_from_fragment): moved to new respective 
files
(try_expand_many_expr): moved to new respective files
(parse_single_string_literal): moved to new respective files
(source_relative_path): moved to new respective files
(load_file_bytes): moved to new respective files
(MacroBuiltin::assert_handler): moved to new respective files
(MacroBuiltin::file_handler): moved to new respective files
(MacroBuiltin::column_handler): moved to new respective files
(MacroBuiltin::include_bytes_handler): moved to new respective files
(MacroBuiltin::include_str_handler): moved to new respective files
(MacroBuiltin::compile_error_handler): moved to new respective files
(MacroBuiltin::concat_handler): moved to new respective files
(MacroBuiltin::env_handler): moved to new respective files
(MacroBuiltin::cfg_handler): moved to new respective files
(MacroBuiltin::include_handler): moved to new respective files
(MacroBuiltin::line_handler): moved to new respective files
(MacroBuiltin::stringify_handler): moved to new respective files
(struct FormatArgsInput): moved to new respective files
(struct FormatArgsParseError): moved to new respective files
(format_args_parse_arguments): moved to new respective files
(MacroBuiltin::format_args_handler): moved to new respective files
* expand/rust-macro-builtins.h (builtin_macro_from_string):
merge tl::optional from master
* expand/rust-macro-builtins-asm.cc: New file.
* expand/rust-macro-builtins-format-args.cc: New file.
* expand/rust-macro-builtins-helpers.cc: New file.
* expand/rust-macro-builtins-helpers.h: New file.
* expand/rust-macro-builtins-include.cc: New file.
* expand/rust-macro-builtins-location.cc: New file.
* expand/rust-macro-builtins-log-debug.cc: New file.
* expand/rust-macro-builtins-test-bench.cc: New file.
* expand/rust-macro-builtins-trait.cc: New file.
* expand/rust-macro-builtins-utility.cc: New file.

Diff:
---
 gcc/rust/Make-lang.in  |   9 +
 gcc/rust/expand/rust-cfg-strip.h   |   4 +
 gcc/rust/expand/rust-macro-builtins-asm.cc |  20 +
 gcc/rust/expand/rust-macro-builtins-format-args.cc | 192 
 gcc/rust/expand/rust-macro-builtins-helpers.cc | 284 ++
 gcc/rust/expand/rust-macro-builtins-helpers.h  |  90 ++
 gcc/rust/expand/rust-macro-builtins-include.cc | 249 ++
 gcc/rust/expand/rust-macro-builtins-location.cc|  61 ++
 gcc/rust/expand/rust-macro-builtins-log-debug.cc   |  31 +
 gcc/rust/expand/rust-macro-builtins-test-bench.cc  |  20 +
 gcc/rust/expand/rust-macro-builtins-trait.cc   |  20 +
 gcc/rust/expand/rust-macro-builtins-utility.cc | 294 ++
 gcc/rust/expand/rust-macro-builtins.cc | 981 +
 gcc/rust/expand/rust-macro-builtins.h  |  79 +-
 14 files changed, 1315 insertions(+), 1019 deletions(-)

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 67df843349f2..10af0814372e 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -102,6 +102,15 @@ GRS_OBJS = \
 rust/rust-proc-macro-invoc-lexer.o \
 rust/rust-macro-substitute-ctx.o \
 rust/rust-macro-builtins.o \
+rust/rust-macro-builtins-helpers.o \
+rust/rust-macro-builtins-asm.o \
+rust/rust-macro-builtins-trait.o \
+rust/rust-macro-builtins-utility.o \
+rust/rust-macro-builtins-log-debug.o \
+rust/rust-macro-builtins-test-bench.o \
+rust/rust-macro-builtins-format-args.o \
+rust/rust-macro-builtins-location.o \
+rust/rust-macro-builtins-include.o \
rust/rust-fmt.o \
 rust/rust-hir.o \
 rust/rust-hir-map.o \
diff --git a/gcc/rust/expand/rust-cfg-strip.h b/gcc/rust/expand/rust-cfg-strip.h
index 4a8e6041ff21..048cebdb9910 100644
--- a/gcc/rust/expand/rust-cfg-strip.h
+++ b/gcc/rust/expand/rust-cfg-strip.h
@@ -15,6 +15,8 @@
 // You should have received a copy of the GNU

[gcc r15-2537] gccrs: nr2.0: Add new ImmutableNameResolutionCtx class.

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:9bf8024bbe8675a67eafee671ee34fc4f9e289df

commit r15-2537-g9bf8024bbe8675a67eafee671ee34fc4f9e289df
Author: Arthur Cohen 
Date:   Thu Aug 24 17:49:42 2023 +0200

gccrs: nr2.0: Add new ImmutableNameResolutionCtx class.

gcc/rust/ChangeLog:

* Make-lang.in: Compile it.
* resolve/rust-immutable-name-resolution-context.cc: New file.
* resolve/rust-immutable-name-resolution-context.h: New file.

Diff:
---
 gcc/rust/Make-lang.in  |  1 +
 .../rust-immutable-name-resolution-context.cc  | 56 ++
 .../rust-immutable-name-resolution-context.h   | 55 +
 3 files changed, 112 insertions(+)

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 10af0814372e..24229c02770d 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -134,6 +134,7 @@ GRS_OBJS = \
 rust/rust-toplevel-name-resolver-2.0.o \
 rust/rust-early-name-resolver-2.0.o \
 rust/rust-late-name-resolver-2.0.o \
+   rust/rust-immutable-name-resolution-context.o \
 rust/rust-early-name-resolver.o \
 rust/rust-name-resolver.o \
 rust/rust-ast-resolve.o \
diff --git a/gcc/rust/resolve/rust-immutable-name-resolution-context.cc 
b/gcc/rust/resolve/rust-immutable-name-resolution-context.cc
new file mode 100644
index ..3894e27cd202
--- /dev/null
+++ b/gcc/rust/resolve/rust-immutable-name-resolution-context.cc
@@ -0,0 +1,56 @@
+// Copyright (C) 2020-2023 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-immutable-name-resolution-context.h"
+
+namespace Rust {
+namespace Resolver2_0 {
+
+static ImmutableNameResolutionContext *instance = nullptr;
+
+const ImmutableNameResolutionContext &
+ImmutableNameResolutionContext::init (const NameResolutionContext &ctx)
+{
+  rust_assert (!instance);
+
+  instance = new ImmutableNameResolutionContext (ctx);
+
+  return *instance;
+}
+
+const ImmutableNameResolutionContext &
+ImmutableNameResolutionContext::get ()
+{
+  rust_assert (instance);
+
+  return *instance;
+}
+
+const NameResolutionContext &
+ImmutableNameResolutionContext::resolver () const
+{
+  return ctx;
+}
+
+ImmutableNameResolutionContext::ImmutableNameResolutionContext (
+  const NameResolutionContext &ctx)
+  : ctx (ctx)
+{}
+
+} // namespace Resolver2_0
+} // namespace Rust
diff --git a/gcc/rust/resolve/rust-immutable-name-resolution-context.h 
b/gcc/rust/resolve/rust-immutable-name-resolution-context.h
new file mode 100644
index ..9f9e7764cd2a
--- /dev/null
+++ b/gcc/rust/resolve/rust-immutable-name-resolution-context.h
@@ -0,0 +1,55 @@
+// Copyright (C) 2020-2023 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_IMMUTABLE_NRCTX_H
+#define RUST_IMMUTABLE_NRCTX_H
+
+#include "rust-name-resolution-context.h"
+
+namespace Rust {
+namespace Resolver2_0 {
+
+/**
+ * Once the name resolution pass is complete, the typechecker can access it
+ *
+ * FIXME: More documentation
+ */
+class ImmutableNameResolutionContext
+{
+public:
+  /** FIXME: Documentation */
+  static const ImmutableNameResolutionContext &
+  init (const NameResolutionContext &ctx);
+
+  /** FIXME: Documentation */
+  static const ImmutableNameResolutionContext &get ();
+
+  const NameResolutionContext &resolver () const;
+
+private:
+  ImmutableNameResolutionContext (const NameResolutionContext &ctx);
+  ImmutableNameResolutionContext (const ImmutableNameResolutionContext &other)
+= default;
+
+  const NameResolutionContext &ctx;
+};
+
+} // namespace Resolver2_0
+} // namespace Rust
+
+#endif //! RUST_IMMUTABLE_NRCTX_H


[gcc r15-2538] gccrs: sesh: Add late name resolution 2.0

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:c3b40bc6db988e248ce535e5a27cb60f5e180e23

commit r15-2538-gc3b40bc6db988e248ce535e5a27cb60f5e180e23
Author: Arthur Cohen 
Date:   Fri Aug 4 11:11:13 2023 +0200

gccrs: sesh: Add late name resolution 2.0

gcc/rust/ChangeLog:

* rust-session-manager.cc (Session::compile_crate): Create name 
resolution
context for Session::expansion and subsequent name resolution 
passes.
(Session::expansion): Take name resolution context as a parameter
instead.
* rust-session-manager.h (Session::expansion): Fix declaration.

Diff:
---
 gcc/rust/rust-session-manager.cc | 14 +-
 gcc/rust/rust-session-manager.h  |  3 ++-
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index ea99d019f64f..40adeb20de49 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -42,6 +42,7 @@
 #include "rust-early-name-resolver.h"
 #include "rust-name-resolution-context.h"
 #include "rust-early-name-resolver-2.0.h"
+#include "rust-late-name-resolver-2.0.h"
 #include "rust-cfg-strip.h"
 #include "rust-expand-visitor.h"
 #include "rust-unicode.h"
@@ -591,8 +592,10 @@ Session::compile_crate (const char *filename)
   if (last_step == CompileOptions::CompileStep::Expansion)
 return;
 
+  auto name_resolution_ctx = Resolver2_0::NameResolutionContext ();
   // expansion pipeline stage
-  expansion (parsed_crate);
+
+  expansion (parsed_crate, name_resolution_ctx);
   rust_debug ("\033[0;31mSUCCESSFULLY FINISHED EXPANSION \033[0m");
   if (options.dump_option_enabled (CompileOptions::EXPANSION_DUMP))
 {
@@ -617,7 +620,10 @@ Session::compile_crate (const char *filename)
 return;
 
   // resolution pipeline stage
-  Resolver::NameResolution::Resolve (parsed_crate);
+  if (flag_name_resolution_2_0)
+Resolver2_0::Late (name_resolution_ctx).go (parsed_crate);
+  else
+Resolver::NameResolution::Resolve (parsed_crate);
 
   if (options.dump_option_enabled (CompileOptions::RESOLUTION_DUMP))
 {
@@ -881,7 +887,7 @@ Session::injection (AST::Crate &crate)
 }
 
 void
-Session::expansion (AST::Crate &crate)
+Session::expansion (AST::Crate &crate, Resolver2_0::NameResolutionContext &ctx)
 {
   rust_debug ("started expansion");
 
@@ -908,8 +914,6 @@ Session::expansion (AST::Crate &crate)
   if (saw_errors ())
break;
 
-  auto ctx = Resolver2_0::NameResolutionContext ();
-
   if (flag_name_resolution_2_0)
{
  Resolver2_0::Early early (ctx);
diff --git a/gcc/rust/rust-session-manager.h b/gcc/rust/rust-session-manager.h
index 41aad6079058..9a5691f45eeb 100644
--- a/gcc/rust/rust-session-manager.h
+++ b/gcc/rust/rust-session-manager.h
@@ -24,6 +24,7 @@
 #include "rust-backend.h"
 #include "rust-hir-map.h"
 #include "safe-ctype.h"
+#include "rust-name-resolution-context.h"
 
 #include "config.h"
 #include "rust-system.h"
@@ -413,7 +414,7 @@ private:
   /* Expansion pipeline stage. TODO maybe move to another object? Expands all
* macros, maybe build test harness in future, AST validation, maybe create
* macro crate (if not rustdoc).*/
-  void expansion (AST::Crate &crate);
+  void expansion (AST::Crate &crate, Resolver2_0::NameResolutionContext &ctx);
 
   // handle cfg_option
   bool handle_cfg_option (std::string &data);


[gcc r15-2539] Fix mismatch between constraint and predicate for ashl3_doubleword.

2024-08-01 Thread hongtao Liu via Gcc-cvs
https://gcc.gnu.org/g:64ca25aec4939aea79bd812b089fbb666ca6f2fd

commit r15-2539-g64ca25aec4939aea79bd812b089fbb666ca6f2fd
Author: liuhongt 
Date:   Fri Jul 26 09:56:03 2024 +0800

Fix mismatch between constraint and predicate for ashl3_doubleword.

(insn 98 94 387 2 (parallel [
(set (reg:TI 337 [ _32 ])
(ashift:TI (reg:TI 329)
(reg:QI 521)))
(clobber (reg:CC 17 flags))
]) "test.c":11:13 953 {ashlti3_doubleword}

is reloaded into

(insn 98 452 387 2 (parallel [
(set (reg:TI 0 ax [orig:337 _32 ] [337])
(ashift:TI (const_int 1671291085 [0x639de0cd])
(reg:QI 2 cx [521])))
(clobber (reg:CC 17 flags))

since constraint n in the pattern accepts that.
(Not sure why reload doesn't check predicate)

(define_insn "ashl3_doubleword"
  [(set (match_operand:DWI 0 "register_operand" "=&r,&r")
(ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n,r")
(match_operand:QI 2 "nonmemory_operand" "c,c")))

The patch fixes the mismatch between constraint and predicate.

gcc/ChangeLog:

PR target/116096
* config/i386/constraints.md (Wc): New constraint for integer
1 or -1.
* config/i386/i386.md (ashl3_doubleword): Refine
constraint with Wc.

gcc/testsuite/ChangeLog:

* gcc.target/i386/pr116096.c: New test.

Diff:
---
 gcc/config/i386/constraints.md   |  6 ++
 gcc/config/i386/i386.md  |  2 +-
 gcc/testsuite/gcc.target/i386/pr116096.c | 26 ++
 3 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md
index b760e7c221a1..18389c478002 100644
--- a/gcc/config/i386/constraints.md
+++ b/gcc/config/i386/constraints.md
@@ -254,6 +254,12 @@
   (and (match_code "const_int")
(match_test "IN_RANGE (ival, 0, 7)")))
 
+(define_constraint "Wc"
+  "Integer constant -1 or 1."
+  (and (match_code "const_int")
+   (ior (match_test "op == constm1_rtx")
+   (match_test "op == const1_rtx"
+
 (define_constraint "Ww"
   "Integer constant in the range 0 @dots{} 15, for 16-bit shifts."
   (and (match_code "const_int")
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 3c293c146569..caa3773a5212 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -14764,7 +14764,7 @@
 
 (define_insn "ashl3_doubleword"
   [(set (match_operand:DWI 0 "register_operand" "=&r,&r")
-   (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n,r")
+   (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0Wc,r")
(match_operand:QI 2 "nonmemory_operand" "c,c")))
(clobber (reg:CC FLAGS_REG))]
   ""
diff --git a/gcc/testsuite/gcc.target/i386/pr116096.c 
b/gcc/testsuite/gcc.target/i386/pr116096.c
new file mode 100644
index ..5ef39805f582
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr116096.c
@@ -0,0 +1,26 @@
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2 -flive-range-shrinkage -fno-peephole2 -mstackrealign 
-Wno-psabi" } */
+
+typedef char U __attribute__((vector_size (32)));
+typedef unsigned V __attribute__((vector_size (32)));
+typedef __int128 W __attribute__((vector_size (32)));
+U g;
+
+W baz ();
+
+static inline U
+bar (V x, W y)
+{
+  y = y | y << (W) x;
+  return (U)y;
+}
+
+void
+foo (W w)
+{
+  g = g <<
+bar ((V){baz ()[1], 3, 3, 5, 7},
+(W){w[0], ~(int) 2623676210}) >>
+bar ((V){baz ()[1]},
+(W){-w[0], ~(int) 2623676210});
+}


[gcc r15-2540] c++/coroutines: only defer expanding co_{await, return, yield} if dependent [PR112341]

2024-08-01 Thread Arsen Arsenovic via Gcc-cvs
https://gcc.gnu.org/g:32e678b2ed752154b2f96719e33f11a7c6417f20

commit r15-2540-g32e678b2ed752154b2f96719e33f11a7c6417f20
Author: Arsen Arsenović 
Date:   Tue Jul 30 23:36:24 2024 +0200

c++/coroutines: only defer expanding co_{await,return,yield} if dependent 
[PR112341]

By doing so, we can get diagnostics in template decls when we know we
can.  For instance, in the following:

  awaitable g();
  template
  task f()
  {
co_await g();
co_yield 1;
co_return "foo";
  }

... the coroutine promise type in each statement is always
std::coroutine_handle::promise_type, and all of the operands are
not type-dependent, so we can always compute the resulting types (and
expected types) of these expressions and statements.

Also, when we do not know the type of the CO_AWAIT_EXPR or
CO_YIELD_EXPR, we now return NULL_TREE as the type rather than
unknown_type_node.  This is more correct, since the type is not unknown,
it just isn't determined yet.  This also means we can remove the
CO_AWAIT_EXPR and CO_YIELD_EXPR special-cases from
type_dependent_expression_p.

PR c++/112341 - error: insufficient contextual information to determine 
type on co_await result in function template

gcc/cp/ChangeLog:

PR c++/112341
* coroutines.cc (struct coroutine_info): Also cache the
traits type.
(ensure_coro_initialized): New function.  Makes sure we have
initialized the coroutine state successfully, or informs the
caller should it fail to do so.  Extracted from
coro_promise_type_found_p.
(coro_get_traits_class): New function.  Gets the (cached)
coroutine traits type for a given coroutine.  Extracted from
coro_promise_type_found_p and refactored to cache the result.
(coro_promise_type_found_p): Use the two functions above.
(build_template_co_await_expr): New function.  Builds a
CO_AWAIT_EXPR representing a CO_AWAIT_EXPR in a template
declaration.
(build_co_await): Use the above if processing_template_decl, and
give it a proper type.
(coro_dependent_p): New function.  Returns true iff its
argument is a type-dependent expression OR the current functions
traits class is type dependent.
(finish_co_await_expr): Defer expansion only in the case
coro_dependent_p returns true.
(finish_co_yield_expr): Ditto.
(finish_co_return_stmt): Ditto.
* pt.cc (type_dependent_expression_p): Do not treat
CO_AWAIT/CO_YIELD specially.

gcc/testsuite/ChangeLog:

PR c++/112341
* g++.dg/coroutines/pr112341-2.C: New test.
* g++.dg/coroutines/pr112341-3.C: New test.
* g++.dg/coroutines/torture/co-yield-03-tmpl-nondependent.C: New
test.
* g++.dg/coroutines/pr112341.C: New test.

Diff:
---
 gcc/cp/coroutines.cc   | 157 -
 gcc/cp/pt.cc   |   5 -
 gcc/testsuite/g++.dg/coroutines/pr112341-2.C   |  25 
 gcc/testsuite/g++.dg/coroutines/pr112341-3.C   |  65 +
 gcc/testsuite/g++.dg/coroutines/pr112341.C |  21 +++
 .../torture/co-yield-03-tmpl-nondependent.C| 140 ++
 6 files changed, 376 insertions(+), 37 deletions(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 127a1c06b56e..91bbe6b0a0eb 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -85,6 +85,7 @@ struct GTY((for_user)) coroutine_info
   tree actor_decl;/* The synthesized actor function.  */
   tree destroy_decl;  /* The synthesized destroy function.  */
   tree promise_type;  /* The cached promise type for this function.  */
+  tree traits_type;   /* The cached traits type for this function.  */
   tree handle_type;   /* The cached coroutine handle for this function.  */
   tree self_h_proxy;  /* A handle instance that is used as the proxy for the
 one that will eventually be allocated in the coroutine
@@ -429,11 +430,12 @@ find_promise_type (tree traits_class)
   return promise_type;
 }
 
+/* Perform initialization of the coroutine processor state, if not done
+   before.  */
+
 static bool
-coro_promise_type_found_p (tree fndecl, location_t loc)
+ensure_coro_initialized (location_t loc)
 {
-  gcc_assert (fndecl != NULL_TREE);
-
   if (!coro_initialized)
 {
   /* Trees we only need to create once.
@@ -466,6 +468,30 @@ coro_promise_type_found_p (tree fndecl, location_t loc)
 
   coro_initialized = true;
 }
+  return true;
+}
+
+/* Try to get the coroutine traits class.  */
+static tree
+coro_get_traits_class (tree fndecl, location_t loc)
+{
+  gcc_assert (fndecl != NULL_TREE);
+  gcc_assert (coro_initialize

[gcc r15-2541] gccrs: session-manager: Dump name resolution pass.

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:d403dd2c9093703ee8910c16bb0ccb480d456704

commit r15-2541-gd403dd2c9093703ee8910c16bb0ccb480d456704
Author: Arthur Cohen 
Date:   Wed Aug 23 15:14:46 2023 +0200

gccrs: session-manager: Dump name resolution pass.

gcc/rust/ChangeLog:

* rust-session-manager.cc: Add files for dumping name resolution, 
call
name resolution dump function.
(Session::dump_name_resolution): New.
* rust-session-manager.h: New declaration.

Diff:
---
 gcc/rust/rust-session-manager.cc | 30 +++---
 gcc/rust/rust-session-manager.h  |  1 +
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 40adeb20de49..64e0190f716d 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -69,6 +69,10 @@ 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 *kASTmacroResolutionDumpFile = "gccrs.ast-macro-resolution.dump";
+const char *kASTlabelResolutionDumpFile = "gccrs.ast-label-resolution.dump";
+const char *kASTtypeResolutionDumpFile = "gccrs.ast-type-resolution.dump";
+const char *kASTvalueResolutionDumpFile = "gccrs.ast-value-resolution.dump";
 const char *kHIRDumpFile = "gccrs.hir.dump";
 const char *kHIRPrettyDumpFile = "gccrs.hir-pretty.dump";
 const char *kHIRTypeResolutionDumpFile = "gccrs.type-resolution.dump";
@@ -86,6 +90,7 @@ Session::get_instance ()
 
 static std::string
 infer_crate_name (const std::string &filename)
+
 {
   if (filename == "-")
 return kDefaultCrateName;
@@ -626,9 +631,7 @@ Session::compile_crate (const char *filename)
 Resolver::NameResolution::Resolve (parsed_crate);
 
   if (options.dump_option_enabled (CompileOptions::RESOLUTION_DUMP))
-{
-  // TODO: what do I dump here? resolved names? AST with resolved names?
-}
+dump_name_resolution (name_resolution_ctx);
 
   if (saw_errors ())
 return;
@@ -982,6 +985,27 @@ Session::dump_ast_pretty (AST::Crate &crate, bool 
expanded) const
   out.close ();
 }
 
+void
+Session::dump_name_resolution (Resolver2_0::NameResolutionContext &ctx) const
+{
+  // YES this is ugly but NO GCC 4.8 does not allow us to make it fancier :(
+  std::string types_content = ctx.types.as_debug_string ();
+  std::ofstream types_stream{kASTtypeResolutionDumpFile};
+  types_stream << types_content;
+
+  std::string macros_content = ctx.macros.as_debug_string ();
+  std::ofstream macros_stream{kASTmacroResolutionDumpFile};
+  macros_stream << macros_content;
+
+  std::string labels_content = ctx.labels.as_debug_string ();
+  std::ofstream labels_stream{kASTlabelResolutionDumpFile};
+  labels_stream << labels_content;
+
+  std::string values_content = ctx.values.as_debug_string ();
+  std::ofstream values_stream{kASTvalueResolutionDumpFile};
+  values_stream << values_content;
+}
+
 void
 Session::dump_hir (HIR::Crate &crate) const
 {
diff --git a/gcc/rust/rust-session-manager.h b/gcc/rust/rust-session-manager.h
index 9a5691f45eeb..845b53ab6db1 100644
--- a/gcc/rust/rust-session-manager.h
+++ b/gcc/rust/rust-session-manager.h
@@ -396,6 +396,7 @@ private:
 
   void dump_lex (Parser &parser) const;
   void dump_ast_pretty (AST::Crate &crate, bool expanded = false) const;
+  void dump_name_resolution (Resolver2_0::NameResolutionContext &ctx) const;
   void dump_hir (HIR::Crate &crate) const;
   void dump_hir_pretty (HIR::Crate &crate) const;


[gcc r15-2542] gccrs: session manager: Init Immutable name resolver.

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:debb0c76ec868c3a1ae6c967be48efb202ad9071

commit r15-2542-gdebb0c76ec868c3a1ae6c967be48efb202ad9071
Author: Arthur Cohen 
Date:   Thu Aug 24 17:50:45 2023 +0200

gccrs: session manager: Init Immutable name resolver.

gcc/rust/ChangeLog:

* rust-session-manager.cc (Session::compile_crate): Create an 
immutable
view of the name resolution context.

Diff:
---
 gcc/rust/rust-session-manager.cc | 4 
 1 file changed, 4 insertions(+)

diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 64e0190f716d..1c7e2766d710 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -18,6 +18,7 @@
 
 #include "rust-session-manager.h"
 #include "rust-diagnostics.h"
+#include "rust-immutable-name-resolution-context.h"
 #include "rust-unsafe-checker.h"
 #include "rust-lex.h"
 #include "rust-parse.h"
@@ -659,6 +660,9 @@ Session::compile_crate (const char *filename)
   if (last_step == CompileOptions::CompileStep::TypeCheck)
 return;
 
+  // name resolution is done, we now freeze the name resolver for type checking
+  Resolver2_0::ImmutableNameResolutionContext::init (name_resolution_ctx);
+
   // type resolve
   Resolver::TypeResolution::Resolve (hir);


[gcc r15-2543] gccrs: nr2.0: Add lookup of resolved nodes.

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:2b91f4b9d64829069e331ead3f36f610e3095d26

commit r15-2543-g2b91f4b9d64829069e331ead3f36f610e3095d26
Author: Arthur Cohen 
Date:   Thu Aug 24 17:51:11 2023 +0200

gccrs: nr2.0: Add lookup of resolved nodes.

gcc/rust/ChangeLog:

* resolve/rust-name-resolution-context.cc 
(NameResolutionContext::lookup):
Add lookup function.
* resolve/rust-name-resolution-context.h: Include mappings and 
optional.

Diff:
---
 gcc/rust/resolve/rust-name-resolution-context.cc | 13 +
 gcc/rust/resolve/rust-name-resolution-context.h  |  3 +++
 2 files changed, 16 insertions(+)

diff --git a/gcc/rust/resolve/rust-name-resolution-context.cc 
b/gcc/rust/resolve/rust-name-resolution-context.cc
index f35db7e925e5..9fd8d52968a8 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.cc
+++ b/gcc/rust/resolve/rust-name-resolution-context.cc
@@ -17,6 +17,8 @@
 // .
 
 #include "rust-name-resolution-context.h"
+#include "optional.h"
+#include "rust-mapping-common.h"
 
 namespace Rust {
 namespace Resolver2_0 {
@@ -52,6 +54,17 @@ NameResolutionContext::map_usage (NodeId usage, NodeId 
definition)
   rust_assert (inserted);
 }
 
+tl::optional
+NameResolutionContext::lookup (NodeId usage)
+{
+  auto it = resolved_nodes.find (usage);
+
+  if (it == resolved_nodes.end ())
+return tl::nullopt;
+
+  return it->second;
+}
+
 void
 NameResolutionContext::scoped (Rib rib, NodeId id,
   std::function lambda,
diff --git a/gcc/rust/resolve/rust-name-resolution-context.h 
b/gcc/rust/resolve/rust-name-resolution-context.h
index bc3c4bb5ddb7..e896ca053608 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.h
+++ b/gcc/rust/resolve/rust-name-resolution-context.h
@@ -19,6 +19,7 @@
 #ifndef RUST_NAME_RESOLVER_2_0_H
 #define RUST_NAME_RESOLVER_2_0_H
 
+#include "optional.h"
 #include "rust-forever-stack.h"
 #include "rust-hir-map.h"
 
@@ -180,7 +181,9 @@ public:
   Analysis::Mappings &mappings;
 
   // TODO: Rename
+  // TODO: Use newtype pattern for Usage and Definition
   void map_usage (NodeId usage, NodeId definition);
+  tl::optional lookup (NodeId usage);
 
 private:
   /* Map of "usage" nodes which have been resolved to a "definition" node */


[gcc r15-2544] gccrs: typecheck: Start using nr2.0 properly

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:e476d3234468f4b565467bfe09722abcc959d934

commit r15-2544-ge476d3234468f4b565467bfe09722abcc959d934
Author: Arthur Cohen 
Date:   Thu Aug 24 17:51:21 2023 +0200

gccrs: typecheck: Start using nr2.0 properly

Fetch the ImmutableNrCtx in order to access name resolver during
typechecking.

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit): 
Start
fetching name resolution information in the typechecker.
* typecheck/rust-hir-type-check-type.cc 
(TypeCheckType::resolve_root_path):
Likewise.
* typecheck/rust-hir-type-check-path.cc: Use nr 2.0.

Diff:
---
 gcc/rust/typecheck/rust-hir-type-check-item.cc | 91 +-
 gcc/rust/typecheck/rust-hir-type-check-path.cc | 16 +++--
 gcc/rust/typecheck/rust-hir-type-check-type.cc | 24 +--
 3 files changed, 105 insertions(+), 26 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc 
b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index 4bbd28021a02..4ab946e1c2a1 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -17,12 +17,17 @@
 // .
 
 #include "rust-hir-type-check-item.h"
+#include "rust-canonical-path.h"
+#include "rust-diagnostics.h"
 #include "rust-hir-type-check-enumitem.h"
 #include "rust-hir-type-check-implitem.h"
 #include "rust-hir-type-check-type.h"
 #include "rust-hir-type-check-expr.h"
 #include "rust-hir-type-check-pattern.h"
 #include "rust-hir-trait-resolve.h"
+#include "rust-identifier.h"
+#include "rust-session-manager.h"
+#include "rust-immutable-name-resolution-context.h"
 #include "rust-substitution-mapper.h"
 #include "rust-type-util.h"
 #include "rust-tyty-variance-analysis.h"
@@ -185,11 +190,30 @@ TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
 }
 
   // get the path
-  const CanonicalPath *canonical_path = nullptr;
-  bool ok = mappings->lookup_canonical_path (
-struct_decl.get_mappings ().get_nodeid (), &canonical_path);
-  rust_assert (ok);
-  RustIdent ident{*canonical_path, struct_decl.get_locus ()};
+
+  auto path = CanonicalPath::create_empty ();
+
+  // FIXME: HACK: ARTHUR: Disgusting
+  if (flag_name_resolution_2_0)
+{
+  auto nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+  auto canonical_path = nr_ctx.values.to_canonical_path (
+   struct_decl.get_mappings ().get_nodeid ());
+
+  path = canonical_path.value ();
+}
+  else
+{
+  const CanonicalPath *canonical_path = nullptr;
+  bool ok = mappings->lookup_canonical_path (
+   struct_decl.get_mappings ().get_nodeid (), &canonical_path);
+  rust_assert (ok);
+
+  path = *canonical_path;
+}
+
+  RustIdent ident{path, struct_decl.get_locus ()};
 
   // its a single variant ADT
   std::vector variants;
@@ -248,12 +272,29 @@ TypeCheckItem::visit (HIR::StructStruct &struct_decl)
   context->insert_type (field.get_mappings (), ty_field->get_field_type 
());
 }
 
-  // get the path
-  const CanonicalPath *canonical_path = nullptr;
-  bool ok = mappings->lookup_canonical_path (
-struct_decl.get_mappings ().get_nodeid (), &canonical_path);
-  rust_assert (ok);
-  RustIdent ident{*canonical_path, struct_decl.get_locus ()};
+  auto path = CanonicalPath::create_empty ();
+
+  // FIXME: HACK: ARTHUR: Disgusting
+  if (flag_name_resolution_2_0)
+{
+  auto nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+  auto canonical_path = nr_ctx.values.to_canonical_path (
+   struct_decl.get_mappings ().get_nodeid ());
+
+  path = canonical_path.value ();
+}
+  else
+{
+  const CanonicalPath *canonical_path = nullptr;
+  bool ok = mappings->lookup_canonical_path (
+   struct_decl.get_mappings ().get_nodeid (), &canonical_path);
+  rust_assert (ok);
+
+  path = *canonical_path;
+}
+
+  RustIdent ident{path, struct_decl.get_locus ()};
 
   // its a single variant ADT
   std::vector variants;
@@ -510,13 +551,29 @@ TypeCheckItem::visit (HIR::Function &function)
   TypeCheckPattern::Resolve (param.get_param_name ().get (), param_tyty);
 }
 
-  const CanonicalPath *canonical_path = nullptr;
-  bool ok
-= mappings->lookup_canonical_path (function.get_mappings ().get_nodeid (),
-  &canonical_path);
-  rust_assert (ok);
+  auto path = CanonicalPath::create_empty ();
+
+  // FIXME: HACK: ARTHUR: Disgusting
+  if (flag_name_resolution_2_0)
+{
+  auto nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+  auto canonical_path = nr_ctx.values.to_canonical_path (
+   function.get_mappings ().get_nodeid ());
+
+  path = canonical_path.value ();
+}
+  else
+{
+  const CanonicalPath *canonical_path = nullptr;
+  bool ok = mappings->lookup_canonical_pa

[gcc r15-2545] gccrs: backend: Use new name resolver where necessary

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:786bc62f957e373d40a8c11fa4e607383ab2e2f1

commit r15-2545-g786bc62f957e373d40a8c11fa4e607383ab2e2f1
Author: Arthur Cohen 
Date:   Fri Aug 25 14:33:36 2023 +0200

gccrs: backend: Use new name resolver where necessary

gcc/rust/ChangeLog:

* backend/rust-compile-base.cc: Use new ImmutableNrCtx.
* backend/rust-compile-context.h: Likewise.
* backend/rust-compile-expr.cc: Likewise.
* backend/rust-compile-item.cc: Likewise.

Diff:
---
 gcc/rust/backend/rust-compile-base.cc   |  1 +
 gcc/rust/backend/rust-compile-context.h |  1 +
 gcc/rust/backend/rust-compile-expr.cc   | 22 +-
 gcc/rust/backend/rust-compile-item.cc   | 31 +--
 4 files changed, 44 insertions(+), 11 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-base.cc 
b/gcc/rust/backend/rust-compile-base.cc
index 4d6f0275b004..584d6a03ea95 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -31,6 +31,7 @@
 #include "rust-type-util.h"
 #include "rust-compile-implitem.h"
 #include "rust-attribute-values.h"
+#include "rust-immutable-name-resolution-context.h"
 
 #include "fold-const.h"
 #include "stringpool.h"
diff --git a/gcc/rust/backend/rust-compile-context.h 
b/gcc/rust/backend/rust-compile-context.h
index 36a36e79f680..671aee196c2a 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -27,6 +27,7 @@
 #include "rust-hir-full.h"
 #include "rust-mangle.h"
 #include "rust-tree.h"
+#include "rust-immutable-name-resolution-context.h"
 
 namespace Rust {
 namespace Compile {
diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index 65de24bf9d8c..6a9bb73ffe0f 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -2311,11 +2311,23 @@ CompileExpr::generate_closure_function 
(HIR::ClosureExpr &expr,
   if (is_block_expr)
 {
   auto body_mappings = function_body->get_mappings ();
-  Resolver::Rib *rib = nullptr;
-  bool ok
-   = ctx->get_resolver ()->find_name_rib (body_mappings.get_nodeid (),
-  &rib);
-  rust_assert (ok);
+  if (flag_name_resolution_2_0)
+   {
+ auto nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+ auto candidate = nr_ctx.values.to_rib (body_mappings.get_nodeid ());
+
+ rust_assert (candidate.has_value ());
+   }
+  else
+   {
+ Resolver::Rib *rib = nullptr;
+ bool ok
+   = ctx->get_resolver ()->find_name_rib (body_mappings.get_nodeid (),
+  &rib);
+ rust_assert (ok);
+   }
 }
 
   tree enclosing_scope = NULL_TREE;
diff --git a/gcc/rust/backend/rust-compile-item.cc 
b/gcc/rust/backend/rust-compile-item.cc
index 234ad2aa59c1..8feed51efa4f 100644
--- a/gcc/rust/backend/rust-compile-item.cc
+++ b/gcc/rust/backend/rust-compile-item.cc
@@ -19,6 +19,7 @@
 #include "rust-compile-item.h"
 #include "rust-compile-implitem.h"
 #include "rust-compile-extern.h"
+#include "rust-immutable-name-resolution-context.h"
 
 namespace Rust {
 namespace Compile {
@@ -149,12 +150,30 @@ CompileItem::visit (HIR::Function &function)
}
 }
 
-  const Resolver::CanonicalPath *canonical_path = nullptr;
-  bool ok = ctx->get_mappings ()->lookup_canonical_path (
-function.get_mappings ().get_nodeid (), &canonical_path);
-  rust_assert (ok);
+  Resolver::CanonicalPath canonical_path
+= Resolver::CanonicalPath::create_empty ();
+
+  if (flag_name_resolution_2_0)
+{
+  auto nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+  auto path = nr_ctx.values.to_canonical_path (
+   function.get_mappings ().get_nodeid ());
+
+  canonical_path = path.value ();
+}
+  else
+{
+  const Resolver::CanonicalPath *path = nullptr;
+  bool ok = ctx->get_mappings ()->lookup_canonical_path (
+   function.get_mappings ().get_nodeid (), &path);
+  rust_assert (ok);
+
+  canonical_path = *path;
+}
 
-  const std::string asm_name = ctx->mangle_item (fntype, *canonical_path);
+  const std::string asm_name = ctx->mangle_item (fntype, canonical_path);
 
   // items can be forward compiled which means we may not need to invoke this
   // code. We might also have already compiled this generic function as well.
@@ -181,7 +200,7 @@ CompileItem::visit (HIR::Function &function)
function.get_function_params (),
function.get_qualifiers (), function.get_visibility (),
function.get_outer_attrs (), function.get_locus (),
-   function.get_definition ().get (), canonical_path,
+   function.get_definition ().get (), &canonical_path,
fntyp

[gcc r15-2546] gccrs: nr2.0: Start using newtype pattern for Usage and Declaration

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:53c74beb3a15a477f4fef770fe6abccbdb124fb7

commit r15-2546-g53c74beb3a15a477f4fef770fe6abccbdb124fb7
Author: Arthur Cohen 
Date:   Thu Sep 14 17:38:06 2023 +0200

gccrs: nr2.0: Start using newtype pattern for Usage and Declaration

gcc/rust/ChangeLog:

* resolve/rust-name-resolution-context.cc 
(NameResolutionContext::map_usage):
Use newtype pattern.
(NameResolutionContext::lookup): Likewise.
* resolve/rust-name-resolution-context.h (class Usage): New class.
(class Definition): Likewise.
* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Create 
instances
of Usage and Definition.

Diff:
---
 gcc/rust/resolve/rust-late-name-resolver-2.0.cc  |  4 ++--
 gcc/rust/resolve/rust-name-resolution-context.cc |  6 +++---
 gcc/rust/resolve/rust-name-resolution-context.h  | 27 ++--
 3 files changed, 30 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index e5a4f2348712..50034073edfe 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -142,7 +142,7 @@ Late::visit (AST::IdentifierExpr &expr)
   return;
 }
 
-  ctx.map_usage (expr.get_node_id (), *resolved);
+  ctx.map_usage (Usage (expr.get_node_id ()), Definition (*resolved));
 
   // in the old resolver, resolutions are kept in the resolver, not the 
mappings
   // :/ how do we deal with that?
@@ -173,7 +173,7 @@ Late::visit (AST::TypePath &type)
 
   auto resolved = ctx.types.get (type.get_segments ().back ()->as_string ());
 
-  ctx.map_usage (type.get_node_id (), *resolved);
+  ctx.map_usage (Usage (type.get_node_id ()), Definition (*resolved));
 }
 
 } // namespace Resolver2_0
diff --git a/gcc/rust/resolve/rust-name-resolution-context.cc 
b/gcc/rust/resolve/rust-name-resolution-context.cc
index 9fd8d52968a8..0340d28f1278 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.cc
+++ b/gcc/rust/resolve/rust-name-resolution-context.cc
@@ -46,7 +46,7 @@ NameResolutionContext::insert (Identifier name, NodeId id, 
Namespace ns)
 }
 
 void
-NameResolutionContext::map_usage (NodeId usage, NodeId definition)
+NameResolutionContext::map_usage (Usage usage, Definition definition)
 {
   auto inserted = resolved_nodes.emplace (usage, definition).second;
 
@@ -57,12 +57,12 @@ NameResolutionContext::map_usage (NodeId usage, NodeId 
definition)
 tl::optional
 NameResolutionContext::lookup (NodeId usage)
 {
-  auto it = resolved_nodes.find (usage);
+  auto it = resolved_nodes.find (Usage (usage));
 
   if (it == resolved_nodes.end ())
 return tl::nullopt;
 
-  return it->second;
+  return it->second.id;
 }
 
 void
diff --git a/gcc/rust/resolve/rust-name-resolution-context.h 
b/gcc/rust/resolve/rust-name-resolution-context.h
index e896ca053608..8702900d0f3a 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.h
+++ b/gcc/rust/resolve/rust-name-resolution-context.h
@@ -133,6 +133,28 @@ change?
 correct
 */
 
+// FIXME: Documentation
+class Usage
+{
+public:
+  explicit Usage (NodeId id) : id (id) {}
+
+  // TODO: move to name-resolution-ctx.cc
+  // storing it as a key in a map
+  bool operator< (const Usage other) const { return other.id < id; }
+
+  NodeId id;
+};
+
+// FIXME: Documentation
+class Definition
+{
+public:
+  explicit Definition (NodeId id) : id (id) {}
+
+  NodeId id;
+};
+
 // Now our resolver, which keeps track of all the `ForeverStack`s we could want
 class NameResolutionContext
 {
@@ -182,12 +204,13 @@ public:
 
   // TODO: Rename
   // TODO: Use newtype pattern for Usage and Definition
-  void map_usage (NodeId usage, NodeId definition);
+  void map_usage (Usage usage, Definition definition);
+
   tl::optional lookup (NodeId usage);
 
 private:
   /* Map of "usage" nodes which have been resolved to a "definition" node */
-  std::map resolved_nodes;
+  std::map resolved_nodes;
 };
 
 } // namespace Resolver2_0


[gcc r15-2547] gccrs: late: Setup builtin types properly, change Rib API

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:c47cae71d32fa580572a5284e677590ed7cd9509

commit r15-2547-gc47cae71d32fa580572a5284e677590ed7cd9509
Author: Arthur Cohen 
Date:   Mon Aug 28 16:40:12 2023 +0200

gccrs: late: Setup builtin types properly, change Rib API

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.hxx: Start using Rib::Definition for
shadowable information.
* resolve/rust-late-name-resolver-2.0.cc (next_node_id): New.
(next_hir_id): New.
(Late::setup_builtin_types): Improve builtin type setup.
* resolve/rust-rib.cc (Rib::Definition::Definition): New 
constructor.
(Rib::Definition::Shadowable): Likewise.
(Rib::Definition::NonShadowable): Likewise.
(Rib::Rib): Fix general constructor.
(Rib::insert): Use Definition class.
(Rib::get): Likewise.
* resolve/rust-rib.h: New Definition class, new prototypes.

Diff:
---
 gcc/rust/resolve/rust-forever-stack.hxx | 22 ---
 gcc/rust/resolve/rust-late-name-resolver-2.0.cc | 84 ++---
 gcc/rust/resolve/rust-rib.cc| 38 ---
 gcc/rust/resolve/rust-rib.h | 30 +++--
 4 files changed, 126 insertions(+), 48 deletions(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index 0aa9943191e8..a2fdce983629 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -100,9 +100,9 @@ ForeverStack::pop ()
 }
 
 static tl::expected
-insert_inner (Rib &rib, std::string name, NodeId node, bool can_shadow)
+insert_inner (Rib &rib, std::string name, Rib::Definition definition)
 {
-  return rib.insert (name, node, can_shadow);
+  return rib.insert (name, definition);
 }
 
 template 
@@ -115,7 +115,8 @@ ForeverStack::insert (Identifier name, NodeId node)
   // pass, we might end up in a situation where it is okay to re-add new names.
   // Do we just ignore that here? Do we keep track of if the Rib is new or not?
   // should our cursor have info on the current node like "is it newly pushed"?
-  return insert_inner (innermost_rib, name.as_string (), node, false);
+  return insert_inner (innermost_rib, name.as_string (),
+  Rib::Definition::NonShadowable (node));
 }
 
 template 
@@ -126,7 +127,8 @@ ForeverStack::insert_at_root (Identifier name, NodeId 
node)
 
   // inserting in the root of the crate is never a shadowing operation, even 
for
   // macros
-  return insert_inner (root_rib, name.as_string (), node, false);
+  return insert_inner (root_rib, name.as_string (),
+  Rib::Definition::NonShadowable (node));
 }
 
 // Specialization for Macros and Labels - where we are allowed to shadow
@@ -135,14 +137,16 @@ template <>
 inline tl::expected
 ForeverStack::insert (Identifier name, NodeId node)
 {
-  return insert_inner (peek (), name.as_string (), node, true);
+  return insert_inner (peek (), name.as_string (),
+  Rib::Definition::Shadowable (node));
 }
 
 template <>
 inline tl::expected
 ForeverStack::insert (Identifier name, NodeId node)
 {
-  return insert_inner (peek (), name.as_string (), node, true);
+  return insert_inner (peek (), name.as_string (),
+  Rib::Definition::Shadowable (node));
 }
 
 template 
@@ -455,10 +459,10 @@ template 
 tl::optional::Node &, std::string>>
 ForeverStack::dfs (ForeverStack::Node &starting_point, NodeId to_find)
 {
-  auto &values = starting_point.rib.get_values ();
+  auto values = starting_point.rib.get_values ();
 
   for (auto &kv : values)
-if (kv.second == to_find)
+if (kv.second.id == to_find)
   return {{starting_point, kv.first}};
 
   for (auto &child : starting_point.children)
@@ -568,7 +572,7 @@ ForeverStack::stream_rib (std::stringstream &stream, 
const Rib &rib,
   stream << next << "rib: {\n";
 
   for (const auto &kv : rib.get_values ())
-stream << next_next << kv.first << ": " << kv.second << "\n";
+stream << next_next << kv.first << ": " << kv.second.id << "\n";
 
   stream << next << "},\n";
 }
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index 50034073edfe..3090bbeff2a9 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -18,8 +18,10 @@
 
 #include "optional.h"
 #include "rust-ast-full.h"
+#include "rust-hir-map.h"
 #include "rust-late-name-resolver-2.0.h"
 #include "rust-default-resolver.h"
+#include "rust-name-resolution-context.h"
 #include "rust-path.h"
 #include "rust-tyty.h"
 #include "rust-hir-type-check.h"
@@ -29,41 +31,75 @@ namespace Resolver2_0 {
 
 Late::Late (NameResolutionContext &ctx) : DefaultResolver (ctx) {}
 
+static NodeId
+next_node_id ()
+{
+  return Analysis::Mappings::get ()->get_next_node_id ();
+};
+
+static HirId
+next_hir_id ()
+{
+  return Analysis::Mappi

[gcc r15-2548] gccrs: Fix duplicate detection

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:d61973e4dd48259577dbc3f2cb4f9b2a489a7950

commit r15-2548-gd61973e4dd48259577dbc3f2cb4f9b2a489a7950
Author: Pierre-Emmanuel Patry 
Date:   Thu Sep 14 17:39:37 2023 +0200

gccrs: Fix duplicate detection

The resolver did report duplicate symbols when being run multiple times
even if the node id was the same. This commit adds an additional
condition, the error will only be reported if the existing node id is
different from the current node id.

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc 
(TopLevel::insert_or_error_out):
Add new constraint to duplicate errors.

Signed-off-by: Pierre-Emmanuel Patry 

Diff:
---
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index 446a1c6a41b1..407892bb7bbd 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -47,11 +47,8 @@ TopLevel::insert_or_error_out (const Identifier &identifier,
 
   auto result = ctx.insert (identifier, node_id, ns);
 
-  if (!result)
+  if (!result && result.error ().existing != node_id)
 {
-  // can we do something like check if the node id is the same? if it is 
the
-  // same, it's not an error, just the resolver running multiple times?
-
   rich_location rich_loc (line_table, locus);
   rich_loc.add_range (node_locations[result.error ().existing]);


[gcc r15-2549] gccrs: Emit error on identical use declarations

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:a3b96f6b74728d0e35ca38327603929d9c4eb678

commit r15-2549-ga3b96f6b74728d0e35ca38327603929d9c4eb678
Author: Pierre-Emmanuel Patry 
Date:   Fri Sep 15 13:14:56 2023 +0200

gccrs: Emit error on identical use declarations

The compiler did not emit any warning when a same target was declared
from different sources.

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc 
(TopLevel::handle_use_dec):
Use the new dict to track down already resolved use declarations.
* resolve/rust-toplevel-name-resolver-2.0.h: Add new dict to store
previous use declarations.

Signed-off-by: Pierre-Emmanuel Patry 

Diff:
---
 .../resolve/rust-toplevel-name-resolver-2.0.cc | 76 --
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h |  4 ++
 2 files changed, 46 insertions(+), 34 deletions(-)

diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index 407892bb7bbd..94cc3cb62d94 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -319,40 +319,48 @@ TopLevel::handle_use_dec (AST::SimplePath path)
 
   auto found = false;
 
-  auto resolve_and_insert = [this, &found, &declared_name,
-locus] (Namespace ns,
-const AST::SimplePath &path) {
-tl::optional resolved = tl::nullopt;
-
-// FIXME: resolve_path needs to return an `expected` so
-// that we can improve it with hints or location or w/ever. and maybe
-// only emit it the first time.
-switch (ns)
-  {
-  case Namespace::Values:
-   resolved = ctx.values.resolve_path (path.get_segments ());
-   break;
-  case Namespace::Types:
-   resolved = ctx.types.resolve_path (path.get_segments ());
-   break;
-  case Namespace::Macros:
-   resolved = ctx.macros.resolve_path (path.get_segments ());
-   break;
-  case Namespace::Labels:
-   // TODO: Is that okay?
-   rust_unreachable ();
-  }
-
-// FIXME: Ugly
-(void) resolved.map ([this, &found, &declared_name, locus, ns] (NodeId id) 
{
-  found = true;
-
-  // what do we do with the id?
-  insert_or_error_out (declared_name, locus, id, ns);
-
-  return id;
-});
-  };
+  auto resolve_and_insert
+= [this, &found, &declared_name, locus] (Namespace ns,
+const AST::SimplePath &path) {
+   tl::optional resolved = tl::nullopt;
+
+   // FIXME: resolve_path needs to return an `expected` so
+   // that we can improve it with hints or location or w/ever. and maybe
+   // only emit it the first time.
+   switch (ns)
+ {
+ case Namespace::Values:
+   resolved = ctx.values.resolve_path (path.get_segments ());
+   break;
+ case Namespace::Types:
+   resolved = ctx.types.resolve_path (path.get_segments ());
+   break;
+ case Namespace::Macros:
+   resolved = ctx.macros.resolve_path (path.get_segments ());
+   break;
+ case Namespace::Labels:
+   // TODO: Is that okay?
+   rust_unreachable ();
+ }
+
+   // FIXME: Ugly
+   (void) resolved.map (
+ [this, &found, &declared_name, locus, ns, path] (NodeId id) {
+   found = true;
+
+   // what do we do with the id?
+   insert_or_error_out (declared_name, locus, id, ns);
+   auto result = node_forwarding.find (id);
+   if (result != node_forwarding.cend ()
+   && result->second != path.get_node_id ())
+ rust_error_at (path.get_locus (), "%<%s%> defined multiple times",
+declared_name.c_str ());
+   else // No previous thing has inserted this into our scope
+ node_forwarding.insert ({id, path.get_node_id ()});
+
+   return id;
+ });
+  };
 
   // do this for all namespaces (even Labels?)
 
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
index ac11f3103708..0a766bab2598 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
@@ -60,6 +60,10 @@ private:
   // FIXME: Do we move these to our mappings?
   std::unordered_map node_locations;
 
+  // Store node forwarding for use declaration, the link between a
+  // "new" local name and its definition.
+  std::unordered_map node_forwarding;
+
   void visit (AST::Module &module) override;
   void visit (AST::MacroRulesDefinition ¯o) override;
   void visit (AST::Function &function) override;


[gcc r15-2550] gccrs: Change error message on unresolved import

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:97402694f71d96c89fac2ad2b859cbe6765e956a

commit r15-2550-g97402694f71d96c89fac2ad2b859cbe6765e956a
Author: Pierre-Emmanuel Patry 
Date:   Sun Mar 24 22:23:03 2024 +0100

gccrs: Change error message on unresolved import

The error message did not match rustc's.

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::visit): 
Change
error message.

Signed-off-by: Pierre-Emmanuel Patry 

Diff:
---
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index 94cc3cb62d94..72c3560b9daf 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -478,8 +478,7 @@ TopLevel::visit (AST::UseDeclaration &use)
   for (auto &path : paths)
 if (!handle_use_dec (path))
   rust_error_at (path.get_final_segment ().get_locus (), ErrorCode::E0433,
-"could not resolve import %qs",
-path.as_string ().c_str ());
+"unresolved import %qs", path.as_string ().c_str ());
 }
 
 } // namespace Resolver2_0


[gcc r15-2551] gccrs: Prevent error emission on resolver reentry

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:36ce08b23ed34ecda82a956998f39ce5afbcdec4

commit r15-2551-g36ce08b23ed34ecda82a956998f39ce5afbcdec4
Author: Pierre-Emmanuel Patry 
Date:   Mon Sep 18 15:34:24 2023 +0200

gccrs: Prevent error emission on resolver reentry

The resolver was emitting an error when meeting the same symbol twice.
What is important here is the origin of the resolved symbol, we should
emit an error when the name is similar but the symbol isn't be not when
the resolver is simply meeting the exact same symbol.

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc (insert_macros): Add
constraint over the ast node id.
(TopLevel::visit): Likewise.

Signed-off-by: Pierre-Emmanuel Patry 

Diff:
---
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index 72c3560b9daf..3b1ccc1d3c50 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -91,7 +91,7 @@ insert_macros (std::vector ¯os, 
NameResolutionContext &ctx)
 {
   auto res = ctx.macros.insert (macro.get_name (), macro.get_node_id ());
 
-  if (!res)
+  if (!res && res.error ().existing != macro.get_node_id ())
{
  rust_error_at (UNKNOWN_LOCATION, ErrorCode::E0428,
 "macro %qs defined multiple times",
@@ -167,7 +167,7 @@ TopLevel::visit (AST::MacroRulesDefinition ¯o)
 {
   auto res = ctx.macros.insert_at_root (macro.get_rule_name (),
macro.get_node_id ());
-  if (!res)
+  if (!res && res.error ().existing != macro.get_node_id ())
{
  // TODO: Factor this
  rich_location rich_loc (line_table, macro.get_locus ());


[gcc r15-2552] gccrs: late: Add bool builtin type

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:1a7e904a7f08670205af52d30020ac601cf258c7

commit r15-2552-g1a7e904a7f08670205af52d30020ac601cf258c7
Author: Arthur Cohen 
Date:   Thu Nov 9 00:39:46 2023 +0100

gccrs: late: Add bool builtin type

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc 
(Late::setup_builtin_types):
Setup bool as builtin type.

Diff:
---
 gcc/rust/resolve/rust-late-name-resolver-2.0.cc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index 3090bbeff2a9..ee06c4efc2ea 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -64,6 +64,7 @@ Late::setup_builtin_types ()
   };
 
   static const LType builtins[] = {
+{LType ("bool", new TyTy::BoolType (next_hir_id ()))},
 {LType ("u8", new TyTy::UintType (next_hir_id (), TyTy::UintType::U8))},
 {LType ("u16", new TyTy::UintType (next_hir_id (), TyTy::UintType::U16))},
 {LType ("u32", new TyTy::UintType (next_hir_id (), TyTy::UintType::U32))},


[gcc r15-2553] gccrs: Add modules to type namespace

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:06ce1b34fc0f1098ed45f25d52c05a6d8586c2c7

commit r15-2553-g06ce1b34fc0f1098ed45f25d52c05a6d8586c2c7
Author: Pierre-Emmanuel Patry 
Date:   Mon Jan 8 15:18:36 2024 +0100

gccrs: Add modules to type namespace

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::visit): 
Module
should be added to the type namespace in order to be retrieved 
later.

Signed-off-by: Pierre-Emmanuel Patry 

Diff:
---
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index 3b1ccc1d3c50..5e6f5e9bd78a 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -72,7 +72,7 @@ TopLevel::go (AST::Crate &crate)
 void
 TopLevel::visit (AST::Module &module)
 {
-  // FIXME: Do we need to insert the module in the type namespace?
+  insert_or_error_out (module.get_name (), module, Namespace::Types);
 
   auto sub_visitor = [this, &module] () {
 for (auto &item : module.get_items ())


[gcc r15-2554] gccrs: Add name resolution for on globbing use decl

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:8c331e24575c0584be372a78bb0bbcca914d567c

commit r15-2554-g8c331e24575c0584be372a78bb0bbcca914d567c
Author: Pierre-Emmanuel Patry 
Date:   Tue Jan 9 13:51:35 2024 +0100

gccrs: Add name resolution for on globbing use decl

This is the first part of the code required to enable globbing on use
declarations.

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc 
(GlobbingVisitor::visit):
Insert names into their namespace.
(TopLevel::visit): Insert ast module.
(TopLevel::handle_use_dec): Resolve use declaration.
(TopLevel::handle_use_glob): Use globbing visitor.
(flatten_list): Use globbing path vector.
(flatten_glob): Likewise.
(flatten): Likewise.
(prefix_subpaths): Add a function to prefix subpath.
* resolve/rust-toplevel-name-resolver-2.0.h (class GlobbingVisitor):
Add globbing visitor.
* util/rust-hir-map.cc (Mappings::insert_ast_module): Add function 
to
insert module in module hashmap.
(Mappings::lookup_ast_module): Add function to retrieve ast module.
* util/rust-hir-map.h: Add module map and getter/setter prototypes.

Signed-off-by: Pierre-Emmanuel Patry 

Diff:
---
 .../resolve/rust-toplevel-name-resolver-2.0.cc | 179 ++---
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h |  23 +++
 gcc/rust/util/rust-hir-map.cc  |  19 +++
 gcc/rust/util/rust-hir-map.h   |   3 +
 4 files changed, 199 insertions(+), 25 deletions(-)

diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index 5e6f5e9bd78a..3122d41412f7 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -25,6 +25,87 @@
 namespace Rust {
 namespace Resolver2_0 {
 
+void
+GlobbingVisitor::visit (AST::Module &module)
+{
+  if (module.get_visibility ().is_public ())
+ctx.insert (module.get_name (), module.get_node_id (), Namespace::Types);
+}
+
+void
+GlobbingVisitor::visit (AST::MacroRulesDefinition ¯o)
+{
+  if (macro.get_visibility ().is_public ())
+ctx.insert (macro.get_rule_name (), macro.get_node_id (),
+   Namespace::Macros);
+}
+
+void
+GlobbingVisitor::visit (AST::Function &function)
+{
+  if (function.get_visibility ().is_public ())
+ctx.insert (function.get_function_name (), function.get_node_id (),
+   Namespace::Values);
+}
+
+void
+GlobbingVisitor::visit (AST::StaticItem &static_item)
+{
+  if (static_item.get_visibility ().is_public ())
+ctx.insert (static_item.get_identifier (), static_item.get_node_id (),
+   Namespace::Values);
+}
+
+void
+GlobbingVisitor::visit (AST::StructStruct &struct_item)
+{
+  if (struct_item.get_visibility ().is_public ())
+ctx.insert (struct_item.get_identifier (), struct_item.get_node_id (),
+   Namespace::Values);
+}
+
+void
+GlobbingVisitor::visit (AST::TupleStruct &tuple_struct)
+{
+  if (tuple_struct.get_visibility ().is_public ())
+ctx.insert (tuple_struct.get_identifier (), tuple_struct.get_node_id (),
+   Namespace::Values);
+}
+
+void
+GlobbingVisitor::visit (AST::Enum &enum_item)
+{
+  if (enum_item.get_visibility ().is_public ())
+ctx.insert (enum_item.get_identifier (), enum_item.get_node_id (),
+   Namespace::Values);
+}
+
+void
+GlobbingVisitor::visit (AST::Union &union_item)
+{
+  if (union_item.get_visibility ().is_public ())
+ctx.insert (union_item.get_identifier (), union_item.get_node_id (),
+   Namespace::Values);
+}
+
+void
+GlobbingVisitor::visit (AST::ConstantItem &const_item)
+{
+  if (const_item.get_visibility ().is_public ())
+ctx.insert (const_item.get_identifier (), const_item.get_node_id (),
+   Namespace::Values);
+}
+
+void
+GlobbingVisitor::visit (AST::ExternCrate &crate)
+{}
+
+void
+GlobbingVisitor::visit (AST::UseDeclaration &use)
+{
+  // Handle cycles ?
+}
+
 TopLevel::TopLevel (NameResolutionContext &resolver)
   : DefaultResolver (resolver)
 {}
@@ -81,6 +162,10 @@ TopLevel::visit (AST::Module &module)
 
   ctx.scoped (Rib::Kind::Module, module.get_node_id (), sub_visitor,
  module.get_name ());
+
+  if (Analysis::Mappings::get ()->lookup_ast_module (module.get_node_id ())
+  == tl::nullopt)
+Analysis::Mappings::get ()->insert_ast_module (&module);
 }
 
 template 
@@ -302,13 +387,26 @@ TopLevel::visit (AST::ConstantItem &const_item)
 }
 
 bool
-TopLevel::handle_use_dec (AST::SimplePath path)
+TopLevel::handle_use_glob (AST::SimplePath glob)
 {
-  // TODO: Glob imports can get shadowed by regular imports and regular items.
-  // So we need to store them in a specific way in the ForeverStack - which can
-  // also probably be used by labels and macros etc. Like store it as a
-  // `S

[gcc r15-2555] gccrs: Shape up name resolver for normal direct calls

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:d284cf6fe2006df512b4e63f5db554ef39e9f3ab

commit r15-2555-gd284cf6fe2006df512b4e63f5db554ef39e9f3ab
Author: Pierre-Emmanuel Patry 
Date:   Wed Jan 10 16:44:09 2024 +0100

gccrs: Shape up name resolver for normal direct calls

Direct function calls did not work anymore due to the transition to the
new resolver.

gcc/rust/ChangeLog:

* checks/lints/rust-lint-marklive.cc (MarkLive::find_ref_node_id):
Add code path for the resolver 2.0
* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Remove 
failing
label context resolve call.

Signed-off-by: Pierre-Emmanuel Patry 

Diff:
---
 gcc/rust/checks/lints/rust-lint-marklive.cc | 23 +++
 gcc/rust/resolve/rust-late-name-resolver-2.0.cc |  3 ++-
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/gcc/rust/checks/lints/rust-lint-marklive.cc 
b/gcc/rust/checks/lints/rust-lint-marklive.cc
index 8787a9d85502..1a0a0a2b904b 100644
--- a/gcc/rust/checks/lints/rust-lint-marklive.cc
+++ b/gcc/rust/checks/lints/rust-lint-marklive.cc
@@ -20,8 +20,10 @@
 // from live codes are live, and everything else is dead.
 
 #include "rust-lint-marklive.h"
+#include "options.h"
 #include "rust-hir-full.h"
 #include "rust-name-resolver.h"
+#include "rust-immutable-name-resolution-context.h"
 
 namespace Rust {
 namespace Analysis {
@@ -270,12 +272,25 @@ MarkLive::mark_hir_id (HirId id)
 void
 MarkLive::find_ref_node_id (NodeId ast_node_id, NodeId &ref_node_id)
 {
-  if (!resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
+  if (flag_name_resolution_2_0)
 {
-  if (!resolver->lookup_resolved_type (ast_node_id, &ref_node_id))
+  auto nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+  nr_ctx.lookup (ast_node_id).map ([&ref_node_id] (NodeId resolved) {
+   ref_node_id = resolved;
+  });
+}
+  else
+{
+  if (!resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
{
- bool ok = resolver->lookup_resolved_misc (ast_node_id, &ref_node_id);
- rust_assert (ok);
+ if (!resolver->lookup_resolved_type (ast_node_id, &ref_node_id))
+   {
+ bool ok
+   = resolver->lookup_resolved_misc (ast_node_id, &ref_node_id);
+ rust_assert (ok);
+   }
}
 }
 }
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index ee06c4efc2ea..68eb88a1e4c9 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -196,8 +196,9 @@ Late::visit (AST::PathInExpression &expr)
   // in a function item` error here?
   // do we emit it in `get`?
 
-  auto label = ctx.labels.resolve_path (expr.get_segments ());
   auto value = ctx.values.resolve_path (expr.get_segments ());
+
+  ctx.map_usage (Usage (expr.get_node_id ()), Definition (*value));
 }
 
 void


[gcc r15-2557] gccrs: Make globbing definition shadowable by default

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:16e00f3b14cf5a36624c287cfcded74a38b55212

commit r15-2557-g16e00f3b14cf5a36624c287cfcded74a38b55212
Author: Pierre-Emmanuel Patry 
Date:   Mon Jan 15 16:34:36 2024 +0100

gccrs: Make globbing definition shadowable by default

Elements from glob use declaration shall be shadowable by default.

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.h: Add a new function prototype to 
insert
a shadowable definition.
* resolve/rust-forever-stack.hxx: Add the new insert_shadowable
function to insert shadowable definition into the forever stack.
* resolve/rust-name-resolution-context.cc 
(NameResolutionContext::insert_shadowable):
Likewise with the name resolution context.
* resolve/rust-name-resolution-context.h: Add name resolution 
context
insert_shadowable member function prototype.
* resolve/rust-toplevel-name-resolver-2.0.cc 
(GlobbingVisitor::visit):
Insert shadowable definition into the forever stack for glob use
declaration.

Signed-off-by: Pierre-Emmanuel Patry 

Diff:
---
 gcc/rust/resolve/rust-forever-stack.h  | 15 ++
 gcc/rust/resolve/rust-forever-stack.hxx| 10 +++
 gcc/rust/resolve/rust-name-resolution-context.cc   | 19 
 gcc/rust/resolve/rust-name-resolution-context.h|  3 ++
 .../resolve/rust-toplevel-name-resolver-2.0.cc | 35 +++---
 5 files changed, 65 insertions(+), 17 deletions(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.h 
b/gcc/rust/resolve/rust-forever-stack.h
index 01371fc7bcda..bba5875d4352 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -437,6 +437,21 @@ public:
*/
   tl::expected insert (Identifier name, NodeId id);
 
+  /**
+   * Insert a new shadowable definition in the innermost `Rib` in this stack
+   *
+   * @param name The name of the definition
+   * @param id Its NodeId
+   *
+   * @return `DuplicateNameError` if that node was already present in the Rib,
+   * the node's `NodeId` otherwise.
+   *
+   * @aborts if there are no `Rib`s inserted in the current map, this function
+   * aborts the program.
+   */
+  tl::expected insert_shadowable (Identifier name,
+ NodeId id);
+
   /**
* Insert a new definition at the root of this stack
*
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index a2fdce983629..008adff4676c 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -119,6 +119,16 @@ ForeverStack::insert (Identifier name, NodeId node)
   Rib::Definition::NonShadowable (node));
 }
 
+template 
+tl::expected
+ForeverStack::insert_shadowable (Identifier name, NodeId node)
+{
+  auto &innermost_rib = peek ();
+
+  return insert_inner (innermost_rib, name.as_string (),
+  Rib::Definition::Shadowable (node));
+}
+
 template 
 tl::expected
 ForeverStack::insert_at_root (Identifier name, NodeId node)
diff --git a/gcc/rust/resolve/rust-name-resolution-context.cc 
b/gcc/rust/resolve/rust-name-resolution-context.cc
index 0340d28f1278..e8529b70bcb7 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.cc
+++ b/gcc/rust/resolve/rust-name-resolution-context.cc
@@ -45,6 +45,25 @@ NameResolutionContext::insert (Identifier name, NodeId id, 
Namespace ns)
 }
 }
 
+tl::expected
+NameResolutionContext::insert_shadowable (Identifier name, NodeId id,
+ Namespace ns)
+{
+  switch (ns)
+{
+case Namespace::Values:
+  return values.insert_shadowable (name, id);
+case Namespace::Types:
+  return types.insert_shadowable (name, id);
+case Namespace::Macros:
+  return macros.insert_shadowable (name, id);
+case Namespace::Labels:
+default:
+  // return labels.insert (name, id);
+  rust_unreachable ();
+}
+}
+
 void
 NameResolutionContext::map_usage (Usage usage, Definition definition)
 {
diff --git a/gcc/rust/resolve/rust-name-resolution-context.h 
b/gcc/rust/resolve/rust-name-resolution-context.h
index 8702900d0f3a..74f110d54dee 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.h
+++ b/gcc/rust/resolve/rust-name-resolution-context.h
@@ -171,6 +171,9 @@ public:
   tl::expected insert (Identifier name, NodeId id,
   Namespace ns);
 
+  tl::expected
+  insert_shadowable (Identifier name, NodeId id, Namespace ns);
+
   /**
* Run a lambda in a "scoped" context, meaning that a new `Rib` will be 
pushed
* before executing the lambda and then popped. This is useful for all kinds
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index 501204174f22..7f4169a4d8e2 100644
---

[gcc r15-2556] gccrs: Add call to globbing visitor

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:f9ad1c29376e06950c3065f574f2df96b3265416

commit r15-2556-gf9ad1c29376e06950c3065f574f2df96b3265416
Author: Pierre-Emmanuel Patry 
Date:   Mon Jan 15 13:41:01 2024 +0100

gccrs: Add call to globbing visitor

Globbing visitor did not visit subitems.

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Add a check
for missing item.
* resolve/rust-toplevel-name-resolver-2.0.cc (GlobbingVisitor::go):
Add a new function in the visitor to dispatch the visitor to items 
in
the given module.
(TopLevel::handle_use_glob): Change call to visitor to use the 
pointer.
* resolve/rust-toplevel-name-resolver-2.0.h: Add prototype for new
member function.

Signed-off-by: Pierre-Emmanuel Patry 

Diff:
---
 gcc/rust/resolve/rust-late-name-resolver-2.0.cc | 2 ++
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc | 9 -
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h  | 1 +
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index 68eb88a1e4c9..d8bd9ac524f3 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -197,6 +197,8 @@ Late::visit (AST::PathInExpression &expr)
   // do we emit it in `get`?
 
   auto value = ctx.values.resolve_path (expr.get_segments ());
+  if (!value.has_value ())
+rust_unreachable (); // Should have been resolved earlier
 
   ctx.map_usage (Usage (expr.get_node_id ()), Definition (*value));
 }
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index 3122d41412f7..501204174f22 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -25,6 +25,13 @@
 namespace Rust {
 namespace Resolver2_0 {
 
+void
+GlobbingVisitor::go (AST::Module *module)
+{
+  for (auto &i : module->get_items ())
+visit (i);
+}
+
 void
 GlobbingVisitor::visit (AST::Module &module)
 {
@@ -399,7 +406,7 @@ TopLevel::handle_use_glob (AST::SimplePath glob)
 return false;
 
   GlobbingVisitor gvisitor (ctx);
-  gvisitor.visit (*result.value ());
+  gvisitor.go (result.value ());
 
   return true;
 }
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
index 31535a9b22e0..f5e224fa0499 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
@@ -33,6 +33,7 @@ class GlobbingVisitor : public AST::DefaultASTVisitor
 public:
   GlobbingVisitor (NameResolutionContext &ctx) : ctx (ctx) {}
 
+  void go (AST::Module *module);
   void visit (AST::Module &module) override;
   void visit (AST::MacroRulesDefinition ¯o) override;
   void visit (AST::Function &function) override;


[gcc r15-2558] gccrs: Add support for ambiguous use declarations

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:f085a67ebb079431a202df822a15315e440ed456

commit r15-2558-gf085a67ebb079431a202df822a15315e440ed456
Author: Pierre-Emmanuel Patry 
Date:   Tue Jan 16 13:55:02 2024 +0100

gccrs: Add support for ambiguous use declarations

Glob use declarations may lead to ambiguous situation where two
definitions with the same name are imported in a given scope. The
compiler now handles shadowable items inserted after non shadowable
items. An error is now thrown when multiple shadowable items are imported
and used in the same rib.

gcc/rust/ChangeLog:

* resolve/rust-early-name-resolver-2.0.cc (Early::visit): Adapt
resolved type to the new API.
(Early::visit_attributes): Retrieve the node id from the definition.
* resolve/rust-forever-stack.h: Change the return type of getter
functions. Those functions now return a definition type instead of a
node id.
* resolve/rust-forever-stack.hxx: Change member function 
implementation
in the forever stack to accomodate it's API changes.
* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Use internal
node id. Emit an error when resolving multiple ambiguous values.
* resolve/rust-rib.cc (Rib::Definition::Definition): Add a default
constructor.
(Rib::Definition::is_ambiguous): Add a new function to determine
whether a function definition is ambiguous or not.
(Rib::Definition::to_string): Add a member function to convert a 
given
definition to a string.
(Rib::insert): Add new rules for value insertion in a rib. Insertion
order does not impact the result anymore: inserting a shadowable 
value
after a non shadowable one does not trigger an error anymore. All
shadowable values inserted in a rib are kepts until being replaced 
by a
non shadowable one.
(Rib::get): Return a definition instead of a node id.
* resolve/rust-rib.h: Update function prototypes.
* resolve/rust-toplevel-name-resolver-2.0.cc 
(TopLevel::handle_use_glob):
Update return value container to match the new function's prototype.
(TopLevel::handle_use_dec): Likewise.
(flatten_glob): Likewise.

Signed-off-by: Pierre-Emmanuel Patry 

Diff:
---
 gcc/rust/resolve/rust-early-name-resolver-2.0.cc   | 18 +++---
 gcc/rust/resolve/rust-forever-stack.h  | 10 ++--
 gcc/rust/resolve/rust-forever-stack.hxx| 39 ++--
 gcc/rust/resolve/rust-late-name-resolver-2.0.cc| 17 --
 gcc/rust/resolve/rust-rib.cc   | 69 +-
 gcc/rust/resolve/rust-rib.h| 19 +-
 .../resolve/rust-toplevel-name-resolver-2.0.cc | 41 +++--
 7 files changed, 142 insertions(+), 71 deletions(-)

diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
index 982c696d2af1..af148b0c1c0d 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -152,9 +152,11 @@ Early::visit (AST::MacroInvocation &invoc)
 
   // 
https://doc.rust-lang.org/reference/macros-by-example.html#path-based-scope
 
-  tl::optional definition = tl::nullopt;
+  tl::optional definition = tl::nullopt;
   if (path.get_segments ().size () == 1)
-definition = textual_scope.get (path.get_final_segment ().as_string ());
+definition
+  = textual_scope.get (path.get_final_segment ().as_string ())
+ .map ([] (NodeId id) { return Rib::Definition::NonShadowable (id); });
 
   // we won't have changed `definition` from `nullopt` if there are more
   // than one segments in our path
@@ -169,13 +171,13 @@ Early::visit (AST::MacroInvocation &invoc)
   return;
 }
 
-  insert_once (invoc, *definition);
+  insert_once (invoc, definition->get_node_id ());
 
   // now do we need to keep mappings or something? or insert "uses" into our
   // ForeverStack? can we do that? are mappings simpler?
   auto mappings = Analysis::Mappings::get ();
   AST::MacroRulesDefinition *rules_def = nullptr;
-  if (!mappings->lookup_macro_def (definition.value (), &rules_def))
+  if (!mappings->lookup_macro_def (definition->get_node_id (), &rules_def))
 {
   // Macro definition not found, maybe it is not expanded yet.
   return;
@@ -212,8 +214,8 @@ Early::visit_attributes (std::vector &attrs)
  continue;
}
 
- auto pm_def
-   = mappings->lookup_derive_proc_macro_def (definition.value ());
+ auto pm_def = mappings->lookup_derive_proc_macro_def (
+   definition->get_node_id ());
 
  rust_assert (pm_def.has_value ());
 
@@ -234,8 +236,8 @@ Early::visit_attributes (std::vector &attrs)

[gcc r15-2559] gccrs: Add tuple struct constructor to value namespace

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:d9d7f79a422f8669a5a7e6d627c764ba9f3eded9

commit r15-2559-gd9d7f79a422f8669a5a7e6d627c764ba9f3eded9
Author: Pierre-Emmanuel Patry 
Date:   Wed Jan 17 13:02:51 2024 +0100

gccrs: Add tuple struct constructor to value namespace

A tuple struct constructor should be inserted in the value namespace
during name resolution in order to reject multiple definitions of the
function.

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::visit): Add
the struct constructor to the value namespace.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Pierre-Emmanuel Patry 

Diff:
---
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc | 3 +++
 gcc/testsuite/rust/compile/name_resolution22.rs | 5 +
 2 files changed, 8 insertions(+)

diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index 6929bdb641e6..4134b9a46202 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -337,6 +337,9 @@ TopLevel::visit (AST::TupleStruct &tuple_struct)
 {
   insert_or_error_out (tuple_struct.get_struct_name (), tuple_struct,
   Namespace::Types);
+
+  insert_or_error_out (tuple_struct.get_struct_name (), tuple_struct,
+  Namespace::Values);
 }
 
 void
diff --git a/gcc/testsuite/rust/compile/name_resolution22.rs 
b/gcc/testsuite/rust/compile/name_resolution22.rs
new file mode 100644
index ..c49331ef38cd
--- /dev/null
+++ b/gcc/testsuite/rust/compile/name_resolution22.rs
@@ -0,0 +1,5 @@
+// { dg-options "-frust-name-resolution-2.0" }
+struct Marker;
+struct Foo(Marker);
+
+fn Foo(m: Marker) {} // { dg-error ".Foo. defined multiple times" }


[gcc r15-2560] gccrs: Change error message to match test

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:54d806b3f11bf1043499dd0a4240be177d40be71

commit r15-2560-g54d806b3f11bf1043499dd0a4240be177d40be71
Author: Pierre-Emmanuel Patry 
Date:   Wed Jan 17 13:53:21 2024 +0100

gccrs: Change error message to match test

Error message did not match the test from the previous name resolver when
a given path cannot be resolved.

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-path.cc 
(TypeCheckExpr::resolve_root_path):
Change error message to match old resolver and test case.

Signed-off-by: Pierre-Emmanuel Patry 

Diff:
---
 gcc/rust/typecheck/rust-hir-type-check-path.cc | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc 
b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index cdb506dacbe5..b0e52c454e9d 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -266,8 +266,10 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression 
&expr, size_t *offset,
{
  if (is_root)
{
- rust_error_at (seg.get_locus (),
-"failed to resolve root segment");
+ rust_error_at (expr.get_locus (), ErrorCode::E0425,
+"cannot find value %qs in this scope",
+expr.as_simple_path ().as_string ().c_str ());
+
  return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
}
  return root_tyty;


[gcc r15-2561] gccrs: Visit function return type in default resolver

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:73e6a3b5d6ad5cc816045ca000e4b700cfa68160

commit r15-2561-g73e6a3b5d6ad5cc816045ca000e4b700cfa68160
Author: Pierre-Emmanuel Patry 
Date:   Wed Jan 24 16:47:50 2024 +0100

gccrs: Visit function return type in default resolver

Function return type was not properly visited in the default resolver
visitor pattern.

gcc/rust/ChangeLog:

* resolve/rust-default-resolver.cc (DefaultResolver::visit): Visit
function return type.

Signed-off-by: Pierre-Emmanuel Patry 

Diff:
---
 gcc/rust/resolve/rust-default-resolver.cc | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gcc/rust/resolve/rust-default-resolver.cc 
b/gcc/rust/resolve/rust-default-resolver.cc
index e2609d13c9a6..d805bc9a511d 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -79,6 +79,9 @@ DefaultResolver::visit (AST::Function &function)
  }
   }
 
+if (function.has_return_type ())
+  visit (function.get_return_type ());
+
 if (function.has_body ())
   function.get_definition ().value ()->accept_vis (*this);
   };


[gcc r15-2562] gccrs: Visit constant item type in default resolver

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:f120362d022b0de351d3ddd4b29bc5404ba741a3

commit r15-2562-gf120362d022b0de351d3ddd4b29bc5404ba741a3
Author: Pierre-Emmanuel Patry 
Date:   Wed Jan 24 16:50:27 2024 +0100

gccrs: Visit constant item type in default resolver

The type of constant item expression was not properly visited in the
default resolver.

gcc/rust/ChangeLog:

* resolve/rust-default-resolver.cc (DefaultResolver::visit): Visit
constant item's types.

Signed-off-by: Pierre-Emmanuel Patry 

Diff:
---
 gcc/rust/resolve/rust-default-resolver.cc | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/resolve/rust-default-resolver.cc 
b/gcc/rust/resolve/rust-default-resolver.cc
index d805bc9a511d..0c2576f6e755 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -464,7 +464,10 @@ DefaultResolver::visit (AST::EnumItemDiscriminant &item)
 void
 DefaultResolver::visit (AST::ConstantItem &item)
 {
-  auto expr_vis = [this, &item] () { item.get_expr ().accept_vis (*this); };
+  auto expr_vis = [this, &item] () {
+item.get_expr ().accept_vis (*this);
+visit (item.get_type ());
+  };
 
   // FIXME: Why do we need a Rib here?
   ctx.scoped (Rib::Kind::Item, item.get_node_id (), expr_vis);


[gcc r15-2563] gccrs: Raw pointer type visitor didn't require overload

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:e206ac4f73c08931dfc776121ba23a4e5c93d3db

commit r15-2563-ge206ac4f73c08931dfc776121ba23a4e5c93d3db
Author: Pierre-Emmanuel Patry 
Date:   Wed Jan 24 16:57:37 2024 +0100

gccrs: Raw pointer type visitor didn't require overload

This overload did not dispatch the visitor to sub members of a raw
pointer like the default one. It is therefore useless as pointed type
shall be visited to be resolved correctly.

gcc/rust/ChangeLog:

* resolve/rust-default-resolver.cc (DefaultResolver::visit): Remove
function implementation.
* resolve/rust-default-resolver.h: Remove function prototype.

Signed-off-by: Pierre-Emmanuel Patry 

Diff:
---
 gcc/rust/resolve/rust-default-resolver.cc | 4 
 gcc/rust/resolve/rust-default-resolver.h  | 1 -
 2 files changed, 5 deletions(-)

diff --git a/gcc/rust/resolve/rust-default-resolver.cc 
b/gcc/rust/resolve/rust-default-resolver.cc
index 0c2576f6e755..f5546181b3c6 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -630,10 +630,6 @@ void
 DefaultResolver::visit (AST::TupleType &)
 {}
 
-void
-DefaultResolver::visit (AST::RawPointerType &)
-{}
-
 void
 DefaultResolver::visit (AST::ReferenceType &)
 {}
diff --git a/gcc/rust/resolve/rust-default-resolver.h 
b/gcc/rust/resolve/rust-default-resolver.h
index 97ad6d78be33..a19d70bc04d9 100644
--- a/gcc/rust/resolve/rust-default-resolver.h
+++ b/gcc/rust/resolve/rust-default-resolver.h
@@ -151,7 +151,6 @@ public:
   void visit (AST::ImplTraitTypeOneBound &);
   void visit (AST::TraitObjectTypeOneBound &);
   void visit (AST::TupleType &);
-  void visit (AST::RawPointerType &);
   void visit (AST::ReferenceType &);
   void visit (AST::ArrayType &);
   void visit (AST::SliceType &);


[gcc r15-2564] gccrs: Values shall be inserted in the value namespace

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:f5da34385410e966a8d517fe2425fcbbdad5617d

commit r15-2564-gf5da34385410e966a8d517fe2425fcbbdad5617d
Author: Pierre-Emmanuel Patry 
Date:   Wed Jan 24 17:00:29 2024 +0100

gccrs: Values shall be inserted in the value namespace

Values were inserted in the label namespace instead of the value
namespace this lead to several bugs.

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Change the
namespace for values from "label" to "values".

Signed-off-by: Pierre-Emmanuel Patry 

Diff:
---
 gcc/rust/resolve/rust-late-name-resolver-2.0.cc | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index 5c8d976b4170..dc7cde1b3233 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -151,7 +151,10 @@ Late::visit (AST::IdentifierPattern &identifier)
   // do we insert in labels or in values
   // but values does not allow shadowing... since functions cannot shadow
   // do we insert functions in labels as well?
-  new_label (identifier.get_ident (), identifier.get_node_id ());
+  auto ok
+= ctx.values.insert (identifier.get_ident (), identifier.get_node_id ());
+
+  rust_assert (ok);
 }
 
 void


[gcc r15-2565] gccrs: Unit struct constructor shall be resolved

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:97539b7c20eb08d5b6532016654ecc6ba6c9a09f

commit r15-2565-g97539b7c20eb08d5b6532016654ecc6ba6c9a09f
Author: Pierre-Emmanuel Patry 
Date:   Wed Jan 24 17:04:51 2024 +0100

gccrs: Unit struct constructor shall be resolved

Unit struct have a special constructor that should be added to the struct
namespace in order to be resolved later when called. As it is a function
it should be added in the value namespace.

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc 
(GlobbingVisitor::visit):
Add the struct constructor when the struct is a unit.

Signed-off-by: Pierre-Emmanuel Patry 

Diff:
---
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index 4134b9a46202..75d9bb82131f 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -68,8 +68,13 @@ void
 GlobbingVisitor::visit (AST::StructStruct &struct_item)
 {
   if (struct_item.get_visibility ().is_public ())
-ctx.insert_shadowable (struct_item.get_identifier (),
-  struct_item.get_node_id (), Namespace::Values);
+{
+  ctx.insert_shadowable (struct_item.get_identifier (),
+struct_item.get_node_id (), Namespace::Types);
+  if (struct_item.is_unit_struct ())
+   ctx.insert_shadowable (struct_item.get_identifier (),
+  struct_item.get_node_id (), Namespace::Values);
+}
 }
 
 void


[gcc r15-2566] gccrs: Add tuple struct to the type namespace

2024-08-01 Thread Arthur Cohen via Gcc-cvs
https://gcc.gnu.org/g:70f235ed8e3af9dc46da9ba2efd57434c041a6fc

commit r15-2566-g70f235ed8e3af9dc46da9ba2efd57434c041a6fc
Author: Pierre-Emmanuel Patry 
Date:   Wed Jan 24 17:06:56 2024 +0100

gccrs: Add tuple struct to the type namespace

Only tuple struct constructor was added to the resolver.

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc 
(GlobbingVisitor::visit):
Add tuple struct type to the resolver's context.

Signed-off-by: Pierre-Emmanuel Patry 

Diff:
---
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index 75d9bb82131f..820ba271ae0c 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -81,8 +81,13 @@ void
 GlobbingVisitor::visit (AST::TupleStruct &tuple_struct)
 {
   if (tuple_struct.get_visibility ().is_public ())
-ctx.insert_shadowable (tuple_struct.get_identifier (),
-  tuple_struct.get_node_id (), Namespace::Values);
+{
+  ctx.insert_shadowable (tuple_struct.get_identifier (),
+tuple_struct.get_node_id (), Namespace::Types);
+
+  ctx.insert_shadowable (tuple_struct.get_identifier (),
+tuple_struct.get_node_id (), Namespace::Values);
+}
 }
 
 void


  1   2   3   >