aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-02-04 09:38:43 +0000
committerGitHub <noreply@github.com>2022-02-04 09:38:43 +0000
commit83bfbf0746c87b641754697a3c8e9f7a7cb08aa9 (patch)
tree7e33205e75ef19e8e3eefef0a1eacd678a7ce35f /gcc
parent7eef766dc5a8abda2ca2cf8d535cdf160f40b50c (diff)
parent9f36d99b4067df98608dc3535e6c786d1897837e (diff)
downloadgcc-83bfbf0746c87b641754697a3c8e9f7a7cb08aa9.zip
gcc-83bfbf0746c87b641754697a3c8e9f7a7cb08aa9.tar.gz
gcc-83bfbf0746c87b641754697a3c8e9f7a7cb08aa9.tar.bz2
Merge #907
907: Support cfg expansions predicates r=philberty a=philberty Config expansion can be not, any, or all predicate to enforce the config expansion logic. This patch refactors the MacroParser to be named AttributeParser as it is only used to parse attributes into MetaItems that we can work with and do expansion logic upon. This handles the case of parsing the inner-meta-item of not(A) to parse it into MetaListNameValueStr and tidies up some of the code in the area. Fixes #901 Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/ast/rust-ast-full-test.cc100
-rw-r--r--gcc/rust/ast/rust-ast.h2
-rw-r--r--gcc/rust/ast/rust-macro.h10
-rw-r--r--gcc/testsuite/rust/compile/cfg2.rs13
-rw-r--r--gcc/testsuite/rust/compile/cfg3.rs11
-rw-r--r--gcc/testsuite/rust/compile/cfg4.rs11
-rw-r--r--gcc/testsuite/rust/execute/torture/cfg4.rs38
7 files changed, 124 insertions, 61 deletions
diff --git a/gcc/rust/ast/rust-ast-full-test.cc b/gcc/rust/ast/rust-ast-full-test.cc
index aff148a..68f6f8c 100644
--- a/gcc/rust/ast/rust-ast-full-test.cc
+++ b/gcc/rust/ast/rust-ast-full-test.cc
@@ -3886,6 +3886,7 @@ MetaItemInner::~MetaItemInner () = default;
std::unique_ptr<MetaNameValueStr>
MetaItemInner::to_meta_name_value_str () const
{
+ // TODO parse foo = bar
return nullptr;
}
@@ -4103,8 +4104,8 @@ Attribute::parse_attr_to_meta_item ()
if (!has_attr_input () || is_parsed_to_meta_item ())
return;
- std::unique_ptr<AttrInput> converted_input (
- attr_input->parse_to_meta_item ());
+ auto res = attr_input->parse_to_meta_item ();
+ std::unique_ptr<AttrInput> converted_input (res);
if (converted_input != nullptr)
attr_input = std::move (converted_input);
@@ -4121,7 +4122,7 @@ DelimTokenTree::parse_to_meta_item () const
* to token stream */
std::vector<std::unique_ptr<Token> > token_stream = to_token_stream ();
- MacroParser parser (std::move (token_stream));
+ AttributeParser parser (std::move (token_stream));
std::vector<std::unique_ptr<MetaItemInner> > meta_items (
parser.parse_meta_item_seq ());
@@ -4129,7 +4130,7 @@ DelimTokenTree::parse_to_meta_item () const
}
std::unique_ptr<MetaItemInner>
-MacroParser::parse_meta_item_inner ()
+AttributeParser::parse_meta_item_inner ()
{
// if first tok not identifier, not a "special" case one
if (peek_token ()->get_id () != IDENTIFIER)
@@ -4144,15 +4145,15 @@ MacroParser::parse_meta_item_inner ()
case FLOAT_LITERAL:
case TRUE_LITERAL:
case FALSE_LITERAL:
- // stream_pos++;
return parse_meta_item_lit ();
+
case SUPER:
case SELF:
case CRATE:
case DOLLAR_SIGN:
- case SCOPE_RESOLUTION: {
- return parse_path_meta_item ();
- }
+ case SCOPE_RESOLUTION:
+ return parse_path_meta_item ();
+
default:
rust_error_at (peek_token ()->get_locus (),
"unrecognised token '%s' in meta item",
@@ -4208,10 +4209,13 @@ MacroParser::parse_meta_item_inner ()
return nullptr;
}
- /* HACK: parse parenthesised sequence, and then try conversions to other
- * stuff */
- std::vector<std::unique_ptr<MetaItemInner> > meta_items
- = parse_meta_item_seq ();
+ // is it one of those special cases like not?
+ if (peek_token ()->get_id () == IDENTIFIER)
+ {
+ return parse_path_meta_item ();
+ }
+
+ auto meta_items = parse_meta_item_seq ();
// pass for meta name value str
std::vector<MetaNameValueStr> meta_name_value_str_items;
@@ -4234,23 +4238,25 @@ MacroParser::parse_meta_item_inner ()
std::move (meta_name_value_str_items)));
}
- // pass for meta list idents
- /*std::vector<Identifier> ident_items;
- for (const auto& item : meta_items) {
- std::unique_ptr<Identifier> converted_ident(item->to_ident_item());
- if (converted_ident == nullptr) {
- ident_items.clear();
- break;
- }
- ident_items.push_back(std::move(*converted_ident));
- }
- // if valid return this
- if (!ident_items.empty()) {
- return std::unique_ptr<MetaListIdents>(new
- MetaListIdents(std::move(ident),
- std::move(ident_items)));
- }*/
- // as currently no meta list ident, currently no path. may change in future
+ // // pass for meta list idents
+ // std::vector<Identifier> ident_items;
+ // for (const auto &item : meta_items)
+ // {
+ // std::unique_ptr<Identifier> converted_ident (item->to_ident_item ());
+ // if (converted_ident == nullptr)
+ // {
+ // ident_items.clear ();
+ // break;
+ // }
+ // ident_items.push_back (std::move (*converted_ident));
+ // }
+ // // if valid return this
+ // if (!ident_items.empty ())
+ // {
+ // return std::unique_ptr<MetaListIdents> (
+ // new MetaListIdents (std::move (ident), std::move (ident_items)));
+ // }
+ // // as currently no meta list ident, currently no path. may change in future
// pass for meta list paths
std::vector<SimplePath> path_items;
@@ -4276,13 +4282,13 @@ MacroParser::parse_meta_item_inner ()
}
bool
-MacroParser::is_end_meta_item_tok (TokenId id) const
+AttributeParser::is_end_meta_item_tok (TokenId id) const
{
return id == COMMA || id == RIGHT_PAREN;
}
std::unique_ptr<MetaItem>
-MacroParser::parse_path_meta_item ()
+AttributeParser::parse_path_meta_item ()
{
SimplePath path = parse_simple_path ();
if (path.is_empty ())
@@ -4334,15 +4340,8 @@ MacroParser::parse_path_meta_item ()
/* Parses a parenthesised sequence of meta item inners. Parentheses are
* required here. */
std::vector<std::unique_ptr<MetaItemInner> >
-MacroParser::parse_meta_item_seq ()
+AttributeParser::parse_meta_item_seq ()
{
- if (stream_pos != 0)
- {
- // warning?
- rust_debug ("WARNING: stream pos for parse_meta_item_seq is not 0!");
- }
-
- // int i = 0;
int vec_length = token_stream.size ();
std::vector<std::unique_ptr<MetaItemInner> > meta_items;
@@ -4414,7 +4413,7 @@ DelimTokenTree::to_token_stream () const
}
Literal
-MacroParser::parse_literal ()
+AttributeParser::parse_literal ()
{
const std::unique_ptr<Token> &tok = peek_token ();
switch (tok->get_id ())
@@ -4453,7 +4452,7 @@ MacroParser::parse_literal ()
}
SimplePath
-MacroParser::parse_simple_path ()
+AttributeParser::parse_simple_path ()
{
bool has_opening_scope_res = false;
if (peek_token ()->get_id () == SCOPE_RESOLUTION)
@@ -4494,7 +4493,7 @@ MacroParser::parse_simple_path ()
}
SimplePathSegment
-MacroParser::parse_simple_path_segment ()
+AttributeParser::parse_simple_path_segment ()
{
const std::unique_ptr<Token> &tok = peek_token ();
switch (tok->get_id ())
@@ -4527,7 +4526,7 @@ MacroParser::parse_simple_path_segment ()
}
std::unique_ptr<MetaItemLitExpr>
-MacroParser::parse_meta_item_lit ()
+AttributeParser::parse_meta_item_lit ()
{
Location locus = peek_token ()->get_locus ();
LiteralExpr lit_expr (parse_literal (), {}, locus);
@@ -4538,27 +4537,16 @@ MacroParser::parse_meta_item_lit ()
bool
AttrInputMetaItemContainer::check_cfg_predicate (const Session &session) const
{
- /* NOTE: assuming that only first item must be true - cfg should only have one
- * item, and cfg_attr only has first item as predicate. TODO ensure that this
- * is correct. */
if (items.empty ())
return false;
- // DEBUG
- rust_debug (
- "asked to check cfg of attrinputmetaitemcontainer - delegating to "
- "first item. container: '%s'",
- as_string ().c_str ());
-
- return items[0]->check_cfg_predicate (session);
-
- /*for (const auto &inner_item : items)
+ for (const auto &inner_item : items)
{
if (!inner_item->check_cfg_predicate (session))
return false;
}
- return true;*/
+ return true;
}
bool
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 1847aea..0c22c37 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -816,7 +816,7 @@ class MetaWord;
class MetaListPaths;
// Forward decl - defined in rust-macro.h
-struct MetaListNameValueStr;
+class MetaListNameValueStr;
/* Base statement abstract class. Note that most "statements" are not allowed in
* top-level module scope - only a subclass of statements called "items" are. */
diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h
index 44c0701..6ea7de8 100644
--- a/gcc/rust/ast/rust-macro.h
+++ b/gcc/rust/ast/rust-macro.h
@@ -610,6 +610,8 @@ class MetaListNameValueStr : public MetaItem
Identifier ident;
std::vector<MetaNameValueStr> strs;
+ // FIXME add location info
+
public:
MetaListNameValueStr (Identifier ident, std::vector<MetaNameValueStr> strs)
: ident (std::move (ident)), strs (std::move (strs))
@@ -690,7 +692,7 @@ public:
// Object that parses macros from a token stream.
/* TODO: would "AttributeParser" be a better name? MetaItems are only for
* attributes, I believe */
-struct MacroParser
+struct AttributeParser
{
private:
// TODO: might as well rewrite to use lexer tokens
@@ -698,12 +700,12 @@ private:
int stream_pos;
public:
- MacroParser (std::vector<std::unique_ptr<Token> > token_stream,
- int stream_start_pos = 0)
+ AttributeParser (std::vector<std::unique_ptr<Token> > token_stream,
+ int stream_start_pos = 0)
: token_stream (std::move (token_stream)), stream_pos (stream_start_pos)
{}
- ~MacroParser () = default;
+ ~AttributeParser () = default;
std::vector<std::unique_ptr<MetaItemInner> > parse_meta_item_seq ();
diff --git a/gcc/testsuite/rust/compile/cfg2.rs b/gcc/testsuite/rust/compile/cfg2.rs
new file mode 100644
index 0000000..939384c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/cfg2.rs
@@ -0,0 +1,13 @@
+// { dg-additional-options "-w -frust-cfg=A" }
+struct Foo;
+impl Foo {
+ #[cfg(not(A))]
+ fn test(&self) {}
+}
+
+fn main() {
+ let a = Foo;
+ a.test();
+ // { dg-error "failed to resolve method for .test." "" { target *-*-* } .-1 }
+ // { dg-error "failed to type resolve expression" "" { target *-*-* } .-2 }
+}
diff --git a/gcc/testsuite/rust/compile/cfg3.rs b/gcc/testsuite/rust/compile/cfg3.rs
new file mode 100644
index 0000000..d6ffab6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/cfg3.rs
@@ -0,0 +1,11 @@
+// { dg-additional-options "-w -frust-cfg=A -frust-cfg=B" }
+struct Foo;
+impl Foo {
+ #[cfg(all(A, B))]
+ fn test(&self) {}
+}
+
+fn main() {
+ let a = Foo;
+ a.test();
+}
diff --git a/gcc/testsuite/rust/compile/cfg4.rs b/gcc/testsuite/rust/compile/cfg4.rs
new file mode 100644
index 0000000..2834c27
--- /dev/null
+++ b/gcc/testsuite/rust/compile/cfg4.rs
@@ -0,0 +1,11 @@
+// { dg-additional-options "-w -frust-cfg=A" }
+struct Foo;
+impl Foo {
+ #[cfg(any(A, B))]
+ fn test(&self) {}
+}
+
+fn main() {
+ let a = Foo;
+ a.test();
+}
diff --git a/gcc/testsuite/rust/execute/torture/cfg4.rs b/gcc/testsuite/rust/execute/torture/cfg4.rs
new file mode 100644
index 0000000..d1c2a22
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/cfg4.rs
@@ -0,0 +1,38 @@
+// { dg-additional-options "-w -frust-cfg=A" }
+// { dg-output "test1\ntest2\n" }
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+struct Foo(i32);
+impl Foo {
+ #[cfg(A)]
+ fn test(&self) {
+ unsafe {
+ let a = "test1\n\0";
+ let b = a as *const str;
+ let c = b as *const i8;
+
+ printf(c);
+ }
+ }
+
+ #[cfg(not(B))]
+ fn test2(&self) {
+ unsafe {
+ let a = "test2\n\0";
+ let b = a as *const str;
+ let c = b as *const i8;
+
+ printf(c);
+ }
+ }
+}
+
+fn main() -> i32 {
+ let a = Foo(123);
+ a.test();
+ a.test2();
+
+ 0
+}