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
138 changes: 74 additions & 64 deletions cpp2rust/converter/converter.cpp

Large diffs are not rendered by default.

73 changes: 53 additions & 20 deletions cpp2rust/converter/converter_lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

#include "converter/lex.h"
#include "converter/mapper.h"
#include "converter/printer.h"
#include "converter/rules/registry.h"

// https://doc.rust-lang.org/reference/keywords.html
static const char rust_keywords[][12] = {
Expand Down Expand Up @@ -717,25 +719,26 @@ static std::string GetParamSignature(const clang::Decl *decl) {
}

static std::string GetLexicalSpecializationID(const clang::Decl *decl) {
auto &ctx = decl->getASTContext();
std::string id;
if (const auto *var =
clang::dyn_cast<clang::VarTemplateSpecializationDecl>(decl)) {
id += clang::ASTNameGenerator(var->getASTContext()).getName(var);
}
if (const auto *self =
clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(decl)) {
id += Mapper::ToString(Mapper::GetTypeForDecl(self));
id += Printer::ToString(ctx, GetTypeForDecl(ctx, self));
}
if (const auto *spec =
clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(
decl->getLexicalDeclContext());
spec && decl->getLexicalDeclContext() != decl->getDeclContext()) {
id += Mapper::ToString(Mapper::GetTypeForDecl(spec));
id += Printer::ToString(ctx, GetTypeForDecl(ctx, spec));
}
for (const auto *dc = decl->getDeclContext(); dc; dc = dc->getParent()) {
if (const auto *spec =
clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(dc)) {
id += Mapper::ToString(Mapper::GetTypeForDecl(spec));
id += Printer::ToString(ctx, GetTypeForDecl(ctx, spec));
}
if (const auto *fn = clang::dyn_cast<clang::FunctionDecl>(dc);
fn && fn->getTemplateSpecializationArgs()) {
Expand All @@ -755,6 +758,35 @@ std::string GetMethodID(const clang::CXXMethodDecl *decl) {
return decl->getQualifiedNameAsString() + GetID(decl);
}

clang::QualType GetTypeForDecl(clang::ASTContext &ctx,
const clang::NamedDecl *decl) {
if (const auto *spec =
llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(decl)) {
llvm::ArrayRef<clang::TemplateArgument> args =
spec->getTemplateArgs().asArray();
llvm::SmallVector<clang::TemplateArgument, 4> canon(args.begin(),
args.end());
ctx.canonicalizeTemplateArguments(canon);

return ctx.getTemplateSpecializationType(
clang::ElaboratedTypeKeyword::None,
clang::TemplateName(spec->getSpecializedTemplate()), args, canon);
}

const auto *rdecl = llvm::dyn_cast<clang::TagDecl>(decl);
assert(rdecl && "Unsupported decl type");

return ctx.getTagType(clang::ElaboratedTypeKeyword::None,
rdecl->getQualifier(), rdecl, /*OwnsTag*/ false);
}

bool HasFunctionParameterPack(const clang::FunctionDecl *decl) {
if (auto *primary = decl->getPrimaryTemplate()) {
decl = primary->getTemplatedDecl();
}
return decl->getNumParams() && decl->parameters().back()->isParameterPack();
}

std::string DisambiguateAnonymousTag(const clang::TagDecl *tag) {
if (!tag) {
return "";
Expand Down Expand Up @@ -1462,15 +1494,15 @@ std::optional<clang::QualType> GetParamImplicitConvertTarget(clang::Expr *expr,
}

std::optional<IteratorCategory>
GetStrongestIteratorCategory(clang::QualType type) {
GetStrongestIteratorCategory(clang::ASTContext &ctx, clang::QualType type) {
type = type.getNonReferenceType().getUnqualifiedType();
if (!Mapper::Contains(type)) {
if (!Mapper::Contains(ctx, type)) {
return std::nullopt;
}
if (Mapper::MapsToRefcountPointer(type)) {
if (RuleRegistry::MapsToRefcountPointer(ctx, type)) {
return IteratorCategory::Contiguous;
}
auto mapped = Mapper::Map(type);
auto mapped = Mapper::Map(ctx, type);
if (mapped.empty()) {
return std::nullopt;
}
Expand Down Expand Up @@ -1547,15 +1579,17 @@ bool IsBuiltinVaStart(const clang::CallExpr *expr) {
return false;
}

bool NeedsImplicitScalarCast(clang::QualType from, clang::QualType to) {
bool NeedsImplicitScalarCast(clang::ASTContext &ctx, clang::QualType from,
clang::QualType to) {
return !from.isNull() && !to.isNull() && from->isIntegerType() &&
to->isIntegerType() &&
from.getCanonicalType().getUnqualifiedType() ==
to.getCanonicalType().getUnqualifiedType() &&
Mapper::Map(from) != Mapper::Map(to);
Mapper::Map(ctx, from) != Mapper::Map(ctx, to);
}

bool NeedsRefBindingTemp(const clang::Expr *arg, clang::QualType param_type) {
bool NeedsRefBindingTemp(clang::ASTContext &ctx, const clang::Expr *arg,
clang::QualType param_type) {
if (!param_type->isReferenceType()) {
return false;
}
Expand All @@ -1571,28 +1605,27 @@ bool NeedsRefBindingTemp(const clang::Expr *arg, clang::QualType param_type) {
// void foo(const size_t &) {} <-- size_t -> usize
// unsigned long x = 1; foo(x); <-- unsigned long -> u64
return param_type->getPointeeType().isConstQualified() &&
NeedsImplicitScalarCast(arg->IgnoreImplicit()->getType(),
NeedsImplicitScalarCast(ctx, arg->IgnoreImplicit()->getType(),
param_type.getNonReferenceType());
}

bool IsSizeType(clang::QualType type) {
auto rust_type = Mapper::Map(type);
bool IsSizeType(clang::ASTContext &ctx, clang::QualType type) {
auto rust_type = Mapper::Map(ctx, type);
return rust_type == "usize" || rust_type == "isize";
}

std::optional<clang::QualType>
GetOperandImplicitConversionTarget(const clang::BinaryOperator *op,
const clang::Expr *operand,
const clang::Expr *sibling) {
std::optional<clang::QualType> GetOperandImplicitConversionTarget(
clang::ASTContext &ctx, const clang::BinaryOperator *op,
const clang::Expr *operand, const clang::Expr *sibling) {
if (op->isComparisonOp()) {
if (NeedsImplicitScalarCast(operand->getType(), sibling->getType()) &&
IsSizeType(sibling->getType())) {
if (NeedsImplicitScalarCast(ctx, operand->getType(), sibling->getType()) &&
IsSizeType(ctx, sibling->getType())) {
return sibling->getType();
}
return std::nullopt;
}
if ((op->isAdditiveOp() || op->isMultiplicativeOp() || op->isBitwiseOp()) &&
NeedsImplicitScalarCast(operand->getType(), op->getType())) {
NeedsImplicitScalarCast(ctx, operand->getType(), op->getType())) {
return op->getType();
}
return std::nullopt;
Expand Down
22 changes: 14 additions & 8 deletions cpp2rust/converter/converter_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ enum class IteratorCategory {
};

std::optional<IteratorCategory>
GetStrongestIteratorCategory(clang::QualType type);
GetStrongestIteratorCategory(clang::ASTContext &ctx, clang::QualType type);
bool IsBuiltinConstantP(const clang::Expr *expr);

bool IsGlobalVar(const clang::VarDecl *decl);
Expand Down Expand Up @@ -169,6 +169,11 @@ std::string GetNamedDeclAsString(const clang::NamedDecl *decl);

std::string DisambiguateAnonymousTag(const clang::TagDecl *tag);

clang::QualType GetTypeForDecl(clang::ASTContext &ctx,
const clang::NamedDecl *decl);

bool HasFunctionParameterPack(const clang::FunctionDecl *decl);

const char *AccessSpecifierAsString(clang::AccessSpecifier spec);

template <class T> llvm::SmallString<16> GetNumAsString(const T &num) {
Expand Down Expand Up @@ -272,16 +277,17 @@ std::string GetClassName(clang::QualType type);

bool IsVaListType(clang::QualType type);

bool NeedsImplicitScalarCast(clang::QualType from, clang::QualType to);
bool NeedsImplicitScalarCast(clang::ASTContext &ctx, clang::QualType from,
clang::QualType to);

bool NeedsRefBindingTemp(const clang::Expr *arg, clang::QualType param_type);
bool NeedsRefBindingTemp(clang::ASTContext &ctx, const clang::Expr *arg,
clang::QualType param_type);

bool IsSizeType(clang::QualType type);
bool IsSizeType(clang::ASTContext &ctx, clang::QualType type);

std::optional<clang::QualType>
GetOperandImplicitConversionTarget(const clang::BinaryOperator *op,
const clang::Expr *operand,
const clang::Expr *sibling);
std::optional<clang::QualType> GetOperandImplicitConversionTarget(
clang::ASTContext &ctx, const clang::BinaryOperator *op,
const clang::Expr *operand, const clang::Expr *sibling);

bool IsBuiltinVaStart(const clang::CallExpr *expr);

Expand Down
4 changes: 2 additions & 2 deletions cpp2rust/converter/factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@

#include "converter/factory.h"

#include "converter/mapper.h"
#include "converter/models/converter_refcount.h"
#include "converter/rules/registry.h"

namespace cpp2rust {

std::unique_ptr<Converter> CreateConverter(std::string &rs_code,
clang::ASTContext &ctx, Model model,
const std::string &rules_dir) {
Mapper::LoadTranslationRules(model, ctx, rules_dir);
RuleRegistry::Load(model, rules_dir);
switch (model) {
case Model::kUnsafe:
return std::make_unique<Converter>(rs_code, ctx);
Expand Down
Loading
Loading