Skip to content

Commit bb0bfec

Browse files
committed
edits
1 parent 1ca5ff9 commit bb0bfec

2 files changed

Lines changed: 61 additions & 30 deletions

File tree

cpp2rust/converter/mapper.cpp

Lines changed: 59 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,35 @@ clang::PrintingPolicy getPrintPolicy() {
4040
return policy;
4141
}
4242

43-
std::string GetMapKey(const std::string &str) {
43+
std::string GetExprMapKey(const std::string &str) {
44+
// Extract the function name from something like
45+
// const T1 & std::foo<T1, T2>::fn_name(args)
46+
auto n = str.find_first_of('(');
47+
if (n == std::string::npos) { // e.g. std::cerr
48+
return str;
49+
}
50+
51+
// Walk backwards from '(' tracking <> depth:
52+
// - skip characters inside template arguments (depth > 0)
53+
// - stop at the first space outside all angle brackets
54+
std::string result;
55+
int depth = 0;
56+
for (int i = (int)n - 1; i >= 0; --i) {
57+
char c = str[i];
58+
if (c == '>')
59+
++depth;
60+
else if (c == '<')
61+
--depth;
62+
else if (c == ' ' && depth == 0)
63+
break;
64+
else if (depth == 0)
65+
result += c;
66+
}
67+
std::reverse(result.begin(), result.end());
68+
return result;
69+
}
70+
71+
std::string GetTypeMapKey(const std::string &str) {
4472
auto n = str.find_first_of("<[");
4573
if (n == std::string::npos || str[n] == '<') {
4674
return str.substr(0, n);
@@ -50,7 +78,7 @@ std::string GetMapKey(const std::string &str) {
5078
}
5179

5280
void AddTypeRule(std::string src, TranslationRule::TypeRule &&rule) {
53-
auto key = GetMapKey(src);
81+
auto key = GetTypeMapKey(src);
5482
rule.src = std::move(src);
5583
types_.emplace(std::move(key), std::move(rule));
5684
}
@@ -68,8 +96,7 @@ std::optional<std::vector<std::string>>
6896
matchTemplate(const std::string &template_str,
6997
const std::string &instantiated) {
7098
auto matchLiteralAt = [&](const std::string &input_str, size_t pos,
71-
const std::string &literal,
72-
size_t &end_pos) -> bool {
99+
std::string_view literal, size_t &end_pos) -> bool {
73100
size_t i = pos;
74101
size_t j = 0;
75102

@@ -101,7 +128,7 @@ matchTemplate(const std::string &template_str,
101128
};
102129

103130
auto findNextLiteralSameDepth = [&](const std::string &s, size_t start,
104-
const std::string &lit) -> size_t {
131+
std::string_view lit) -> size_t {
105132
int ang = 0;
106133
int par = 0;
107134
int sq = 0;
@@ -209,7 +236,7 @@ matchTemplate(const std::string &template_str,
209236
size_t type_idx = std::stoi(&template_str[ti + 1]) - 1;
210237
ti = tj;
211238

212-
std::string nextLit;
239+
std::string_view nextLit;
213240
size_t scan = ti;
214241
while (scan < template_str.size()) {
215242
if (template_str[scan] == 'T' && scan + 1 < template_str.size() &&
@@ -218,7 +245,7 @@ matchTemplate(const std::string &template_str,
218245
}
219246
scan++;
220247
}
221-
nextLit = template_str.substr(ti, scan - ti);
248+
nextLit = std::string_view(template_str).substr(ti, scan - ti);
222249

223250
captured.resize(std::max(captured.size(), type_idx + 1));
224251
auto &repl = captured[type_idx];
@@ -281,7 +308,7 @@ matchTemplate(const std::string &template_str,
281308
++tj;
282309
}
283310

284-
std::string lit = template_str.substr(ti, tj - ti);
311+
auto lit = std::string_view(template_str).substr(ti, tj - ti);
285312
size_t end_pos = 0;
286313
if (!matchLiteralAt(instantiated, si, lit, end_pos)) {
287314
return std::nullopt;
@@ -332,15 +359,15 @@ std::string instantiateTgt(const std::vector<std::string> &types,
332359

333360
template <typename T>
334361
std::pair<T *, std::vector<std::string>>
335-
search(std::unordered_multimap<std::string, T> &map,
336-
const std::string &cpp_type) {
337-
auto [it, end] = map.equal_range(GetMapKey(cpp_type));
362+
search(std::unordered_multimap<std::string, T> &map, const std::string &txt,
363+
const std::string &key) {
364+
auto [it, end] = map.equal_range(key);
338365
T *rule = nullptr;
339366
std::vector<std::string> subs;
340367

341368
for (; it != end; ++it) {
342369
auto &this_rule = it->second;
343-
auto this_subs = matchTemplate(this_rule.src, cpp_type);
370+
auto this_subs = matchTemplate(this_rule.src, txt);
344371
if (!this_subs) {
345372
continue;
346373
}
@@ -355,7 +382,8 @@ search(std::unordered_multimap<std::string, T> &map,
355382

356383
TranslationRule::ExprRule *search(const clang::Expr *expr) {
357384
auto qualified_name = ToString(expr);
358-
auto [rule, subs] = search(exprs_, qualified_name);
385+
auto [rule, subs] =
386+
search(exprs_, qualified_name, GetExprMapKey(qualified_name));
359387
llvm::errs() << "search expr " << qualified_name << ", result:\n";
360388
if (rule) {
361389
rule->dump();
@@ -367,7 +395,7 @@ TranslationRule::ExprRule *search(const clang::Expr *expr) {
367395

368396
TranslationRule::TypeRule *search(clang::QualType qual_type) {
369397
auto type = ToString(qual_type);
370-
auto [rule, subs] = search(types_, type);
398+
auto [rule, subs] = search(types_, type, GetTypeMapKey(type));
371399
llvm::errs() << "search type " << type
372400
<< ", result: " << (rule ? rule->type_info.type : "None")
373401
<< '\n';
@@ -384,10 +412,10 @@ void addRulesFromDirectory(const std::filesystem::path &dir, Model model) {
384412
continue;
385413
}
386414
for (auto &[_, rule] : expr_rules) {
387-
exprs_.emplace(GetMapKey(rule.src), std::move(rule));
415+
exprs_.emplace(GetExprMapKey(rule.src), std::move(rule));
388416
}
389417
for (auto &[_, rule] : type_rules) {
390-
types_.emplace(GetMapKey(rule.src), std::move(rule));
418+
types_.emplace(GetTypeMapKey(rule.src), std::move(rule));
391419
}
392420
}
393421
}
@@ -505,7 +533,7 @@ clang::QualType normalizeQualType(clang::QualType qual_type) {
505533
}
506534

507535
std::string mapTypeStringRecursive(const std::string &cpp_type) {
508-
auto [rule, subs] = search(types_, cpp_type);
536+
auto [rule, subs] = search(types_, cpp_type, GetTypeMapKey(cpp_type));
509537
if (!rule) {
510538
llvm::errs() << "cpp_type: " << cpp_type << '\n';
511539
assert(0 && "Type is not present in types_");
@@ -572,8 +600,9 @@ std::string MapFunctionName(const clang::FunctionDecl *decl) {
572600
}
573601

574602
std::string InstantiateTemplate(const clang::Expr *expr, unsigned n) {
575-
auto text = 'T' + std::to_string(n);
576-
auto [rule, subs] = search(exprs_, ToString(expr));
603+
auto expr_str = ToString(expr);
604+
auto [rule, subs] = search(exprs_, expr_str, GetExprMapKey(expr_str));
605+
auto text = std::format("T{}", n);
577606
if (!rule) {
578607
return text;
579608
}
@@ -584,7 +613,8 @@ std::string InstantiateTemplate(const clang::Expr *expr, unsigned n) {
584613
}
585614

586615
std::string Map(clang::QualType qual_type) {
587-
auto [rule, subs] = search(types_, ToString(qual_type));
616+
auto type_str = ToString(qual_type);
617+
auto [rule, subs] = search(types_, type_str, GetTypeMapKey(type_str));
588618
if (rule) {
589619
for (auto &ty : subs) {
590620
ty = mapTypeStringRecursive(ty);
@@ -617,12 +647,12 @@ const TranslationRule::TypeInfo &GetParamInfo(const clang::Expr *expr,
617647
}
618648

619649
std::string GetParamType(const clang::Expr *expr, unsigned index) {
620-
auto &info = GetParamInfo(expr, index);
621-
auto [rule, subs] = search(exprs_, ToString(expr));
650+
auto expr_str = ToString(expr);
651+
auto [rule, subs] = search(exprs_, expr_str, GetExprMapKey(expr_str));
622652
for (auto &ty : subs) {
623653
ty = mapTypeStringRecursive(ty);
624654
}
625-
return instantiateTgt(subs, info.type);
655+
return instantiateTgt(subs, rule->params.at(index).type);
626656
}
627657

628658
bool ParamIsPointer(const clang::Expr *expr, unsigned index) {
@@ -853,14 +883,14 @@ void LoadTranslationRules(Model model, clang::ASTContext &ctx,
853883
addRulesFromDirectory(rules_dir, model);
854884
addBuiltinTypes(model);
855885

856-
#if 0
857-
for (auto &[src, expr] : exprs_) {
858-
llvm::errs() << "Expr: " << src << '\n';
859-
expr.dump();
886+
#if 1
887+
for (auto &[src, rule] : exprs_) {
888+
llvm::errs() << "Expr key: " << src << '\n';
889+
rule.dump();
860890
}
861-
for (auto &[src, type_tgt] : types_) {
891+
for (auto &[src, rule] : types_) {
862892
llvm::errs() << "Type key: " << src << '\n';
863-
type_tgt.dump();
893+
rule.dump();
864894
}
865895
#endif
866896
}

cpp2rust/converter/translation_rule.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,7 @@ void MethodCallFragment::dump() const {
949949
}
950950

951951
void ExprRule::dump() const {
952+
llvm::errs() << "Matching: " << src << '\n';
952953
unsigned i = 0;
953954
for (auto &info : params) {
954955
llvm::errs() << " param a" << i++ << ": ";
@@ -962,7 +963,7 @@ void ExprRule::dump() const {
962963
}
963964
i = 0;
964965
for (auto &bounds : generics) {
965-
llvm::errs() << " generic " << ++i << ':';
966+
llvm::errs() << " generic T" << ++i << ':';
966967
for (auto &b : bounds) {
967968
llvm::errs() << ' ' << b;
968969
}

0 commit comments

Comments
 (0)