1 //===--- AST.cpp - Utility AST functions -----------------------*- C++ -*-===// 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "AST.h" 10 11 #include "SourceCode.h" 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/DeclTemplate.h" 18 #include "clang/AST/DeclarationName.h" 19 #include "clang/AST/NestedNameSpecifier.h" 20 #include "clang/AST/PrettyPrinter.h" 21 #include "clang/AST/RecursiveASTVisitor.h" 22 #include "clang/AST/Stmt.h" 23 #include "clang/AST/TemplateBase.h" 24 #include "clang/AST/TypeLoc.h" 25 #include "clang/Basic/SourceLocation.h" 26 #include "clang/Basic/SourceManager.h" 27 #include "clang/Basic/Specifiers.h" 28 #include "clang/Index/USRGeneration.h" 29 #include "llvm/ADT/ArrayRef.h" 30 #include "llvm/ADT/Optional.h" 31 #include "llvm/ADT/STLExtras.h" 32 #include "llvm/ADT/StringRef.h" 33 #include "llvm/Support/Casting.h" 34 #include "llvm/Support/raw_ostream.h" 35 #include <string> 36 #include <vector> 37 38 namespace clang { 39 namespace clangd { 40 41 namespace { 42 llvm::Optional<llvm::ArrayRef<TemplateArgumentLoc>> 43 getTemplateSpecializationArgLocs(const NamedDecl &ND) { 44 if (auto *Func = llvm::dyn_cast<FunctionDecl>(&ND)) { 45 if (const ASTTemplateArgumentListInfo *Args = 46 Func->getTemplateSpecializationArgsAsWritten()) 47 return Args->arguments(); 48 } else if (auto *Cls = 49 llvm::dyn_cast<ClassTemplatePartialSpecializationDecl>(&ND)) { 50 if (auto *Args = Cls->getTemplateArgsAsWritten()) 51 return Args->arguments(); 52 } else if (auto *Var = 53 llvm::dyn_cast<VarTemplatePartialSpecializationDecl>(&ND)) { 54 if (auto *Args = Var->getTemplateArgsAsWritten()) 55 return Args->arguments(); 56 } else if (auto *Var = llvm::dyn_cast<VarTemplateSpecializationDecl>(&ND)) { 57 if (auto *Args = Var->getTemplateArgsInfo()) 58 return Args->arguments(); 59 } 60 // We return None for ClassTemplateSpecializationDecls because it does not 61 // contain TemplateArgumentLoc information. 62 return llvm::None; 63 } 64 65 template <class T> 66 bool isTemplateSpecializationKind(const NamedDecl *D, 67 TemplateSpecializationKind Kind) { 68 if (const auto *TD = dyn_cast<T>(D)) 69 return TD->getTemplateSpecializationKind() == Kind; 70 return false; 71 } 72 73 bool isTemplateSpecializationKind(const NamedDecl *D, 74 TemplateSpecializationKind Kind) { 75 return isTemplateSpecializationKind<FunctionDecl>(D, Kind) || 76 isTemplateSpecializationKind<CXXRecordDecl>(D, Kind) || 77 isTemplateSpecializationKind<VarDecl>(D, Kind); 78 } 79 80 // Store all UsingDirectiveDecls in parent contexts of DestContext, that were 81 // introduced before InsertionPoint. 82 llvm::DenseSet<const NamespaceDecl *> 83 getUsingNamespaceDirectives(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)) 91 continue; 92 if (auto *UDD = llvm::dyn_cast<UsingDirectiveDecl>(D)) 93 VisibleNamespaceDecls.insert( 94 UDD->getNominatedNamespace()->getCanonicalDecl()); 95 } 96 } 97 return VisibleNamespaceDecls; 98 } 99 100 // Goes over all parents of SourceContext until we find a common ancestor for 101 // DestContext and SourceContext. Any qualifier including and above common 102 // ancestor is redundant, therefore we stop at lowest common ancestor. 103 // In addition to that stops early whenever IsVisible returns true. This can be 104 // used to implement support for "using namespace" decls. 105 std::string 106 getQualification(ASTContext &Context, const DeclContext *DestContext, 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()) { 113 // Stop once we reach a common ancestor. 114 if (CurContext->Encloses(DestContext)) 115 break; 116 117 NestedNameSpecifier *NNS = nullptr; 118 if (auto *TD = llvm::dyn_cast<TagDecl>(CurContext)) { 119 // There can't be any more tag parents after hitting a namespace. 120 assert(!ReachedNS); 121 (void)ReachedNS; 122 NNS = NestedNameSpecifier::Create(Context, nullptr, false, 123 TD->getTypeForDecl()); 124 } else if (auto *NSD = llvm::dyn_cast<NamespaceDecl>(CurContext)) { 125 ReachedNS = true; 126 NNS = NestedNameSpecifier::Create(Context, nullptr, NSD); 127 // Anonymous and inline namespace names are not spelled while qualifying 128 // a name, so skip those. 129 if (NSD->isAnonymousNamespace() || NSD->isInlineNamespace()) 130 continue; 131 } else { 132 // Other types of contexts cannot be spelled in code, just skip over 133 // them. 134 continue; 135 } 136 // Stop if this namespace is already visible at DestContext. 137 if (IsVisible(NNS)) 138 break; 139 140 Parents.push_back(NNS); 141 } 142 143 // Go over name-specifiers in reverse order to create necessary qualification, 144 // since we stored inner-most parent first. 145 std::string Result; 146 llvm::raw_string_ostream OS(Result); 147 for (const auto *Parent : llvm::reverse(Parents)) 148 Parent->print(OS, Context.getPrintingPolicy()); 149 return OS.str(); 150 } 151 152 } // namespace 153 154 bool isImplicitTemplateInstantiation(const NamedDecl *D) { 155 return isTemplateSpecializationKind(D, TSK_ImplicitInstantiation); 156 } 157 158 bool isExplicitTemplateSpecialization(const NamedDecl *D) { 159 return isTemplateSpecializationKind(D, TSK_ExplicitSpecialization); 160 } 161 162 bool isImplementationDetail(const Decl *D) { 163 return !isSpelledInSource(D->getLocation(), 164 D->getASTContext().getSourceManager()); 165 } 166 167 SourceLocation nameLocation(const clang::Decl &D, const SourceManager &SM) { 168 auto L = D.getLocation(); 169 if (isSpelledInSource(L, SM)) 170 return SM.getSpellingLoc(L); 171 return SM.getExpansionLoc(L); 172 } 173 174 std::string printQualifiedName(const NamedDecl &ND) { 175 std::string QName; 176 llvm::raw_string_ostream OS(QName); 177 PrintingPolicy Policy(ND.getASTContext().getLangOpts()); 178 // Note that inline namespaces are treated as transparent scopes. This 179 // reflects the way they're most commonly used for lookup. Ideally we'd 180 // include them, but at query time it's hard to find all the inline 181 // namespaces to query: the preamble doesn't have a dedicated list. 182 Policy.SuppressUnwrittenScope = true; 183 ND.printQualifiedName(OS, Policy); 184 OS.flush(); 185 assert(!StringRef(QName).startswith("::")); 186 return QName; 187 } 188 189 static bool isAnonymous(const DeclarationName &N) { 190 return N.isIdentifier() && !N.getAsIdentifierInfo(); 191 } 192 193 NestedNameSpecifierLoc getQualifierLoc(const NamedDecl &ND) { 194 if (auto *V = llvm::dyn_cast<DeclaratorDecl>(&ND)) 195 return V->getQualifierLoc(); 196 if (auto *T = llvm::dyn_cast<TagDecl>(&ND)) 197 return T->getQualifierLoc(); 198 return NestedNameSpecifierLoc(); 199 } 200 201 std::string printUsingNamespaceName(const ASTContext &Ctx, 202 const UsingDirectiveDecl &D) { 203 PrintingPolicy PP(Ctx.getLangOpts()); 204 std::string Name; 205 llvm::raw_string_ostream Out(Name); 206 207 if (auto *Qual = D.getQualifier()) 208 Qual->print(Out, PP); 209 D.getNominatedNamespaceAsWritten()->printName(Out); 210 return Out.str(); 211 } 212 213 std::string printName(const ASTContext &Ctx, const NamedDecl &ND) { 214 std::string Name; 215 llvm::raw_string_ostream Out(Name); 216 PrintingPolicy PP(Ctx.getLangOpts()); 217 // We don't consider a class template's args part of the constructor name. 218 PP.SuppressTemplateArgsInCXXConstructors = true; 219 220 // Handle 'using namespace'. They all have the same name - <using-directive>. 221 if (auto *UD = llvm::dyn_cast<UsingDirectiveDecl>(&ND)) { 222 Out << "using namespace "; 223 if (auto *Qual = UD->getQualifier()) 224 Qual->print(Out, PP); 225 UD->getNominatedNamespaceAsWritten()->printName(Out); 226 return Out.str(); 227 } 228 229 if (isAnonymous(ND.getDeclName())) { 230 // Come up with a presentation for an anonymous entity. 231 if (isa<NamespaceDecl>(ND)) 232 return "(anonymous namespace)"; 233 if (auto *Cls = llvm::dyn_cast<RecordDecl>(&ND)) { 234 if (Cls->isLambda()) 235 return "(lambda)"; 236 return ("(anonymous " + Cls->getKindName() + ")").str(); 237 } 238 if (isa<EnumDecl>(ND)) 239 return "(anonymous enum)"; 240 return "(anonymous)"; 241 } 242 243 // Print nested name qualifier if it was written in the source code. 244 if (auto *Qualifier = getQualifierLoc(ND).getNestedNameSpecifier()) 245 Qualifier->print(Out, PP); 246 // Print the name itself. 247 ND.getDeclName().print(Out, PP); 248 // Print template arguments. 249 Out << printTemplateSpecializationArgs(ND); 250 251 return Out.str(); 252 } 253 254 std::string printTemplateSpecializationArgs(const NamedDecl &ND) { 255 std::string TemplateArgs; 256 llvm::raw_string_ostream OS(TemplateArgs); 257 PrintingPolicy Policy(ND.getASTContext().getLangOpts()); 258 if (llvm::Optional<llvm::ArrayRef<TemplateArgumentLoc>> Args = 259 getTemplateSpecializationArgLocs(ND)) { 260 printTemplateArgumentList(OS, *Args, Policy); 261 } else if (auto *Cls = llvm::dyn_cast<ClassTemplateSpecializationDecl>(&ND)) { 262 if (const TypeSourceInfo *TSI = Cls->getTypeAsWritten()) { 263 // ClassTemplateSpecializationDecls do not contain 264 // TemplateArgumentTypeLocs, they only have TemplateArgumentTypes. So we 265 // create a new argument location list from TypeSourceInfo. 266 auto STL = TSI->getTypeLoc().getAs<TemplateSpecializationTypeLoc>(); 267 llvm::SmallVector<TemplateArgumentLoc> ArgLocs; 268 ArgLocs.reserve(STL.getNumArgs()); 269 for (unsigned I = 0; I < STL.getNumArgs(); ++I) 270 ArgLocs.push_back(STL.getArgLoc(I)); 271 printTemplateArgumentList(OS, ArgLocs, Policy); 272 } else { 273 // FIXME: Fix cases when getTypeAsWritten returns null inside clang AST, 274 // e.g. friend decls. Currently we fallback to Template Arguments without 275 // location information. 276 printTemplateArgumentList(OS, Cls->getTemplateArgs().asArray(), Policy); 277 } 278 } 279 OS.flush(); 280 return TemplateArgs; 281 } 282 283 std::string printNamespaceScope(const DeclContext &DC) { 284 for (const auto *Ctx = &DC; Ctx != nullptr; Ctx = Ctx->getParent()) 285 if (const auto *NS = dyn_cast<NamespaceDecl>(Ctx)) 286 if (!NS->isAnonymousNamespace() && !NS->isInlineNamespace()) 287 return printQualifiedName(*NS) + "::"; 288 return ""; 289 } 290 291 static llvm::StringRef 292 getNameOrErrForObjCInterface(const ObjCInterfaceDecl *ID) { 293 return ID ? ID->getName() : "<<error-type>>"; 294 } 295 296 std::string printObjCMethod(const ObjCMethodDecl &Method) { 297 std::string Name; 298 llvm::raw_string_ostream OS(Name); 299 300 OS << (Method.isInstanceMethod() ? '-' : '+') << '['; 301 302 // Should always be true. 303 if (const ObjCContainerDecl *C = 304 dyn_cast<ObjCContainerDecl>(Method.getDeclContext())) 305 OS << printObjCContainer(*C); 306 307 Method.getSelector().print(OS << ' '); 308 if (Method.isVariadic()) 309 OS << ", ..."; 310 311 OS << ']'; 312 OS.flush(); 313 return Name; 314 } 315 316 std::string printObjCContainer(const ObjCContainerDecl &C) { 317 if (const ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(&C)) { 318 std::string Name; 319 llvm::raw_string_ostream OS(Name); 320 const ObjCInterfaceDecl *Class = Category->getClassInterface(); 321 OS << getNameOrErrForObjCInterface(Class) << '(' << Category->getName() 322 << ')'; 323 OS.flush(); 324 return Name; 325 } 326 if (const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(&C)) { 327 std::string Name; 328 llvm::raw_string_ostream OS(Name); 329 const ObjCInterfaceDecl *Class = CID->getClassInterface(); 330 OS << getNameOrErrForObjCInterface(Class) << '(' << CID->getName() << ')'; 331 OS.flush(); 332 return Name; 333 } 334 return C.getNameAsString(); 335 } 336 337 SymbolID getSymbolID(const Decl *D) { 338 llvm::SmallString<128> USR; 339 if (index::generateUSRForDecl(D, USR)) 340 return {}; 341 return SymbolID(USR); 342 } 343 344 SymbolID getSymbolID(const llvm::StringRef MacroName, const MacroInfo *MI, 345 const SourceManager &SM) { 346 if (MI == nullptr) 347 return {}; 348 llvm::SmallString<128> USR; 349 if (index::generateUSRForMacro(MacroName, MI->getDefinitionLoc(), SM, USR)) 350 return {}; 351 return SymbolID(USR); 352 } 353 354 std::string printType(const QualType QT, const DeclContext &CurContext, 355 const llvm::StringRef Placeholder) { 356 std::string Result; 357 llvm::raw_string_ostream OS(Result); 358 PrintingPolicy PP(CurContext.getParentASTContext().getPrintingPolicy()); 359 PP.SuppressTagKeyword = true; 360 PP.SuppressUnwrittenScope = true; 361 362 class PrintCB : public PrintingCallbacks { 363 public: 364 PrintCB(const DeclContext *CurContext) : CurContext(CurContext) {} 365 virtual ~PrintCB() {} 366 virtual bool isScopeVisible(const DeclContext *DC) const override { 367 return DC->Encloses(CurContext); 368 } 369 370 private: 371 const DeclContext *CurContext; 372 }; 373 PrintCB PCB(&CurContext); 374 PP.Callbacks = &PCB; 375 376 QT.print(OS, PP, Placeholder); 377 return OS.str(); 378 } 379 380 bool hasReservedName(const Decl &D) { 381 if (const auto *ND = llvm::dyn_cast<NamedDecl>(&D)) 382 if (const auto *II = ND->getIdentifier()) 383 return isReservedName(II->getName()); 384 return false; 385 } 386 387 bool hasReservedScope(const DeclContext &DC) { 388 for (const DeclContext *D = &DC; D; D = D->getParent()) { 389 if (D->isTransparentContext() || D->isInlineNamespace()) 390 continue; 391 if (const auto *ND = llvm::dyn_cast<NamedDecl>(D)) 392 if (hasReservedName(*ND)) 393 return true; 394 } 395 return false; 396 } 397 398 QualType declaredType(const TypeDecl *D) { 399 if (const auto *CTSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>(D)) 400 if (const auto *TSI = CTSD->getTypeAsWritten()) 401 return TSI->getType(); 402 return D->getASTContext().getTypeDeclType(D); 403 } 404 405 namespace { 406 /// Computes the deduced type at a given location by visiting the relevant 407 /// nodes. We use this to display the actual type when hovering over an "auto" 408 /// keyword or "decltype()" expression. 409 /// FIXME: This could have been a lot simpler by visiting AutoTypeLocs but it 410 /// seems that the AutoTypeLocs that can be visited along with their AutoType do 411 /// not have the deduced type set. Instead, we have to go to the appropriate 412 /// DeclaratorDecl/FunctionDecl and work our back to the AutoType that does have 413 /// a deduced type set. The AST should be improved to simplify this scenario. 414 class DeducedTypeVisitor : public RecursiveASTVisitor<DeducedTypeVisitor> { 415 SourceLocation SearchedLocation; 416 417 public: 418 DeducedTypeVisitor(SourceLocation SearchedLocation) 419 : SearchedLocation(SearchedLocation) {} 420 421 // Handle auto initializers: 422 //- auto i = 1; 423 //- decltype(auto) i = 1; 424 //- auto& i = 1; 425 //- auto* i = &a; 426 bool VisitDeclaratorDecl(DeclaratorDecl *D) { 427 if (!D->getTypeSourceInfo() || 428 D->getTypeSourceInfo()->getTypeLoc().getBeginLoc() != SearchedLocation) 429 return true; 430 431 if (auto *AT = D->getType()->getContainedAutoType()) { 432 DeducedType = AT->desugar(); 433 } 434 return true; 435 } 436 437 // Handle auto return types: 438 //- auto foo() {} 439 //- auto& foo() {} 440 //- auto foo() -> int {} 441 //- auto foo() -> decltype(1+1) {} 442 //- operator auto() const { return 10; } 443 bool VisitFunctionDecl(FunctionDecl *D) { 444 if (!D->getTypeSourceInfo()) 445 return true; 446 // Loc of auto in return type (c++14). 447 auto CurLoc = D->getReturnTypeSourceRange().getBegin(); 448 // Loc of "auto" in operator auto() 449 if (CurLoc.isInvalid() && isa<CXXConversionDecl>(D)) 450 CurLoc = D->getTypeSourceInfo()->getTypeLoc().getBeginLoc(); 451 // Loc of "auto" in function with trailing return type (c++11). 452 if (CurLoc.isInvalid()) 453 CurLoc = D->getSourceRange().getBegin(); 454 if (CurLoc != SearchedLocation) 455 return true; 456 457 const AutoType *AT = D->getReturnType()->getContainedAutoType(); 458 if (AT && !AT->getDeducedType().isNull()) { 459 DeducedType = AT->getDeducedType(); 460 } else if (auto *DT = dyn_cast<DecltypeType>(D->getReturnType())) { 461 // auto in a trailing return type just points to a DecltypeType and 462 // getContainedAutoType does not unwrap it. 463 if (!DT->getUnderlyingType().isNull()) 464 DeducedType = DT->getUnderlyingType(); 465 } else if (!D->getReturnType().isNull()) { 466 DeducedType = D->getReturnType(); 467 } 468 return true; 469 } 470 471 // Handle non-auto decltype, e.g.: 472 // - auto foo() -> decltype(expr) {} 473 // - decltype(expr); 474 bool VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { 475 if (TL.getBeginLoc() != SearchedLocation) 476 return true; 477 478 // A DecltypeType's underlying type can be another DecltypeType! E.g. 479 // int I = 0; 480 // decltype(I) J = I; 481 // decltype(J) K = J; 482 const DecltypeType *DT = dyn_cast<DecltypeType>(TL.getTypePtr()); 483 while (DT && !DT->getUnderlyingType().isNull()) { 484 DeducedType = DT->getUnderlyingType(); 485 DT = dyn_cast<DecltypeType>(DeducedType.getTypePtr()); 486 } 487 return true; 488 } 489 490 // Handle functions/lambdas with `auto` typed parameters. 491 // We deduce the type if there's exactly one instantiation visible. 492 bool VisitParmVarDecl(ParmVarDecl *PVD) { 493 if (!PVD->getType()->isDependentType()) 494 return true; 495 // 'auto' here does not name an AutoType, but an implicit template param. 496 TemplateTypeParmTypeLoc Auto = 497 getContainedAutoParamType(PVD->getTypeSourceInfo()->getTypeLoc()); 498 if (Auto.isNull() || Auto.getNameLoc() != SearchedLocation) 499 return true; 500 501 // We expect the TTP to be attached to this function template. 502 // Find the template and the param index. 503 auto *Templated = llvm::dyn_cast<FunctionDecl>(PVD->getDeclContext()); 504 if (!Templated) 505 return true; 506 auto *FTD = Templated->getDescribedFunctionTemplate(); 507 if (!FTD) 508 return true; 509 int ParamIndex = paramIndex(*FTD, *Auto.getDecl()); 510 if (ParamIndex < 0) { 511 assert(false && "auto TTP is not from enclosing function?"); 512 return true; 513 } 514 515 // Now find the instantiation and the deduced template type arg. 516 auto *Instantiation = 517 llvm::dyn_cast_or_null<FunctionDecl>(getOnlyInstantiation(Templated)); 518 if (!Instantiation) 519 return true; 520 const auto *Args = Instantiation->getTemplateSpecializationArgs(); 521 if (Args->size() != FTD->getTemplateParameters()->size()) 522 return true; // no weird variadic stuff 523 DeducedType = Args->get(ParamIndex).getAsType(); 524 return true; 525 } 526 527 static int paramIndex(const TemplateDecl &TD, NamedDecl &Param) { 528 unsigned I = 0; 529 for (auto *ND : *TD.getTemplateParameters()) { 530 if (&Param == ND) 531 return I; 532 ++I; 533 } 534 return -1; 535 } 536 537 QualType DeducedType; 538 }; 539 } // namespace 540 541 llvm::Optional<QualType> getDeducedType(ASTContext &ASTCtx, 542 SourceLocation Loc) { 543 if (!Loc.isValid()) 544 return {}; 545 DeducedTypeVisitor V(Loc); 546 V.TraverseAST(ASTCtx); 547 if (V.DeducedType.isNull()) 548 return llvm::None; 549 return V.DeducedType; 550 } 551 552 TemplateTypeParmTypeLoc getContainedAutoParamType(TypeLoc TL) { 553 if (auto QTL = TL.getAs<QualifiedTypeLoc>()) 554 return getContainedAutoParamType(QTL.getUnqualifiedLoc()); 555 if (llvm::isa<PointerType, ReferenceType, ParenType>(TL.getTypePtr())) 556 return getContainedAutoParamType(TL.getNextTypeLoc()); 557 if (auto FTL = TL.getAs<FunctionTypeLoc>()) 558 return getContainedAutoParamType(FTL.getReturnLoc()); 559 if (auto TTPTL = TL.getAs<TemplateTypeParmTypeLoc>()) { 560 if (TTPTL.getTypePtr()->getDecl()->isImplicit()) 561 return TTPTL; 562 } 563 return {}; 564 } 565 566 template <typename TemplateDeclTy> 567 static NamedDecl *getOnlyInstantiationImpl(TemplateDeclTy *TD) { 568 NamedDecl *Only = nullptr; 569 for (auto *Spec : TD->specializations()) { 570 if (Spec->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) 571 continue; 572 if (Only != nullptr) 573 return nullptr; 574 Only = Spec; 575 } 576 return Only; 577 } 578 579 NamedDecl *getOnlyInstantiation(NamedDecl *TemplatedDecl) { 580 if (TemplateDecl *TD = TemplatedDecl->getDescribedTemplate()) { 581 if (auto *CTD = llvm::dyn_cast<ClassTemplateDecl>(TD)) 582 return getOnlyInstantiationImpl(CTD); 583 if (auto *FTD = llvm::dyn_cast<FunctionTemplateDecl>(TD)) 584 return getOnlyInstantiationImpl(FTD); 585 if (auto *VTD = llvm::dyn_cast<VarTemplateDecl>(TD)) 586 return getOnlyInstantiationImpl(VTD); 587 } 588 return nullptr; 589 } 590 591 std::vector<const Attr *> getAttributes(const DynTypedNode &N) { 592 std::vector<const Attr *> Result; 593 if (const auto *TL = N.get<TypeLoc>()) { 594 for (AttributedTypeLoc ATL = TL->getAs<AttributedTypeLoc>(); !ATL.isNull(); 595 ATL = ATL.getModifiedLoc().getAs<AttributedTypeLoc>()) { 596 if (const Attr *A = ATL.getAttr()) 597 Result.push_back(A); 598 assert(!ATL.getModifiedLoc().isNull()); 599 } 600 } 601 if (const auto *S = N.get<AttributedStmt>()) { 602 for (; S != nullptr; S = dyn_cast<AttributedStmt>(S->getSubStmt())) 603 for (const Attr *A : S->getAttrs()) 604 if (A) 605 Result.push_back(A); 606 } 607 if (const auto *D = N.get<Decl>()) { 608 for (const Attr *A : D->attrs()) 609 if (A) 610 Result.push_back(A); 611 } 612 return Result; 613 } 614 615 std::string getQualification(ASTContext &Context, 616 const DeclContext *DestContext, 617 SourceLocation InsertionPoint, 618 const NamedDecl *ND) { 619 auto VisibleNamespaceDecls = 620 getUsingNamespaceDirectives(DestContext, InsertionPoint); 621 return getQualification( 622 Context, DestContext, ND->getDeclContext(), 623 [&](NestedNameSpecifier *NNS) { 624 if (NNS->getKind() != NestedNameSpecifier::Namespace) 625 return false; 626 const auto *CanonNSD = NNS->getAsNamespace()->getCanonicalDecl(); 627 return llvm::any_of(VisibleNamespaceDecls, 628 [CanonNSD](const NamespaceDecl *NSD) { 629 return NSD->getCanonicalDecl() == CanonNSD; 630 }); 631 }); 632 } 633 634 std::string getQualification(ASTContext &Context, 635 const DeclContext *DestContext, 636 const NamedDecl *ND, 637 llvm::ArrayRef<std::string> VisibleNamespaces) { 638 for (llvm::StringRef NS : VisibleNamespaces) { 639 assert(NS.endswith("::")); 640 (void)NS; 641 } 642 return getQualification( 643 Context, DestContext, ND->getDeclContext(), 644 [&](NestedNameSpecifier *NNS) { 645 return llvm::any_of(VisibleNamespaces, [&](llvm::StringRef Namespace) { 646 std::string NS; 647 llvm::raw_string_ostream OS(NS); 648 NNS->print(OS, Context.getPrintingPolicy()); 649 return OS.str() == Namespace; 650 }); 651 }); 652 } 653 654 bool hasUnstableLinkage(const Decl *D) { 655 // Linkage of a ValueDecl depends on the type. 656 // If that's not deduced yet, deducing it may change the linkage. 657 auto *VD = llvm::dyn_cast_or_null<ValueDecl>(D); 658 return VD && !VD->getType().isNull() && VD->getType()->isUndeducedType(); 659 } 660 661 bool isDeeplyNested(const Decl *D, unsigned MaxDepth) { 662 size_t ContextDepth = 0; 663 for (auto *Ctx = D->getDeclContext(); Ctx && !Ctx->isTranslationUnit(); 664 Ctx = Ctx->getParent()) { 665 if (++ContextDepth == MaxDepth) 666 return true; 667 } 668 return false; 669 } 670 } // namespace clangd 671 } // namespace clang 672