mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 12:19:54 +00:00
Everywhere: Warn on function definitions without prototypes
If no header includes the prototype of a function, then it cannot be used from outside the translation unit it was defined in. In that case, it should be marked as `static`, in order to avoid possible ODR problems, unnecessary exported symbols, and allow the compiler to better optimize those. If this warning triggers in a function defined in a header, `inline` needs to be added, otherwise if the header is included in more than one TU, it will fail to link with a duplicate definition error. The reason this diff got so big is that Lagom-only code wasn't built with this flag even in Serenity times.
This commit is contained in:
parent
7fe82a1cda
commit
c62240aa80
Notes:
sideshowbarker
2024-07-18 08:27:14 +09:00
Author: https://github.com/BertalanD
Commit: c62240aa80
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/626
Reviewed-by: https://github.com/ADKaster ✅
Reviewed-by: https://github.com/trflynn89
24 changed files with 146 additions and 97 deletions
|
@ -16,6 +16,7 @@
|
|||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace {
|
||||
struct Parameter {
|
||||
Vector<ByteString> attributes;
|
||||
ByteString type;
|
||||
|
@ -823,6 +824,7 @@ void build(StringBuilder& builder, Vector<Endpoint> const& endpoints)
|
|||
for (auto const& endpoint : endpoints)
|
||||
build_endpoint(generator.fork(), endpoint);
|
||||
}
|
||||
} // end anonymous namespace
|
||||
|
||||
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
{
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <LibCore/File.h>
|
||||
#include <LibMain/Main.h>
|
||||
|
||||
namespace {
|
||||
struct LookupTable {
|
||||
u32 first_pointer;
|
||||
u32 max_code_point;
|
||||
|
@ -175,6 +176,7 @@ namespace TextCodec {
|
|||
TRY(file.write_until_depleted(generator.as_string_view().bytes()));
|
||||
return {};
|
||||
}
|
||||
} // end anonymous namespace
|
||||
|
||||
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
{
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "IDLGenerators.h"
|
||||
#include "Namespaces.h"
|
||||
#include <AK/Array.h>
|
||||
#include <AK/LexicalPath.h>
|
||||
|
@ -17,10 +18,10 @@
|
|||
#include <AK/QuickSort.h>
|
||||
#include <LibIDL/Types.h>
|
||||
|
||||
Vector<StringView> s_header_search_paths;
|
||||
|
||||
namespace IDL {
|
||||
|
||||
Vector<StringView> g_header_search_paths;
|
||||
|
||||
// FIXME: Generate this automatically somehow.
|
||||
static bool is_platform_object(Type const& type)
|
||||
{
|
||||
|
@ -284,7 +285,7 @@ static void generate_include_for(auto& generator, auto& path)
|
|||
{
|
||||
auto forked_generator = generator.fork();
|
||||
auto path_string = path;
|
||||
for (auto& search_path : s_header_search_paths) {
|
||||
for (auto& search_path : g_header_search_paths) {
|
||||
if (!path.starts_with(search_path))
|
||||
continue;
|
||||
auto relative_path = LexicalPath::relative_path(path, search_path);
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2020-2023, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2021-2023, Linus Groh <linusg@serenityos.org>
|
||||
* Copyright (c) 2021-2023, Luke Wilde <lukew@serenityos.org>
|
||||
* Copyright (c) 2022, Ali Mohammad Pur <mpfard@serenityos.org>
|
||||
* Copyright (c) 2023-2024, Kenneth Myhra <kennethmyhra@serenityos.org>
|
||||
* Copyright (c) 2023-2024, Shannon Booth <shannon@serenityos.org>
|
||||
* Copyright (c) 2023-2024, Matthew Olsson <mattco@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <LibIDL/Types.h>
|
||||
|
||||
namespace IDL {
|
||||
|
||||
void generate_namespace_header(IDL::Interface const&, StringBuilder&);
|
||||
void generate_namespace_implementation(IDL::Interface const&, StringBuilder&);
|
||||
void generate_constructor_header(IDL::Interface const&, StringBuilder&);
|
||||
void generate_constructor_implementation(IDL::Interface const&, StringBuilder&);
|
||||
void generate_prototype_header(IDL::Interface const&, StringBuilder&);
|
||||
void generate_prototype_implementation(IDL::Interface const&, StringBuilder&);
|
||||
void generate_iterator_prototype_header(IDL::Interface const&, StringBuilder&);
|
||||
void generate_iterator_prototype_implementation(IDL::Interface const&, StringBuilder&);
|
||||
void generate_global_mixin_header(IDL::Interface const&, StringBuilder&);
|
||||
void generate_global_mixin_implementation(IDL::Interface const&, StringBuilder&);
|
||||
|
||||
extern Vector<StringView> g_header_search_paths;
|
||||
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "IDLGenerators.h"
|
||||
#include "Namespaces.h"
|
||||
#include <AK/Debug.h>
|
||||
#include <AK/LexicalPath.h>
|
||||
|
@ -16,21 +17,6 @@
|
|||
#include <LibIDL/IDLParser.h>
|
||||
#include <LibIDL/Types.h>
|
||||
|
||||
extern Vector<StringView> s_header_search_paths;
|
||||
|
||||
namespace IDL {
|
||||
void generate_namespace_header(IDL::Interface const&, StringBuilder&);
|
||||
void generate_namespace_implementation(IDL::Interface const&, StringBuilder&);
|
||||
void generate_constructor_header(IDL::Interface const&, StringBuilder&);
|
||||
void generate_constructor_implementation(IDL::Interface const&, StringBuilder&);
|
||||
void generate_prototype_header(IDL::Interface const&, StringBuilder&);
|
||||
void generate_prototype_implementation(IDL::Interface const&, StringBuilder&);
|
||||
void generate_iterator_prototype_header(IDL::Interface const&, StringBuilder&);
|
||||
void generate_iterator_prototype_implementation(IDL::Interface const&, StringBuilder&);
|
||||
void generate_global_mixin_header(IDL::Interface const&, StringBuilder&);
|
||||
void generate_global_mixin_implementation(IDL::Interface const&, StringBuilder&);
|
||||
}
|
||||
|
||||
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
{
|
||||
Core::ArgsParser args_parser;
|
||||
|
@ -47,7 +33,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
.short_name = 'i',
|
||||
.value_name = "path",
|
||||
.accept_value = [&](StringView s) {
|
||||
s_header_search_paths.append(s);
|
||||
IDL::g_header_search_paths.append(s);
|
||||
return true;
|
||||
},
|
||||
});
|
||||
|
|
|
@ -10,34 +10,7 @@
|
|||
#include <LibCore/ArgsParser.h>
|
||||
#include <LibMain/Main.h>
|
||||
|
||||
ErrorOr<void> generate_header_file(JsonObject& roles_data, Core::File& file);
|
||||
ErrorOr<void> generate_implementation_file(JsonObject& roles_data, Core::File& file);
|
||||
|
||||
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
{
|
||||
StringView generated_header_path;
|
||||
StringView generated_implementation_path;
|
||||
StringView identifiers_json_path;
|
||||
|
||||
Core::ArgsParser args_parser;
|
||||
args_parser.add_option(generated_header_path, "Path to the TransformFunctions header file to generate", "generated-header-path", 'h', "generated-header-path");
|
||||
args_parser.add_option(generated_implementation_path, "Path to the TransformFunctions implementation file to generate", "generated-implementation-path", 'c', "generated-implementation-path");
|
||||
args_parser.add_option(identifiers_json_path, "Path to the JSON file to read from", "json-path", 'j', "json-path");
|
||||
args_parser.parse(arguments);
|
||||
|
||||
auto json = TRY(read_entire_file_as_json(identifiers_json_path));
|
||||
VERIFY(json.is_object());
|
||||
auto roles_data = json.as_object();
|
||||
|
||||
auto generated_header_file = TRY(Core::File::open(generated_header_path, Core::File::OpenMode::Write));
|
||||
auto generated_implementation_file = TRY(Core::File::open(generated_implementation_path, Core::File::OpenMode::Write));
|
||||
|
||||
TRY(generate_header_file(roles_data, *generated_header_file));
|
||||
TRY(generate_implementation_file(roles_data, *generated_implementation_file));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
namespace {
|
||||
ErrorOr<void> generate_header_file(JsonObject& roles_data, Core::File& file)
|
||||
{
|
||||
StringBuilder builder;
|
||||
|
@ -387,3 +360,29 @@ NameFromSource @name@::name_from_source() const
|
|||
TRY(file.write_until_depleted(generator.as_string_view().bytes()));
|
||||
return {};
|
||||
}
|
||||
} // end anonymous namespace
|
||||
|
||||
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
{
|
||||
StringView generated_header_path;
|
||||
StringView generated_implementation_path;
|
||||
StringView identifiers_json_path;
|
||||
|
||||
Core::ArgsParser args_parser;
|
||||
args_parser.add_option(generated_header_path, "Path to the TransformFunctions header file to generate", "generated-header-path", 'h', "generated-header-path");
|
||||
args_parser.add_option(generated_implementation_path, "Path to the TransformFunctions implementation file to generate", "generated-implementation-path", 'c', "generated-implementation-path");
|
||||
args_parser.add_option(identifiers_json_path, "Path to the JSON file to read from", "json-path", 'j', "json-path");
|
||||
args_parser.parse(arguments);
|
||||
|
||||
auto json = TRY(read_entire_file_as_json(identifiers_json_path));
|
||||
VERIFY(json.is_object());
|
||||
auto roles_data = json.as_object();
|
||||
|
||||
auto generated_header_file = TRY(Core::File::open(generated_header_path, Core::File::OpenMode::Write));
|
||||
auto generated_implementation_file = TRY(Core::File::open(generated_implementation_path, Core::File::OpenMode::Write));
|
||||
|
||||
TRY(generate_header_file(roles_data, *generated_header_file));
|
||||
TRY(generate_implementation_file(roles_data, *generated_implementation_file));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -10,34 +10,7 @@
|
|||
#include <LibCore/ArgsParser.h>
|
||||
#include <LibMain/Main.h>
|
||||
|
||||
ErrorOr<void> generate_header_file(JsonObject& functions_data, Core::File& file);
|
||||
ErrorOr<void> generate_implementation_file(JsonObject& functions_data, Core::File& file);
|
||||
|
||||
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
{
|
||||
StringView generated_header_path;
|
||||
StringView generated_implementation_path;
|
||||
StringView identifiers_json_path;
|
||||
|
||||
Core::ArgsParser args_parser;
|
||||
args_parser.add_option(generated_header_path, "Path to the MathFunctions header file to generate", "generated-header-path", 'h', "generated-header-path");
|
||||
args_parser.add_option(generated_implementation_path, "Path to the MathFunctions implementation file to generate", "generated-implementation-path", 'c', "generated-implementation-path");
|
||||
args_parser.add_option(identifiers_json_path, "Path to the JSON file to read from", "json-path", 'j', "json-path");
|
||||
args_parser.parse(arguments);
|
||||
|
||||
auto json = TRY(read_entire_file_as_json(identifiers_json_path));
|
||||
VERIFY(json.is_object());
|
||||
auto math_functions_data = json.as_object();
|
||||
|
||||
auto generated_header_file = TRY(Core::File::open(generated_header_path, Core::File::OpenMode::Write));
|
||||
auto generated_implementation_file = TRY(Core::File::open(generated_implementation_path, Core::File::OpenMode::Write));
|
||||
|
||||
TRY(generate_header_file(math_functions_data, *generated_header_file));
|
||||
TRY(generate_implementation_file(math_functions_data, *generated_implementation_file));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
namespace {
|
||||
ErrorOr<void> generate_header_file(JsonObject& functions_data, Core::File& file)
|
||||
{
|
||||
StringBuilder builder;
|
||||
|
@ -378,3 +351,29 @@ OwnPtr<CalculationNode> Parser::parse_math_function(PropertyID property_id, Func
|
|||
TRY(file.write_until_depleted(generator.as_string_view().bytes()));
|
||||
return {};
|
||||
}
|
||||
} // end anonymous namespace
|
||||
|
||||
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
{
|
||||
StringView generated_header_path;
|
||||
StringView generated_implementation_path;
|
||||
StringView identifiers_json_path;
|
||||
|
||||
Core::ArgsParser args_parser;
|
||||
args_parser.add_option(generated_header_path, "Path to the MathFunctions header file to generate", "generated-header-path", 'h', "generated-header-path");
|
||||
args_parser.add_option(generated_implementation_path, "Path to the MathFunctions implementation file to generate", "generated-implementation-path", 'c', "generated-implementation-path");
|
||||
args_parser.add_option(identifiers_json_path, "Path to the JSON file to read from", "json-path", 'j', "json-path");
|
||||
args_parser.parse(arguments);
|
||||
|
||||
auto json = TRY(read_entire_file_as_json(identifiers_json_path));
|
||||
VERIFY(json.is_object());
|
||||
auto math_functions_data = json.as_object();
|
||||
|
||||
auto generated_header_file = TRY(Core::File::open(generated_header_path, Core::File::OpenMode::Write));
|
||||
auto generated_implementation_file = TRY(Core::File::open(generated_implementation_path, Core::File::OpenMode::Write));
|
||||
|
||||
TRY(generate_header_file(math_functions_data, *generated_header_file));
|
||||
TRY(generate_implementation_file(math_functions_data, *generated_implementation_file));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include <LibCore/File.h>
|
||||
#include <ctype.h>
|
||||
|
||||
String title_casify(StringView dashy_name)
|
||||
inline String title_casify(StringView dashy_name)
|
||||
{
|
||||
auto parts = dashy_name.split_view('-');
|
||||
StringBuilder builder;
|
||||
|
@ -28,7 +28,7 @@ String title_casify(StringView dashy_name)
|
|||
return MUST(builder.to_string());
|
||||
}
|
||||
|
||||
String camel_casify(StringView dashy_name)
|
||||
inline String camel_casify(StringView dashy_name)
|
||||
{
|
||||
auto parts = dashy_name.split_view('-');
|
||||
StringBuilder builder;
|
||||
|
@ -49,14 +49,14 @@ String camel_casify(StringView dashy_name)
|
|||
return MUST(builder.to_string());
|
||||
}
|
||||
|
||||
String snake_casify(StringView dashy_name)
|
||||
inline String snake_casify(StringView dashy_name)
|
||||
{
|
||||
// FIXME: We don't really need to convert dashy_name to a String first, but currently
|
||||
// all the `replace` functions that take a StringView return ByteString.
|
||||
return MUST(MUST(String::from_utf8(dashy_name)).replace("-"sv, "_"sv, ReplaceMode::All));
|
||||
}
|
||||
|
||||
ErrorOr<JsonValue> read_entire_file_as_json(StringView filename)
|
||||
inline ErrorOr<JsonValue> read_entire_file_as_json(StringView filename)
|
||||
{
|
||||
auto file = TRY(Core::File::open(filename, Core::File::OpenMode::Read));
|
||||
auto json_size = TRY(file->size());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue