Skip to content

Commit 9541a0a

Browse files
committed
Resolve member types only in matching partial specializations
1 parent e962dbf commit 9541a0a

5 files changed

Lines changed: 45 additions & 12 deletions

File tree

‎cpp2rust/converter/rules/registry.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ void addRule(clang::ASTContext &ctx, const std::string &dir,
170170
assert(llvm::isa<clang::VarDecl>(decl) &&
171171
"expression rule is neither a function nor a variable");
172172
}
173-
auto keys = RuleKeys::GetExprKeys(ctx, decl);
173+
auto keys = RuleKeys::GetExprKeys(*sema_, decl);
174174
assert(!keys.empty() && "expression rule has no key");
175175
for (const auto &key : keys) {
176176
exprs_.emplace(

‎cpp2rust/converter/rules/rule_keys.cpp‎

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include <clang/Basic/OperatorKinds.h>
1010
#include <clang/Basic/SourceManager.h>
1111
#include <clang/Lex/Lexer.h>
12+
#include <clang/Sema/Sema.h>
13+
#include <clang/Sema/TemplateDeduction.h>
1214
#include <llvm/ADT/STLExtras.h>
1315

1416
#include <cassert>
@@ -56,32 +58,51 @@ const clang::Decl *getParent(const clang::Decl *decl) {
5658
return nullptr;
5759
}
5860

59-
std::vector<clang::QualType> resolveMemberType(clang::QualType type) {
61+
llvm::SmallVector<clang::CXXRecordDecl *>
62+
matchingDefinitions(clang::Sema &sema, clang::ClassTemplateDecl *tmpl,
63+
const clang::TemplateSpecializationType *spec) {
64+
llvm::SmallVector<clang::ClassTemplatePartialSpecializationDecl *> partials;
65+
tmpl->getPartialSpecializations(partials);
66+
llvm::SmallVector<clang::CXXRecordDecl *> records;
67+
for (auto partial : partials) {
68+
RuleDecls::Trial trial(sema);
69+
clang::sema::TemplateDeductionInfo info(partial->getLocation());
70+
if (sema.DeduceTemplateArguments(partial, spec->template_arguments(),
71+
info) ==
72+
clang::TemplateDeductionResult::Success &&
73+
!trial.failed()) {
74+
records.push_back(partial);
75+
}
76+
}
77+
if (records.empty()) {
78+
records.push_back(tmpl->getTemplatedDecl());
79+
}
80+
return records;
81+
}
82+
83+
std::vector<clang::QualType> resolveMemberType(clang::Sema &sema,
84+
clang::QualType type) {
6085
auto member = type->getAs<clang::DependentNameType>();
6186
if (!member) {
6287
return {type};
6388
}
6489
auto qualifier = member->getQualifier().getAsType();
6590
assert(qualifier && "member type is not qualified by a type");
6691
std::vector<clang::QualType> resolved;
67-
for (auto owner : resolveMemberType(clang::QualType(qualifier, 0))) {
92+
for (auto owner : resolveMemberType(sema, clang::QualType(qualifier, 0))) {
6893
auto spec = owner->getAs<clang::TemplateSpecializationType>();
6994
auto tmpl = spec ? llvm::dyn_cast_or_null<clang::ClassTemplateDecl>(
7095
spec->getTemplateName().getAsTemplateDecl())
7196
: nullptr;
7297
assert(tmpl && "member type is not qualified by a class template");
73-
llvm::SmallVector<clang::ClassTemplatePartialSpecializationDecl *> partials;
74-
tmpl->getPartialSpecializations(partials);
75-
llvm::SmallVector<clang::CXXRecordDecl *> records{tmpl->getTemplatedDecl()};
76-
records.append(partials.begin(), partials.end());
77-
for (auto record : records) {
98+
for (auto record : matchingDefinitions(sema, tmpl, spec)) {
7899
if (!record->hasDefinition()) {
79100
continue;
80101
}
81102
for (auto decl :
82103
record->getDefinition()->lookup(member->getIdentifier())) {
83104
if (auto alias = llvm::dyn_cast<clang::TypedefNameDecl>(decl)) {
84-
auto types = resolveMemberType(alias->getUnderlyingType());
105+
auto types = resolveMemberType(sema, alias->getUnderlyingType());
85106
resolved.insert(resolved.end(), types.begin(), types.end());
86107
}
87108
}
@@ -203,8 +224,9 @@ std::optional<ExprKey> GetExprKey(clang::ASTContext &ctx,
203224
return getExprKey(ctx, use);
204225
}
205226

206-
std::vector<ExprKey> GetExprKeys(clang::ASTContext &ctx,
227+
std::vector<ExprKey> GetExprKeys(clang::Sema &sema,
207228
const clang::NamedDecl *rule) {
229+
auto &ctx = sema.Context;
208230
if (auto var = llvm::dyn_cast<clang::VarDecl>(rule)) {
209231
auto key = getExprKey(ctx, var->getInit());
210232
assert(key && "expression rule has no key");
@@ -215,7 +237,7 @@ std::vector<ExprKey> GetExprKeys(clang::ASTContext &ctx,
215237
if (auto construct =
216238
llvm::dyn_cast<clang::CXXUnresolvedConstructExpr>(returned)) {
217239
std::vector<ExprKey> keys;
218-
for (auto type : resolveMemberType(construct->getTypeAsWritten())) {
240+
for (auto type : resolveMemberType(sema, construct->getTypeAsWritten())) {
219241
if (type->getAs<clang::TemplateTypeParmType>()) {
220242
if (!llvm::is_contained(keys, ExprKey{kAnyConstructor})) {
221243
keys.push_back(kAnyConstructor);

‎cpp2rust/converter/rules/rule_keys.h‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <clang/AST/DeclarationName.h>
99
#include <clang/AST/Expr.h>
1010
#include <clang/AST/Type.h>
11+
#include <clang/Sema/Sema.h>
1112
#include <llvm/ADT/Hashing.h>
1213

1314
#include <compare>
@@ -46,7 +47,7 @@ inline const Constructor kAnyConstructor{nullptr};
4647
std::optional<ExprKey> GetExprKey(clang::ASTContext &ctx,
4748
const clang::Expr *use);
4849

49-
std::vector<ExprKey> GetExprKeys(clang::ASTContext &ctx,
50+
std::vector<ExprKey> GetExprKeys(clang::Sema &sema,
5051
const clang::NamedDecl *rule);
5152

5253
std::optional<ExprKey> GetDeclKey(const clang::NamedDecl *decl);

‎rules/vector/src.cpp‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,3 +254,9 @@ f116(std::vector<T1, T2> &o, typename std::vector<T1, T2>::const_iterator pos,
254254
std::initializer_list<T1> l) {
255255
return o.insert(pos, l);
256256
}
257+
258+
template <typename T1>
259+
typename std::vector<bool, T1>::reference
260+
f117(const typename std::vector<bool, T1>::reference &a0) {
261+
return typename std::vector<bool, T1>::reference(a0);
262+
}

‎rules/vector/tgt_unsafe.rs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,3 +249,7 @@ unsafe fn f116<T1>(a0: &mut Vec<T1>, a1: UnsafeRandomAccessIterator<T1>, a2: Vec
249249
a0.splice(__off..__off, a2);
250250
UnsafeRandomAccessIterator::Vec(a0.as_mut_ptr().add(__off))
251251
}
252+
253+
unsafe fn f117(a0: bool) -> bool {
254+
a0
255+
}

0 commit comments

Comments
 (0)