aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimplyTheOther <simplytheother@gmail.com>2020-10-11 22:11:02 +0800
committerSimplyTheOther <simplytheother@gmail.com>2020-12-08 21:10:15 +0800
commiteb644945a4f1bcac234a099f904812dcbbafcc93 (patch)
tree5343707ddba956043cd3cf3a69ecbde605399625
parent423462fb6785896c8031319d50ac38fbca3afb51 (diff)
downloadgcc-eb644945a4f1bcac234a099f904812dcbbafcc93.zip
gcc-eb644945a4f1bcac234a099f904812dcbbafcc93.tar.gz
gcc-eb644945a4f1bcac234a099f904812dcbbafcc93.tar.bz2
Added cfg stripping code (will top-level strip currently)
Rearranged order of definitions in rust-ast.h, should fix compile error Attempted error fix for Attribute-AttrInput interaction and Crate stripping Fixed constructor arguments for MacroExpander
-rw-r--r--gcc/rust/ast/rust-ast-full-test.cc24
-rw-r--r--gcc/rust/ast/rust-ast.h259
-rw-r--r--gcc/rust/expand/rust-macro-expand.cc33
-rw-r--r--gcc/rust/expand/rust-macro-expand.h2
-rw-r--r--gcc/rust/rust-session-manager.cc2
5 files changed, 184 insertions, 136 deletions
diff --git a/gcc/rust/ast/rust-ast-full-test.cc b/gcc/rust/ast/rust-ast-full-test.cc
index 44a38ac..e269645 100644
--- a/gcc/rust/ast/rust-ast-full-test.cc
+++ b/gcc/rust/ast/rust-ast-full-test.cc
@@ -171,13 +171,29 @@ Attribute::as_string () const
{
std::string path_str = path.as_string ();
if (attr_input == nullptr)
- {
return path_str;
- }
else
- {
return path_str + attr_input->as_string ();
- }
+}
+
+// Copy constructor must deep copy attr_input as unique pointer
+Attribute::Attribute (Attribute const &other) : path (other.path), locus (other.locus)
+{
+ // guard to protect from null pointer dereference
+ if (other.attr_input != nullptr)
+ attr_input = other.attr_input->clone_attr_input ();
+}
+
+// overload assignment operator to use custom clone method
+Attribute &Attribute::operator= (Attribute const &other)
+{
+ path = other.path;
+ locus = other.locus;
+ // guard to protect from null pointer dereference
+ if (other.attr_input != nullptr)
+ attr_input = other.attr_input->clone_attr_input ();
+
+ return *this;
}
std::string
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index cfb5f9b..90e3504 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -62,34 +62,6 @@ Location?
};*/
// decided to not have node as a "node" would never need to be stored
-// Attribute body - abstract base class
-class AttrInput
-{
-public:
- virtual ~AttrInput () {}
-
- // Unique pointer custom clone function
- std::unique_ptr<AttrInput> clone_attr_input () const
- {
- return std::unique_ptr<AttrInput> (clone_attr_input_impl ());
- }
-
- virtual std::string as_string () const = 0;
-
- virtual void accept_vis (ASTVisitor &vis) = 0;
-
- virtual bool check_cfg_predicate (const Session &session) const = 0;
-
- // Parse attribute input to meta item, if possible
- virtual AttrInput *parse_to_meta_item () const { return nullptr; }
-
- virtual std::vector<Attribute> separate_cfg_attrs () const { return {}; }
-
-protected:
- // pure virtual clone implementation
- virtual AttrInput *clone_attr_input_impl () const = 0;
-};
-
// forward decl for use in token tree method
class Token;
@@ -281,95 +253,6 @@ public:
bool is_error () const { return value_as_string == ""; }
};
-// A token tree with delimiters
-class DelimTokenTree : public TokenTree, public AttrInput
-{
- DelimType delim_type;
- std::vector<std::unique_ptr<TokenTree>> token_trees;
- Location locus;
-
-protected:
- DelimTokenTree *clone_delim_tok_tree_impl () const
- {
- return new DelimTokenTree (*this);
- }
-
- /* Use covariance to implement clone function as returning a DelimTokenTree
- * object */
- DelimTokenTree *clone_attr_input_impl () const override
- {
- return clone_delim_tok_tree_impl ();
- }
-
- /* Use covariance to implement clone function as returning a DelimTokenTree
- * object */
- DelimTokenTree *clone_token_tree_impl () const override
- {
- return clone_delim_tok_tree_impl ();
- }
-
-public:
- DelimTokenTree (DelimType delim_type,
- std::vector<std::unique_ptr<TokenTree>> token_trees
- = std::vector<std::unique_ptr<TokenTree>> (),
- Location locus = Location ())
- : delim_type (delim_type), token_trees (std::move (token_trees)),
- locus (locus)
- {}
-
- // Copy constructor with vector clone
- DelimTokenTree (DelimTokenTree const &other)
- : delim_type (other.delim_type), locus (other.locus)
- {
- token_trees.reserve (other.token_trees.size ());
- for (const auto &e : other.token_trees)
- token_trees.push_back (e->clone_token_tree ());
- }
-
- // overloaded assignment operator with vector clone
- DelimTokenTree &operator= (DelimTokenTree const &other)
- {
- delim_type = other.delim_type;
- locus = other.locus;
-
- token_trees.reserve (other.token_trees.size ());
- for (const auto &e : other.token_trees)
- token_trees.push_back (e->clone_token_tree ());
-
- return *this;
- }
-
- // move constructors
- DelimTokenTree (DelimTokenTree &&other) = default;
- DelimTokenTree &operator= (DelimTokenTree &&other) = default;
-
- static DelimTokenTree create_empty () { return DelimTokenTree (PARENS); }
-
- std::string as_string () const override;
-
- void accept_vis (ASTVisitor &vis) override;
-
- bool
- check_cfg_predicate (const Session &session ATTRIBUTE_UNUSED) const override
- {
- // this should never be called - should be converted first
- return false;
- }
-
- AttrInput *parse_to_meta_item () const override;
-
- std::vector<std::unique_ptr<Token>> to_token_stream () const override;
-
- std::unique_ptr<DelimTokenTree> clone_delim_token_tree () const
- {
- return std::unique_ptr<DelimTokenTree> (clone_delim_tok_tree_impl ());
- }
-};
-
-/* Forward decl - definition moved to rust-expr.h as it requires LiteralExpr to
- * be defined */
-class AttrInputLiteral;
-
/* TODO: move applicable stuff into here or just don't include it because
* nothing uses it A segment of a path (maybe) */
class PathSegment
@@ -462,6 +345,9 @@ public:
}
};
+// forward decl for Attribute
+class AttrInput;
+
// aka Attr
// Attribute AST representation
struct Attribute
@@ -490,15 +376,17 @@ public:
~Attribute () = default;
// Copy constructor must deep copy attr_input as unique pointer
- Attribute (Attribute const &other) : path (other.path), locus (other.locus)
+ /*Attribute (Attribute const &other) : path (other.path), locus (other.locus)
{
// guard to protect from null pointer dereference
if (other.attr_input != nullptr)
attr_input = other.attr_input->clone_attr_input ();
- }
+ }*/
+ // no point in being defined inline as requires virtual call anyway
+ Attribute (const Attribute &other);
// overload assignment operator to use custom clone method
- Attribute &operator= (Attribute const &other)
+ /*Attribute &operator= (Attribute const &other)
{
path = other.path;
locus = other.locus;
@@ -507,7 +395,9 @@ public:
attr_input = other.attr_input->clone_attr_input ();
return *this;
- }
+ }*/
+ // no point in being defined inline as requires virtual call anyway
+ Attribute &operator= (const Attribute &other);
// default move semantics
Attribute (Attribute &&other) = default;
@@ -604,6 +494,123 @@ protected:
}
};
+// Attribute body - abstract base class
+class AttrInput
+{
+public:
+ virtual ~AttrInput () {}
+
+ // Unique pointer custom clone function
+ std::unique_ptr<AttrInput> clone_attr_input () const
+ {
+ return std::unique_ptr<AttrInput> (clone_attr_input_impl ());
+ }
+
+ virtual std::string as_string () const = 0;
+
+ virtual void accept_vis (ASTVisitor &vis) = 0;
+
+ virtual bool check_cfg_predicate (const Session &session) const = 0;
+
+ // Parse attribute input to meta item, if possible
+ virtual AttrInput *parse_to_meta_item () const { return nullptr; }
+
+ virtual std::vector<Attribute> separate_cfg_attrs () const { return {}; }
+
+protected:
+ // pure virtual clone implementation
+ virtual AttrInput *clone_attr_input_impl () const = 0;
+};
+
+// A token tree with delimiters
+class DelimTokenTree : public TokenTree, public AttrInput
+{
+ DelimType delim_type;
+ std::vector<std::unique_ptr<TokenTree>> token_trees;
+ Location locus;
+
+protected:
+ DelimTokenTree *clone_delim_tok_tree_impl () const
+ {
+ return new DelimTokenTree (*this);
+ }
+
+ /* Use covariance to implement clone function as returning a DelimTokenTree
+ * object */
+ DelimTokenTree *clone_attr_input_impl () const override
+ {
+ return clone_delim_tok_tree_impl ();
+ }
+
+ /* Use covariance to implement clone function as returning a DelimTokenTree
+ * object */
+ DelimTokenTree *clone_token_tree_impl () const override
+ {
+ return clone_delim_tok_tree_impl ();
+ }
+
+public:
+ DelimTokenTree (DelimType delim_type,
+ std::vector<std::unique_ptr<TokenTree>> token_trees
+ = std::vector<std::unique_ptr<TokenTree>> (),
+ Location locus = Location ())
+ : delim_type (delim_type), token_trees (std::move (token_trees)),
+ locus (locus)
+ {}
+
+ // Copy constructor with vector clone
+ DelimTokenTree (DelimTokenTree const &other)
+ : delim_type (other.delim_type), locus (other.locus)
+ {
+ token_trees.reserve (other.token_trees.size ());
+ for (const auto &e : other.token_trees)
+ token_trees.push_back (e->clone_token_tree ());
+ }
+
+ // overloaded assignment operator with vector clone
+ DelimTokenTree &operator= (DelimTokenTree const &other)
+ {
+ delim_type = other.delim_type;
+ locus = other.locus;
+
+ token_trees.reserve (other.token_trees.size ());
+ for (const auto &e : other.token_trees)
+ token_trees.push_back (e->clone_token_tree ());
+
+ return *this;
+ }
+
+ // move constructors
+ DelimTokenTree (DelimTokenTree &&other) = default;
+ DelimTokenTree &operator= (DelimTokenTree &&other) = default;
+
+ static DelimTokenTree create_empty () { return DelimTokenTree (PARENS); }
+
+ std::string as_string () const override;
+
+ void accept_vis (ASTVisitor &vis) override;
+
+ bool
+ check_cfg_predicate (const Session &session ATTRIBUTE_UNUSED) const override
+ {
+ // this should never be called - should be converted first
+ return false;
+ }
+
+ AttrInput *parse_to_meta_item () const override;
+
+ std::vector<std::unique_ptr<Token>> to_token_stream () const override;
+
+ std::unique_ptr<DelimTokenTree> clone_delim_token_tree () const
+ {
+ return std::unique_ptr<DelimTokenTree> (clone_delim_tok_tree_impl ());
+ }
+};
+
+/* Forward decl - definition moved to rust-expr.h as it requires LiteralExpr to
+ * be defined */
+class AttrInputLiteral;
+
// Forward decl - defined in rust-macro.h
class MetaNameValueStr;
@@ -1452,6 +1459,16 @@ public:
// Get crate representation as string (e.g. for debugging).
std::string as_string () const;
+
+ // Delete all crate information, e.g. if fails cfg.
+ void strip_crate () {
+ inner_attrs.clear ();
+ inner_attrs.shrink_to_fit ();
+
+ items.clear ();
+ items.shrink_to_fit ();
+ // TODO: is this the best way to do this?
+ }
};
// Base path expression AST node - abstract
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
index 6afe8a5..4a39be3 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -24,24 +24,31 @@ namespace Rust {
- derive container macro - unreachable*/
}
- /* Determines whether cfg predicate is true and item with attribute should not
- * be stripped. TODO can this be const reference or does it have to mutate? */
- bool MacroExpander::check_cfg(AST::Attribute& attr) {}
+ /* Determines whether any cfg predicate is false and hence item with attributes should
+ * be stripped. */
+ bool MacroExpander::fails_cfg(std::vector<AST::Attribute>& attrs) {
+ for (auto& attr : attrs) {
+ if (attr.get_path() == "cfg" && !attr.check_cfg_predicate(session))
+ return true;
+ }
+ return false;
+ }
// Expands cfg_attr attributes.
void MacroExpander::expand_cfg_attrs(std::vector<AST::Attribute>& attrs) {
- for (int i = 0; i < attrs.size (); ) {
+ for (int i = 0; i < attrs.size();) {
auto& attr = attrs[i];
if (attr.get_path() == "cfg_attr") {
- if (attr.check_cfg_predicate (session)) {
+ if (attr.check_cfg_predicate(session)) {
// split off cfg_attr
- std::vector<AST::Attribute> new_attrs = attr.separate_cfg_attrs ();
+ std::vector<AST::Attribute> new_attrs = attr.separate_cfg_attrs();
// remove attr from vector
- attrs.erase (attrs.begin () + i);
+ attrs.erase(attrs.begin() + i);
// add new attrs to vector
- attrs.insert (attrs.begin() + i, std::make_move_iterator (new_attrs.begin ()), std::make_move_iterator (new_attrs.end ()));
+ attrs.insert(attrs.begin() + i, std::make_move_iterator(new_attrs.begin()),
+ std::make_move_iterator(new_attrs.end()));
}
/* do something - if feature (first token in tree) is in fact enabled,
@@ -54,16 +61,24 @@ namespace Rust {
i++;
}
}
- attrs.shrink_to_fit ();
+ attrs.shrink_to_fit();
}
void MacroExpander::expand_crate() {
/* fill macro/decorator map from init list? not sure where init list comes
* from? */
+ // TODO: does cfg apply for inner attributes? research.
+ // the apparent answer (from playground test) is yes
+
// expand crate cfg_attr attributes
expand_cfg_attrs(crate.inner_attrs);
+ if (fails_cfg(crate.inner_attrs)) {
+ // basically, delete whole crate
+ crate.strip_crate();
+ // TODO: maybe create warning here? probably not desired behaviour
+ }
// expand module attributes?
// expand module tree recursively
diff --git a/gcc/rust/expand/rust-macro-expand.h b/gcc/rust/expand/rust-macro-expand.h
index 7e684a9..a7fe076 100644
--- a/gcc/rust/expand/rust-macro-expand.h
+++ b/gcc/rust/expand/rust-macro-expand.h
@@ -41,7 +41,7 @@ struct MacroExpander
void expand_invoc (std::unique_ptr<AST::MacroInvocation> &invoc);
void expand_cfg_attrs(std::vector<AST::Attribute>& attrs);
- bool check_cfg(AST::Attribute& attr);
+ bool fails_cfg(std::vector<AST::Attribute>& attr);
/* TODO: make it extend ASTVisitor so that individual items can be accessed
* properly? */
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 20c7e34..7940df7 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -715,7 +715,7 @@ Session::expansion (AST::Crate &crate)
// create extctxt? from parse session, cfg, and resolver?
/* expand by calling cxtctxt object's monotonic_expander's expand_crate
* method. */
- MacroExpander expander (crate, cfg);
+ MacroExpander expander (crate, cfg, *this);
expander.expand_crate ();
// error reporting - check unused macros, get missing fragment specifiers