Skip to content

Commit 226c3de

Browse files
committed
Fix operator name collisions
1 parent ed3c7bf commit 226c3de

7 files changed

Lines changed: 170 additions & 2 deletions

File tree

‎cpp2rust/converter/mapper.cpp‎

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "converter/mapper.h"
55

66
#include <clang/AST/ExprCXX.h>
7+
#include <clang/Basic/OperatorKinds.h>
78
#include <clang/Basic/SourceManager.h>
89
#include <clang/Lex/Lexer.h>
910
#include <llvm/Support/ThreadPool.h>
@@ -922,8 +923,30 @@ std::string ToString(const clang::NamedDecl *decl) {
922923
}
923924

924925
os << ToString(func_decl->getReturnType()) << ' ';
925-
if (const auto *method_decl =
926-
llvm::dyn_cast<clang::CXXMethodDecl>(func_decl)) {
926+
if (const auto op = func_decl->getOverloadedOperator();
927+
op >= clang::OverloadedOperatorKind::OO_LessLess &&
928+
op <= clang::OverloadedOperatorKind::OO_GreaterGreaterEqual) {
929+
// ensure matchTemplate does not consider these operator names when matching
930+
func_decl->getQualifier().print(os, getPrintPolicy());
931+
os << "operator ";
932+
switch (op) {
933+
case clang::OverloadedOperatorKind::OO_LessLess:
934+
os << "shl";
935+
break;
936+
case clang::OverloadedOperatorKind::OO_GreaterGreater:
937+
os << "shr";
938+
break;
939+
case clang::OverloadedOperatorKind::OO_LessLessEqual:
940+
os << "shleq";
941+
break;
942+
case clang::OverloadedOperatorKind::OO_GreaterGreaterEqual:
943+
os << "shreq";
944+
break;
945+
default:
946+
std::unreachable();
947+
}
948+
} else if (const auto *method_decl =
949+
llvm::dyn_cast<clang::CXXMethodDecl>(func_decl)) {
927950
if (method_decl->getParent()->isLambda() &&
928951
method_decl->getOverloadedOperator() == clang::OO_Call) {
929952
func_decl->printName(os, getPrintPolicy());

‎rules/bitset/src.cpp‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright (c) 2022-present INESC-ID.
2+
// Distributed under the MIT license that can be found in the LICENSE file.
3+
4+
#include <bitset>
5+
6+
template <std::size_t T1> using t1 = std::bitset<T1>;
7+
8+
template <std::size_t T1> std::bitset<T1> f1() { return std::bitset<T1>(); }
9+
10+
template <std::size_t T1> std::bitset<T1> f2(unsigned long long a0) {
11+
return std::bitset<T1>(a0);
12+
}
13+
14+
template <std::size_t T1>
15+
std::bitset<T1> f3(const std::bitset<T1> &a0, std::size_t a1) {
16+
return a0.operator<<(a1);
17+
}
18+
19+
template <std::size_t T1>
20+
std::bitset<T1> f4(const std::bitset<T1> &a0, std::size_t a1) {
21+
return a0.operator>>(a1);
22+
}
23+
24+
template <std::size_t T1> unsigned long f5(const std::bitset<T1> &a0) {
25+
return a0.to_ulong();
26+
}

‎rules/bitset/tgt_unsafe.rs‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright (c) 2022-present INESC-ID.
2+
// Distributed under the MIT license that can be found in the LICENSE file.
3+
4+
fn t1() -> Vec<bool> {
5+
Vec::new()
6+
}
7+
8+
fn f1() -> Vec<bool> {
9+
Vec::new()
10+
}
11+
12+
fn f2(a0: u64) -> Vec<bool> {
13+
(0..u64::BITS).map(|i| (a0 >> i) & 1 == 1).collect()
14+
}
15+
16+
fn f3(a0: Vec<bool>, a1: usize) -> Vec<bool> {
17+
let mut bits = vec![false; a1];
18+
bits.extend(a0.iter());
19+
bits
20+
}
21+
22+
fn f4(a0: Vec<bool>, a1: usize) -> Vec<bool> {
23+
a0.iter().skip(a1).copied().collect()
24+
}
25+
26+
fn f5(a0: Vec<bool>) -> u64 {
27+
a0.iter().rev().fold(0u64, |acc, &b| (acc << 1) | b as u64)
28+
}

‎rules/src/modules.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ pub mod array_tgt_unsafe;
1414
pub mod assert_tgt_refcount;
1515
#[path = r#"../assert/tgt_unsafe.rs"#]
1616
pub mod assert_tgt_unsafe;
17+
#[path = r#"../bitset/tgt_unsafe.rs"#]
18+
pub mod bitset_tgt_unsafe;
1719
#[path = r#"../brotli/tgt_refcount.rs"#]
1820
pub mod brotli_tgt_refcount;
1921
#[path = r#"../brotli/tgt_unsafe.rs"#]

‎tests/unit/bitset.cpp‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright (c) 2022-present INESC-ID.
2+
// Distributed under the MIT license that can be found in the LICENSE file.
3+
4+
#include <bitset>
5+
#include <cassert>
6+
7+
int main() {
8+
std::bitset<16> b1(5);
9+
std::bitset<16> b2 = b1 << 2;
10+
std::bitset<16> b3 = b2 >> 1;
11+
12+
assert(b1.to_ulong() == 5);
13+
assert(b2.to_ulong() == 20);
14+
assert(b3.to_ulong() == 10);
15+
16+
return 0;
17+
}

‎tests/unit/out/refcount/bitset.rs‎

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
extern crate libcc2rs;
2+
use libcc2rs::*;
3+
use std::cell::RefCell;
4+
use std::collections::BTreeMap;
5+
use std::io::prelude::*;
6+
use std::io::{Read, Seek, Write};
7+
use std::os::fd::AsFd;
8+
use std::rc::{Rc, Weak};
9+
pub fn main() {
10+
std::process::exit(main_0());
11+
}
12+
fn main_0() -> i32 {
13+
let b1: Value<Vec<bool>> = Rc::new(RefCell::new(
14+
(0..u64::BITS).map(|i| (5_u64 >> i) & 1 == 1).collect(),
15+
));
16+
let b2: Value<Vec<bool>> = Rc::new(RefCell::new({
17+
let mut bits = vec![false; 2_usize];
18+
bits.extend((*b1.borrow()).iter());
19+
bits
20+
}));
21+
let b3: Value<Vec<bool>> = Rc::new(RefCell::new(
22+
(*b2.borrow()).iter().skip(1_usize).copied().collect(),
23+
));
24+
assert!(
25+
((*b1.borrow())
26+
.iter()
27+
.rev()
28+
.fold(0u64, |acc, &b| (acc << 1) | b as u64)
29+
== 5_u64)
30+
);
31+
assert!(
32+
((*b2.borrow())
33+
.iter()
34+
.rev()
35+
.fold(0u64, |acc, &b| (acc << 1) | b as u64)
36+
== 20_u64)
37+
);
38+
assert!(
39+
((*b3.borrow())
40+
.iter()
41+
.rev()
42+
.fold(0u64, |acc, &b| (acc << 1) | b as u64)
43+
== 10_u64)
44+
);
45+
return 0;
46+
}

‎tests/unit/out/unsafe/bitset.rs‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
extern crate libc;
2+
use libc::*;
3+
extern crate libcc2rs;
4+
use libcc2rs::*;
5+
use std::collections::BTreeMap;
6+
use std::io::{Read, Seek, Write};
7+
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
8+
use std::rc::Rc;
9+
pub fn main() {
10+
unsafe {
11+
std::process::exit(main_0() as i32);
12+
}
13+
}
14+
unsafe fn main_0() -> i32 {
15+
let mut b1: Vec<bool> = (0..u64::BITS).map(|i| (5_u64 >> i) & 1 == 1).collect();
16+
let mut b2: Vec<bool> = {
17+
let mut bits = vec![false; 2_usize];
18+
bits.extend(b1.iter());
19+
bits
20+
};
21+
let mut b3: Vec<bool> = b2.iter().skip(1_usize).copied().collect();
22+
assert!(((b1.iter().rev().fold(0u64, |acc, &b| (acc << 1) | b as u64)) == (5_u64)));
23+
assert!(((b2.iter().rev().fold(0u64, |acc, &b| (acc << 1) | b as u64)) == (20_u64)));
24+
assert!(((b3.iter().rev().fold(0u64, |acc, &b| (acc << 1) | b as u64)) == (10_u64)));
25+
return 0;
26+
}

0 commit comments

Comments
 (0)