From 8962581c9c6e7322331ee9553a1ce6a048fe44df Mon Sep 17 00:00:00 2001 From: Itamar Date: Wed, 31 Mar 2021 22:21:31 +0300 Subject: [PATCH] LibCpp: Parse C++ cast expressions parse static_cast, reinterpret_cast, dynamic_cast & const_cast --- Userland/Libraries/LibCpp/AST.cpp | 17 ++++++++++++ Userland/Libraries/LibCpp/AST.h | 16 +++++++++++ Userland/Libraries/LibCpp/Parser.cpp | 40 +++++++++++++++++++++++++++- Userland/Libraries/LibCpp/Parser.h | 2 ++ 4 files changed, 74 insertions(+), 1 deletion(-) diff --git a/Userland/Libraries/LibCpp/AST.cpp b/Userland/Libraries/LibCpp/AST.cpp index 399905f056..601b689807 100644 --- a/Userland/Libraries/LibCpp/AST.cpp +++ b/Userland/Libraries/LibCpp/AST.cpp @@ -501,7 +501,24 @@ void TemplatizedFunctionCall::dump(size_t indent) const for (const auto& arg : m_arguments) { arg.dump(indent + 1); } +} +void CppCastExpression::dump(size_t indent) const +{ + ASTNode::dump(indent); + + print_indent(indent); + outln("{}", m_cast_type); + + print_indent(indent + 1); + outln("<"); + if (m_type) + m_type->dump(indent + 1); + print_indent(indent + 1); + outln(">"); + + if (m_expression) + m_expression->dump(indent + 1); } } diff --git a/Userland/Libraries/LibCpp/AST.h b/Userland/Libraries/LibCpp/AST.h index 9f0140c5ce..a5f1ca356c 100644 --- a/Userland/Libraries/LibCpp/AST.h +++ b/Userland/Libraries/LibCpp/AST.h @@ -696,4 +696,20 @@ public: NonnullRefPtrVector m_declarations; }; +class CppCastExpression : public Expression { +public: + CppCastExpression(ASTNode* parent, Optional start, Optional end, const String& filename) + : Expression(parent, start, end, filename) + { + } + + virtual ~CppCastExpression() override = default; + virtual const char* class_name() const override { return "CppCastExpression"; } + virtual void dump(size_t indent) const override; + + StringView m_cast_type; + RefPtr m_type; + RefPtr m_expression; +}; + } diff --git a/Userland/Libraries/LibCpp/Parser.cpp b/Userland/Libraries/LibCpp/Parser.cpp index 96b84f54d0..2fb02a84eb 100644 --- a/Userland/Libraries/LibCpp/Parser.cpp +++ b/Userland/Libraries/LibCpp/Parser.cpp @@ -440,6 +440,9 @@ NonnullRefPtr Parser::parse_primary_expression(ASTNode& parent) return parse_literal(parent); } + if (match_cpp_cast_expression()) + return parse_cpp_cast_expression(parent); + if (match_name()) { if (match_function_call() != TemplatizedMatchResult::NoMatch) return parse_function_call(parent); @@ -827,7 +830,8 @@ bool Parser::match_expression() auto token_type = peek().type(); return match_literal() || token_type == Token::Type::Identifier - || match_unary_expression(); + || match_unary_expression() + || match_cpp_cast_expression(); } bool Parser::eof() const @@ -1341,4 +1345,38 @@ NonnullRefPtr Parser::parse_name(ASTNode& parent) return name_node; } +bool Parser::match_cpp_cast_expression() +{ + save_state(); + ScopeGuard state_guard = [this] { load_state(); }; + + auto token = consume(); + if (token.type() != Token::Type::Keyword) + return false; + + auto text = token.text(); + if (text == "static_cast" || text == "reinterpret_cast" || text == "dynamic_cast" || text == "const_cast") + return true; + return false; +} + +NonnullRefPtr Parser::parse_cpp_cast_expression(ASTNode& parent) +{ + auto cast_expression = create_ast_node(parent, position(), {}); + + cast_expression->m_cast_type = consume(Token::Type::Keyword).text(); + + consume(Token::Type::Less); + cast_expression->m_type = parse_type(*cast_expression); + consume(Token::Type::Greater); + + consume(Token::Type::LeftParen); + cast_expression->m_expression = parse_expression(*cast_expression); + consume(Token::Type::RightParen); + + cast_expression->set_end(position()); + + return cast_expression; +} + } diff --git a/Userland/Libraries/LibCpp/Parser.h b/Userland/Libraries/LibCpp/Parser.h index d59b81b44d..de6a614028 100644 --- a/Userland/Libraries/LibCpp/Parser.h +++ b/Userland/Libraries/LibCpp/Parser.h @@ -89,6 +89,7 @@ private: bool match_namespace_declaration(); bool match_template_arguments(); bool match_name(); + bool match_cpp_cast_expression(); enum class TemplatizedMatchResult { NoMatch, @@ -131,6 +132,7 @@ private: RefPtr parse_single_declaration_in_translation_unit(ASTNode& parent); NonnullRefPtrVector parse_template_arguments(ASTNode& parent); NonnullRefPtr parse_name(ASTNode& parent); + NonnullRefPtr parse_cpp_cast_expression(ASTNode& parent); bool match(Token::Type); Token consume(Token::Type);