1176 lines · cpp
1//===--- FindTarget.cpp - What does an AST node refer to? -----------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "FindTarget.h"10#include "AST.h"11#include "support/Logger.h"12#include "clang/AST/ASTConcept.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/DeclTemplate.h"18#include "clang/AST/DeclVisitor.h"19#include "clang/AST/DeclarationName.h"20#include "clang/AST/Expr.h"21#include "clang/AST/ExprCXX.h"22#include "clang/AST/ExprConcepts.h"23#include "clang/AST/ExprObjC.h"24#include "clang/AST/NestedNameSpecifier.h"25#include "clang/AST/PrettyPrinter.h"26#include "clang/AST/RecursiveASTVisitor.h"27#include "clang/AST/StmtVisitor.h"28#include "clang/AST/TemplateBase.h"29#include "clang/AST/Type.h"30#include "clang/AST/TypeLoc.h"31#include "clang/AST/TypeLocVisitor.h"32#include "clang/AST/TypeVisitor.h"33#include "clang/Basic/LangOptions.h"34#include "clang/Basic/SourceLocation.h"35#include "clang/Basic/SourceManager.h"36#include "clang/Basic/Specifiers.h"37#include "clang/Sema/HeuristicResolver.h"38#include "llvm/ADT/STLExtras.h"39#include "llvm/ADT/SmallVector.h"40#include "llvm/ADT/StringExtras.h"41#include "llvm/Support/Casting.h"42#include "llvm/Support/Compiler.h"43#include "llvm/Support/raw_ostream.h"44#include <iterator>45#include <string>46#include <utility>47#include <vector>48 49namespace clang {50namespace clangd {51namespace {52 53[[maybe_unused]] std::string nodeToString(const DynTypedNode &N) {54 std::string S = std::string(N.getNodeKind().asStringRef());55 {56 llvm::raw_string_ostream OS(S);57 OS << ": ";58 N.print(OS, PrintingPolicy(LangOptions()));59 }60 llvm::replace(S, '\n', ' ');61 return S;62}63 64const NamedDecl *getTemplatePattern(const NamedDecl *D) {65 if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(D)) {66 if (const auto *Result = CRD->getTemplateInstantiationPattern())67 return Result;68 // getTemplateInstantiationPattern returns null if the Specialization is69 // incomplete (e.g. the type didn't need to be complete), fall back to the70 // primary template.71 if (CRD->getTemplateSpecializationKind() == TSK_Undeclared)72 if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(CRD))73 return Spec->getSpecializedTemplate()->getTemplatedDecl();74 } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {75 return FD->getTemplateInstantiationPattern();76 } else if (auto *VD = dyn_cast<VarDecl>(D)) {77 // Hmm: getTIP returns its arg if it's not an instantiation?!78 VarDecl *T = VD->getTemplateInstantiationPattern();79 return (T == D) ? nullptr : T;80 } else if (const auto *ED = dyn_cast<EnumDecl>(D)) {81 return ED->getInstantiatedFromMemberEnum();82 } else if (isa<FieldDecl>(D) || isa<TypedefNameDecl>(D)) {83 if (const auto *Parent = llvm::dyn_cast<NamedDecl>(D->getDeclContext()))84 if (const DeclContext *ParentPat =85 dyn_cast_or_null<DeclContext>(getTemplatePattern(Parent)))86 for (const NamedDecl *BaseND : ParentPat->lookup(D->getDeclName()))87 if (!BaseND->isImplicit() && BaseND->getKind() == D->getKind())88 return BaseND;89 } else if (const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {90 if (const auto *ED = dyn_cast<EnumDecl>(ECD->getDeclContext())) {91 if (const EnumDecl *Pattern = ED->getInstantiatedFromMemberEnum()) {92 for (const NamedDecl *BaseECD : Pattern->lookup(ECD->getDeclName()))93 return BaseECD;94 }95 }96 }97 return nullptr;98}99 100// Returns true if the `TypedefNameDecl` should not be reported.101bool shouldSkipTypedef(const TypedefNameDecl *TD) {102 // These should be treated as keywords rather than decls - the typedef is an103 // odd implementation detail.104 if (TD == TD->getASTContext().getObjCInstanceTypeDecl() ||105 TD == TD->getASTContext().getObjCIdDecl())106 return true;107 return false;108}109 110// TargetFinder locates the entities that an AST node refers to.111//112// Typically this is (possibly) one declaration and (possibly) one type, but113// may be more:114// - for ambiguous nodes like OverloadExpr115// - if we want to include e.g. both typedefs and the underlying type116//117// This is organized as a set of mutually recursive helpers for particular node118// types, but for most nodes this is a short walk rather than a deep traversal.119//120// It's tempting to do e.g. typedef resolution as a second normalization step,121// after finding the 'primary' decl etc. But we do this monolithically instead122// because:123// - normalization may require these traversals again (e.g. unwrapping a124// typedef reveals a decltype which must be traversed)125// - it doesn't simplify that much, e.g. the first stage must still be able126// to yield multiple decls to handle OverloadExpr127// - there are cases where it's required for correctness. e.g:128// template<class X> using pvec = vector<x*>; pvec<int> x;129// There's no Decl `pvec<int>`, we must choose `pvec<X>` or `vector<int*>`130// and both are lossy. We must know upfront what the caller ultimately wants.131struct TargetFinder {132 using RelSet = DeclRelationSet;133 using Rel = DeclRelation;134 135private:136 const HeuristicResolver *Resolver;137 llvm::SmallDenseMap<const NamedDecl *,138 std::pair<RelSet, /*InsertionOrder*/ size_t>>139 Decls;140 llvm::SmallDenseMap<const Decl *, RelSet> Seen;141 RelSet Flags;142 143 template <typename T> void debug(T &Node, RelSet Flags) {144 dlog("visit [{0}] {1}", Flags, nodeToString(DynTypedNode::create(Node)));145 }146 147 void report(const NamedDecl *D, RelSet Flags) {148 dlog("--> [{0}] {1}", Flags, nodeToString(DynTypedNode::create(*D)));149 auto It = Decls.try_emplace(D, std::make_pair(Flags, Decls.size()));150 // If already exists, update the flags.151 if (!It.second)152 It.first->second.first |= Flags;153 }154 155public:156 TargetFinder(const HeuristicResolver *Resolver) : Resolver(Resolver) {}157 158 llvm::SmallVector<std::pair<const NamedDecl *, RelSet>, 1> takeDecls() const {159 using ValTy = std::pair<const NamedDecl *, RelSet>;160 llvm::SmallVector<ValTy, 1> Result;161 Result.resize(Decls.size());162 for (const auto &Elem : Decls)163 Result[Elem.second.second] = {Elem.first, Elem.second.first};164 return Result;165 }166 167 void add(const Decl *Dcl, RelSet Flags) {168 const NamedDecl *D = llvm::dyn_cast_or_null<NamedDecl>(Dcl);169 if (!D)170 return;171 debug(*D, Flags);172 173 // Avoid recursion (which can arise in the presence of heuristic174 // resolution of dependent names) by exiting early if we have175 // already seen this decl with all flags in Flags.176 auto Res = Seen.try_emplace(D);177 if (!Res.second && Res.first->second.contains(Flags))178 return;179 Res.first->second |= Flags;180 181 if (const UsingDirectiveDecl *UDD = llvm::dyn_cast<UsingDirectiveDecl>(D))182 D = UDD->getNominatedNamespaceAsWritten();183 184 if (const TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(D)) {185 add(TND->getUnderlyingType(), Flags | Rel::Underlying);186 Flags |= Rel::Alias; // continue with the alias.187 } else if (const UsingDecl *UD = dyn_cast<UsingDecl>(D)) {188 // no Underlying as this is a non-renaming alias.189 for (const UsingShadowDecl *S : UD->shadows())190 add(S->getUnderlyingDecl(), Flags);191 Flags |= Rel::Alias; // continue with the alias.192 } else if (const UsingEnumDecl *UED = dyn_cast<UsingEnumDecl>(D)) {193 // UsingEnumDecl is not an alias at all, just a reference.194 D = UED->getEnumDecl();195 } else if (const auto *NAD = dyn_cast<NamespaceAliasDecl>(D)) {196 add(NAD->getUnderlyingDecl(), Flags | Rel::Underlying);197 Flags |= Rel::Alias; // continue with the alias198 } else if (const UnresolvedUsingValueDecl *UUVD =199 dyn_cast<UnresolvedUsingValueDecl>(D)) {200 if (Resolver) {201 for (const NamedDecl *Target : Resolver->resolveUsingValueDecl(UUVD)) {202 add(Target, Flags); // no Underlying as this is a non-renaming alias203 }204 }205 Flags |= Rel::Alias; // continue with the alias206 } else if (isa<UnresolvedUsingTypenameDecl>(D)) {207 // FIXME: improve common dependent scope using name lookup in primary208 // templates.209 Flags |= Rel::Alias;210 } else if (const UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(D)) {211 // Include the introducing UsingDecl, but don't traverse it. This may end212 // up including *all* shadows, which we don't want.213 // Don't apply this logic to UsingEnumDecl, which can't easily be214 // conflated with the aliases it introduces.215 if (llvm::isa<UsingDecl>(USD->getIntroducer()))216 report(USD->getIntroducer(), Flags | Rel::Alias);217 // Shadow decls are synthetic and not themselves interesting.218 // Record the underlying decl instead, if allowed.219 D = USD->getTargetDecl();220 } else if (const auto *DG = dyn_cast<CXXDeductionGuideDecl>(D)) {221 D = DG->getDeducedTemplate();222 } else if (const ObjCImplementationDecl *IID =223 dyn_cast<ObjCImplementationDecl>(D)) {224 // Treat ObjC{Interface,Implementation}Decl as if they were a decl/def225 // pair as long as the interface isn't implicit.226 if (const auto *CID = IID->getClassInterface())227 if (const auto *DD = CID->getDefinition())228 if (!DD->isImplicitInterfaceDecl())229 D = DD;230 } else if (const ObjCCategoryImplDecl *CID =231 dyn_cast<ObjCCategoryImplDecl>(D)) {232 // Treat ObjC{Category,CategoryImpl}Decl as if they were a decl/def pair.233 D = CID->getCategoryDecl();234 }235 if (!D)236 return;237 238 if (const Decl *Pat = getTemplatePattern(D)) {239 assert(Pat != D);240 add(Pat, Flags | Rel::TemplatePattern);241 // Now continue with the instantiation.242 Flags |= Rel::TemplateInstantiation;243 }244 245 report(D, Flags);246 }247 248 void add(const Stmt *S, RelSet Flags) {249 if (!S)250 return;251 debug(*S, Flags);252 struct Visitor : public ConstStmtVisitor<Visitor> {253 TargetFinder &Outer;254 RelSet Flags;255 Visitor(TargetFinder &Outer, RelSet Flags) : Outer(Outer), Flags(Flags) {}256 257 void VisitCallExpr(const CallExpr *CE) {258 Outer.add(CE->getCalleeDecl(), Flags);259 }260 void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E) {261 Outer.add(E->getConceptReference(), Flags);262 }263 void VisitDeclRefExpr(const DeclRefExpr *DRE) {264 const Decl *D = DRE->getDecl();265 // UsingShadowDecl allows us to record the UsingDecl.266 // getFoundDecl() returns the wrong thing in other cases (templates).267 if (auto *USD = llvm::dyn_cast<UsingShadowDecl>(DRE->getFoundDecl()))268 D = USD;269 Outer.add(D, Flags);270 }271 void VisitMemberExpr(const MemberExpr *ME) {272 const Decl *D = ME->getMemberDecl();273 if (auto *USD =274 llvm::dyn_cast<UsingShadowDecl>(ME->getFoundDecl().getDecl()))275 D = USD;276 Outer.add(D, Flags);277 }278 void VisitOverloadExpr(const OverloadExpr *OE) {279 for (auto *D : OE->decls())280 Outer.add(D, Flags);281 }282 void VisitSizeOfPackExpr(const SizeOfPackExpr *SE) {283 Outer.add(SE->getPack(), Flags);284 }285 void VisitCXXConstructExpr(const CXXConstructExpr *CCE) {286 Outer.add(CCE->getConstructor(), Flags);287 }288 void VisitDesignatedInitExpr(const DesignatedInitExpr *DIE) {289 for (const DesignatedInitExpr::Designator &D :290 llvm::reverse(DIE->designators()))291 if (D.isFieldDesignator()) {292 Outer.add(D.getFieldDecl(), Flags);293 // We don't know which designator was intended, we assume the outer.294 break;295 }296 }297 void VisitGotoStmt(const GotoStmt *Goto) {298 if (auto *LabelDecl = Goto->getLabel())299 Outer.add(LabelDecl, Flags);300 }301 void VisitLabelStmt(const LabelStmt *Label) {302 if (auto *LabelDecl = Label->getDecl())303 Outer.add(LabelDecl, Flags);304 }305 void306 VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {307 if (Outer.Resolver) {308 for (const NamedDecl *D : Outer.Resolver->resolveMemberExpr(E)) {309 Outer.add(D, Flags);310 }311 }312 }313 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E) {314 if (Outer.Resolver) {315 for (const NamedDecl *D : Outer.Resolver->resolveDeclRefExpr(E)) {316 Outer.add(D, Flags);317 }318 }319 }320 void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *OIRE) {321 Outer.add(OIRE->getDecl(), Flags);322 }323 void VisitObjCMessageExpr(const ObjCMessageExpr *OME) {324 Outer.add(OME->getMethodDecl(), Flags);325 }326 void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *OPRE) {327 if (OPRE->isExplicitProperty())328 Outer.add(OPRE->getExplicitProperty(), Flags);329 else {330 if (OPRE->isMessagingGetter())331 Outer.add(OPRE->getImplicitPropertyGetter(), Flags);332 if (OPRE->isMessagingSetter())333 Outer.add(OPRE->getImplicitPropertySetter(), Flags);334 }335 }336 void VisitObjCProtocolExpr(const ObjCProtocolExpr *OPE) {337 Outer.add(OPE->getProtocol(), Flags);338 }339 void VisitOpaqueValueExpr(const OpaqueValueExpr *OVE) {340 Outer.add(OVE->getSourceExpr(), Flags);341 }342 void VisitPseudoObjectExpr(const PseudoObjectExpr *POE) {343 Outer.add(POE->getSyntacticForm(), Flags);344 }345 void VisitCXXNewExpr(const CXXNewExpr *CNE) {346 Outer.add(CNE->getOperatorNew(), Flags);347 }348 void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE) {349 Outer.add(CDE->getOperatorDelete(), Flags);350 }351 void352 VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *RBO) {353 Outer.add(RBO->getDecomposedForm().InnerBinOp, Flags);354 }355 };356 Visitor(*this, Flags).Visit(S);357 }358 359 void add(QualType T, RelSet Flags) {360 if (T.isNull())361 return;362 debug(T, Flags);363 struct Visitor : public TypeVisitor<Visitor> {364 TargetFinder &Outer;365 RelSet Flags;366 Visitor(TargetFinder &Outer, RelSet Flags) : Outer(Outer), Flags(Flags) {}367 368 void VisitTagType(const TagType *TT) {369 Outer.add(cast<TagType>(TT)->getDecl(), Flags);370 }371 372 void VisitUsingType(const UsingType *ET) {373 Outer.add(ET->getDecl(), Flags);374 }375 376 void VisitDecltypeType(const DecltypeType *DTT) {377 Outer.add(DTT->getUnderlyingType(), Flags | Rel::Underlying);378 }379 void VisitDeducedType(const DeducedType *DT) {380 // FIXME: In practice this doesn't work: the AutoType you find inside381 // TypeLoc never has a deduced type. https://llvm.org/PR42914382 Outer.add(DT->getDeducedType(), Flags);383 }384 void VisitUnresolvedUsingType(const UnresolvedUsingType *UUT) {385 Outer.add(UUT->getDecl(), Flags);386 }387 void VisitDeducedTemplateSpecializationType(388 const DeducedTemplateSpecializationType *DTST) {389 if (const auto *USD = DTST->getTemplateName().getAsUsingShadowDecl())390 Outer.add(USD, Flags);391 392 // FIXME: This is a workaround for https://llvm.org/PR42914,393 // which is causing DTST->getDeducedType() to be empty. We394 // fall back to the template pattern and miss the instantiation395 // even when it's known in principle. Once that bug is fixed,396 // the following code can be removed (the existing handling in397 // VisitDeducedType() is sufficient).398 if (auto *TD = DTST->getTemplateName().getAsTemplateDecl())399 Outer.add(TD->getTemplatedDecl(), Flags | Rel::TemplatePattern);400 }401 void VisitDependentNameType(const DependentNameType *DNT) {402 if (Outer.Resolver) {403 for (const NamedDecl *ND :404 Outer.Resolver->resolveDependentNameType(DNT)) {405 Outer.add(ND, Flags);406 }407 }408 }409 void VisitTypedefType(const TypedefType *TT) {410 if (shouldSkipTypedef(TT->getDecl()))411 return;412 Outer.add(TT->getDecl(), Flags);413 }414 void415 VisitTemplateSpecializationType(const TemplateSpecializationType *TST) {416 // Have to handle these case-by-case.417 418 if (const auto *UTN = TST->getTemplateName().getAsUsingShadowDecl())419 Outer.add(UTN, Flags);420 421 // templated type aliases: there's no specialized/instantiated using422 // decl to point to. So try to find a decl for the underlying type423 // (after substitution), and failing that point to the (templated) using424 // decl.425 if (TST->isTypeAlias()) {426 Outer.add(TST->getAliasedType(), Flags | Rel::Underlying);427 // Don't *traverse* the alias, which would result in traversing the428 // template of the underlying type.429 430 TemplateDecl *TD = TST->getTemplateName().getAsTemplateDecl();431 // Builtin templates e.g. __make_integer_seq, __type_pack_element432 // are such that they don't have alias *decls*. Even then, we still433 // traverse their desugared *types* so that instantiated decls are434 // collected.435 if (llvm::isa<BuiltinTemplateDecl>(TD))436 return;437 Outer.report(TD->getTemplatedDecl(),438 Flags | Rel::Alias | Rel::TemplatePattern);439 }440 // specializations of template template parameters aren't instantiated441 // into decls, so they must refer to the parameter itself.442 else if (const auto *Parm =443 llvm::dyn_cast_or_null<TemplateTemplateParmDecl>(444 TST->getTemplateName().getAsTemplateDecl()))445 Outer.add(Parm, Flags);446 // class template specializations have a (specialized) CXXRecordDecl.447 else if (const CXXRecordDecl *RD = TST->getAsCXXRecordDecl())448 Outer.add(RD, Flags); // add(Decl) will despecialize if needed.449 else if (auto *TD = TST->getTemplateName().getAsTemplateDecl())450 // fallback: the (un-specialized) declaration from primary template.451 Outer.add(TD->getTemplatedDecl(), Flags | Rel::TemplatePattern);452 else if (Outer.Resolver)453 for (const NamedDecl *ND :454 Outer.Resolver->resolveTemplateSpecializationType(TST))455 Outer.add(ND, Flags);456 }457 void458 VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *STTPT) {459 Outer.add(STTPT->getReplacementType(), Flags);460 }461 void VisitTemplateTypeParmType(const TemplateTypeParmType *TTPT) {462 Outer.add(TTPT->getDecl(), Flags);463 }464 void VisitObjCInterfaceType(const ObjCInterfaceType *OIT) {465 Outer.add(OIT->getDecl(), Flags);466 }467 };468 Visitor(*this, Flags).Visit(T.getTypePtr());469 }470 471 void add(NestedNameSpecifier NNS, RelSet Flags) {472 if (!NNS)473 return;474 debug(NNS, Flags);475 switch (NNS.getKind()) {476 case NestedNameSpecifier::Kind::Namespace:477 add(NNS.getAsNamespaceAndPrefix().Namespace, Flags);478 return;479 case NestedNameSpecifier::Kind::Type:480 add(QualType(NNS.getAsType(), 0), Flags);481 return;482 case NestedNameSpecifier::Kind::Global:483 // This should be TUDecl, but we can't get a pointer to it!484 return;485 case NestedNameSpecifier::Kind::MicrosoftSuper:486 add(NNS.getAsMicrosoftSuper(), Flags);487 return;488 case NestedNameSpecifier::Kind::Null:489 llvm_unreachable("unexpected null nested name specifier");490 }491 llvm_unreachable("unhandled NestedNameSpecifier::Kind");492 }493 494 void add(const CXXCtorInitializer *CCI, RelSet Flags) {495 if (!CCI)496 return;497 debug(*CCI, Flags);498 499 if (CCI->isAnyMemberInitializer())500 add(CCI->getAnyMember(), Flags);501 // Constructor calls contain a TypeLoc node, so we don't handle them here.502 }503 504 void add(const TemplateArgument &Arg, RelSet Flags) {505 // Only used for template template arguments.506 // For type and non-type template arguments, SelectionTree507 // will hit a more specific node (e.g. a TypeLoc or a508 // DeclRefExpr).509 if (Arg.getKind() == TemplateArgument::Template ||510 Arg.getKind() == TemplateArgument::TemplateExpansion) {511 if (TemplateDecl *TD =512 Arg.getAsTemplateOrTemplatePattern().getAsTemplateDecl()) {513 report(TD, Flags);514 }515 if (const auto *USD =516 Arg.getAsTemplateOrTemplatePattern().getAsUsingShadowDecl())517 add(USD, Flags);518 }519 }520 521 void add(const ConceptReference *CR, RelSet Flags) {522 add(CR->getNamedConcept(), Flags);523 }524};525 526} // namespace527 528llvm::SmallVector<std::pair<const NamedDecl *, DeclRelationSet>, 1>529allTargetDecls(const DynTypedNode &N, const HeuristicResolver *Resolver) {530 dlog("allTargetDecls({0})", nodeToString(N));531 TargetFinder Finder(Resolver);532 DeclRelationSet Flags;533 if (const Decl *D = N.get<Decl>())534 Finder.add(D, Flags);535 else if (const Stmt *S = N.get<Stmt>())536 Finder.add(S, Flags);537 else if (const NestedNameSpecifierLoc *NNSL = N.get<NestedNameSpecifierLoc>())538 Finder.add(NNSL->getNestedNameSpecifier(), Flags);539 else if (const NestedNameSpecifier *NNS = N.get<NestedNameSpecifier>())540 Finder.add(*NNS, Flags);541 else if (const TypeLoc *TL = N.get<TypeLoc>())542 Finder.add(TL->getType(), Flags);543 else if (const QualType *QT = N.get<QualType>())544 Finder.add(*QT, Flags);545 else if (const CXXCtorInitializer *CCI = N.get<CXXCtorInitializer>())546 Finder.add(CCI, Flags);547 else if (const TemplateArgumentLoc *TAL = N.get<TemplateArgumentLoc>())548 Finder.add(TAL->getArgument(), Flags);549 else if (const CXXBaseSpecifier *CBS = N.get<CXXBaseSpecifier>())550 Finder.add(CBS->getTypeSourceInfo()->getType(), Flags);551 else if (const ObjCProtocolLoc *PL = N.get<ObjCProtocolLoc>())552 Finder.add(PL->getProtocol(), Flags);553 else if (const ConceptReference *CR = N.get<ConceptReference>())554 Finder.add(CR, Flags);555 return Finder.takeDecls();556}557 558llvm::SmallVector<const NamedDecl *, 1>559targetDecl(const DynTypedNode &N, DeclRelationSet Mask,560 const HeuristicResolver *Resolver) {561 llvm::SmallVector<const NamedDecl *, 1> Result;562 for (const auto &Entry : allTargetDecls(N, Resolver)) {563 if (!(Entry.second & ~Mask))564 Result.push_back(Entry.first);565 }566 return Result;567}568 569llvm::SmallVector<const NamedDecl *, 1>570explicitReferenceTargets(DynTypedNode N, DeclRelationSet Mask,571 const HeuristicResolver *Resolver) {572 assert(!(Mask & (DeclRelation::TemplatePattern |573 DeclRelation::TemplateInstantiation)) &&574 "explicitReferenceTargets handles templates on its own");575 auto Decls = allTargetDecls(N, Resolver);576 577 // We prefer to return template instantiation, but fallback to template578 // pattern if instantiation is not available.579 Mask |= DeclRelation::TemplatePattern | DeclRelation::TemplateInstantiation;580 581 llvm::SmallVector<const NamedDecl *, 1> TemplatePatterns;582 llvm::SmallVector<const NamedDecl *, 1> Targets;583 bool SeenTemplateInstantiations = false;584 for (auto &D : Decls) {585 if (D.second & ~Mask)586 continue;587 if (D.second & DeclRelation::TemplatePattern) {588 TemplatePatterns.push_back(D.first);589 continue;590 }591 if (D.second & DeclRelation::TemplateInstantiation)592 SeenTemplateInstantiations = true;593 Targets.push_back(D.first);594 }595 if (!SeenTemplateInstantiations)596 Targets.insert(Targets.end(), TemplatePatterns.begin(),597 TemplatePatterns.end());598 return Targets;599}600 601namespace {602llvm::SmallVector<ReferenceLoc> refInDecl(const Decl *D,603 const HeuristicResolver *Resolver) {604 struct Visitor : ConstDeclVisitor<Visitor> {605 Visitor(const HeuristicResolver *Resolver) : Resolver(Resolver) {}606 607 const HeuristicResolver *Resolver;608 llvm::SmallVector<ReferenceLoc> Refs;609 610 void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {611 // We want to keep it as non-declaration references, as the612 // "using namespace" declaration doesn't have a name.613 Refs.push_back(ReferenceLoc{D->getQualifierLoc(),614 D->getIdentLocation(),615 /*IsDecl=*/false,616 {D->getNominatedNamespaceAsWritten()}});617 }618 619 void VisitUsingDecl(const UsingDecl *D) {620 // "using ns::identifier;" is a non-declaration reference.621 Refs.push_back(ReferenceLoc{622 D->getQualifierLoc(), D->getLocation(), /*IsDecl=*/false,623 explicitReferenceTargets(DynTypedNode::create(*D),624 DeclRelation::Underlying, Resolver)});625 }626 627 void VisitUsingEnumDecl(const UsingEnumDecl *D) {628 // "using enum ns::E" is a non-declaration reference.629 // The reference is covered by the embedded typeloc.630 // Don't use the default VisitNamedDecl, which would report a declaration.631 }632 633 void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {634 // For namespace alias, "namespace Foo = Target;", we add two references.635 // Add a declaration reference for Foo.636 VisitNamedDecl(D);637 // Add a non-declaration reference for Target.638 Refs.push_back(ReferenceLoc{D->getQualifierLoc(),639 D->getTargetNameLoc(),640 /*IsDecl=*/false,641 {D->getAliasedNamespace()}});642 }643 644 void VisitNamedDecl(const NamedDecl *ND) {645 // We choose to ignore {Class, Function, Var, TypeAlias}TemplateDecls. As646 // as their underlying decls, covering the same range, will be visited.647 if (llvm::isa<ClassTemplateDecl>(ND) ||648 llvm::isa<FunctionTemplateDecl>(ND) ||649 llvm::isa<VarTemplateDecl>(ND) ||650 llvm::isa<TypeAliasTemplateDecl>(ND))651 return;652 // FIXME: decide on how to surface destructors when we need them.653 if (llvm::isa<CXXDestructorDecl>(ND))654 return;655 // Filter anonymous decls, name location will point outside the name token656 // and the clients are not prepared to handle that.657 if (ND->getDeclName().isIdentifier() &&658 !ND->getDeclName().getAsIdentifierInfo())659 return;660 Refs.push_back(ReferenceLoc{getQualifierLoc(*ND),661 ND->getLocation(),662 /*IsDecl=*/true,663 {ND}});664 }665 666 void VisitCXXDeductionGuideDecl(const CXXDeductionGuideDecl *DG) {667 // The class template name in a deduction guide targets the class668 // template.669 Refs.push_back(ReferenceLoc{DG->getQualifierLoc(),670 DG->getNameInfo().getLoc(),671 /*IsDecl=*/false,672 {DG->getDeducedTemplate()}});673 }674 675 void VisitObjCMethodDecl(const ObjCMethodDecl *OMD) {676 // The name may have several tokens, we can only report the first.677 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),678 OMD->getSelectorStartLoc(),679 /*IsDecl=*/true,680 {OMD}});681 }682 683 void VisitObjCCategoryDecl(const ObjCCategoryDecl *OCD) {684 // getLocation is the extended class's location, not the category's.685 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),686 OCD->getLocation(),687 /*IsDecl=*/false,688 {OCD->getClassInterface()}});689 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),690 OCD->getCategoryNameLoc(),691 /*IsDecl=*/true,692 {OCD}});693 }694 695 void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *OCID) {696 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),697 OCID->getLocation(),698 /*IsDecl=*/false,699 {OCID->getClassInterface()}});700 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),701 OCID->getCategoryNameLoc(),702 /*IsDecl=*/false,703 {OCID->getCategoryDecl()}});704 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),705 OCID->getCategoryNameLoc(),706 /*IsDecl=*/true,707 {OCID}});708 }709 710 void VisitObjCImplementationDecl(const ObjCImplementationDecl *OIMD) {711 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),712 OIMD->getLocation(),713 /*IsDecl=*/false,714 {OIMD->getClassInterface()}});715 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),716 OIMD->getLocation(),717 /*IsDecl=*/true,718 {OIMD}});719 }720 };721 722 Visitor V{Resolver};723 V.Visit(D);724 return V.Refs;725}726 727llvm::SmallVector<ReferenceLoc> refInStmt(const Stmt *S,728 const HeuristicResolver *Resolver) {729 struct Visitor : ConstStmtVisitor<Visitor> {730 Visitor(const HeuristicResolver *Resolver) : Resolver(Resolver) {}731 732 const HeuristicResolver *Resolver;733 // FIXME: handle more complicated cases: more ObjC, designated initializers.734 llvm::SmallVector<ReferenceLoc> Refs;735 736 void VisitDeclRefExpr(const DeclRefExpr *E) {737 Refs.push_back(ReferenceLoc{E->getQualifierLoc(),738 E->getNameInfo().getLoc(),739 /*IsDecl=*/false,740 {E->getFoundDecl()}});741 }742 743 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E) {744 Refs.push_back(ReferenceLoc{745 E->getQualifierLoc(), E->getNameInfo().getLoc(), /*IsDecl=*/false,746 explicitReferenceTargets(DynTypedNode::create(*E), {}, Resolver)});747 }748 749 void VisitMemberExpr(const MemberExpr *E) {750 // Skip destructor calls to avoid duplication: TypeLoc within will be751 // visited separately.752 if (llvm::isa<CXXDestructorDecl>(E->getFoundDecl().getDecl()))753 return;754 Refs.push_back(ReferenceLoc{E->getQualifierLoc(),755 E->getMemberNameInfo().getLoc(),756 /*IsDecl=*/false,757 {E->getFoundDecl()}});758 }759 760 void761 VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {762 Refs.push_back(ReferenceLoc{763 E->getQualifierLoc(), E->getMemberNameInfo().getLoc(),764 /*IsDecl=*/false,765 explicitReferenceTargets(DynTypedNode::create(*E), {}, Resolver)});766 }767 768 void VisitOverloadExpr(const OverloadExpr *E) {769 Refs.push_back(ReferenceLoc{E->getQualifierLoc(),770 E->getNameInfo().getLoc(),771 /*IsDecl=*/false,772 llvm::SmallVector<const NamedDecl *, 1>(773 E->decls().begin(), E->decls().end())});774 }775 776 void VisitSizeOfPackExpr(const SizeOfPackExpr *E) {777 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),778 E->getPackLoc(),779 /*IsDecl=*/false,780 {E->getPack()}});781 }782 783 void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *E) {784 Refs.push_back(ReferenceLoc{785 NestedNameSpecifierLoc(), E->getLocation(),786 /*IsDecl=*/false,787 // Select the getter, setter, or @property depending on the call.788 explicitReferenceTargets(DynTypedNode::create(*E), {}, Resolver)});789 }790 791 void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *OIRE) {792 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),793 OIRE->getLocation(),794 /*IsDecl=*/false,795 {OIRE->getDecl()}});796 }797 798 void VisitObjCMessageExpr(const ObjCMessageExpr *E) {799 // The name may have several tokens, we can only report the first.800 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),801 E->getSelectorStartLoc(),802 /*IsDecl=*/false,803 {E->getMethodDecl()}});804 }805 806 void VisitDesignatedInitExpr(const DesignatedInitExpr *DIE) {807 for (const DesignatedInitExpr::Designator &D : DIE->designators()) {808 if (!D.isFieldDesignator())809 continue;810 811 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),812 D.getFieldLoc(),813 /*IsDecl=*/false,814 {D.getFieldDecl()}});815 }816 }817 818 void VisitGotoStmt(const GotoStmt *GS) {819 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),820 GS->getLabelLoc(),821 /*IsDecl=*/false,822 {GS->getLabel()}});823 }824 825 void VisitLabelStmt(const LabelStmt *LS) {826 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),827 LS->getIdentLoc(),828 /*IsDecl=*/true,829 {LS->getDecl()}});830 }831 };832 833 Visitor V{Resolver};834 V.Visit(S);835 return V.Refs;836}837 838llvm::SmallVector<ReferenceLoc>839refInTypeLoc(TypeLoc L, const HeuristicResolver *Resolver) {840 struct Visitor : TypeLocVisitor<Visitor> {841 Visitor(const HeuristicResolver *Resolver) : Resolver(Resolver) {}842 843 const HeuristicResolver *Resolver;844 llvm::SmallVector<ReferenceLoc> Refs;845 846 void VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc L) {847 Refs.push_back(ReferenceLoc{L.getQualifierLoc(),848 L.getLocalSourceRange().getBegin(),849 /*IsDecl=*/false,850 {L.getDecl()}});851 }852 853 void VisitUsingTypeLoc(UsingTypeLoc L) {854 Refs.push_back(ReferenceLoc{L.getQualifierLoc(),855 L.getLocalSourceRange().getBegin(),856 /*IsDecl=*/false,857 {L.getDecl()}});858 }859 860 void VisitTagTypeLoc(TagTypeLoc L) {861 Refs.push_back(ReferenceLoc{L.getQualifierLoc(),862 L.getNameLoc(),863 /*IsDecl=*/false,864 {L.getDecl()}});865 }866 867 void VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc L) {868 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),869 L.getNameLoc(),870 /*IsDecl=*/false,871 {L.getDecl()}});872 }873 874 void VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc L) {875 // We must ensure template type aliases are included in results if they876 // were written in the source code, e.g. in877 // template <class T> using valias = vector<T>;878 // ^valias<int> x;879 // 'explicitReferenceTargets' will return:880 // 1. valias with mask 'Alias'.881 // 2. 'vector<int>' with mask 'Underlying'.882 // we want to return only #1 in this case.883 Refs.push_back(ReferenceLoc{884 L.getQualifierLoc(), L.getTemplateNameLoc(), /*IsDecl=*/false,885 explicitReferenceTargets(DynTypedNode::create(L.getType()),886 DeclRelation::Alias, Resolver)});887 }888 void VisitDeducedTemplateSpecializationTypeLoc(889 DeducedTemplateSpecializationTypeLoc L) {890 Refs.push_back(ReferenceLoc{891 L.getQualifierLoc(), L.getNameLoc(), /*IsDecl=*/false,892 explicitReferenceTargets(DynTypedNode::create(L.getType()),893 DeclRelation::Alias, Resolver)});894 }895 896 void VisitDependentNameTypeLoc(DependentNameTypeLoc L) {897 Refs.push_back(898 ReferenceLoc{L.getQualifierLoc(), L.getNameLoc(),899 /*IsDecl=*/false,900 explicitReferenceTargets(901 DynTypedNode::create(L.getType()), {}, Resolver)});902 }903 904 void VisitTypedefTypeLoc(TypedefTypeLoc L) {905 if (shouldSkipTypedef(L.getDecl()))906 return;907 Refs.push_back(ReferenceLoc{L.getQualifierLoc(),908 L.getNameLoc(),909 /*IsDecl=*/false,910 {L.getDecl()}});911 }912 913 void VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc L) {914 Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),915 L.getNameLoc(),916 /*IsDecl=*/false,917 {L.getIFaceDecl()}});918 }919 };920 921 Visitor V{Resolver};922 V.Visit(L.getUnqualifiedLoc());923 return V.Refs;924}925 926class ExplicitReferenceCollector927 : public RecursiveASTVisitor<ExplicitReferenceCollector> {928public:929 ExplicitReferenceCollector(llvm::function_ref<void(ReferenceLoc)> Out,930 const HeuristicResolver *Resolver)931 : Out(Out), Resolver(Resolver) {932 assert(Out);933 }934 935 bool VisitTypeLoc(TypeLoc TTL) {936 if (TypeLocsToSkip.count(TTL.getBeginLoc()))937 return true;938 visitNode(DynTypedNode::create(TTL));939 return true;940 }941 942 bool VisitStmt(Stmt *S) {943 visitNode(DynTypedNode::create(*S));944 return true;945 }946 947 bool TraverseOpaqueValueExpr(OpaqueValueExpr *OVE) {948 visitNode(DynTypedNode::create(*OVE));949 // Not clear why the source expression is skipped by default...950 // FIXME: can we just make RecursiveASTVisitor do this?951 return RecursiveASTVisitor::TraverseStmt(OVE->getSourceExpr());952 }953 954 bool TraversePseudoObjectExpr(PseudoObjectExpr *POE) {955 visitNode(DynTypedNode::create(*POE));956 // Traverse only the syntactic form to find the *written* references.957 // (The semantic form also contains lots of duplication)958 return RecursiveASTVisitor::TraverseStmt(POE->getSyntacticForm());959 }960 961 // We re-define Traverse*, since there's no corresponding Visit*.962 // TemplateArgumentLoc is the only way to get locations for references to963 // template template parameters.964 bool TraverseTemplateArgumentLoc(TemplateArgumentLoc A) {965 switch (A.getArgument().getKind()) {966 case TemplateArgument::Template:967 case TemplateArgument::TemplateExpansion:968 reportReference(ReferenceLoc{A.getTemplateQualifierLoc(),969 A.getTemplateNameLoc(),970 /*IsDecl=*/false,971 {A.getArgument()972 .getAsTemplateOrTemplatePattern()973 .getAsTemplateDecl()}},974 DynTypedNode::create(A.getArgument()));975 break;976 case TemplateArgument::Declaration:977 break; // FIXME: can this actually happen in TemplateArgumentLoc?978 case TemplateArgument::Integral:979 case TemplateArgument::Null:980 case TemplateArgument::NullPtr:981 break; // no references.982 case TemplateArgument::Pack:983 case TemplateArgument::Type:984 case TemplateArgument::Expression:985 case TemplateArgument::StructuralValue:986 break; // Handled by VisitType and VisitExpression.987 };988 return RecursiveASTVisitor::TraverseTemplateArgumentLoc(A);989 }990 991 bool VisitDecl(Decl *D) {992 visitNode(DynTypedNode::create(*D));993 return true;994 }995 996 // We have to use Traverse* because there is no corresponding Visit*.997 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc L) {998 if (!L.getNestedNameSpecifier())999 return true;1000 visitNode(DynTypedNode::create(L));1001 // Inner type is missing information about its qualifier, skip it.1002 if (auto TL = L.getAsTypeLoc())1003 TypeLocsToSkip.insert(TL.getBeginLoc());1004 return RecursiveASTVisitor::TraverseNestedNameSpecifierLoc(L);1005 }1006 1007 bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLoc) {1008 visitNode(DynTypedNode::create(ProtocolLoc));1009 return true;1010 }1011 1012 bool TraverseConstructorInitializer(CXXCtorInitializer *Init) {1013 visitNode(DynTypedNode::create(*Init));1014 return RecursiveASTVisitor::TraverseConstructorInitializer(Init);1015 }1016 1017 bool VisitConceptReference(const ConceptReference *CR) {1018 visitNode(DynTypedNode::create(*CR));1019 return true;1020 }1021 1022private:1023 /// Obtain information about a reference directly defined in \p N. Does not1024 /// recurse into child nodes, e.g. do not expect references for constructor1025 /// initializers1026 ///1027 /// Any of the fields in the returned structure can be empty, but not all of1028 /// them, e.g.1029 /// - for implicitly generated nodes (e.g. MemberExpr from range-based-for),1030 /// source location information may be missing,1031 /// - for dependent code, targets may be empty.1032 ///1033 /// (!) For the purposes of this function declarations are not considered to1034 /// be references. However, declarations can have references inside them,1035 /// e.g. 'namespace foo = std' references namespace 'std' and this1036 /// function will return the corresponding reference.1037 llvm::SmallVector<ReferenceLoc> explicitReference(DynTypedNode N) {1038 if (auto *D = N.get<Decl>())1039 return refInDecl(D, Resolver);1040 if (auto *S = N.get<Stmt>())1041 return refInStmt(S, Resolver);1042 if (auto *NNSL = N.get<NestedNameSpecifierLoc>()) {1043 if (TypeLoc TL = NNSL->getAsTypeLoc())1044 return refInTypeLoc(TL, Resolver);1045 // (!) 'DeclRelation::Alias' ensures we do not lose namespace aliases.1046 NestedNameSpecifierLoc Qualifier = NNSL->getAsNamespaceAndPrefix().Prefix;1047 SourceLocation NameLoc = NNSL->getLocalBeginLoc();1048 return {1049 ReferenceLoc{Qualifier, NameLoc, false,1050 explicitReferenceTargets(1051 DynTypedNode::create(NNSL->getNestedNameSpecifier()),1052 DeclRelation::Alias, Resolver)}};1053 }1054 if (const TypeLoc *TL = N.get<TypeLoc>())1055 return refInTypeLoc(*TL, Resolver);1056 if (const CXXCtorInitializer *CCI = N.get<CXXCtorInitializer>()) {1057 // Other type initializers (e.g. base initializer) are handled by visiting1058 // the typeLoc.1059 if (CCI->isAnyMemberInitializer()) {1060 return {ReferenceLoc{NestedNameSpecifierLoc(),1061 CCI->getMemberLocation(),1062 /*IsDecl=*/false,1063 {CCI->getAnyMember()}}};1064 }1065 }1066 if (const ObjCProtocolLoc *PL = N.get<ObjCProtocolLoc>())1067 return {ReferenceLoc{NestedNameSpecifierLoc(),1068 PL->getLocation(),1069 /*IsDecl=*/false,1070 {PL->getProtocol()}}};1071 if (const ConceptReference *CR = N.get<ConceptReference>())1072 return {ReferenceLoc{CR->getNestedNameSpecifierLoc(),1073 CR->getConceptNameLoc(),1074 /*IsDecl=*/false,1075 {CR->getNamedConcept()}}};1076 1077 // We do not have location information for other nodes (QualType, etc)1078 return {};1079 }1080 1081 void visitNode(DynTypedNode N) {1082 for (auto &R : explicitReference(N))1083 reportReference(std::move(R), N);1084 }1085 1086 void reportReference(ReferenceLoc &&Ref, DynTypedNode N) {1087 // Strip null targets that can arise from invalid code.1088 // (This avoids having to check for null everywhere we insert)1089 llvm::erase(Ref.Targets, nullptr);1090 // Our promise is to return only references from the source code. If we lack1091 // location information, skip these nodes.1092 // Normally this should not happen in practice, unless there are bugs in the1093 // traversals or users started the traversal at an implicit node.1094 if (Ref.NameLoc.isInvalid()) {1095 dlog("invalid location at node {0}", nodeToString(N));1096 return;1097 }1098 Out(Ref);1099 }1100 1101 llvm::function_ref<void(ReferenceLoc)> Out;1102 const HeuristicResolver *Resolver;1103 /// TypeLocs starting at these locations must be skipped, see1104 /// TraverseElaboratedTypeSpecifierLoc for details.1105 llvm::DenseSet<SourceLocation> TypeLocsToSkip;1106};1107} // namespace1108 1109void findExplicitReferences(const Stmt *S,1110 llvm::function_ref<void(ReferenceLoc)> Out,1111 const HeuristicResolver *Resolver) {1112 assert(S);1113 ExplicitReferenceCollector(Out, Resolver).TraverseStmt(const_cast<Stmt *>(S));1114}1115void findExplicitReferences(const Decl *D,1116 llvm::function_ref<void(ReferenceLoc)> Out,1117 const HeuristicResolver *Resolver) {1118 assert(D);1119 ExplicitReferenceCollector(Out, Resolver).TraverseDecl(const_cast<Decl *>(D));1120}1121void findExplicitReferences(const ASTContext &AST,1122 llvm::function_ref<void(ReferenceLoc)> Out,1123 const HeuristicResolver *Resolver) {1124 ExplicitReferenceCollector(Out, Resolver)1125 .TraverseAST(const_cast<ASTContext &>(AST));1126}1127 1128llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, DeclRelation R) {1129 switch (R) {1130#define REL_CASE(X) \1131 case DeclRelation::X: \1132 return OS << #X;1133 REL_CASE(Alias);1134 REL_CASE(Underlying);1135 REL_CASE(TemplateInstantiation);1136 REL_CASE(TemplatePattern);1137#undef REL_CASE1138 }1139 llvm_unreachable("Unhandled DeclRelation enum");1140}1141llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, DeclRelationSet RS) {1142 const char *Sep = "";1143 for (unsigned I = 0; I < RS.S.size(); ++I) {1144 if (RS.S.test(I)) {1145 OS << Sep << static_cast<DeclRelation>(I);1146 Sep = "|";1147 }1148 }1149 return OS;1150}1151 1152llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, ReferenceLoc R) {1153 // note we cannot print R.NameLoc without a source manager.1154 OS << "targets = {";1155 llvm::SmallVector<std::string> Targets;1156 for (const NamedDecl *T : R.Targets) {1157 llvm::raw_string_ostream Target(Targets.emplace_back());1158 Target << printQualifiedName(*T) << printTemplateSpecializationArgs(*T);1159 }1160 llvm::sort(Targets);1161 OS << llvm::join(Targets, ", ");1162 OS << "}";1163 if (R.Qualifier) {1164 OS << ", qualifier = '";1165 R.Qualifier.getNestedNameSpecifier().print(OS,1166 PrintingPolicy(LangOptions()));1167 OS << "'";1168 }1169 if (R.IsDecl)1170 OS << ", decl";1171 return OS;1172}1173 1174} // namespace clangd1175} // namespace clang1176