1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 20:47:45 +00:00

LibCpp: Add support for type aliases with typedef/using

This commit is contained in:
Ali Mohammad Pur 2023-06-17 22:41:30 +03:30 committed by Andreas Kling
parent 2e2e535abb
commit 543ccecc0b
4 changed files with 115 additions and 0 deletions

View file

@ -93,6 +93,10 @@ NonnullRefPtr<Declaration const> Parser::parse_declaration(ASTNode const& parent
return parse_destructor(parent);
case DeclarationType::UsingNamespace:
return parse_using_namespace_declaration(parent);
case DeclarationType::UsingType:
return parse_using_type_declaration(parent);
case DeclarationType::Typedef:
return parse_typedef_declaration(parent);
default:
error("unexpected declaration type"sv);
return create_ast_node<InvalidDeclaration>(parent, position(), position());
@ -641,6 +645,10 @@ Optional<Parser::DeclarationType> Parser::match_declaration_in_translation_unit(
return DeclarationType::Variable;
if (match_using_namespace_declaration())
return DeclarationType::UsingNamespace;
if (match_using_type_declaration())
return DeclarationType::UsingType;
if (match_typedef_declaration())
return DeclarationType::Typedef;
return {};
}
@ -1761,6 +1769,41 @@ bool Parser::match_using_namespace_declaration()
return true;
}
bool Parser::match_using_type_declaration()
{
save_state();
ScopeGuard state_guard = [this] { load_state(); };
if (!match_keyword("using"))
return false;
consume();
if (!match(Token::Type::Identifier))
return false;
return true;
}
bool Parser::match_typedef_declaration()
{
save_state();
ScopeGuard state_guard = [this] { load_state(); };
if (!match_keyword("typedef"))
return false;
consume();
// FIXME: typedef void (*fn)()
if (!match_type())
return false;
if (!match(Token::Type::Identifier))
return false;
return true;
}
NonnullRefPtr<UsingNamespaceDeclaration const> Parser::parse_using_namespace_declaration(ASTNode const& parent)
{
auto decl = create_ast_node<UsingNamespaceDeclaration>(parent, position(), {});
@ -1778,4 +1821,44 @@ NonnullRefPtr<UsingNamespaceDeclaration const> Parser::parse_using_namespace_dec
return decl;
}
NonnullRefPtr<TypedefDeclaration const> Parser::parse_typedef_declaration(Cpp::ASTNode const& parent)
{
auto decl = create_ast_node<TypedefDeclaration>(parent, position(), {});
consume_keyword("typedef");
auto type = parse_type(*decl);
decl->set_alias(type);
auto name = parse_name(*decl);
decl->set_name(name);
decl->set_end(position());
consume(Token::Type::Semicolon);
return decl;
}
NonnullRefPtr<TypedefDeclaration const> Parser::parse_using_type_declaration(Cpp::ASTNode const& parent)
{
auto decl = create_ast_node<TypedefDeclaration>(parent, position(), {});
// FIXME: These can also be templated.
consume_keyword("using");
auto name = parse_name(*decl);
decl->set_name(name);
if (match(Token::Type::Equals)) {
consume();
auto type = parse_type(*decl);
decl->set_alias(type);
}
decl->set_end(position());
consume(Token::Type::Semicolon);
return decl;
}
}