Skip to content

Commit

Permalink
feat: try to check that the lookup by Cpp1 and cppfront match
Browse files Browse the repository at this point in the history
  • Loading branch information
JohelEGP committed Dec 30, 2023
1 parent 9816d1b commit 22496c9
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 5 deletions.
1 change: 1 addition & 0 deletions source/parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -2552,6 +2552,7 @@ struct declaration_node
> type;

std::vector<std::unique_ptr<id_expression_node>> metafunctions;
std::vector<std::string> metafunction_lookup_checks;
std::unique_ptr<parameter_declaration_list_node> template_parameters;
source_position requires_pos = {};
std::unique_ptr<logical_or_expression_node> requires_clause_expression;
Expand Down
38 changes: 33 additions & 5 deletions source/sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,18 @@ auto demangle(std::string_view s)
return res;
}

struct lookup_res {
meta::lookup_res meta_res;
std::string demangled_name;
};

auto lookup(
std::string const& name,
current_names_span current_names
)
-> meta::expected<meta::lookup_res>
-> meta::expected<lookup_res>
{
auto res = meta::lookup_res{};
auto res = lookup_res{};
auto libraries = meta::get_reachable_metafunction_symbols();

(void)current_names;
Expand All @@ -93,7 +98,7 @@ auto lookup(
{
auto dname = demangle(sym.substr(meta::symbol_prefix.size()));
if (dname == name) {
return {{lib.name, sym}};
return {{{lib.name, sym}, std::move(dname)}};
}
}
}
Expand All @@ -105,7 +110,7 @@ auto lookup(
}

// Case not yet handled.
if (res.library.empty()) {
if (res.meta_res.library.empty()) {
return meta::diagnostic{"(ICE) metafunction '" + name + "' not found"};
}
// else
Expand All @@ -125,7 +130,30 @@ auto parser::apply_type_metafunctions( declaration_node& n )
n,
rtype,
[&](std::string const& msg) { error( msg, false ); },
[&](std::string const& name) { return lookup(name, current_names); }
[&](std::string const& name) {
return lookup(name, current_names).and_then(
[&](lookup_res res)
-> meta::expected<meta::lookup_res>
{
auto to_metafunction = [](std::string name) {
return "static_cast<void(*)(cpp2::meta::type_declaration&)>(" + std::move(name) + ")";
};
auto check = std::string{};
check += "static_assert(";
check += to_metafunction(name);
check += " == ";
check += to_metafunction("::" + std::move(res.demangled_name));
check += ", ";
// A static_assert doesn't really check that its the evaluated metafunction
// For that, we would have to load the metafunction symbol at runtime
check += "\"the metafunction name '" + name + "' must be ";
check += "reachable and equal to the one evaluated by cppfront\"";
check += ");\n";
n.metafunction_lookup_checks.push_back(check);
return res.meta_res;
}
);
}
);
}

Expand Down
7 changes: 7 additions & 0 deletions source/to_cpp1.h
Original file line number Diff line number Diff line change
Expand Up @@ -5523,6 +5523,13 @@ class cppfront
}


if (printer.get_phase() == printer.phase1_type_defs_func_decls) {
for (auto&& check : n.metafunction_lookup_checks) {
printer.print_extra(check);
}
}


// If this is a function that has multiple return values,
// first we need to emit the struct that contains the returns
if (
Expand Down

0 comments on commit 22496c9

Please sign in to comment.