diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-02-04 09:38:43 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-04 09:38:43 +0000 |
commit | 83bfbf0746c87b641754697a3c8e9f7a7cb08aa9 (patch) | |
tree | 7e33205e75ef19e8e3eefef0a1eacd678a7ce35f /gcc | |
parent | 7eef766dc5a8abda2ca2cf8d535cdf160f40b50c (diff) | |
parent | 9f36d99b4067df98608dc3535e6c786d1897837e (diff) | |
download | gcc-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.cc | 100 | ||||
-rw-r--r-- | gcc/rust/ast/rust-ast.h | 2 | ||||
-rw-r--r-- | gcc/rust/ast/rust-macro.h | 10 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/cfg2.rs | 13 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/cfg3.rs | 11 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/cfg4.rs | 11 | ||||
-rw-r--r-- | gcc/testsuite/rust/execute/torture/cfg4.rs | 38 |
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 +} |