Skip to content

Commit 7430791

Browse files
Merge #1082
1082: Add base for privacy visitor r=CohenArthur a=CohenArthur This PR is extremely early and implements some building blocks for privacy visitors. I'd like to get some feedback on the architecture and, if satisfactory, merge this first "visitor" which only takes care of visiting HIR struct definitions, to make reviewing easier. We could also merge it to a different branch for now, in order to not add an incomplete pass to the compiler. Thanks! Co-authored-by: Arthur Cohen <[email protected]>
2 parents 2076e69 + 1e51260 commit 7430791

14 files changed

+591
-9
lines changed

gcc/rust/Make-lang.in

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ GRS_OBJS = \
8989
rust/rust-ast-resolve-expr.o \
9090
rust/rust-ast-resolve-type.o \
9191
rust/rust-hir-type-check.o \
92+
rust/rust-privacy-check.o \
93+
rust/rust-privacy-ctx.o \
94+
rust/rust-reachability.o \
9295
rust/rust-tyty.o \
9396
rust/rust-tyctx.o \
9497
rust/rust-tyty-bounds.o \
@@ -278,6 +281,7 @@ RUST_INCLUDES = -I $(srcdir)/rust \
278281
-I $(srcdir)/rust/resolve \
279282
-I $(srcdir)/rust/util \
280283
-I $(srcdir)/rust/typecheck \
284+
-I $(srcdir)/rust/privacy \
281285
-I $(srcdir)/rust/lint
282286

283287
# add files that require cross-folder includes - currently rust-lang.o, rust-lex.o
@@ -339,6 +343,11 @@ rust/%.o: rust/typecheck/%.cc
339343
$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
340344
$(POSTCOMPILE)
341345

346+
# build rust/privacy files in rust folder
347+
rust/%.o: rust/privacy/%.cc
348+
$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
349+
$(POSTCOMPILE)
350+
342351
# build rust/lint files in rust folder
343352
rust/%.o: rust/lint/%.cc
344353
$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<

gcc/rust/hir/tree/rust-hir-item.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,9 @@ struct Visibility
576576
// Returns whether visibility is in an error state.
577577
bool is_error () const { return vis_type == ERROR; }
578578

579+
// Does the current visibility refer to a simple `pub <item>` entirely public
580+
bool is_public () const { return vis_type == PUBLIC; }
581+
579582
// Creates an error visibility.
580583
static Visibility create_error ()
581584
{
@@ -621,6 +624,8 @@ class VisItem : public Item
621624
public:
622625
using HIR::Stmt::accept_vis;
623626

627+
BaseKind get_hir_kind () override final { return VIS_ITEM; }
628+
624629
/* Does the item have some kind of public visibility (non-default
625630
* visibility)? */
626631
bool has_visibility () const { return !visibility.is_error (); }
@@ -1458,6 +1463,8 @@ struct StructField
14581463
Analysis::NodeMapping get_mappings () const { return mappings; }
14591464

14601465
Location get_locus () { return locus; }
1466+
1467+
Visibility &get_visibility () { return visibility; }
14611468
};
14621469

14631470
// Rust struct declaration with true struct type HIR node
@@ -2744,7 +2751,7 @@ class ImplBlock : public VisItem
27442751
};
27452752

