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 = 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;
107 const DeclContext *SourceContext,
108 llvm::function_ref<
bool(NestedNameSpecifier *)> IsVisible) {
109 std::vector<const NestedNameSpecifier *>
Parents;
110 bool ReachedNS =
false;
111 for (
const DeclContext *CurContext = SourceContext; CurContext;
112 CurContext = CurContext->getLookupParent()) {
114 if (CurContext->Encloses(DestContext))
117 NestedNameSpecifier *NNS =
nullptr;
118 if (
auto *TD = llvm::dyn_cast<TagDecl>(CurContext)) {
122 NNS = NestedNameSpecifier::Create(
Context,
nullptr,
false,
123 TD->getTypeForDecl());
124 }
else if (
auto *NSD = llvm::dyn_cast<NamespaceDecl>(CurContext)) {
126 NNS = NestedNameSpecifier::Create(
Context,
nullptr, NSD);
129 if (NSD->isAnonymousNamespace() || NSD->isInlineNamespace())
146 llvm::raw_string_ostream
OS(Result);
155 return isTemplateSpecializationKind(D, TSK_ImplicitInstantiation);
159 return isTemplateSpecializationKind(D, TSK_ExplicitSpecialization);
164 D->getASTContext().getSourceManager());
167SourceLocation
nameLocation(
const clang::Decl &D,
const SourceManager &SM) {
168 auto L = D.getLocation();
170 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(&D))
171 L = MD->getSelectorStartLoc();
173 return SM.getSpellingLoc(L);
174 return SM.getExpansionLoc(L);
179 llvm::raw_string_ostream
OS(QName);
180 PrintingPolicy Policy(ND.getASTContext().getLangOpts());
185 Policy.SuppressUnwrittenScope =
true;
188 Policy.AnonymousTagLocations =
false;
189 ND.printQualifiedName(
OS, Policy);
191 assert(!StringRef(QName).starts_with(
"::"));
196 return N.isIdentifier() && !N.getAsIdentifierInfo();
200 if (
auto *V = llvm::dyn_cast<DeclaratorDecl>(&ND))
201 return V->getQualifierLoc();
202 if (
auto *T = llvm::dyn_cast<TagDecl>(&ND))
203 return T->getQualifierLoc();
204 return NestedNameSpecifierLoc();
208 const UsingDirectiveDecl &D) {
209 PrintingPolicy PP(Ctx.getLangOpts());
211 llvm::raw_string_ostream
Out(
Name);
213 if (
auto *Qual = D.getQualifier())
214 Qual->print(
Out, PP);
215 D.getNominatedNamespaceAsWritten()->printName(
Out);
219std::string
printName(
const ASTContext &Ctx,
const NamedDecl &ND) {
221 llvm::raw_string_ostream
Out(
Name);
222 PrintingPolicy PP(Ctx.getLangOpts());
224 PP.SuppressTemplateArgsInCXXConstructors =
true;
227 if (
auto *UD = llvm::dyn_cast<UsingDirectiveDecl>(&ND)) {
228 Out <<
"using namespace ";
229 if (
auto *Qual = UD->getQualifier())
230 Qual->print(
Out, PP);
231 UD->getNominatedNamespaceAsWritten()->printName(
Out);
237 if (isa<NamespaceDecl>(ND))
238 return "(anonymous namespace)";
239 if (
auto *Cls = llvm::dyn_cast<RecordDecl>(&ND)) {
242 return (
"(anonymous " + Cls->getKindName() +
")").str();
244 if (isa<EnumDecl>(ND))
245 return "(anonymous enum)";
246 return "(anonymous)";
251 Qualifier->print(
Out, PP);
253 ND.getDeclName().print(
Out, PP);
261 std::string TemplateArgs;
262 llvm::raw_string_ostream
OS(TemplateArgs);
263 PrintingPolicy Policy(ND.getASTContext().getLangOpts());
264 if (std::optional<llvm::ArrayRef<TemplateArgumentLoc>>
Args =
265 getTemplateSpecializationArgLocs(ND)) {
266 printTemplateArgumentList(
OS, *
Args, Policy);
267 }
else if (
auto *Cls = llvm::dyn_cast<ClassTemplateSpecializationDecl>(&ND)) {
271 printTemplateArgumentList(
OS, Cls->getTemplateArgs().asArray(), Policy);
278 for (
const auto *Ctx = &DC; Ctx !=
nullptr; Ctx = Ctx->getParent())
279 if (
const auto *NS = dyn_cast<NamespaceDecl>(Ctx))
280 if (!NS->isAnonymousNamespace() && !NS->isInlineNamespace())
285static llvm::StringRef
287 return ID ?
ID->getName() :
"<<error-type>>";
292 llvm::raw_string_ostream
OS(
Name);
294 OS << (
Method.isInstanceMethod() ?
'-' :
'+') <<
'[';
297 if (
const ObjCContainerDecl *
C =
298 dyn_cast<ObjCContainerDecl>(
Method.getDeclContext()))
301 Method.getSelector().print(
OS <<
' ');
311 if (
const ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(&
C)) {
313 llvm::raw_string_ostream
OS(
Name);
314 const ObjCInterfaceDecl *
Class = Category->getClassInterface();
320 if (
const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(&
C)) {
322 llvm::raw_string_ostream
OS(
Name);
323 const ObjCInterfaceDecl *
Class = CID->getClassInterface();
328 return C.getNameAsString();
332 llvm::SmallString<128>
USR;
333 if (index::generateUSRForDecl(D,
USR))
339 const SourceManager &SM) {
342 llvm::SmallString<128>
USR;
343 if (index::generateUSRForMacro(
MacroName, MI->getDefinitionLoc(), SM,
USR))
349 if (
const auto *
ID = dyn_cast<ObjCInterfaceDecl>(D))
350 return ID->getImplementation();
351 if (
const auto *CD = dyn_cast<ObjCCategoryDecl>(D)) {
352 if (CD->IsClassExtension()) {
353 if (
const auto *
ID = CD->getClassInterface())
354 return ID->getImplementation();
357 return CD->getImplementation();
364 ArrayRef<Inclusion> MainFileIncludes,
365 ArrayRef<const Decl *> TopLevelDecls) {
379 for (
auto &Inc : MainFileIncludes)
380 if (Inc.Directive == tok::pp_import)
386 for (
const Decl *D : TopLevelDecls)
387 if (isa<ObjCContainerDecl, ObjCIvarDecl, ObjCMethodDecl, ObjCPropertyDecl>(
394std::string
printType(
const QualType QT,
const DeclContext &CurContext,
395 const llvm::StringRef Placeholder) {
397 llvm::raw_string_ostream
OS(Result);
398 PrintingPolicy PP(CurContext.getParentASTContext().getPrintingPolicy());
399 PP.SuppressTagKeyword =
true;
400 PP.SuppressUnwrittenScope =
true;
402 class PrintCB :
public PrintingCallbacks {
404 PrintCB(
const DeclContext *CurContext) : CurContext(CurContext) {}
405 virtual ~PrintCB() {}
406 bool isScopeVisible(
const DeclContext *DC)
const override {
407 return DC->Encloses(CurContext);
411 const DeclContext *CurContext;
413 PrintCB PCB(&CurContext);
416 QT.print(
OS, PP, Placeholder);
421 if (
const auto *ND = llvm::dyn_cast<NamedDecl>(&D))
422 if (
const auto *II = ND->getIdentifier())
428 for (
const DeclContext *D = &DC; D; D = D->getParent()) {
429 if (D->isTransparentContext() || D->isInlineNamespace())
431 if (
const auto *ND = llvm::dyn_cast<NamedDecl>(D))
439 ASTContext &
Context = D->getASTContext();
440 if (
const auto *CTSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>(D))
441 if (
const auto *
Args = CTSD->getTemplateArgsAsWritten())
442 return Context.getTemplateSpecializationType(
443 TemplateName(CTSD->getSpecializedTemplate()),
Args->arguments());
444 return Context.getTypeDeclType(D);
456class DeducedTypeVisitor :
public RecursiveASTVisitor<DeducedTypeVisitor> {
457 SourceLocation SearchedLocation;
460 DeducedTypeVisitor(SourceLocation SearchedLocation)
461 : SearchedLocation(SearchedLocation) {}
468 bool VisitDeclaratorDecl(DeclaratorDecl *D) {
469 if (!D->getTypeSourceInfo() ||
470 !D->getTypeSourceInfo()->getTypeLoc().getContainedAutoTypeLoc() ||
471 D->getTypeSourceInfo()
473 .getContainedAutoTypeLoc()
474 .getNameLoc() != SearchedLocation)
477 if (
auto *AT = D->getType()->getContainedAutoType()) {
489 bool VisitFunctionDecl(FunctionDecl *D) {
490 if (!D->getTypeSourceInfo())
493 auto CurLoc = D->getReturnTypeSourceRange().getBegin();
495 if (CurLoc.isInvalid() && isa<CXXConversionDecl>(D))
496 CurLoc = D->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
498 if (CurLoc.isInvalid())
499 CurLoc = D->getSourceRange().getBegin();
500 if (CurLoc != SearchedLocation)
503 const AutoType *AT = D->getReturnType()->getContainedAutoType();
504 if (AT && !AT->getDeducedType().isNull()) {
506 }
else if (
auto *DT = dyn_cast<DecltypeType>(D->getReturnType())) {
509 if (!DT->getUnderlyingType().isNull())
511 }
else if (!D->getReturnType().isNull()) {
520 bool VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
521 if (TL.getBeginLoc() != SearchedLocation)
528 const DecltypeType *DT = dyn_cast<DecltypeType>(TL.getTypePtr());
529 while (DT && !DT->getUnderlyingType().isNull()) {
531 DT = dyn_cast<DecltypeType>(
DeducedType.getTypePtr());
538 bool VisitParmVarDecl(ParmVarDecl *PVD) {
539 if (!PVD->getType()->isDependentType())
542 TemplateTypeParmTypeLoc
Auto =
544 if (
Auto.isNull() ||
Auto.getNameLoc() != SearchedLocation)
549 auto *Templated = llvm::dyn_cast<FunctionDecl>(PVD->getDeclContext());
552 auto *FTD = Templated->getDescribedFunctionTemplate();
555 int ParamIndex = paramIndex(*FTD, *
Auto.getDecl());
556 if (ParamIndex < 0) {
557 assert(
false &&
"auto TTP is not from enclosing function?");
562 auto *Instantiation =
566 const auto *
Args = Instantiation->getTemplateSpecializationArgs();
567 if (
Args->size() != FTD->getTemplateParameters()->size())
573 static int paramIndex(
const TemplateDecl &TD, NamedDecl &Param) {
575 for (
auto *ND : *TD.getTemplateParameters()) {
590 DeducedTypeVisitor V(
Loc);
591 V.TraverseAST(ASTCtx);
592 if (V.DeducedType.isNull())
594 return V.DeducedType;
598 if (
auto QTL = TL.getAs<QualifiedTypeLoc>())
600 if (llvm::isa<PointerType, ReferenceType, ParenType>(TL.getTypePtr()))
602 if (
auto FTL = TL.getAs<FunctionTypeLoc>())
604 if (
auto TTPTL = TL.getAs<TemplateTypeParmTypeLoc>()) {
605 if (TTPTL.getTypePtr()->getDecl()->isImplicit())
611template <
typename TemplateDeclTy>
613 NamedDecl *Only =
nullptr;
614 for (
auto *Spec : TD->specializations()) {
615 if (Spec->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
625 if (TemplateDecl *TD = TemplatedDecl->getDescribedTemplate()) {
626 if (
auto *CTD = llvm::dyn_cast<ClassTemplateDecl>(TD))
628 if (
auto *FTD = llvm::dyn_cast<FunctionTemplateDecl>(TD))
630 if (
auto *VTD = llvm::dyn_cast<VarTemplateDecl>(TD))
637 std::vector<const Attr *> Result;
638 if (
const auto *TL = N.get<TypeLoc>()) {
639 for (AttributedTypeLoc ATL = TL->getAs<AttributedTypeLoc>(); !ATL.isNull();
640 ATL = ATL.getModifiedLoc().getAs<AttributedTypeLoc>()) {
641 if (
const Attr *A = ATL.getAttr())
643 assert(!ATL.getModifiedLoc().isNull());
646 if (
const auto *S = N.get<AttributedStmt>()) {
647 for (; S !=
nullptr; S = dyn_cast<AttributedStmt>(S->getSubStmt()))
648 for (
const Attr *A : S->getAttrs())
652 if (
const auto *D = N.get<
Decl>()) {
653 for (
const Attr *A : D->attrs())
661 const DeclContext *DestContext,
662 SourceLocation InsertionPoint,
663 const NamedDecl *ND) {
664 auto VisibleNamespaceDecls =
665 getUsingNamespaceDirectives(DestContext, InsertionPoint);
667 Context, DestContext, ND->getDeclContext(),
668 [&](NestedNameSpecifier *NNS) {
669 if (NNS->getKind() != NestedNameSpecifier::Namespace)
671 const auto *CanonNSD = NNS->getAsNamespace()->getCanonicalDecl();
672 return llvm::any_of(VisibleNamespaceDecls,
673 [CanonNSD](const NamespaceDecl *NSD) {
674 return NSD->getCanonicalDecl() == CanonNSD;
680 const DeclContext *DestContext,
682 llvm::ArrayRef<std::string> VisibleNamespaces) {
683 for (llvm::StringRef NS : VisibleNamespaces) {
684 assert(NS.ends_with(
"::"));
688 Context, DestContext, ND->getDeclContext(),
689 [&](NestedNameSpecifier *NNS) {
690 return llvm::any_of(VisibleNamespaces, [&](llvm::StringRef Namespace) {
692 llvm::raw_string_ostream OS(NS);
693 NNS->print(OS, Context.getPrintingPolicy());
694 return OS.str() == Namespace;
702 auto *VD = llvm::dyn_cast_or_null<ValueDecl>(D);
703 return VD && !VD->getType().isNull() && VD->getType()->isUndeducedType();
707 size_t ContextDepth = 0;
708 for (
auto *Ctx = D->getDeclContext(); Ctx && !Ctx->isTranslationUnit();
709 Ctx = Ctx->getParent()) {
710 if (++ContextDepth == MaxDepth)
719bool isTemplateTypeParameterPack(NamedDecl *D) {
720 if (
const auto *TTPD = dyn_cast<TemplateTypeParmDecl>(D)) {
721 return TTPD->isParameterPack();
728const TemplateTypeParmType *getFunctionPackType(
const FunctionDecl *Callee) {
729 if (
const auto *TemplateDecl = Callee->getPrimaryTemplate()) {
730 auto TemplateParams = TemplateDecl->getTemplateParameters()->asArray();
732 const auto It = std::find_if(TemplateParams.rbegin(), TemplateParams.rend(),
733 isTemplateTypeParameterPack);
734 if (It != TemplateParams.rend()) {
735 const auto *TTPD = dyn_cast<TemplateTypeParmDecl>(*It);
736 return TTPD->getTypeForDecl()->castAs<TemplateTypeParmType>();
745const TemplateTypeParmType *getUnderlyingPackType(
const ParmVarDecl *Param) {
746 const auto *PlainType = Param->getType().getTypePtr();
747 if (
auto *RT = dyn_cast<ReferenceType>(PlainType))
748 PlainType = RT->getPointeeTypeAsWritten().getTypePtr();
749 if (
const auto *SubstType = dyn_cast<SubstTemplateTypeParmType>(PlainType)) {
750 const auto *ReplacedParameter = SubstType->getReplacedParameter();
751 if (ReplacedParameter->isParameterPack()) {
752 return ReplacedParameter->getTypeForDecl()
753 ->castAs<TemplateTypeParmType>();
777class ForwardingCallVisitor
780 ForwardingCallVisitor(ArrayRef<const ParmVarDecl *>
Parameters)
784 bool VisitCallExpr(CallExpr *
E) {
785 auto *Callee = getCalleeDeclOrUniqueOverload(
E);
787 handleCall(Callee,
E->arguments());
789 return !
Info.has_value();
792 bool VisitCXXConstructExpr(CXXConstructExpr *
E) {
793 auto *Callee =
E->getConstructor();
795 handleCall(Callee,
E->arguments());
797 return !
Info.has_value();
805 struct ForwardingInfo {
809 ArrayRef<const ParmVarDecl *>
Head;
813 ArrayRef<const ParmVarDecl *>
Pack;
817 ArrayRef<const ParmVarDecl *>
Tail;
824 std::optional<ForwardingInfo>
Info;
829 void handleCall(FunctionDecl *Callee,
typename CallExpr::arg_range
Args) {
831 if (Callee->parameters().size() <
Parameters.size())
833 if (llvm::any_of(
Args,
834 [](
const Expr *
E) {
return isa<PackExpansionExpr>(
E); })) {
837 auto PackLocation = findPack(
Args);
840 ArrayRef<ParmVarDecl *> MatchingParams =
841 Callee->parameters().slice(*PackLocation,
Parameters.size());
844 if (
const auto *TTPT = getFunctionPackType(Callee)) {
846 auto IsExpandedPack = [&](
const ParmVarDecl *P) {
847 return getUnderlyingPackType(P) == TTPT;
850 FI.Head = MatchingParams.take_until(IsExpandedPack);
852 MatchingParams.drop_front(FI.Head.size()).take_while(IsExpandedPack);
853 FI.Tail = MatchingParams.drop_front(FI.Head.size() + FI.Pack.size());
854 FI.PackTarget = Callee;
860 FI.Head = MatchingParams;
866 std::optional<size_t> findPack(
typename CallExpr::arg_range
Args) {
868 assert(
Parameters.size() <=
static_cast<size_t>(llvm::size(
Args)));
870 Begin != End; ++Begin) {
871 if (
const auto *RefArg = unwrapForward(*Begin)) {
877 auto ParamEnd = Begin +
Parameters.size() - 1;
878 RefArg = unwrapForward(*ParamEnd);
879 if (!RefArg ||
Parameters.back() != RefArg->getDecl())
881 return std::distance(
Args.begin(), Begin);
887 static FunctionDecl *getCalleeDeclOrUniqueOverload(CallExpr *
E) {
888 Decl *CalleeDecl =
E->getCalleeDecl();
889 auto *Callee = dyn_cast_or_null<FunctionDecl>(CalleeDecl);
891 if (
auto *Lookup = dyn_cast<UnresolvedLookupExpr>(
E->getCallee())) {
892 Callee = resolveOverload(Lookup,
E);
896 if (Callee && Callee->getNumParams() ==
E->getNumArgs())
901 static FunctionDecl *resolveOverload(UnresolvedLookupExpr *Lookup,
903 FunctionDecl *MatchingDecl =
nullptr;
904 if (!Lookup->requiresADL()) {
907 for (
auto *
Candidate : Lookup->decls()) {
908 if (
auto *FuncCandidate = dyn_cast_or_null<FunctionDecl>(
Candidate)) {
909 if (FuncCandidate->getNumParams() ==
E->getNumArgs()) {
914 MatchingDecl = FuncCandidate;
924 static const DeclRefExpr *unwrapForward(
const Expr *
E) {
925 E =
E->IgnoreImplicitAsWritten();
929 if (
const auto *
Const = dyn_cast<CXXConstructExpr>(
E))
930 if (
Const->getConstructor()->isCopyOrMoveConstructor())
931 E =
Const->getArg(0)->IgnoreImplicitAsWritten();
932 if (
const auto *Call = dyn_cast<CallExpr>(
E)) {
933 const auto Callee = Call->getBuiltinCallee();
934 if (Callee == Builtin::BIforward) {
935 return dyn_cast<DeclRefExpr>(
936 Call->getArg(0)->IgnoreImplicitAsWritten());
939 return dyn_cast<DeclRefExpr>(
E);
945SmallVector<const ParmVarDecl *>
949 if (
const auto *TTPT = getFunctionPackType(D)) {
951 auto IsExpandedPack = [TTPT](
const ParmVarDecl *P) {
952 return getUnderlyingPackType(P) == TTPT;
954 ArrayRef<const ParmVarDecl *>
Head =
Parameters.take_until(IsExpandedPack);
955 ArrayRef<const ParmVarDecl *>
Pack =
957 ArrayRef<const ParmVarDecl *>
Tail =
959 SmallVector<const ParmVarDecl *> Result(
Parameters.size());
961 auto *HeadIt = std::copy(
Head.begin(),
Head.end(), Result.begin());
962 auto TailIt = std::copy(
Tail.rbegin(),
Tail.rend(), Result.rbegin());
965 const FunctionDecl *CurrentFunction = D;
966 llvm::SmallSet<const FunctionTemplateDecl *, 4> SeenTemplates;
967 if (
const auto *Template = D->getPrimaryTemplate()) {
968 SeenTemplates.insert(Template);
970 while (!
Pack.empty() && CurrentFunction && Depth < MaxDepth) {
972 ForwardingCallVisitor V{
Pack};
973 V.TraverseStmt(CurrentFunction->getBody());
979 HeadIt = std::copy(
Info.Head.begin(),
Info.Head.end(), HeadIt);
980 TailIt = std::copy(
Info.Tail.rbegin(),
Info.Tail.rend(), TailIt);
983 CurrentFunction =
Info.PackTarget.value_or(
nullptr);
986 if (CurrentFunction) {
987 if (
const auto *Template = CurrentFunction->getPrimaryTemplate()) {
988 bool NewFunction = SeenTemplates.insert(Template).second;
996 HeadIt = std::copy(
Pack.begin(),
Pack.end(), HeadIt);
997 assert(TailIt.base() == HeadIt);
1004 return getUnderlyingPackType(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
llvm::SmallString< 256U > Name
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"