Skip to content

Commit f9e0fb7

Browse files
authored
[NFC] Drop printer dependencies in converter (#537)
printer.cpp and ToString will slowly become deprecated for the new AST matcher.
1 parent 21e51a4 commit f9e0fb7

5 files changed

Lines changed: 100 additions & 65 deletions

File tree

‎cpp2rust/converter/converter.cpp‎

Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1720,7 +1720,6 @@ const clang::Expr *Converter::GetParentExpr(const clang::Expr *expr) {
17201720
bool Converter::GetFmtArg(clang::Expr *arg, std::string &fmt,
17211721
std::string &fmt_args, const char *&fmt_trait,
17221722
std::string &fmt_width) {
1723-
std::string arg_str = Printer::ToString(ctx_, arg);
17241723
if (auto *str_lit =
17251724
clang::dyn_cast<clang::StringLiteral>(arg->IgnoreImplicit())) {
17261725
if (!IsAsciiStringLiteral(str_lit)) {
@@ -1734,20 +1733,20 @@ bool Converter::GetFmtArg(clang::Expr *arg, std::string &fmt,
17341733
fmt += trim;
17351734
} else if (auto ch = GetEscapedUTF8CharLiteral(arg); !ch.empty()) {
17361735
fmt += std::move(ch);
1737-
} else if (arg_str.contains("std::endl")) {
1736+
} else if (IsStdFunction(arg, "endl")) {
17381737
fmt += "\\n";
1739-
} else if (arg_str.contains("std::hex")) {
1738+
} else if (IsStdFunction(arg, "hex")) {
17401739
fmt_trait = "x";
1741-
} else if (arg_str.contains("std::dec")) {
1740+
} else if (IsStdFunction(arg, "dec")) {
17421741
fmt_trait = "";
1743-
} else if (arg_str.contains("Setw")) {
1742+
} else if (IsStdFunction(arg, "setw")) {
17441743
fmt_width = Trim(ToString(arg));
17451744
} else if (!arg->getType()->isCharType() &&
17461745
Mapper::Map(*this, arg->getType()) !=
17471746
std::format("Vec<{}>", CharRustType())) {
17481747
fmt += ("{:" + fmt_width + fmt_trait + "}");
17491748
fmt_width.clear(); // Reset setw after first usage
1750-
arg_str = ToString(arg);
1749+
auto arg_str = ToString(arg);
17511750
if (arg->getType()->isBooleanType()) {
17521751
arg_str = std::format("({} as u8)", std::move(arg_str));
17531752
}
@@ -1767,7 +1766,7 @@ bool Converter::GetRawArg(clang::Expr *arg, std::string &raw_args) {
17671766
std::string str = ToString(arg);
17681767
raw_args += "(&(" + str + ").iter().take((" + str +
17691768
").len() - 1).map(|&c| c as u8).collect::<Vec<u8>>()[..]";
1770-
} else if (Printer::ToString(ctx_, arg).contains("std::endl")) {
1769+
} else if (IsStdFunction(arg, "endl")) {
17711770
raw_args += "(&[b'\\n']";
17721771
} else if (clang::isa<clang::StringLiteral>(arg->IgnoreImplicit())) {
17731772
raw_args += "(b" + GetEscapedStringLiteral(arg);
@@ -1853,8 +1852,7 @@ void Converter::ConvertCallToOstream(clang::CallExpr *expr) {
18531852
}
18541853

18551854
void Converter::ConvertPrintf(clang::CallExpr *expr) {
1856-
bool is_fprintf =
1857-
Printer::ToString(ctx_, expr->getCallee()).starts_with("int fprintf");
1855+
bool is_fprintf = IsCDecl(expr->getDirectCallee(), "fprintf");
18581856

18591857
StrCat("printf(");
18601858
for (unsigned i = is_fprintf; i < expr->getNumArgs(); ++i) {
@@ -2338,9 +2336,8 @@ std::optional<Converter::TempMaterializationCtx>
23382336
Converter::ConvertCallExpr(clang::CallExpr *expr) {
23392337
auto *callee = expr->getCallee();
23402338

2341-
auto fn = Printer::ToString(ctx_, callee);
2342-
bool is_printf = fn.starts_with("int printf");
2343-
bool is_fprintf = fn.starts_with("int fprintf");
2339+
bool is_printf = IsCDecl(expr->getDirectCallee(), "printf");
2340+
bool is_fprintf = IsCDecl(expr->getDirectCallee(), "fprintf");
23442341
unsigned format_arg = is_fprintf ? 1 : 0;
23452342
if ((is_printf || is_fprintf) &&
23462343
clang::isa<clang::StringLiteral>(
@@ -4295,7 +4292,7 @@ std::string Converter::GetArrayDefaultAsString(clang::QualType qual_type) {
42954292
if (clang::isa<clang::IncompleteArrayType>(qual_type)) {
42964293
return "[]";
42974294
}
4298-
if (Printer::ToString(ctx_, qual_type).contains("std::array")) {
4295+
if (IsStdDecl(qual_type->getAsCXXRecordDecl(), "array")) {
42994296
assert(GetTemplateArgs(qual_type).has_value());
43004297
auto template_args = *GetTemplateArgs(qual_type);
43014298
assert(template_args.size() == 2);
@@ -4505,24 +4502,7 @@ void Converter::ConvertVarInit(clang::QualType qual_type, clang::Expr *expr) {
45054502
StrCat(keyword_mut_);
45064503
}
45074504
}
4508-
auto *ignore_casts = expr->IgnoreCasts();
4509-
// FIXME: this looks very complicated
4510-
if (auto *ctor = clang::dyn_cast<clang::CXXConstructExpr>(ignore_casts);
4511-
ctor && ctor->getNumArgs() != 0 && IsReferenceType(ctor->getArg(0)) &&
4512-
clang::isa<clang::CallExpr>(ctor->getArg(0)->IgnoreCasts()) &&
4513-
!Mapper::Contains(
4514-
ctx_, clang::cast<clang::CallExpr>(ctor->getArg(0)->IgnoreCasts())
4515-
->getCallee()) &&
4516-
Printer::ToString(ctx_, ctor->getConstructor()->getThisType()) ==
4517-
"std::string") {
4518-
{
4519-
PushParen paren(*this);
4520-
StrCat(token::kStar);
4521-
PushInitType init_type(*this, qual_type);
4522-
Convert(expr);
4523-
}
4524-
StrCat(".clone()");
4525-
} else if (IsReferenceType(expr) || qual_type->isFunctionPointerType()) {
4505+
if (IsReferenceType(expr) || qual_type->isFunctionPointerType()) {
45264506
PushExprKind push(*this, ExprKind::AddrOf);
45274507
PushInitType init_type(*this, qual_type);
45284508
Convert(expr, qual_type);

‎cpp2rust/converter/converter.h‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,15 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
3535
const char *keyword_mut = keyword::kMut)
3636
: rs_code_(&rs_code), ctx_(ctx), keyword_unsafe_(keyword_unsafe),
3737
keyword_mut_(keyword_mut) {
38-
if (!GetNameGenerator()) {
39-
name_generator_ = std::make_unique<clang::ASTNameGenerator>(ctx);
40-
SetNameGenerator(name_generator_.get());
38+
if (!GetMangleContext()) {
39+
mangle_context_.reset(ctx.createMangleContext());
40+
SetMangleContext(mangle_context_.get());
4141
}
4242
}
4343

4444
virtual ~Converter() {
45-
if (name_generator_) {
46-
SetNameGenerator(nullptr);
45+
if (mangle_context_) {
46+
SetMangleContext(nullptr);
4747
}
4848
}
4949

@@ -806,7 +806,7 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
806806

807807
std::string *rs_code_;
808808
clang::ASTContext &ctx_;
809-
std::unique_ptr<clang::ASTNameGenerator> name_generator_;
809+
std::unique_ptr<clang::MangleContext> mangle_context_;
810810
clang::FunctionDecl *curr_function_ = nullptr;
811811
bool in_function_formals_ = false;
812812
enum class MethodTarget : uint8_t {

‎cpp2rust/converter/converter_lib.cpp‎

Lines changed: 61 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828

2929
#include "converter/lex.h"
3030
#include "converter/mapper.h"
31-
#include "converter/printer.h"
3231
#include "converter/rules/registry.h"
3332

3433
// https://doc.rust-lang.org/reference/keywords.html
@@ -668,19 +667,38 @@ bool IsConvertibleFunctionDecl(const clang::FunctionDecl *decl) {
668667
return decl->hasBody() && decl->isThisDeclarationADefinition();
669668
}
670669

670+
bool IsStdDecl(const clang::NamedDecl *decl, llvm::StringRef name) {
671+
return decl && decl->isInStdNamespace() && decl->getIdentifier() &&
672+
decl->getName() == name;
673+
}
674+
671675
bool IsUniquePtr(clang::QualType type) {
672-
auto *record_decl = type.getNonReferenceType()->getAsCXXRecordDecl();
673-
return record_decl && record_decl->getNameAsString() == "unique_ptr";
676+
return IsStdDecl(type.getNonReferenceType()->getAsCXXRecordDecl(),
677+
"unique_ptr");
674678
}
675679

676680
bool IsCallToOstream(clang::CallExpr *expr) {
677-
if (auto *op = clang::dyn_cast<clang::CXXOperatorCallExpr>(expr)) {
678-
if (auto *record_decl = expr->getType()->getAsCXXRecordDecl()) {
679-
return record_decl->getNameAsString() == "basic_ostream" &&
680-
op->getOperator() == clang::OverloadedOperatorKind::OO_LessLess;
681-
}
681+
auto *op = clang::dyn_cast<clang::CXXOperatorCallExpr>(expr);
682+
return op &&
683+
op->getOperator() == clang::OverloadedOperatorKind::OO_LessLess &&
684+
IsStdDecl(expr->getType()->getAsCXXRecordDecl(), "basic_ostream");
685+
}
686+
687+
bool IsCDecl(const clang::NamedDecl *decl, llvm::StringRef name) {
688+
auto *function = clang::dyn_cast_or_null<clang::FunctionDecl>(decl);
689+
return function && function->isExternC() && function->getIdentifier() &&
690+
function->getName() == name;
691+
}
692+
693+
bool IsStdFunction(const clang::Expr *expr, llvm::StringRef name) {
694+
expr = expr->IgnoreUnlessSpelledInSource();
695+
const clang::NamedDecl *decl = nullptr;
696+
if (auto *call = clang::dyn_cast<clang::CallExpr>(expr)) {
697+
decl = call->getDirectCallee();
698+
} else if (auto *ref = clang::dyn_cast<clang::DeclRefExpr>(expr)) {
699+
decl = clang::dyn_cast<clang::FunctionDecl>(ref->getDecl());
682700
}
683-
return false;
701+
return IsStdDecl(decl, name);
684702
}
685703

686704
bool IsAsciiStringLiteral(const clang::StringLiteral *str) {
@@ -840,40 +858,64 @@ static std::string GetParamSignature(const clang::Decl *decl) {
840858
return args;
841859
}
842860

843-
static clang::ASTNameGenerator *name_generator = nullptr;
861+
static clang::MangleContext *mangle_context = nullptr;
844862

845-
void SetNameGenerator(clang::ASTNameGenerator *generator) {
846-
name_generator = generator;
863+
void SetMangleContext(clang::MangleContext *context) {
864+
mangle_context = context;
847865
}
848866

849-
clang::ASTNameGenerator *GetNameGenerator() { return name_generator; }
867+
clang::MangleContext *GetMangleContext() { return mangle_context; }
850868

851869
static std::string GetMangledName(const clang::Decl *decl) {
852-
assert(name_generator);
853-
return name_generator->getName(decl);
870+
assert(mangle_context);
871+
auto *named = clang::cast<clang::NamedDecl>(decl);
872+
if (!mangle_context->shouldMangleDeclName(named)) {
873+
return named->getNameAsString();
874+
}
875+
clang::GlobalDecl global;
876+
if (auto *ctor = clang::dyn_cast<clang::CXXConstructorDecl>(decl)) {
877+
global = clang::GlobalDecl(ctor, clang::Ctor_Complete);
878+
} else if (auto *dtor = clang::dyn_cast<clang::CXXDestructorDecl>(decl)) {
879+
global = clang::GlobalDecl(dtor, clang::Dtor_Complete);
880+
} else {
881+
global = clang::GlobalDecl(named);
882+
}
883+
std::string name;
884+
llvm::raw_string_ostream os(name);
885+
mangle_context->mangleName(global, os);
886+
return name;
887+
}
888+
889+
static std::string
890+
GetMangledTypeName(const clang::ClassTemplateSpecializationDecl *decl) {
891+
assert(mangle_context);
892+
std::string name;
893+
llvm::raw_string_ostream os(name);
894+
mangle_context->mangleCanonicalTypeName(
895+
decl->getASTContext().getCanonicalTagType(decl), os);
896+
return name;
854897
}
855898

856899
static std::string GetLexicalSpecializationID(const clang::Decl *decl) {
857-
auto &ctx = decl->getASTContext();
858900
std::string id;
859901
if (const auto *var =
860902
clang::dyn_cast<clang::VarTemplateSpecializationDecl>(decl)) {
861903
id += GetMangledName(var);
862904
}
863905
if (const auto *self =
864906
clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(decl)) {
865-
id += Printer::ToString(ctx, GetTypeForDecl(ctx, self));
907+
id += GetMangledTypeName(self);
866908
}
867909
if (const auto *spec =
868910
clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(
869911
decl->getLexicalDeclContext());
870912
spec && decl->getLexicalDeclContext() != decl->getDeclContext()) {
871-
id += Printer::ToString(ctx, GetTypeForDecl(ctx, spec));
913+
id += GetMangledTypeName(spec);
872914
}
873915
for (const auto *dc = decl->getDeclContext(); dc; dc = dc->getParent()) {
874916
if (const auto *spec =
875917
clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(dc)) {
876-
id += Printer::ToString(ctx, GetTypeForDecl(ctx, spec));
918+
id += GetMangledTypeName(spec);
877919
}
878920
if (const auto *fn = clang::dyn_cast<clang::FunctionDecl>(dc);
879921
fn && fn->getTemplateSpecializationArgs()) {

‎cpp2rust/converter/converter_lib.h‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,16 @@ bool IsMethodOnPtr(const clang::CXXMethodDecl *method);
147147

148148
bool IsConvertibleFunctionDecl(const clang::FunctionDecl *decl);
149149

150+
bool IsStdDecl(const clang::NamedDecl *decl, llvm::StringRef name);
151+
150152
bool IsUniquePtr(clang::QualType type);
151153

152154
bool IsCallToOstream(clang::CallExpr *expr);
153155

156+
bool IsCDecl(const clang::NamedDecl *decl, llvm::StringRef name);
157+
158+
bool IsStdFunction(const clang::Expr *expr, llvm::StringRef name);
159+
154160
bool IsAsciiStringLiteral(const clang::StringLiteral *str);
155161

156162
bool IsInitExprOfStringLiteral(const clang::InitListExpr *expr);
@@ -182,9 +188,9 @@ unsigned GetColumnNumber(const clang::Decl *decl);
182188

183189
unsigned GetArraySize(clang::QualType array_type);
184190

185-
void SetNameGenerator(clang::ASTNameGenerator *generator);
191+
void SetMangleContext(clang::MangleContext *context);
186192

187-
clang::ASTNameGenerator *GetNameGenerator();
193+
clang::MangleContext *GetMangleContext();
188194

189195
std::string GetID(const clang::Decl *decl);
190196
std::string GetMethodID(const clang::CXXMethodDecl *decl);

‎cpp2rust/converter/models/converter_refcount.cpp‎

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include <clang/AST/RecordLayout.h>
77
#include <clang/Basic/OperatorKinds.h>
8+
#include <clang/Lex/Lexer.h>
89
#include <llvm/Support/ErrorHandling.h>
910

1011
#include <algorithm>
@@ -15,7 +16,6 @@
1516
#include "converter/converter_lib.h"
1617
#include "converter/lex.h"
1718
#include "converter/mapper.h"
18-
#include "converter/printer.h"
1919
#include "converter/rules/registry.h"
2020

2121
namespace cpp2rust {
@@ -1234,19 +1234,26 @@ static std::vector<const char *> printf2fmt(std::string &format) {
12341234
}
12351235

12361236
void ConverterRefCount::ConvertPrintf(clang::CallExpr *expr) {
1237-
bool is_fprintf =
1238-
Printer::ToString(ctx_, expr->getCallee()).starts_with("int fprintf");
1237+
bool is_fprintf = IsCDecl(expr->getDirectCallee(), "fprintf");
12391238
auto format = GetEscapedStringLiteral(clang::cast<clang::StringLiteral>(
12401239
expr->getArg(is_fprintf)->IgnoreImplicit()));
12411240
bool ends_newline = format.ends_with("\\n\"");
12421241

1243-
auto fd = is_fprintf ? Printer::ToString(ctx_, expr->getArg(0)) : "stdout";
1244-
if (fd == "stdout" || fd == "__stdoutp") {
1242+
llvm::StringRef stream = "stdout";
1243+
if (is_fprintf) {
1244+
auto loc = expr->getArg(0)->IgnoreParenImpCasts()->getBeginLoc();
1245+
stream = loc.isMacroID()
1246+
? clang::Lexer::getImmediateMacroName(
1247+
loc, ctx_.getSourceManager(), ctx_.getLangOpts())
1248+
: "";
1249+
}
1250+
if (stream == "stdout") {
12451251
StrCat(ends_newline ? "println!(" : "print!(");
1246-
} else if (fd == "stderr" || fd == "__stderrp") {
1252+
} else if (stream == "stderr") {
12471253
StrCat(ends_newline ? "eprintln!(" : "eprint!(");
12481254
} else {
1249-
llvm::errs() << "Unknown fprintf fd: " << fd << '\n';
1255+
llvm::errs() << "Unknown fprintf fd:\n";
1256+
expr->getArg(0)->dump(llvm::errs(), ctx_);
12501257
exit(1);
12511258
}
12521259
if (ends_newline) {

0 commit comments

Comments
 (0)