diff options
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 +} |