Skip to content
Merged
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
8 changes: 6 additions & 2 deletions cpp2rust/converter/converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ Converter::GetTemplateArgumentAsString(const clang::TemplateArgument &arg) {
case clang::TemplateArgument::Type:
return GetUnboxedTypeAsString(arg.getAsType());
case clang::TemplateArgument::Integral:
if (!arg.getIntegralType()->isBooleanType()) {
llvm::SmallString<16> value;
arg.getAsIntegral().toString(value);
return std::string(value);
}
[[fallthrough]];
case clang::TemplateArgument::NullPtr:
case clang::TemplateArgument::Declaration:
case clang::TemplateArgument::StructuralValue: {
Expand Down Expand Up @@ -5114,8 +5120,6 @@ std::string Converter::GetMappedAsString(clang::Expr *expr, clang::Expr **args,
if (!tgt_ir)
return {};

CheckRuleReturnType(expr);

auto saved_borrows = std::exchange(mut_borrows_, {});
auto *operand = tgt_ir->refExprOperand();
bool lvalue = operand && !isAddrOf();
Expand Down
3 changes: 0 additions & 3 deletions cpp2rust/converter/converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -916,9 +916,6 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
return false;
}

// Checks that the rule of expr returns the type that expr returns in C++.
virtual void CheckRuleReturnType(clang::Expr * /*expr*/) {}

bool RecordHasCopyableFields(const clang::RecordDecl *decl);

bool ShouldReplaceWithMappedBody(const clang::ValueDecl *decl) const;
Expand Down
5 changes: 0 additions & 5 deletions cpp2rust/converter/mapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,4 @@ std::string GetParamType(Converter &converter, const clang::Expr *expr,
return Matcher::InstantiateTgt(converter, subs, rule->params.at(index).type);
}

std::string GetReturnType(Converter &converter, const clang::Expr *expr) {
auto [rule, subs] = RuleRegistry::Search(converter.GetASTContext(), expr);
return Matcher::InstantiateTgt(converter, subs, rule->return_type.type);
}

} // namespace cpp2rust::Mapper
1 change: 0 additions & 1 deletion cpp2rust/converter/mapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,4 @@ std::string MapFunctionName(clang::ASTContext &ctx,
const clang::FunctionDecl *decl);
std::string GetParamType(Converter &converter, const clang::Expr *expr,
unsigned index);
std::string GetReturnType(Converter &converter, const clang::Expr *expr);
} // namespace cpp2rust::Mapper
23 changes: 0 additions & 23 deletions cpp2rust/converter/models/converter_refcount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -438,29 +438,6 @@ std::string ConverterRefCount::ConvertElementPtr(clang::Expr *arg) {
return ConvertObject(arg, ObjectShape::Element);
}

void ConverterRefCount::CheckRuleReturnType(clang::Expr *expr) {
auto *call = clang::dyn_cast<clang::CallExpr>(expr);
if (!call ||
!RuleRegistry::GetExprRule(ctx_, expr)->return_type.is_refcount_pointer) {
return;
}
auto type = RuleRegistry::GetDeclaredReturnType(expr);
if (auto ref = type->getAs<clang::ReferenceType>()) {
auto pointee = ref->getPointeeType();
type = pointee->isRecordType() &&
RuleRegistry::MapsToRefcountPointer(ctx_, pointee)
? pointee
: ctx_.getPointerType(pointee);
}
auto ret = NormalizeType(Mapper::GetReturnType(*this, expr));
auto expected = NormalizeType(ToString(type));
if (ret != expected) {
llvm::errs() << "rule return type " << ret << " is not " << expected
<< '\n';
llvm::report_fatal_error("rule return type does not match the C++ one");
}
}

