Skip to content

Commit 9128e08

Browse files
committed
Merge branch 'master' into non-uniform
2 parents 4094716 + f9e0fb7 commit 9128e08

5 files changed

Lines changed: 100 additions & 66 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>(
@@ -4289,7 +4286,7 @@ std::string Converter::GetArrayDefaultAsString(clang::QualType qual_type) {
42894286
if (clang::isa<clang::IncompleteArrayType>(qual_type)) {
42904287
return "[]";
42914288
}
4292-
if (Printer::ToString(ctx_, qual_type).contains("std::array")) {
4289+
if (IsStdDecl(qual_type->getAsCXXRecordDecl(), "array")) {
42934290
assert(GetTemplateArgs(qual_type).has_value());
42944291
auto template_args = *GetTemplateArgs(qual_type);
42954292
assert(template_args.size() == 2);
@@ -4499,24 +4496,7 @@ void Converter::ConvertVarInit(clang::QualType qual_type, clang::Expr *expr) {
44994496
StrCat(keyword_mut_);
45004497
}
45014498
}
4502-
auto *ignore_casts = expr->IgnoreCasts();
4503-
// FIXME: this looks very complicated
4504-
if (auto *ctor = clang::dyn_cast<clang::CXXConstructExpr>(ignore_casts);
4505-
ctor && ctor->getNumArgs() != 0 && IsReferenceType(ctor->getArg(0)) &&
4506-
clang::isa<clang::CallExpr>(ctor->getArg(0)->IgnoreCasts()) &&
4507-
!Mapper::Contains(
4508-
ctx_, clang::cast<clang::CallExpr>(ctor->getArg(0)->IgnoreCasts())
4509-
->getCallee()) &&
4510-
Printer::ToString(ctx_, ctor->getConstructor()->getThisType()) ==
4511-
"std::string") {
4512-
{
4513-
PushParen paren(*this);
4514-
StrCat(token::kStar);
4515-
PushInitType init_type(*this, qual_type);
4516-
Convert(expr);
4517-
}
4518-
StrCat(".clone()");
4519-
} else if (IsReferenceType(expr) || qual_type->isFunctionPointerType()) {
4499+
if (IsReferenceType(expr) || qual_type->isFunctionPointerType()) {
45204500
PushExprKind push(*this, ExprKind::AddrOf);
45214501
PushInitType init_type(*this, qual_type);
45224502
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 & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@
2828

2929
#include "converter/lex.h"
3030
#include "converter/mapper.h"
31-
#include "converter/printer.h"
32-
#include "converter/rules/decls.h"
3331
#include "converter/rules/registry.h"
3432

3533
// https://doc.rust-lang.org/reference/keywords.html
@@ -630,19 +628,38 @@ bool IsConvertibleFunctionDecl(const clang::FunctionDecl *decl) {
630628
return decl->hasBody() && decl->isThisDeclarationADefinition();
631629
}
632630

631+
bool IsStdDecl(const clang::NamedDecl *decl, llvm::StringRef name) {
632+
return decl && decl->isInStdNamespace() && decl->getIdentifier() &&
633+
decl->getName() == name;
634+
}
635+
633636
bool IsUniquePtr(clang::QualType type) {
634-
auto *record_decl = type.getNonReferenceType()->getAsCXXRecordDecl();
635-
return record_decl && record_decl->getNameAsString() == "unique_ptr";
637+
return IsStdDecl(type.getNonReferenceType()->getAsCXXRecordDecl(),
638+
"unique_ptr");
636639
}
637640

638641
bool IsCallToOstream(clang::CallExpr *expr) {
639-
if (auto *op = clang::dyn_cast<clang::CXXOperatorCallExpr>(expr)) {
640-
if (auto *record_decl = expr->getType()->getAsCXXRecordDecl()) {
641-
return record_decl->getNameAsString() == "basic_ostream" &&
642-
op->getOperator() == clang::OverloadedOperatorKind::OO_LessLess;
643-
}
642+
auto *op = clang::dyn_cast<clang::CXXOperatorCallExpr>(expr);
643+
return op &&
644+
op->getOperator() == clang::OverloadedOperatorKind::OO_LessLess &&
645+
IsStdDecl(expr->getType()->getAsCXXRecordDecl(), "basic_ostream");
646+
}
647+
648+
bool IsCDecl(const clang::NamedDecl *decl, llvm::StringRef name) {
649+
auto *function = clang::dyn_cast_or_null<clang::FunctionDecl>(decl);
650+
return function && function->isExternC() && function->getIdentifier() &&
651+
function->getName() == name;
652+
}
653+
654+
bool IsStdFunction(const clang::Expr *expr, llvm::StringRef name) {
655+
expr = expr->IgnoreUnlessSpelledInSource();
656+
const clang::NamedDecl *decl = nullptr;
657+
if (auto *call = clang::dyn_cast<clang::CallExpr>(expr)) {
658+
decl = call->getDirectCallee();
659+
} else if (auto *ref = clang::dyn_cast<clang::DeclRefExpr>(expr)) {
660+
decl = clang::dyn_cast<clang::FunctionDecl>(ref->getDecl());
644661
}
645-
return false;
662+
return IsStdDecl(decl, name);
646663
}
647664

648665
bool IsAsciiStringLiteral(const clang::StringLiteral *str) {
@@ -802,40 +819,64 @@ static std::string GetParamSignature(const clang::Decl *decl) {
802819
return args;
803820
}
804821

805-
static clang::ASTNameGenerator *name_generator = nullptr;
822+
static clang::MangleContext *mangle_context = nullptr;
806823

807-
void SetNameGenerator(clang::ASTNameGenerator *generator) {
808-
name_generator = generator;
824+
void SetMangleContext(clang::MangleContext *context) {
825+
mangle_context = context;
809826
}
810827

811-
clang::ASTNameGenerator *GetNameGenerator() { return name_generator; }
828+
clang::MangleContext *GetMangleContext() { return mangle_context; }
812829

813830
static std::string GetMangledName(const clang::Decl *decl) {
814-
assert(name_generator);
815-
return name_generator->getName(decl);
831+
assert(mangle_context);
832+
auto *named = clang::cast<clang::NamedDecl>(decl);
833+
if (!mangle_context->shouldMangleDeclName(named)) {
834+
return named->getNameAsString();
835+
}
836+
clang::GlobalDecl global;
837+
if (auto *ctor = clang::dyn_cast<clang::CXXConstructorDecl>(decl)) {
838+
global = clang::GlobalDecl(ctor, clang::Ctor_Complete);
839+
} else if (auto *dtor = clang::dyn_cast<clang::CXXDestructorDecl>(decl)) {
840+
global = clang::GlobalDecl(dtor, clang::Dtor_Complete);
841+
} else {
842+
global = clang::GlobalDecl(named);
843+
}
844+
std::string name;
845+
llvm::raw_string_ostream os(name);
846+
mangle_context->mangleName(global, os);
847+
return name;
848+
}
849+
850+
static std::string
851+
GetMangledTypeName(const clang::ClassTemplateSpecializationDecl *decl) {
852+
assert(mangle_context);
853+
std::string name;
854+
llvm::raw_string_ostream os(name);
855+
mangle_context->mangleCanonicalTypeName(
856+
decl->getASTContext().getCanonicalTagType(decl), os);
857+
return name;
816858
}
817859

818860
static std::string GetLexicalSpecializationID(const clang::Decl *decl) {
819-
auto &ctx = decl->getASTContext();
820861
std::string id;
821862
if (const auto *var =
822863
clang::dyn_cast<clang::VarTemplateSpecializationDecl>(decl)) {
823864
id += GetMangledName(var);
824865
}
825866
if (const auto *self =
826867
clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(decl)) {
827-
id += Printer::ToString(ctx, GetTypeForDecl(ctx, self));
868+
id += GetMangledTypeName(self);
828869
}
829870
if (const auto *spec =
830871
clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(
831872
decl->getLexicalDeclContext());
832873
spec && decl->getLexicalDeclContext() != decl->getDeclContext()) {
833-
id += Printer::ToString(ctx, GetTypeForDecl(ctx, spec));
874+
id += GetMangledTypeName(spec);
834875
}
835876
for (const auto *dc = decl->getDeclContext(); dc; dc = dc->getParent()) {
836877
if (const auto *spec =
837878
clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(dc)) {
838-
id += Printer::ToString(ctx, GetTypeForDecl(ctx, spec));
879+
id += GetMangledTypeName(spec);
839880
}
840881
if (const auto *fn = clang::dyn_cast<clang::FunctionDecl>(dc);
841882
fn && fn->getTemplateSpecializationArgs()) {

‎cpp2rust/converter/converter_lib.h‎

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

145145
bool IsConvertibleFunctionDecl(const clang::FunctionDecl *decl);
146146

147+
bool IsStdDecl(const clang::NamedDecl *decl, llvm::StringRef name);
148+
147149
bool IsUniquePtr(clang::QualType type);
148150

149151
bool IsCallToOstream(clang::CallExpr *expr);
150152

153+
bool IsCDecl(const clang::NamedDecl *decl, llvm::StringRef name);
154+
155+
bool IsStdFunction(const clang::Expr *expr, llvm::StringRef name);
156+
151157
bool IsAsciiStringLiteral(const clang::StringLiteral *str);
152158

153159
bool IsInitExprOfStringLiteral(const clang::InitListExpr *expr);
@@ -179,9 +185,9 @@ unsigned GetColumnNumber(const clang::Decl *decl);
179185

180186
unsigned GetArraySize(clang::QualType array_type);
181187

182-
void SetNameGenerator(clang::ASTNameGenerator *generator);
188+
void SetMangleContext(clang::MangleContext *context);
183189

184-
clang::ASTNameGenerator *GetNameGenerator();
190+
clang::MangleContext *GetMangleContext();
185191

186192
std::string GetID(const clang::Decl *decl);
187193
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)