Skip to content

Commit 61c16cf

Browse files
committed
Merge branch 'master' into decomposition
2 parents 7134ff0 + b907253 commit 61c16cf

446 files changed

Lines changed: 18122 additions & 16973 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.gitignore‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# CMake
22
build/
33
_buildconfig.py
4+
Cargo.lock
5+
target/
46

57
rules/rustls/rustls.h
68
rules/brotli/brotli/

‎cpp2rust/converter/converter.cpp‎

Lines changed: 115 additions & 145 deletions
Large diffs are not rendered by default.

‎cpp2rust/converter/converter.h‎

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -402,8 +402,6 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
402402

403403
virtual bool VisitStmtExpr(clang::StmtExpr *expr);
404404

405-
virtual void EmitStmtExprTail(clang::Expr *tail);
406-
407405
virtual bool VisitConditionalOperator(clang::ConditionalOperator *expr);
408406

409407
virtual bool VisitDeclRefExpr(clang::DeclRefExpr *expr);
@@ -583,7 +581,7 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
583581
virtual std::string ConvertVarDefaultInit(clang::QualType qual_type);
584582

585583
virtual std::string
586-
GetOverloadedFunctionName(const clang::FunctionDecl *decl);
584+
GetOverloadedFunctionName(const clang::CXXMethodDecl *decl);
587585

588586
virtual std::string GetRecordName(const clang::NamedDecl *decl) const;
589587

@@ -597,6 +595,11 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
597595

598596
virtual void ConvertVarInit(clang::QualType qual_type, clang::Expr *expr);
599597

598+
// The initial value of a field of a struct: `init`, or the default value
599+
// if null.
600+
virtual void ConvertFieldInit(const clang::FieldDecl *field,
601+
clang::Expr *init);
602+
600603
virtual void ConvertUnsignedArithOperand(clang::Expr *expr,
601604
clang::QualType type);
602605

@@ -668,7 +671,7 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
668671

669672
void EmitDefaultStructLiteral(const clang::RecordDecl *decl);
670673

671-
virtual void AddByteReprTrait(const clang::RecordDecl *decl);
674+
virtual void EmitByteSizeAttr(const clang::RecordDecl *decl);
672675

673676
virtual void
674677
ConvertUnsignedArithBinaryOperator(clang::BinaryOperator *binary_operator,

‎cpp2rust/converter/converter_lib.cpp‎

Lines changed: 71 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
#include "converter/lex.h"
2828
#include "converter/mapper.h"
29+
#include "converter/printer.h"
30+
#include "converter/rules/registry.h"
2931

3032
// https://doc.rust-lang.org/reference/keywords.html
3133
static const char rust_keywords[][12] = {
@@ -270,30 +272,6 @@ bool IsMut(clang::QualType qual_type) {
270272
qual_type->getPointeeType().isConstQualified());
271273
}
272274

273-
bool TypeImplementsByteRepr(clang::QualType qt) {
274-
if (qt->isIntegerType() || qt->isFloatingType() || qt->isEnumeralType()) {
275-
return true;
276-
}
277-
if (qt->isPointerType()) {
278-
return true;
279-
}
280-
if (const auto *arr = qt->getAsArrayTypeUnsafe()) {
281-
return TypeImplementsByteRepr(arr->getElementType());
282-
}
283-
if (const auto *rd = qt->getAsRecordDecl()) {
284-
if (rd->isUnion()) {
285-
return true;
286-
}
287-
for (const auto *field : rd->fields()) {
288-
if (!TypeImplementsByteRepr(field->getType())) {
289-
return false;
290-
}
291-
}
292-
return true;
293-
}
294-
return false;
295-
}
296-
297275
bool RustSizeDivergesFromC(clang::QualType qt) {
298276
qt = qt.getCanonicalType();
299277
// Records have Rc<RefCell<>> fields that diverge from the C size
@@ -352,6 +330,24 @@ bool IsOverloadedMethod(const clang::CXXMethodDecl *decl) {
352330
}) > 1;
353331
}
354332

