Re: [PATCH] build: Check for cargo when building rust language

2024-04-09 Thread Andrew Pinski
On Mon, Apr 8, 2024 at 9:39 AM  wrote:
>
> From: Pierre-Emmanuel Patry 
>
> Hello,
>
> The rust frontend requires cargo to build some of it's components,
> it's presence was not checked during configuration.

NOTE cargo itself is a huge security hole. If anything we should place
all of the required dependencies with the specific versions that has
been tested on gcc.gnu.org (with md5 sums) and download that instead
of depending on some random downloads via cargo. Talk about broken
supply chain when things are downloading things randomly off the
internet.

If there is a way to cache and use those specific versions using
cargo, that should be done but I suspect cargo does not work that way.
Also any time someone says this is a temporary measure it is NOT and
we should never treat it as such unless you already have a patch to
remove it.


Thanks,
Andrew Pinski


>
> Best regards,
> Pierre-Emmanuel
>
> --
>
> Prevent rust language from building when cargo is
> missing.
>
> config/ChangeLog:
>
> * acx.m4: Add a macro to check for rust
> components.
>
> ChangeLog:
>
> * configure: Regenerate.
> * configure.ac: Emit an error message when cargo
> is missing.
>
> Signed-off-by: Pierre-Emmanuel Patry 
> ---
>  config/acx.m4 |  11 +
>  configure | 117 ++
>  configure.ac  |  18 
>  3 files changed, 146 insertions(+)
>
> diff --git a/config/acx.m4 b/config/acx.m4
> index 7efe98aaf96..3c5fe67342e 100644
> --- a/config/acx.m4
> +++ b/config/acx.m4
> @@ -424,6 +424,17 @@ else
>  fi
>  ])
>
> +# Test for Rust
> +# We require cargo and rustc for some parts of the rust compiler.
> +AC_DEFUN([ACX_PROG_CARGO],
> +[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])
> +AC_CHECK_TOOL(CARGO, cargo, no)
> +if test "x$CARGO" != xno; then
> +  have_cargo=yes
> +else
> +  have_cargo=no
> +fi])
> +
>  # Test for D.
>  AC_DEFUN([ACX_PROG_GDC],
>  [AC_REQUIRE([AC_CHECK_TOOL_PREFIX])
> diff --git a/configure b/configure
> index 874966fb9f0..46e66e20197 100755
> --- a/configure
> +++ b/configure
> @@ -714,6 +714,7 @@ PGO_BUILD_GEN_CFLAGS
>  HAVE_CXX11_FOR_BUILD
>  HAVE_CXX11
>  do_compare
> +CARGO
>  GDC
>  GNATMAKE
>  GNATBIND
> @@ -5786,6 +5787,104 @@ else
>have_gdc=no
>  fi
>
> +
> +if test -n "$ac_tool_prefix"; then
> +  # Extract the first word of "${ac_tool_prefix}cargo", so it can be a 
> program name with args.
> +set dummy ${ac_tool_prefix}cargo; ac_word=$2
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
> +$as_echo_n "checking for $ac_word... " >&6; }
> +if ${ac_cv_prog_CARGO+:} false; then :
> +  $as_echo_n "(cached) " >&6
> +else
> +  if test -n "$CARGO"; then
> +  ac_cv_prog_CARGO="$CARGO" # Let the user override the test.
> +else
> +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
> +for as_dir in $PATH
> +do
> +  IFS=$as_save_IFS
> +  test -z "$as_dir" && as_dir=.
> +for ac_exec_ext in '' $ac_executable_extensions; do
> +  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
> +ac_cv_prog_CARGO="${ac_tool_prefix}cargo"
> +$as_echo "$as_me:${as_lineno-$LINENO}: found 
> $as_dir/$ac_word$ac_exec_ext" >&5
> +break 2
> +  fi
> +done
> +  done
> +IFS=$as_save_IFS
> +
> +fi
> +fi
> +CARGO=$ac_cv_prog_CARGO
> +if test -n "$CARGO"; then
> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CARGO" >&5
> +$as_echo "$CARGO" >&6; }
> +else
> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
> +$as_echo "no" >&6; }
> +fi
> +
> +
> +fi
> +if test -z "$ac_cv_prog_CARGO"; then
> +  ac_ct_CARGO=$CARGO
> +  # Extract the first word of "cargo", so it can be a program name with args.
> +set dummy cargo; ac_word=$2
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
> +$as_echo_n "checking for $ac_word... " >&6; }
> +if ${ac_cv_prog_ac_ct_CARGO+:} false; then :
> +  $as_echo_n "(cached) " >&6
> +else
> +  if test -n "$ac_ct_CARGO"; then
> +  ac_cv_prog_ac_ct_CARGO="$ac_ct_CARGO" # Let the user override the test.
> +else
> +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
> +for as_dir in $PATH
> +do
> +  IFS=$as_save_IFS
> +  test -z "$as_dir" && as_dir=.
> +for ac_exec_ext in '' $ac_executable_extensions; do
> +  if as_fn_executable_

Re: [PATCH] build: Check for cargo when building rust language

2024-04-16 Thread Andrew Pinski
On Mon, Apr 8, 2024 at 9:39 AM  wrote:
>
> From: Pierre-Emmanuel Patry 
>
> Hello,
>
> The rust frontend requires cargo to build some of it's components,
> it's presence was not checked during configuration.

WHY did this go in right before the release of GCC 14?
I don't get why this is considered temporary and it goes in right
before a release.
That seems broken to me.

Thanks,
Andrew

