Skip to content

Commit 7b5d4c5

Browse files
authored
Add support for non-instantiated template rules (#14)
Adds support for writing translation rules without having to manually create placeholder classes to instantiate them. For a rule as follows: ```cpp template <typename T1> void f1(T1 first, T1 last) { return std::sort(first, last); } ``` We must determine what the name `std::sort` refers to. First, the rule's template parameters are inspected, and a set of template arguments is synthesized. Each synthesized argument is either an empty struct or a constexpr with an appropriate type, depending on the kind of the corresponding template parameter. These template arguments are then used to instantiate the rule's function signature, which yields the non-dependent type of each call argument. These types are used to synthesize a set of expressions corresponding to call arguments. Since the synthesized template arguments may not respect all of the constraints of a given template, it's not possible to directly instantiate the body of the rule and simply fetch the returned value. For instance, `std::sort` expects its arguments to be iterator-like, and it cannot be specialized with an empty struct `struct T1{};`. Afterwards, the name is looked up. For each overload, any implicit template arguments are deduced using the previously obtained synthesized call arguments. The deduced template arguments are combined with any explicit template arguments and used to instantiate the overloads' declaration. Finally, overload resolution is performed, and the best match is selected. The only rules that are not yet handled are those that receive a lambda expression as a parameter (e.g. the rule `algorithm/f6`), as it is not possible to explicitly write the type of such expressions. Since rule matching is performed by printing rules and comparing strings, I believe that a possible solution would be to print lambda expressions as if they were regular function pointers. This would eliminate the need to write duplicate rules for functions receiving function pointers and functions receiving lambda expressions, but it would also preclude us from writing rules that handle lambda expressions and function pointers differently.
1 parent ff93441 commit 7b5d4c5

22 files changed

Lines changed: 887 additions & 887 deletions

File tree

cpp2rust/converter/mapper.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,6 @@ decltype(types_)::const_iterator search(clang::QualType qual_type) {
391391
}
392392

393393
void addRulesFromDirectory(const std::filesystem::path &dir, Model model) {
394-
std::vector<std::filesystem::path> paths;
395394
for (const auto &entry : std::filesystem::recursive_directory_iterator(dir)) {
396395
auto &path = entry.path();
397396
if (entry.is_regular_file() && path.extension() == ".cpp") {
@@ -670,7 +669,7 @@ void AddRuleForUserDefinedType(clang::NamedDecl *decl) {
670669
break;
671670
case Model::kRefCount:
672671
types_[cpp_name + " *"] = TranslationRule::TypeTgt::RefcountPtr(
673-
"PtrDyn<dyn " + rs_name + ">");
672+
"PtrDyn<dyn " + rs_name + '>');
674673
break;
675674
}
676675
} else {
@@ -681,7 +680,7 @@ void AddRuleForUserDefinedType(clang::NamedDecl *decl) {
681680
break;
682681
case Model::kRefCount:
683682
types_[cpp_name + " *"] =
684-
TranslationRule::TypeTgt::RefcountPtr("Ptr<" + rs_name + ">");
683+
TranslationRule::TypeTgt::RefcountPtr("Ptr<" + rs_name + '>');
685684
break;
686685
}
687686
}

0 commit comments

Comments
 (0)