mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 03:37:43 +00:00
LibCpp: Add support for type aliases with typedef/using
This commit is contained in:
parent
2e2e535abb
commit
543ccecc0b
4 changed files with 115 additions and 0 deletions
|
@ -683,4 +683,13 @@ void UsingNamespaceDeclaration::dump(FILE* output, size_t indent) const
|
||||||
outln(output, "{}", full_name());
|
outln(output, "{}", full_name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TypedefDeclaration::dump(FILE* output, size_t indent) const
|
||||||
|
{
|
||||||
|
ASTNode::dump(output, indent);
|
||||||
|
print_indent(output, indent + 1);
|
||||||
|
outln(output, "{}", full_name());
|
||||||
|
if (m_alias)
|
||||||
|
m_alias->dump(output, indent + 1);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1007,6 +1007,23 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TypedefDeclaration : public Declaration {
|
||||||
|
public:
|
||||||
|
virtual ~TypedefDeclaration() override = default;
|
||||||
|
virtual StringView class_name() const override { return "TypedefDeclaration"sv; }
|
||||||
|
virtual void dump(FILE* = stdout, size_t indent = 0) const override;
|
||||||
|
|
||||||
|
TypedefDeclaration(ASTNode const* parent, Optional<Position> start, Optional<Position> end, DeprecatedString const& filename)
|
||||||
|
: Declaration(parent, start, end, filename)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_alias(Type const& alias) { m_alias = alias; }
|
||||||
|
Type const* alias() const { return m_alias.ptr(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
RefPtr<Type const> m_alias;
|
||||||
|
};
|
||||||
template<>
|
template<>
|
||||||
inline bool ASTNode::fast_is<Identifier>() const { return is_identifier(); }
|
inline bool ASTNode::fast_is<Identifier>() const { return is_identifier(); }
|
||||||
template<>
|
template<>
|
||||||
|
|
|
@ -93,6 +93,10 @@ NonnullRefPtr<Declaration const> Parser::parse_declaration(ASTNode const& parent
|
||||||
return parse_destructor(parent);
|
return parse_destructor(parent);
|
||||||
case DeclarationType::UsingNamespace:
|
case DeclarationType::UsingNamespace:
|
||||||
return parse_using_namespace_declaration(parent);
|
return parse_using_namespace_declaration(parent);
|
||||||
|
case DeclarationType::UsingType:
|
||||||
|
return parse_using_type_declaration(parent);
|
||||||
|
case DeclarationType::Typedef:
|
||||||
|
return parse_typedef_declaration(parent);
|
||||||
default:
|
default:
|
||||||
error("unexpected declaration type"sv);
|
error("unexpected declaration type"sv);
|
||||||
return create_ast_node<InvalidDeclaration>(parent, position(), position());
|
return create_ast_node<InvalidDeclaration>(parent, position(), position());
|
||||||
|
@ -641,6 +645,10 @@ Optional<Parser::DeclarationType> Parser::match_declaration_in_translation_unit(
|
||||||
return DeclarationType::Variable;
|
return DeclarationType::Variable;
|
||||||
if (match_using_namespace_declaration())
|
if (match_using_namespace_declaration())
|
||||||
return DeclarationType::UsingNamespace;
|
return DeclarationType::UsingNamespace;
|
||||||
|
if (match_using_type_declaration())
|
||||||
|
return DeclarationType::UsingType;
|
||||||
|
if (match_typedef_declaration())
|
||||||
|
return DeclarationType::Typedef;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1761,6 +1769,41 @@ bool Parser::match_using_namespace_declaration()
|
||||||
return true;
|
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)
|
NonnullRefPtr<UsingNamespaceDeclaration const> Parser::parse_using_namespace_declaration(ASTNode const& parent)
|
||||||
{
|
{
|
||||||
auto decl = create_ast_node<UsingNamespaceDeclaration>(parent, position(), {});
|
auto decl = create_ast_node<UsingNamespaceDeclaration>(parent, position(), {});
|
||||||
|
@ -1778,4 +1821,44 @@ NonnullRefPtr<UsingNamespaceDeclaration const> Parser::parse_using_namespace_dec
|
||||||
return decl;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,8 @@ private:
|
||||||
Constructor,
|
Constructor,
|
||||||
Destructor,
|
Destructor,
|
||||||
UsingNamespace,
|
UsingNamespace,
|
||||||
|
Typedef,
|
||||||
|
UsingType,
|
||||||
};
|
};
|
||||||
|
|
||||||
Optional<DeclarationType> match_declaration_in_translation_unit();
|
Optional<DeclarationType> match_declaration_in_translation_unit();
|
||||||
|
@ -82,6 +84,8 @@ private:
|
||||||
bool match_constructor(StringView class_name);
|
bool match_constructor(StringView class_name);
|
||||||
bool match_destructor(StringView class_name);
|
bool match_destructor(StringView class_name);
|
||||||
bool match_using_namespace_declaration();
|
bool match_using_namespace_declaration();
|
||||||
|
bool match_typedef_declaration();
|
||||||
|
bool match_using_type_declaration();
|
||||||
|
|
||||||
Optional<Vector<NonnullRefPtr<Parameter const>>> parse_parameter_list(ASTNode const& parent);
|
Optional<Vector<NonnullRefPtr<Parameter const>>> parse_parameter_list(ASTNode const& parent);
|
||||||
Optional<Token> consume_whitespace();
|
Optional<Token> consume_whitespace();
|
||||||
|
@ -122,6 +126,8 @@ private:
|
||||||
NonnullRefPtr<Constructor const> parse_constructor(ASTNode const& parent);
|
NonnullRefPtr<Constructor const> parse_constructor(ASTNode const& parent);
|
||||||
NonnullRefPtr<Destructor const> parse_destructor(ASTNode const& parent);
|
NonnullRefPtr<Destructor const> parse_destructor(ASTNode const& parent);
|
||||||
NonnullRefPtr<UsingNamespaceDeclaration const> parse_using_namespace_declaration(ASTNode const& parent);
|
NonnullRefPtr<UsingNamespaceDeclaration const> parse_using_namespace_declaration(ASTNode const& parent);
|
||||||
|
NonnullRefPtr<TypedefDeclaration const> parse_typedef_declaration(ASTNode const& parent);
|
||||||
|
NonnullRefPtr<TypedefDeclaration const> parse_using_type_declaration(ASTNode const& parent);
|
||||||
|
|
||||||
bool match(Token::Type);
|
bool match(Token::Type);
|
||||||
Token consume(Token::Type);
|
Token consume(Token::Type);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue