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.AnonymousTagLocations =
false;
219 ND.printQualifiedName(OS, Policy);
220 assert(!StringRef(QName).starts_with(
"::"));
225 return N.isIdentifier() && !N.getAsIdentifierInfo();
229 if (
auto *V = llvm::dyn_cast<DeclaratorDecl>(&ND))
230 return V->getQualifierLoc();
231 if (
auto *T = llvm::dyn_cast<TagDecl>(&ND))
232 return T->getQualifierLoc();
233 return NestedNameSpecifierLoc();
237 const UsingDirectiveDecl &D) {
238 PrintingPolicy PP(Ctx.getLangOpts());
240 llvm::raw_string_ostream Out(Name);
242 D.getQualifier().print(Out, PP);
243 D.getNominatedNamespaceAsWritten()->printName(Out);
247std::string
printName(
const ASTContext &Ctx,
const NamedDecl &ND) {
249 llvm::raw_string_ostream Out(Name);
250 PrintingPolicy PP(Ctx.getLangOpts());
252 PP.SuppressTemplateArgsInCXXConstructors =
true;
255 if (
auto *UD = llvm::dyn_cast<UsingDirectiveDecl>(&ND)) {
256 Out <<
"using namespace ";
257 UD->getQualifier().print(Out, PP);
258 UD->getNominatedNamespaceAsWritten()->printName(Out);
264 if (isa<NamespaceDecl>(ND))
265 return "(anonymous namespace)";
266 if (
auto *Cls = llvm::dyn_cast<RecordDecl>(&ND)) {
269 return (
"(anonymous " + Cls->getKindName() +
")").str();
271 if (isa<EnumDecl>(ND))
272 return "(anonymous enum)";
273 return "(anonymous)";
279 ND.getDeclName().print(Out, PP);
287 std::string TemplateArgs;
288 llvm::raw_string_ostream OS(TemplateArgs);
289 PrintingPolicy Policy(ND.getASTContext().getLangOpts());
290 if (std::optional<llvm::ArrayRef<TemplateArgumentLoc>> Args =
291 getTemplateSpecializationArgLocs(ND)) {
292 printTemplateArgumentList(OS, *Args, Policy);
293 }
else if (
auto *Cls = llvm::dyn_cast<ClassTemplateSpecializationDecl>(&ND)) {
297 printTemplateArgumentList(OS, Cls->getTemplateArgs().asArray(), Policy);
303 for (
const auto *Ctx = &DC; Ctx !=
nullptr; Ctx = Ctx->getParent())
304 if (
const auto *NS = dyn_cast<NamespaceDecl>(Ctx))
305 if (!NS->isAnonymousNamespace() && !NS->isInlineNamespace())
310static llvm::StringRef
312 return ID ? ID->getName() :
"<<error-type>>";
317 llvm::raw_string_ostream OS(Name);
319 OS << (
Method.isInstanceMethod() ?
'-' :
'+') <<
'[';
322 if (
const ObjCContainerDecl *C =
323 dyn_cast<ObjCContainerDecl>(
Method.getDeclContext()))
326 Method.getSelector().print(OS <<
' ');
335 if (
const ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(&C)) {
337 llvm::raw_string_ostream OS(Name);
338 const ObjCInterfaceDecl *
Class = Category->getClassInterface();
343 if (
const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(&C)) {
345 llvm::raw_string_ostream OS(Name);
346 const ObjCInterfaceDecl *
Class = CID->getClassInterface();
350 return C.getNameAsString();
354 llvm::SmallString<128> USR;
355 if (index::generateUSRForDecl(D, USR))
361 const SourceManager &SM) {
364 llvm::SmallString<128> USR;
365 if (index::generateUSRForMacro(MacroName, MI->getDefinitionLoc(), SM, USR))
371 if (
const auto *ID = dyn_cast<ObjCInterfaceDecl>(D))
372 return ID->getImplementation();
373 if (
const auto *CD = dyn_cast<ObjCCategoryDecl>(D)) {
374 if (CD->IsClassExtension()) {
375 if (
const auto *ID = CD->getClassInterface())
376 return ID->getImplementation();
379 return CD->getImplementation();
386 ArrayRef<Inclusion> MainFileIncludes,
387 ArrayRef<const Decl *> TopLevelDecls) {
401 for (
auto &Inc : MainFileIncludes)
402 if (Inc.Directive == tok::pp_import)
408 for (
const Decl *D : TopLevelDecls)
409 if (isa<ObjCContainerDecl, ObjCIvarDecl, ObjCMethodDecl, ObjCPropertyDecl>(
416std::string
printType(
const QualType QT,
const DeclContext &CurContext,
417 const llvm::StringRef Placeholder,
bool FullyQualify) {
419 llvm::raw_string_ostream OS(Result);
420 PrintingPolicy PP(CurContext.getParentASTContext().getPrintingPolicy());
421 PP.SuppressTagKeyword =
true;
422 PP.SuppressUnwrittenScope =
true;
423 PP.FullyQualifiedName = FullyQualify;
425 class PrintCB :
public PrintingCallbacks {
427 PrintCB(
const DeclContext *CurContext) : CurContext(CurContext) {}
428 virtual ~PrintCB() {}
429 bool isScopeVisible(
const DeclContext *DC)
const override {
430 return DC->Encloses(CurContext);
434 const DeclContext *CurContext;
436 PrintCB PCB(&CurContext);
439 QT.print(OS, PP, Placeholder);
444 if (
const auto *ND = llvm::dyn_cast<NamedDecl>(&D))
445 if (
const auto *II = ND->getIdentifier())
451 for (
const DeclContext *D = &DC; D; D = D->getParent()) {
452 if (D->isTransparentContext() || D->isInlineNamespace())
454 if (
const auto *ND = llvm::dyn_cast<NamedDecl>(D))
462 ASTContext &
Context = D->getASTContext();
463 if (
const auto *CTSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>(D))
464 if (
const auto *Args = CTSD->getTemplateArgsAsWritten())
465 return Context.getTemplateSpecializationType(
466 ElaboratedTypeKeyword::None,
467 TemplateName(CTSD->getSpecializedTemplate()), Args->arguments(),
469 return Context.getTypeDeclType(D);
481class DeducedTypeVisitor :
public RecursiveASTVisitor<DeducedTypeVisitor> {
482 SourceLocation SearchedLocation;
483 const HeuristicResolver *Resolver;
486 DeducedTypeVisitor(SourceLocation SearchedLocation,
487 const HeuristicResolver *Resolver)
488 : SearchedLocation(SearchedLocation), Resolver(Resolver) {}
495 bool VisitDeclaratorDecl(DeclaratorDecl *D) {
496 if (!D->getTypeSourceInfo() ||
497 !D->getTypeSourceInfo()->getTypeLoc().getContainedAutoTypeLoc() ||
498 D->getTypeSourceInfo()
500 .getContainedAutoTypeLoc()
501 .getNameLoc() != SearchedLocation)
504 if (
auto *AT = D->getType()->getContainedAutoType()) {
505 if (AT->isUndeducedAutoType()) {
506 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
507 if (Resolver && VD->hasInit()) {
508 DeducedType = Resolver->resolveExprToType(VD->getInit());
513 DeducedType = AT->desugar();
524 bool VisitFunctionDecl(FunctionDecl *D) {
525 if (!
D->getTypeSourceInfo())
528 auto CurLoc =
D->getReturnTypeSourceRange().getBegin();
530 if (CurLoc.isInvalid() && isa<CXXConversionDecl>(D))
531 CurLoc =
D->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
533 if (CurLoc.isInvalid())
534 CurLoc =
D->getSourceRange().getBegin();
535 if (CurLoc != SearchedLocation)
538 const AutoType *AT =
D->getReturnType()->getContainedAutoType();
539 if (AT && !AT->getDeducedType().isNull()) {
540 DeducedType = AT->getDeducedType();
541 }
else if (
auto *DT = dyn_cast<DecltypeType>(
D->getReturnType())) {
544 if (!DT->getUnderlyingType().isNull())
545 DeducedType = DT->getUnderlyingType();
546 }
else if (!
D->getReturnType().isNull()) {
547 DeducedType =
D->getReturnType();
555 bool VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
556 if (TL.getBeginLoc() != SearchedLocation)
563 const DecltypeType *DT = dyn_cast<DecltypeType>(TL.getTypePtr());
564 while (DT && !DT->getUnderlyingType().isNull()) {
565 DeducedType = DT->getUnderlyingType();
566 DT = dyn_cast<DecltypeType>(DeducedType.getTypePtr());
573 bool VisitParmVarDecl(ParmVarDecl *PVD) {
574 if (!PVD->getType()->isDependentType())
577 TemplateTypeParmTypeLoc
Auto =
579 if (
Auto.isNull() ||
Auto.getNameLoc() != SearchedLocation)
584 auto *Templated = llvm::dyn_cast<FunctionDecl>(PVD->getDeclContext());
587 auto *FTD = Templated->getDescribedFunctionTemplate();
590 int ParamIndex = paramIndex(*FTD, *
Auto.getDecl());
591 if (ParamIndex < 0) {
592 assert(
false &&
"auto TTP is not from enclosing function?");
597 auto *Instantiation =
601 const auto *Args = Instantiation->getTemplateSpecializationArgs();
602 if (Args->size() != FTD->getTemplateParameters()->size())
604 DeducedType = Args->get(ParamIndex).getAsType();
608 static int paramIndex(
const TemplateDecl &TD, NamedDecl &Param) {
610 for (
auto *ND : *TD.getTemplateParameters()) {
618 QualType DeducedType;
623 const HeuristicResolver *Resolver,
624 SourceLocation Loc) {
627 DeducedTypeVisitor V(Loc, Resolver);
628 V.TraverseAST(ASTCtx);
629 if (V.DeducedType.isNull())
631 return V.DeducedType;
635 if (
auto QTL = TL.getAs<QualifiedTypeLoc>())
637 if (llvm::isa<PointerType, ReferenceType, ParenType>(TL.getTypePtr()))
639 if (
auto FTL = TL.getAs<FunctionTypeLoc>())
641 if (
auto TTPTL = TL.getAs<TemplateTypeParmTypeLoc>()) {
642 if (TTPTL.getTypePtr()->getDecl()->isImplicit())
648template <
typename TemplateDeclTy>
650 NamedDecl *Only =
nullptr;
651 for (
auto *Spec : TD->specializations()) {
652 if (Spec->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
662 if (TemplateDecl *TD = TemplatedDecl->getDescribedTemplate()) {
663 if (
auto *CTD = llvm::dyn_cast<ClassTemplateDecl>(TD))
665 if (
auto *FTD = llvm::dyn_cast<FunctionTemplateDecl>(TD))
667 if (
auto *VTD = llvm::dyn_cast<VarTemplateDecl>(TD))
674 std::vector<const Attr *> Result;
675 if (
const auto *TL = N.get<TypeLoc>()) {
676 for (AttributedTypeLoc ATL = TL->getAs<AttributedTypeLoc>(); !ATL.isNull();
677 ATL = ATL.getModifiedLoc().getAs<AttributedTypeLoc>()) {
678 if (
const Attr *A = ATL.getAttr())
680 assert(!ATL.getModifiedLoc().isNull());
683 if (
const auto *S = N.get<AttributedStmt>()) {
684 for (; S !=
nullptr; S = dyn_cast<AttributedStmt>(S->getSubStmt()))
685 for (
const Attr *A : S->getAttrs())
689 if (
const auto *D = N.get<Decl>()) {
690 for (
const Attr *A : D->attrs())
698 const DeclContext *DestContext,
699 SourceLocation InsertionPoint,
700 const NamedDecl *ND) {
701 auto VisibleNamespaceDecls =
702 getUsingNamespaceDirectives(DestContext, InsertionPoint);
704 Context, DestContext, ND->getDeclContext(), [&](
const Decl *D) {
705 if (D->getKind() != Decl::Namespace)
707 const auto *NS = cast<NamespaceDecl>(D)->getCanonicalDecl();
708 return llvm::any_of(VisibleNamespaceDecls,
709 [NS](const NamespaceDecl *NSD) {
710 return NSD->getCanonicalDecl() == NS;
716 const DeclContext *DestContext,
718 llvm::ArrayRef<std::string> VisibleNamespaces) {
719 for (llvm::StringRef NS : VisibleNamespaces) {
720 assert(NS.ends_with(
"::"));
724 Context, DestContext, ND->getDeclContext(), [&](
const Decl *D) {
725 return llvm::any_of(VisibleNamespaces, [&](llvm::StringRef Namespace) {
727 llvm::raw_string_ostream OS(NS);
728 D->print(OS, Context.getPrintingPolicy());
729 return OS.str() == Namespace;
737 auto *VD = llvm::dyn_cast_or_null<ValueDecl>(D);
738 return VD && !VD->getType().isNull() && VD->getType()->isUndeducedType();
742 size_t ContextDepth = 0;
743 for (
auto *Ctx = D->getDeclContext(); Ctx && !Ctx->isTranslationUnit();
744 Ctx = Ctx->getParent()) {
745 if (++ContextDepth == MaxDepth)
754bool isTemplateTypeParameterPack(NamedDecl *D) {
755 if (
const auto *TTPD = dyn_cast<TemplateTypeParmDecl>(D)) {
756 return TTPD->isParameterPack();
763const TemplateTypeParmType *getFunctionPackType(
const FunctionDecl *Callee) {
764 if (
const auto *TemplateDecl = Callee->getPrimaryTemplate()) {
765 auto TemplateParams = TemplateDecl->getTemplateParameters()->asArray();
767 const auto It = std::find_if(TemplateParams.rbegin(), TemplateParams.rend(),
768 isTemplateTypeParameterPack);
769 if (It != TemplateParams.rend()) {
770 const auto *TTPD = dyn_cast<TemplateTypeParmDecl>(*It);
771 return TTPD->getTypeForDecl()->castAs<TemplateTypeParmType>();
780const TemplateTypeParmType *getUnderlyingPackType(
const ParmVarDecl *Param) {
781 const auto *PlainType = Param->getType().getTypePtr();
782 if (
auto *RT = dyn_cast<ReferenceType>(PlainType))
783 PlainType = RT->getPointeeTypeAsWritten().getTypePtr();
784 if (
const auto *SubstType = dyn_cast<SubstTemplateTypeParmType>(PlainType)) {
785 const auto *ReplacedParameter = SubstType->getReplacedParameter();
786 if (ReplacedParameter->isParameterPack()) {
787 return ReplacedParameter->getTypeForDecl()
788 ->castAs<TemplateTypeParmType>();
812class ForwardingCallVisitor
815 ForwardingCallVisitor(ArrayRef<const ParmVarDecl *> Parameters)
816 : Parameters{Parameters},
817 PackType{getUnderlyingPackType(Parameters.front())} {}
819 bool VisitCallExpr(CallExpr *E) {
820 auto *Callee = getCalleeDeclOrUniqueOverload(E);
822 handleCall(Callee, E->arguments());
824 return !
Info.has_value();
827 bool VisitCXXConstructExpr(CXXConstructExpr *E) {
828 auto *Callee = E->getConstructor();
830 handleCall(Callee, E->arguments());
832 return !
Info.has_value();
836 ArrayRef<const ParmVarDecl *> Parameters;
838 const TemplateTypeParmType *PackType;
840 struct ForwardingInfo {
844 ArrayRef<const ParmVarDecl *>
Head;
848 ArrayRef<const ParmVarDecl *> Pack;
852 ArrayRef<const ParmVarDecl *>
Tail;
855 std::optional<FunctionDecl *> PackTarget;
859 std::optional<ForwardingInfo>
Info;
864 void handleCall(FunctionDecl *Callee,
typename CallExpr::arg_range Args) {
866 if (Callee->parameters().size() < Parameters.size())
868 if (llvm::any_of(Args,
869 [](
const Expr *E) {
return isa<PackExpansionExpr>(E); })) {
872 auto PackLocation = findPack(Args);
875 ArrayRef<ParmVarDecl *> MatchingParams =
876 Callee->parameters().slice(*PackLocation, Parameters.size());
879 if (
const auto *TTPT = getFunctionPackType(Callee)) {
881 auto IsExpandedPack = [&](
const ParmVarDecl *
P) {
882 return getUnderlyingPackType(P) == TTPT;
885 FI.Head = MatchingParams.take_until(IsExpandedPack);
887 MatchingParams.drop_front(FI.Head.size()).take_while(IsExpandedPack);
888 FI.Tail = MatchingParams.drop_front(FI.Head.size() + FI.Pack.size());
889 FI.PackTarget = Callee;
895 FI.Head = MatchingParams;
901 std::optional<size_t> findPack(
typename CallExpr::arg_range Args) {
903 assert(Parameters.size() <=
static_cast<size_t>(llvm::size(Args)));
904 for (
auto Begin = Args.begin(), End = Args.end() - Parameters.size() + 1;
905 Begin != End; ++Begin) {
906 if (
const auto *RefArg = unwrapForward(*Begin)) {
907 if (Parameters.front() != RefArg->getDecl())
912 auto ParamEnd = Begin + Parameters.size() - 1;
913 RefArg = unwrapForward(*ParamEnd);
914 if (!RefArg || Parameters.back() != RefArg->getDecl())
916 return std::distance(Args.begin(), Begin);
922 static FunctionDecl *getCalleeDeclOrUniqueOverload(CallExpr *E) {
923 Decl *CalleeDecl = E->getCalleeDecl();
924 auto *Callee = dyn_cast_or_null<FunctionDecl>(CalleeDecl);
926 if (
auto *Lookup = dyn_cast<UnresolvedLookupExpr>(E->getCallee())) {
927 Callee = resolveOverload(Lookup, E);
931 if (Callee && Callee->getNumParams() == E->getNumArgs())
936 static FunctionDecl *resolveOverload(UnresolvedLookupExpr *Lookup,
938 FunctionDecl *MatchingDecl =
nullptr;
939 if (!Lookup->requiresADL()) {
942 for (
auto *Candidate : Lookup->decls()) {
943 if (
auto *FuncCandidate = dyn_cast_or_null<FunctionDecl>(Candidate)) {
944 if (FuncCandidate->getNumParams() == E->getNumArgs()) {
949 MatchingDecl = FuncCandidate;
959 static const DeclRefExpr *unwrapForward(
const Expr *E) {
960 E = E->IgnoreImplicitAsWritten();
964 if (
const auto *Const = dyn_cast<CXXConstructExpr>(E))
965 if (Const->getConstructor()->isCopyOrMoveConstructor())
966 E = Const->getArg(0)->IgnoreImplicitAsWritten();
967 if (
const auto *Call = dyn_cast<CallExpr>(E)) {
968 const auto Callee =
Call->getBuiltinCallee();
969 if (Callee == Builtin::BIforward) {
970 return dyn_cast<DeclRefExpr>(
971 Call->getArg(0)->IgnoreImplicitAsWritten());
974 return dyn_cast<DeclRefExpr>(E);
980SmallVector<const ParmVarDecl *>
982 auto Parameters = D->parameters();
984 if (
const auto *TTPT = getFunctionPackType(D)) {
986 auto IsExpandedPack = [TTPT](
const ParmVarDecl *P) {
987 return getUnderlyingPackType(P) == TTPT;
989 ArrayRef<const ParmVarDecl *>
Head = Parameters.take_until(IsExpandedPack);
990 ArrayRef<const ParmVarDecl *> Pack =
991 Parameters.drop_front(
Head.size()).take_while(IsExpandedPack);
992 ArrayRef<const ParmVarDecl *>
Tail =
993 Parameters.drop_front(
Head.size() + Pack.size());
994 SmallVector<const ParmVarDecl *> Result(Parameters.size());
996 auto *HeadIt = std::copy(
Head.begin(),
Head.end(), Result.begin());
997 auto TailIt = std::copy(
Tail.rbegin(),
Tail.rend(), Result.rbegin());
1000 const FunctionDecl *CurrentFunction = D;
1001 llvm::SmallPtrSet<const FunctionTemplateDecl *, 4> SeenTemplates;
1002 if (
const auto *Template = D->getPrimaryTemplate()) {
1003 SeenTemplates.insert(Template);
1005 while (!Pack.empty() && CurrentFunction && Depth < MaxDepth) {
1007 ForwardingCallVisitor V{Pack};
1008 V.TraverseStmt(CurrentFunction->getBody());
1013 auto Info = *V.Info;
1014 HeadIt = std::copy(
Info.Head.begin(),
Info.Head.end(), HeadIt);
1015 TailIt = std::copy(
Info.Tail.rbegin(),
Info.Tail.rend(), TailIt);
1018 CurrentFunction =
Info.PackTarget.value_or(
nullptr);
1021 if (CurrentFunction) {
1022 if (
const auto *Template = CurrentFunction->getPrimaryTemplate()) {
1023 bool NewFunction = SeenTemplates.insert(Template).second;
1025 return {Parameters.begin(), Parameters.end()};
1031 HeadIt = std::copy(Pack.begin(), Pack.end(), HeadIt);
1032 assert(TailIt.base() == HeadIt);
1035 return {Parameters.begin(), Parameters.end()};
1039 return getUnderlyingPackType(D) !=
nullptr;
1043 const auto *FD = FT->getTemplatedDecl();
1044 const auto NumParams = FD->getNumParams();
1046 if (NumParams > 0) {
1047 const auto *LastParam = FD->getParamDecl(NumParams - 1);
1048 if (
const auto *PET = dyn_cast<PackExpansionType>(LastParam->getType())) {
1050 const auto BaseType = PET->getPattern().getNonReferenceType();
1051 if (
const auto *TTPT =
1052 dyn_cast<TemplateTypeParmType>(BaseType.getTypePtr())) {
1054 if (FT->getTemplateParameters()->getDepth() == TTPT->getDepth()) {
1064 :
public RecursiveASTVisitor<ForwardingToConstructorVisitor> {
1068 SmallVector<const CXXConstructorDecl *, 1> &Output)
1075 if (
auto *FD = E->getDirectCallee()) {
1079 if (
auto *PT = FD->getPrimaryTemplate();
1083 Visitor.TraverseStmt(FD->getBody());
1091 if (
auto *CE = E->getConstructExpr())
1092 if (
auto *Callee = CE->getConstructor()) {
1093 auto *Adjusted = &adjustDeclToTemplate(*Callee);
1094 if (
auto *Template = dyn_cast<TemplateDecl>(Adjusted))
1095 Adjusted = Template->getTemplatedDecl();
1096 if (
auto *
Constructor = dyn_cast<CXXConstructorDecl>(Adjusted))
1108SmallVector<const CXXConstructorDecl *, 1>
1110 SmallVector<const CXXConstructorDecl *, 1> Result;
1111 llvm::DenseSet<const FunctionDecl *> SeenFunctions{FD};
1113 Visitor.TraverseStmt(FD->getBody());