27462753
// Abstract base class for an item used inside an extern block
2747-
class ExternalItem
2754+
class ExternalItem : public Node
27482755
{
27492756
Analysis::NodeMapping mappings;
27502757
AST::AttrVec outer_attrs;
@@ -2755,6 +2762,8 @@ class ExternalItem
27552762
public:
27562763
virtual ~ExternalItem () {}
27572764

2765+
BaseKind get_hir_kind () override final { return EXTERNAL; }
2766+
27582767
// Returns whether item has outer attributes.
27592768
bool has_outer_attrs () const { return !outer_attrs.empty (); }
27602769

gcc/rust/hir/tree/rust-hir.h

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,41 @@ class HIRTypeVisitor;
4545
// forward decl for use in token tree method
4646
class Token;
4747

48+
class Node
49+
{
50+
public:
51+
// Kind for downcasting various HIR nodes to other base classes when visiting
52+
// them
53+
enum BaseKind
54+
{
55+
/* class ExternalItem */
56+
EXTERNAL,
57+
/* class TraitItem */
58+
TRAIT_ITEM,
59+
/* class VisItem */
60+
VIS_ITEM,
61+
/* class Item */
62+
ITEM,
63+
/* class ImplItem */
64+
IMPL,
65+
/* class Type */
66+
TYPE,
67+
/* class Stmt */
68+
STMT,
69+
/* class Expr */
70+
EXPR,
71+
/* class Pattern */
72+
PATTERN,
73+
};
74+
75+
/**
76+
* Get the kind of HIR node we are dealing with. This is useful for
77+
* downcasting to more precise types when necessary, i.e going from an `Item*`
78+
* to a `VisItem*`
79+
*/
80+
virtual BaseKind get_hir_kind () = 0;
81+
};
82+
4883
// A literal - value with a type. Used in LiteralExpr and LiteralPattern.
4984
struct Literal
5085
{
@@ -91,7 +126,7 @@ struct Literal
91126

92127
/* Base statement abstract class. Note that most "statements" are not allowed in
93128
* top-level module scope - only a subclass of statements called "items" are. */
94-
class Stmt
129+
class Stmt : public Node
95130
{
96131
public:
97132
// Unique pointer custom clone function
@@ -100,6 +135,8 @@ class Stmt
100135
return std::unique_ptr<Stmt> (clone_stmt_impl ());
101136
}
102137

138+
BaseKind get_hir_kind () override { return STMT; }
139+
103140
virtual ~Stmt () {}
104141

105142
virtual std::string as_string () const = 0;
@@ -138,6 +175,8 @@ class Item : public Stmt
138175
return std::unique_ptr<Item> (clone_item_impl ());
139176
}
140177

178+
BaseKind get_hir_kind () override { return ITEM; }
179+
141180
std::string as_string () const override;
142181

143182
/* Adds crate names to the vector passed by reference, if it can
@@ -171,7 +210,7 @@ class Item : public Stmt
171210
class ExprWithoutBlock;
172211

173212
// Base expression HIR node - abstract
174-
class Expr
213+
class Expr : public Node
175214
{
176215
AST::AttrVec outer_attrs;
177216
Analysis::NodeMapping mappings;
@@ -213,6 +252,8 @@ class Expr
213252
Path,
214253
};
215254

255+
BaseKind get_hir_kind () override final { return EXPR; }
256+
216257
const AST::AttrVec &get_outer_attrs () const { return outer_attrs; }
217258

218259
// Unique pointer custom clone function
@@ -358,7 +399,7 @@ class IdentifierExpr : public ExprWithoutBlock
358399
};
359400

360401
// Pattern base HIR node
361-
class Pattern
402+
class Pattern : public Node
362403
{
363404
public:
364405
enum PatternType
@@ -376,6 +417,8 @@ class Pattern
376417
SLICE,
377418
};
378419

420+
BaseKind get_hir_kind () override final { return PATTERN; }
421+
379422
// Unique pointer custom clone function
380423
std::unique_ptr<Pattern> clone_pattern () const
381424
{
@@ -406,7 +449,7 @@ class Pattern
406449
class TraitBound;
407450

408451
// Base class for types as represented in HIR - abstract
409-
class Type
452+
class Type : public Node
410453
{
411454
public:
412455
// Unique pointer custom clone function
@@ -418,6 +461,8 @@ class Type
418461
// virtual destructor
419462
virtual ~Type () {}
420463

464+
BaseKind get_hir_kind () override final { return TYPE; }
465+
421466
virtual std::string as_string () const = 0;
422467

423468
/* HACK: convert to trait bound. Virtual method overriden by classes that
@@ -686,7 +731,7 @@ class LifetimeParam : public GenericParam
686731
};
687732

688733
// Item used in trait declarations - abstract base class
689-
class TraitItem
734+
class TraitItem : public Node
690735
{
691736
public:
692737
enum TraitItemKind
@@ -696,6 +741,8 @@ class TraitItem
696741
TYPE
697742
};
698743

744+
BaseKind get_hir_kind () override final { return TRAIT_ITEM; }
745+
699746
protected:
700747
// Constructor
701748
TraitItem (Analysis::NodeMapping mappings) : mappings (mappings) {}
@@ -728,7 +775,7 @@ class TraitItem
728775
virtual const AST::AttrVec &get_outer_attrs () const = 0;
729776
};
730777

731-
class ImplItem
778+
class ImplItem : public Node
732779
{
733780
public:
734781
enum ImplItemType
@@ -740,6 +787,8 @@ class ImplItem
740787

741788
virtual ~ImplItem () {}
742789

790+
BaseKind get_hir_kind () override final { return IMPL; }
791+
743792
// Unique pointer custom clone function
744793
std::unique_ptr<ImplItem> clone_inherent_impl_item () const
745794
{
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright (C) 2020-2022 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+
#include "rust-privacy-check.h"
20+
#include "rust-reachability.h"
21+
#include "rust-hir-type-check.h"
22+
23+
extern bool
24+
saw_errors (void);
25+
26+
namespace Rust {
27+
namespace Privacy {
28+
void
29+
Resolver::resolve (HIR::Crate &crate)
30+
{
31+
PrivacyContext ctx;
32+
auto ty_ctx = ::Rust::Resolver::TypeCheckContext::get ();
33+
auto visitor = ReachabilityVisitor (ctx, *ty_ctx);
34+
35+
const auto &items = crate.items;
36+
for (auto &item : items)
37+
{
38+
if (item->get_hir_kind () == HIR::Node::VIS_ITEM)
39+
{
40+
auto vis_item = static_cast<HIR::VisItem *> (item.get ());
41+
vis_item->accept_vis (visitor);
42+
}
43+
}
44+
45+
if (saw_errors ())
46+
return;
47+
}
48+
} // namespace Privacy
49+
} // namespace Rust

gcc/rust/privacy/rust-privacy-check.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright (C) 2020-2022 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_PRIVACY_CHECK_H
20+
#define RUST_PRIVACY_CHECK_H
21+
22+
#include "rust-hir-map.h"
23+
#include "rust-hir.h"
24+
#include "rust-hir-expr.h"
25+
#include "rust-hir-stmt.h"
26+
#include "rust-hir-item.h"
27+
#include "rust-hir-type-check.h"
28+
29+
namespace Rust {
30+
namespace Privacy {
31+
class Resolver
32+
{
33+
public:
34+
/**
35+
* Perform the full privacy resolving pass on a crate.
36+
*
37+
* This resolver first computes the reachability of all items in a crate,
38+
* before checking for privacy violations.
39+
*/
40+
static void resolve (HIR::Crate &crate);
41+
};
42+
} // namespace Privacy
43+
} // namespace Rust
44+
45+
#endif // !RUST_PRIVACY_CHECK_H

0 commit comments

Comments
 (0)