From 91d4c0320e7bd120f8f2d2611e57099bf464afa2 Mon Sep 17 00:00:00 2001 From: "lucas.plantrose" Date: Thu, 17 Oct 2024 11:20:07 +0200 Subject: [PATCH] Fixes #3196 gcc/rust/ChangeLog: * ast/rust-ast-collector.cc (TokenCollector::visit): Add behaviour. In Attribute visitor, recognize doc from comment and handle it. * ast/rust-ast.h: Changes Attribute constructor and add a boolean in the class for doc comments. * lex/rust-token.cc (Token::as_string): Return the correct string for the new DOC_STRING_LITERAL token. * lex/rust-token.h (enum PrimitiveCoreType): Add two tokens : DOC_STRING_LITERAL and DOC_END, for pretty-printing purposes. Also modify the string of two previous tokens. * parse/rust-parse-impl.h (Parser::parse_inner_attribute): Updates the Attribute constructor call. (Parser::parse_outer_attribute): Same as above. Signed-off-by: lucas.plantrose --- gcc/rust/ast/rust-ast-collector.cc | 76 +++++++++++++++++++----------- gcc/rust/ast/rust-ast.h | 10 +++- gcc/rust/lex/rust-token.cc | 2 + gcc/rust/lex/rust-token.h | 12 ++++- gcc/rust/parse/rust-parse-impl.h | 6 ++- 5 files changed, 72 insertions(+), 34 deletions(-) diff --git a/gcc/rust/ast/rust-ast-collector.cc b/gcc/rust/ast/rust-ast-collector.cc index a1306463e250..843c892f8fca 100644 --- a/gcc/rust/ast/rust-ast-collector.cc +++ b/gcc/rust/ast/rust-ast-collector.cc @@ -141,38 +141,58 @@ TokenCollector::visit (VariadicParam ¶m) void TokenCollector::visit (Attribute &attrib) { - push (Rust::Token::make (HASH, attrib.get_locus ())); - if (attrib.is_inner_attribute ()) - push (Rust::Token::make (EXCLAM, UNDEF_LOCATION)); - push (Rust::Token::make (LEFT_SQUARE, UNDEF_LOCATION)); - visit (attrib.get_path ()); - - if (attrib.has_attr_input ()) + if (attrib.is_from_comment () && attrib.has_attr_input ()) + { + if (attrib.is_inner_attribute ()) + push (Rust::Token::make (INNER_DOC_COMMENT, attrib.get_locus ())); + else + push (Rust::Token::make (OUTER_DOC_COMMENT, attrib.get_locus ())); + auto lit = (static_cast (attrib.get_attr_input ())) + .get_literal () + .get_literal (); + push (Rust::Token::make_doc_string_literal (attrib.get_locus (), + lit.as_string ())); + push (Rust::Token::make (DOC_COMMENT_END, attrib.get_locus ())); + return; + } + else { - switch (attrib.get_attr_input ().get_attr_input_type ()) + push (Rust::Token::make (HASH, attrib.get_locus ())); + if (attrib.is_inner_attribute ()) + push (Rust::Token::make (EXCLAM, UNDEF_LOCATION)); + push (Rust::Token::make (LEFT_SQUARE, UNDEF_LOCATION)); + visit (attrib.get_path ()); + + if (attrib.has_attr_input ()) { - case AST::AttrInput::AttrInputType::LITERAL: { - visit (static_cast (attrib.get_attr_input ())); - break; - } - case AST::AttrInput::AttrInputType::MACRO: { - visit (static_cast (attrib.get_attr_input ())); - break; - } - case AST::AttrInput::AttrInputType::META_ITEM: { - visit (static_cast ( - attrib.get_attr_input ())); - break; - } - case AST::AttrInput::AttrInputType::TOKEN_TREE: { - visit (static_cast (attrib.get_attr_input ())); - break; - } - default: - rust_unreachable (); + switch (attrib.get_attr_input ().get_attr_input_type ()) + { + case AST::AttrInput::AttrInputType::LITERAL: { + visit ( + static_cast (attrib.get_attr_input ())); + break; + } + case AST::AttrInput::AttrInputType::MACRO: { + visit ( + static_cast (attrib.get_attr_input ())); + break; + } + case AST::AttrInput::AttrInputType::META_ITEM: { + visit (static_cast ( + attrib.get_attr_input ())); + break; + } + case AST::AttrInput::AttrInputType::TOKEN_TREE: { + visit ( + static_cast (attrib.get_attr_input ())); + break; + } + default: + rust_unreachable (); + } } + push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION)); } - push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION)); } void diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h index f83c99a57d2d..7871a657f156 100644 --- a/gcc/rust/ast/rust-ast.h +++ b/gcc/rust/ast/rust-ast.h @@ -636,6 +636,9 @@ struct Attribute bool inner_attribute; + // Only relevant in case of a doc attribute + bool from_comment; + // TODO: maybe a variable storing whether attr input is parsed or not public: @@ -644,9 +647,10 @@ struct Attribute // Constructor has pointer AttrInput for polymorphism reasons Attribute (SimplePath path, std::unique_ptr input, - location_t locus = UNDEF_LOCATION, bool inner_attribute = false) + location_t locus = UNDEF_LOCATION, bool inner_attribute = false, + bool from_comment = false) : path (std::move (path)), attr_input (std::move (input)), locus (locus), - inner_attribute (inner_attribute) + inner_attribute (inner_attribute), from_comment (from_comment) {} bool is_derive () const; @@ -681,6 +685,8 @@ struct Attribute // Returns whether the attribute is considered an "empty" attribute. bool is_empty () const { return attr_input == nullptr && path.is_empty (); } + bool is_from_comment () { return from_comment; } + location_t get_locus () const { return locus; } AttrInput &get_attr_input () const { return *attr_input; } diff --git a/gcc/rust/lex/rust-token.cc b/gcc/rust/lex/rust-token.cc index e1eb78f66a67..3fecd3a1ba1b 100644 --- a/gcc/rust/lex/rust-token.cc +++ b/gcc/rust/lex/rust-token.cc @@ -268,6 +268,8 @@ Token::as_string () const return get_str (); else return get_str () + get_type_hint_str (); + case DOC_STRING_LITERAL: + return escape_special_chars (*std::move (str), Context::String); default: return get_str (); } diff --git a/gcc/rust/lex/rust-token.h b/gcc/rust/lex/rust-token.h index 1a2a28682e15..171643dd79bd 100644 --- a/gcc/rust/lex/rust-token.h +++ b/gcc/rust/lex/rust-token.h @@ -144,8 +144,10 @@ enum PrimitiveCoreType /* Macros */ \ RS_TOKEN (DOLLAR_SIGN, "$") \ /* Doc Comments */ \ - RS_TOKEN (INNER_DOC_COMMENT, "#![doc]") \ - RS_TOKEN (OUTER_DOC_COMMENT, "#[doc]") \ + RS_TOKEN (INNER_DOC_COMMENT, "/**!") \ + RS_TOKEN (OUTER_DOC_COMMENT, "/**") \ + RS_TOKEN (DOC_COMMENT_END, "*/") \ + RS_TOKEN (DOC_STRING_LITERAL, "string") \ RS_TOKEN_KEYWORD_2015 (ABSTRACT, "abstract") /* unused */ \ RS_TOKEN_KEYWORD_2015 (AS, "as") \ RS_TOKEN_KEYWORD_2018 (ASYNC, "async") /* unused */ \ @@ -396,6 +398,11 @@ class Token return TokenPtr (new Token (OUTER_DOC_COMMENT, locus, std::move (str))); } + static TokenPtr make_doc_string_literal (location_t locus, std::string &&str) + { + return TokenPtr (new Token (DOC_STRING_LITERAL, locus, std::move (str))); + } + // Makes and returns a new TokenPtr of type LIFETIME. static TokenPtr make_lifetime (location_t locus, std::string &&str) { @@ -458,6 +465,7 @@ return *str; case BYTE_CHAR_LITERAL: case BYTE_STRING_LITERAL: case RAW_STRING_LITERAL: + case DOC_STRING_LITERAL: return true; default: return false; diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index aff81448deae..cad2ad1eb467 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -523,7 +523,8 @@ Parser::parse_inner_attribute () auto path = std::move (std::get<0> (values)); auto input = std::move (std::get<1> (values)); auto loc = std::get<2> (values); - return AST::Attribute (std::move (path), std::move (input), loc, true); + return AST::Attribute (std::move (path), std::move (input), loc, true, + true); } if (lexer.peek_token ()->get_id () != HASH) @@ -1242,7 +1243,8 @@ Parser::parse_outer_attribute () auto path = std::move (std::get<0> (values)); auto input = std::move (std::get<1> (values)); auto loc = std::get<2> (values); - return AST::Attribute (std::move (path), std::move (input), loc, false); + return AST::Attribute (std::move (path), std::move (input), loc, false, + true); } if (lexer.peek_token ()->get_id () == INNER_DOC_COMMENT)