Skip to content

Add translation rules for variadic libc calls#159

Open
lucic71 wants to merge 29 commits into
Cpp2Rust:masterfrom
lucic71:variadic-call
Open

Add translation rules for variadic libc calls#159
lucic71 wants to merge 29 commits into
Cpp2Rust:masterfrom
lucic71:variadic-call

Conversation

@lucic71
Copy link
Copy Markdown
Contributor

@lucic71 lucic71 commented May 27, 2026

Variadic rules are defined with the following syntax:

template <typename... Args>
int f1(int a0, unsigned long a1, Args... args) {
  return ioctl(a0, a1, args...);
}

and

unsafe extern "C" {
    fn f1(a0: i32, a1: u64, ...) -> i32;
}

For the C++ side, use a template argument pack. This makes it clear that the function call is variadic. For the Rust side, use a variadic function inside an extern block, that's the only place Rust allows variadic functions.

I added a new attribute in the IR, called is_extern. It's used by the new Mapper::IsLibcPassthrough. A libc passthrough is a rule that it's declared in Rust extern block. In the above example ioctl is defined as a passthrough for libc::ioctl. In the future, we can use this for non-variadic rules as well.

@lucic71 lucic71 marked this pull request as draft May 27, 2026 14:21
@lucic71 lucic71 force-pushed the variadic-call branch 2 times, most recently from 65c9c49 to 6e1a7cc Compare May 27, 2026 18:06
@lucic71 lucic71 marked this pull request as ready for review June 4, 2026 16:28
@lucic71
Copy link
Copy Markdown
Contributor Author

lucic71 commented Jun 4, 2026

@joaotgouveia please take a look at the changes in cpp2rust/cpp_rule_preprocessor.cpp

@lucic71
Copy link
Copy Markdown
Contributor Author

lucic71 commented Jun 4, 2026

@nunoplopes this is ready for review

@nunoplopes
Copy link
Copy Markdown
Contributor

Uhm, this seems like a hack that works for a few unsafe rules, but it's of no use for refcount. Doesn't feel like the solution we need.

@lucic71
Copy link
Copy Markdown
Contributor Author

lucic71 commented Jun 4, 2026

Uhm, this seems like a hack that works for a few unsafe rules, but it's of no use for refcount. Doesn't feel like the solution we need.

It works for all variadic unsafe rules. I designed this only with unsafe in mind. Probably for refcount we will need another solution.

Let me think if I can come up with something that would also work for refcount.

if (llvm::isa<clang::TemplateTypeParmDecl>(param)) {
if (param->isTemplateParameterPack()) {
out.emplace_back(
clang::TemplateArgument::CreatePackCopy(sema_->Context, {}));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this can be replaced by clang::TemplateArgument::getEmptyPack()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants