Skip to content

Commit 9d2ceaf

Browse files
authored
Translate variable template declarations (#389)
1 parent 29a8f8b commit 9d2ceaf

6 files changed

Lines changed: 47 additions & 2 deletions

File tree

‎cpp2rust/converter/converter.cpp‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,13 @@ bool Converter::VisitFunctionTemplateDecl(clang::FunctionTemplateDecl *decl) {
490490
return false;
491491
}
492492

493+
bool Converter::VisitVarTemplateDecl(clang::VarTemplateDecl *decl) {
494+
for (auto *var_decl : decl->specializations()) {
495+
VisitVarDecl(var_decl);
496+
}
497+
return false;
498+
}
499+
493500
void Converter::ConvertVaListVarDecl(clang::VarDecl *decl) {
494501
if (clang::isa<clang::ParmVarDecl>(decl)) {
495502
// va_list parameter (decayed to __va_list_tag *)

‎cpp2rust/converter/converter.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
9898
void EmitHoistedDecls(clang::CompoundStmt *body);
9999

100100
virtual bool VisitFunctionTemplateDecl(clang::FunctionTemplateDecl *decl);
101+
bool VisitVarTemplateDecl(clang::VarTemplateDecl *decl);
101102

102103
virtual bool VisitVarDecl(clang::VarDecl *decl);
103104
virtual bool LazyStaticInit() const { return true; }

‎cpp2rust/converter/converter_lib.cpp‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,10 @@ static std::string GetParamSignature(const clang::Decl *decl) {
583583

584584
static std::string GetLexicalSpecializationID(const clang::Decl *decl) {
585585
std::string id;
586+
if (const auto *var =
587+
clang::dyn_cast<clang::VarTemplateSpecializationDecl>(decl)) {
588+
id += clang::ASTNameGenerator(var->getASTContext()).getName(var);
589+
}
586590
if (const auto *spec =
587591
clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(
588592
decl->getLexicalDeclContext());

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ pub fn func_5(x1: f64, x2: i32, x3: f64) -> i32 {
4444
let x3: Value<f64> = Rc::new(RefCell::new(x3));
4545
return ((((*x1.borrow()) + ((*x2.borrow()) as f64)) + (*x3.borrow())) as i32);
4646
}
47+
thread_local!(
48+
pub static half_6: Value<i32> = Rc::new(RefCell::new((1 / 2)));
49+
);
50+
thread_local!(
51+
pub static half_7: Value<f64> = Rc::new(RefCell::new((1_f64 / 2_f64)));
52+
);
4753
pub fn main() {
4854
__cpp2rust_init_globals();
4955
std::process::exit(main_0());
@@ -59,6 +65,14 @@ fn main_0() -> i32 {
5965
+ (({ func_5(2.0E+0, (*x.borrow()), (*y.borrow()),) }) as f64))
6066
== 68_f64)
6167
);
68+
assert!((half_6.with(|rc| rc.borrow().clone()) == 0));
69+
assert!((half_7.with(|rc| rc.borrow().clone()) == 5.0E-1));
70+
(*half_6.with(Value::clone).borrow_mut()) = 7;
71+
assert!((half_6.with(|rc| rc.borrow().clone()) == 7));
72+
assert!((half_7.with(|rc| rc.borrow().clone()) == 5.0E-1));
6273
return 0;
6374
}
64-
pub fn __cpp2rust_init_globals() {}
75+
pub fn __cpp2rust_init_globals() {
76+
let _ = half_6.with(|_| ());
77+
let _ = half_7.with(|_| ());
78+
}

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ pub unsafe fn func_4(mut x1: i32, mut x2: i32, mut x3: i32) -> i32 {
2424
pub unsafe fn func_5(mut x1: f64, mut x2: i32, mut x3: f64) -> i32 {
2525
return ((((x1) + (x2 as f64)) + (x3)) as i32);
2626
}
27+
pub static mut half_6: std::cell::LazyCell<i32> =
28+
std::cell::LazyCell::new(|| unsafe { ((1) / (2)) });
29+
pub static mut half_7: std::cell::LazyCell<f64> =
30+
std::cell::LazyCell::new(|| unsafe { ((1_f64) / (2_f64)) });
2731
pub fn main() {
2832
unsafe {
2933
__cpp2rust_init_globals();
@@ -41,6 +45,14 @@ unsafe fn main_0() -> i32 {
4145
+ ((unsafe { func_5(2.0E+0, x, y,) }) as f64))
4246
== (68_f64))
4347
);
48+
assert!(((*std::cell::LazyCell::force_mut(&mut *&raw mut half_6)) == (0)));
49+
assert!(((*std::cell::LazyCell::force_mut(&mut *&raw mut half_7)) == (5.0E-1)));
50+
(*std::cell::LazyCell::force_mut(&mut *&raw mut half_6)) = 7;
51+
assert!(((*std::cell::LazyCell::force_mut(&mut *&raw mut half_6)) == (7)));
52+
assert!(((*std::cell::LazyCell::force_mut(&mut *&raw mut half_7)) == (5.0E-1)));
4453
return 0;
4554
}
46-
pub unsafe fn __cpp2rust_init_globals() {}
55+
pub unsafe fn __cpp2rust_init_globals() {
56+
std::cell::LazyCell::force(&*&raw const half_6);
57+
std::cell::LazyCell::force(&*&raw const half_7);
58+
}

‎tests/unit/templates.cpp‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,18 @@ template <typename T1, typename T2, typename T3> int func(T1 x1, T2 x2, T3 x3) {
88
return x1 + x2 + x3;
99
}
1010

11+
template <typename T> T half = T(1) / T(2);
12+
1113
int main() {
1214
int x = 10;
1315
double y = x;
1416
assert(foo(x) + foo(y) + *bar(&x, true) + *bar(&y, true) + func(1, 2, 3) +
1517
func(2.0, x, y) ==
1618
68);
19+
assert(half<int> == 0);
20+
assert(half<double> == 0.5);
21+
half<int> = 7;
22+
assert(half<int> == 7);
23+
assert(half<double> == 0.5);
1724
return 0;
1825
}

0 commit comments

Comments
 (0)