1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 14:27:35 +00:00

LibCpp: Support for parsing c-style fixed arrays (arr[2])

Also adds tests for finding declaration of arrays inside
CppComprehension which requires proper parsing for passing.

Side-effect of this patch: if we ctrl+click on array variables, it
should jump to the correct declaration inside HackStudio.
This commit is contained in:
iyush 2023-04-15 16:40:40 +02:00 committed by Sam Atkins
parent 34b04271f4
commit ac435f914c
7 changed files with 184 additions and 8 deletions

View file

@ -572,6 +572,24 @@ StringView TemplatizedName::full_name() const
return *m_full_name;
}
void SizedName::dump(FILE* output, size_t indent) const
{
Name::dump(output, indent);
print_indent(output, indent + 1);
StringBuilder dimension_info;
for (auto const& dim : m_dimensions) {
dimension_info.append('[');
dimension_info.append(dim);
dimension_info.append(']');
}
if (dimension_info.is_empty()) {
dimension_info.append("[]"sv);
}
outln(output, "{}", dimension_info.to_deprecated_string());
}
void CppCastExpression::dump(FILE* output, size_t indent) const
{
ASTNode::dump(output, indent);

View file

@ -434,6 +434,7 @@ public:
virtual void dump(FILE* = stdout, size_t indent = 0) const override;
virtual bool is_name() const override { return true; }
virtual bool is_templatized() const { return false; }
virtual bool is_sized() const { return false; }
Name(ASTNode const* parent, Optional<Position> start, Optional<Position> end, DeprecatedString const& filename)
: Expression(parent, start, end, filename)
@ -453,6 +454,25 @@ private:
mutable Optional<DeprecatedString> m_full_name;
};
class SizedName : public Name {
public:
virtual ~SizedName() override = default;
virtual StringView class_name() const override { return "SizedName"sv; }
virtual bool is_sized() const override { return true; }
void dump(FILE* output, size_t indent) const override;
SizedName(ASTNode const* parent, Optional<Position> start, Optional<Position> end, DeprecatedString const& filename)
: Name(parent, start, end, filename)
{
}
void append_dimension(StringView dim) { m_dimensions.append(dim); };
private:
Vector<StringView> m_dimensions;
mutable Optional<DeprecatedString> m_full_name;
};
class TemplatizedName : public Name {
public:
virtual ~TemplatizedName() override = default;
@ -1020,5 +1040,6 @@ template<>
inline bool ASTNode::fast_is<NamedType>() const { return is_type() && verify_cast<Type>(*this).is_named_type(); }
template<>
inline bool ASTNode::fast_is<TemplatizedName>() const { return is_name() && verify_cast<Name>(*this).is_templatized(); }
template<>
inline bool ASTNode::fast_is<SizedName>() const { return is_name() && verify_cast<Name>(*this).is_sized(); }
}

View file

@ -294,6 +294,19 @@ bool Parser::match_variable_declaration()
(void)parse_name(get_dummy_node());
while (!eof() && (peek().type() == Token::Type::LeftBracket)) {
consume(Token::Type::LeftBracket);
if (match(Token::Type::Integer)) {
consume(Token::Type::Integer);
}
if (!match(Token::Type::RightBracket)) {
error("No closing right bracket"sv);
return false;
}
consume(Token::Type::RightBracket);
}
if (match(Token::Type::Equals)) {
consume(Token::Type::Equals);
if (!match_expression()) {
@ -1449,7 +1462,9 @@ NonnullRefPtr<Name const> Parser::parse_name(ASTNode const& parent)
return name_node;
}
bool is_templatized = false;
if (match_template_arguments()) {
is_templatized = true;
consume(Token::Type::Less);
NonnullRefPtr<TemplatizedName> templatized_name = create_ast_node<TemplatizedName>(parent, name_node->start(), {});
templatized_name->set_name(name_node->name());
@ -1464,6 +1479,27 @@ NonnullRefPtr<Name const> Parser::parse_name(ASTNode const& parent)
consume(Token::Type::Greater);
}
if (!is_templatized && (peek().type() == Token::Type::LeftBracket)) {
NonnullRefPtr<SizedName> sized_name = create_ast_node<SizedName>(parent, name_node->start(), {});
sized_name->set_name(name_node->name());
sized_name->set_scope(name_node->scope());
while (peek().type() == Token::Type::LeftBracket) {
consume(Token::Type::LeftBracket);
StringView size = "0"sv;
if (peek().type() == Token::Type::Integer) {
auto token = consume(Token::Type::Integer);
size = token.text();
}
sized_name->append_dimension(size);
consume(Token::Type::RightBracket);
}
name_node->set_end(position());
name_node = sized_name;
}
name_node->set_end(previous_token_end());
return name_node;
}
@ -1564,6 +1600,8 @@ NonnullRefPtr<BracedInitList const> Parser::parse_braced_init_list(ASTNode const
consume(Token::Type::LeftCurly);
while (!eof() && peek().type() != Token::Type::RightCurly) {
init_list->add_expression(parse_expression(*init_list));
if (peek().type() == Token::Type::Comma)
consume(Token::Type::Comma);
}
consume(Token::Type::RightCurly);
init_list->set_end(position());

View file

@ -0,0 +1,19 @@
TranslationUnit[0:0->2:0]
FunctionDeclaration[0:0->2:0]
NamedType[0:0->0:3]
void
foo
(
)
FunctionDefinition[0:11->2:0]
{
VariableDeclaration[1:4->1:20]
NamedType[1:4->1:6]
int
x
BracedInitList[1:15->1:20]
NumericLiteral[1:16->1:16]
1
NumericLiteral[1:18->1:18]
2
}

View file

@ -0,0 +1,3 @@
void foo() {
int x[0] = {1,2};
}