333+
unsigned GetMethodIndex(const clang::CXXMethodDecl *decl) {
334+
const clang::Decl *key = decl->getCanonicalDecl();
335+
if (auto *tmpl = decl->getPrimaryTemplate()) {
336+
key = tmpl->getCanonicalDecl();
337+
}
338+
unsigned index = 0;
339+
for (auto *d : decl->getParent()->decls()) {
340+
if (clang::isa<clang::CXXMethodDecl, clang::FunctionTemplateDecl>(d)) {
341+
++index;
342+
if (d->getCanonicalDecl() == key) {
343+
return index;
344+
}
345+
}
346+
}
347+
assert(false && "method not found in its record");
348+
return 0;
349+
}
350+
355351
const char *GetCopyOrMoveName(const clang::CXXMethodDecl *method) {
356352
if (auto *ctor = clang::dyn_cast<clang::CXXConstructorDecl>(method)) {
357353
if (ctor->isCopyConstructor()) {
@@ -461,10 +457,6 @@ bool HasDefaultedCopyConstructor(const clang::RecordDecl *decl) {
461457
return !cxx->defaultedCopyConstructorIsDeleted();
462458
}
463459

464-
bool RecordDerivesByteRepr(const clang::RecordDecl *decl) {
465-
return !decl->isUnion() && decl->field_empty();
466-
}
467-
468460
bool RecordHasOnlyReferenceFields(const clang::RecordDecl *decl) {
469461
for (auto *field : decl->fields()) {
470462
if (!field->getType()->isReferenceType()) {
@@ -699,25 +691,26 @@ static std::string GetParamSignature(const clang::Decl *decl) {
699691
}
700692

701693
static std::string GetLexicalSpecializationID(const clang::Decl *decl) {
694+
auto &ctx = decl->getASTContext();
702695
std::string id;
703696
if (const auto *var =
704697
clang::dyn_cast<clang::VarTemplateSpecializationDecl>(decl)) {
705698
id += clang::ASTNameGenerator(var->getASTContext()).getName(var);
706699
}
707700
if (const auto *self =
708701
clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(decl)) {
709-
id += Mapper::ToString(Mapper::GetTypeForDecl(self));
702+
id += Printer::ToString(ctx, GetTypeForDecl(ctx, self));
710703
}
711704
if (const auto *spec =
712705
clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(
713706
decl->getLexicalDeclContext());
714707
spec && decl->getLexicalDeclContext() != decl->getDeclContext()) {
715-
id += Mapper::ToString(Mapper::GetTypeForDecl(spec));
708+
id += Printer::ToString(ctx, GetTypeForDecl(ctx, spec));
716709
}
717710
for (const auto *dc = decl->getDeclContext(); dc; dc = dc->getParent()) {
718711
if (const auto *spec =
719712
clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(dc)) {
720-
id += Mapper::ToString(Mapper::GetTypeForDecl(spec));
713+
id += Printer::ToString(ctx, GetTypeForDecl(ctx, spec));
721714
}
722715
if (const auto *fn = clang::dyn_cast<clang::FunctionDecl>(dc);
723716
fn && fn->getTemplateSpecializationArgs()) {
@@ -737,6 +730,35 @@ std::string GetMethodID(const clang::CXXMethodDecl *decl) {
737730
return decl->getQualifiedNameAsString() + GetID(decl);
738731
}
739732

733+
clang::QualType GetTypeForDecl(clang::ASTContext &ctx,
734+
const clang::NamedDecl *decl) {
735+
if (const auto *spec =
736+
llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(decl)) {
737+
llvm::ArrayRef<clang::TemplateArgument> args =
738+
spec->getTemplateArgs().asArray();
739+
llvm::SmallVector<clang::TemplateArgument, 4> canon(args.begin(),
740+
args.end());
741+
ctx.canonicalizeTemplateArguments(canon);
742+
743+
return ctx.getTemplateSpecializationType(
744+
clang::ElaboratedTypeKeyword::None,
745+
clang::TemplateName(spec->getSpecializedTemplate()), args, canon);
746+
}
747+
748+
const auto *rdecl = llvm::dyn_cast<clang::TagDecl>(decl);
749+
assert(rdecl && "Unsupported decl type");
750+
751+
return ctx.getTagType(clang::ElaboratedTypeKeyword::None,
752+
rdecl->getQualifier(), rdecl, /*OwnsTag*/ false);
753+
}
754+
755+
bool HasFunctionParameterPack(const clang::FunctionDecl *decl) {
756+
if (auto *primary = decl->getPrimaryTemplate()) {
757+
decl = primary->getTemplatedDecl();
758+
}
759+
return decl->getNumParams() && decl->parameters().back()->isParameterPack();
760+
}
761+
740762
std::string DisambiguateAnonymousTag(const clang::TagDecl *tag) {
741763
if (!tag) {
742764
return "";
@@ -1451,15 +1473,15 @@ std::optional<clang::QualType> GetParamImplicitConvertTarget(clang::Expr *expr,
14511473
}
14521474

14531475
std::optional<IteratorCategory>
1454-
GetStrongestIteratorCategory(clang::QualType type) {
1476+
GetStrongestIteratorCategory(clang::ASTContext &ctx, clang::QualType type) {
14551477
type = type.getNonReferenceType().getUnqualifiedType();
1456-
if (!Mapper::Contains(type)) {
1478+
if (!Mapper::Contains(ctx, type)) {
14571479
return std::nullopt;
14581480
}
1459-
if (Mapper::MapsToRefcountPointer(type)) {
1481+
if (RuleRegistry::MapsToRefcountPointer(ctx, type)) {
14601482
return IteratorCategory::Contiguous;
14611483
}
1462-
auto mapped = Mapper::Map(type);
1484+
auto mapped = Mapper::Map(ctx, type);
14631485
if (mapped.empty()) {
14641486
return std::nullopt;
14651487
}
@@ -1536,15 +1558,17 @@ bool IsBuiltinVaStart(const clang::CallExpr *expr) {
15361558
return false;
15371559
}
15381560

1539-
bool NeedsImplicitScalarCast(clang::QualType from, clang::QualType to) {
1561+
bool NeedsImplicitScalarCast(clang::ASTContext &ctx, clang::QualType from,
1562+
clang::QualType to) {
15401563
return !from.isNull() && !to.isNull() && from->isIntegerType() &&
15411564
to->isIntegerType() &&
15421565
from.getCanonicalType().getUnqualifiedType() ==
15431566
to.getCanonicalType().getUnqualifiedType() &&
1544-
Mapper::Map(from) != Mapper::Map(to);
1567+
Mapper::Map(ctx, from) != Mapper::Map(ctx, to);
15451568
}
15461569

1547-
bool NeedsRefBindingTemp(const clang::Expr *arg, clang::QualType param_type) {
1570+
bool NeedsRefBindingTemp(clang::ASTContext &ctx, const clang::Expr *arg,
1571+
clang::QualType param_type) {
15481572
if (!param_type->isReferenceType()) {
15491573
return false;
15501574
}
@@ -1560,28 +1584,27 @@ bool NeedsRefBindingTemp(const clang::Expr *arg, clang::QualType param_type) {
15601584
// void foo(const size_t &) {} <-- size_t -> usize
15611585
// unsigned long x = 1; foo(x); <-- unsigned long -> u64
15621586
return param_type->getPointeeType().isConstQualified() &&
1563-
NeedsImplicitScalarCast(arg->IgnoreImplicit()->getType(),
1587+
NeedsImplicitScalarCast(ctx, arg->IgnoreImplicit()->getType(),
15641588
param_type.getNonReferenceType());
15651589
}
15661590

1567-
bool IsSizeType(clang::QualType type) {
1568-
auto rust_type = Mapper::Map(type);
1591+
bool IsSizeType(clang::ASTContext &ctx, clang::QualType type) {
1592+
auto rust_type = Mapper::Map(ctx, type);
15691593
return rust_type == "usize" || rust_type == "isize";
15701594
}
15711595

1572-
std::optional<clang::QualType>
1573-
GetOperandImplicitConversionTarget(const clang::BinaryOperator *op,
1574-
const clang::Expr *operand,
1575-
const clang::Expr *sibling) {
1596+
std::optional<clang::QualType> GetOperandImplicitConversionTarget(
1597+
clang::ASTContext &ctx, const clang::BinaryOperator *op,
1598+
const clang::Expr *operand, const clang::Expr *sibling) {
15761599
if (op->isComparisonOp()) {
1577-
if (NeedsImplicitScalarCast(operand->getType(), sibling->getType()) &&
1578-
IsSizeType(sibling->getType())) {
1600+
if (NeedsImplicitScalarCast(ctx, operand->getType(), sibling->getType()) &&
1601+
IsSizeType(ctx, sibling->getType())) {
15791602
return sibling->getType();
15801603
}
15811604
return std::nullopt;
15821605
}
15831606
if ((op->isAdditiveOp() || op->isMultiplicativeOp() || op->isBitwiseOp()) &&
1584-
NeedsImplicitScalarCast(operand->getType(), op->getType())) {
1607+
NeedsImplicitScalarCast(ctx, operand->getType(), op->getType())) {
15851608
return op->getType();
15861609
}
15871610
return std::nullopt;

‎cpp2rust/converter/converter_lib.h‎

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ enum class IteratorCategory {
3535
};
3636

3737
std::optional<IteratorCategory>
38-
GetStrongestIteratorCategory(clang::QualType type);
38+
GetStrongestIteratorCategory(clang::ASTContext &ctx, clang::QualType type);
3939
bool IsBuiltinConstantP(const clang::Expr *expr);
4040

4141
bool IsGlobalVar(const clang::VarDecl *decl);
@@ -67,8 +67,6 @@ bool IsUnsignedArithOp(const clang::BinaryOperator *expr);
6767

6868
bool IsMut(clang::QualType qual_type);
6969

70-
bool TypeImplementsByteRepr(clang::QualType qt);
71-
7270
bool RustSizeDivergesFromC(clang::QualType qt);
7371

7472
bool IsMutatingCall(const clang::CallExpr *expr);
@@ -81,6 +79,8 @@ void ForEachTemplateInstantiatedMethod(
8179

8280
bool IsOverloadedMethod(const clang::CXXMethodDecl *decl);
8381

82+
unsigned GetMethodIndex(const clang::CXXMethodDecl *decl);
83+
8484
const char *GetCopyOrMoveName(const clang::CXXMethodDecl *method);
8585

8686
bool CanUseCopyOrMoveName(const clang::CXXMethodDecl *decl,
@@ -107,8 +107,6 @@ bool HasDefaultedCopyConstructor(const clang::RecordDecl *decl);
107107

108108
bool RecordHasOnlyReferenceFields(const clang::RecordDecl *decl);
109109

110-
bool RecordDerivesByteRepr(const clang::RecordDecl *decl);
111-
112110
bool HasDefaultedCopyAssignment(const clang::RecordDecl *decl);
113111

114112
bool IsRValueConvertingConstructor(const clang::CXXConstructorDecl *ctor);
@@ -167,6 +165,11 @@ std::string GetNamedDeclAsString(const clang::NamedDecl *decl);
167165

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

168+
clang::QualType GetTypeForDecl(clang::ASTContext &ctx,
169+
const clang::NamedDecl *decl);
170+
171+
bool HasFunctionParameterPack(const clang::FunctionDecl *decl);
172+
170173
const char *AccessSpecifierAsString(clang::AccessSpecifier spec);
171174

172175
template <class T> llvm::SmallString<16> GetNumAsString(const T &num) {
@@ -270,16 +273,17 @@ std::string GetClassName(clang::QualType type);
270273

271274
bool IsVaListType(clang::QualType type);
272275

273-
bool NeedsImplicitScalarCast(clang::QualType from, clang::QualType to);
276+
bool NeedsImplicitScalarCast(clang::ASTContext &ctx, clang::QualType from,
277+
clang::QualType to);
274278

275-
bool NeedsRefBindingTemp(const clang::Expr *arg, clang::QualType param_type);
279+
bool NeedsRefBindingTemp(clang::ASTContext &ctx, const clang::Expr *arg,
280+
clang::QualType param_type);
276281

277-
bool IsSizeType(clang::QualType type);
282+
bool IsSizeType(clang::ASTContext &ctx, clang::QualType type);
278283

279-
std::optional<clang::QualType>
280-
GetOperandImplicitConversionTarget(const clang::BinaryOperator *op,
281-
const clang::Expr *operand,
282-
const clang::Expr *sibling);
284+
std::optional<clang::QualType> GetOperandImplicitConversionTarget(
285+
clang::ASTContext &ctx, const clang::BinaryOperator *op,
286+
const clang::Expr *operand, const clang::Expr *sibling);
283287

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

‎cpp2rust/converter/factory.cpp‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33

44
#include "converter/factory.h"
55

6-
#include "converter/mapper.h"
76
#include "converter/models/converter_refcount.h"
7+
#include "converter/rules/registry.h"
88

99
namespace cpp2rust {
1010

1111
std::unique_ptr<Converter> CreateConverter(std::string &rs_code,
1212
clang::ASTContext &ctx, Model model,
1313
const std::string &rules_dir) {
14-
Mapper::LoadTranslationRules(model, ctx, rules_dir);
14+
RuleRegistry::Load(model, rules_dir);
1515
switch (model) {
1616
case Model::kUnsafe:
1717
return std::make_unique<Converter>(rs_code, ctx);

0 commit comments

Comments
 (0)