Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions cpp2rust/converter/converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1172,6 +1172,12 @@ bool Converter::VisitTypedefDecl([[maybe_unused]] clang::TypedefDecl *decl) {
return false;
}

bool Converter::VisitStaticAssertDecl(clang::StaticAssertDecl *) {
return false;
}

bool Converter::VisitConceptDecl(clang::ConceptDecl *) { return false; }

static bool IsaSemiColonStmt(const clang::Stmt *stmt) {
switch (stmt->getStmtClass()) {
case clang::Stmt::IfStmtClass:
Expand Down Expand Up @@ -3407,6 +3413,21 @@ bool Converter::VisitUnaryExprOrTypeTraitExpr(
return false;
}

bool Converter::VisitConceptSpecializationExpr(
clang::ConceptSpecializationExpr *expr) {
assert(!expr->isValueDependent());
StrCat(expr->isSatisfied() ? keyword::kTrue : keyword::kFalse);
computed_expr_type_ = ComputedExprType::FreshValue;
return false;
}

bool Converter::VisitRequiresExpr(clang::RequiresExpr *expr) {
assert(!expr->isValueDependent());
StrCat(expr->isSatisfied() ? keyword::kTrue : keyword::kFalse);
computed_expr_type_ = ComputedExprType::FreshValue;
return false;
}

bool Converter::VisitTypeTraitExpr(clang::TypeTraitExpr *expr) {
clang::Expr::EvalResult result;
ENSURE(expr->EvaluateAsInt(result, ctx_));
Expand Down
8 changes: 8 additions & 0 deletions cpp2rust/converter/converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {

virtual bool VisitTypedefDecl(clang::TypedefDecl *decl);

bool VisitStaticAssertDecl(clang::StaticAssertDecl *decl);
bool VisitConceptDecl(clang::ConceptDecl *decl);

virtual bool VisitCompoundStmt(clang::CompoundStmt *stmt);

virtual bool VisitDeclStmt(clang::DeclStmt *stmt);
Expand Down Expand Up @@ -405,8 +408,13 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
VisitUnaryExprOrTypeTraitExpr(clang::UnaryExprOrTypeTraitExpr *expr);

virtual bool VisitTypeTraitExpr(clang::TypeTraitExpr *expr);

virtual bool VisitSizeOfPackExpr(clang::SizeOfPackExpr *expr);

virtual bool
VisitConceptSpecializationExpr(clang::ConceptSpecializationExpr *expr);
virtual bool VisitRequiresExpr(clang::RequiresExpr *expr);

virtual bool VisitOffsetOfExpr(clang::OffsetOfExpr *expr);

virtual bool VisitEnumDecl(clang::EnumDecl *decl);
Expand Down
44 changes: 44 additions & 0 deletions tests/unit/concepts.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// ADDITIONAL_COMPILE_FLAGS: -std=c++20
#include <cassert>
#include <concepts>

template <typename T>
concept Small = sizeof(T) <= 4;

static_assert(Small<int>);

template <typename T>
concept HasSize = requires(T t) {
{ t.size() } -> std::same_as<int>;
};

struct Sized {
int size() { return 4; }
};

template <typename T> bool is_small() { return Small<T>; }

template <typename T> bool has_size() {
return requires(T t) { t.size(); };
}

template <typename T> int pick(T x) {
if (std::integral<T> && Small<T>) {
return 1;
}
return 2;
}

int main() {
static_assert(!Small<long>);
assert(is_small<char>());
assert(!is_small<double>());
assert(HasSize<Sized>);
assert(!HasSize<int>);
assert(has_size<Sized>());
assert(!has_size<int>());
assert(pick(1) == 1);
assert(pick(1L) == 2);
assert(pick(1.0f) == 2);
return 0;
}
82 changes: 82 additions & 0 deletions tests/unit/out/refcount/concepts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
extern crate libcc2rs;
use libcc2rs::*;
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::io::prelude::*;
use std::io::{Read, Seek, Write};
use std::os::fd::AsFd;
use std::rc::{Rc, Weak};
#[derive(Default)]
pub struct Sized {}
impl Clone for Sized {
fn clone(&self) -> Self {
let __this: Value<Sized> = Rc::new(RefCell::new(Self {}));
let this: Ptr<Sized> = __this.as_pointer();
Rc::try_unwrap(__this).ok().unwrap().into_inner()
}
}
impl ByteRepr for Sized {
fn byte_size() -> usize {
1
}
fn to_bytes(&self, buf: &mut [u8]) {}
fn from_bytes(buf: &[u8]) -> Self {
Self {}
}
}
pub fn is_small_0() -> bool {
return true;
}
pub fn is_small_1() -> bool {
return false;
}
pub fn has_size_2() -> bool {
return true;
}
pub fn has_size_3() -> bool {
return false;
}
pub fn pick_4(x: i32) -> i32 {
let x: Value<i32> = Rc::new(RefCell::new(x));
if (true) && (true) {
return 1;
}
return 2;
}
pub fn pick_5(x: i64) -> i32 {
let x: Value<i64> = Rc::new(RefCell::new(x));
if (true) && (false) {
return 1;
}
return 2;
}
pub fn pick_6(x: f32) -> i32 {
let x: Value<f32> = Rc::new(RefCell::new(x));
if (false) && (true) {
return 1;
}
return 2;
}
pub fn main() {
std::process::exit(main_0());
}
fn main_0() -> i32 {
assert!(({ is_small_0() }));
assert!(!({ is_small_1() }));
assert!(true);
assert!(!false);
assert!(({ has_size_2() }));
assert!(!({ has_size_3() }));
assert!((({ pick_4(1,) }) == 1));
assert!((({ pick_5(1_i64,) }) == 2));
assert!((({ pick_6(1.0E+0,) }) == 2));
return 0;
}
pub trait SizedImpl {
fn size(&self) -> i32;
}
impl SizedImpl for Ptr<Sized> {
fn size(&self) -> i32 {
return 4;
}
}
63 changes: 63 additions & 0 deletions tests/unit/out/unsafe/concepts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
extern crate libc;
use libc::*;
extern crate libcc2rs;
use libcc2rs::*;
use std::collections::BTreeMap;
use std::io::{Read, Seek, Write};
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
use std::rc::Rc;
#[repr(C)]
#[derive(Copy, Clone, Default)]
pub struct Sized {}
impl Sized {
pub unsafe fn size(&mut self) -> i32 {
return 4;
}
}
pub unsafe fn is_small_0() -> bool {
return true;
}
pub unsafe fn is_small_1() -> bool {
return false;
}
pub unsafe fn has_size_2() -> bool {
return true;
}
pub unsafe fn has_size_3() -> bool {
return false;
}
pub unsafe fn pick_4(mut x: i32) -> i32 {
if (true) && (true) {
return 1;
}
return 2;
}
pub unsafe fn pick_5(mut x: i64) -> i32 {
if (true) && (false) {
return 1;
}
return 2;
}
pub unsafe fn pick_6(mut x: f32) -> i32 {
if (false) && (true) {
return 1;
}
return 2;
}
pub fn main() {
unsafe {
std::process::exit(main_0() as i32);
}
}
unsafe fn main_0() -> i32 {
assert!((unsafe { is_small_0() }));
assert!(!(unsafe { is_small_1() }));
assert!(true);
assert!(!false);
assert!((unsafe { has_size_2() }));
assert!(!(unsafe { has_size_3() }));
assert!(((unsafe { pick_4(1,) }) == (1)));
assert!(((unsafe { pick_5(1_i64,) }) == (2)));
assert!(((unsafe { pick_6(1.0E+0,) }) == (2)));
return 0;
}
Loading