std::string ConverterRefCount::ConvertFreshObject(clang::Expr *expr) {
return MakeFresh(ConvertObject(expr));
}
Expand Down
1 change: 0 additions & 1 deletion cpp2rust/converter/models/converter_refcount.h
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,6 @@ class ConverterRefCount final : public Converter {
// The method that makes a pointer to an object of the given type, which is
// one to its elements if they are what ConvertObject wants.
std::string AsPointerMethod(clang::QualType type);
void CheckRuleReturnType(clang::Expr *expr) override;

std::string ConvertTemporaryPointer(
clang::Expr *expr,
Expand Down
30 changes: 30 additions & 0 deletions cpp2rust/converter/rules/expr_matcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,32 @@ getExplicitTemplateArgs(const clang::Expr *expr) {
return {};
}

void deduceNonTypeFromExplicitArg(
clang::ASTContext &ctx, const clang::TemplateArgument &rule_arg,
const clang::Expr *use, unsigned i,
std::vector<clang::TemplateArgument> &deduced) {
auto ref = llvm::dyn_cast<clang::DeclRefExpr>(
rule_arg.getAsExpr()->IgnoreParenImpCasts());
auto nttp =
ref ? llvm::dyn_cast<clang::NonTypeTemplateParmDecl>(ref->getDecl())
: nullptr;
if (!nttp) {
return;
}
auto call = llvm::cast<clang::CallExpr>(RuleDecls::SkipImplicit(use));
auto callee = call->getDirectCallee();
auto spec = callee ? callee->getTemplateSpecializationArgs() : nullptr;
assert(spec && i < spec->size() &&
"explicit template argument of a non-specialized callee");
const auto &value = spec->get(i);
assert(value.getKind() == clang::TemplateArgument::Integral &&
"non-type template argument is not an integral");
auto &slot = deduced[nttp->getIndex()];
if (slot.isNull()) {
slot = clang::TemplateArgument(ctx, value.getAsIntegral(), nttp->getType());
}
}

void deduceFromExplicitArgs(clang::Sema &sema,
clang::FunctionTemplateDecl *rule,
const clang::Expr *use,
Expand All @@ -308,6 +334,10 @@ void deduceFromExplicitArgs(clang::Sema &sema,
for (unsigned i = 0; i < rule_args.size() && i < use_args.size(); ++i) {
const auto &rule_arg = rule_args[i].getArgument();
const auto &use_arg = use_args[i].getArgument();
if (rule_arg.getKind() == clang::TemplateArgument::Expression) {
deduceNonTypeFromExplicitArg(sema.Context, rule_arg, use, i, deduced);
continue;
}
if (rule_arg.getKind() != clang::TemplateArgument::Type ||
use_arg.getKind() != clang::TemplateArgument::Type) {
continue;
Expand Down
17 changes: 0 additions & 17 deletions cpp2rust/converter/rules/registry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -496,23 +496,6 @@ std::string InitAliasName(Model model, const std::string &name) {
model == Model::kRefCount ? "refcount" : "unsafe", name);
}

clang::QualType GetDeclaredReturnType(const clang::Expr *expr) {
auto match = findExpr(expr);
assert(match.rule_decl && "expression must have a translation rule");
auto function = match.rule_decl->decl->getAsFunction();
assert(function && "rule is not a function");
auto tmpl = function->getDescribedFunctionTemplate();
if (!tmpl) {
return function->getReturnType();
}
clang::MultiLevelTemplateArgumentList args(tmpl, match.args,
/*Final=*/false);
clang::Sema::InstantiatingTemplate inst(
*sema_, expr->getBeginLoc(), const_cast<clang::FunctionDecl *>(function));
return sema_->SubstType(function->getReturnType(), args, expr->getBeginLoc(),
clang::DeclarationName());
}

bool HasExprRule(const clang::FunctionDecl *decl) {
auto key = RuleKeys::GetDeclKey(decl);
if (!key) {
Expand Down
2 changes: 0 additions & 2 deletions cpp2rust/converter/rules/registry.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@ clang::QualType GetGenericType(clang::ASTContext &ctx, const clang::Expr *expr,
clang::QualType GetConversionSourceType(clang::ASTContext &ctx,
const clang::Expr *expr, unsigned to);

clang::QualType GetDeclaredReturnType(const clang::Expr *expr);

bool HasExprRule(const clang::FunctionDecl *decl);
bool IsLibcPassthrough(clang::ASTContext &ctx, const clang::Expr *expr);
bool ReturnsPointer(clang::ASTContext &ctx, const clang::Expr *expr);
Expand Down
13 changes: 10 additions & 3 deletions rule-preprocessor/src/syntactic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,9 +481,16 @@ impl<'a> FnIrBuilder<'a> {

if let Some(gpl) = self.fn_item.generic_param_list() {
for param in gpl.generic_params() {
if let ast::GenericParam::TypeParam(tp) = param {
let name = tp.name().map(|n| n.text().to_string()).unwrap_or_default();
generics.insert(name, extract_bounds(tp.type_bound_list()));
match param {
ast::GenericParam::TypeParam(tp) => {
let name = tp.name().map(|n| n.text().to_string()).unwrap_or_default();
generics.insert(name, extract_bounds(tp.type_bound_list()));
}
ast::GenericParam::ConstParam(cp) => {
let name = cp.name().map(|n| n.text().to_string()).unwrap_or_default();
generics.insert(name, Vec::new());
}
_ => {}
}
}
}
Expand Down
23 changes: 23 additions & 0 deletions rules/array/src.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ using t4 = typename std::array<T1, T2>::pointer;
template <typename T1, std::size_t T2>
using t5 = typename std::array<T1, T2>::const_pointer;

template <std::size_t T1, typename T2, std::size_t T3>
using t6 = typename std::tuple_element<T1, std::array<T2, T3>>::type;

template <typename T1, std::size_t T2>
const T1 *f1(const std::array<T1, T2> &o) {
return o.data();
Expand Down Expand Up @@ -54,3 +57,23 @@ std::array<T1, T2> &f7(std::array<T1, T2> &dst, const std::array<T1, T2> &src) {
template <typename T1, std::size_t T2> std::array<T1, T2> f8(T1 (&&a0)[T2]) {
return std::array<T1, T2>{a0};
}

template <std::size_t T1, typename T2, std::size_t T3>
T2 &f9(std::array<T2, T3> &a0) {
return std::get<T1>(a0);
}

template <std::size_t T1, typename T2, std::size_t T3>
const T2 &f10(const std::array<T2, T3> &a0) {
return std::get<T1>(a0);
}

template <std::size_t T1, typename T2, std::size_t T3>
T2 &&f11(std::array<T2, T3> &&a0) {
return std::get<T1>(std::move(a0));
}

template <std::size_t T1, typename T2, std::size_t T3>
const T2 &&f12(const std::array<T2, T3> &&a0) {
return std::get<T1>(std::move(a0));
}
16 changes: 16 additions & 0 deletions rules/array/tgt_refcount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,19 @@ fn f5<T1: ByteRepr + Clone>(a0: Ptr<Vec<T1>>, a1: &mut Vec<T1>) {
fn f7<T1: Clone + ByteRepr>(a0: Ptr<Vec<T1>>, a1: Vec<T1>) {
a0.write(a1)
}

fn f9<const T1: usize, T2>(a0: Ptr<T2>) -> Ptr<T2> {
a0.offset(T1 as isize)
}

fn f10<const T1: usize, T2>(a0: Ptr<T2>) -> Ptr<T2> {
a0.offset(T1 as isize)
}

fn f11<const T1: usize, T2>(a0: Ptr<T2>) -> Ptr<T2> {
a0.offset(T1 as isize)
}

fn f12<const T1: usize, T2>(a0: Ptr<T2>) -> Ptr<T2> {
a0.offset(T1 as isize)
}
20 changes: 20 additions & 0 deletions rules/array/tgt_unsafe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ fn t5<T1>() -> *const T1 {
::std::ptr::null()
}

fn t6<T2>() -> T2 {
unimplemented!()
}

unsafe fn f1<T1>(a0: Vec<T1>) -> *const T1 {
a0.as_ptr()
}
Expand Down Expand Up @@ -54,3 +58,19 @@ unsafe fn f7<T1: Clone>(a0: &mut Vec<T1>, a1: Vec<T1>) {
unsafe fn f8<T1, const T2: usize>(a0: [T1; T2]) -> Vec<T1> {
Vec::from(a0)
}

unsafe fn f9<const T1: usize, T2>(a0: &mut Vec<T2>) -> *mut T2 {
a0.as_mut_ptr().offset(T1 as isize)
}

unsafe fn f10<const T1: usize, T2>(a0: &Vec<T2>) -> *const T2 {
a0.as_ptr().offset(T1 as isize)
}

unsafe fn f11<const T1: usize, T2>(a0: &mut Vec<T2>) -> *mut T2 {
a0.as_mut_ptr().offset(T1 as isize)
}

unsafe fn f12<const T1: usize, T2>(a0: &Vec<T2>) -> *const T2 {
a0.as_ptr().offset(T1 as isize)
}
78 changes: 78 additions & 0 deletions rules/pair/shim.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright (c) 2022-present INESC-ID.
// Distributed under the MIT license that can be found in the LICENSE file.

use crate::Value;

pub trait TupleElement<const N: usize> {
type Type;

fn element(&self) -> &Self::Type;

fn element_mut(&mut self) -> &mut Self::Type;
}

pub trait TupleGet {
fn get<const N: usize>(&self) -> &<Self as TupleElement<N>>::Type
where
Self: TupleElement<N>,
{
TupleElement::<N>::element(self)
}

fn get_mut<const N: usize>(&mut self) -> &mut <Self as TupleElement<N>>::Type
where
Self: TupleElement<N>,
{
TupleElement::<N>::element_mut(self)
}
}

pub trait TupleElementValue<const N: usize>: TupleElement<N> {
type Values;

fn value(values: &Self::Values) -> &Value<Self::Type>;
}

pub trait ValueTupleGet {
type Plain;

fn get_value<const N: usize>(&self) -> &Value<<Self::Plain as TupleElement<N>>::Type>
where
Self::Plain: TupleElementValue<N, Values = Self>,
{
<Self::Plain as TupleElementValue<N>>::value(self)
}
}

macro_rules! impl_tuple_get {
(@element ($($t:ident),+) $n:tt $element:ident) => {
impl<$($t),+> TupleElement<$n> for ($($t,)+) {
type Type = $element;

fn element(&self) -> &$element {
&self.$n
}

fn element_mut(&mut self) -> &mut $element {
&mut self.$n
}
}

impl<$($t),+> TupleElementValue<$n> for ($($t,)+) {
type Values = ($(Value<$t>,)+);

fn value(values: &Self::Values) -> &Value<$element> {
&values.$n
}
}
};
($tuple:tt; $($n:tt $element:ident),+) => {
impl<$($element),+> TupleGet for ($($element,)+) {}
impl<$($element),+> ValueTupleGet for ($(Value<$element>,)+) {
type Plain = ($($element,)+);
}
$(impl_tuple_get!(@element $tuple $n $element);)+
};
}

impl_tuple_get!((T0, T1); 0 T0, 1 T1);
36 changes: 18 additions & 18 deletions rules/pair/src.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,28 +55,22 @@ template <typename T1, typename T2> const T1 &f16(const std::pair<T1, T2> &a0) {
return a0.first;
}

template <typename T1, typename T2> T1 &f17(std::pair<T1, T2> &a0) {
return std::get<0>(a0);
template <std::size_t T1, typename T2, typename T3>
typename std::tuple_element<T1, std::pair<T2, T3>>::type &
f17(std::pair<T2, T3> &a0) {
return std::get<T1>(a0);
}

template <typename T1, typename T2> T2 &f18(std::pair<T1, T2> &a0) {
return std::get<1>(a0);
template <std::size_t T1, typename T2, typename T3>
const typename std::tuple_element<T1, std::pair<T2, T3>>::type &
f19(const std::pair<T2, T3> &a0) {
return std::get<T1>(a0);
}

template <typename T1, typename T2> const T1 &f19(const std::pair<T1, T2> &a0) {
return std::get<0>(a0);
}

template <typename T1, typename T2> const T2 &f20(const std::pair<T1, T2> &a0) {
return std::get<1>(a0);
}

template <typename T1, typename T2> T1 &&f21(std::pair<T1, T2> &&a0) {
return std::get<0>(std::move(a0));
}

template <typename T1, typename T2> T2 &&f22(std::pair<T1, T2> &&a0) {
return std::get<1>(std::move(a0));
template <std::size_t T1, typename T2, typename T3>
typename std::tuple_element<T1, std::pair<T2, T3>>::type &&
f21(std::pair<T2, T3> &&a0) {
return std::get<T1>(std::move(a0));
}

template <
Expand Down Expand Up @@ -110,3 +104,9 @@ template <
std::pair<T1, T2> &f26(std::pair<T1, T2> &a0, std::pair<T3, T4> &&a1) {
return a0.template operator= <T3, T4>(std::move(a1));
}

template <std::size_t T1, typename T2, typename T3>
const typename std::tuple_element<T1, std::pair<T2, T3>>::type &&
f27(const std::pair<T2, T3> &&a0) {
return std::get<T1>(std::move(a0));
}
Loading
Loading