12#include "clang/AST/ASTContext.h"
13#include "clang/AST/ASTTypeTraits.h"
14#include "clang/AST/Decl.h"
15#include "clang/AST/DeclBase.h"
16#include "clang/AST/DeclCXX.h"
17#include "clang/AST/DeclObjC.h"
18#include "clang/AST/DeclTemplate.h"
19#include "clang/AST/DeclarationName.h"
20#include "clang/AST/ExprCXX.h"
21#include "clang/AST/NestedNameSpecifier.h"
22#include "clang/AST/PrettyPrinter.h"
23#include "clang/AST/RecursiveASTVisitor.h"
24#include "clang/AST/Stmt.h"
25#include "clang/AST/TemplateBase.h"
26#include "clang/AST/TypeLoc.h"
27#include "clang/Basic/Builtins.h"
28#include "clang/Basic/SourceLocation.h"
29#include "clang/Basic/SourceManager.h"
30#include "clang/Basic/Specifiers.h"
31#include "clang/Index/USRGeneration.h"
32#include "llvm/ADT/ArrayRef.h"
33#include "llvm/ADT/STLExtras.h"
34#include "llvm/ADT/SmallSet.h"
35#include "llvm/ADT/StringRef.h"
36#include "llvm/Support/Casting.h"
37#include "llvm/Support/raw_ostream.h"
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 =
54 llvm::dyn_cast<ClassTemplatePartialSpecializationDecl>(&ND)) {
55 if (
auto *
Args = Cls->getTemplateArgsAsWritten())
56 return Args->arguments();
57 }
else if (
auto *Var =
58 llvm::dyn_cast<VarTemplatePartialSpecializationDecl>(&ND)) {
59 if (
auto *
Args = Var->getTemplateArgsAsWritten())
60 return Args->arguments();
61 }
else if (
auto *Var = llvm::dyn_cast<VarTemplateSpecializationDecl>(&ND)) {
62 if (
auto *
Args = Var->getTemplateArgsInfo())
63 return Args->arguments();
71bool isTemplateSpecializationKind(
const NamedDecl *D,
72 TemplateSpecializationKind
Kind) {
73 if (
const auto *TD = dyn_cast<T>(D))
74 return TD->getTemplateSpecializationKind() ==
Kind;
78bool isTemplateSpecializationKind(
const NamedDecl *D,
79 TemplateSpecializationKind
Kind) {
80 return isTemplateSpecializationKind<FunctionDecl>(D,
Kind) ||
81 isTemplateSpecializationKind<CXXRecordDecl>(D,
Kind) ||
82 isTemplateSpecializationKind<VarDecl>(D,
Kind);
87llvm::DenseSet<const NamespaceDecl *>
88getUsingNamespaceDirectives(
const DeclContext *DestContext,
89 SourceLocation Until) {
90 const auto &SM = DestContext->getParentASTContext().getSourceManager();
91 llvm::DenseSet<const NamespaceDecl *> VisibleNamespaceDecls;
92 for (
const auto *DC = DestContext; DC; DC = DC->getLookupParent()) {
93 for (
const auto *D : DC->decls()) {
94 if (!SM.isWrittenInSameFile(D->getLocation(), Until) ||
95 !SM.isBeforeInTranslationUnit(D->getLocation(), Until))
97 if (
auto *UDD = llvm::dyn_cast<UsingDirectiveDecl>(D))
98 VisibleNamespaceDecls.insert(
99 UDD->getNominatedNamespace()->getCanonicalDecl());
102 return VisibleNamespaceDecls;
112 const DeclContext *SourceContext,
113 llvm::function_ref<
bool(NestedNameSpecifier *)> IsVisible) {
114 std::vector<const NestedNameSpecifier *>
Parents;
115 bool ReachedNS =
false;
116 for (
const DeclContext *CurContext = SourceContext; CurContext;
117 CurContext = CurContext->getLookupParent()) {
119 if (CurContext->Encloses(DestContext))
122 NestedNameSpecifier *NNS =
nullptr;
123 if (
auto *TD = llvm::dyn_cast<TagDecl>(CurContext)) {
127 NNS = NestedNameSpecifier::Create(
Context,
nullptr,
false,
128 TD->getTypeForDecl());
129 }
else if (
auto *NSD = llvm::dyn_cast<NamespaceDecl>(CurContext)) {
131 NNS = NestedNameSpecifier::Create(
Context,
nullptr, NSD);
134 if (NSD->isAnonymousNamespace() || NSD->isInlineNamespace())
151 llvm::raw_string_ostream
OS(Result);
160 return isTemplateSpecializationKind(D, TSK_ImplicitInstantiation);
164 return isTemplateSpecializationKind(D, TSK_ExplicitSpecialization);
169 D->getASTContext().getSourceManager());
172SourceLocation
nameLocation(
const clang::Decl &D,
const SourceManager &SM) {
173 auto L = D.getLocation();
175 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(&D))
176 L = MD->getSelectorStartLoc();
178 return SM.getSpellingLoc(L);
179 return SM.getExpansionLoc(L);
184 llvm::raw_string_ostream
OS(QName);
185 PrintingPolicy Policy(ND.getASTContext().getLangOpts());
190 Policy.SuppressUnwrittenScope =
true;
193 Policy.AnonymousTagLocations =
false;
194 ND.printQualifiedName(
OS, Policy);
196 assert(!StringRef(QName).startswith(
"::"));
201 return N.isIdentifier() && !N.getAsIdentifierInfo();
205 if (
auto *V = llvm::dyn_cast<DeclaratorDecl>(&ND))
206 return V->getQualifierLoc();
207 if (
auto *T = llvm::dyn_cast<TagDecl>(&ND))
208 return T->getQualifierLoc();
209 return NestedNameSpecifierLoc();
213 const UsingDirectiveDecl &D) {
214 PrintingPolicy PP(Ctx.getLangOpts());
216 llvm::raw_string_ostream
Out(
Name);
218 if (
auto *Qual = D.getQualifier())
219 Qual->print(
Out, PP);
220 D.getNominatedNamespaceAsWritten()->printName(
Out);
224std::string
printName(
const ASTContext &Ctx,
const NamedDecl &ND) {
226 llvm::raw_string_ostream
Out(
Name);
227 PrintingPolicy PP(Ctx.getLangOpts());
229 PP.SuppressTemplateArgsInCXXConstructors =
true;
232 if (
auto *UD = llvm::dyn_cast<UsingDirectiveDecl>(&ND)) {
233 Out <<
"using namespace ";
234 if (
auto *Qual = UD->getQualifier())
235 Qual->print(
Out, PP);
236 UD->getNominatedNamespaceAsWritten()->printName(
Out);
242 if (isa<NamespaceDecl>(ND))
243 return "(anonymous namespace)";
244 if (
auto *Cls = llvm::dyn_cast<RecordDecl>(&ND)) {
247 return (
"(anonymous " + Cls->getKindName() +
")").str();
249 if (isa<EnumDecl>(ND))
250 return "(anonymous enum)";
251 return "(anonymous)";
256 Qualifier->print(
Out, PP);
258 ND.getDeclName().print(
Out, PP);
266 std::string TemplateArgs;
267 llvm::raw_string_ostream
OS(TemplateArgs);
268 PrintingPolicy Policy(ND.getASTContext().getLangOpts());
269 if (std::optional<llvm::ArrayRef<TemplateArgumentLoc>>
Args =
270 getTemplateSpecializationArgLocs(ND)) {
271 printTemplateArgumentList(
OS, *
Args, Policy);
272 }
else if (
auto *Cls = llvm::dyn_cast<ClassTemplateSpecializationDecl>(&ND)) {
273 if (
const TypeSourceInfo *TSI = Cls->getTypeAsWritten()) {
277 auto STL = TSI->getTypeLoc().getAs<TemplateSpecializationTypeLoc>();
278 llvm::SmallVector<TemplateArgumentLoc> ArgLocs;
279 ArgLocs.reserve(STL.getNumArgs());
280 for (
unsigned I = 0; I < STL.getNumArgs(); ++I)
281 ArgLocs.push_back(STL.getArgLoc(I));
282 printTemplateArgumentList(
OS, ArgLocs, Policy);
287 printTemplateArgumentList(
OS, Cls->getTemplateArgs().asArray(), Policy);
295 for (
const auto *Ctx = &DC; Ctx !=
nullptr; Ctx = Ctx->getParent())
296 if (
const auto *NS = dyn_cast<NamespaceDecl>(Ctx))
297 if (!NS->isAnonymousNamespace() && !NS->isInlineNamespace())
302static llvm::StringRef
304 return ID ? ID->getName() :
"<<error-type>>";
309 llvm::raw_string_ostream
OS(
Name);
311 OS << (
Method.isInstanceMethod() ?
'-' :
'+') <<
'[';
314 if (
const ObjCContainerDecl *
C =
315 dyn_cast<ObjCContainerDecl>(
Method.getDeclContext()))
318 Method.getSelector().print(
OS <<
' ');
328 if (
const ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(&
C)) {
330 llvm::raw_string_ostream
OS(
Name);
331 const ObjCInterfaceDecl *
Class = Category->getClassInterface();
337 if (
const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(&
C)) {
339 llvm::raw_string_ostream
OS(
Name);
340 const ObjCInterfaceDecl *
Class = CID->getClassInterface();
345 return C.getNameAsString();
349 llvm::SmallString<128>
USR;
350 if (index::generateUSRForDecl(D,
USR))
356 const SourceManager &SM) {
359 llvm::SmallString<128>
USR;
360 if (index::generateUSRForMacro(
MacroName, MI->getDefinitionLoc(), SM,
USR))
366 if (
const auto *ID = dyn_cast<ObjCInterfaceDecl>(D))
367 return ID->getImplementation();
368 if (
const auto *CD = dyn_cast<ObjCCategoryDecl>(D)) {
369 if (CD->IsClassExtension()) {
370 if (
const auto *ID = CD->getClassInterface())
371 return ID->getImplementation();
374 return CD->getImplementation();
381 ArrayRef<Inclusion> MainFileIncludes,
382 ArrayRef<const Decl *> TopLevelDecls) {
396 for (
auto &Inc : MainFileIncludes)
397 if (Inc.Directive == tok::pp_import)
403 for (
const Decl *D : TopLevelDecls)
404 if (isa<ObjCContainerDecl, ObjCIvarDecl, ObjCMethodDecl, ObjCPropertyDecl>(
411std::string
printType(
const QualType QT,
const DeclContext &CurContext,
412 const llvm::StringRef Placeholder) {
414 llvm::raw_string_ostream
OS(Result);
415 PrintingPolicy PP(CurContext.getParentASTContext().getPrintingPolicy());
416 PP.SuppressTagKeyword =
true;
417 PP.SuppressUnwrittenScope =
true;
419 class PrintCB :
public PrintingCallbacks {
421 PrintCB(
const DeclContext *CurContext) : CurContext(CurContext) {}
422 virtual ~PrintCB() {}
423 bool isScopeVisible(
const DeclContext *DC)
const override {
424 return DC->Encloses(CurContext);
428 const DeclContext *CurContext;
430 PrintCB PCB(&CurContext);
433 QT.print(
OS, PP, Placeholder);
438 if (
const auto *ND = llvm::dyn_cast<NamedDecl>(&D))
439 if (
const auto *II = ND->getIdentifier())
445 for (
const DeclContext *D = &DC; D; D = D->getParent()) {
446 if (D->isTransparentContext() || D->isInlineNamespace())
448 if (
const auto *ND = llvm::dyn_cast<NamedDecl>(D))
456 if (
const auto *CTSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>(D))
457 if (
const auto *TSI = CTSD->getTypeAsWritten())
458 return TSI->getType();
459 return D->getASTContext().getTypeDeclType(D);
471class DeducedTypeVisitor :
public RecursiveASTVisitor<DeducedTypeVisitor> {
472 SourceLocation SearchedLocation;
475 DeducedTypeVisitor(SourceLocation SearchedLocation)
476 : SearchedLocation(SearchedLocation) {}
483 bool VisitDeclaratorDecl(DeclaratorDecl *D) {
484 if (!D->getTypeSourceInfo() ||
485 D->getTypeSourceInfo()->getTypeLoc().getBeginLoc() != SearchedLocation)
488 if (
auto *AT = D->getType()->getContainedAutoType()) {
500 bool VisitFunctionDecl(FunctionDecl *D) {
501 if (!
D->getTypeSourceInfo())
504 auto CurLoc =
D->getReturnTypeSourceRange().getBegin();
506 if (CurLoc.isInvalid() && isa<CXXConversionDecl>(D))
507 CurLoc =
D->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
509 if (CurLoc.isInvalid())
510 CurLoc =
D->getSourceRange().getBegin();
511 if (CurLoc != SearchedLocation)
514 const AutoType *AT =
D->getReturnType()->getContainedAutoType();
515 if (AT && !AT->getDeducedType().isNull()) {
517 }
else if (
auto *DT = dyn_cast<DecltypeType>(
D->getReturnType())) {
520 if (!DT->getUnderlyingType().isNull())
522 }
else if (!
D->getReturnType().isNull()) {
531 bool VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
532 if (TL.getBeginLoc() != SearchedLocation)
539 const DecltypeType *DT = dyn_cast<DecltypeType>(TL.getTypePtr());
540 while (DT && !DT->getUnderlyingType().isNull()) {
542 DT = dyn_cast<DecltypeType>(
DeducedType.getTypePtr());
549 bool VisitParmVarDecl(ParmVarDecl *PVD) {
550 if (!PVD->getType()->isDependentType())
553 TemplateTypeParmTypeLoc
Auto =
555 if (
Auto.isNull() ||
Auto.getNameLoc() != SearchedLocation)
560 auto *Templated = llvm::dyn_cast<FunctionDecl>(PVD->getDeclContext());
563 auto *FTD = Templated->getDescribedFunctionTemplate();
566 int ParamIndex = paramIndex(*FTD, *
Auto.getDecl());
567 if (ParamIndex < 0) {
568 assert(
false &&
"auto TTP is not from enclosing function?");
573 auto *Instantiation =
577 const auto *
Args = Instantiation->getTemplateSpecializationArgs();
578 if (
Args->size() != FTD->getTemplateParameters()->size())
584 static int paramIndex(
const TemplateDecl &TD, NamedDecl &Param) {
586 for (
auto *ND : *TD.getTemplateParameters()) {
601 DeducedTypeVisitor V(
Loc);
602 V.TraverseAST(ASTCtx);
603 if (V.DeducedType.isNull())
605 return V.DeducedType;
609 if (
auto QTL = TL.getAs<QualifiedTypeLoc>())
611 if (llvm::isa<PointerType, ReferenceType, ParenType>(TL.getTypePtr()))
613 if (
auto FTL = TL.getAs<FunctionTypeLoc>())
615 if (
auto TTPTL = TL.getAs<TemplateTypeParmTypeLoc>()) {
616 if (TTPTL.getTypePtr()->getDecl()->isImplicit())
622template <
typename TemplateDeclTy>
624 NamedDecl *Only =
nullptr;
625 for (
auto *Spec : TD->specializations()) {
626 if (Spec->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
636 if (TemplateDecl *TD = TemplatedDecl->getDescribedTemplate()) {
637 if (
auto *CTD = llvm::dyn_cast<ClassTemplateDecl>(TD))
639 if (
auto *FTD = llvm::dyn_cast<FunctionTemplateDecl>(TD))
641 if (
auto *VTD = llvm::dyn_cast<VarTemplateDecl>(TD))
648 std::vector<const Attr *> Result;
649 if (
const auto *TL = N.get<TypeLoc>()) {
650 for (AttributedTypeLoc ATL = TL->getAs<AttributedTypeLoc>(); !ATL.isNull();
651 ATL = ATL.getModifiedLoc().getAs<AttributedTypeLoc>()) {
652 if (
const Attr *A = ATL.getAttr())
654 assert(!ATL.getModifiedLoc().isNull());
657 if (
const auto *S = N.get<AttributedStmt>()) {
658 for (; S !=
nullptr; S = dyn_cast<AttributedStmt>(S->getSubStmt()))
659 for (
const Attr *A : S->getAttrs())
663 if (
const auto *D = N.get<
Decl>()) {
664 for (
const Attr *A : D->attrs())
672 const DeclContext *DestContext,
673 SourceLocation InsertionPoint,
674 const NamedDecl *ND) {
675 auto VisibleNamespaceDecls =
676 getUsingNamespaceDirectives(DestContext, InsertionPoint);
678 Context, DestContext, ND->getDeclContext(),
679 [&](NestedNameSpecifier *NNS) {
680 if (NNS->getKind() != NestedNameSpecifier::Namespace)
682 const auto *CanonNSD = NNS->getAsNamespace()->getCanonicalDecl();
683 return llvm::any_of(VisibleNamespaceDecls,
684 [CanonNSD](const NamespaceDecl *NSD) {
685 return NSD->getCanonicalDecl() == CanonNSD;
691 const DeclContext *DestContext,
693 llvm::ArrayRef<std::string> VisibleNamespaces) {
694 for (llvm::StringRef NS : VisibleNamespaces) {
695 assert(NS.endswith(
"::"));
699 Context, DestContext, ND->getDeclContext(),
700 [&](NestedNameSpecifier *NNS) {
701 return llvm::any_of(VisibleNamespaces, [&](llvm::StringRef Namespace) {
703 llvm::raw_string_ostream OS(NS);
704 NNS->print(OS, Context.getPrintingPolicy());
705 return OS.str() == Namespace;
713 auto *VD = llvm::dyn_cast_or_null<ValueDecl>(D);
714 return VD && !VD->getType().isNull() && VD->getType()->isUndeducedType();
718 size_t ContextDepth = 0;
719 for (
auto *Ctx = D->getDeclContext(); Ctx && !Ctx->isTranslationUnit();
720 Ctx = Ctx->getParent()) {
721 if (++ContextDepth == MaxDepth)
730bool isTemplateTypeParameterPack(NamedDecl *D) {
731 if (
const auto *TTPD = dyn_cast<TemplateTypeParmDecl>(D)) {
732 return TTPD->isParameterPack();
739const TemplateTypeParmType *getFunctionPackType(
const FunctionDecl *Callee) {
740 if (
const auto *TemplateDecl = Callee->getPrimaryTemplate()) {
741 auto TemplateParams = TemplateDecl->getTemplateParameters()->asArray();
743 const auto It = std::find_if(TemplateParams.rbegin(), TemplateParams.rend(),
744 isTemplateTypeParameterPack);
745 if (It != TemplateParams.rend()) {
746 const auto *TTPD = dyn_cast<TemplateTypeParmDecl>(*It);
747 return TTPD->getTypeForDecl()->castAs<TemplateTypeParmType>();
756const TemplateTypeParmType *getUnderylingPackType(
const ParmVarDecl *Param) {
757 const auto *PlainType = Param->getType().getTypePtr();
758 if (
auto *RT = dyn_cast<ReferenceType>(PlainType))
759 PlainType = RT->getPointeeTypeAsWritten().getTypePtr();
760 if (
const auto *SubstType = dyn_cast<SubstTemplateTypeParmType>(PlainType)) {
761 const auto *ReplacedParameter = SubstType->getReplacedParameter();
762 if (ReplacedParameter->isParameterPack()) {
763 return ReplacedParameter->getTypeForDecl()
764 ->castAs<TemplateTypeParmType>();
788class ForwardingCallVisitor
791 ForwardingCallVisitor(ArrayRef<const ParmVarDecl *>
Parameters)
795 bool VisitCallExpr(CallExpr *
E) {
796 auto *Callee = getCalleeDeclOrUniqueOverload(
E);
798 handleCall(Callee,
E->arguments());
800 return !
Info.has_value();
803 bool VisitCXXConstructExpr(CXXConstructExpr *
E) {
804 auto *Callee =
E->getConstructor();
806 handleCall(Callee,
E->arguments());
808 return !
Info.has_value();
816 struct ForwardingInfo {
820 ArrayRef<const ParmVarDecl *>
Head;
824 ArrayRef<const ParmVarDecl *>
Pack;
828 ArrayRef<const ParmVarDecl *>
Tail;
835 std::optional<ForwardingInfo>
Info;
840 void handleCall(FunctionDecl *Callee,
typename CallExpr::arg_range
Args) {
842 if (Callee->parameters().size() <
Parameters.size())
844 if (llvm::any_of(
Args,
845 [](
const Expr *
E) {
return isa<PackExpansionExpr>(
E); })) {
848 auto PackLocation = findPack(
Args);
851 ArrayRef<ParmVarDecl *> MatchingParams =
852 Callee->parameters().slice(*PackLocation,
Parameters.size());
855 if (
const auto *TTPT = getFunctionPackType(Callee)) {
857 auto IsExpandedPack = [&](
const ParmVarDecl *P) {
858 return getUnderylingPackType(P) == TTPT;
861 FI.Head = MatchingParams.take_until(IsExpandedPack);
863 MatchingParams.drop_front(FI.Head.size()).take_while(IsExpandedPack);
864 FI.Tail = MatchingParams.drop_front(FI.Head.size() + FI.Pack.size());
865 FI.PackTarget = Callee;
871 FI.Head = MatchingParams;
877 std::optional<size_t> findPack(
typename CallExpr::arg_range
Args) {
879 assert(
Parameters.size() <=
static_cast<size_t>(llvm::size(
Args)));
881 Begin != End; ++Begin) {
882 if (
const auto *RefArg = unwrapForward(*Begin)) {
888 auto ParamEnd = Begin +
Parameters.size() - 1;
889 RefArg = unwrapForward(*ParamEnd);
890 if (!RefArg ||
Parameters.back() != RefArg->getDecl())
892 return std::distance(
Args.begin(), Begin);
898 static FunctionDecl *getCalleeDeclOrUniqueOverload(CallExpr *
E) {
899 Decl *CalleeDecl =
E->getCalleeDecl();
900 auto *Callee = dyn_cast_or_null<FunctionDecl>(CalleeDecl);
902 if (
auto *Lookup = dyn_cast<UnresolvedLookupExpr>(
E->getCallee())) {
903 Callee = resolveOverload(Lookup,
E);
907 if (Callee && Callee->getNumParams() ==
E->getNumArgs())
912 static FunctionDecl *resolveOverload(UnresolvedLookupExpr *Lookup,
914 FunctionDecl *MatchingDecl =
nullptr;
915 if (!Lookup->requiresADL()) {
918 for (
auto *
Candidate : Lookup->decls()) {
919 if (
auto *FuncCandidate = dyn_cast_or_null<FunctionDecl>(
Candidate)) {
920 if (FuncCandidate->getNumParams() ==
E->getNumArgs()) {
925 MatchingDecl = FuncCandidate;
935 static const DeclRefExpr *unwrapForward(
const Expr *
E) {
936 E =
E->IgnoreImplicitAsWritten();
940 if (
const auto *
Const = dyn_cast<CXXConstructExpr>(
E))
941 if (
Const->getConstructor()->isCopyOrMoveConstructor())
942 E =
Const->getArg(0)->IgnoreImplicitAsWritten();
943 if (
const auto *Call = dyn_cast<CallExpr>(
E)) {
944 const auto Callee = Call->getBuiltinCallee();
945 if (Callee == Builtin::BIforward) {
946 return dyn_cast<DeclRefExpr>(
947 Call->getArg(0)->IgnoreImplicitAsWritten());
950 return dyn_cast<DeclRefExpr>(
E);
956SmallVector<const ParmVarDecl *>
960 if (
const auto *TTPT = getFunctionPackType(D)) {
962 auto IsExpandedPack = [TTPT](
const ParmVarDecl *P) {
963 return getUnderylingPackType(P) == TTPT;
965 ArrayRef<const ParmVarDecl *>
Head =
Parameters.take_until(IsExpandedPack);
966 ArrayRef<const ParmVarDecl *>
Pack =
968 ArrayRef<const ParmVarDecl *>
Tail =
970 SmallVector<const ParmVarDecl *> Result(
Parameters.size());
972 auto HeadIt = std::copy(
Head.begin(),
Head.end(), Result.begin());
973 auto TailIt = std::copy(
Tail.rbegin(),
Tail.rend(), Result.rbegin());
976 const FunctionDecl *CurrentFunction = D;
977 llvm::SmallSet<const FunctionTemplateDecl *, 4> SeenTemplates;
978 if (
const auto *Template = D->getPrimaryTemplate()) {
979 SeenTemplates.insert(Template);
981 while (!
Pack.empty() && CurrentFunction && Depth < MaxDepth) {
983 ForwardingCallVisitor V{
Pack};
984 V.TraverseStmt(CurrentFunction->getBody());
990 HeadIt = std::copy(
Info.Head.begin(),
Info.Head.end(), HeadIt);
991 TailIt = std::copy(
Info.Tail.rbegin(),
Info.Tail.rend(), TailIt);
994 CurrentFunction =
Info.PackTarget.value_or(
nullptr);
997 if (CurrentFunction) {
998 if (
const auto *Template = CurrentFunction->getPrimaryTemplate()) {
999 bool NewFunction = SeenTemplates.insert(Template).second;
1007 HeadIt = std::copy(
Pack.begin(),
Pack.end(), HeadIt);
1008 assert(TailIt.base() == HeadIt);
1015 return getUnderylingPackType(D) !=
nullptr;
const TemplateTypeParmType * PackType
ArrayRef< const ParmVarDecl * > Tail
ArrayRef< const ParmVarDecl * > Parameters
ArrayRef< const ParmVarDecl * > Head
std::optional< ForwardingInfo > Info
ArrayRef< const ParmVarDecl * > Pack
std::optional< FunctionDecl * > PackTarget
const FunctionDecl * Decl
CompiledFragmentImpl & Out
llvm::raw_string_ostream OS
A context is an immutable container for per-request data that must be propagated through layers that ...
SmallVector< const ParmVarDecl * > resolveForwardingParameters(const FunctionDecl *D, unsigned MaxDepth)
Recursively resolves the parameters of a FunctionDecl that forwards its parameters to another functio...
static llvm::StringRef getNameOrErrForObjCInterface(const ObjCInterfaceDecl *ID)
std::string printTemplateSpecializationArgs(const NamedDecl &ND)
Prints template arguments of a decl as written in the source code, including enclosing '<' and '>',...
std::string printObjCMethod(const ObjCMethodDecl &Method)
Print the Objective-C method name, including the full container name, e.g.
SymbolID getSymbolID(const Decl *D)
Gets the symbol ID for a declaration. Returned SymbolID might be null.
std::string printType(const QualType QT, const DeclContext &CurContext, const llvm::StringRef Placeholder)
Returns a QualType as string.
std::string printName(const ASTContext &Ctx, const NamedDecl &ND)
Prints unqualified name of the decl for the purpose of displaying it to the user.
std::string printObjCContainer(const ObjCContainerDecl &C)
Print the Objective-C container name including categories, e.g. MyClass,.
std::string getQualification(ASTContext &Context, const DeclContext *DestContext, SourceLocation InsertionPoint, const NamedDecl *ND)
Gets the nested name specifier necessary for spelling ND in DestContext, at InsertionPoint.
bool isReservedName(llvm::StringRef Name)
Returns true if Name is reserved, like _Foo or __Vector_base.
bool isExplicitTemplateSpecialization(const NamedDecl *D)
Indicates if D is an explicit template specialization, e.g.
NamedDecl * getOnlyInstantiation(NamedDecl *TemplatedDecl)
SourceLocation nameLocation(const clang::Decl &D, const SourceManager &SM)
Find the source location of the identifier for D.
NestedNameSpecifierLoc getQualifierLoc(const NamedDecl &ND)
Returns a nested name specifier loc of ND if it was present in the source, e.g.
static NamedDecl * getOnlyInstantiationImpl(TemplateDeclTy *TD)
Symbol::IncludeDirective preferredIncludeDirective(llvm::StringRef FileName, const LangOptions &LangOpts, ArrayRef< Inclusion > MainFileIncludes, ArrayRef< const Decl * > TopLevelDecls)
Infer the include directive to use for the given FileName.
bool isExpandedFromParameterPack(const ParmVarDecl *D)
Checks whether D is instantiated from a function parameter pack whose type is a bare type parameter p...
bool hasUnstableLinkage(const Decl *D)
Whether we must avoid computing linkage for D during code completion.
std::string printUsingNamespaceName(const ASTContext &Ctx, const UsingDirectiveDecl &D)
Returns the name of the namespace inside the 'using namespace' directive, as written in the code.
bool hasReservedName(const Decl &D)
Returns true if this is a NamedDecl with a reserved name.
std::vector< const Attr * > getAttributes(const DynTypedNode &N)
Return attributes attached directly to a node.
static bool isAnonymous(const DeclarationName &N)
@ Auto
Diagnostics must not be generated for this snapshot.
QualType declaredType(const TypeDecl *D)
bool isImplementationDetail(const Decl *D)
Returns true if the declaration is considered implementation detail based on heuristics.
const ObjCImplDecl * getCorrespondingObjCImpl(const ObjCContainerDecl *D)
Return the corresponding implementation/definition for the given ObjC container if it has one,...
bool isImplicitTemplateInstantiation(const NamedDecl *D)
Indicates if D is a template instantiation implicitly generated by the compiler, e....
bool hasReservedScope(const DeclContext &DC)
Returns true if this scope would be written with a reserved name.
bool isSpelledInSource(SourceLocation Loc, const SourceManager &SM)
Returns true if the token at Loc is spelled in the source code.
std::string printQualifiedName(const NamedDecl &ND)
Returns the qualified name of ND.
TemplateTypeParmTypeLoc getContainedAutoParamType(TypeLoc TL)
bool isDeeplyNested(const Decl *D, unsigned MaxDepth)
Checks whether D is more than MaxDepth away from translation unit scope.
bool isHeaderFile(llvm::StringRef FileName, std::optional< LangOptions > LangOpts)
Infers whether this is a header from the FileName and LangOpts (if presents).
std::string printNamespaceScope(const DeclContext &DC)
Returns the first enclosing namespace scope starting from DC.
std::optional< QualType > getDeducedType(ASTContext &ASTCtx, SourceLocation Loc)
Retrieves the deduced type at a given location (auto, decltype).
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
@ Include
#include "header.h"
@ Import
#import "header.h"