2626
2727#include " converter/lex.h"
2828#include " converter/mapper.h"
29+ #include " converter/printer.h"
30+ #include " converter/rules/registry.h"
2931
3032// https://doc.rust-lang.org/reference/keywords.html
3133static const char rust_keywords[][12 ] = {
@@ -717,25 +719,26 @@ static std::string GetParamSignature(const clang::Decl *decl) {
717719}
718720
719721static std::string GetLexicalSpecializationID (const clang::Decl *decl) {
722+ auto &ctx = decl->getASTContext ();
720723 std::string id;
721724 if (const auto *var =
722725 clang::dyn_cast<clang::VarTemplateSpecializationDecl>(decl)) {
723726 id += clang::ASTNameGenerator (var->getASTContext ()).getName (var);
724727 }
725728 if (const auto *self =
726729 clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(decl)) {
727- id += Mapper ::ToString (Mapper:: GetTypeForDecl (self));
730+ id += Printer ::ToString (ctx, GetTypeForDecl (ctx, self));
728731 }
729732 if (const auto *spec =
730733 clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(
731734 decl->getLexicalDeclContext ());
732735 spec && decl->getLexicalDeclContext () != decl->getDeclContext ()) {
733- id += Mapper ::ToString (Mapper:: GetTypeForDecl (spec));
736+ id += Printer ::ToString (ctx, GetTypeForDecl (ctx, spec));
734737 }
735738 for (const auto *dc = decl->getDeclContext (); dc; dc = dc->getParent ()) {
736739 if (const auto *spec =
737740 clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(dc)) {
738- id += Mapper ::ToString (Mapper:: GetTypeForDecl (spec));
741+ id += Printer ::ToString (ctx, GetTypeForDecl (ctx, spec));
739742 }
740743 if (const auto *fn = clang::dyn_cast<clang::FunctionDecl>(dc);
741744 fn && fn->getTemplateSpecializationArgs ()) {
@@ -755,6 +758,35 @@ std::string GetMethodID(const clang::CXXMethodDecl *decl) {
755758 return decl->getQualifiedNameAsString () + GetID (decl);
756759}
757760
761+ clang::QualType GetTypeForDecl (clang::ASTContext &ctx,
762+ const clang::NamedDecl *decl) {
763+ if (const auto *spec =
764+ llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(decl)) {
765+ llvm::ArrayRef<clang::TemplateArgument> args =
766+ spec->getTemplateArgs ().asArray ();
767+ llvm::SmallVector<clang::TemplateArgument, 4 > canon (args.begin (),
768+ args.end ());
769+ ctx.canonicalizeTemplateArguments (canon);
770+
771+ return ctx.getTemplateSpecializationType (
772+ clang::ElaboratedTypeKeyword::None,
773+ clang::TemplateName (spec->getSpecializedTemplate ()), args, canon);
774+ }
775+
776+ const auto *rdecl = llvm::dyn_cast<clang::TagDecl>(decl);
777+ assert (rdecl && " Unsupported decl type" );
778+
779+ return ctx.getTagType (clang::ElaboratedTypeKeyword::None,
780+ rdecl->getQualifier (), rdecl, /* OwnsTag*/ false );
781+ }
782+
783+ bool HasFunctionParameterPack (const clang::FunctionDecl *decl) {
784+ if (auto *primary = decl->getPrimaryTemplate ()) {
785+ decl = primary->getTemplatedDecl ();
786+ }
787+ return decl->getNumParams () && decl->parameters ().back ()->isParameterPack ();
788+ }
789+
758790std::string DisambiguateAnonymousTag (const clang::TagDecl *tag) {
759791 if (!tag) {
760792 return " " ;
@@ -1462,15 +1494,15 @@ std::optional<clang::QualType> GetParamImplicitConvertTarget(clang::Expr *expr,
14621494}
14631495
14641496std::optional<IteratorCategory>
1465- GetStrongestIteratorCategory (clang::QualType type) {
1497+ GetStrongestIteratorCategory (clang::ASTContext &ctx, clang:: QualType type) {
14661498 type = type.getNonReferenceType ().getUnqualifiedType ();
1467- if (!Mapper::Contains (type)) {
1499+ if (!Mapper::Contains (ctx, type)) {
14681500 return std::nullopt ;
14691501 }
1470- if (Mapper ::MapsToRefcountPointer (type)) {
1502+ if (RuleRegistry ::MapsToRefcountPointer (ctx, type)) {
14711503 return IteratorCategory::Contiguous;
14721504 }
1473- auto mapped = Mapper::Map (type);
1505+ auto mapped = Mapper::Map (ctx, type);
14741506 if (mapped.empty ()) {
14751507 return std::nullopt ;
14761508 }
@@ -1547,15 +1579,17 @@ bool IsBuiltinVaStart(const clang::CallExpr *expr) {
15471579 return false ;
15481580}
15491581
1550- bool NeedsImplicitScalarCast (clang::QualType from, clang::QualType to) {
1582+ bool NeedsImplicitScalarCast (clang::ASTContext &ctx, clang::QualType from,
1583+ clang::QualType to) {
15511584 return !from.isNull () && !to.isNull () && from->isIntegerType () &&
15521585 to->isIntegerType () &&
15531586 from.getCanonicalType ().getUnqualifiedType () ==
15541587 to.getCanonicalType ().getUnqualifiedType () &&
1555- Mapper::Map (from) != Mapper::Map (to);
1588+ Mapper::Map (ctx, from) != Mapper::Map (ctx, to);
15561589}
15571590
1558- bool NeedsRefBindingTemp (const clang::Expr *arg, clang::QualType param_type) {
1591+ bool NeedsRefBindingTemp (clang::ASTContext &ctx, const clang::Expr *arg,
1592+ clang::QualType param_type) {
15591593 if (!param_type->isReferenceType ()) {
15601594 return false ;
15611595 }
@@ -1571,28 +1605,27 @@ bool NeedsRefBindingTemp(const clang::Expr *arg, clang::QualType param_type) {
15711605 // void foo(const size_t &) {} <-- size_t -> usize
15721606 // unsigned long x = 1; foo(x); <-- unsigned long -> u64
15731607 return param_type->getPointeeType ().isConstQualified () &&
1574- NeedsImplicitScalarCast (arg->IgnoreImplicit ()->getType (),
1608+ NeedsImplicitScalarCast (ctx, arg->IgnoreImplicit ()->getType (),
15751609 param_type.getNonReferenceType ());
15761610}
15771611
1578- bool IsSizeType (clang::QualType type) {
1579- auto rust_type = Mapper::Map (type);
1612+ bool IsSizeType (clang::ASTContext &ctx, clang:: QualType type) {
1613+ auto rust_type = Mapper::Map (ctx, type);
15801614 return rust_type == " usize" || rust_type == " isize" ;
15811615}
15821616
1583- std::optional<clang::QualType>
1584- GetOperandImplicitConversionTarget (const clang::BinaryOperator *op,
1585- const clang::Expr *operand,
1586- const clang::Expr *sibling) {
1617+ std::optional<clang::QualType> GetOperandImplicitConversionTarget (
1618+ clang::ASTContext &ctx, const clang::BinaryOperator *op,
1619+ const clang::Expr *operand, const clang::Expr *sibling) {
15871620 if (op->isComparisonOp ()) {
1588- if (NeedsImplicitScalarCast (operand->getType (), sibling->getType ()) &&
1589- IsSizeType (sibling->getType ())) {
1621+ if (NeedsImplicitScalarCast (ctx, operand->getType (), sibling->getType ()) &&
1622+ IsSizeType (ctx, sibling->getType ())) {
15901623 return sibling->getType ();
15911624 }
15921625 return std::nullopt ;
15931626 }
15941627 if ((op->isAdditiveOp () || op->isMultiplicativeOp () || op->isBitwiseOp ()) &&
1595- NeedsImplicitScalarCast (operand->getType (), op->getType ())) {
1628+ NeedsImplicitScalarCast (ctx, operand->getType (), op->getType ())) {
15961629 return op->getType ();
15971630 }
15981631 return std::nullopt ;
0 commit comments