diff --git a/cpp2rust/converter/mapper.cpp b/cpp2rust/converter/mapper.cpp index e0e84c51..c3cc0897 100644 --- a/cpp2rust/converter/mapper.cpp +++ b/cpp2rust/converter/mapper.cpp @@ -391,7 +391,6 @@ decltype(types_)::const_iterator search(clang::QualType qual_type) { } void addRulesFromDirectory(const std::filesystem::path &dir, Model model) { - std::vector paths; for (const auto &entry : std::filesystem::recursive_directory_iterator(dir)) { auto &path = entry.path(); if (entry.is_regular_file() && path.extension() == ".cpp") { @@ -670,7 +669,7 @@ void AddRuleForUserDefinedType(clang::NamedDecl *decl) { break; case Model::kRefCount: types_[cpp_name + " *"] = TranslationRule::TypeTgt::RefcountPtr( - "PtrDyn"); + "PtrDyn'); break; } } else { @@ -681,7 +680,7 @@ void AddRuleForUserDefinedType(clang::NamedDecl *decl) { break; case Model::kRefCount: types_[cpp_name + " *"] = - TranslationRule::TypeTgt::RefcountPtr("Ptr<" + rs_name + ">"); + TranslationRule::TypeTgt::RefcountPtr("Ptr<" + rs_name + '>'); break; } } diff --git a/cpp2rust/converter/translation_rule.cpp b/cpp2rust/converter/translation_rule.cpp index 6350a21a..748bbab7 100644 --- a/cpp2rust/converter/translation_rule.cpp +++ b/cpp2rust/converter/translation_rule.cpp @@ -7,9 +7,15 @@ #include #include #include +#include #include #include #include +#include +#include +#include +#include +#include #include #include #include @@ -29,17 +35,68 @@ namespace cpp2rust::TranslationRule { namespace { +enum LookupKind { RegularName, CXXMethodName, CXXConstructorName, ADL }; + +struct LookupInfo { + clang::DeclarationName name; + LookupKind kind; + llvm::ArrayRef explicitArgs; + + LookupInfo(const clang::Expr *expr) { + if (const auto *ul = llvm::dyn_cast(expr)) { + clang::DeclarationName dname = ul->getName(); + name = dname; + if (ul->requiresADL()) { + kind = LookupKind::ADL; + } else { + kind = LookupKind::RegularName; + } + explicitArgs = ul->template_arguments(); + } else if (const auto *dm = + llvm::dyn_cast(expr)) { + name = dm->getMember(); + kind = LookupKind::CXXMethodName; + explicitArgs = dm->template_arguments(); + } else if (const auto *dref = + llvm::dyn_cast(expr)) { + clang::DeclarationName dname = dref->getDeclName(); + if (name.getNameKind() == + clang::DeclarationName::NameKind::CXXConstructorName) { + name = dname; + kind = LookupKind::CXXConstructorName; + } else { + assert(0 && "Unsupported dref name kind"); + } + } else if (llvm::isa(expr)) { + kind = LookupKind::CXXConstructorName; + } else { + expr->dump(); + assert(0 && "Unsupported lookup expression"); + } + } +}; + using RuleMap = std::unordered_map; class Callback : public clang::ast_matchers::MatchFinder::MatchCallback { public: explicit Callback(RuleMap &out) : out_(out) {} + void setSema(clang::Sema &sema) { sema_ = &sema; } + void run(const clang::ast_matchers::MatchFinder::MatchResult &R) override { - if (auto var = R.Nodes.getNodeAs("tvar")) { + assert(sema_); + if (auto var = R.Nodes.getNodeAs("tvar")) { + clang::QualType type; + if (auto *tdecl = var->getDescribedAliasTemplate()) { + type = lookupType(tdecl); + } else { + type = var->getUnderlyingType(); + } + Rule rule; - rule.src = Mapper::ToString(var->getType()); - out_[var->getNameAsString()] = std::move(rule); + rule.src = Mapper::ToString(type); + out_[var->getQualifiedNameAsString()] = std::move(rule); return; } @@ -51,18 +108,17 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback { out_[sym] = std::move(rule); }; - if (const auto *mcall = - R.Nodes.getNodeAs("mcall")) { - if (mcall->getDirectCallee()) { - add(Mapper::ToString(mcall)); - return; - } - } if (const auto *fcall = R.Nodes.getNodeAs("fcall")) { if (fcall->getDirectCallee()) { add(Mapper::ToString(fcall)); return; } + + LookupInfo lookup(fcall->getCallee()); + clang::NamedDecl *decl = + lookupCalledDecl(func->getDescribedFunctionTemplate(), lookup); + add(Mapper::ToString(decl)); + return; } if (const auto *ctor = R.Nodes.getNodeAs("ctor")) { @@ -98,11 +154,494 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback { add(Mapper::ToString(uop)); return; } + if (const auto *dsme = + R.Nodes.getNodeAs("dsme")) { + if (dsme->isArrow()) { + clang::MemberExpr *expr = lookupArrowAccess( + func->getDescribedFunctionTemplate(), dsme->getMemberNameInfo(), + dsme->getQualifierLoc()); + add(Mapper::ToString(expr)); + return; + } + clang::NamedDecl *decl = lookupMemberAccess( + func->getDescribedFunctionTemplate(), dsme->getMember()); + add(Mapper::ToString(decl)); + return; + } + if (const auto *uctor = + R.Nodes.getNodeAs("uctor")) { + LookupInfo lookup(uctor); + clang::NamedDecl *decl = + lookupCalledDecl(func->getDescribedFunctionTemplate(), lookup); + add(Mapper::ToString(decl)); + return; + } } } private: RuleMap &out_; + clang::Sema *sema_ = nullptr; + + void forceCompleteDefinition(clang::QualType type) { + type = type.getCanonicalType(); + if (type->isPointerType()) { + type = type->getPointeeType(); + } + + if (!type->isIncompleteType()) { + return; + } + + sema_->RequireCompleteType(clang::SourceLocation(), type, + clang::Sema::CompleteTypeKind::Normal, + clang::diag::err_incomplete_type); + + if (auto *spec = + llvm::dyn_cast_or_null( + type->getAsCXXRecordDecl())) { + for (const auto *decl : spec->decls()) { + if (const auto *tdef = llvm::dyn_cast(decl)) { + clang::QualType tdef_t = tdef->getUnderlyingType(); + forceCompleteDefinition(tdef_t); + } + } + + for (const auto &arg : spec->getTemplateArgs().asArray()) { + if (arg.getKind() == clang::TemplateArgument::Type) { + forceCompleteDefinition(arg.getAsType()); + } + } + } + } + + clang::FunctionDecl *deduceTemplateArguments( + clang::FunctionTemplateDecl *decl, llvm::ArrayRef callArgs, + clang::QualType obj_t, clang::Expr::Classification exprClass, + clang::TemplateArgumentListInfo *explicitArgs = nullptr) { + clang::FunctionDecl *spec = nullptr; + clang::sema::TemplateDeductionInfo info((clang::SourceLocation())); + auto check = [](llvm::ArrayRef, bool) -> bool { + return false; + }; + + auto result = sema_->DeduceTemplateArguments( + decl, explicitArgs, callArgs, spec, info, false, false, false, obj_t, + exprClass, false, check); + + if (result == clang::TemplateDeductionResult::Success) { + return spec; + } + + if (result == clang::TemplateDeductionResult::SubstitutionFailure) { + if (const auto *deduced = info.takeCanonical()) { + clang::TemplateArgumentListInfo targsInfo; + for (const auto &arg : deduced->asArray()) { + targsInfo.addArgument( + sema_->getTrivialTemplateArgumentLoc(arg, {}, {}, nullptr)); + } + + clang::DefaultArguments defaultArgs; + clang::Sema::CheckTemplateArgumentInfo ctai; + auto invalid = sema_->CheckTemplateArgumentList( + decl, decl->getTemplateParameters(), clang::SourceLocation(), + targsInfo, defaultArgs, true, ctai); + + if (!invalid) { + return sema_->InstantiateFunctionDeclaration(decl, deduced, + clang::SourceLocation()); + } + } + } + + return nullptr; + } + + clang::NamespaceDecl *createNamespaceDecl() { + auto &ctx = sema_->getASTContext(); + auto *tu = ctx.getTranslationUnitDecl(); + auto *ns = clang::NamespaceDecl::Create( + ctx, tu, false, clang::SourceLocation(), clang::SourceLocation(), + nullptr, nullptr, false); + tu->addDecl(ns); + return ns; + } + + clang::RecordDecl *createRecordDecl(llvm::StringRef name) { + bool owned = true; + bool dependent = false; + clang::CXXScopeSpec scope; + clang::MultiTemplateParamsArg args; + auto decl = sema_->ActOnTag( + sema_->getCurScope(), clang::DeclSpec::TST_struct, + clang::TagUseKind::Definition, clang::SourceLocation(), scope, + &sema_->Context.Idents.get(name), clang::SourceLocation(), + clang::ParsedAttributesView(), clang::AS_none, clang::SourceLocation(), + args, owned, dependent, clang::SourceLocation(), false, + clang::TypeResult(), false, false, clang::OffsetOfKind::Outside, + nullptr); + assert(decl.isUsable() && "Record decl creation failed"); + auto *rdecl = decl.getAs(); + rdecl->startDefinition(); + rdecl->completeDefinition(); + return rdecl; + } + + clang::VarDecl *createVarDecl(clang::QualType type, llvm::StringRef name, + clang::StorageClass sclass = clang::SC_None) { + clang::ASTContext &ctx = sema_->Context; + clang::VarDecl *decl = + clang::VarDecl::Create(ctx, sema_->CurContext, clang::SourceLocation(), + clang::SourceLocation(), &ctx.Idents.get(name), + type.getNonReferenceType(), nullptr, sclass); + sema_->CurContext->addDecl(decl); + decl->markUsed(ctx); + return decl; + } + + clang::DeclRefExpr *createDeclRefExpr(clang::VarDecl *decl) { + return clang::DeclRefExpr::Create( + sema_->Context, clang::NestedNameSpecifierLoc(), + clang::SourceLocation(), decl, false, clang::SourceLocation(), + decl->getType().getCanonicalType(), clang::VK_LValue); + } + + clang::DeclRefExpr *createConstexprDeclRefExpr(clang::QualType type, + llvm::StringRef name) { + clang::VarDecl *decl = createVarDecl(type, name, clang::SC_Static); + decl->setConstexpr(true); + + clang::Expr *init; + clang::ASTContext &ctx = sema_->Context; + if (type->isIntegerType()) { + init = clang::IntegerLiteral::Create(ctx, llvm::APInt(1, 1), type, {}); + } else { + init = new (ctx) clang::ImplicitValueInitExpr(type); + } + decl->setInit(init); + return createDeclRefExpr(decl); + } + + clang::OpaqueValueExpr *createOpaqueValueExpr(clang::QualType type) { + return new (sema_->Context) clang::OpaqueValueExpr( + {}, type.getNonReferenceType(), + type->isRValueReferenceType() ? clang::VK_XValue : clang::VK_LValue); + } + + void + createTemplateArguments(clang::TemplateDecl *decl, + llvm::SmallVectorImpl &out) { + for (clang::NamedDecl *param : *decl->getTemplateParameters()) { + if (llvm::isa(param)) { + clang::RecordDecl *rdecl = createRecordDecl(param->getName()); + clang::QualType type = sema_->Context.getTagType( + clang::ElaboratedTypeKeyword::None, {}, rdecl, false); + out.emplace_back(type); + } else if (const auto *nttp = + llvm::dyn_cast(param)) { + clang::QualType type = nttp->getType(); + clang::DeclRefExpr *var = + createConstexprDeclRefExpr(type, param->getName()); + out.emplace_back(var, true); + } else { + assert(0 && "Unsupported template param kind"); + } + } + } + + clang::FunctionDecl *instantiateRuleDecl(clang::FunctionTemplateDecl *decl) { + llvm::SmallVector args; + createTemplateArguments(decl, args); + return sema_->InstantiateFunctionDeclaration( + decl, clang::TemplateArgumentList::CreateCopy(sema_->Context, args), + clang::SourceLocation()); + } + + clang::FunctionDecl *createCandidate( + clang::NamedDecl *decl, llvm::ArrayRef callArgs, + clang::TemplateArgumentListInfo *explicitArgs = nullptr, + clang::QualType obj_t = clang::QualType(), + clang::Expr::Classification eclass = clang::Expr::Classification()) { + if (auto *tdecl = llvm::dyn_cast(decl)) { + if (auto *fdecl = deduceTemplateArguments(tdecl, callArgs, obj_t, eclass, + explicitArgs)) { + return fdecl; + } + return nullptr; + } + return llvm::dyn_cast(decl); + } + + clang::CXXRecordDecl *resolveCXXRecordDecl(clang::QualType obj_t) { + obj_t = obj_t.getCanonicalType(); + if (obj_t->isReferenceType()) { + obj_t = obj_t.getNonReferenceType(); + } + + forceCompleteDefinition(obj_t); + if (auto *rdecl = obj_t->getAsCXXRecordDecl()) { + return rdecl->getDefinition(); + } + return nullptr; + } + + void regularNameLookup(llvm::ArrayRef callArgs, + clang::TemplateArgumentListInfo *explicitTArgs, + clang::DeclarationName &name, + clang::OverloadCandidateSet &candidates) { + clang::LookupResult decls(*sema_, name, clang::SourceLocation(), + clang::Sema::LookupOrdinaryName); + sema_->LookupQualifiedName(decls, sema_->getStdNamespace()); + for (auto *ndecl : decls) { + if (auto *candidate = createCandidate(ndecl, callArgs, explicitTArgs)) { + sema_->AddOverloadCandidate( + candidate, clang::DeclAccessPair::make(candidate, clang::AS_public), + callArgs, candidates, false); + } + } + + for (const auto *arg : callArgs) { + if (auto *rdecl = resolveCXXRecordDecl(arg->getType())) { + for (auto *frdecl : rdecl->friends()) { + auto *fd = frdecl->getFriendDecl(); + if (!fd) { + continue; + } + + if (auto *ndecl = llvm::dyn_cast(fd); + ndecl && ndecl->getDeclName() == name) { + if (auto *candidate = + createCandidate(ndecl, callArgs, explicitTArgs)) { + sema_->AddOverloadCandidate( + candidate, + clang::DeclAccessPair::make(candidate, clang::AS_public), + callArgs, candidates, false); + } + } + } + } + } + } + + void cxxMethodNameLookup(clang::QualType obj_t, + llvm::ArrayRef callArgs, + clang::TemplateArgumentListInfo *explicitTArgs, + clang::DeclarationName &name, + clang::OverloadCandidateSet &candidates) { + clang::CXXRecordDecl *rdecl = resolveCXXRecordDecl(obj_t); + assert(rdecl && "Failed fetching record decl"); + clang::LookupResult members(*sema_, name, clang::SourceLocation(), + clang::Sema::LookupMemberName); + sema_->LookupQualifiedName(members, rdecl); + + auto eclass = clang::Expr::Classification::makeSimpleLValue(); + for (auto *ndecl : members) { + if (auto *candidate = + createCandidate(ndecl, callArgs, explicitTArgs, obj_t, eclass)) { + sema_->AddMethodCandidate( + clang::DeclAccessPair::make(candidate, clang::AS_public), obj_t, + eclass, callArgs, candidates); + } + } + } + + void cxxConstructorNameLookup(clang::QualType obj_t, + llvm::ArrayRef callArgs, + clang::OverloadCandidateSet &candidates) { + clang::CXXRecordDecl *rdecl = resolveCXXRecordDecl(obj_t); + assert(rdecl && "Failed fetching record decl"); + clang::DeclContextLookupResult ctors = sema_->LookupConstructors(rdecl); + + for (auto *ndecl : ctors) { + if (auto *candidate = createCandidate(ndecl, callArgs)) { + sema_->AddOverloadCandidate( + candidate, clang::DeclAccessPair::make(candidate, clang::AS_public), + callArgs, candidates, false); + } + } + } + + void adlLookup(llvm::ArrayRef callArgs, + clang::DeclarationName &name, + clang::OverloadCandidateSet &candidates) { + clang::ADLResult adl; + sema_->ArgumentDependentLookup(name, {}, callArgs, adl); + + for (auto *ndecl : adl) { + if (auto *candidate = createCandidate(ndecl, callArgs)) { + sema_->AddOverloadCandidate( + candidate, clang::DeclAccessPair::make(candidate, clang::AS_public), + callArgs, candidates, false); + } + } + } + + clang::FunctionDecl *lookupCalledDecl(clang::FunctionTemplateDecl *decl, + LookupInfo &lookup) { + clang::NamespaceDecl *ns = createNamespaceDecl(); + clang::Sema::ContextRAII savedContext(*sema_, ns); + clang::FunctionDecl *rule = instantiateRuleDecl(decl); + llvm::ArrayRef parms = rule->parameters(); + auto csk = lookup.name.getNameKind() == + clang::DeclarationName::NameKind::CXXOperatorName + ? clang::OverloadCandidateSet::CSK_Operator + : clang::OverloadCandidateSet::CSK_Normal; + + llvm::SmallVector callArgs; + for (const auto *parm : parms) { + clang::QualType parm_t = parm->getType(); + forceCompleteDefinition(parm_t); + callArgs.emplace_back(createOpaqueValueExpr(parm_t)); + } + + llvm::ArrayRef ruleTArgs = + rule->getTemplateSpecializationArgs()->asArray(); + clang::TemplateArgumentListInfo explicitTArgs; + for (const auto &argloc : lookup.explicitArgs) { + const auto &arg = argloc.getArgument(); + if (!arg.isDependent()) { + explicitTArgs.addArgument(argloc); + continue; + } + + clang::TemplateArgument inst; + if (arg.getKind() == clang::TemplateArgument::Type) { + clang::QualType type = arg.getAsType(); + clang::MultiLevelTemplateArgumentList mtal(nullptr, ruleTArgs, false); + mtal.setKind(clang::TemplateSubstitutionKind::Rewrite); + clang::TypeSourceInfo *tsi = + sema_->SubstType(sema_->Context.getTrivialTypeSourceInfo(type), + mtal, {}, clang::DeclarationName()); + assert(tsi && "Template argument type instantiation failed"); + inst = clang::TemplateArgument(tsi->getType()); + } else if (arg.getKind() == clang::TemplateArgument::Expression) { + if (auto *expr = llvm::dyn_cast(arg.getAsExpr())) { + const auto *nttp = + llvm::dyn_cast(expr->getDecl()); + assert(nttp && "Unexpected decl in expr"); + inst = ruleTArgs[nttp->getIndex()]; + } else { + assert(0 && "Unsupported explicit template argument expression"); + } + } else { + assert(0 && "Unsupported explicit template argument kind"); + } + + explicitTArgs.addArgument( + sema_->getTrivialTemplateArgumentLoc(inst, {}, {}, nullptr)); + } + + clang::DeclarationName &name = lookup.name; + clang::OverloadCandidateSet candidates(clang::SourceLocation(), csk); + switch (lookup.kind) { + case LookupKind::RegularName: + regularNameLookup(callArgs, &explicitTArgs, name, candidates); + break; + case LookupKind::CXXMethodName: { + llvm::ArrayRef margs = callArgs; + cxxMethodNameLookup(margs.front()->getType().getNonReferenceType(), + margs.drop_front(), &explicitTArgs, name, candidates); + break; + } + case LookupKind::CXXConstructorName: + cxxConstructorNameLookup(rule->getReturnType(), callArgs, candidates); + break; + case LookupKind::ADL: + adlLookup(callArgs, name, candidates); + break; + } + + clang::OverloadCandidateSet::iterator best; + switch ( + candidates.BestViableFunction(*sema_, clang::SourceLocation(), best)) { + case clang::OverloadingResult::OR_Success: + return best->Function; + case clang::OverloadingResult::OR_Ambiguous: + for (auto &candidate : candidates) { + if (candidate.Viable) { + return candidate.Function; + } + } + break; + case clang::OverloadingResult::OR_No_Viable_Function: + llvm::errs() << "No viable function\n"; + break; + case clang::OverloadingResult::OR_Deleted: + llvm::errs() << "Deleted function selected\n"; + break; + } + + assert(0 && "Rule resolution failed"); + return nullptr; + } + + clang::NamedDecl *lookupMemberAccess(clang::FunctionTemplateDecl *decl, + clang::DeclarationName name) { + clang::NamespaceDecl *ns = createNamespaceDecl(); + clang::Sema::ContextRAII savedContext(*sema_, ns); + clang::FunctionDecl *rule = instantiateRuleDecl(decl); + clang::CXXRecordDecl *rdecl = + resolveCXXRecordDecl(rule->getParamDecl(0)->getType()); + assert(rdecl && "Failed fetching record decl"); + clang::LookupResult members(*sema_, name, clang::SourceLocation(), + clang::Sema::LookupMemberName); + sema_->LookupQualifiedName(members, rdecl); + assert(!members.empty() && "Rule resolution failed"); + return members.getRepresentativeDecl(); + } + + clang::MemberExpr * + lookupArrowAccess(clang::FunctionTemplateDecl *decl, + const clang::DeclarationNameInfo &nameInfo, + clang::NestedNameSpecifierLoc nns) { + clang::NamespaceDecl *ns = createNamespaceDecl(); + clang::Sema::ContextRAII savedContext(*sema_, ns); + clang::FunctionDecl *rule = instantiateRuleDecl(decl); + + clang::Expr *obj = createOpaqueValueExpr( + rule->getParamDecl(0)->getType().getNonReferenceType()); + auto arrow = sema_->BuildOverloadedArrowExpr(sema_->getCurScope(), obj, + clang::SourceLocation()); + assert(arrow.isUsable() && "Overloaded arrow operator not found"); + + auto *base = arrow.getAs(); + assert(base && "Unexpected base type"); + + clang::CXXRecordDecl *rdecl = + resolveCXXRecordDecl(base->getType()->getPointeeType()); + assert(rdecl && "Failed fetching record decl"); + + clang::LookupResult members(*sema_, nameInfo.getName(), + clang::SourceLocation(), + clang::Sema::LookupMemberName); + sema_->LookupQualifiedName(members, rdecl); + for (auto *ndecl : members) { + if (auto *vdecl = llvm::dyn_cast(ndecl)) { + clang::MemberExpr *access = sema_->BuildMemberExpr( + base, true, clang::SourceLocation(), nns, clang::SourceLocation(), + vdecl, clang::DeclAccessPair::make(vdecl, clang::AS_public), false, + nameInfo, vdecl->getType(), clang::VK_LValue, clang::OK_Ordinary); + assert(access && "Rule resolution failed"); + return access; + } + } + assert(0 && "Rule resolution failed"); + return nullptr; + } + + clang::QualType lookupType(clang::TypeAliasTemplateDecl *decl) { + clang::NamespaceDecl *ns = createNamespaceDecl(); + clang::Sema::ContextRAII savedContext(*sema_, ns); + llvm::SmallVector args; + createTemplateArguments(decl, args); + + clang::MultiLevelTemplateArgumentList mtal(nullptr, args, false); + clang::TypeSourceInfo *tsi = + sema_->SubstType(decl->getTemplatedDecl()->getTypeSourceInfo(), mtal, + {}, clang::DeclarationName()); + assert(tsi && "Rule resolution failed"); + return tsi->getType(); + } }; class ActionFactory : public clang::tooling::FrontendActionFactory { @@ -113,9 +652,7 @@ class ActionFactory : public clang::tooling::FrontendActionFactory { returnStmt( isExpansionInMainFile(), hasReturnValue(ignoringImplicit(ignoringParenImpCasts(anyOf( - cxxMemberCallExpr().bind("mcall"), - callExpr(unless(cxxMemberCallExpr())).bind("fcall"), - cxxConstructExpr().bind("ctor"), + callExpr().bind("fcall"), cxxConstructExpr().bind("ctor"), cxxFunctionalCastExpr(has(ignoringImplicit( ignoringParenImpCasts(cxxConstructExpr().bind("ctor"))))), memberExpr(hasDeclaration(fieldDecl())).bind("muse"), @@ -125,36 +662,61 @@ class ActionFactory : public clang::tooling::FrontendActionFactory { .bind("declref"), unaryOperator(hasUnaryOperand( declRefExpr(to(decl(unless(parmVarDecl())))))) - .bind("udeclref"))))), + .bind("udeclref"), + cxxDependentScopeMemberExpr().bind("dsme"), + cxxUnresolvedConstructExpr().bind("uctor"))))), hasAncestor(functionDecl(isDefinition(), matchesName("(^|::)f[0-9]+$"), isExpansionInMainFile()) .bind("func"))), &cb_); - finder_.addMatcher(varDecl(hasGlobalStorage(), isExpansionInMainFile(), - matchesName("(^|::)t[0-9]+$")) - .bind("tvar"), - &cb_); + finder_.addMatcher( + typeAliasDecl(matchesName("(^|::)t[0-9]+$"), isExpansionInMainFile()) + .bind("tvar"), + &cb_); } std::unique_ptr create() override { + class ASTConsumer : public clang::ASTConsumer { + public: + explicit ASTConsumer(std::unique_ptr AC, + clang::CompilerInstance &CI, Callback *CB) + : AC_(std::move(AC)), CI_(&CI), CB_(CB) {} + + void HandleTranslationUnit(clang::ASTContext &ctx) override { + auto &DE = CI_->getDiagnostics(); + DE.setSuppressAllDiagnostics(true); + DE.setClient(new clang::IgnoringDiagConsumer(), true); + CB_->setSema(CI_->getSema()); + AC_->HandleTranslationUnit(ctx); + } + + private: + std::unique_ptr AC_; + clang::CompilerInstance *CI_; + Callback *CB_; + }; + class Wrapped : public clang::ASTFrontendAction { clang::ast_matchers::MatchFinder &F_; + Callback *CB_; public: - explicit Wrapped(clang::ast_matchers::MatchFinder &MF) : F_(MF) {} + explicit Wrapped(clang::ast_matchers::MatchFinder &MF, Callback &CB) + : F_(MF), CB_(&CB) {} + std::unique_ptr - CreateASTConsumer(clang::CompilerInstance &, llvm::StringRef) override { - return F_.newASTConsumer(); + CreateASTConsumer(clang::CompilerInstance &CI, llvm::StringRef) override { + return std::make_unique(F_.newASTConsumer(), CI, CB_); } }; - return std::make_unique(finder_); + return std::make_unique(finder_, cb_); } private: - Callback cb_; clang::ast_matchers::MatchFinder finder_; + Callback cb_; }; TextFragment ParseTextFragmentJSON(const llvm::json::Object &obj) { @@ -488,6 +1050,15 @@ std::vector Load(const std::filesystem::path &path, Model model) { std::vector result; for (auto &[name, rule] : rules) { + if (rule.src.empty()) { + llvm::errs() << name << '\n'; + if (const auto *tgt = std::get_if(&rule.tgt)) { + tgt->dump(); + } + if (const auto *tgt = std::get_if(&rule.tgt)) { + tgt->dump(); + } + } assert(!rule.src.empty() && "Rule loaded from IR but has no src"); result.push_back(std::move(rule)); } diff --git a/rules/algorithm/src.cpp b/rules/algorithm/src.cpp index 1efa943c..097b05cb 100644 --- a/rules/algorithm/src.cpp +++ b/rules/algorithm/src.cpp @@ -79,227 +79,68 @@ struct T1 { T1 &operator=(const T2 &rhs) { return *this; } }; -template void f1(RandomIt first, RandomIt last) { +template void f1(T1 first, T1 last) { return std::sort(first, last); } -template void f1(T1, T1); - -struct T3 { - using iterator_category = std::input_iterator_tag; - using value_type = int; - using difference_type = std::ptrdiff_t; - using pointer = const int *; - using reference = const int &; - - pointer p{}; - - T3() = default; - explicit T3(pointer q) : p(q) {} - - reference operator*() const { return *p; } - T3 &operator++() { - ++p; - return *this; - } - T3 operator++(int) { - T3 tmp(*this); - ++(*this); - return tmp; - } - - friend bool operator==(const T3 &a, const T3 &b) { return a.p == b.p; } - friend bool operator!=(const T3 &a, const T3 &b) { return !(a == b); } -}; - -struct T4 { - using iterator_category = std::output_iterator_tag; - using value_type = void; - using difference_type = std::ptrdiff_t; - using pointer = int *; - using reference = int &; - - pointer p{}; - - T4() = default; - explicit T4(pointer q) : p(q) {} - - reference operator*() const { return *p; } - T4 &operator++() { - ++p; - return *this; - } - T4 operator++(int) { - T4 tmp(*this); - ++(*this); - return tmp; - } - - friend bool operator==(const T4 &a, const T4 &b) { return a.p == b.p; } - friend bool operator!=(const T4 &a, const T4 &b) { return !(a == b); } -}; - -template -OutputIt f2(InputIt first, InputIt last, OutputIt d_first) { +template T2 f2(T1 first, T1 last, T2 d_first) { return std::copy(first, last, d_first); } -template T4 f2(T3, T3, T4); - -struct T6 { - friend bool operator==(T6 a, T6 b) { return true; } -}; - -struct T5 { - using value_type = T6; - using difference_type = std::ptrdiff_t; - using reference = T6 &; - using pointer = T6 *; - using iterator_category = std::random_access_iterator_tag; - - pointer p = nullptr; - - T5() = default; - - reference operator*() const { return *p; } - pointer operator->() const { return p; } - reference operator[](difference_type n) const { return p[n]; } - - T5 &operator++() { - ++p; - return *this; - } - T5 operator++(int) { - T5 tmp = *this; - ++*this; - return tmp; - } - T5 &operator--() { - --p; - return *this; - } - T5 operator--(int) { - T5 tmp = *this; - --*this; - return tmp; - } - - T5 &operator+=(difference_type n) { - p += n; - return *this; - } - T5 &operator-=(difference_type n) { - p -= n; - return *this; - } - friend T5 operator+(T5 it, difference_type n) { - it += n; - return it; - } - friend T5 operator+(difference_type n, T5 it) { - it += n; - return it; - } - friend T5 operator-(T5 it, difference_type n) { - it -= n; - return it; - } - friend difference_type operator-(T5 a, T5 b) { return a.p - b.p; } - - friend bool operator==(T5 a, T5 b) { return a.p == b.p; } - friend bool operator!=(T5 a, T5 b) { return a.p != b.p; } - friend bool operator<(T5 a, T5 b) { return a.p < b.p; } - friend bool operator>(T5 a, T5 b) { return a.p > b.p; } - friend bool operator<=(T5 a, T5 b) { return a.p <= b.p; } - friend bool operator>=(T5 a, T5 b) { return a.p >= b.p; } -}; - -template -InputIt f3(InputIt first, InputIt last, const T &value) { +template T1 f3(T1 first, T1 last, const T2 &value) { return std::find(first, last, value); } -template T5 f3(T5, T5, const T6 &); - -template -void f6(RandomIt first, RandomIt last, Compare comp) { +// TODO +auto lambda = [](const T2 &a, const T2 &b) { return false; }; +void f6(T1 first, T1 last, decltype(lambda) comp) { return std::stable_sort(first, last, comp); } -auto lambda = [](const T2 &a, const T2 &b) { return false; }; - -template void f6(T1, T1, decltype(lambda)); - -template -void f7(RandomIt first, RandomIt last, Compare comp) { +template +void f7(T1 first, T1 last, bool (*comp)(const T2 &, const T2 &)) { return std::stable_sort(first, last, comp); } -bool f(const T2 &a, const T2 &b) { return false; }; - -template void f7(T1, T1, decltype(f)); - -template T *f8(T *first, T *last) { +template T1 *f8(T1 *first, T1 *last) { return std::max_element(first, last); } -template T1 *f8(T1 *, T1 *); - -template void f9(T &a0, T &a1) { return std::swap(a0, a1); } - -template void f9(T1 &, T1 &); +template void f9(T1 &a0, T1 &a1) { return std::swap(a0, a1); } -template -typename std::vector::iterator f10(typename std::vector::iterator a0, - typename std::vector::iterator a1) { +template +typename std::vector::iterator f10(typename std::vector::iterator a0, + typename std::vector::iterator a1) { return std::unique(a0, a1); } -template std::vector::iterator f10(std::vector::iterator, - std::vector::iterator); - template void f12(typename std::vector::iterator a0, typename std::vector::iterator a1, const T2 &a2) { return std::fill(a0, a1, a2); } -template void f12(std::vector::iterator, std::vector::iterator, - const T2 &); - std::ostream_iterator f13(std::string::iterator a0, std::string::iterator a1, std::ostream_iterator a2) { return std::copy(a0, a1, a2); } -template -void f14(RandomIt first, RandomIt last, Compare comp) { +// TODO +auto lambda_nref = [](T2 a, T2 b) { return false; }; +void f14(T1 *first, T1 *last, decltype(lambda_nref) comp) { return std::stable_sort(first, last, comp); } -auto lambda_nref = [](T2 a, T2 b) { return false; }; - -template void f14(T1 *, T1 *, - decltype(lambda_nref)); - -template -void f15(RandomIt first, RandomIt last, Compare comp) { +template +void f15(T1 *first, T1 *last, bool (*comp)(T2, T2)) { return std::stable_sort(first, last, comp); } -bool f_nref(T2 a, T2 b) { return false; }; - -template void f15(T1 *, T1 *, decltype(f_nref)); - -template const T &f16(const T &a, const T &b) { +template const T1 &f16(const T1 &a, const T1 &b) { return std::min(a, b); } -template const T2 &f16(const T2 &, const T2 &); - -template const T &f17(const T &a, const T &b) { +template const T1 &f17(const T1 &a, const T1 &b) { return std::max(a, b); } - -template const T2 &f17(const T2 &, const T2 &); diff --git a/rules/array/src.cpp b/rules/array/src.cpp index 5cc52c40..7c2cdcd2 100644 --- a/rules/array/src.cpp +++ b/rules/array/src.cpp @@ -3,23 +3,19 @@ #include -struct T1 {}; -constexpr std::size_t DUMMY_SIZE = 0x0b57ac1e; +template +using t1 = std::array; -std::array t1; - -template const T *f1(const std::array &o) { +template +const T1 *f1(const std::array &o) { return o.data(); } -template const T1 *f1(const std::array &); - -template std::size_t f2(const std::array &o) { +template +std::size_t f2(const std::array &o) { return o.size(); } -template std::size_t f2(const std::array &); - -template T *f3(std::array &o) { return o.data(); } - -template T1 *f3(std::array &); +template T1 *f3(std::array &o) { + return o.data(); +} diff --git a/rules/brotli/src.cpp b/rules/brotli/src.cpp index 8afc8bf0..57226b55 100644 --- a/rules/brotli/src.cpp +++ b/rules/brotli/src.cpp @@ -4,10 +4,10 @@ #include "brotli/decode.h" #include "brotli/encode.h" -BrotliDecoderResult t1; -BrotliEncoderMode t2; -BrotliDecoderStateStruct *t3; -const BrotliDecoderStateStruct *t4; +using t1 = BrotliDecoderResult; +using t2 = BrotliEncoderMode; +using t3 = BrotliDecoderStateStruct *; +using t4 = const BrotliDecoderStateStruct *; BrotliEncoderMode f1() { return BROTLI_MODE_FONT; } diff --git a/rules/carray/src.cpp b/rules/carray/src.cpp index 150bd0a7..bc9100f6 100644 --- a/rules/carray/src.cpp +++ b/rules/carray/src.cpp @@ -3,9 +3,5 @@ #include -struct T1 {}; - -constexpr size_t DUMMY_SIZE = 1; - -T1 t1[DUMMY_SIZE][DUMMY_SIZE]; -T1 t2[DUMMY_SIZE][DUMMY_SIZE][DUMMY_SIZE]; +template using t1 = T1[T2][T2]; +template using t2 = T1[T2][T2][T2]; diff --git a/rules/deque/src.cpp b/rules/deque/src.cpp index 5d155527..b7c1bac3 100644 --- a/rules/deque/src.cpp +++ b/rules/deque/src.cpp @@ -4,35 +4,21 @@ #include #include -struct T1 {}; +template using t1 = std::deque; -std::deque t1; +template T1 &f1(std::deque &o) { return o.back(); } -template T &f1(std::deque &o) { return o.back(); } +template T1 &f2(std::deque &o) { return o.front(); } -template T1 &f1(std::deque &); +template bool f3(const std::deque &o) { return o.empty(); } -template T &f2(std::deque &o) { return o.front(); } - -template T1 &f2(std::deque &); - -template bool f3(const std::deque &o) { return o.empty(); } - -template bool f3(const std::deque &); - -template void f4(std::deque &o, T &&value) { +template void f4(std::deque &o, T1 &&value) { return o.push_back(std::move(value)); } -template void f4(std::deque &, T1 &&); +template void f5(std::deque &o) { return o.pop_front(); } -template void f5(std::deque &o) { return o.pop_front(); } - -template void f5(std::deque &); - -template -void f7(std::deque> &o, const std::vector &value) { +template +void f7(std::deque> &o, const std::vector &value) { return o.push_back(value); } - -template void f7(std::deque> &, const std::vector &); diff --git a/rules/fstream/src.cpp b/rules/fstream/src.cpp index 13cc14dc..5627ad79 100644 --- a/rules/fstream/src.cpp +++ b/rules/fstream/src.cpp @@ -5,47 +5,39 @@ #include #include -struct T1 {}; - -std::ifstream t1; -std::ofstream t2(""); -std::ostream_iterator t3{std::cout}; +using t1 = std::ifstream; +using t2 = std::ofstream; +using t3 = std::ostream_iterator; std::ofstream f1(const char *filename, std::ios_base::openmode mode) { return std::ofstream(filename, mode); } -template std::ostream_iterator f2(std::ostream_iterator a0) { - return a0; +template +std::ostream_iterator f2(const std::ostream_iterator &a0) { + return std::ostream_iterator(a0); } -template std::ostream_iterator f2(std::ostream_iterator); - -template std::ostream_iterator f3(std::ostream &a0) { - return std::ostream_iterator(a0); +template std::ostream_iterator f3(std::ostream &a0) { + return std::ostream_iterator(a0); } -template std::ostream_iterator f3(std::ostream &); - std::filebuf *f4(const std::ifstream &o) { return o.rdbuf(); } std::ifstream f5(const char *filename, std::ios_base::openmode mode) { return std::ifstream(filename, mode); } -template std::istream_iterator f6(std::istream_iterator a0) { - return a0; +template +std::istream_iterator f6(const std::istream_iterator &a0) { + return std::istream_iterator(a0); } -template std::istream_iterator f6(std::istream_iterator); - -template -std::istreambuf_iterator f7(std::istreambuf_iterator a0) { - return a0; +template +std::istreambuf_iterator f7(std::istreambuf_iterator &a0) { + return std::istreambuf_iterator(a0); } -template std::istreambuf_iterator f7(std::istreambuf_iterator); - std::istreambuf_iterator f8(std::basic_streambuf *p) { return std::istreambuf_iterator(p); } diff --git a/rules/initializer_list/src.cpp b/rules/initializer_list/src.cpp index 0b12192a..e77e85e8 100644 --- a/rules/initializer_list/src.cpp +++ b/rules/initializer_list/src.cpp @@ -3,14 +3,9 @@ #include -struct T1 {}; +template using t1 = std::initializer_list; -std::initializer_list t1; - -template -typename std::initializer_list::size_type f1(std::initializer_list &o) { +template +typename std::initializer_list::size_type f1(std::initializer_list &o) { return o.size(); } - -template std::initializer_list::size_type -f1(std::initializer_list &); diff --git a/rules/iostream/src.cpp b/rules/iostream/src.cpp index 23856df6..bec87ff6 100644 --- a/rules/iostream/src.cpp +++ b/rules/iostream/src.cpp @@ -3,9 +3,9 @@ #include -std::ostream t1(std::cout.rdbuf()); -std::ostream &t2 = t1; -std::ostream *t3 = &t1; +using t1 = std::ostream; +using t2 = std::ostream &; +using t3 = std::ostream *; std::ostream &f1() { return std::cout; } diff --git a/rules/limits/src.cpp b/rules/limits/src.cpp index 227e682d..66f00d68 100644 --- a/rules/limits/src.cpp +++ b/rules/limits/src.cpp @@ -3,12 +3,6 @@ #include -struct T1 {}; +template T1 f1(std::numeric_limits &a0) { return a0.max(); } -template T f1() { return std::numeric_limits::max(); } - -template T1 f1(); - -template T f2() { return std::numeric_limits::min(); } - -template T1 f2(); +template T1 f2(std::numeric_limits &a0) { return a0.min(); } diff --git a/rules/map/src.cpp b/rules/map/src.cpp index 27a6e4bd..2ab0aa1a 100644 --- a/rules/map/src.cpp +++ b/rules/map/src.cpp @@ -4,163 +4,116 @@ #include #include -struct T1 { - friend bool operator<(const T1 &a, const T1 &b) noexcept { return true; } -}; -struct T2 {}; +template using t1 = std::map; -std::map t1; -std::map::const_iterator t2; -std::map::iterator t3; +template +using t2 = typename std::map::const_iterator; -template V &f1(std::map &o, const K &key) { - return o[key]; -} +template +using t3 = typename std::map::iterator; -template T2 &f1(std::map &, const T1 &); +template T2 &f1(std::map &o, const T1 &key) { + return o.operator[](key); +} -template std::size_t f2(const std::map &o) { +template std::size_t f2(const std::map &o) { return o.size(); } -template std::size_t f2(const std::map &); - -template -typename std::map::iterator f3(std::map &o, - typename std::map::iterator it) { +template +typename std::map::iterator f3(std::map &o, + typename std::map::iterator it) { return o.erase(it); } -template std::map::iterator f3(std::map &, - std::map::iterator); - -template std::map f5() { - return std::map(); +template std::map f5() { + return std::map(); } -template std::map f5(); - -template std::map f6(std::map &o) { - return o; +template +std::map f6(const std::map &&o) { + return std::map(std::move(o)); } -template std::map f6(std::map &); - -template V &f7(std::map &o, const K &key) { +template T2 &f7(std::map &o, const T1 &key) { return o.at(key); } -template T2 &f7(std::map &, const T1 &); - -template V &f8(std::map &o, K &&key) { - return o[std::move(key)]; +template T2 &f8(std::map &o, T1 &&key) { + return o.operator[](std::move(key)); } -template T2 &f8(std::map &, T1 &&); - -template -typename std::map::const_iterator f9(const std::map &o) { +template +typename std::map::const_iterator f9(const std::map &o) { return o.end(); } -template std::map::const_iterator f9(const std::map &); - -template -typename std::map::iterator f10(std::map &o, const K &key) { +template +typename std::map::iterator f10(std::map &o, const T1 &key) { return o.find(key); } -template std::map::iterator f10(std::map &, const T1 &); - -template -bool f11(typename std::map::iterator a, - typename std::map::iterator b) { - return a != b; +template +bool f11(typename std::map::iterator a, + typename std::map::iterator b) { + return operator!=(a, b); } -template bool f11(std::map::iterator, - std::map::iterator); - -template -typename std::map::iterator f12(std::map &o) { +template +typename std::map::iterator f12(std::map &o) { return o.begin(); } -template std::map::iterator f12(std::map &); - -template -bool f13(typename std::map::const_iterator a, - typename std::map::const_iterator b) { - return a == b; +template +bool f13(typename std::map::const_iterator a, + typename std::map::const_iterator b) { + return operator==(a, b); } -template bool f13(std::map::const_iterator, - std::map::const_iterator); - -template -typename std::map::iterator f14(std::map &o) { +template +typename std::map::iterator f14(std::map &o) { return o.end(); } -template std::map::iterator f14(std::map &); - -template -const V &f15(const std::map &o, const K &key) { +template +const T2 &f15(const std::map &o, const T1 &key) { return o.at(key); } -template const T2 &f15(const std::map &, const T1 &); - -template -bool f16(typename std::map::iterator a, - typename std::map::iterator b) { - return a == b; +template +bool f16(typename std::map::iterator a, + typename std::map::iterator b) { + return operator==(a, b); } -template bool f16(std::map::iterator, - std::map::iterator); - -template -typename std::map::const_iterator f17(const std::map &o, - const K &key) { +template +typename std::map::const_iterator f17(const std::map &o, + const T1 &key) { return o.find(key); } -template std::map::const_iterator f17(const std::map &, - const T1 &); - -template -typename std::map::const_iterator -f19(typename std::map::iterator it) { - return it; +template +typename std::map::const_iterator +f19(const typename std::map::iterator &it) { + return typename std::map::const_iterator(it); } -template std::map::const_iterator - f19(std::map::iterator); - -template -const K &f20(typename std::map::const_iterator it) { +template +const T1 &f20(typename std::map::const_iterator it) { return it->first; } -template const T1 &f20(std::map::const_iterator); - -template -const V &f21(typename std::map::const_iterator it) { +template +const T2 &f21(typename std::map::const_iterator it) { return it->second; } -template const T2 &f21(std::map::const_iterator); - -template -const K &f22(typename std::map::iterator it) { +template +const T1 &f22(typename std::map::iterator it) { return it->first; } -template const T1 &f22(std::map::iterator); - -template V &f23(typename std::map::iterator it) { +template +T2 &f23(typename std::map::iterator it) { return it->second; } - -template T2 &f23(std::map::iterator); diff --git a/rules/pair/ir_refcount.json b/rules/pair/ir_refcount.json index e9a267ec..cc529999 100644 --- a/rules/pair/ir_refcount.json +++ b/rules/pair/ir_refcount.json @@ -224,97 +224,6 @@ "type": "(Value, Value)" } }, - "f3": { - "body": [ - { - "text": "(\n Rc::new(RefCell::new(" - }, - { - "method_call": { - "receiver": [ - { - "method_call": { - "receiver": [ - { - "placeholder": { - "arg": "a0", - "access": "read" - } - }, - { - "text": ".0" - } - ], - "body": [ - { - "text": ".borrow()" - } - ] - } - } - ], - "body": [ - { - "text": ".clone()" - } - ] - } - }, - { - "text": ")),\n Rc::new(RefCell::new(" - }, - { - "method_call": { - "receiver": [ - { - "method_call": { - "receiver": [ - { - "placeholder": { - "arg": "a0", - "access": "read" - } - }, - { - "text": ".1" - } - ], - "body": [ - { - "text": ".borrow()" - } - ] - } - } - ], - "body": [ - { - "text": ".clone()" - } - ] - } - }, - { - "text": ")),\n )" - } - ], - "generics": { - "T1": [ - "Clone" - ], - "T2": [ - "Clone" - ] - }, - "params": { - "a0": { - "type": "(Value, Value)" - } - }, - "return_type": { - "type": "(Value, Value)" - } - }, "f4": { "body": [ { diff --git a/rules/pair/ir_unsafe.json b/rules/pair/ir_unsafe.json index 8afa27f4..32774953 100644 --- a/rules/pair/ir_unsafe.json +++ b/rules/pair/ir_unsafe.json @@ -148,43 +148,6 @@ "type": "(T1, T2)" } }, - "f3": { - "body": [ - { - "method_call": { - "receiver": [ - { - "placeholder": { - "arg": "a0", - "access": "read" - } - } - ], - "body": [ - { - "text": ".clone()" - } - ] - } - } - ], - "generics": { - "T1": [ - "Clone" - ], - "T2": [ - "Clone" - ] - }, - "params": { - "a0": { - "type": "(T1, T2)" - } - }, - "return_type": { - "type": "(T1, T2)" - } - }, "f4": { "body": [ { diff --git a/rules/pair/src.cpp b/rules/pair/src.cpp index 3ad940ca..24d4ec4c 100644 --- a/rules/pair/src.cpp +++ b/rules/pair/src.cpp @@ -3,89 +3,45 @@ #include -struct T1 {}; -struct T2 {}; -struct T3 { - operator T1() const { return T1{}; } -}; -struct T4 { - operator T2() const { return T2{}; } -}; -struct T5 { - T5(const T5 &) noexcept(false) {} -}; - -std::pair t1; +template using t1 = std::pair; template T2 &f1(std::pair &o) { return o.second; } -template T2 &f1(std::pair &); - -template -std::pair f2(const std::pair &o) { - return o; -} - -template std::pair f2(const std::pair &); - template -std::pair f3(const std::pair &o) { - return o; +std::pair f2(const std::pair &a0) { + return std::pair(a0); } -template std::pair f3(const std::pair &); - template std::pair f4(const T1 &a0, const T2 &a1) { - return {a0, a1}; + return std::pair(a0, a1); } -template std::pair f4(const T1 &, const T2 &); - template -std::pair f5(T3 &&a, T4 &&b) { - return std::pair(std::forward(a), std::forward(b)); +std::pair f5(const T3 &a0, T4 &a1) { + return std::pair(a0, a1); } -template std::pair f5(const T3 &, T4 &); -#include -#include - template -std::pair f6(T3 &&a, T4 &&b) { - return std::pair(std::forward(a), std::forward(b)); +std::pair f6(T3 &a0, T4 &a1) { + return std::pair(a0, a1); } -template std::pair f6(T3 &, T4 &); -#include -#include - template -std::pair f7(T3 &&a, T4 &&b) { - return std::pair(std::move(a), std::move(b)); +std::pair f7(T3 &&a0, T4 &&a1) { + return std::pair(std::move(a0), std::move(a1)); } -template std::pair f7(T3 &&, T4 &&); -#include - -template auto f9(A &&a, B &&b) { - return std::make_pair(std::forward(a), std::forward(b)); +template auto f9(T1 &&a0, T2 &a1) { + return std::make_pair(std::move(a0), a1); } -template auto f9(T1 &&, T2 &); -#include - -template auto f10(A &&a, B &&b) { - return std::make_pair(std::forward(a), std::forward(b)); +template auto f10(T1 &&a0, T2 &&a1) { + return std::make_pair(std::move(a0), std::move(a1)); } -template auto f10(T1 &&, T2 &&); -#include - -template T1 &f11(std::pair &o) { - return o.first; +template T1 &f11(std::pair &a0) { + return a0.first; } - -template T1 &f11(std::pair &); diff --git a/rules/pair/tgt_refcount.rs b/rules/pair/tgt_refcount.rs index 9c23190c..3578346b 100644 --- a/rules/pair/tgt_refcount.rs +++ b/rules/pair/tgt_refcount.rs @@ -29,13 +29,6 @@ fn f2(a0: (Value, Value)) -> (Value, Value ) } -fn f3(a0: (Value, Value)) -> (Value, Value) { - ( - Rc::new(RefCell::new(a0.0.borrow().clone())), - Rc::new(RefCell::new(a0.1.borrow().clone())), - ) -} - fn f4(a0: T1, a1: T2) -> (Value, Value) { ( Rc::new(RefCell::new(a0.try_into().expect("failed conversion"))), diff --git a/rules/pair/tgt_unsafe.rs b/rules/pair/tgt_unsafe.rs index 0b4e1447..5ac4de00 100644 --- a/rules/pair/tgt_unsafe.rs +++ b/rules/pair/tgt_unsafe.rs @@ -17,9 +17,6 @@ unsafe fn f1(a0: (T1, T2)) -> T2 { unsafe fn f2(a0: (T1, T2)) -> (T1, T2) { a0.clone() } -unsafe fn f3(a0: (T1, T2)) -> (T1, T2) { - a0.clone() -} unsafe fn f4(a0: T1, a1: T2) -> (T1, T2) { (a0.into(), a1.into()) } diff --git a/rules/stdarg/src.cpp b/rules/stdarg/src.cpp index bb020abb..9943ed0b 100644 --- a/rules/stdarg/src.cpp +++ b/rules/stdarg/src.cpp @@ -1,3 +1,3 @@ #include -va_list t1; +using t1 = va_list; diff --git a/rules/stdio/src.cpp b/rules/stdio/src.cpp index ea6be9c3..fd198f40 100644 --- a/rules/stdio/src.cpp +++ b/rules/stdio/src.cpp @@ -3,7 +3,7 @@ #include -FILE *t1; +using t1 = FILE *; FILE *f1(const char *pathname, const char *mode) { return fopen(pathname, mode); diff --git a/rules/string/src.cpp b/rules/string/src.cpp index 1a63405c..1d6bfab9 100644 --- a/rules/string/src.cpp +++ b/rules/string/src.cpp @@ -5,8 +5,8 @@ #include #include -std::string t1; -std::string::iterator t2; +using t1 = std::string; +using t2 = std::string::iterator; std::string f1(const std::string &s, std::size_t pos, std::size_t count) { return s.substr(pos, count); diff --git a/rules/unique_ptr/src.cpp b/rules/unique_ptr/src.cpp index 83c5ddd3..acc6b05a 100644 --- a/rules/unique_ptr/src.cpp +++ b/rules/unique_ptr/src.cpp @@ -4,54 +4,32 @@ #include #include -struct T1 {}; +template using t1 = std::unique_ptr; +template using t2 = std::unique_ptr; -std::unique_ptr t1; -std::unique_ptr t2; - -template std::unique_ptr f1(std::size_t n) { - return std::make_unique(n); +template std::unique_ptr f1(std::size_t n) { + return std::make_unique(n); } -template std::unique_ptr f1(std::size_t); -#include - -template T *f2(std::unique_ptr &o) { return o.get(); } - -template T1 *f2(std::unique_ptr &); -#include +template T1 *f2(std::unique_ptr &o) { return o.get(); } -template std::unique_ptr f3(T *p) { - return std::unique_ptr(p); +template std::unique_ptr f3(T1 *p) { + return std::unique_ptr(p); } -template std::unique_ptr f3(T1 *); -#include - -template std::unique_ptr f4(T *p) { - return std::unique_ptr(p); +template std::unique_ptr f4(T1 *p) { + return std::unique_ptr(p); } -template std::unique_ptr f4(T1 *); -#include - -template void f5(std::unique_ptr &o, T *p) { +template void f5(std::unique_ptr &o, T1 *p) { return o.reset(p); } -template void f5(std::unique_ptr &, T1 *); -#include - -template void f6(std::unique_ptr &o, T *p) { +template void f6(std::unique_ptr &o, T1 *p) { return o.reset(p); } -template void f6(std::unique_ptr &, T1 *); -#include - -template T *f7(std::unique_ptr &o) { return o.get(); } - -template T1 *f7(std::unique_ptr &); +template T1 *f7(std::unique_ptr &o) { return o.get(); } // template // std::unique_ptr f8(Args&&... args) { @@ -62,24 +40,18 @@ template T1 *f7(std::unique_ptr &); // versions for make_unique with 1, 2, 3, etc arguments and translate the // specialized versions. -template std::unique_ptr f8(Arg &&arg) { - return std::make_unique(std::forward(arg)); +template std::unique_ptr f8(T2 &&a0) { + return std::make_unique(std::move(a0)); } -template std::unique_ptr f8(T1 &&); - -template void f9(std::unique_ptr &o) { +template void f9(std::unique_ptr &o) { return o.reset(nullptr); } -template void f9(std::unique_ptr &); - -template std::unique_ptr f10() { return std::unique_ptr(); } - -template std::unique_ptr f10(); - -template std::unique_ptr f11() { - return std::unique_ptr(); +template std::unique_ptr f10() { + return std::unique_ptr(); } -template std::unique_ptr f11(); +template std::unique_ptr f11() { + return std::unique_ptr(); +} diff --git a/rules/vector/src.cpp b/rules/vector/src.cpp index 48de8c6f..91ba5851 100644 --- a/rules/vector/src.cpp +++ b/rules/vector/src.cpp @@ -5,260 +5,176 @@ #include #include -struct T1 { - friend bool operator<(const T1 &a, const T1 &b) noexcept { return true; } -}; - -struct T2 { - operator T1() { return {}; } -}; - -std::vector t1; -std::vector::iterator t2; -std::vector> t3; -std::vector::const_iterator t4; - -template -typename std::vector::iterator -f1(std::vector &o, typename std::vector::const_iterator it) { +template using t1 = std::vector; +template using t2 = typename std::vector::iterator; +template using t3 = std::vector>; +template using t4 = typename std::vector::const_iterator; + +template +typename std::vector::iterator +f1(std::vector &o, typename std::vector::const_iterator it) { return o.erase(it); } -template std::vector::iterator f1(std::vector &, - std::vector::const_iterator); - -template std::size_t f2(const std::vector &o) { +template std::size_t f2(const std::vector &o) { return o.size(); } +template bool f3(const std::vector &o) { return o.empty(); } -template std::size_t f2(const std::vector &); - -template bool f3(const std::vector &o) { return o.empty(); } - -template bool f3(const std::vector &); - -template std::vector f4() { return std::vector(); } +template std::vector f4() { return std::vector(); } -template std::vector f4(); +template void f5(std::vector &o) { return o.pop_back(); } -template void f5(std::vector &o) { return o.pop_back(); } +template T1 *f6(std::vector &o) { return o.data(); } -template void f5(std::vector &); - -template T *f6(std::vector &o) { return o.data(); } - -template T1 *f6(std::vector &); - -template T &f7(std::vector &o, std::size_t idx) { +template T1 &f7(std::vector &o, std::size_t idx) { return o.at(idx); } -template T1 &f7(std::vector &, std::size_t); - -template std::vector f8(std::size_t n) { - return std::vector(n); +template std::vector f8(std::size_t n) { + return std::vector(n); } -template std::vector f8(std::size_t); +template T1 &f9(std::vector &o) { return o.front(); } -template T &f9(std::vector &o) { return o.front(); } +template T1 &f10(std::vector &o) { return o.back(); } -template T1 &f9(std::vector &); - -template T &f10(std::vector &o) { return o.back(); } - -template T1 &f10(std::vector &); - -template std::size_t f11(const std::vector &o) { +template std::size_t f11(const std::vector &o) { return o.capacity(); } -template std::size_t f11(const std::vector &); - -template void f12(std::vector &o, std::size_t n) { +template void f12(std::vector &o, std::size_t n) { return o.reserve(n); } -template void f12(std::vector &, std::size_t); - -template typename std::vector::iterator f13(std::vector &o) { +template +typename std::vector::iterator f13(std::vector &o) { return o.begin(); } -template std::vector::iterator f13(std::vector &); - -template void f14(std::vector &o, T &&value) { +template void f14(std::vector &o, T1 &&value) { return o.push_back(std::move(value)); } -template void f14(std::vector &, T1 &&); - -template void f15(std::vector &o, std::size_t n) { +template void f15(std::vector &o, std::size_t n) { return o.resize(n); } -template void f15(std::vector &, std::size_t); +template void f16(std::vector &o) { return o.clear(); } -template void f16(std::vector &o) { return o.clear(); } - -template void f16(std::vector &); - -template typename std::vector::iterator f17(std::vector &o) { +template +typename std::vector::iterator f17(std::vector &o) { return o.end(); } -template std::vector::iterator f17(std::vector &); - -template -typename std::vector::iterator -f18(std::vector &o, typename std::vector::const_iterator it, T &&value) { +template +typename std::vector::iterator +f18(std::vector &o, typename std::vector::const_iterator it, + T1 &&value) { return o.insert(it, std::move(value)); } -template std::vector::iterator -f18(std::vector &, std::vector::const_iterator, T1 &&); - -template std::vector f19(std::size_t n, const T &value) { - return std::vector(n, value); +template std::vector f19(std::size_t n, const T1 &value) { + return std::vector(n, value); } -template std::vector f19(std::size_t, const T1 &); - -template -typename std::vector::iterator -f20(std::vector &o, typename std::vector::const_iterator it, - const T &value) { +template +typename std::vector::iterator +f20(std::vector &o, typename std::vector::const_iterator it, + const T1 &value) { return o.insert(it, value); } -template std::vector::iterator -f20(std::vector &, std::vector::const_iterator, const T1 &); - -template void f21(std::vector &o, const T &value) { +template void f21(std::vector &o, const T1 &value) { return o.push_back(value); } -template void f21(std::vector &, const T1 &); - -template -typename std::vector::reference f22(typename std::vector::iterator it) { - return *it; +template +typename std::vector::reference f22(typename std::vector::iterator it) { + return it.operator*(); } -template std::vector::reference f22(std::vector::iterator); - -template -typename std::vector::iterator -f23(const typename std::vector::iterator it) { - return it; +template +typename std::vector::iterator +f23(const typename std::vector::iterator &it) { + return typename std::vector::iterator(it); } -template std::vector::iterator f23(std::vector::iterator); - -template -typename std::vector::const_iterator -f24(typename std::vector::iterator it) { - return it; +template +typename std::vector::const_iterator +f24(const typename std::vector::iterator &it) { + return typename std::vector::const_iterator(it); } -template std::vector::const_iterator f24(std::vector::iterator); - -template -typename std::vector::iterator f25(typename std::vector::iterator it, - std::size_t n) { - return it + n; +template +typename std::vector::iterator f25(typename std::vector::iterator it, + std::size_t n) { + return it.operator+(n); } -template std::vector::iterator f25(std::vector::iterator, - std::size_t); - -template -bool f26(const typename std::vector::iterator it1, - const typename std::vector::iterator it2) { - return it1 != it2; +template +bool f26(const typename std::vector::iterator &it1, + const typename std::vector::iterator &it2) { + return operator!=(it1, it2); } -template bool f26(const typename std::vector::iterator, - const typename std::vector::iterator); - -template -bool f27(const typename std::vector::iterator it1, - const typename std::vector::iterator it2) { - return it1 == it2; +template +bool f27(const typename std::vector::iterator &it1, + const typename std::vector::iterator &it2) { + return operator==(it1, it2); } -template bool f27(const typename std::vector::iterator, - const typename std::vector::iterator); - -template -typename std::vector::iterator f28(typename std::vector::iterator it) { - return it++; +template +typename std::vector::iterator f28(typename std::vector::iterator a0, + int a1) { + return a0.operator++(a1); } -template std::vector::iterator f28(std::vector::iterator); - -template -std::vector> f29(std::vector> &o) { - return o; +template +std::vector> f29(const std::vector> &&o) { + return std::vector>(std::move(o)); } -template std::vector> f29(std::vector> &); - -template std::vector> f30(std::size_t n) { - return std::vector>(n); +template std::vector> f30(std::size_t n) { + return std::vector>(n); } -template std::vector> f30(std::size_t); - -template -void f31(std::vector> &o, std::vector &&value) { +template +void f31(std::vector> &o, std::vector &&value) { return o.push_back(std::move(value)); } -template void f31(std::vector> &, std::vector &&); - -template void f32(std::vector> &o, std::size_t n) { +template +void f32(std::vector> &o, std::size_t n) { return o.resize(n); } -template void f32(std::vector> &, std::size_t); - -template -typename std::vector::iterator::difference_type -f33(const typename std::vector::iterator it1, - const typename std::vector::iterator it2) { - return it1 - it2; +template +typename std::vector::iterator::difference_type +f33(const typename std::vector::iterator &it1, + const typename std::vector::iterator &it2) { + return operator-(it1, it2); } -template std::vector::iterator::difference_type -f33(const typename std::vector::iterator, - const typename std::vector::iterator); - -template -typename std::vector::iterator &f34(typename std::vector::iterator &it) { - return ++it; +template +typename std::vector::iterator & +f34(typename std::vector::iterator &it) { + return it.operator++(); } -template std::vector::iterator &f34(std::vector::iterator &); - -template std::vector f35(const T *first, const T *last) { - return std::vector(first, last); +template std::vector f35(const T1 *first, const T1 *last) { + return std::vector(first, last); } -template std::vector f35(const T1 *, const T1 *); - -template std::vector f36(const std::initializer_list &a0) { - return std::vector(a0); +template +std::vector f36(const std::initializer_list &a0) { + return std::vector(a0); } -template std::vector f36(const std::initializer_list &); - -template std::vector f37(T *first, T *last) { - return std::vector(first, last); +template std::vector f37(T1 *first, T1 *last) { + return std::vector(first, last); } -template std::vector f37(T1 *, T1 *); - std::vector f38(std::size_t n, const bool &value) { return std::vector(n, value); } @@ -267,112 +183,83 @@ std::vector f39(unsigned int *first, unsigned int *last) { return std::vector(first, last); } -template const T *f40(T const (&a0)[N]) { +template const T1 *f40(T1 const (&a0)[T2]) { return std::end(a0); } -template const T1 *f40(T1 const (&a0)[16]); - -template const T *f41(const std::vector &o) { return o.data(); } - -template const T1 *f41(const std::vector &); +template const T1 *f41(const std::vector &o) { + return o.data(); +} -template -typename std::vector::const_iterator -f42(typename std::vector::const_iterator first, - typename std::vector::const_iterator last) { +template +typename std::vector::const_iterator +f42(typename std::vector::const_iterator first, + typename std::vector::const_iterator last) { return std::max_element(first, last); } -template std::vector::const_iterator - f42(std::vector::const_iterator, std::vector::const_iterator); - -template -typename std::vector::const_iterator f43(const std::vector &o) { +template +typename std::vector::const_iterator f43(const std::vector &o) { return o.begin(); } -template std::vector::const_iterator f43(const std::vector &); - -template -typename std::vector::const_iterator f44(const std::vector &o) { +template +typename std::vector::const_iterator f44(const std::vector &o) { return o.end(); } -template std::vector::const_iterator f44(const std::vector &); - bool f47(std::vector &o) { return o[0]; } -template void f48(std::vector &o, std::vector &a0) { +template void f48(std::vector &o, std::vector &a0) { return o.swap(a0); } -template void f48(std::vector &o, std::vector &a0); - -template const T &f50(const std::vector &o, std::size_t idx) { +template +const T1 &f50(const std::vector &o, std::size_t idx) { return o.at(idx); } -template const T1 &f50(const std::vector &, std::size_t); - -template const T &f51(const std::vector &o) { return o.back(); } - -template const T1 &f51(const std::vector &); +template const T1 &f51(const std::vector &o) { + return o.back(); +} -template -void f52(std::vector> &o, const std::vector &value) { +template +void f52(std::vector> &o, const std::vector &value) { return o.push_back(value); } -template void f52(std::vector> &, const std::vector &); - -template -typename std::vector::iterator -f53(std::vector &o, typename std::vector::const_iterator pos, - const T *first, const T *last) { +template +typename std::vector::iterator +f53(std::vector &o, typename std::vector::const_iterator pos, + const T1 *first, const T1 *last) { return o.insert(pos, first, last); } -template std::vector::iterator f53(std::vector &, - std::vector::const_iterator, - const T1 *, const T1 *); - -template -void f54(std::vector &o, std::size_t n, - const typename std::vector::value_type &value) { +template +void f54(std::vector &o, std::size_t n, + const typename std::vector::value_type &value) { return o.resize(n, value); } -template void f54(std::vector &, std::size_t, - const std::vector::value_type &); - -template -std::vector &f55(std::vector &dst, std::vector &&src) { - return dst = std::move(src); +template +std::vector &f55(std::vector &dst, std::vector &&src) { + return dst.operator=(std::move(src)); } -template std::vector &f55(std::vector &, std::vector &&); - -template std::vector &f56(std::vector> &o) { +template std::vector &f56(std::vector> &o) { return o.back(); } -template std::vector &f56(std::vector> &); - -template -typename std::vector::const_iterator f57(const std::vector &o) { +template +typename std::vector::const_iterator f57(const std::vector &o) { return o.cend(); } -template std::vector::const_iterator f57(const std::vector &); - -template -std::vector &f58(std::vector &dst, const std::vector &src) { - return dst = src; +template +std::vector &f58(std::vector &dst, const std::vector &src) { + return dst.operator=(src); } -template std::vector &f58(std::vector &, const std::vector &); - -template void f59(std::vector &o) { return o.shrink_to_fit(); } - -template void f59(std::vector &); +template void f59(std::vector &o) { + return o.shrink_to_fit(); +}