>
> Best regards,
> Pierre-Emmanuel
>
> --
>
> Prevent rust language from building when cargo is
> missing.
>
> config/ChangeLog:
>
> * acx.m4: Add a macro to check for rust
> components.
>
> ChangeLog:
>
> * configure: Regenerate.
> * configure.ac: Emit an error message when cargo
> is missing.
>
> Signed-off-by: Pierre-Emmanuel Patry 
> ---
>  config/acx.m4 |  11 +
>  configure | 117 ++
>  configure.ac  |  18 
>  3 files changed, 146 insertions(+)
>
> diff --git a/config/acx.m4 b/config/acx.m4
> index 7efe98aaf96..3c5fe67342e 100644
> --- a/config/acx.m4
> +++ b/config/acx.m4
> @@ -424,6 +424,17 @@ else
>  fi
>  ])
>
> +# Test for Rust
> +# We require cargo and rustc for some parts of the rust compiler.
> +AC_DEFUN([ACX_PROG_CARGO],
> +[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])
> +AC_CHECK_TOOL(CARGO, cargo, no)
> +if test "x$CARGO" != xno; then
> +  have_cargo=yes
> +else
> +  have_cargo=no
> +fi])
> +
>  # Test for D.
>  AC_DEFUN([ACX_PROG_GDC],
>  [AC_REQUIRE([AC_CHECK_TOOL_PREFIX])
> diff --git a/configure b/configure
> index 874966fb9f0..46e66e20197 100755
> --- a/configure
> +++ b/configure
> @@ -714,6 +714,7 @@ PGO_BUILD_GEN_CFLAGS
>  HAVE_CXX11_FOR_BUILD
>  HAVE_CXX11
>  do_compare
> +CARGO
>  GDC
>  GNATMAKE
>  GNATBIND
> @@ -5786,6 +5787,104 @@ else
>have_gdc=no
>  fi
>
> +
> +if test -n "$ac_tool_prefix"; then
> +  # Extract the first word of "${ac_tool_prefix}cargo", so it can be a 
> program name with args.
> +set dummy ${ac_tool_prefix}cargo; ac_word=$2
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
> +$as_echo_n "checking for $ac_word... " >&6; }
> +if ${ac_cv_prog_CARGO+:} false; then :
> +  $as_echo_n "(cached) " >&6
> +else
> +  if test -n "$CARGO"; then
> +  ac_cv_prog_CARGO="$CARGO" # Let the user override the test.
> +else
> +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
> +for as_dir in $PATH
> +do
> +  IFS=$as_save_IFS
> +  test -z "$as_dir" && as_dir=.
> +for ac_exec_ext in '' $ac_executable_extensions; do
> +  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
> +ac_cv_prog_CARGO="${ac_tool_prefix}cargo"
> +$as_echo "$as_me:${as_lineno-$LINENO}: found 
> $as_dir/$ac_word$ac_exec_ext" >&5
> +break 2
> +  fi
> +done
> +  done
> +IFS=$as_save_IFS
> +
> +fi
> +fi
> +CARGO=$ac_cv_prog_CARGO
> +if test -n "$CARGO"; then
> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CARGO" >&5
> +$as_echo "$CARGO" >&6; }
> +else
> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
> +$as_echo "no" >&6; }
> +fi
> +
> +
> +fi
> +if test -z "$ac_cv_prog_CARGO"; then
> +  ac_ct_CARGO=$CARGO
> +  # Extract the first word of "cargo", so it can be a program name with args.
> +set dummy cargo; ac_word=$2
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
> +$as_echo_n "checking for $ac_word... " >&6; }
> +if ${ac_cv_prog_ac_ct_CARGO+:} false; then :
> +  $as_echo_n "(cached) " >&6
> +else
> +  if test -n "$ac_ct_CARGO"; then
> +  ac_cv_prog_ac_ct_CARGO="$ac_ct_CARGO" # Let the user override the test.
> +else
> +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
> +for as_dir in $PATH
> +do
> +  IFS=$as_save_IFS
> +  test -z "$as_dir" && as_dir=.
> +for ac_exec_ext in '' $ac_executable_extensions; do
> +  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
> +ac_cv_prog_ac_ct_CARGO="cargo"
> +$as_echo "$as_me:${as_lineno-$LINENO}: found 
> $as_dir/$ac_word$ac_exec_ext" >&5
> +break 2
> +  fi
> +done
> +  done
> +IFS=$as_save_IFS
> +
> +fi
> +fi
> +ac_ct_CARGO=$ac_cv_prog_ac_ct_CARGO
> +if test -n "$ac_ct_CARGO"; then
> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CARGO" >&5
> +$as_echo "$ac_ct_CARGO" >&6; }
> +else
> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
> +$as_echo "no" >&6; }
> +fi
> +
> +  if test "x$ac_ct_CARGO" = x; then
> +CARGO="no"
> +  else
> +case $cross_compiling:$ac_tool_warned in
> +yes:)
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not 
> prefixed with host triplet" >&5
> +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" 
> >&2;}
> +ac_tool_warned=yes ;;
> +esac
> +CARGO=$ac_ct_CARGO
> +  fi
> +else
> +  CARGO="$ac_cv_prog_CARGO"
> +fi
> +
> +if test "x$CARGO" != xno; then
> +  have_cargo=yes
> +else
> +  have_cargo=no
> +fi
>  { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to compare 
> bootstrapped objects" >&5
>  $as_echo_n "checking how to compare bootstrapped objects... " >&6; }
>  if ${gcc_cv_prog_cmp_skip+:} 

[PATCH v2 1/4] rust: Use FLOAT_TYPE_P instead of manual checking

2025-03-19 Thread Andrew Pinski
This moves is_floating_point over to using FLOAT_TYPE_P instead
of manually checking. Note before it would return true for all
COMPLEX_TYPE but complex types' inner type could be integral.

Also fixes up the comment to be in more of the GNU style.

Bootstrapped and tested on x86_64-linux-gnu.

gcc/rust/ChangeLog:

* rust-gcc.cc (is_floating_point): Use FLOAT_TYPE_P
instead of manually checking the type.

Signed-off-by: Andrew Pinski 
---
 gcc/rust/rust-gcc.cc | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 273ab7889b0..43c4b3ee816 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -1018,12 +1018,12 @@ operator_to_tree_code (LazyBooleanOperator op)
 }
 }
 
-/* Helper function for deciding if a tree is a floating point node. */
+/* Returns true if the type of EXP is a floating point type.
+   False otherwise.  */
 bool
-is_floating_point (tree t)
+is_floating_point (tree exp)
 {
-  auto tree_type = TREE_CODE (TREE_TYPE (t));
-  return tree_type == REAL_TYPE || tree_type == COMPLEX_TYPE;
+  return FLOAT_TYPE_P (TREE_TYPE (exp));
 }
 
 // Return an expression for the negation operation OP EXPR.
-- 
2.43.0



[PATCH v2 0/4] rust: Small cleanups of rust-gcc.cc

2025-03-19 Thread Andrew Pinski
This is a set of 4 patches that do some small cleanups of rust-gcc.cc
The first patch might fix a bug in some cases but I am not 100% sure since
I suspect complex types here might only be floating point types but who knows.
The rest are using GCC's checks better or just other small changes that help
the readability.

