Add translation rules for variadic libc calls#159
Conversation
65c9c49 to
6e1a7cc
Compare
This allows writing
```cpp
template <typename... Args>
int f1(int a0, int a1, Args... args) {
return fcntl(a0, a1, args...);
}
```
Which becomes `f1: int fcntl(int, int, ...)`
In C++, builtin mul overflow is a variadic function: `bool (...)`. In C is an unprototyped function: `int ()`.
|
@joaotgouveia please take a look at the changes in cpp2rust/cpp_rule_preprocessor.cpp |
|
@nunoplopes this is ready for review |
|
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, {})); |
There was a problem hiding this comment.
I think that this can be replaced by clang::TemplateArgument::getEmptyPack()
For unsafe define the rule using a variadic argument syntax: unsafe extern "C" {
fn f21(a0: *mut i8, a1: usize, a2: *const i8, ...) -> i32;
}This means that the translation rule is a direct passthrough to the libc equivalent. For refcount use a fixed variadic agrument: fn f1(a0: i32, a1: u64, va: &[VaArg]) -> i32 {
panic!(
"ioctl is not supported in the refcount model (fd={}, request={}, varargs={})",
a0,
a1,
va.len()
)
}VaArg already is used for translating user-defined variadic functions. |
|
I didn't add proper translation rules for the safe equivalents because that requires more work. For the moment I added a panic implemnetation for each of them. I will add the proper translation later. |
Variadic rules are defined with the following syntax:
and
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 forlibc::ioctl. In the future, we can use this for non-variadic rules as well.