Branch data Line data Source code
1 : : // Copyright (C) 2025 Free Software Foundation, Inc.
2 : :
3 : : // This file is part of GCC.
4 : :
5 : : // GCC is free software; you can redistribute it and/or modify it under
6 : : // the terms of the GNU General Public License as published by the Free
7 : : // Software Foundation; either version 3, or (at your option) any later
8 : : // version.
9 : :
10 : : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 : : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 : : // for more details.
14 : :
15 : : // You should have received a copy of the GNU General Public License
16 : : // along with GCC; see the file COPYING3. If not see
17 : : // <http://www.gnu.org/licenses/>.
18 : :
19 : : #ifndef RUST_DERIVE_ORD_H
20 : : #define RUST_DERIVE_ORD_H
21 : :
22 : : #include "rust-ast.h"
23 : : #include "rust-derive-cmp-common.h"
24 : : #include "rust-derive.h"
25 : :
26 : : namespace Rust {
27 : : namespace AST {
28 : :
29 : : /**
30 : : * DeriveOrd is a bit special as the expansion of both `PartialOrd` and `Ord`
31 : : * is extremely similar. The only difference is that `PartialOrd` concerns
32 : : * partial-ordering, and thus its main method returns an `Option<Ordering>`,
33 : : * while `Ord` concerns total-ordering, and its main method returns an
34 : : * `Ordering`. Otherwise, the expansion logic is the same, so we factor both
35 : : * derives into one.
36 : : */
37 : 75 : class DeriveOrd : public DeriveVisitor
38 : : {
39 : : public:
40 : : enum class Ordering
41 : : {
42 : : Total,
43 : : Partial
44 : : };
45 : :
46 : 266 : std::string fn (Ordering ordering)
47 : : {
48 : 266 : if (ordering == Ordering::Total)
49 : 112 : return "cmp";
50 : : else
51 : 154 : return "partial_cmp";
52 : : }
53 : :
54 : 191 : std::string trait (Ordering ordering)
55 : : {
56 : 191 : if (ordering == Ordering::Total)
57 : 75 : return "Ord";
58 : : else
59 : 116 : return "PartialOrd";
60 : : }
61 : :
62 : : DeriveOrd (Ordering ordering, location_t loc);
63 : :
64 : : std::unique_ptr<Item> go (Item &item);
65 : :
66 : : private:
67 : : std::unique_ptr<Item> expanded;
68 : :
69 : : Ordering ordering;
70 : :
71 : : /* Identifier patterns for the non-equal match arms */
72 : : constexpr static const char *not_equal = "#non_eq";
73 : : constexpr static const char *self_discr = "#self_discr";
74 : : constexpr static const char *other_discr = "#other_discr";
75 : :
76 : : /**
77 : : * Create the recursive matching structure used when implementing the
78 : : * comparison function on multiple sub items (fields, tuple indexes...)
79 : : */
80 : : std::unique_ptr<Expr> recursive_match (std::vector<SelfOther> &&members);
81 : :
82 : : /**
83 : : * Create a pattern for the `Ordering::Equal` case. In the case of partial
84 : : * ordering, `Option::Some(Ordering::Equal)`.
85 : : */
86 : : std::unique_ptr<Pattern> make_equal ();
87 : :
88 : : /**
89 : : * Make the match arms for one inner match in a comparison function block.
90 : : * This returns the "equal" match arm and the "rest" match arm, so something
91 : : * like `Ordering::Equal` and `non_eq` in the following match expression:
92 : : *
93 : : * match cmp(...) {
94 : : * Ordering::Equal => match cmp(...) { ... }
95 : : * non_eq => non_eq,
96 : : * }
97 : : */
98 : : std::pair<MatchArm, MatchArm> make_cmp_arms ();
99 : :
100 : : /**
101 : : * Generate a call to the proper trait function, based on the ordering, in
102 : : * order to compare two given expressions
103 : : */
104 : : std::unique_ptr<Expr> cmp_call (std::unique_ptr<Expr> &&self_expr,
105 : : std::unique_ptr<Expr> &&other_expr);
106 : :
107 : : std::unique_ptr<Item>
108 : : cmp_impl (std::unique_ptr<BlockExpr> &&fn_block, Identifier type_name,
109 : : const std::vector<std::unique_ptr<GenericParam>> &type_generics);
110 : : std::unique_ptr<AssociatedItem> cmp_fn (std::unique_ptr<BlockExpr> &&block,
111 : : Identifier type_name);
112 : :
113 : : virtual void visit_struct (StructStruct &item) override;
114 : : virtual void visit_tuple (TupleStruct &item) override;
115 : : virtual void visit_enum (Enum &item) override;
116 : : virtual void visit_union (Union &item) override;
117 : : };
118 : :
119 : : } // namespace AST
120 : : } // namespace Rust
121 : :
122 : : #endif // ! RUST_DERIVE_ORD_H
|