Andrew Pinski (4):
  rust: Use FLOAT_TYPE_P instead of manual checking
  rust: Use error_operand_p in rust-gcc.cc
  rust: use range for inside rust-gcc.cc [PR119341]
  rust: Add comment inside block [PR119342]

 gcc/rust/rust-gcc.cc | 254 +++
 1 file changed, 114 insertions(+), 140 deletions(-)

-- 
2.43.0



[PATCH v2 3/4] rust: use range for inside rust-gcc.cc [PR119341]

2025-03-19 Thread Andrew Pinski
There are some places inside rust-gcc.cc which are candidates
to use range for instead of iterators directly. This changes
the locations I saw and makes the code slightly more readable.

gcc/rust/ChangeLog:

PR rust/119341
* rust-gcc.cc (function_type): Use range fors.
(function_type_variadic): Likewise.
(fill_in_fields): Likewise.
(statement_list): Likewise.
(block): Likewise.
(block_add_statements): Likewise.
(function_set_parameters): Likewise.
(write_global_definitions): Likewise.

Signed-off-by: Andrew Pinski 
---
 gcc/rust/rust-gcc.cc | 57 
 1 file changed, 21 insertions(+), 36 deletions(-)

diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 78e8ddbed00..1252798a87a 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -478,10 +478,9 @@ function_type (const typed_identifier &receiver,
   pp = &TREE_CHAIN (*pp);
 }
 
