2222#include < vector>
2323
2424#include " converter/rules/decls.h"
25+ #include " converter/rules/rule_keys.h"
2526
2627namespace cpp2rust ::AstMatcher {
2728
@@ -60,8 +61,15 @@ struct RewrittenOperatorUsage {
6061 bool operator ==(const RewrittenOperatorUsage &) const = default ;
6162};
6263
63- using ResolvedDecl = std::variant<std::monostate, const clang::Decl *,
64- MacroUsage, RewrittenOperatorUsage>;
64+ struct AggregateUsage {
65+ RuleKeys::TypeKey type;
66+
67+ bool operator ==(const AggregateUsage &) const = default ;
68+ };
69+
70+ using ResolvedDecl =
71+ std::variant<std::monostate, const clang::Decl *, MacroUsage,
72+ RewrittenOperatorUsage, AggregateUsage>;
6573
6674ResolvedDecl getResolvedDecl (clang::ASTContext &ctx, const clang::Expr *expr,
6775 bool must_resolve) {
@@ -85,6 +93,14 @@ ResolvedDecl getResolvedDecl(clang::ASTContext &ctx, const clang::Expr *expr,
8593 if (auto cast = llvm::dyn_cast<clang::ExplicitCastExpr>(expr)) {
8694 return getResolvedDecl (ctx, cast->getSubExpr (), must_resolve);
8795 }
96+ if (auto list = llvm::dyn_cast<clang::InitListExpr>(expr);
97+ list && list->getType ()->isRecordType ()) {
98+ return AggregateUsage{*RuleKeys::GetTypeKey (list->getType ())};
99+ }
100+ if (auto construct = llvm::dyn_cast<clang::CXXUnresolvedConstructExpr>(expr);
101+ construct && construct->isListInitialization ()) {
102+ return AggregateUsage{*RuleKeys::GetTypeKey (construct->getTypeAsWritten ())};
103+ }
88104 if (auto call = llvm::dyn_cast<clang::CallExpr>(expr)) {
89105 if (auto callee = call->getDirectCallee ()) {
90106 return callee->getCanonicalDecl ();
@@ -149,6 +165,8 @@ std::vector<clang::Expr *> getOperands(clang::ASTContext &ctx,
149165 operands.insert (operands.end (), call->arg_begin (), call->arg_end ());
150166 } else if (auto construct = llvm::dyn_cast<clang::CXXConstructExpr>(expr)) {
151167 operands.assign (construct->arg_begin (), construct->arg_end ());
168+ } else if (auto list = llvm::dyn_cast<clang::InitListExpr>(expr)) {
169+ operands.assign (list->inits ().begin (), list->inits ().end ());
152170 } else if (auto member = llvm::dyn_cast<clang::MemberExpr>(expr)) {
153171 auto macro_base =
154172 RuleDecls::GetMacroMemberBase (ctx.getSourceManager (), member);
@@ -320,6 +338,17 @@ MatchResult matchTemplate(clang::Sema &sema, const clang::Expr *use,
320338 auto explicit_args = getResultArgs (sema, rule, use);
321339 auto specialization =
322340 deduce (sema, rule, explicit_args, getOperands (ctx, use));
341+ if (!specialization) {
342+ return std::nullopt ;
343+ }
344+ if (std::holds_alternative<AggregateUsage>(usage_decl)) {
345+ auto returned = RuleDecls::GetReturned (rule->getTemplatedDecl ());
346+ if (getResolvedDecl (ctx, returned, /* must_resolve=*/ false ) != usage_decl) {
347+ return std::nullopt ;
348+ }
349+ checkCallable (sema, use, rule->getTemplatedDecl ());
350+ return specialization->getTemplateSpecializationArgs ()->asArray ();
351+ }
323352 auto returned =
324353 substituteSpecializationInRuleTmpl (sema, rule, specialization);
325354 if (!returned ||
0 commit comments