Skip to content

Commit 370bf3d

Browse files
authored
Translate SourceLocExpr (#468)
1 parent 819a4cf commit 370bf3d

7 files changed

Lines changed: 130 additions & 7 deletions

File tree

‎cpp2rust/converter/converter.cpp‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2406,6 +2406,37 @@ Converter::GetCodeUnitArrayLiteral(const clang::StringLiteral *expr) {
24062406
return out;
24072407
}
24082408

2409+
std::string Converter::GetSourceFileAsString(clang::QualType type) {
2410+
return std::format("concat!(file!(), \"\\0\").as_ptr() as {}",
2411+
ToString(type));
2412+
}
2413+
2414+
bool Converter::VisitSourceLocExpr(clang::SourceLocExpr *expr) {
2415+
switch (expr->getIdentKind()) {
2416+
case clang::SourceLocIdentKind::Line:
2417+
StrCat(std::format("line!() as {}", ToString(expr->getType())));
2418+
computed_expr_type_ = ComputedExprType::FreshValue;
2419+
return false;
2420+
case clang::SourceLocIdentKind::File:
2421+
StrCat(GetSourceFileAsString(expr->getType()));
2422+
computed_expr_type_ = ComputedExprType::FreshPointer;
2423+
return false;
2424+
case clang::SourceLocIdentKind::Function: {
2425+
auto value = expr->EvaluateInContext(ctx_, nullptr);
2426+
auto *str = clang::cast<clang::StringLiteral>(
2427+
value.getLValueBase().get<const clang::Expr *>());
2428+
Convert(clang::ImplicitCastExpr::Create(
2429+
ctx_, expr->getType(), clang::CK_ArrayToPointerDecay,
2430+
const_cast<clang::StringLiteral *>(str), nullptr, clang::VK_PRValue,
2431+
clang::FPOptionsOverride()));
2432+
return false;
2433+
}
2434+
default:
2435+
assert(0 && "unsupported SourceLocExpr");
2436+
return false;
2437+
}
2438+
}
2439+
24092440
bool Converter::VisitStringLiteral(clang::StringLiteral *expr) {
24102441
if (IsCodeUnitStringLiteral(expr)) {
24112442
StrCat(GetCodeUnitArrayLiteral(expr));

‎cpp2rust/converter/converter.h‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,10 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
382382
uint64_t pad_nulls = 0) const;
383383
virtual bool VisitStringLiteral(clang::StringLiteral *expr);
384384

385+
bool VisitSourceLocExpr(clang::SourceLocExpr *expr);
386+
387+
virtual std::string GetSourceFileAsString(clang::QualType type);
388+
385389
virtual bool VisitCXXBoolLiteralExpr(clang::CXXBoolLiteralExpr *expr);
386390

387391
bool VisitCXXNoexceptExpr(clang::CXXNoexceptExpr *expr);

‎cpp2rust/converter/models/converter_refcount.cpp‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1365,6 +1365,11 @@ bool ConverterRefCount::VisitCallExpr(clang::CallExpr *expr) {
13651365
return false;
13661366
}
13671367

1368+
std::string ConverterRefCount::GetSourceFileAsString(clang::QualType type) {
1369+
return std::format("Ptr::<{}>::from_string_literal(file!().as_bytes())",
1370+
ToStringBase(type->getPointeeType().getUnqualifiedType()));
1371+
}
1372+
13681373
bool ConverterRefCount::VisitStringLiteral(clang::StringLiteral *expr) {
13691374
if (IsCodeUnitStringLiteral(expr)) {
13701375
auto arr = GetCodeUnitArrayLiteral(expr);

‎cpp2rust/converter/models/converter_refcount.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ class ConverterRefCount final : public Converter {
137137

138138
bool VisitStringLiteral(clang::StringLiteral *expr) override;
139139

140+
std::string GetSourceFileAsString(clang::QualType type) override;
141+
140142
bool VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) override;
141143

142144
bool VisitFunctionPointerCast(clang::ExplicitCastExpr *expr);

‎tests/unit/macros.cpp‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,26 @@
1+
#include <assert.h>
12
#include <stdio.h>
3+
#include <string.h>
4+
5+
const char *base_name(const char *path) {
6+
const char *slash = strrchr(path, '/');
7+
return slash ? slash + 1 : path;
8+
}
29

310
void log(const char *file, int line, const char *func) {
411
printf("%s %d %s\n", file, line, func);
512
}
613

14+
int line() { return __builtin_LINE(); }
15+
16+
const char *function() { return __builtin_FUNCTION(); }
17+
718
int main() {
819
printf("%s %d %s\n", __FILE__, __LINE__, __FUNCTION__);
920
log(__FILE__, __LINE__, __FUNCTION__);
21+
assert(__builtin_LINE() > 0);
22+
assert(base_name(__builtin_FILE())[0] != '\0');
23+
assert(line() > 0);
24+
printf("%s\n", function());
1025
return 0;
1126
}

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

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,41 @@ use std::io::prelude::*;
66
use std::io::{Read, Seek, Write};
77
use std::os::fd::AsFd;
88
use std::rc::{Rc, Weak};
9-
pub fn log_0(mut file: Ptr<i8>, mut line: i32, mut func: Ptr<i8>) {
9+
pub fn base_name_0(mut path: Ptr<i8>) -> Ptr<i8> {
10+
let mut slash: Ptr<i8> = {
11+
let __s = (path).clone();
12+
let __t = (('/' as i8) as i32) as i8;
13+
match __s
14+
.to_c_string_iterator()
15+
.enumerate()
16+
.filter(|__e| __e.1 == __t)
17+
.last()
18+
{
19+
Some((__i, _)) => __s.offset(__i),
20+
None => {
21+
if __t == 0 {
22+
__s.offset(__s.to_c_string_iterator().count())
23+
} else {
24+
Ptr::null()
25+
}
26+
}
27+
}
28+
};
29+
return if !(slash).is_null() {
30+
slash.offset((1) as isize)
31+
} else {
32+
path
33+
};
34+
}
35+
pub fn log_1(mut file: Ptr<i8>, mut line: i32, mut func: Ptr<i8>) {
1036
println!("{} {} {}", file, line, func);
1137
}
38+
pub fn line_2() -> i32 {
39+
return (line!() as u32 as i32);
40+
}
41+
pub fn function_3() -> Ptr<i8> {
42+
return Ptr::<i8>::from_string_literal(b"function");
43+
}
1244
pub fn main() {
1345
__cpp2rust_init_globals();
1446
std::process::exit(main_0());
@@ -17,16 +49,27 @@ fn main_0() -> i32 {
1749
println!(
1850
"{} {} {}",
1951
Ptr::<i8>::from_string_literal(b"macros.cpp"),
20-
8,
52+
19,
2153
Ptr::<i8>::from_string_literal(b"main")
2254
);
2355
({
24-
log_0(
56+
log_1(
2557
Ptr::<i8>::from_string_literal(b"macros.cpp"),
26-
9,
58+
20,
2759
Ptr::<i8>::from_string_literal(b"main"),
2860
)
2961
});
62+
assert!((line!() as u32 > 0_u32));
63+
assert!(
64+
(((elem!(
65+
({ base_name_0(Ptr::<i8>::from_string_literal(file!().as_bytes()),) }),
66+
0
67+
)
68+
.read()) as i32)
69+
!= (('\0' as i8) as i32))
70+
);
71+
assert!((({ line_2() }) > 0));
72+
println!("{}", ({ function_3() }));
3073
return 0;
3174
}
3275
pub fn __cpp2rust_init_globals() {}

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

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,24 @@ use std::collections::BTreeMap;
66
use std::io::{Read, Seek, Write};
77
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
88
use std::rc::Rc;
9-
pub unsafe fn log_0(mut file: *const libc::c_char, mut line: i32, mut func: *const libc::c_char) {
9+
pub unsafe fn base_name_0(mut path: *const libc::c_char) -> *const libc::c_char {
10+
let mut slash: *const libc::c_char =
11+
(libc::strrchr(path, (('/' as libc::c_char) as i32)) as *const libc::c_char);
12+
return if !(slash).is_null() {
13+
slash.offset((1) as isize)
14+
} else {
15+
path
16+
};
17+
}
18+
pub unsafe fn log_1(mut file: *const libc::c_char, mut line: i32, mut func: *const libc::c_char) {
1019
printf(c"%s %d %s\n".as_ptr() as *const i8, file, line, func);
1120
}
21+
pub unsafe fn line_2() -> i32 {
22+
return (line!() as u32 as i32);
23+
}
24+
pub unsafe fn function_3() -> *const libc::c_char {
25+
return c"function".as_ptr();
26+
}
1227
pub fn main() {
1328
unsafe {
1429
__cpp2rust_init_globals();
@@ -19,10 +34,18 @@ unsafe fn main_0() -> i32 {
1934
printf(
2035
c"%s %d %s\n".as_ptr() as *const i8,
2136
c"macros.cpp".as_ptr(),
22-
8,
37+
19,
2338
c"main".as_ptr(),
2439
);
25-
(unsafe { log_0(c"macros.cpp".as_ptr(), 9, c"main".as_ptr()) });
40+
(unsafe { log_1(c"macros.cpp".as_ptr(), 20, c"main".as_ptr()) });
41+
assert!(((line!() as u32) > (0_u32)));
42+
assert!(
43+
(((*(unsafe { base_name_0(concat!(file!(), "\0").as_ptr() as *const libc::c_char,) })
44+
.offset((0) as isize)) as i32)
45+
!= (('\0' as libc::c_char) as i32))
46+
);
47+
assert!(((unsafe { line_2() }) > (0)));
48+
printf(c"%s\n".as_ptr() as *const i8, (unsafe { function_3() }));
2649
return 0;
2750
}
2851
pub unsafe fn __cpp2rust_init_globals() {}

0 commit comments

Comments
 (0)