-  for (std::vector::const_iterator p = parameters.begin ();
-   p != parameters.end (); ++p)
+  for (const auto &p : parameters)
 {
-  tree t = p->type;
+  tree t = p.type;
   if (error_operand_p (t))
return error_mark_node;
   *pp = tree_cons (NULL_TREE, t, NULL_TREE);
@@ -527,10 +526,9 @@ function_type_variadic (const typed_identifier &receiver,
   if (receiver.type != NULL_TREE)
 args[offs++] = receiver.type;
 
-  for (std::vector::const_iterator p = parameters.begin ();
-   p != parameters.end (); ++p)
+  for (const auto &p : parameters)
 {
-  tree t = p->type;
+  tree t = p.type;
   if (error_operand_p (t))
return error_mark_node;
   args[offs++] = t;
@@ -608,14 +606,13 @@ fill_in_fields (tree fill, const 
std::vector &fields)
 {
   tree field_trees = NULL_TREE;
   tree *pp = &field_trees;
-  for (std::vector::const_iterator p = fields.begin ();
-   p != fields.end (); ++p)
+  for (const auto &p : fields)
 {
-  tree name_tree = get_identifier_from_string (p->name);
-  tree type_tree = p->type;
+  tree name_tree = get_identifier_from_string (p.name);
+  tree type_tree = p.type;
   if (error_operand_p (type_tree))
return error_mark_node;
-  tree field = build_decl (p->location, FIELD_DECL, name_tree, type_tree);
+  tree field = build_decl (p.location, FIELD_DECL, name_tree, type_tree);
   DECL_CONTEXT (field) = fill;
   *pp = field;
   pp = &DECL_CHAIN (field);
@@ -1721,10 +1718,8 @@ tree
 statement_list (const std::vector &statements)
 {
   tree stmt_list = NULL_TREE;
-  for (std::vector::const_iterator p = statements.begin ();
-   p != statements.end (); ++p)
+  for (tree t : statements)
 {
-  tree t = (*p);
   if (error_operand_p (t))
return error_mark_node;
   append_to_statement_list (t, &stmt_list);
@@ -1778,10 +1773,9 @@ block (tree fndecl, tree enclosing, const 
std::vector &vars,
 }
 
   tree *pp = &BLOCK_VARS (block_tree);
-  for (std::vector::const_iterator pv = vars.begin ();
-   pv != vars.end (); ++pv)
+  for (Bvariable *bv : vars)
 {
-  *pp = (*pv)->get_decl ();
+  *pp = bv->get_decl ();
   if (!error_operand_p (*pp))
pp = &DECL_CHAIN (*pp);
 }
@@ -1801,10 +1795,8 @@ void
 block_add_statements (tree bind_tree, const std::vector &statements)
 {
   tree stmt_list = NULL_TREE;
-  for (std::vector::const_iterator p = statements.begin ();
-   p != statements.end (); ++p)
+  for (tree s : statements)
 {
-  tree s = (*p);
   if (!error_operand_p (s))
append_to_statement_list (s, &stmt_list);
 }
@@ -2248,10 +2240,9 @@ function_set_parameters (tree function,
 
   tree params = NULL_TREE;
   tree *pp = ¶ms;
-  for (std::vector::const_iterator pv = param_vars.begin ();
-   pv != param_vars.end (); ++pv)
+  for (Bvariable *bv : param_vars)
 {
-  *pp = (*pv)->get_decl ();
+  *pp = bv->get_decl ();
   gcc_assert (!error_operand_p (*pp));
   pp = &DECL_CHAIN (*pp);
 }
@@ -2277,10 +2268,9 @@ write_global_definitions (const std::vector 
&type_decls,
 
   // Convert all non-erroneous declarations into Gimple form.
   size_t i = 0;
-  for (std::vector::const_iterator p = variable_decls.begin ();
-   p != variable_decls.end (); ++p)
+  for (Bvariable *bv : variable_decls)
 {
-  tree v = (*p)->get_decl ();
+  tree v = bv->get_decl ();
   if (error_operand_p (v))
continue;
defs[i] = v;
@@ -2288,10 +2278,8 @@ write_global_definitions (const std::vector 
&type_decls,
++i;
 }
 
-  for (std::vector::const_iterator p = type_decls.begin ();
-   p != type_decls.end (); ++p)
+  for (tree type_tree : type_decls)
 {
-  tree type_tree = (*p);
   if (!error_operand_p (type_tree) && IS_TYPE_OR_DECL_P (type_tree))
{
  

[PATCH v2 4/4] rust: Add comment inside block [PR119342]

2025-03-19 Thread Andrew Pinski
Inside a BLOCK node, all of the variables of the scope/block
are chained together and that connects them to the block.
This just adds a comment to that effect as reading the code
it is not so obvious why they need to be chained together.

gcc/rust/ChangeLog:

PR rust/119342
* rust-gcc.cc (block): Add comment on why chaining
the variables of the scope toether.

Signed-off-by: Andrew Pinski 
---
 gcc/rust/rust-gcc.cc | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 1252798a87a..32d3aabbbe4 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -1772,6 +1772,8 @@ block (tree fndecl, tree enclosing, const 
std::vector &vars,
   *pp = block_tree;
 }
 
+  // Chain the variables of the scope together so they are all connected
+  // to the block.
   tree *pp = &BLOCK_VARS (block_tree);
   for (Bvariable *bv : vars)
 {
-- 
2.43.0



[PATCH 2/4] rust: Use error_operand_p in rust-gcc.cc

2025-03-17 Thread Andrew Pinski
Just a simple cleanupof the code to use error_operand_p
instead of directly comparing against error_mark_node.

This also moves some cdoe around when dealing with error_operand_p
just to be faster and/or slightly tighten up the code slightly.

gcc/rust/ChangeLog:

* rust-gcc.cc (Bvariable::get_tree): Use error_operand_p.
(pointer_type): Likewise.
(reference_type): Likewise.
(immutable_type): Likewise.
(function_type): Likewise.
(function_type_variadic): Likewise.
Cleanup the check for receiver.type first.
(function_ptr_type): Use error_operand_p.
(fill_in_fields): Likewise.
(fill_in_array): Likewise.
(named_type): Likewise.
(type_size): Likewise.
(type_alignment): Likewise.
(type_field_alignment): Likewise.
(type_field_offset): Likewise.
(zero_expression): Likewise.
(float_constant_expression): Likewise.
(convert_expression): Likewise.
(struct_field_expression): Likewise.
(compound_expression): Likewise.
(conditional_expression): Likewise.
(negation_expression): Likewise.
(arithmetic_or_logical_expression): Likewise.
(arithmetic_or_logical_expression_checked): Likewise.
(comparison_expression): Likewise.
(lazy_boolean_expression): Likewise.
(constructor_expression): Likewise.
(array_constructor_expression): Likewise.
(array_index_expression): Likewise.
(call_expression): Likewise.
(init_statement): Likewise.
(assignment_statement): Likewise.
(return_statement): Likewise.
(exception_handler_statement): Likewise.
(if_statement): Likewise.
(compound_statement): Likewise.
Tighten up the code, removing t variable.
(statement_list): Use error_operand_p.
(block): Likewise.
(block_add_statements): Likewise.
(convert_tree): Likewise.
(global_variable): Likewise.
(global_variable_set_init): Likewise.
(local_variable): Likewise.
(parameter_variable): Likewise.
(static_chain_variable): Likewise.
(temporary_variable): Likewise.
(function): Likewise. Tighten up the code.
(function_defer_statement): Use error_operand_p.
(function_set_parameters): Use error_operand_p.
(write_global_definitions): Use error_operand_p.
Tighten up the code around the loop.

Signed-off-by: Andrew Pinski 
---
 gcc/rust/rust-gcc.cc | 183 ---
 1 file changed, 85 insertions(+), 98 deletions(-)

diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index e877c034452..f8b29bc6cf1 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -61,7 +61,7 @@
 tree
 Bvariable::get_tree (location_t location) const
 {
-  if (this->t_ == error_mark_node)
+  if (error_operand_p (this->t_))
 return error_mark_node;
 
   TREE_USED (this->t_) = 1;
@@ -431,7 +431,7 @@ float_type (int bits)
 tree
 pointer_type (tree to_type)
 {
-  if (to_type == error_mark_node)
+  if (error_operand_p (to_type))
 return error_mark_node;
   tree type = build_pointer_type (to_type);
   return type;
@@ -442,7 +442,7 @@ pointer_type (tree to_type)
 tree
 reference_type (tree to_type)
 {
-  if (to_type == error_mark_node)
+  if (error_operand_p (to_type))
 return error_mark_node;
   tree type = build_reference_type (to_type);
   return type;
@@ -453,7 +453,7 @@ reference_type (tree to_type)
 tree
 immutable_type (tree base)
 {
-  if (base == error_mark_node)
+  if (error_operand_p (base))
 return error_mark_node;
   tree constified = build_qualified_type (base, TYPE_QUAL_CONST);
   return constified;
@@ -472,7 +472,7 @@ function_type (const typed_identifier &receiver,
   if (receiver.type != NULL_TREE)
 {
   tree t = receiver.type;
-  if (t == error_mark_node)
+  if (error_operand_p (t))
return error_mark_node;
   *pp = tree_cons (NULL_TREE, t, NULL_TREE);
   pp = &TREE_CHAIN (*pp);
@@ -482,7 +482,7 @@ function_type (const typed_identifier &receiver,
p != parameters.end (); ++p)
 {
   tree t = p->type;
-  if (t == error_mark_node)
+  if (error_operand_p (t))
return error_mark_node;
   *pp = tree_cons (NULL_TREE, t, NULL_TREE);
   pp = &TREE_CHAIN (*pp);
@@ -502,11 +502,11 @@ function_type (const typed_identifier &receiver,
   gcc_assert (result_struct != NULL);
   result = result_struct;
 }
-  if (result == error_mark_node)
+  if (error_operand_p (result))
 return error_mark_node;
 
   tree fntype = build_function_type (result, args);
-  if (fntype == error_mark_node)
+  if (error_operand_p (fntype))
 return error_mark_node;
 
   return build_pointer_type (fntype);
@@ -521,21 +521,17 @@ function_type_variadic (const typed_identifier &receiver,
   size_t n = parameters.size () + (receiver

[PATCH 3/4] rust: use range for inside rust-gcc.cc [PR119341]

2025-03-17 Thread Andrew Pinski
There are some places inside rust-gcc.cc which are candidates
to use range for instead of iterators directly. This changes
the locations I saw and makes the code slightly more readable.

gcc/rust/ChangeLog:

PR rust/119341
* rust-gcc.cc (function_type): Use range fors.
(function_type_variadic): Likewise.
(fill_in_fields): Likewise.
(statement_list): Likewise.
(block): Likewise.
(block_add_statements): Likewise.
(function_set_parameters): Likewise.
(write_global_definitions): Likewise.

Signed-off-by: Andrew Pinski 
---
 gcc/rust/rust-gcc.cc | 56 +---
 1 file changed, 21 insertions(+), 35 deletions(-)

diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index f8b29bc6cf1..8a740f72513 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -478,10 +478,9 @@ function_type (const typed_identifier &receiver,
   pp = &TREE_CHAIN (*pp);
 }
 
-  for (std::vector::const_iterator p = parameters.begin ();
-   p != parameters.end (); ++p)
+  for (const auto &p : parameters)
 {
-  tree t = p->type;
+  tree t = p.type;
   if (error_operand_p (t))
return error_mark_node;
   *pp = tree_cons (NULL_TREE, t, NULL_TREE);
@@ -527,10 +526,9 @@ function_type_variadic (const typed_identifier &receiver,
   if (receiver.type != NULL_TREE)
 args[offs++] = receiver.type;
 
-  for (std::vector::const_iterator p = parameters.begin ();
-   p != parameters.end (); ++p)
+  for (const auto &p : parameters)
 {
-  tree t = p->type;
+  tree t = p.type;
   if (error_operand_p (t))
return error_mark_node;
   args[offs++] = t;
@@ -608,14 +606,13 @@ fill_in_fields (tree fill, const 
std::vector &fields)
 {
   tree field_trees = NULL_TREE;
   tree *pp = &field_trees;
-  for (std::vector::const_iterator p = fields.begin ();
-   p != fields.end (); ++p)
+  for (const auto &p : fields)
 {
-  tree name_tree = get_identifier_from_string (p->name);
-  tree type_tree = p->type;
+  tree name_tree = get_identifier_from_string (p.name);
+  tree type_tree = p.type;
   if (error_operand_p (type_tree))
return error_mark_node;
-  tree field = build_decl (p->location, FIELD_DECL, name_tree, type_tree);
+  tree field = build_decl (p.location, FIELD_DECL, name_tree, type_tree);
   DECL_CONTEXT (field) = fill;
   *pp = field;
   pp = &DECL_CHAIN (field);
@@ -1721,10 +1718,8 @@ tree
 statement_list (const std::vector &statements)
 {
   tree stmt_list = NULL_TREE;
-  for (std::vector::const_iterator p = statements.begin ();
-   p != statements.end (); ++p)
+  for (tree t : statements)
 {
-  tree t = (*p);
   if (error_operand_p (t))
return error_mark_node;
   append_to_statement_list (t, &stmt_list);
@@ -1778,10 +1773,9 @@ block (tree fndecl, tree enclosing, const 
std::vector &vars,
 }
 
   tree *pp = &BLOCK_VARS (block_tree);
-  for (std::vector::const_iterator pv = vars.begin ();
-   pv != vars.end (); ++pv)
+  for (Bvariable *bv : vars)
 {
-  *pp = (*pv)->get_decl ();
+  *pp = bv->get_decl ();
   if (!error_operand_p (*pp))
pp = &DECL_CHAIN (*pp);
 }
@@ -1801,10 +1795,8 @@ void
 block_add_statements (tree bind_tree, const std::vector &statements)
 {
   tree stmt_list = NULL_TREE;
-  for (std::vector::const_iterator p = statements.begin ();
-   p != statements.end (); ++p)
+  for (tree s : statements)
 {
-  tree s = (*p);
   if (!error_operand_p (s))
append_to_statement_list (s, &stmt_list);
 }
@@ -2248,10 +2240,9 @@ function_set_parameters (tree function,
 
   tree params = NULL_TREE;
   tree *pp = ¶ms;
-  for (std::vector::const_iterator pv = param_vars.begin ();
-   pv != param_vars.end (); ++pv)
+  for (Bvariable *bv : param_vars)
 {
-  *pp = (*pv)->get_decl ();
+  *pp = bv->get_decl ();
   gcc_assert (!error_operand_p (*pp));
   pp = &DECL_CHAIN (*pp);
 }
@@ -2277,10 +2268,9 @@ write_global_definitions (const std::vector 
&type_decls,
 
   // Convert all non-erroneous declarations into Gimple form.
   size_t i = 0;
-  for (std::vector::const_iterator p = variable_decls.begin ();
-   p != variable_decls.end (); ++p)
+  for (Bvariable *bv : variable_decls)
 {
-  tree v = (*p)->get_decl ();
+  tree v = bv->get_decl ();
   if (error_operand_p (v))
continue;
defs[i] = v;
@@ -2288,8 +2278,7 @@ write_global_definitions (const std::vector 
&type_decls,
++i;
 }
 
-  for (std::vector::const_iterator p = type_decls.begin ();
-   p != type_decls.end (); ++p)
+  for (tree type_tree : type_decls)
 {
   tree type_tree = (*p);
   if (type_tree != error_mark_node && IS_TYPE_OR_DECL_P (type_tree))
@@ -2300,20 +228

[PATCH 1/4] rust: Use REAL_TYPE_P instead of manual checking

2025-03-17 Thread Andrew Pinski
This moves is_floating_point over to using REAL_TYPE_P instead
of manually checking. Note before it would return true for all
COMPLEX_TYPE but complex types' inner type could be integral.

Also fixes up the comment to be in more of the GNU style.

Bootstrapped and tested on x86_64-linux-gnu.

gcc/rust/ChangeLog:

* rust-gcc.cc (is_floating_point): Use REAL_TYPE_P
instead of manually checking the type.

Signed-off-by: Andrew Pinski 
---
 gcc/rust/rust-gcc.cc | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 273ab7889b0..e877c034452 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -1018,12 +1018,12 @@ operator_to_tree_code (LazyBooleanOperator op)
 }
 }
 
-/* Helper function for deciding if a tree is a floating point node. */
+/* Returns true if the type of EXP is a floating point type.
+   False otherwise.  */
 bool
-is_floating_point (tree t)
+is_floating_point (tree exp)
 {
-  auto tree_type = TREE_CODE (TREE_TYPE (t));
-  return tree_type == REAL_TYPE || tree_type == COMPLEX_TYPE;
+  return REAL_TYPE_P (TREE_TYPE (exp));
 }
 
 // Return an expression for the negation operation OP EXPR.
-- 
2.43.0



[PATCH 4/4] rust: Add comment inside block [PR119342]

2025-03-17 Thread Andrew Pinski
Inside a BLOCK node, all of the variables of the scope/block
are chained together and that connects them to the block.
This just adds a comment to that effect as reading the code
it is not so obvious why they need to be chained together.

gcc/rust/ChangeLog:

PR rust/119342
* rust-gcc.cc (block): Add comment on why chaining
the variables of the scope toether.

Signed-off-by: Andrew Pinski 
---
 gcc/rust/rust-gcc.cc | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 8a740f72513..53950a35fdc 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -1772,6 +1772,8 @@ block (tree fndecl, tree enclosing, const 
std::vector &vars,
   *pp = block_tree;
 }
 
+  // Chain the variables of the scope together so they are all connected
+  // to the block.
   tree *pp = &BLOCK_VARS (block_tree);
   for (Bvariable *bv : vars)
 {
-- 
2.43.0



[PATCH v2 2/4] rust: Use error_operand_p in rust-gcc.cc

2025-03-19 Thread Andrew Pinski
Just a simple cleanupof the code to use error_operand_p
instead of directly comparing against error_mark_node.

This also moves some cdoe around when dealing with error_operand_p
just to be faster and/or slightly tighten up the code slightly.

gcc/rust/ChangeLog:

* rust-gcc.cc (Bvariable::get_tree): Use error_operand_p.
(pointer_type): Likewise.
(reference_type): Likewise.
(immutable_type): Likewise.
(function_type): Likewise.
(function_type_variadic): Likewise.
Cleanup the check for receiver.type first.
(function_ptr_type): Use error_operand_p.
(fill_in_fields): Likewise.
(fill_in_array): Likewise.
(named_type): Likewise.
(type_size): Likewise.
(type_alignment): Likewise.
(type_field_alignment): Likewise.
(type_field_offset): Likewise.
(zero_expression): Likewise.
(float_constant_expression): Likewise.
(convert_expression): Likewise.
(struct_field_expression): Likewise.
(compound_expression): Likewise.
(conditional_expression): Likewise.
(negation_expression): Likewise.
(arithmetic_or_logical_expression): Likewise.
(arithmetic_or_logical_expression_checked): Likewise.
(comparison_expression): Likewise.
(lazy_boolean_expression): Likewise.
(constructor_expression): Likewise.
(array_constructor_expression): Likewise.
(array_index_expression): Likewise.
(call_expression): Likewise.
(init_statement): Likewise.
(assignment_statement): Likewise.
(return_statement): Likewise.
(exception_handler_statement): Likewise.
(if_statement): Likewise.
(compound_statement): Likewise.
Tighten up the code, removing t variable.
(statement_list): Use error_operand_p.
(block): Likewise.
(block_add_statements): Likewise.
(convert_tree): Likewise.
(global_variable): Likewise.
(global_variable_set_init): Likewise.
(local_variable): Likewise.
(parameter_variable): Likewise.
(static_chain_variable): Likewise.
(temporary_variable): Likewise.
(function): Likewise. Tighten up the code.
(function_defer_statement): Use error_operand_p.
(function_set_parameters): Use error_operand_p.
(write_global_definitions): Use error_operand_p.
Tighten up the code around the loop.

Signed-off-by: Andrew Pinski 
---
 gcc/rust/rust-gcc.cc | 189 ---
 1 file changed, 88 insertions(+), 101 deletions(-)

diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 43c4b3ee816..78e8ddbed00 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -61,7 +61,7 @@
 tree
 Bvariable::get_tree (location_t location) const
 {
-  if (this->t_ == error_mark_node)
+  if (error_operand_p (this->t_))
 return error_mark_node;
 
   TREE_USED (this->t_) = 1;
@@ -431,7 +431,7 @@ float_type (int bits)
 tree
 pointer_type (tree to_type)
 {
-  if (to_type == error_mark_node)
+  if (error_operand_p (to_type))
 return error_mark_node;
   tree type = build_pointer_type (to_type);
   return type;
@@ -442,7 +442,7 @@ pointer_type (tree to_type)
 tree
 reference_type (tree to_type)
 {
-  if (to_type == error_mark_node)
+  if (error_operand_p (to_type))
 return error_mark_node;
   tree type = build_reference_type (to_type);
   return type;
@@ -453,7 +453,7 @@ reference_type (tree to_type)
 tree
 immutable_type (tree base)
 {
-  if (base == error_mark_node)
+  if (error_operand_p (base))
 return error_mark_node;
   tree constified = build_qualified_type (base, TYPE_QUAL_CONST);
   return constified;
@@ -472,7 +472,7 @@ function_type (const typed_identifier &receiver,
   if (receiver.type != NULL_TREE)
 {
   tree t = receiver.type;
-  if (t == error_mark_node)
+  if (error_operand_p (t))
return error_mark_node;
   *pp = tree_cons (NULL_TREE, t, NULL_TREE);
   pp = &TREE_CHAIN (*pp);
@@ -482,7 +482,7 @@ function_type (const typed_identifier &receiver,
p != parameters.end (); ++p)
 {
   tree t = p->type;
-  if (t == error_mark_node)
+  if (error_operand_p (t))
return error_mark_node;
   *pp = tree_cons (NULL_TREE, t, NULL_TREE);
   pp = &TREE_CHAIN (*pp);
@@ -502,11 +502,11 @@ function_type (const typed_identifier &receiver,
   gcc_assert (result_struct != NULL);
   result = result_struct;
 }
-  if (result == error_mark_node)
+  if (error_operand_p (result))
 return error_mark_node;
 
   tree fntype = build_function_type (result, args);
-  if (fntype == error_mark_node)
+  if (error_operand_p (fntype))
 return error_mark_node;
 
   return build_pointer_type (fntype);
@@ -521,21 +521,17 @@ function_type_variadic (const typed_identifier &receiver,
   size_t n = parameters.size () + (receiver

Re: [COMMITTED 09/42] gccrs: Add llvmInlineAsm node

2025-04-28 Thread Andrew Pinski
On Mon, Apr 28, 2025 at 8:48 AM  wrote:
>
> From: Pierre-Emmanuel Patry 
>
> InlineAsm node does not support memory clobbers.

A few review on this.
I think this should just be called extended rather than referencing LLVM here.

>
> gcc/rust/ChangeLog:
>
> * ast/rust-ast-collector.cc (TokenCollector::visit): Make visitor
> unreachable.
> * ast/rust-ast-collector.h: Add visit for LlvmInlineAsmNode.
> * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Add visit
> function for the default ast visitor.
> * ast/rust-ast-visitor.h: Add function prototype.
> * ast/rust-ast.cc (LlvmInlineAsm::accept_vis): Add accept_vis to
> LlvmInlineAsm node.
> * ast/rust-ast.h: Add LlvmInlineAsm node kind.
> * ast/rust-expr.h (class LlvmInlineAsm): Add LlvmInlineAsm node.
> * expand/rust-derive.h: Add visit function for LlvmInlineAsm node.
> * expand/rust-macro-builtins-asm.cc (MacroBuiltin::llvm_asm_handler):
> Add handler for llvm inline assembly nodes.
> (parse_llvm_asm): Add function to parse llvm assembly nodes.
> * expand/rust-macro-builtins-asm.h (parse_llvm_asm): Add function
> prototypes.
> * expand/rust-macro-builtins.cc (inline_llvm_asm_maker): Add macro
> transcriber.
> * expand/rust-macro-builtins.h: Add transcriber function prototype.
> * hir/rust-ast-lower-base.cc (ASTLoweringBase::visit): Add visit
> function for LlvmInlineAsm node.
> * hir/rust-ast-lower-base.h: Add visit function prototype.
> * resolve/rust-ast-resolve-base.cc (ResolverBase::visit): Add visit
> function for LlvmInlineAsm node.
> * resolve/rust-ast-resolve-base.h: Add visit function prototype.
>
> Signed-off-by: Pierre-Emmanuel Patry 
> ---
>  gcc/rust/ast/rust-ast-collector.cc | 10 -
>  gcc/rust/ast/rust-ast-collector.h  |  1 +
>  gcc/rust/ast/rust-ast-visitor.cc   |  4 ++
>  gcc/rust/ast/rust-ast-visitor.h|  2 +
>  gcc/rust/ast/rust-ast.cc   |  6 +++
>  gcc/rust/ast/rust-ast.h|  1 +
>  gcc/rust/ast/rust-expr.h   | 48 ++
>  gcc/rust/expand/rust-derive.h  |  1 +
>  gcc/rust/expand/rust-macro-builtins-asm.cc | 21 ++
>  gcc/rust/expand/rust-macro-builtins-asm.h  |  7 
>  gcc/rust/expand/rust-macro-builtins.cc | 11 -
>  gcc/rust/expand/rust-macro-builtins.h  |  4 ++
>  gcc/rust/hir/rust-ast-lower-base.cc|  4 ++
>  gcc/rust/hir/rust-ast-lower-base.h |  1 +
>  gcc/rust/resolve/rust-ast-resolve-base.cc  |  4 ++
>  gcc/rust/resolve/rust-ast-resolve-base.h   |  1 +
>  16 files changed, 124 insertions(+), 2 deletions(-)
>
> diff --git a/gcc/rust/ast/rust-ast-collector.cc 
> b/gcc/rust/ast/rust-ast-collector.cc
> index 8ee63752f32..90ff2e36251 100644
> --- a/gcc/rust/ast/rust-ast-collector.cc
> +++ b/gcc/rust/ast/rust-ast-collector.cc
> @@ -1520,7 +1520,15 @@ TokenCollector::visit (AsyncBlockExpr &expr)
>
>  void
>  TokenCollector::visit (InlineAsm &expr)
> -{}
> +{
> +  rust_unreachable ();
> +}
> +
> +void
> +TokenCollector::visit (LlvmInlineAsm &expr)
> +{
> +  rust_unreachable ();
> +}
>
>  // rust-item.h
>
> diff --git a/gcc/rust/ast/rust-ast-collector.h 
> b/gcc/rust/ast/rust-ast-collector.h
> index b014c23ed0b..f45e3cc51ae 100644
> --- a/gcc/rust/ast/rust-ast-collector.h
> +++ b/gcc/rust/ast/rust-ast-collector.h
> @@ -303,6 +303,7 @@ public:
>void visit (AwaitExpr &expr);
>void visit (AsyncBlockExpr &expr);
>void visit (InlineAsm &expr);
> +  void visit (LlvmInlineAsm &expr);
>// rust-item.h
>void visit (TypeParam ¶m);
>void visit (LifetimeWhereClauseItem &item);
> diff --git a/gcc/rust/ast/rust-ast-visitor.cc 
> b/gcc/rust/ast/rust-ast-visitor.cc
> index 9d524c3cc4c..beb3360c4e1 100644
> --- a/gcc/rust/ast/rust-ast-visitor.cc
> +++ b/gcc/rust/ast/rust-ast-visitor.cc
> @@ -713,6 +713,10 @@ DefaultASTVisitor::visit (AST::InlineAsm &expr)
>  }
>  }
>
> +void
> +DefaultASTVisitor::visit (AST::LlvmInlineAsm &expr)
> +{}
> +
>  void
>  DefaultASTVisitor::visit (AST::TypeParam ¶m)
>  {
> diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h
> index 51661df76b4..6d243e7b063 100644
> --- a/gcc/rust/ast/rust-ast-visitor.h
> +++ b/gcc/rust/ast/rust-ast-visitor.h
> @@ -131,6 +131,7 @@ public:
>virtual void visit (AwaitExpr &expr) = 0;
>virtual void visit (AsyncBlockExpr &expr) = 0;
>virtual void visit (InlineAsm &expr) = 0;
> +  virtual void visit (LlvmInlineAsm &expr) = 0;
>
>// rust-item.h
>virtual void visit (TypeParam ¶m) = 0;
> @@ -314,6 +315,7 @@ public:
>virtual void visit (AST::AwaitExpr &expr) override;
>virtual void visit (AST::AsyncBlockExpr &expr) override;
>virtual void visit (InlineAsm &expr) override;
> +  virtual void visit (LlvmInlineAsm &expr) override;
>
>virtual void visit (AST::TypeParam ¶m

Re: [PATCH][15.2] nr2.0: late: Correctly initialize funny_error member

2025-04-29 Thread Andrew Pinski
On Tue, Apr 29, 2025 at 1:26 AM  wrote:
>
> From: Arthur Cohen 
>
> Hi everyone,
>
> We noticed inconsistent errors when running name-resolution 2.0 on
> certain files, where an invalid error was triggered and the message was
> from the `funny_ice` error finalizer function we had added as an easter
> egg. We realized yesterday that the undefined value was actually our
> `funny_error` boolean, which is supposed to be set only when resolving
> specific easter eggs `AST::IdentifierExpr`s.
>
> Since `funny_error` is a boolean, it does not get default-initialized in
> the constructor of `Late` - which this patch corrects.
>
> I will be pushing it to trunk directly, but this email specifically
> concerns its port into 15.2.

I am not sure if using NSDMI might be a better style here than doing
it in the constructor.

That is:
```
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.h
b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
index 171d9bfe0f6..2f93981b0d7 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
@@ -76,7 +76,7 @@ private:
   /* Setup Rust's builtin types (u8, i32, !...) in the resolver */
   void setup_builtin_types ();

-  bool funny_error;
+  bool funny_error = false;
 };

 // TODO: Add missing mappings and data structures
```

Thanks,
Andrew

>
> Thanks a lot to Marc Poulhiès and Owen Avery for their help in
> discovering and fixing this.
>
> Best,
>
> Arthur
>
> gcc/rust/ChangeLog:
>
> * resolve/rust-late-name-resolver-2.0.cc (Late::Late): False 
> initialize the
> funny_error field.
> ---
>  gcc/rust/resolve/rust-late-name-resolver-2.0.cc | 4 +++-
>  1 file changed, 3 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 5f215db0a72..f46f9e7dd3e 100644
> --- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
> +++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
> @@ -33,7 +33,9 @@
>  namespace Rust {
>  namespace Resolver2_0 {
>
> -Late::Late (NameResolutionContext &ctx) : DefaultResolver (ctx) {}
> +Late::Late (NameResolutionContext &ctx)
> +  : DefaultResolver (ctx), funny_error (false)
> +{}
>
>  static NodeId
>  next_node_id ()
> --
> 2.49.0
>


Re: [COMMITTED 09/42] gccrs: Add llvmInlineAsm node

2025-04-28 Thread Andrew Pinski
On Mon, Apr 28, 2025 at 9:05 AM Andrew Pinski  wrote:
>
> On Mon, Apr 28, 2025 at 8:48 AM  wrote:
> >
> > From: Pierre-Emmanuel Patry 
> >
> > InlineAsm node does not support memory clobbers.
>
> A few review on this.
> I think this should just be called extended rather than referencing LLVM here.
>
> >
> > gcc/rust/ChangeLog:
> >
> > * ast/rust-ast-collector.cc (TokenCollector::visit): Make visitor
> > unreachable.
> > * ast/rust-ast-collector.h: Add visit for LlvmInlineAsmNode.
> > * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Add visit
> > function for the default ast visitor.
> > * ast/rust-ast-visitor.h: Add function prototype.
> > * ast/rust-ast.cc (LlvmInlineAsm::accept_vis): Add accept_vis to
> > LlvmInlineAsm node.
> > * ast/rust-ast.h: Add LlvmInlineAsm node kind.
> > * ast/rust-expr.h (class LlvmInlineAsm): Add LlvmInlineAsm node.
> > * expand/rust-derive.h: Add visit function for LlvmInlineAsm node.
> > * expand/rust-macro-builtins-asm.cc 
> > (MacroBuiltin::llvm_asm_handler):
> > Add handler for llvm inline assembly nodes.
> > (parse_llvm_asm): Add function to parse llvm assembly nodes.
> > * expand/rust-macro-builtins-asm.h (parse_llvm_asm): Add function
> > prototypes.
> > * expand/rust-macro-builtins.cc (inline_llvm_asm_maker): Add macro
> > transcriber.
> > * expand/rust-macro-builtins.h: Add transcriber function prototype.
> > * hir/rust-ast-lower-base.cc (ASTLoweringBase::visit): Add visit
> > function for LlvmInlineAsm node.
> > * hir/rust-ast-lower-base.h: Add visit function prototype.
> > * resolve/rust-ast-resolve-base.cc (ResolverBase::visit): Add visit
> > function for LlvmInlineAsm node.
> > * resolve/rust-ast-resolve-base.h: Add visit function prototype.
> >
> > Signed-off-by: Pierre-Emmanuel Patry 
> > ---
> >  gcc/rust/ast/rust-ast-collector.cc | 10 -
> >  gcc/rust/ast/rust-ast-collector.h  |  1 +
> >  gcc/rust/ast/rust-ast-visitor.cc   |  4 ++
> >  gcc/rust/ast/rust-ast-visitor.h|  2 +
> >  gcc/rust/ast/rust-ast.cc   |  6 +++
> >  gcc/rust/ast/rust-ast.h|  1 +
> >  gcc/rust/ast/rust-expr.h   | 48 ++
> >  gcc/rust/expand/rust-derive.h  |  1 +
> >  gcc/rust/expand/rust-macro-builtins-asm.cc | 21 ++
> >  gcc/rust/expand/rust-macro-builtins-asm.h  |  7 
> >  gcc/rust/expand/rust-macro-builtins.cc | 11 -
> >  gcc/rust/expand/rust-macro-builtins.h  |  4 ++
> >  gcc/rust/hir/rust-ast-lower-base.cc|  4 ++
> >  gcc/rust/hir/rust-ast-lower-base.h |  1 +
> >  gcc/rust/resolve/rust-ast-resolve-base.cc  |  4 ++
> >  gcc/rust/resolve/rust-ast-resolve-base.h   |  1 +
> >  16 files changed, 124 insertions(+), 2 deletions(-)
> >
> > diff --git a/gcc/rust/ast/rust-ast-collector.cc 
> > b/gcc/rust/ast/rust-ast-collector.cc
> > index 8ee63752f32..90ff2e36251 100644
> > --- a/gcc/rust/ast/rust-ast-collector.cc
> > +++ b/gcc/rust/ast/rust-ast-collector.cc
> > @@ -1520,7 +1520,15 @@ TokenCollector::visit (AsyncBlockExpr &expr)
> >
> >  void
> >  TokenCollector::visit (InlineAsm &expr)
> > -{}
> > +{
> > +  rust_unreachable ();
> > +}
> > +
> > +void
> > +TokenCollector::visit (LlvmInlineAsm &expr)
> > +{
> > +  rust_unreachable ();
> > +}
> >
> >  // rust-item.h
> >
> > diff --git a/gcc/rust/ast/rust-ast-collector.h 
> > b/gcc/rust/ast/rust-ast-collector.h
> > index b014c23ed0b..f45e3cc51ae 100644
> > --- a/gcc/rust/ast/rust-ast-collector.h
> > +++ b/gcc/rust/ast/rust-ast-collector.h
> > @@ -303,6 +303,7 @@ public:
> >void visit (AwaitExpr &expr);
> >void visit (AsyncBlockExpr &expr);
> >void visit (InlineAsm &expr);
> > +  void visit (LlvmInlineAsm &expr);
> >// rust-item.h
> >void visit (TypeParam ¶m);
> >void visit (LifetimeWhereClauseItem &item);
> > diff --git a/gcc/rust/ast/rust-ast-visitor.cc 
> > b/gcc/rust/ast/rust-ast-visitor.cc
> > index 9d524c3cc4c..beb3360c4e1 100644
> > --- a/gcc/rust/ast/rust-ast-visitor.cc
> > +++ b/gcc/rust/ast/rust-ast-visitor.cc
> > @@ -713,6 +713,10 @@ DefaultASTVisitor::visit (AST::InlineAsm &expr)
> >  }
> >  }
> >
> > +void
> &