summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorItamar <itamar8910@gmail.com>2021-03-27 19:19:53 +0300
committerAndreas Kling <kling@serenityos.org>2021-04-06 21:51:58 +0200
commit1f9f6ea9d64ab412bd5a017c81aebe3602cde3e7 (patch)
tree8f778408492b7a152c1bde94c2acd7fc566e9756
parentee35fc0da31a99d8d5198e9f141cd0b142d461dc (diff)
downloadserenity-1f9f6ea9d64ab412bd5a017c81aebe3602cde3e7.zip
LibCpp: Support parsing function qualifiers
-rw-r--r--Userland/Libraries/LibCpp/AST.cpp7
-rw-r--r--Userland/Libraries/LibCpp/AST.h1
-rw-r--r--Userland/Libraries/LibCpp/Parser.cpp58
-rw-r--r--Userland/Libraries/LibCpp/Parser.h2
4 files changed, 58 insertions, 10 deletions
diff --git a/Userland/Libraries/LibCpp/AST.cpp b/Userland/Libraries/LibCpp/AST.cpp
index 9243099f90..a928a53afc 100644
--- a/Userland/Libraries/LibCpp/AST.cpp
+++ b/Userland/Libraries/LibCpp/AST.cpp
@@ -51,6 +51,13 @@ void TranslationUnit::dump(size_t indent) const
void FunctionDeclaration::dump(size_t indent) const
{
ASTNode::dump(indent);
+
+ String qualifiers_string;
+ if (!m_qualifiers.is_empty()) {
+ print_indent(indent+1);
+ outln("[{}]", String::join(" ", m_qualifiers));
+ }
+
m_return_type->dump(indent + 1);
if (!m_name.is_null()) {
print_indent(indent + 1);
diff --git a/Userland/Libraries/LibCpp/AST.h b/Userland/Libraries/LibCpp/AST.h
index 1fab2109ed..1d749e348b 100644
--- a/Userland/Libraries/LibCpp/AST.h
+++ b/Userland/Libraries/LibCpp/AST.h
@@ -171,6 +171,7 @@ public:
virtual NonnullRefPtrVector<Declaration> declarations() const override;
+ Vector<StringView> m_qualifiers;
RefPtr<Type> m_return_type;
NonnullRefPtrVector<Parameter> m_parameters;
RefPtr<FunctionDefinition> m_definition;
diff --git a/Userland/Libraries/LibCpp/Parser.cpp b/Userland/Libraries/LibCpp/Parser.cpp
index 647adc9f75..42ca7f04dd 100644
--- a/Userland/Libraries/LibCpp/Parser.cpp
+++ b/Userland/Libraries/LibCpp/Parser.cpp
@@ -142,10 +142,17 @@ NonnullRefPtr<FunctionDeclaration> Parser::parse_function_declaration(ASTNode& p
{
auto func = create_ast_node<FunctionDeclaration>(parent, position(), {});
- auto return_type_token = consume(Token::Type::KnownType);
+ func->m_qualifiers = parse_function_qualifiers();
+ func->m_return_type = parse_type(*func);
+
auto function_name = consume(Token::Type::Identifier);
+ func->m_name = text_of_token(function_name);
+
consume(Token::Type::LeftParen);
auto parameters = parse_parameter_list(*func);
+ if (parameters.has_value())
+ func->m_parameters = move(parameters.value());
+
consume(Token::Type::RightParen);
RefPtr<FunctionDefinition> body;
@@ -160,10 +167,6 @@ NonnullRefPtr<FunctionDeclaration> Parser::parse_function_declaration(ASTNode& p
consume(Token::Type::Semicolon);
}
- func->m_name = text_of_token(function_name);
- func->m_return_type = create_ast_node<Type>(*func, return_type_token.start(), return_type_token.end(), text_of_token(return_type_token));
- if (parameters.has_value())
- func->m_parameters = move(parameters.value());
func->m_definition = move(body);
func->set_end(func_end);
return func;
@@ -248,9 +251,8 @@ NonnullRefPtr<BlockStatement> Parser::parse_block_statement(ASTNode& parent)
return block_statement;
}
-bool Parser::match_variable_declaration()
+bool Parser::match_type()
{
- SCOPE_LOGGER();
save_state();
ScopeGuard state_guard = [this] { load_state(); };
@@ -258,7 +260,19 @@ bool Parser::match_variable_declaration()
// Type
if (!peek(Token::Type::KnownType).has_value() && !peek(Token::Type::Identifier).has_value())
return false;
- consume();
+ return true;
+}
+
+bool Parser::match_variable_declaration()
+{
+ SCOPE_LOGGER();
+ save_state();
+ ScopeGuard state_guard = [this] { load_state(); };
+
+ if (!match_type())
+ return false;
+ VERIFY(m_root_node);
+ parse_type(*m_root_node);
// Identifier
if (!peek(Token::Type::Identifier).has_value())
@@ -561,9 +575,12 @@ bool Parser::match_function_declaration()
save_state();
ScopeGuard state_guard = [this] { load_state(); };
- if (!peek(Token::Type::KnownType).has_value())
+ parse_function_qualifiers();
+
+ if (!match_type())
return false;
- consume();
+ VERIFY(m_root_node);
+ parse_type(*m_root_node);
if (!peek(Token::Type::Identifier).has_value())
return false;
@@ -1098,6 +1115,27 @@ Vector<StringView> Parser::parse_type_qualifiers()
}
return qualifiers;
}
+
+Vector<StringView> Parser::parse_function_qualifiers()
+{
+ SCOPE_LOGGER();
+ Vector<StringView> qualifiers;
+ while (!eof()) {
+ auto token = peek();
+ if (token.type() != Token::Type::Keyword)
+ break;
+ auto text = text_of_token(token);
+ if (text == "static" || text == "inline") {
+ qualifiers.append(text);
+ consume();
+ } else {
+ break;
+ }
+ }
+ return qualifiers;
+}
+
+
bool Parser::match_attribute_specification()
{
return text_of_token(peek()) == "__attribute__";
diff --git a/Userland/Libraries/LibCpp/Parser.h b/Userland/Libraries/LibCpp/Parser.h
index 2255fcbc29..2fe0bacd43 100644
--- a/Userland/Libraries/LibCpp/Parser.h
+++ b/Userland/Libraries/LibCpp/Parser.h
@@ -88,6 +88,7 @@ private:
bool match_keyword(const String&);
bool match_block_statement();
bool match_namespace_declaration();
+ bool match_type();
Optional<NonnullRefPtrVector<Parameter>> parse_parameter_list(ASTNode& parent);
Optional<Token> consume_whitespace();
@@ -163,6 +164,7 @@ private:
void initialize_program_tokens(const StringView& program);
void add_tokens_for_preprocessor(Token& replaced_token, Preprocessor::DefinedValue&);
Vector<StringView> parse_type_qualifiers();
+ Vector<StringView> parse_function_qualifiers();
Preprocessor::Definitions m_definitions;
String m_filename;