Skip to content

Commit c6441cb

Browse files
committed
Add refcount support for va_args
1 parent 538a21a commit c6441cb

4 files changed

Lines changed: 57 additions & 11 deletions

File tree

cpp2rust/converter/converter.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -358,17 +358,22 @@ bool Converter::VisitFunctionTemplateDecl(clang::FunctionTemplateDecl *decl) {
358358
return false;
359359
}
360360

361+
void Converter::ConvertVaListVarDecl(clang::VarDecl *decl) {
362+
if (clang::isa<clang::ParmVarDecl>(decl)) {
363+
// va_list parameter (decayed to __va_list_tag *): emit "mut ap: VaList"
364+
} else {
365+
// va_list local variable: emit "let mut ap: VaList"
366+
StrCat(keyword::kLet);
367+
}
368+
StrCat(keyword_mut_, GetNamedDeclAsString(decl), token::kColon, "VaList");
369+
}
370+
361371
bool Converter::ConvertVarDeclSkipInit(clang::VarDecl *decl) {
362372
auto qual_type = decl->getType();
363373
auto name = GetNamedDeclAsString(decl);
364374

365375
if (IsVaListType(ctx_, qual_type) && decl->isLocalVarDecl()) {
366-
if (!clang::isa<clang::ParmVarDecl>(decl)) {
367-
// va_list local variable: emit "let mut ap: VaList"
368-
StrCat(keyword::kLet);
369-
} // else va_list parameter (decayed to __va_list_tag *): emit "mut ap:
370-
// VaList"
371-
StrCat(keyword_mut_, name, token::kColon, "VaList");
376+
ConvertVaListVarDecl(decl);
372377
return true;
373378
}
374379

@@ -429,9 +434,7 @@ void Converter::ConvertVarDecl(clang::VarDecl *decl) {
429434
return;
430435
}
431436
auto qual_type = decl->getType();
432-
if (IsVaListType(ctx_, qual_type)) {
433-
StrCat(token::kAssign, "VaList::empty()");
434-
} else if (decl->hasInit()) {
437+
if (decl->hasInit()) {
435438
StrCat(token::kAssign);
436439
ConvertVarInit(qual_type, decl->getInit());
437440
} else if (!clang::isa<clang::ParmVarDecl>(decl)) {

cpp2rust/converter/converter.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
8585

8686
virtual void ConvertGlobalVarDecl(clang::VarDecl *decl);
8787

88-
bool ConvertVarDeclSkipInit(clang::VarDecl *decl);
88+
virtual void ConvertVaListVarDecl(clang::VarDecl *decl);
89+
90+
virtual bool ConvertVarDeclSkipInit(clang::VarDecl *decl);
8991

9092
virtual bool ConvertLambdaVarDecl(clang::VarDecl *decl);
9193

@@ -199,7 +201,7 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
199201

200202
virtual void ConvertPrintf(clang::CallExpr *expr);
201203

202-
virtual void ConvertVAArgCall(clang::CallExpr *expr);
204+
void ConvertVAArgCall(clang::CallExpr *expr);
203205

204206
virtual bool VisitCallExpr(clang::CallExpr *expr);
205207

cpp2rust/converter/models/converter_refcount.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,11 @@ bool ConverterRefCount::VisitPointerType(clang::PointerType *type) {
172172
return false;
173173
}
174174

175+
if (IsVaListType(ctx_, clang::QualType(type, 0))) {
176+
StrCat("VaList");
177+
return false;
178+
}
179+
175180
if (type->isVoidPointerType()) {
176181
StrCat("AnyPtr");
177182
return false;
@@ -472,6 +477,17 @@ void ConverterRefCount::EmitFunctionPreamble(clang::FunctionDecl *decl) {
472477
}
473478
}
474479

480+
void ConverterRefCount::ConvertVaListVarDecl(clang::VarDecl *decl) {
481+
if (clang::isa<clang::ParmVarDecl>(decl)) {
482+
// va_list parameter (decayed to __va_list_tag *): emit "mut ap: VaList"
483+
} else {
484+
// va_list local variable: emit "let mut ap: VaList"
485+
StrCat(keyword::kLet);
486+
}
487+
488+
StrCat(GetNamedDeclAsString(decl), token::kColon, "Value<VaList>");
489+
}
490+
475491
bool ConverterRefCount::ConvertLambdaVarDecl(clang::VarDecl *decl) {
476492
return false;
477493
}
@@ -775,6 +791,11 @@ void ConverterRefCount::ConvertPrintf(clang::CallExpr *expr) {
775791
}
776792

777793
bool ConverterRefCount::VisitCallExpr(clang::CallExpr *expr) {
794+
if (IsBuiltinVaStart(expr) || IsBuiltinVaEnd(expr) || IsBuiltinVaCopy(expr)) {
795+
ConvertVAArgCall(expr);
796+
return false;
797+
}
798+
778799
if (expr->isCallToStdMove()) {
779800
if (IsUniquePtr(expr->getArg(0)->getType())) {
780801
StrCat(std::format("{}.take()", ConvertLValue(expr->getArg(0))));
@@ -912,6 +933,10 @@ bool ConverterRefCount::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
912933
}
913934

914935
if (expr->getCastKind() == clang::CastKind::CK_ArrayToPointerDecay) {
936+
if (IsVaListType(ctx_, sub_expr->getType())) {
937+
Convert(sub_expr);
938+
return false;
939+
}
915940
if (clang::isa<clang::StringLiteral>(sub_expr) ||
916941
clang::isa<clang::PredefinedExpr>(sub_expr)) {
917942
StrCat(std::format("Ptr::from_string_literal({})", ToString(sub_expr)));
@@ -1366,6 +1391,18 @@ bool ConverterRefCount::VisitImplicitValueInitExpr(
13661391
return Converter::VisitImplicitValueInitExpr(expr);
13671392
}
13681393

1394+
bool ConverterRefCount::VisitVAArgExpr(clang::VAArgExpr *expr) {
1395+
auto va_list_expr = expr->getSubExpr();
1396+
if (auto *cast = clang::dyn_cast<clang::ImplicitCastExpr>(va_list_expr)) {
1397+
va_list_expr = cast->getSubExpr();
1398+
}
1399+
StrCat(ConvertLValue(va_list_expr));
1400+
StrCat(".arg::<");
1401+
Convert(expr->getType());
1402+
StrCat(">()");
1403+
return false;
1404+
}
1405+
13691406
bool ConverterRefCount::VisitCXXDefaultArgExpr(clang::CXXDefaultArgExpr *expr) {
13701407
return Converter::VisitCXXDefaultArgExpr(expr);
13711408
}

cpp2rust/converter/models/converter_refcount.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ class ConverterRefCount final : public Converter {
4747

4848
void ConvertGlobalVarDecl(clang::VarDecl *decl) override;
4949

50+
void ConvertVaListVarDecl(clang::VarDecl *decl) override;
51+
5052
bool ConvertLambdaVarDecl(clang::VarDecl *decl) override;
5153

5254
bool VisitDeclRefExpr(clang::DeclRefExpr *expr) override;
@@ -93,6 +95,8 @@ class ConverterRefCount final : public Converter {
9395

9496
bool VisitImplicitValueInitExpr(clang::ImplicitValueInitExpr *expr) override;
9597

98+
bool VisitVAArgExpr(clang::VAArgExpr *expr) override;
99+
96100
void ConvertArrayCXXConstructExpr(clang::CXXConstructExpr *expr) override;
97101

98102
bool VisitCXXDefaultArgExpr(clang::CXXDefaultArgExpr *expr) override;

0 commit comments

Comments
 (0)