diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/CppComprehensionEngine.cpp b/Userland/DevTools/HackStudio/LanguageServers/Cpp/CppComprehensionEngine.cpp index fd07b4f370..84c776faff 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/CppComprehensionEngine.cpp +++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/CppComprehensionEngine.cpp @@ -569,11 +569,16 @@ OwnPtr CppComprehensionEngine::create_docu document_data->m_preprocessor = make(document_data->m_filename, document_data->text()); document_data->preprocessor().set_ignore_unsupported_keywords(true); document_data->preprocessor().set_keep_include_statements(true); - auto tokens = document_data->preprocessor().process_and_lex(); - Preprocessor::Definitions preprocessor_definitions; - for (auto item : document_data->preprocessor().definitions()) - preprocessor_definitions.set(move(item.key), move(item.value)); + document_data->preprocessor().definitions_in_header_callback = [this](StringView include_path) -> Preprocessor::Definitions { + auto included_document = get_or_create_document_data(document_path_from_include_path(include_path)); + if (!included_document) + return {}; + + return included_document->preprocessor().definitions(); + }; + + auto tokens = document_data->preprocessor().process_and_lex(); for (auto include_path : document_data->preprocessor().included_paths()) { auto include_fullpath = document_path_from_include_path(include_path); @@ -585,12 +590,9 @@ OwnPtr CppComprehensionEngine::create_docu for (auto& header : included_document->m_available_headers) document_data->m_available_headers.set(header); - - for (auto item : included_document->parser().preprocessor_definitions()) - preprocessor_definitions.set(move(item.key), move(item.value)); } - document_data->m_parser = make(move(tokens), filename, move(preprocessor_definitions)); + document_data->m_parser = make(move(tokens), filename, document_data->preprocessor().definitions()); auto root = document_data->parser().parse(); diff --git a/Userland/Libraries/LibCpp/Parser.cpp b/Userland/Libraries/LibCpp/Parser.cpp index da0d479fda..4bcc5ecd67 100644 --- a/Userland/Libraries/LibCpp/Parser.cpp +++ b/Userland/Libraries/LibCpp/Parser.cpp @@ -15,7 +15,7 @@ namespace Cpp { -Parser::Parser(Vector const& tokens, const String& filename, Preprocessor::Definitions&& definitions) +Parser::Parser(Vector const& tokens, const String& filename, Preprocessor::Definitions const& definitions) : m_preprocessor_definitions(move(definitions)) , m_filename(filename) { diff --git a/Userland/Libraries/LibCpp/Parser.h b/Userland/Libraries/LibCpp/Parser.h index b21eca15bc..34e70bd7a6 100644 --- a/Userland/Libraries/LibCpp/Parser.h +++ b/Userland/Libraries/LibCpp/Parser.h @@ -18,7 +18,7 @@ class Parser final { AK_MAKE_NONCOPYABLE(Parser); public: - explicit Parser(Vector const& tokens, const String& filename, Preprocessor::Definitions&& = {}); + explicit Parser(Vector const& tokens, const String& filename, Preprocessor::Definitions const& = {}); ~Parser() = default; NonnullRefPtr parse(); diff --git a/Userland/Libraries/LibCpp/Preprocessor.cpp b/Userland/Libraries/LibCpp/Preprocessor.cpp index 85d5f143e4..cb7be70f7a 100644 --- a/Userland/Libraries/LibCpp/Preprocessor.cpp +++ b/Userland/Libraries/LibCpp/Preprocessor.cpp @@ -108,7 +108,12 @@ void Preprocessor::handle_preprocessor_keyword(const StringView& keyword, Generi { if (keyword == "include") { consume_whitespace(line_lexer); - m_included_paths.append(line_lexer.consume_all()); + auto include_path = line_lexer.consume_all(); + m_included_paths.append(include_path); + if (definitions_in_header_callback) { + for (auto& def : definitions_in_header_callback(include_path)) + m_definitions.set(def.key, def.value); + } return; } diff --git a/Userland/Libraries/LibCpp/Preprocessor.h b/Userland/Libraries/LibCpp/Preprocessor.h index e3dd45aa40..6459a7582c 100644 --- a/Userland/Libraries/LibCpp/Preprocessor.h +++ b/Userland/Libraries/LibCpp/Preprocessor.h @@ -7,6 +7,7 @@ #pragma once #include +#include #include #include #include @@ -36,6 +37,8 @@ public: void set_ignore_unsupported_keywords(bool ignore) { m_options.ignore_unsupported_keywords = ignore; } void set_keep_include_statements(bool keep) { m_options.keep_include_statements = keep; } + Function definitions_in_header_callback { nullptr }; + private: using PreprocessorKeyword = StringView; PreprocessorKeyword handle_preprocessor_line(StringView const&);