Skip to content

Commit bd7c863

Browse files
committed
Merge branch 'master' into concepts
2 parents c08d280 + 1ce3815 commit bd7c863

201 files changed

Lines changed: 2395 additions & 1841 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.

‎cpp2rust/converter/converter.cpp‎

Lines changed: 45 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,10 @@ bool Converter::RecordDerivesDefault(const clang::RecordDecl *decl) {
685685
}
686686

687687
for (auto f : decl->fields()) {
688+
if (f->hasInClassInitializer()) {
689+
return false;
690+
}
691+
688692
// Records that contain function pointer do not derive Default
689693
if (auto ptr_ty = f->getType()->getAs<clang::PointerType>()) {
690694
if (ptr_ty->getPointeeType()->isFunctionType()) {
@@ -1095,9 +1099,17 @@ std::string Converter::GetMethodName(const clang::CXXMethodDecl *decl) {
10951099
if (clang::isa<clang::CXXDestructorDecl>(decl)) {
10961100
return kDestructorName;
10971101
}
1102+
if (const char *name = GetCopyOrMoveName(decl);
1103+
name && CanUseCopyOrMoveName(decl, name)) {
1104+
return name;
1105+
}
10981106
if (IsOverloadedMethod(decl)) {
10991107
return GetOverloadedFunctionName(decl);
11001108
}
1109+
if (auto *conversion = clang::dyn_cast<clang::CXXConversionDecl>(decl)) {
1110+
return GetConversionName(
1111+
conversion, GetUnsafeTypeAsString(conversion->getConversionType()));
1112+
}
11011113
return GetNamedDeclAsString(decl);
11021114
}
11031115

@@ -1140,12 +1152,15 @@ std::string Converter::GetSelfMaybeWithMut(const clang::CXXMethodDecl *decl) {
11401152

11411153
std::string Converter::GetCtorName(clang::CXXConstructorDecl *decl) {
11421154
if (decl->isCopyOrMoveConstructor()) {
1155+
if (const char *name = GetCopyOrMoveName(decl);
1156+
CanUseCopyOrMoveName(decl, name)) {
1157+
return name;
1158+
}
11431159
return GetOverloadedFunctionName(decl);
11441160
}
1145-
return GetRecordName(decl->getParent()) +
1146-
(GetNumberOfConvertingCtors(decl->getParent()) != 1
1147-
? std::to_string(GetCtorIndex(decl))
1148-
: "");
1161+
return GetNumberOfConvertingCtors(decl->getParent()) != 1
1162+
? std::format("new_{}", GetCtorIndex(decl))
1163+
: "new";
11491164
}
11501165

11511166
bool Converter::VisitCXXConstructorDecl(clang::CXXConstructorDecl *decl) {
@@ -1386,7 +1401,12 @@ bool Converter::VisitIfStmt(clang::IfStmt *stmt) {
13861401
return false;
13871402
}
13881403
StrCat(keyword::kIf);
1389-
ConvertCondition(stmt->getCond());
1404+
if (auto *cond = clang::dyn_cast<clang::ConstantExpr>(stmt->getCond());
1405+
cond && stmt->isConstexpr()) {
1406+
StrCat(cond->getResultAsAPSInt() != 0 ? keyword::kTrue : keyword::kFalse);
1407+
} else {
1408+
ConvertCondition(stmt->getCond());
1409+
}
13901410
ConvertBody(stmt->getThen());
13911411
if (stmt->hasElseStorage()) {
13921412
StrCat(keyword::kElse);
@@ -3331,7 +3351,7 @@ void Converter::ConvertMemberExpr(clang::MemberExpr *expr) {
33313351
if (auto *method = clang::dyn_cast<clang::CXXMethodDecl>(member);
33323352
method && IsOverloadedMethod(method)) {
33333353
StrCat(token::kDot);
3334-
StrCat(GetOverloadedFunctionName(method));
3354+
StrCat(GetMethodName(method));
33353355
} else if (!name_override.empty()) {
33363356
StrCat(token::kDot, name_override);
33373357
} else if (member->getDeclName().isIdentifier()) {
@@ -3373,6 +3393,7 @@ bool Converter::VisitArrayInitLoopExpr(clang::ArrayInitLoopExpr *expr) {
33733393
}
33743394

33753395
bool Converter::VisitInitListExpr(clang::InitListExpr *expr) {
3396+
auto *syntactic = expr->isSyntacticForm() ? expr : expr->getSyntacticForm();
33763397
if (auto form = expr->getSemanticForm())
33773398
expr = form;
33783399

@@ -3398,6 +3419,12 @@ bool Converter::VisitInitListExpr(clang::InitListExpr *expr) {
33983419
return false;
33993420
}
34003421

3422+
if (syntactic->getNumInits() == 0) {
3423+
StrCat(GetDefaultAsString(qual_type));
3424+
SetFreshType(qual_type);
3425+
return false;
3426+
}
3427+
34013428
StrCat(GetUnsafeTypeAsString(qual_type));
34023429
PushBrace brace(*this);
34033430
int i = 0;
@@ -4056,18 +4083,6 @@ std::string Converter::GetDefaultAsStringFallback(clang::QualType qual_type) {
40564083
return getTypedLiteral("0.0", ToString(qual_type));
40574084
}
40584085

4059-
if (auto record = qual_type->getAsRecordDecl();
4060-
record && in_const_initializer_) {
4061-
if (auto cxx = clang::dyn_cast<clang::CXXRecordDecl>(record)) {
4062-
ENSURE(GetUserDefinedDefaultConstructor(cxx) == nullptr &&
4063-
"Default initializing globals using default constructor is not "
4064-
"supported");
4065-
}
4066-
Buffer buf(*this);
4067-
EmitDefaultStructLiteral(record);
4068-
return std::move(buf).str();
4069-
}
4070-
40714086
if (auto record = qual_type->getAsRecordDecl()) {
40724087
if (ctx_.getSourceManager().isInSystemHeader(record->getLocation()) &&
40734088
qual_type.isPODType(ctx_)) {
@@ -4094,6 +4109,10 @@ std::string Converter::ConvertVarDefaultInit(clang::QualType qual_type) {
40944109
std::string
40954110
Converter::GetOverloadedFunctionName(const clang::FunctionDecl *decl) {
40964111
auto name = GetFunctionBaseName(decl);
4112+
if (auto *conversion = clang::dyn_cast<clang::CXXConversionDecl>(decl)) {
4113+
name = GetConversionName(
4114+
conversion, GetUnsafeTypeAsString(conversion->getConversionType()));
4115+
}
40974116
if (auto *ctor = clang::dyn_cast<clang::CXXConstructorDecl>(decl);
40984117
ctor && !ctor->getParent()->getIdentifier()) {
40994118
name = GetRecordName(ctor->getParent());
@@ -4163,19 +4182,7 @@ Converter::GetOverloadedFunctionName(const clang::FunctionDecl *decl) {
41634182
}
41644183
}
41654184

4166-
ReplaceAll(name, "[", "arr");
4167-
ReplaceAll(name, "]", "arr");
4168-
ReplaceAll(name, ";", "_");
4169-
ReplaceAll(name, ",", "_");
4170-
name.erase(std::remove_if(name.begin(), name.end(),
4171-
[](char c) {
4172-
return c == '<' || c == '>' || c == ' ' ||
4173-
c == ':' || c == '(' || c == ')' ||
4174-
c == '-';
4175-
}),
4176-
name.end());
4177-
std::replace(name.begin(), name.end(), '*', 'p');
4178-
4185+
ToIdentifier(name);
41794186
return name;
41804187
}
41814188

@@ -4734,8 +4741,13 @@ void Converter::EmitDefaultStructLiteral(const clang::RecordDecl *decl) {
47344741
StrCat(GetRecordName(decl));
47354742
PushBrace brace(*this);
47364743
for (auto *field : decl->fields()) {
4737-
StrCat(GetNamedDeclAsString(field), token::kColon,
4738-
GetDefaultAsString(field->getType()), token::kComma);
4744+
StrCat(GetNamedDeclAsString(field), token::kColon);
4745+
if (auto *init = field->getInClassInitializer()) {
4746+
ConvertVarInit(field->getType(), init);
4747+
} else {
4748+
StrCat(GetDefaultAsString(field->getType()));
4749+
}
4750+
StrCat(token::kComma);
47394751
}
47404752
}
47414753

‎cpp2rust/converter/converter.h‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,21 +132,35 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
132132
virtual const char *CharRustType() const { return "libc::c_char"; }
133133

134134
virtual bool VisitCXXMethodDecl(clang::CXXMethodDecl *decl);
135+
135136
virtual bool ShouldConvertMethod(const clang::CXXMethodDecl *decl);
137+
136138
virtual bool ConvertOutOfLineMethod(clang::CXXMethodDecl *decl);
139+
137140
bool ConvertCXXMethodDecl(clang::CXXMethodDecl *decl);
141+
138142
std::string GetMethodName(const clang::CXXMethodDecl *decl);
143+
139144
virtual std::string GetSelfMaybeWithMut(const clang::CXXMethodDecl *decl);
145+
140146
std::string GetCtorName(clang::CXXConstructorDecl *decl);
147+
141148
virtual void ConvertCXXRecordMethods(clang::CXXRecordDecl *decl);
149+
142150
virtual void ConvertLateInstantiatedMethods(clang::CXXRecordDecl *decl);
151+
143152
virtual std::string DestroyMembers(const clang::CXXRecordDecl *decl);
153+
144154
virtual void EmitScopedDestructor(const clang::VarDecl *decl);
155+
145156
void EmitDeallocation(clang::CXXDeleteExpr *expr,
146157
const std::string &argument_as_string);
158+
147159
virtual void SetUFCSReceiver(clang::Expr *base, bool is_arrow,
148160
const clang::CXXMethodDecl *method);
161+
149162
void ConvertUserOperatorCall(clang::CXXOperatorCallExpr *expr);
163+
150164
virtual std::string GetUFCSName(const clang::CXXMethodDecl *method) const;
151165

152166
virtual bool ThisIsRustPtr() const { return false; }

‎cpp2rust/converter/converter_lib.cpp‎

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,44 @@ bool IsOverloadedMethod(const clang::CXXMethodDecl *decl) {
349349
}) > 1;
350350
}
351351

352+
const char *GetCopyOrMoveName(const clang::CXXMethodDecl *method) {
353+
if (auto *ctor = clang::dyn_cast<clang::CXXConstructorDecl>(method)) {
354+
if (ctor->isCopyConstructor()) {
355+
return "copy_from";
356+
}
357+
if (ctor->isMoveConstructor()) {
358+
return "move_from";
359+
}
360+
return nullptr;
361+
}
362+
if (method->isCopyAssignmentOperator()) {
363+
return "copy_assign";
364+
}
365+
if (method->isMoveAssignmentOperator()) {
366+
return "move_assign";
367+
}
368+
return nullptr;
369+
}
370+
371+
bool CanUseCopyOrMoveName(const clang::CXXMethodDecl *decl,
372+
const std::string &name) {
373+
const auto *record = decl->getParent();
374+
bool is_unique_member =
375+
std::count_if(record->method_begin(), record->method_end(),
376+
[&name](const clang::CXXMethodDecl *method) {
377+
const char *method_name = GetCopyOrMoveName(method);
378+
return !method->isDeleted() && method_name &&
379+
method_name == name;
380+
}) == 1;
381+
bool is_unique_name =
382+
std::none_of(record->method_begin(), record->method_end(),
383+
[&name](const clang::CXXMethodDecl *method) {
384+
return method->getDeclName().isIdentifier() &&
385+
method->getName() == name;
386+
});
387+
return is_unique_member && is_unique_name;
388+
}
389+
352390
bool IsUserDefinedCopyConstructor(const clang::CXXConstructorDecl *ctor) {
353391
return ctor->isCopyConstructor() && ctor->isUserProvided() &&
354392
IsUserDefinedDecl(ctor);
@@ -1005,6 +1043,35 @@ std::string GetFunctionBaseName(const clang::FunctionDecl *decl) {
10051043
return decl->getNameAsString();
10061044
}
10071045

1046+
void ToIdentifier(std::string &name) {
1047+
ReplaceAll(name, "[", "arr");
1048+
ReplaceAll(name, "]", "arr");
1049+
ReplaceAll(name, ";", "_");
1050+
ReplaceAll(name, ",", "_");
1051+
name.erase(std::remove_if(name.begin(), name.end(),
1052+
[](char c) {
1053+
return c == '<' || c == '>' || c == ' ' ||
1054+
c == ':' || c == '(' || c == ')' ||
1055+
c == '-';
1056+
}),
1057+
name.end());
1058+
std::replace(name.begin(), name.end(), '*', 'p');
1059+
}
1060+
1061+
std::string GetConversionName(const clang::CXXConversionDecl *decl,
1062+
const std::string &rust_type) {
1063+
auto name = "to_" + rust_type;
1064+
ToIdentifier(name);
1065+
const auto *record = decl->getParent();
1066+
bool is_unique_name =
1067+
std::none_of(record->method_begin(), record->method_end(),
1068+
[&name](const clang::CXXMethodDecl *method) {
1069+
return method->getDeclName().isIdentifier() &&
1070+
method->getName() == name;
1071+
});
1072+
return is_unique_name ? name : GetFunctionBaseName(decl);
1073+
}
1074+
10081075
clang::CXXDestructorDecl *
10091076
GetUserDefinedDestructor(const clang::CXXRecordDecl *decl) {
10101077
if (!decl->hasDefinition() || !IsUserDefinedDecl(decl) ||

‎cpp2rust/converter/converter_lib.h‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ void ForEachTemplateInstantiatedMethod(
7777

7878
bool IsOverloadedMethod(const clang::CXXMethodDecl *decl);
7979

80+
const char *GetCopyOrMoveName(const clang::CXXMethodDecl *method);
81+
82+
bool CanUseCopyOrMoveName(const clang::CXXMethodDecl *decl,
83+
const std::string &name);
84+
8085
bool IsUserDefinedCopyConstructor(const clang::CXXConstructorDecl *ctor);
8186

8287
bool IsConvertibleCopyOrMoveConstructor(const clang::CXXConstructorDecl *ctor);
@@ -172,6 +177,11 @@ const char *GetOverloadedOperator(const clang::FunctionDecl *decl);
172177

173178
std::string GetFunctionBaseName(const clang::FunctionDecl *decl);
174179

180+
void ToIdentifier(std::string &name);
181+
182+
std::string GetConversionName(const clang::CXXConversionDecl *decl,
183+
const std::string &rust_type);
184+
175185
bool IsImplicitAssignmentCall(const clang::CallExpr *expr);
176186
bool IsUserOperatorCall(const clang::CXXOperatorCallExpr *expr);
177187

0 commit comments

Comments
 (0)