48std::optional<llvm::ArrayRef<TemplateArgumentLoc>>
49getTemplateSpecializationArgLocs(
const NamedDecl &ND) {
50 if (
auto *Func = llvm::dyn_cast<FunctionDecl>(&ND)) {
51 if (
const ASTTemplateArgumentListInfo *Args =
52 Func->getTemplateSpecializationArgsAsWritten())
53 return Args->arguments();
54 }
else if (
auto *Cls = llvm::dyn_cast<ClassTemplateSpecializationDecl>(&ND)) {
55 if (
auto *Args = Cls->getTemplateArgsAsWritten())
56 return Args->arguments();
57 }
else if (
auto *Var = llvm::dyn_cast<VarTemplateSpecializationDecl>(&ND)) {
58 if (
auto *Args = Var->getTemplateArgsAsWritten())
59 return Args->arguments();
67bool isTemplateSpecializationKind(
const NamedDecl *D,
68 TemplateSpecializationKind Kind) {
69 if (
const auto *TD = dyn_cast<T>(D))
70 return TD->getTemplateSpecializationKind() == Kind;
74bool isTemplateSpecializationKind(
const NamedDecl *D,
75 TemplateSpecializationKind Kind) {
76 return isTemplateSpecializationKind<FunctionDecl>(D, Kind) ||
77 isTemplateSpecializationKind<CXXRecordDecl>(D, Kind) ||
78 isTemplateSpecializationKind<VarDecl>(D, Kind);
83llvm::DenseSet<const NamespaceDecl *>
84getUsingNamespaceDirectives(
const DeclContext *DestContext,
85 SourceLocation Until) {
86 const auto &SM = DestContext->getParentASTContext().getSourceManager();
87 llvm::DenseSet<const NamespaceDecl *> VisibleNamespaceDecls;
88 for (
const auto *DC = DestContext; DC; DC = DC->getLookupParent()) {
89 for (
const auto *D : DC->decls()) {
90 if (!SM.isWrittenInSameFile(D->getLocation(), Until) ||
91 !SM.isBeforeInTranslationUnit(D->getLocation(), Until))
93 if (
auto *UDD = llvm::dyn_cast<UsingDirectiveDecl>(D))
94 VisibleNamespaceDecls.insert(
95 UDD->getNominatedNamespace()->getCanonicalDecl());
98 return VisibleNamespaceDecls;
107 const DeclContext *DestContext,
108 const DeclContext *SourceContext,
109 llvm::function_ref<
bool(
const Decl *)> IsVisible) {
110 std::vector<const Decl *>
Parents;
111 [[maybe_unused]]
bool ReachedNS =
false;
112 for (
const DeclContext *CurContext = SourceContext; CurContext;
113 CurContext = CurContext->getLookupParent()) {
115 if (CurContext->Encloses(DestContext))
119 if (
auto *TD = llvm::dyn_cast<TagDecl>(CurContext)) {
123 }
else if (
auto *NSD = llvm::dyn_cast<NamespaceDecl>(CurContext)) {
127 if (NSD->isAnonymousNamespace() || NSD->isInlineNamespace())
144 NestedNameSpecifier Qualifier = std::nullopt;
146 for (
const auto *CurD : llvm::reverse(
Parents)) {
147 if (
auto *TD = llvm::dyn_cast<TagDecl>(CurD)) {
149 if (
const auto *RD = dyn_cast<CXXRecordDecl>(TD);
150 ClassTemplateDecl *CTD =
151 RD ? RD->getDescribedClassTemplate() :
nullptr) {
152 ArrayRef<TemplateArgument> Args;
153 if (
const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
154 Args = SD->getTemplateArgs().asArray();
156 Args = CTD->getTemplateParameters()->getInjectedTemplateArgs(
Context);
157 T =
Context.getTemplateSpecializationType(
158 ElaboratedTypeKeyword::None,
159 Context.getQualifiedTemplateName(
160 Qualifier, !IsFirst, TemplateName(CTD)),
161 Args, {},
Context.getCanonicalTagType(RD));
163 T =
Context.getTagType(ElaboratedTypeKeyword::None, Qualifier, TD,
166 Qualifier = NestedNameSpecifier(T.getTypePtr());
169 NestedNameSpecifier(
Context, cast<NamespaceDecl>(CurD), Qualifier);
177 llvm::raw_string_ostream OS(Result);
178 Qualifier.print(OS,
Context.getPrintingPolicy());
185 return isTemplateSpecializationKind(D, TSK_ImplicitInstantiation);
189 return isTemplateSpecializationKind(D, TSK_ExplicitSpecialization);
194 D->getASTContext().getSourceManager());
197SourceLocation
nameLocation(
const clang::Decl &D,
const SourceManager &SM) {
198 auto L = D.getLocation();
200 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(&D))
201 L = MD->getSelectorStartLoc();
203 return SM.getSpellingLoc(L);
204 return SM.getExpansionLoc(L);
209 llvm::raw_string_ostream OS(QName);
210 PrintingPolicy Policy(ND.getASTContext().getLangOpts());
215 Policy.SuppressUnwrittenScope =
true;
216 Policy.SuppressScope =
true;
219 Policy.AnonymousTagLocations =
false;
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 (CurLoc.isInvalid())
535 CurLoc =
D->getSourceRange().getBegin();
536 if (CurLoc != SearchedLocation)
539 const AutoType *AT =
D->getReturnType()->getContainedAutoType();
540 if (AT && !AT->getDeducedType().isNull()) {
541 DeducedType = AT->getDeducedType();
542 }
else if (
auto *DT = dyn_cast<DecltypeType>(
D->getReturnType())) {
545 if (!DT->getUnderlyingType().isNull())
546 DeducedType = DT->getUnderlyingType();
547 }
else if (!
D->getReturnType().isNull()) {
548 DeducedType =
D->getReturnType();
556 bool VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
557 if (TL.getBeginLoc() != SearchedLocation)
564 const DecltypeType *DT = dyn_cast<DecltypeType>(TL.getTypePtr());
565 while (DT && !DT->getUnderlyingType().isNull()) {
566 DeducedType = DT->getUnderlyingType();
567 DT = dyn_cast<DecltypeType>(DeducedType.getTypePtr());
574 bool VisitParmVarDecl(ParmVarDecl *PVD) {
575 if (!PVD->getType()->isDependentType())
578 TemplateTypeParmTypeLoc
Auto =
580 if (
Auto.isNull() ||
Auto.getNameLoc() != SearchedLocation)
585 auto *Templated = llvm::dyn_cast<FunctionDecl>(PVD->getDeclContext());
588 auto *FTD = Templated->getDescribedFunctionTemplate();
591 int ParamIndex = paramIndex(*FTD, *
Auto.getDecl());
592 if (ParamIndex < 0) {
593 assert(
false &&
"auto TTP is not from enclosing function?");
598 auto *Instantiation =
602 const auto *Args = Instantiation->getTemplateSpecializationArgs();
603 if (Args->size() != FTD->getTemplateParameters()->size())
605 DeducedType = Args->get(ParamIndex).getAsType();
609 static int paramIndex(
const TemplateDecl &TD, NamedDecl &Param) {
611 for (
auto *ND : *TD.getTemplateParameters()) {
619 QualType DeducedType;
624 const HeuristicResolver *Resolver,
625 SourceLocation Loc) {
628 DeducedTypeVisitor V(Loc, Resolver);
629 V.TraverseAST(ASTCtx);
630 if (V.DeducedType.isNull())
632 return V.DeducedType;
636 if (
auto QTL = TL.getAs<QualifiedTypeLoc>())
638 if (llvm::isa<PointerType, ReferenceType, ParenType>(TL.getTypePtr()))
640 if (
auto FTL = TL.getAs<FunctionTypeLoc>())
642 if (
auto TTPTL = TL.getAs<TemplateTypeParmTypeLoc>()) {
643 if (TTPTL.getTypePtr()->getDecl()->isImplicit())
649template <
typename TemplateDeclTy>
651 NamedDecl *Only =
nullptr;
652 for (
auto *Spec : TD->specializations()) {
653 if (Spec->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
663 if (TemplateDecl *TD = TemplatedDecl->getDescribedTemplate()) {
664 if (
auto *CTD = llvm::dyn_cast<ClassTemplateDecl>(TD))
666 if (
auto *FTD = llvm::dyn_cast<FunctionTemplateDecl>(TD))
668 if (
auto *VTD = llvm::dyn_cast<VarTemplateDecl>(TD))
675 std::vector<const Attr *> Result;
676 if (
const auto *TL = N.get<TypeLoc>()) {
677 for (AttributedTypeLoc ATL = TL->getAs<AttributedTypeLoc>(); !ATL.isNull();
678 ATL = ATL.getModifiedLoc().getAs<AttributedTypeLoc>()) {
679 if (
const Attr *A = ATL.getAttr())
681 assert(!ATL.getModifiedLoc().isNull());
684 if (
const auto *S = N.get<AttributedStmt>()) {
685 for (; S !=
nullptr; S = dyn_cast<AttributedStmt>(S->getSubStmt()))
686 for (
const Attr *A : S->getAttrs())
690 if (
const auto *D = N.get<Decl>()) {
691 for (
const Attr *A : D->attrs())
699 const DeclContext *DestContext,
700 SourceLocation InsertionPoint,
701 const NamedDecl *ND) {
702 auto VisibleNamespaceDecls =
703 getUsingNamespaceDirectives(DestContext, InsertionPoint);
705 Context, DestContext, ND->getDeclContext(), [&](
const Decl *D) {
706 if (D->getKind() != Decl::Namespace)
708 const auto *NS = cast<NamespaceDecl>(D)->getCanonicalDecl();
709 return llvm::any_of(VisibleNamespaceDecls,
710 [NS](const NamespaceDecl *NSD) {
711 return NSD->getCanonicalDecl() == NS;
717 const DeclContext *DestContext,
719 llvm::ArrayRef<std::string> VisibleNamespaces) {
720 for (llvm::StringRef NS : VisibleNamespaces) {
721 assert(NS.ends_with(
"::"));
725 Context, DestContext, ND->getDeclContext(), [&](
const Decl *D) {
726 return llvm::any_of(VisibleNamespaces, [&](llvm::StringRef Namespace) {
728 llvm::raw_string_ostream OS(NS);
729 D->print(OS, Context.getPrintingPolicy());
730 return OS.str() == Namespace;
738 auto *VD = llvm::dyn_cast_or_null<ValueDecl>(D);
739 return VD && !VD->getType().isNull() && VD->getType()->isUndeducedType();
743 size_t ContextDepth = 0;
744 for (
auto *Ctx = D->getDeclContext(); Ctx && !Ctx->isTranslationUnit();
745 Ctx = Ctx->getParent()) {
746 if (++ContextDepth == MaxDepth)
755bool isTemplateTypeParameterPack(NamedDecl *D) {
756 if (
const auto *TTPD = dyn_cast<TemplateTypeParmDecl>(D)) {
757 return TTPD->isParameterPack();
764const TemplateTypeParmType *getFunctionPackType(
const FunctionDecl *Callee) {
765 if (
const auto *TemplateDecl = Callee->getPrimaryTemplate()) {
766 auto TemplateParams = TemplateDecl->getTemplateParameters()->asArray();
768 const auto It = std::find_if(TemplateParams.rbegin(), TemplateParams.rend(),
769 isTemplateTypeParameterPack);
770 if (It != TemplateParams.rend()) {
771 const auto *TTPD = dyn_cast<TemplateTypeParmDecl>(*It);
772 return TTPD->getTypeForDecl()->castAs<TemplateTypeParmType>();
781const TemplateTypeParmType *getUnderlyingPackType(
const ParmVarDecl *Param) {
782 const auto *PlainType = Param->getType().getTypePtr();
783 if (
auto *RT = dyn_cast<ReferenceType>(PlainType))
784 PlainType = RT->getPointeeTypeAsWritten().getTypePtr();
785 if (
const auto *SubstType = dyn_cast<SubstTemplateTypeParmType>(PlainType)) {
786 const auto *ReplacedParameter = SubstType->getReplacedParameter();
787 if (ReplacedParameter->isParameterPack()) {
788 return ReplacedParameter->getTypeForDecl()
789 ->castAs<TemplateTypeParmType>();
813class ForwardingCallVisitor
816 ForwardingCallVisitor(ArrayRef<const ParmVarDecl *> Parameters)
817 : Parameters{Parameters},
818 PackType{getUnderlyingPackType(Parameters.front())} {}
820 bool VisitCallExpr(CallExpr *E) {
821 auto *Callee = getCalleeDeclOrUniqueOverload(E);
823 handleCall(Callee, E->arguments());
825 return !
Info.has_value();
828 bool VisitCXXConstructExpr(CXXConstructExpr *E) {
829 auto *Callee = E->getConstructor();
831 handleCall(Callee, E->arguments());
833 return !
Info.has_value();
837 ArrayRef<const ParmVarDecl *> Parameters;
839 const TemplateTypeParmType *PackType;
841 struct ForwardingInfo {
845 ArrayRef<const ParmVarDecl *>
Head;
849 ArrayRef<const ParmVarDecl *> Pack;
853 ArrayRef<const ParmVarDecl *>
Tail;
856 std::optional<FunctionDecl *> PackTarget;
860 std::optional<ForwardingInfo>
Info;
865 void handleCall(FunctionDecl *Callee,
typename CallExpr::arg_range Args) {
867 if (Callee->parameters().size() < Parameters.size())
869 if (llvm::any_of(Args,
870 [](
const Expr *E) {
return isa<PackExpansionExpr>(E); })) {
873 auto PackLocation = findPack(Args);
876 ArrayRef<ParmVarDecl *> MatchingParams =
877 Callee->parameters().slice(*PackLocation, Parameters.size());
880 if (
const auto *TTPT = getFunctionPackType(Callee)) {
882 auto IsExpandedPack = [&](
const ParmVarDecl *
P) {
883 return getUnderlyingPackType(P) == TTPT;
886 FI.Head = MatchingParams.take_until(IsExpandedPack);
888 MatchingParams.drop_front(FI.Head.size()).take_while(IsExpandedPack);
889 FI.Tail = MatchingParams.drop_front(FI.Head.size() + FI.Pack.size());
890 FI.PackTarget = Callee;
896 FI.Head = MatchingParams;
902 std::optional<size_t> findPack(
typename CallExpr::arg_range Args) {
904 assert(Parameters.size() <=
static_cast<size_t>(llvm::size(Args)));
905 for (
auto Begin = Args.begin(), End = Args.end() - Parameters.size() + 1;
906 Begin != End; ++Begin) {
907 if (
const auto *RefArg = unwrapForward(*Begin)) {
908 if (Parameters.front() != RefArg->getDecl())
913 auto ParamEnd = Begin + Parameters.size() - 1;
914 RefArg = unwrapForward(*ParamEnd);
915 if (!RefArg || Parameters.back() != RefArg->getDecl())
917 return std::distance(Args.begin(), Begin);
923 static FunctionDecl *getCalleeDeclOrUniqueOverload(CallExpr *E) {
924 Decl *CalleeDecl = E->getCalleeDecl();
925 auto *Callee = dyn_cast_or_null<FunctionDecl>(CalleeDecl);
927 if (
auto *Lookup = dyn_cast<UnresolvedLookupExpr>(E->getCallee())) {
928 Callee = resolveOverload(Lookup, E);
932 if (Callee && Callee->getNumParams() == E->getNumArgs())
937 static FunctionDecl *resolveOverload(UnresolvedLookupExpr *Lookup,
939 FunctionDecl *MatchingDecl =
nullptr;
940 if (!Lookup->requiresADL()) {
943 for (
auto *Candidate : Lookup->decls()) {
944 if (
auto *FuncCandidate = dyn_cast_or_null<FunctionDecl>(Candidate)) {
945 if (FuncCandidate->getNumParams() == E->getNumArgs()) {
950 MatchingDecl = FuncCandidate;
960 static const DeclRefExpr *unwrapForward(
const Expr *E) {
961 E = E->IgnoreImplicitAsWritten();
965 if (
const auto *Const = dyn_cast<CXXConstructExpr>(E))
966 if (Const->getConstructor()->isCopyOrMoveConstructor())
967 E = Const->getArg(0)->IgnoreImplicitAsWritten();
968 if (
const auto *Call = dyn_cast<CallExpr>(E)) {
969 const auto Callee =
Call->getBuiltinCallee();
970 if (Callee == Builtin::BIforward) {
971 return dyn_cast<DeclRefExpr>(
972 Call->getArg(0)->IgnoreImplicitAsWritten());
975 return dyn_cast<DeclRefExpr>(E);
981SmallVector<const ParmVarDecl *>
983 auto Parameters = D->parameters();
985 if (
const auto *TTPT = getFunctionPackType(D)) {
987 auto IsExpandedPack = [TTPT](
const ParmVarDecl *P) {
988 return getUnderlyingPackType(P) == TTPT;
990 ArrayRef<const ParmVarDecl *>
Head = Parameters.take_until(IsExpandedPack);
991 ArrayRef<const ParmVarDecl *> Pack =
992 Parameters.drop_front(
Head.size()).take_while(IsExpandedPack);
993 ArrayRef<const ParmVarDecl *>
Tail =
994 Parameters.drop_front(
Head.size() + Pack.size());
995 SmallVector<const ParmVarDecl *> Result(Parameters.size());
997 auto *HeadIt = std::copy(
Head.begin(),
Head.end(), Result.begin());
998 auto TailIt = std::copy(
Tail.rbegin(),
Tail.rend(), Result.rbegin());
1001 const FunctionDecl *CurrentFunction = D;
1002 llvm::SmallPtrSet<const FunctionTemplateDecl *, 4> SeenTemplates;
1003 if (
const auto *
Template = D->getPrimaryTemplate()) {
1006 while (!Pack.empty() && CurrentFunction && Depth < MaxDepth) {
1008 ForwardingCallVisitor V{Pack};
1009 V.TraverseStmt(CurrentFunction->getBody());
1014 auto Info = *V.Info;
1015 HeadIt = std::copy(
Info.Head.begin(),
Info.Head.end(), HeadIt);
1016 TailIt = std::copy(
Info.Tail.rbegin(),
Info.Tail.rend(), TailIt);
1019 CurrentFunction =
Info.PackTarget.value_or(
nullptr);
1022 if (CurrentFunction) {
1023 if (
const auto *
Template = CurrentFunction->getPrimaryTemplate()) {
1024 bool NewFunction = SeenTemplates.insert(
Template).second;
1026 return {Parameters.begin(), Parameters.end()};
1032 HeadIt = std::copy(Pack.begin(), Pack.end(), HeadIt);
1033 assert(TailIt.base() == HeadIt);
1036 return {Parameters.begin(), Parameters.end()};
1040 return getUnderlyingPackType(D) !=
nullptr;