diff --git a/Userland/Libraries/LibCpp/AST.h b/Userland/Libraries/LibCpp/AST.h index 95cbddf167..402057c19a 100644 --- a/Userland/Libraries/LibCpp/AST.h +++ b/Userland/Libraries/LibCpp/AST.h @@ -77,7 +77,8 @@ public: virtual bool is_function_call() const { return false; } virtual bool is_type() const { return false; } virtual bool is_declaration() const { return false; } - virtual bool is_name() const {return false;} + virtual bool is_name() const { return false; } + virtual bool is_dummy_node() const { return false; } protected: ASTNode(ASTNode* parent, Optional start, Optional end, const String& filename) @@ -347,7 +348,7 @@ public: virtual ~Name() override = default; virtual const char* class_name() const override { return "Name"; } virtual void dump(size_t indent) const override; - virtual bool is_name() const override {return true;} + virtual bool is_name() const override { return true; } Name(ASTNode* parent, Optional start, Optional end, const String& filename) : Expression(parent, start, end, filename) @@ -756,4 +757,15 @@ public: NonnullRefPtrVector m_expressions; }; + +class DummyAstNode : public ASTNode { +public: + DummyAstNode(ASTNode* parent, Optional start, Optional end, const String& filename) + : ASTNode(parent, start, end, filename) + { + } + virtual bool is_dummy_node() const override { return true; } + virtual const char* class_name() const override { return "DummyAstNode"; } + virtual void dump(size_t) const override { } +}; } diff --git a/Userland/Libraries/LibCpp/Parser.cpp b/Userland/Libraries/LibCpp/Parser.cpp index 9398169218..aaac3f5934 100644 --- a/Userland/Libraries/LibCpp/Parser.cpp +++ b/Userland/Libraries/LibCpp/Parser.cpp @@ -263,7 +263,7 @@ Parser::TemplatizedMatchResult Parser::match_type() if (!match_name()) return TemplatizedMatchResult::NoMatch; - parse_name(*m_root_node); + parse_name(get_dummy_node()); if (peek(Token::Type::Less).has_value()) { if (match_template_arguments()) { @@ -287,7 +287,7 @@ bool Parser::match_template_arguments() while (!eof() && peek().type() != Token::Type::Greater) { if (match_type() == TemplatizedMatchResult::NoMatch) return false; - parse_type(*m_root_node); + parse_type(get_dummy_node()); } return peek().type() == Token::Type::Greater; @@ -320,7 +320,7 @@ bool Parser::match_variable_declaration() } VERIFY(m_root_node); - parse_type(*m_root_node); + parse_type(get_dummy_node()); // Identifier if (!peek(Token::Type::Identifier).has_value()) { @@ -668,7 +668,7 @@ bool Parser::match_function_declaration() if (match_type() == TemplatizedMatchResult::NoMatch) return false; VERIFY(m_root_node); - parse_type(*m_root_node); + parse_type(get_dummy_node()); if (!peek(Token::Type::Identifier).has_value()) return false; @@ -888,7 +888,7 @@ RefPtr Parser::node_at(Position pos) const auto index = index_of_node_at(pos); if (!index.has_value()) return nullptr; - return m_nodes[index.value()]; + return m_state.nodes[index.value()]; } Optional Parser::index_of_node_at(Position pos) const @@ -902,12 +902,12 @@ Optional Parser::index_of_node_at(Position pos) const return Position { node.end().line - node.start().line, node.start().line != node.end().line ? 0 : node.end().column - node.start().column }; }; - for (size_t node_index = 0; node_index < m_nodes.size(); ++node_index) { - auto& node = m_nodes[node_index]; + for (size_t node_index = 0; node_index < m_state.nodes.size(); ++node_index) { + auto& node = m_state.nodes[node_index]; if (node.start() > pos || node.end() < pos) continue; - if (!match_node_index.has_value() || (node_span(node) < node_span(m_nodes[match_node_index.value()]))) + if (!match_node_index.has_value() || (node_span(node) < node_span(m_state.nodes[match_node_index.value()]))) match_node_index = node_index; } return match_node_index; @@ -945,12 +945,12 @@ Parser::TemplatizedMatchResult Parser::match_function_call() ScopeGuard state_guard = [this] { load_state(); }; if (!match_name()) return TemplatizedMatchResult::NoMatch; - parse_name(*m_root_node); + parse_name(get_dummy_node()); bool is_templatized = false; if (match_template_arguments()) { is_templatized = true; - parse_template_arguments(*m_root_node); + parse_template_arguments(get_dummy_node()); } if (!match(Token::Type::LeftParen)) @@ -1408,7 +1408,7 @@ bool Parser::match_c_style_cast_expression() if (match_type() == TemplatizedMatchResult::NoMatch) return false; - parse_type(*m_root_node); + parse_type(get_dummy_node()); if (consume().type() != Token::Type::RightParen) return false; diff --git a/Userland/Libraries/LibCpp/Parser.h b/Userland/Libraries/LibCpp/Parser.h index 0fff5f685d..94961e6968 100644 --- a/Userland/Libraries/LibCpp/Parser.h +++ b/Userland/Libraries/LibCpp/Parser.h @@ -155,6 +155,7 @@ private: struct State { size_t token_index { 0 }; Vector errors; + NonnullRefPtrVector nodes; }; void error(StringView message = {}); @@ -164,7 +165,9 @@ private: create_ast_node(ASTNode& parent, const Position& start, Optional end, Args&&... args) { auto node = adopt(*new T(&parent, start, end, m_filename, forward(args)...)); - m_nodes.append(node); + if(!parent.is_dummy_node()) { + m_state.nodes.append(node); + } return node; } @@ -172,11 +175,19 @@ private: create_root_ast_node(const Position& start, Position end) { auto node = adopt(*new TranslationUnit(nullptr, start, end, m_filename)); - m_nodes.append(node); + m_state.nodes.append(node); m_root_node = node; return node; } + + DummyAstNode& get_dummy_node() + { + static NonnullRefPtr dummy = adopt(*new DummyAstNode(nullptr, {}, {}, {})); + return dummy; + } + + bool match_attribute_specification(); void consume_attribute_specification(); bool match_ellipsis(); @@ -191,7 +202,6 @@ private: State m_state; Vector m_saved_states; RefPtr m_root_node; - NonnullRefPtrVector m_nodes; Vector m_replaced_preprocessor_tokens; };