From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ed1-x531.google.com (mail-ed1-x531.google.com [IPv6:2a00:1450:4864:20::531]) by sourceware.org (Postfix) with ESMTPS id 39682385E458 for ; Thu, 1 Aug 2024 14:58:54 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 39682385E458 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=embecosm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 39682385E458 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a00:1450:4864:20::531 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722524352; cv=none; b=tkcRHoHBj3WgQZkOxKgfNmw+cihBRjYH17i4rwH25w5lRpTpIyW2mxn/qzTKwUV5Kz5Q0ionuvvLUTZ+74wHh9A1YL7LpPIyRW0dmOdFymQgF3r9g+jd6oUUm93wLS9ZC2nBH/XQWRsx6zfKdVfD34jfO/wJng3jRHjyKaCKodc= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722524352; c=relaxed/simple; bh=X7Im5ayALiB6HY0q8QkeLIZ5Oh/oI59F40KrqWsn8rs=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=XzIg/F+AG1t55KAK124lq6sXvjLGbIA+ilZGmirUrRPHyYkg/yi6wkcYTpvcfOOKUYk0z7RbCaahcplfFyHtAadzO4WecUh2T3Z81O1x5sk3OVmBeC/lVtcWyJTWuBI438X+F3Yipg8x8LQO+XNQjAQEo9kUIMsXhxP82O+yR0k= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-ed1-x531.google.com with SMTP id 4fb4d7f45d1cf-5a156557026so9573429a12.2 for ; Thu, 01 Aug 2024 07:58:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; t=1722524333; x=1723129133; darn=gcc.gnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=DKAbb2xYrBzce/nNLOC0l33H5LZjblPJYbi4Kn3Rzno=; b=E6AtoegqVgTgPoUuBpgbPR7ibn3XSrax1DDOYCdtZ/K04upQexx84sfc3t3bU/lXPz pLR+88lNhDt3FvxCkYTrqgpjwSMrLz1pxKAFLMY/AlG8ddzdy+PNKxVRSdSsvU4eem2F yEWqJnrf62+eFEymU6d/IhCvxov1HmjIpItQdAV3tMv1hndxXHIDbLEeo4P+3TyAn3/M rFCu49bJxgTDR4qRMtQNXHdcB2fI7zz5VEnmnjnrbyRygoYGjyVf/SQUz1s42zgcWuq3 mRDCDw7xmM3PyzrSgk9zWggu2ins6sbObLTMKUMZab5UBrq+5UN1+49oUUKYkYcJxvQ7 r7xg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1722524333; x=1723129133; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=DKAbb2xYrBzce/nNLOC0l33H5LZjblPJYbi4Kn3Rzno=; b=ttipnkb99tX6PQa0/29+oMrXrQ+97O10ROKdG4MT94bFsvXdrvKvZ8oVpZKUmCSTy0 yHFfaD0DlIlHY4F+dk5RB7GY8nQEGxWluzgFY15VPVbaFOPQb2kMHq73D+SHhWvQvjUx jCrrXFm5EmnH2dq9LIPWDw+jxdGlvOMP1n0z2EOneiEoYtIBN8j7qI8xCeLCY55ykz0R 47mwP/yzhPPlAe7B0cZ6+0hZnY5JwPbmdA2B3jJ6K6rFvoJd6+FI87KNHoCdmNnn/P/4 DSmvz3WO6LSjuFhGYqhW2SNYYFTW1FO5DaMIjxH70A/Ei0W12eAhacPmV9VnSgN/ssqU QK2Q== X-Gm-Message-State: AOJu0YwHTLSo1zz/rRKIkGdB8Upnd9SK6cSgM7vmDvCIl7KwdQzwsV98 4BXsxUuSgVusOSN28h5tT9jFRe8Bok1xoVns/RdRdCH9fJwLUIF68leYPfKd1Fm/T1h8/Sz7sh9 aeGyd X-Google-Smtp-Source: AGHT+IGqGXlWA43hQEUJ+XJBSBU5b6EEI63rjNe3HvtiMIyYLykbTFqjeVy1wanDfjKpqO/CmGpXOg== X-Received: by 2002:aa7:c599:0:b0:5a2:2fa5:f145 with SMTP id 4fb4d7f45d1cf-5b7f57f3128mr451576a12.25.1722524332647; Thu, 01 Aug 2024 07:58:52 -0700 (PDT) Received: from platypus.lan ([2a04:cec2:9:dc84:3622:6733:ff49:ee91]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5ac63590592sm10252456a12.25.2024.08.01.07.58.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Aug 2024 07:58:52 -0700 (PDT) From: Arthur Cohen To: gcc-patches@gcc.gnu.org Cc: gcc-rust@gcc.gnu.org, Arthur Cohen Subject: [PATCH 028/125] gccrs: ast: Add base nodes for FormatArgs Date: Thu, 1 Aug 2024 16:56:24 +0200 Message-ID: <20240801145809.366388-30-arthur.cohen@embecosm.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240801145809.366388-2-arthur.cohen@embecosm.com> References: <20240801145809.366388-2-arthur.cohen@embecosm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00,BODY_8BITS,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,WEIRD_QUOTING autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: 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. --- 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(+) create mode 100644 gcc/rust/ast/rust-builtin-ast-nodes.h diff --git a/gcc/rust/ast/rust-ast-collector.cc b/gcc/rust/ast/rust-ast-collector.cc index 181f1b100be..b8ec62367bc 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 cf97c185a26..ec695ef5b31 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 c96bbfb07d9..8d5c8dbc821 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 f2152193a13..ebd38f2520c 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 27b9aa47d99..c72e2d72f6d 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 6c9715eb077..c5c9a025ba6 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 `asm!()` + virtual void visit (FormatArgs &fmt) = 0; + // TODO: rust-cond-compilation.h visiting? not currently used }; @@ -390,6 +393,7 @@ protected: virtual void visit (AST::SelfParam &self) override; virtual void visit (AST::FunctionParam ¶m) override; virtual void visit (AST::VariadicParam ¶m) override; + virtual void visit (AST::FormatArgs &fmt) override; template void visit (T &node) { node.accept_vis (*this); } @@ -422,6 +426,7 @@ protected: virtual void visit (AST::MacroTranscriber &transcriber); virtual void visit (AST::StructPatternElements &spe); virtual void visit (AST::MaybeNamedParam ¶m); + void visit (AST::Attribute &attribute) {} template void visit_outer_attrs (T &node) diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc index 90fe9269404..5d571b46622 100644 --- a/gcc/rust/ast/rust-ast.cc +++ b/gcc/rust/ast/rust-ast.cc @@ -5048,6 +5048,12 @@ MetaWord::accept_vis (ASTVisitor &vis) vis.visit (*this); } +void +FormatArgs::accept_vis (ASTVisitor &vis) +{ + vis.visit (*this); +} + } // namespace AST std::ostream & diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h index 1422d77eade..c4d5858dd63 100644 --- a/gcc/rust/ast/rust-ast.h +++ b/gcc/rust/ast/rust-ast.h @@ -2029,6 +2029,7 @@ public: class PathExpr : public ExprWithoutBlock { }; + } // namespace AST } // namespace Rust diff --git a/gcc/rust/ast/rust-builtin-ast-nodes.h b/gcc/rust/ast/rust-builtin-ast-nodes.h new file mode 100644 index 00000000000..3998fbfb4a7 --- /dev/null +++ b/gcc/rust/ast/rust-builtin-ast-nodes.h @@ -0,0 +1,129 @@ +// 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_AST_BUILTIN_NODES_H +#define RUST_AST_BUILTIN_NODES_H + +#include "rust-system.h" +#include "line-map.h" +#include "optional.h" +#include "rust-ast.h" +#include "rust-fmt.h" + +namespace Rust { +namespace AST { + +// Definitions, from rustc's `FormatArgs` AST struct +// https://github.com/rust-lang/rust/blob/1be468815c/compiler/rustc_ast/src/format.rs +// +// format_args!("hello {abc:.xyz$}!!", abc="world"); +// └──────────────────────────────────────────────┘ +// FormatArgs +// +// format_args!("hello {abc:.xyz$}!!", abc="world"); +// └─────────┘ +// argument +// +// format_args!("hello {abc:.xyz$}!!", abc="world"); +// └───────────────────┘ +// template +// +// format_args!("hello {abc:.xyz$}!!", abc="world"); +// └────┘└─────────┘└┘ +// pieces +// +// format_args!("hello {abc:.xyz$}!!", abc="world"); +// └────┘ └┘ +// literal pieces +// +// format_args!("hello {abc:.xyz$}!!", abc="world"); +// └─────────┘ +// placeholder +// +// format_args!("hello {abc:.xyz$}!!", abc="world"); +// └─┘ └─┘ +// positions (could be names, numbers, empty, or `*`) + +class FormatArgumentKind +{ +public: + Identifier &get_ident () + { + rust_assert (kind == Kind::Captured || kind == Kind::Named); + + return ident.value (); + } + +private: + enum class Kind + { + Normal, + Named, + Captured, + } kind; + + tl::optional ident; +}; + +class FormatArgument +{ + FormatArgumentKind kind; + std::unique_ptr expr; +}; + +class FormatArguments +{ + std::vector args; +}; + +// TODO: Format documentation better +// Having a separate AST node for `format_args!()` expansion allows some +// important optimizations which help reduce generated code a lot. For example, +// turning `format_args!("a {} {} {}", 15, "hey", 'a')` directly into +// `format_args!("a 15 hey a")`, since all arguments are literals. Or, +// flattening imbricated `format_args!()` calls: `format_args!("heyo {}", +// format_args!("result: {}", some_result))` -> `format_args!("heyo result: {}", +// some_result)` +// FIXME: Move to rust-macro.h +class FormatArgs : public Visitable +{ +public: + enum class Newline + { + Yes, + No + }; + + FormatArgs (location_t loc, Fmt::PieceSlice template_str, + FormatArguments arguments) + : loc (loc), template_str (std::move (template_str)), + arguments (std::move (arguments)) + {} + + void accept_vis (AST::ASTVisitor &vis); + +private: + location_t loc; + Fmt::PieceSlice template_str; + FormatArguments arguments; +}; + +} // namespace AST +} // namespace Rust + +#endif // ! RUST_AST_BUILTIN_NODES_H diff --git a/gcc/rust/expand/rust-derive.h b/gcc/rust/expand/rust-derive.h index 8fe29c0db75..f953c3decbf 100644 --- a/gcc/rust/expand/rust-derive.h +++ b/gcc/rust/expand/rust-derive.h @@ -221,6 +221,7 @@ private: virtual void visit (SelfParam ¶m) override final{}; virtual void visit (FunctionParam ¶m) override final{}; virtual void visit (VariadicParam ¶m) override final{}; + virtual void visit (FormatArgs ¶m) override final{}; }; } // namespace AST diff --git a/gcc/rust/hir/rust-ast-lower-base.cc b/gcc/rust/hir/rust-ast-lower-base.cc index bcc4797df77..fa37d62d026 100644 --- a/gcc/rust/hir/rust-ast-lower-base.cc +++ b/gcc/rust/hir/rust-ast-lower-base.cc @@ -20,6 +20,7 @@ #include "rust-ast-lower-type.h" #include "rust-ast-lower-pattern.h" #include "rust-ast-lower-extern.h" +#include "rust-ast.h" #include "rust-attribute-values.h" #include "rust-item.h" #include "rust-system.h" @@ -523,6 +524,10 @@ void ASTLoweringBase::visit (AST::SelfParam ¶m) {} +void +ASTLoweringBase::visit (AST::FormatArgs &fmt) +{} + HIR::Lifetime ASTLoweringBase::lower_lifetime (AST::Lifetime &lifetime, bool default_to_static_lifetime) diff --git a/gcc/rust/hir/rust-ast-lower-base.h b/gcc/rust/hir/rust-ast-lower-base.h index d7b94ac8a70..7b0ce375f83 100644 --- a/gcc/rust/hir/rust-ast-lower-base.h +++ b/gcc/rust/hir/rust-ast-lower-base.h @@ -19,6 +19,7 @@ #ifndef RUST_AST_LOWER_BASE #define RUST_AST_LOWER_BASE +#include "rust-ast.h" #include "rust-system.h" #include "rust-ast-full.h" #include "rust-ast-visitor.h" @@ -253,6 +254,8 @@ public: virtual void visit (AST::VariadicParam ¶m); virtual void visit (AST::SelfParam ¶m); + virtual void visit (AST::FormatArgs &fmt); + protected: ASTLoweringBase () : mappings (Analysis::Mappings::get ()), diff --git a/gcc/rust/hir/rust-ast-lower-expr.cc b/gcc/rust/hir/rust-ast-lower-expr.cc index 35deb57abe6..8e07b19df4c 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.cc +++ b/gcc/rust/hir/rust-ast-lower-expr.cc @@ -22,6 +22,8 @@ #include "rust-ast-lower-struct-field-expr.h" #include "rust-ast-lower-pattern.h" #include "rust-ast-lower-type.h" +#include "rust-ast.h" +#include "rust-diagnostics.h" namespace Rust { namespace HIR { @@ -828,5 +830,11 @@ ASTLoweringExpr::visit (AST::ClosureExprInnerTyped &expr) expr.get_locus ()); } +void +ASTLoweringExpr::visit (AST::FormatArgs &fmt) +{ + rust_sorry_at (0, "unimplemented format_args!() visitor"); +} + } // namespace HIR } // namespace Rust diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h index 56da9d1ab88..168dd014002 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.h +++ b/gcc/rust/hir/rust-ast-lower-expr.h @@ -20,6 +20,7 @@ #define RUST_AST_LOWER_EXPR #include "rust-ast-lower-base.h" +#include "rust-ast.h" namespace Rust { namespace HIR { @@ -121,6 +122,9 @@ public: void visit (AST::ClosureExprInner &expr) override; void visit (AST::ClosureExprInnerTyped &expr) override; + // Extra visitor for FormatArgs nodes + void visit (AST::FormatArgs &fmt) override; + private: ASTLoweringExpr (); diff --git a/gcc/rust/resolve/rust-ast-resolve-base.cc b/gcc/rust/resolve/rust-ast-resolve-base.cc index c88bd58860a..04a0bb65ec2 100644 --- a/gcc/rust/resolve/rust-ast-resolve-base.cc +++ b/gcc/rust/resolve/rust-ast-resolve-base.cc @@ -650,5 +650,11 @@ void ResolverBase::visit (AST::FunctionParam &) {} +void +ResolverBase::visit (AST::FormatArgs &fmt) +{ + rust_sorry_at (0, "unimplemented format_args!() visitor"); +} + } // namespace Resolver } // namespace Rust diff --git a/gcc/rust/resolve/rust-ast-resolve-base.h b/gcc/rust/resolve/rust-ast-resolve-base.h index 9bc64331f5a..3b4d28618e4 100644 --- a/gcc/rust/resolve/rust-ast-resolve-base.h +++ b/gcc/rust/resolve/rust-ast-resolve-base.h @@ -20,6 +20,7 @@ #define RUST_AST_RESOLVE_BASE_H #include "rust-ast-visitor.h" +#include "rust-ast.h" #include "rust-name-resolver.h" #include "rust-diagnostics.h" #include "rust-location.h" @@ -198,6 +199,8 @@ public: void visit (AST::VariadicParam ¶m); void visit (AST::SelfParam ¶m); + void visit (AST::FormatArgs &fmt); + protected: ResolverBase () : resolver (Resolver::get ()), mappings (Analysis::Mappings::get ()), -- 2.45.2