47std::optional<llvm::ArrayRef<TemplateArgumentLoc>>
48getTemplateSpecializationArgLocs(
const NamedDecl &ND) {
49 if (
auto *Func = llvm::dyn_cast<FunctionDecl>(&ND)) {
50 if (
const ASTTemplateArgumentListInfo *Args =
51 Func->getTemplateSpecializationArgsAsWritten())
52 return Args->arguments();
53 }
else if (
auto *Cls = llvm::dyn_cast<ClassTemplateSpecializationDecl>(&ND)) {
54 if (
auto *Args = Cls->getTemplateArgsAsWritten())
55 return Args->arguments();
56 }
else if (
auto *Var = llvm::dyn_cast<VarTemplateSpecializationDecl>(&ND)) {
57 if (
auto *Args = Var->getTemplateArgsAsWritten())
58 return Args->arguments();
66bool isTemplateSpecializationKind(
const NamedDecl *D,
67 TemplateSpecializationKind Kind) {
68 if (
const auto *TD = dyn_cast<T>(D))
69 return TD->getTemplateSpecializationKind() == Kind;
73bool isTemplateSpecializationKind(
const NamedDecl *D,
74 TemplateSpecializationKind Kind) {
75 return isTemplateSpecializationKind<FunctionDecl>(D, Kind) ||
76 isTemplateSpecializationKind<CXXRecordDecl>(D, Kind) ||
77 isTemplateSpecializationKind<VarDecl>(D, Kind);
82llvm::DenseSet<const NamespaceDecl *>
83getUsingNamespaceDirectives(
const DeclContext *DestContext,
84 SourceLocation Until) {
85 const auto &SM = DestContext->getParentASTContext().getSourceManager();
86 llvm::DenseSet<const NamespaceDecl *> VisibleNamespaceDecls;
87 for (
const auto *DC = DestContext; DC; DC = DC->getLookupParent()) {
88 for (
const auto *D : DC->decls()) {
89 if (!SM.isWrittenInSameFile(D->getLocation(), Until) ||
90 !SM.isBeforeInTranslationUnit(D->getLocation(), Until))
92 if (
auto *UDD = llvm::dyn_cast<UsingDirectiveDecl>(D))
93 VisibleNamespaceDecls.insert(
94 UDD->getNominatedNamespace()->getCanonicalDecl());
97 return VisibleNamespaceDecls;
106 const DeclContext *DestContext,
107 const DeclContext *SourceContext,
108 llvm::function_ref<
bool(
const Decl *)> IsVisible) {
109 std::vector<const Decl *>
Parents;
110 [[maybe_unused]]
bool ReachedNS =
false;
111 for (
const DeclContext *CurContext = SourceContext; CurContext;
112 CurContext = CurContext->getLookupParent()) {
114 if (CurContext->Encloses(DestContext))
118 if (
auto *TD = llvm::dyn_cast<TagDecl>(CurContext)) {
122 }
else if (
auto *NSD = llvm::dyn_cast<NamespaceDecl>(CurContext)) {
126 if (NSD->isAnonymousNamespace() || NSD->isInlineNamespace())
143 NestedNameSpecifier Qualifier = std::nullopt;
145 for (
const auto *CurD : llvm::reverse(
Parents)) {
146 if (
auto *TD = llvm::dyn_cast<TagDecl>(CurD)) {
148 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD);
149 ClassTemplateDecl *CTD =
150 RD ? RD->getDescribedClassTemplate() :
nullptr) {
151 ArrayRef<TemplateArgument> Args;
152 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
153 Args = SD->getTemplateArgs().asArray();
155 Args = CTD->getTemplateParameters()->getInjectedTemplateArgs(
Context);
156 T =
Context.getTemplateSpecializationType(
157 ElaboratedTypeKeyword::None,
158 Context.getQualifiedTemplateName(
159 Qualifier, !IsFirst, TemplateName(CTD)),
160 Args, {},
Context.getCanonicalTagType(RD));
162 T =
Context.getTagType(ElaboratedTypeKeyword::None, Qualifier, TD,
165 Qualifier = NestedNameSpecifier(T.getTypePtr());
168 NestedNameSpecifier(
Context, cast<NamespaceDecl>(CurD), Qualifier);
176 llvm::raw_string_ostream OS(Result);
177 Qualifier.print(OS,
Context.getPrintingPolicy());
184 return isTemplateSpecializationKind(D, TSK_ImplicitInstantiation);
188 return isTemplateSpecializationKind(D, TSK_ExplicitSpecialization);
193 D->getASTContext().getSourceManager());
196SourceLocation
nameLocation(
const clang::Decl &D,
const SourceManager &SM) {
197 auto L = D.getLocation();
199 if (
const auto *
MD = dyn_cast<ObjCMethodDecl>(&D))
200 L =
MD->getSelectorStartLoc();
202 return SM.getSpellingLoc(L);
203 return SM.getExpansionLoc(L);
208 llvm::raw_string_ostream OS(QName);
209 PrintingPolicy Policy(ND.getASTContext().getLangOpts());
214 Policy.SuppressUnwrittenScope =
true;
215 Policy.SuppressScope =
true;
218 Policy.AnonymousTagNameStyle =
219 llvm::to_underlying(PrintingPolicy::AnonymousTagMode::Plain);
220 ND.printQualifiedName(OS, Policy);
221 assert(!StringRef(QName).starts_with(
"::"));
226 return N.isIdentifier() && !N.getAsIdentifierInfo();
230 if (
auto *V = llvm::dyn_cast<DeclaratorDecl>(&ND))
231 return V->getQualifierLoc();
232 if (
auto *T = llvm::dyn_cast<TagDecl>(&ND))
233 return T->getQualifierLoc();
234 return NestedNameSpecifierLoc();
238 const UsingDirectiveDecl &D) {
239 PrintingPolicy PP(Ctx.getLangOpts());
241 llvm::raw_string_ostream Out(Name);
243 D.getQualifier().print(Out, PP);
244 D.getNominatedNamespaceAsWritten()->printName(Out);
248std::string
printName(
const ASTContext &Ctx,
const NamedDecl &ND) {
250 llvm::raw_string_ostream Out(Name);
251 PrintingPolicy PP(Ctx.getLangOpts());
253 PP.SuppressTemplateArgsInCXXConstructors =
true;
256 if (
auto *UD = llvm::dyn_cast<UsingDirectiveDecl>(&ND)) {
257 Out <<
"using namespace ";
258 UD->getQualifier().print(Out, PP);
259 UD->getNominatedNamespaceAsWritten()->printName(Out);
265 if (isa<NamespaceDecl>(ND))
266 return "(anonymous namespace)";
267 if (
auto *Cls = llvm::dyn_cast<RecordDecl>(&ND)) {
270 return (
"(anonymous " + Cls->getKindName() +
")").str();
272 if (isa<EnumDecl>(ND))
273 return "(anonymous enum)";
274 return "(anonymous)";
280 ND.getDeclName().print(Out, PP);
288 std::string TemplateArgs;
289 llvm::raw_string_ostream OS(TemplateArgs);
290 PrintingPolicy Policy(ND.getASTContext().getLangOpts());
291 if (std::optional<llvm::ArrayRef<TemplateArgumentLoc>> Args =
292 getTemplateSpecializationArgLocs(ND)) {
293 printTemplateArgumentList(OS, *Args, Policy);
294 }
else if (
auto *Cls = llvm::dyn_cast<ClassTemplateSpecializationDecl>(&ND)) {
298 printTemplateArgumentList(OS, Cls->getTemplateArgs().asArray(), Policy);
304 for (
const auto *Ctx = &DC; Ctx !=
nullptr; Ctx = Ctx->getParent())
305 if (
const auto *NS = dyn_cast<NamespaceDecl>(Ctx))
306 if (!NS->isAnonymousNamespace() && !NS->isInlineNamespace())
311static llvm::StringRef
313 return ID ? ID->getName() :
"<<error-type>>";
318 llvm::raw_string_ostream OS(Name);
320 OS << (
Method.isInstanceMethod() ?
'-' :
'+') <<
'[';
323 if (
const ObjCContainerDecl *C =
324 dyn_cast<ObjCContainerDecl>(
Method.getDeclContext()))
327 Method.getSelector().print(OS <<
' ');
336 if (
const ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(&C)) {
338 llvm::raw_string_ostream OS(Name);
339 const ObjCInterfaceDecl *
Class = Category->getClassInterface();
344 if (
const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(&C)) {
346 llvm::raw_string_ostream OS(Name);
347 const ObjCInterfaceDecl *
Class = CID->getClassInterface();
351 return C.getNameAsString();
355 llvm::SmallString<128> USR;
356 if (index::generateUSRForDecl(D, USR))
362 const SourceManager &SM) {
365 llvm::SmallString<128> USR;
366 if (index::generateUSRForMacro(MacroName, MI->getDefinitionLoc(), SM, USR))
372 if (
const auto *ID = dyn_cast<ObjCInterfaceDecl>(D))
373 return ID->getImplementation();
374 if (
const auto *CD = dyn_cast<ObjCCategoryDecl>(D)) {
375 if (CD->IsClassExtension()) {
376 if (
const auto *ID = CD->getClassInterface())
377 return ID->getImplementation();
380 return CD->getImplementation();
387 ArrayRef<Inclusion> MainFileIncludes,
388 ArrayRef<const Decl *> TopLevelDecls) {
402 for (
auto &Inc : MainFileIncludes)
403 if (Inc.Directive == tok::pp_import)
409 for (
const Decl *D : TopLevelDecls)
410 if (isa<ObjCContainerDecl, ObjCIvarDecl, ObjCMethodDecl, ObjCPropertyDecl>(
417std::string
printType(
const QualType QT,
const DeclContext &CurContext,
418 const llvm::StringRef Placeholder,
bool FullyQualify) {
420 llvm::raw_string_ostream OS(Result);
421 PrintingPolicy PP(CurContext.getParentASTContext().getPrintingPolicy());
422 PP.SuppressTagKeyword =
true;
423 PP.SuppressUnwrittenScope =
true;
424 PP.FullyQualifiedName = FullyQualify;
426 class PrintCB :
public PrintingCallbacks {
428 PrintCB(
const DeclContext *CurContext) : CurContext(CurContext) {}
429 virtual ~PrintCB() {}
430 bool isScopeVisible(
const DeclContext *DC)
const override {
431 return DC->Encloses(CurContext);
435 const DeclContext *CurContext;
437 PrintCB PCB(&CurContext);
440 QT.print(OS, PP, Placeholder);
445 if (
const auto *ND = llvm::dyn_cast<NamedDecl>(&D))
446 if (
const auto *II = ND->getIdentifier())
452 for (
const DeclContext *D = &DC; D; D = D->getParent()) {
453 if (D->isTransparentContext() || D->isInlineNamespace())
455 if (
const auto *ND = llvm::dyn_cast<NamedDecl>(D))
463 ASTContext &
Context = D->getASTContext();
464 if (
const auto *CTSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>(D))
465 if (
const auto *Args = CTSD->getTemplateArgsAsWritten())
466 return Context.getTemplateSpecializationType(
467 ElaboratedTypeKeyword::None,
468 TemplateName(CTSD->getSpecializedTemplate()), Args->arguments(),
470 return Context.getTypeDeclType(D);
482class DeducedTypeVisitor :
public RecursiveASTVisitor<DeducedTypeVisitor> {
483 SourceLocation SearchedLocation;
484 const HeuristicResolver *Resolver;
487 DeducedTypeVisitor(SourceLocation SearchedLocation,
488 const HeuristicResolver *Resolver)
489 : SearchedLocation(SearchedLocation), Resolver(Resolver) {}
496 bool VisitDeclaratorDecl(DeclaratorDecl *D) {
497 if (!D->getTypeSourceInfo() ||
498 !D->getTypeSourceInfo()->getTypeLoc().getContainedAutoTypeLoc() ||
499 D->getTypeSourceInfo()
501 .getContainedAutoTypeLoc()
502 .getNameLoc() != SearchedLocation)
505 if (
auto *AT = D->getType()->getContainedAutoType()) {
506 if (AT->isUndeducedAutoType()) {
507 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
508 if (Resolver && VD->hasInit()) {
509 DeducedType = Resolver->resolveExprToType(VD->getInit());
514 DeducedType = AT->desugar();
525 bool VisitFunctionDecl(FunctionDecl *D) {
526 if (!
D->getTypeSourceInfo())
529 auto CurLoc =
D->getReturnTypeSourceRange().getBegin();
531 if (CurLoc.isInvalid() && isa<CXXConversionDecl>(D))
532 CurLoc =
D->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
534 if (
auto *FPT =
D->getType()->getAs<FunctionProtoType>();
535 FPT && FPT->hasTrailingReturn())
536 CurLoc =
D->getSourceRange().getBegin();
537 if (CurLoc != SearchedLocation)
540 const AutoType *AT =
D->getReturnType()->getContainedAutoType();
541 if (AT && !AT->getDeducedType().isNull()) {
542 DeducedType = AT->getDeducedType();
543 }
else if (
auto *DT = dyn_cast<DecltypeType>(
D->getReturnType())) {
546 if (!DT->getUnderlyingType().isNull())
547 DeducedType = DT->getUnderlyingType();
548 }
else if (!
D->getReturnType().isNull()) {
549 DeducedType =
D->getReturnType();
557 bool VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
558 if (TL.getBeginLoc() != SearchedLocation)
565 const DecltypeType *DT = dyn_cast<DecltypeType>(TL.getTypePtr());
566 while (DT && !DT->getUnderlyingType().isNull()) {
567 DeducedType = DT->getUnderlyingType();
568 DT = dyn_cast<DecltypeType>(DeducedType.getTypePtr());
575 bool VisitParmVarDecl(ParmVarDecl *PVD) {
576 if (!PVD->getType()->isDependentType())
579 TemplateTypeParmTypeLoc
Auto =
581 if (
Auto.isNull() ||
Auto.getNameLoc() != SearchedLocation)
586 auto *Templated = llvm::dyn_cast<FunctionDecl>(PVD->getDeclContext());
589 auto *FTD = Templated->getDescribedFunctionTemplate();
592 int ParamIndex = paramIndex(*FTD, *
Auto.getDecl());
593 if (ParamIndex < 0) {
594 assert(
false &&
"auto TTP is not from enclosing function?");
599 auto *Instantiation =
603 const auto *Args = Instantiation->getTemplateSpecializationArgs();
604 if (Args->size() != FTD->getTemplateParameters()->size())
606 DeducedType = Args->get(ParamIndex).getAsType();
610 static int paramIndex(
const TemplateDecl &TD, NamedDecl &Param) {
612 for (
auto *ND : *TD.getTemplateParameters()) {
620 QualType DeducedType;
625 const HeuristicResolver *Resolver,
626 SourceLocation Loc) {
629 DeducedTypeVisitor V(Loc, Resolver);
630 V.TraverseAST(ASTCtx);
631 if (V.DeducedType.isNull())
633 return V.DeducedType;
637 if (
auto QTL = TL.getAs<QualifiedTypeLoc>())
639 if (llvm::isa<PointerType, ReferenceType, ParenType>(TL.getTypePtr()))
641 if (
auto FTL = TL.getAs<FunctionTypeLoc>())
643 if (
auto TTPTL = TL.getAs<TemplateTypeParmTypeLoc>()) {
644 if (TTPTL.getTypePtr()->getDecl()->isImplicit())
650template <
typename TemplateDeclTy>
652 NamedDecl *Only =
nullptr;
653 for (
auto *Spec : TD->specializations()) {
654 if (Spec->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
664 if (TemplateDecl *TD = TemplatedDecl->getDescribedTemplate()) {
665 if (
auto *CTD = llvm::dyn_cast<ClassTemplateDecl>(TD))
667 if (
auto *FTD = llvm::dyn_cast<FunctionTemplateDecl>(TD))
669 if (
auto *VTD = llvm::dyn_cast<VarTemplateDecl>(TD))
676 std::vector<const Attr *> Result;
677 if (
const auto *TL = N.get<TypeLoc>()) {
678 for (AttributedTypeLoc ATL = TL->getAs<AttributedTypeLoc>(); !ATL.isNull();
679 ATL = ATL.getModifiedLoc().getAs<AttributedTypeLoc>()) {
680 if (
const Attr *A = ATL.getAttr())
682 assert(!ATL.getModifiedLoc().isNull());
685 if (
const auto *S = N.get<AttributedStmt>()) {
686 for (; S !=
nullptr; S = dyn_cast<AttributedStmt>(S->getSubStmt()))
687 for (
const Attr *A : S->getAttrs())
691 if (
const auto *D = N.get<Decl>()) {
692 for (
const Attr *A : D->attrs())
700 const DeclContext *DestContext,
701 SourceLocation InsertionPoint,
702 const NamedDecl *ND) {
703 auto VisibleNamespaceDecls =
704 getUsingNamespaceDirectives(DestContext, InsertionPoint);
706 Context, DestContext, ND->getDeclContext(), [&](
const Decl *D) {
707 if (D->getKind() != Decl::Namespace)
709 const auto *NS = cast<NamespaceDecl>(D)->getCanonicalDecl();
710 return llvm::any_of(VisibleNamespaceDecls,
711 [NS](const NamespaceDecl *NSD) {
712 return NSD->getCanonicalDecl() == NS;
718 const DeclContext *DestContext,
720 llvm::ArrayRef<std::string> VisibleNamespaces) {
721 for (llvm::StringRef NS : VisibleNamespaces) {
722 assert(NS.ends_with(
"::"));
726 Context, DestContext, ND->getDeclContext(), [&](
const Decl *D) {
727 return llvm::any_of(VisibleNamespaces, [&](llvm::StringRef Namespace) {
729 llvm::raw_string_ostream OS(NS);
730 D->print(OS, Context.getPrintingPolicy());
731 return OS.str() == Namespace;
739 auto *VD = llvm::dyn_cast_or_null<ValueDecl>(D);
740 return VD && !VD->getType().isNull() && VD->getType()->isUndeducedType();
744 size_t ContextDepth = 0;
745 for (
auto *Ctx = D->getDeclContext(); Ctx && !Ctx->isTranslationUnit();
746 Ctx = Ctx->getParent()) {
747 if (++ContextDepth == MaxDepth)
756bool isTemplateTypeParameterPack(NamedDecl *D) {
757 if (
const auto *TTPD = dyn_cast<TemplateTypeParmDecl>(D)) {
758 return TTPD->isParameterPack();
765const TemplateTypeParmType *getFunctionPackType(
const FunctionDecl *Callee) {
766 if (
const auto *TemplateDecl = Callee->getPrimaryTemplate()) {
767 auto TemplateParams = TemplateDecl->getTemplateParameters()->asArray();
769 const auto It = std::find_if(TemplateParams.rbegin(), TemplateParams.rend(),
770 isTemplateTypeParameterPack);
771 if (It != TemplateParams.rend()) {
772 const auto *TTPD = dyn_cast<TemplateTypeParmDecl>(*It);
773 return TTPD->getTypeForDecl()->castAs<TemplateTypeParmType>();
782const TemplateTypeParmType *getUnderlyingPackType(
const ParmVarDecl *Param) {
783 const auto *PlainType = Param->getType().getTypePtr();
784 if (
auto *RT = dyn_cast<ReferenceType>(PlainType))
785 PlainType = RT->getPointeeTypeAsWritten().getTypePtr();
786 if (
const auto *SubstType = dyn_cast<SubstTemplateTypeParmType>(PlainType)) {
787 const auto *ReplacedParameter = SubstType->getReplacedParameter();
788 if (ReplacedParameter->isParameterPack()) {
789 return ReplacedParameter->getTypeForDecl()
790 ->castAs<TemplateTypeParmType>();
814class ForwardingCallVisitor
817 ForwardingCallVisitor(ArrayRef<const ParmVarDecl *> Parameters)
818 : Parameters{Parameters},
819 PackType{getUnderlyingPackType(Parameters.front())} {}
821 bool VisitCallExpr(CallExpr *E) {
822 auto *Callee = getCalleeDeclOrUniqueOverload(E);
824 handleCall(Callee, E->arguments());
826 return !
Info.has_value();
829 bool VisitCXXConstructExpr(CXXConstructExpr *E) {
830 auto *Callee = E->getConstructor();
832 handleCall(Callee, E->arguments());
834 return !
Info.has_value();
838 ArrayRef<const ParmVarDecl *> Parameters;
840 const TemplateTypeParmType *PackType;
842 struct ForwardingInfo {
846 ArrayRef<const ParmVarDecl *>
Head;
850 ArrayRef<const ParmVarDecl *> Pack;
854 ArrayRef<const ParmVarDecl *>
Tail;
857 std::optional<FunctionDecl *> PackTarget;
861 std::optional<ForwardingInfo>
Info;
866 void handleCall(FunctionDecl *Callee,
typename CallExpr::arg_range Args) {
868 if (Callee->parameters().size() < Parameters.size())
870 if (llvm::any_of(Args,
871 [](
const Expr *E) {
return isa<PackExpansionExpr>(E); })) {
874 auto PackLocation = findPack(Args);
881 if (Callee->parameters().size() < (*PackLocation + Parameters.size())) {
882 assert(Callee->isVariadic());
885 ArrayRef<ParmVarDecl *> MatchingParams =
886 Callee->parameters().slice(*PackLocation, Parameters.size());
889 if (
const auto *TTPT = getFunctionPackType(Callee)) {
891 auto IsExpandedPack = [&](
const ParmVarDecl *
P) {
892 return getUnderlyingPackType(P) == TTPT;
895 FI.Head = MatchingParams.take_until(IsExpandedPack);
897 MatchingParams.drop_front(FI.Head.size()).take_while(IsExpandedPack);
898 FI.Tail = MatchingParams.drop_front(FI.Head.size() + FI.Pack.size());
899 FI.PackTarget = Callee;
905 FI.Head = MatchingParams;
911 std::optional<size_t> findPack(
typename CallExpr::arg_range Args) {
913 assert(Parameters.size() <=
static_cast<size_t>(llvm::size(Args)));
914 for (
auto Begin = Args.begin(), End = Args.end() - Parameters.size() + 1;
915 Begin != End; ++Begin) {
916 if (
const auto *RefArg = unwrapForward(*Begin)) {
917 if (Parameters.front() != RefArg->getDecl())
922 auto ParamEnd = Begin + Parameters.size() - 1;
923 RefArg = unwrapForward(*ParamEnd);
924 if (!RefArg || Parameters.back() != RefArg->getDecl())
926 return std::distance(Args.begin(), Begin);
932 static FunctionDecl *getCalleeDeclOrUniqueOverload(CallExpr *E) {
933 Decl *CalleeDecl = E->getCalleeDecl();
934 auto *Callee = dyn_cast_or_null<FunctionDecl>(CalleeDecl);
936 if (
auto *Lookup = dyn_cast<UnresolvedLookupExpr>(E->getCallee())) {
937 Callee = resolveOverload(Lookup, E);
941 if (Callee && Callee->getNumParams() == E->getNumArgs())
946 static FunctionDecl *resolveOverload(UnresolvedLookupExpr *Lookup,
948 FunctionDecl *MatchingDecl =
nullptr;
949 if (!Lookup->requiresADL()) {
952 for (
auto *Candidate : Lookup->decls()) {
953 if (
auto *FuncCandidate = dyn_cast_or_null<FunctionDecl>(Candidate)) {
954 if (FuncCandidate->getNumParams() == E->getNumArgs()) {
959 MatchingDecl = FuncCandidate;
969 static const DeclRefExpr *unwrapForward(
const Expr *E) {
970 E = E->IgnoreImplicitAsWritten();
974 if (
const auto *Const = dyn_cast<CXXConstructExpr>(E))
975 if (Const->getConstructor()->isCopyOrMoveConstructor())
976 E = Const->getArg(0)->IgnoreImplicitAsWritten();
977 if (
const auto *Call = dyn_cast<CallExpr>(E)) {
978 const auto Callee =
Call->getBuiltinCallee();
979 if (Callee == Builtin::BIforward) {
980 return dyn_cast<DeclRefExpr>(
981 Call->getArg(0)->IgnoreImplicitAsWritten());
984 return dyn_cast<DeclRefExpr>(E);
992 auto Parameters = D->parameters();
994 if (
const auto *TTPT = getFunctionPackType(D)) {
996 auto IsExpandedPack = [TTPT](
const ParmVarDecl *P) {
997 return getUnderlyingPackType(P) == TTPT;
999 ArrayRef<const ParmVarDecl *>
Head = Parameters.take_until(IsExpandedPack);
1000 ArrayRef<const ParmVarDecl *> Pack =
1001 Parameters.drop_front(
Head.size()).take_while(IsExpandedPack);
1002 ArrayRef<const ParmVarDecl *>
Tail =
1003 Parameters.drop_front(
Head.size() + Pack.size());
1006 auto *HeadIt = std::copy(
Head.begin(),
Head.end(), Result.begin());
1007 auto TailIt = std::copy(
Tail.rbegin(),
Tail.rend(), Result.rbegin());
1010 const FunctionDecl *CurrentFunction = D;
1011 llvm::SmallPtrSet<const FunctionTemplateDecl *, 4> SeenTemplates;
1012 if (
const auto *Template = D->getPrimaryTemplate()) {
1013 SeenTemplates.insert(Template);
1015 while (!Pack.empty() && CurrentFunction && Depth < MaxDepth) {
1017 ForwardingCallVisitor V{Pack};
1018 V.TraverseStmt(CurrentFunction->getBody());
1023 auto Info = *V.Info;
1024 HeadIt = std::copy(
Info.Head.begin(),
Info.Head.end(), HeadIt);
1025 TailIt = std::copy(
Info.Tail.rbegin(),
Info.Tail.rend(), TailIt);
1028 CurrentFunction =
Info.PackTarget.value_or(
nullptr);
1031 if (CurrentFunction) {
1032 if (
const auto *Template = CurrentFunction->getPrimaryTemplate()) {
1033 bool NewFunction = SeenTemplates.insert(Template).second;
1035 return {Parameters.begin(), Parameters.end()};
1041 HeadIt = std::copy(Pack.begin(), Pack.end(), HeadIt);
1042 assert(TailIt.base() == HeadIt);
1045 return {Parameters.begin(), Parameters.end()};
1049 return getUnderlyingPackType(D) !=
nullptr;
1053 const auto *FD = FT->getTemplatedDecl();
1054 const auto NumParams = FD->getNumParams();
1056 if (NumParams > 0) {
1057 const auto *LastParam = FD->getParamDecl(NumParams - 1);
1058 if (
const auto *PET = dyn_cast<PackExpansionType>(LastParam->getType())) {
1060 const auto BaseType = PET->getPattern().getNonReferenceType();
1061 if (
const auto *TTPT =
1062 dyn_cast<TemplateTypeParmType>(BaseType.getTypePtr())) {
1064 if (FT->getTemplateParameters()->getDepth() == TTPT->getDepth()) {
1074 :
public RecursiveASTVisitor<ForwardingToConstructorVisitor> {
1085 if (
auto *FD = E->getDirectCallee()) {
1089 if (
auto *PT = FD->getPrimaryTemplate();
1093 Visitor.TraverseStmt(FD->getBody());
1101 if (
auto *CE = E->getConstructExpr())
1102 if (
auto *Callee = CE->getConstructor()) {
1103 auto *Adjusted = &adjustDeclToTemplate(*Callee);
1104 if (
auto *Template = dyn_cast<TemplateDecl>(Adjusted))
1105 Adjusted = Template->getTemplatedDecl();
1106 if (
auto *
Constructor = dyn_cast<CXXConstructorDecl>(Adjusted))
1121 llvm::DenseSet<const FunctionDecl *> SeenFunctions{FD};
1123 Visitor.TraverseStmt(FD->getBody());
1127ArrayRef<const CXXConstructorDecl *>
1130 assert(FD &&
"FD must not be null");
1131 if (!FD->isTemplateInstantiation())
1133 if (
auto It = Cache.find(FD); It != Cache.end())
1134 return It->getSecond();
1135 const auto *PT = FD->getPrimaryTemplate();
1140 return Inserted.first->getSecond();