1 //===--- XRefs.cpp -----------------------------------------------*- 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 #include "XRefs.h" 9 #include "AST.h" 10 #include "FindSymbols.h" 11 #include "FindTarget.h" 12 #include "HeuristicResolver.h" 13 #include "ParsedAST.h" 14 #include "Protocol.h" 15 #include "Quality.h" 16 #include "Selection.h" 17 #include "SourceCode.h" 18 #include "URI.h" 19 #include "index/Index.h" 20 #include "index/Merge.h" 21 #include "index/Relation.h" 22 #include "index/SymbolID.h" 23 #include "index/SymbolLocation.h" 24 #include "support/Logger.h" 25 #include "clang/AST/ASTContext.h" 26 #include "clang/AST/ASTTypeTraits.h" 27 #include "clang/AST/Attr.h" 28 #include "clang/AST/Attrs.inc" 29 #include "clang/AST/Decl.h" 30 #include "clang/AST/DeclCXX.h" 31 #include "clang/AST/DeclObjC.h" 32 #include "clang/AST/DeclTemplate.h" 33 #include "clang/AST/DeclVisitor.h" 34 #include "clang/AST/ExprCXX.h" 35 #include "clang/AST/RecursiveASTVisitor.h" 36 #include "clang/AST/Stmt.h" 37 #include "clang/AST/StmtCXX.h" 38 #include "clang/AST/StmtVisitor.h" 39 #include "clang/AST/Type.h" 40 #include "clang/Basic/LLVM.h" 41 #include "clang/Basic/LangOptions.h" 42 #include "clang/Basic/SourceLocation.h" 43 #include "clang/Basic/SourceManager.h" 44 #include "clang/Basic/TokenKinds.h" 45 #include "clang/Index/IndexDataConsumer.h" 46 #include "clang/Index/IndexSymbol.h" 47 #include "clang/Index/IndexingAction.h" 48 #include "clang/Index/IndexingOptions.h" 49 #include "clang/Index/USRGeneration.h" 50 #include "clang/Tooling/Syntax/Tokens.h" 51 #include "llvm/ADT/ArrayRef.h" 52 #include "llvm/ADT/DenseMap.h" 53 #include "llvm/ADT/None.h" 54 #include "llvm/ADT/STLExtras.h" 55 #include "llvm/ADT/ScopeExit.h" 56 #include "llvm/ADT/SmallSet.h" 57 #include "llvm/ADT/SmallVector.h" 58 #include "llvm/ADT/StringRef.h" 59 #include "llvm/Support/Casting.h" 60 #include "llvm/Support/Error.h" 61 #include "llvm/Support/Path.h" 62 #include "llvm/Support/raw_ostream.h" 63 64 namespace clang { 65 namespace clangd { 66 namespace { 67 68 // Returns the single definition of the entity declared by D, if visible. 69 // In particular: 70 // - for non-redeclarable kinds (e.g. local vars), return D 71 // - for kinds that allow multiple definitions (e.g. namespaces), return nullptr 72 // Kinds of nodes that always return nullptr here will not have definitions 73 // reported by locateSymbolAt(). 74 const NamedDecl *getDefinition(const NamedDecl *D) { 75 assert(D); 76 // Decl has one definition that we can find. 77 if (const auto *TD = dyn_cast<TagDecl>(D)) 78 return TD->getDefinition(); 79 if (const auto *VD = dyn_cast<VarDecl>(D)) 80 return VD->getDefinition(); 81 if (const auto *FD = dyn_cast<FunctionDecl>(D)) 82 return FD->getDefinition(); 83 if (const auto *CTD = dyn_cast<ClassTemplateDecl>(D)) 84 if (const auto *RD = CTD->getTemplatedDecl()) 85 return RD->getDefinition(); 86 // Objective-C classes can have three types of declarations: 87 // 88 // - forward declaration: @class MyClass; 89 // - true declaration (interface definition): @interface MyClass ... @end 90 // - true definition (implementation): @implementation MyClass ... @end 91 // 92 // Objective-C categories are extensions are on classes: 93 // 94 // - declaration: @interface MyClass (Ext) ... @end 95 // - definition: @implementation MyClass (Ext) ... @end 96 // 97 // With one special case, a class extension, which is normally used to keep 98 // some declarations internal to a file without exposing them in a header. 99 // 100 // - class extension declaration: @interface MyClass () ... @end 101 // - which really links to class definition: @implementation MyClass ... @end 102 if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(D)) 103 return ID->getImplementation(); 104 if (const auto *CD = dyn_cast<ObjCCategoryDecl>(D)) { 105 if (CD->IsClassExtension()) { 106 if (const auto *ID = CD->getClassInterface()) 107 return ID->getImplementation(); 108 return nullptr; 109 } 110 return CD->getImplementation(); 111 } 112 // Only a single declaration is allowed. 113 if (isa<ValueDecl>(D) || isa<TemplateTypeParmDecl>(D) || 114 isa<TemplateTemplateParmDecl>(D)) // except cases above 115 return D; 116 // Multiple definitions are allowed. 117 return nullptr; // except cases above 118 } 119 120 void logIfOverflow(const SymbolLocation &Loc) { 121 if (Loc.Start.hasOverflow() || Loc.End.hasOverflow()) 122 log("Possible overflow in symbol location: {0}", Loc); 123 } 124 125 // Convert a SymbolLocation to LSP's Location. 126 // TUPath is used to resolve the path of URI. 127 // FIXME: figure out a good home for it, and share the implementation with 128 // FindSymbols. 129 llvm::Optional<Location> toLSPLocation(const SymbolLocation &Loc, 130 llvm::StringRef TUPath) { 131 if (!Loc) 132 return None; 133 auto Uri = URI::parse(Loc.FileURI); 134 if (!Uri) { 135 elog("Could not parse URI {0}: {1}", Loc.FileURI, Uri.takeError()); 136 return None; 137 } 138 auto U = URIForFile::fromURI(*Uri, TUPath); 139 if (!U) { 140 elog("Could not resolve URI {0}: {1}", Loc.FileURI, U.takeError()); 141 return None; 142 } 143 144 Location LSPLoc; 145 LSPLoc.uri = std::move(*U); 146 LSPLoc.range.start.line = Loc.Start.line(); 147 LSPLoc.range.start.character = Loc.Start.column(); 148 LSPLoc.range.end.line = Loc.End.line(); 149 LSPLoc.range.end.character = Loc.End.column(); 150 logIfOverflow(Loc); 151 return LSPLoc; 152 } 153 154 SymbolLocation toIndexLocation(const Location &Loc, std::string &URIStorage) { 155 SymbolLocation SymLoc; 156 URIStorage = Loc.uri.uri(); 157 SymLoc.FileURI = URIStorage.c_str(); 158 SymLoc.Start.setLine(Loc.range.start.line); 159 SymLoc.Start.setColumn(Loc.range.start.character); 160 SymLoc.End.setLine(Loc.range.end.line); 161 SymLoc.End.setColumn(Loc.range.end.character); 162 return SymLoc; 163 } 164 165 // Returns the preferred location between an AST location and an index location. 166 SymbolLocation getPreferredLocation(const Location &ASTLoc, 167 const SymbolLocation &IdxLoc, 168 std::string &Scratch) { 169 // Also use a mock symbol for the index location so that other fields (e.g. 170 // definition) are not factored into the preference. 171 Symbol ASTSym, IdxSym; 172 ASTSym.ID = IdxSym.ID = SymbolID("mock_symbol_id"); 173 ASTSym.CanonicalDeclaration = toIndexLocation(ASTLoc, Scratch); 174 IdxSym.CanonicalDeclaration = IdxLoc; 175 auto Merged = mergeSymbol(ASTSym, IdxSym); 176 return Merged.CanonicalDeclaration; 177 } 178 179 std::vector<std::pair<const NamedDecl *, DeclRelationSet>> 180 getDeclAtPositionWithRelations(ParsedAST &AST, SourceLocation Pos, 181 DeclRelationSet Relations, 182 ASTNodeKind *NodeKind = nullptr) { 183 unsigned Offset = AST.getSourceManager().getDecomposedSpellingLoc(Pos).second; 184 std::vector<std::pair<const NamedDecl *, DeclRelationSet>> Result; 185 auto ResultFromTree = [&](SelectionTree ST) { 186 if (const SelectionTree::Node *N = ST.commonAncestor()) { 187 if (NodeKind) 188 *NodeKind = N->ASTNode.getNodeKind(); 189 // Attributes don't target decls, look at the 190 // thing it's attached to. 191 // We still report the original NodeKind! 192 // This makes the `override` hack work. 193 if (N->ASTNode.get<Attr>() && N->Parent) 194 N = N->Parent; 195 llvm::copy_if(allTargetDecls(N->ASTNode, AST.getHeuristicResolver()), 196 std::back_inserter(Result), 197 [&](auto &Entry) { return !(Entry.second & ~Relations); }); 198 } 199 return !Result.empty(); 200 }; 201 SelectionTree::createEach(AST.getASTContext(), AST.getTokens(), Offset, 202 Offset, ResultFromTree); 203 return Result; 204 } 205 206 std::vector<const NamedDecl *> 207 getDeclAtPosition(ParsedAST &AST, SourceLocation Pos, DeclRelationSet Relations, 208 ASTNodeKind *NodeKind = nullptr) { 209 std::vector<const NamedDecl *> Result; 210 for (auto &Entry : 211 getDeclAtPositionWithRelations(AST, Pos, Relations, NodeKind)) 212 Result.push_back(Entry.first); 213 return Result; 214 } 215 216 // Expects Loc to be a SpellingLocation, will bail out otherwise as it can't 217 // figure out a filename. 218 llvm::Optional<Location> makeLocation(const ASTContext &AST, SourceLocation Loc, 219 llvm::StringRef TUPath) { 220 const auto &SM = AST.getSourceManager(); 221 const FileEntry *F = SM.getFileEntryForID(SM.getFileID(Loc)); 222 if (!F) 223 return None; 224 auto FilePath = getCanonicalPath(F, SM); 225 if (!FilePath) { 226 log("failed to get path!"); 227 return None; 228 } 229 Location L; 230 L.uri = URIForFile::canonicalize(*FilePath, TUPath); 231 // We call MeasureTokenLength here as TokenBuffer doesn't store spelled tokens 232 // outside the main file. 233 auto TokLen = Lexer::MeasureTokenLength(Loc, SM, AST.getLangOpts()); 234 L.range = halfOpenToRange( 235 SM, CharSourceRange::getCharRange(Loc, Loc.getLocWithOffset(TokLen))); 236 return L; 237 } 238 239 // Treat #included files as symbols, to enable go-to-definition on them. 240 llvm::Optional<LocatedSymbol> locateFileReferent(const Position &Pos, 241 ParsedAST &AST, 242 llvm::StringRef MainFilePath) { 243 for (auto &Inc : AST.getIncludeStructure().MainFileIncludes) { 244 if (!Inc.Resolved.empty() && Inc.HashLine == Pos.line) { 245 LocatedSymbol File; 246 File.Name = std::string(llvm::sys::path::filename(Inc.Resolved)); 247 File.PreferredDeclaration = { 248 URIForFile::canonicalize(Inc.Resolved, MainFilePath), Range{}}; 249 File.Definition = File.PreferredDeclaration; 250 // We're not going to find any further symbols on #include lines. 251 return File; 252 } 253 } 254 return llvm::None; 255 } 256 257 // Macros are simple: there's no declaration/definition distinction. 258 // As a consequence, there's no need to look them up in the index either. 259 llvm::Optional<LocatedSymbol> 260 locateMacroReferent(const syntax::Token &TouchedIdentifier, ParsedAST &AST, 261 llvm::StringRef MainFilePath) { 262 if (auto M = locateMacroAt(TouchedIdentifier, AST.getPreprocessor())) { 263 if (auto Loc = 264 makeLocation(AST.getASTContext(), M->NameLoc, MainFilePath)) { 265 LocatedSymbol Macro; 266 Macro.Name = std::string(M->Name); 267 Macro.PreferredDeclaration = *Loc; 268 Macro.Definition = Loc; 269 Macro.ID = getSymbolID(M->Name, M->Info, AST.getSourceManager()); 270 return Macro; 271 } 272 } 273 return llvm::None; 274 } 275 276 // A wrapper around `Decl::getCanonicalDecl` to support cases where Clang's 277 // definition of a canonical declaration doesn't match up to what a programmer 278 // would expect. For example, Objective-C classes can have three types of 279 // declarations: 280 // 281 // - forward declaration(s): @class MyClass; 282 // - true declaration (interface definition): @interface MyClass ... @end 283 // - true definition (implementation): @implementation MyClass ... @end 284 // 285 // Clang will consider the forward declaration to be the canonical declaration 286 // because it is first. We actually want the class definition if it is 287 // available since that is what a programmer would consider the primary 288 // declaration to be. 289 const NamedDecl *getPreferredDecl(const NamedDecl *D) { 290 // FIXME: Canonical declarations of some symbols might refer to built-in 291 // decls with possibly-invalid source locations (e.g. global new operator). 292 // In such cases we should pick up a redecl with valid source location 293 // instead of failing. 294 D = llvm::cast<NamedDecl>(D->getCanonicalDecl()); 295 296 // Prefer Objective-C class/protocol definitions over the forward declaration. 297 if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(D)) 298 if (const auto *DefinitionID = ID->getDefinition()) 299 return DefinitionID; 300 if (const auto *PD = dyn_cast<ObjCProtocolDecl>(D)) 301 if (const auto *DefinitionID = PD->getDefinition()) 302 return DefinitionID; 303 304 return D; 305 } 306 307 std::vector<LocatedSymbol> findImplementors(llvm::DenseSet<SymbolID> IDs, 308 RelationKind Predicate, 309 const SymbolIndex *Index, 310 llvm::StringRef MainFilePath) { 311 if (IDs.empty() || !Index) 312 return {}; 313 static constexpr trace::Metric FindImplementorsMetric( 314 "find_implementors", trace::Metric::Counter, "case"); 315 switch (Predicate) { 316 case RelationKind::BaseOf: 317 FindImplementorsMetric.record(1, "find-base"); 318 break; 319 case RelationKind::OverriddenBy: 320 FindImplementorsMetric.record(1, "find-override"); 321 break; 322 } 323 324 RelationsRequest Req; 325 Req.Predicate = Predicate; 326 Req.Subjects = std::move(IDs); 327 std::vector<LocatedSymbol> Results; 328 Index->relations(Req, [&](const SymbolID &Subject, const Symbol &Object) { 329 auto DeclLoc = 330 indexToLSPLocation(Object.CanonicalDeclaration, MainFilePath); 331 if (!DeclLoc) { 332 elog("Find overrides: {0}", DeclLoc.takeError()); 333 return; 334 } 335 Results.emplace_back(); 336 Results.back().Name = Object.Name.str(); 337 Results.back().PreferredDeclaration = *DeclLoc; 338 auto DefLoc = indexToLSPLocation(Object.Definition, MainFilePath); 339 if (!DefLoc) { 340 elog("Failed to convert location: {0}", DefLoc.takeError()); 341 return; 342 } 343 Results.back().Definition = *DefLoc; 344 }); 345 return Results; 346 } 347 348 // Decls are more complicated. 349 // The AST contains at least a declaration, maybe a definition. 350 // These are up-to-date, and so generally preferred over index results. 351 // We perform a single batch index lookup to find additional definitions. 352 std::vector<LocatedSymbol> 353 locateASTReferent(SourceLocation CurLoc, const syntax::Token *TouchedIdentifier, 354 ParsedAST &AST, llvm::StringRef MainFilePath, 355 const SymbolIndex *Index, ASTNodeKind &NodeKind) { 356 const SourceManager &SM = AST.getSourceManager(); 357 // Results follow the order of Symbols.Decls. 358 std::vector<LocatedSymbol> Result; 359 // Keep track of SymbolID -> index mapping, to fill in index data later. 360 llvm::DenseMap<SymbolID, size_t> ResultIndex; 361 362 static constexpr trace::Metric LocateASTReferentMetric( 363 "locate_ast_referent", trace::Metric::Counter, "case"); 364 auto AddResultDecl = [&](const NamedDecl *D) { 365 D = getPreferredDecl(D); 366 auto Loc = 367 makeLocation(AST.getASTContext(), nameLocation(*D, SM), MainFilePath); 368 if (!Loc) 369 return; 370 371 Result.emplace_back(); 372 Result.back().Name = printName(AST.getASTContext(), *D); 373 Result.back().PreferredDeclaration = *Loc; 374 Result.back().ID = getSymbolID(D); 375 if (const NamedDecl *Def = getDefinition(D)) 376 Result.back().Definition = makeLocation( 377 AST.getASTContext(), nameLocation(*Def, SM), MainFilePath); 378 379 // Record SymbolID for index lookup later. 380 if (auto ID = getSymbolID(D)) 381 ResultIndex[ID] = Result.size() - 1; 382 }; 383 384 // Emit all symbol locations (declaration or definition) from AST. 385 DeclRelationSet Relations = 386 DeclRelation::TemplatePattern | DeclRelation::Alias; 387 auto Candidates = 388 getDeclAtPositionWithRelations(AST, CurLoc, Relations, &NodeKind); 389 llvm::DenseSet<SymbolID> VirtualMethods; 390 for (const auto &E : Candidates) { 391 const NamedDecl *D = E.first; 392 if (const auto *CMD = llvm::dyn_cast<CXXMethodDecl>(D)) { 393 // Special case: virtual void ^method() = 0: jump to all overrides. 394 // FIXME: extend it to ^virtual, unfortunately, virtual location is not 395 // saved in the AST. 396 if (CMD->isPure()) { 397 if (TouchedIdentifier && SM.getSpellingLoc(CMD->getLocation()) == 398 TouchedIdentifier->location()) { 399 VirtualMethods.insert(getSymbolID(CMD)); 400 LocateASTReferentMetric.record(1, "method-to-override"); 401 } 402 } 403 // Special case: void foo() ^override: jump to the overridden method. 404 if (NodeKind.isSame(ASTNodeKind::getFromNodeKind<OverrideAttr>()) || 405 NodeKind.isSame(ASTNodeKind::getFromNodeKind<FinalAttr>())) { 406 // We may be overridding multiple methods - offer them all. 407 for (const NamedDecl *ND : CMD->overridden_methods()) 408 AddResultDecl(ND); 409 continue; 410 } 411 } 412 413 // Special case: the cursor is on an alias, prefer other results. 414 // This targets "using ns::^Foo", where the target is more interesting. 415 // This does not trigger on renaming aliases: 416 // `using Foo = ^Bar` already targets Bar via a TypeLoc 417 // `using ^Foo = Bar` has no other results, as Underlying is filtered. 418 if (E.second & DeclRelation::Alias && Candidates.size() > 1 && 419 // beginLoc/endLoc are a token range, so rewind the identifier we're in. 420 SM.isPointWithin(TouchedIdentifier ? TouchedIdentifier->location() 421 : CurLoc, 422 D->getBeginLoc(), D->getEndLoc())) 423 continue; 424 425 // Special case: the point of declaration of a template specialization, 426 // it's more useful to navigate to the template declaration. 427 if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) { 428 if (TouchedIdentifier && 429 D->getLocation() == TouchedIdentifier->location()) { 430 LocateASTReferentMetric.record(1, "template-specialization-to-primary"); 431 AddResultDecl(CTSD->getSpecializedTemplate()); 432 continue; 433 } 434 } 435 436 // Special case: if the class name is selected, also map Objective-C 437 // categories and category implementations back to their class interface. 438 // 439 // Since `TouchedIdentifier` might refer to the `ObjCCategoryImplDecl` 440 // instead of the `ObjCCategoryDecl` we intentionally check the contents 441 // of the locs when checking for class name equivalence. 442 if (const auto *CD = dyn_cast<ObjCCategoryDecl>(D)) 443 if (const auto *ID = CD->getClassInterface()) 444 if (TouchedIdentifier && 445 (CD->getLocation() == TouchedIdentifier->location() || 446 ID->getName() == TouchedIdentifier->text(SM))) { 447 LocateASTReferentMetric.record(1, "objc-category-to-class"); 448 AddResultDecl(ID); 449 } 450 451 LocateASTReferentMetric.record(1, "regular"); 452 // Otherwise the target declaration is the right one. 453 AddResultDecl(D); 454 } 455 456 // Now query the index for all Symbol IDs we found in the AST. 457 if (Index && !ResultIndex.empty()) { 458 LookupRequest QueryRequest; 459 for (auto It : ResultIndex) 460 QueryRequest.IDs.insert(It.first); 461 std::string Scratch; 462 Index->lookup(QueryRequest, [&](const Symbol &Sym) { 463 auto &R = Result[ResultIndex.lookup(Sym.ID)]; 464 465 if (R.Definition) { // from AST 466 // Special case: if the AST yielded a definition, then it may not be 467 // the right *declaration*. Prefer the one from the index. 468 if (auto Loc = toLSPLocation(Sym.CanonicalDeclaration, MainFilePath)) 469 R.PreferredDeclaration = *Loc; 470 471 // We might still prefer the definition from the index, e.g. for 472 // generated symbols. 473 if (auto Loc = toLSPLocation( 474 getPreferredLocation(*R.Definition, Sym.Definition, Scratch), 475 MainFilePath)) 476 R.Definition = *Loc; 477 } else { 478 R.Definition = toLSPLocation(Sym.Definition, MainFilePath); 479 480 // Use merge logic to choose AST or index declaration. 481 if (auto Loc = toLSPLocation( 482 getPreferredLocation(R.PreferredDeclaration, 483 Sym.CanonicalDeclaration, Scratch), 484 MainFilePath)) 485 R.PreferredDeclaration = *Loc; 486 } 487 }); 488 } 489 490 auto Overrides = findImplementors(VirtualMethods, RelationKind::OverriddenBy, 491 Index, MainFilePath); 492 Result.insert(Result.end(), Overrides.begin(), Overrides.end()); 493 return Result; 494 } 495 496 std::vector<LocatedSymbol> locateSymbolForType(const ParsedAST &AST, 497 const QualType &Type) { 498 const auto &SM = AST.getSourceManager(); 499 auto MainFilePath = 500 getCanonicalPath(SM.getFileEntryForID(SM.getMainFileID()), SM); 501 if (!MainFilePath) { 502 elog("Failed to get a path for the main file, so no symbol."); 503 return {}; 504 } 505 506 // FIXME: this sends unique_ptr<Foo> to unique_ptr<T>. 507 // Likely it would be better to send it to Foo (heuristically) or to both. 508 auto Decls = targetDecl(DynTypedNode::create(Type.getNonReferenceType()), 509 DeclRelation::TemplatePattern | DeclRelation::Alias, 510 AST.getHeuristicResolver()); 511 if (Decls.empty()) 512 return {}; 513 514 std::vector<LocatedSymbol> Results; 515 const auto &ASTContext = AST.getASTContext(); 516 517 for (const NamedDecl *D : Decls) { 518 D = getPreferredDecl(D); 519 520 auto Loc = makeLocation(ASTContext, nameLocation(*D, SM), *MainFilePath); 521 if (!Loc) 522 continue; 523 524 Results.emplace_back(); 525 Results.back().Name = printName(ASTContext, *D); 526 Results.back().PreferredDeclaration = *Loc; 527 Results.back().ID = getSymbolID(D); 528 if (const NamedDecl *Def = getDefinition(D)) 529 Results.back().Definition = 530 makeLocation(ASTContext, nameLocation(*Def, SM), *MainFilePath); 531 } 532 533 return Results; 534 } 535 536 bool tokenSpelledAt(SourceLocation SpellingLoc, const syntax::TokenBuffer &TB) { 537 auto ExpandedTokens = TB.expandedTokens( 538 TB.sourceManager().getMacroArgExpandedLocation(SpellingLoc)); 539 return !ExpandedTokens.empty(); 540 } 541 542 llvm::StringRef sourcePrefix(SourceLocation Loc, const SourceManager &SM) { 543 auto D = SM.getDecomposedLoc(Loc); 544 bool Invalid = false; 545 llvm::StringRef Buf = SM.getBufferData(D.first, &Invalid); 546 if (Invalid || D.second > Buf.size()) 547 return ""; 548 return Buf.substr(0, D.second); 549 } 550 551 bool isDependentName(ASTNodeKind NodeKind) { 552 return NodeKind.isSame(ASTNodeKind::getFromNodeKind<OverloadExpr>()) || 553 NodeKind.isSame( 554 ASTNodeKind::getFromNodeKind<CXXDependentScopeMemberExpr>()) || 555 NodeKind.isSame( 556 ASTNodeKind::getFromNodeKind<DependentScopeDeclRefExpr>()); 557 } 558 559 } // namespace 560 561 std::vector<LocatedSymbol> 562 locateSymbolTextually(const SpelledWord &Word, ParsedAST &AST, 563 const SymbolIndex *Index, const std::string &MainFilePath, 564 ASTNodeKind NodeKind) { 565 // Don't use heuristics if this is a real identifier, or not an 566 // identifier. 567 // Exception: dependent names, because those may have useful textual 568 // matches that AST-based heuristics cannot find. 569 if ((Word.ExpandedToken && !isDependentName(NodeKind)) || 570 !Word.LikelyIdentifier || !Index) 571 return {}; 572 // We don't want to handle words in string literals. (It'd be nice to list 573 // *allowed* token kinds explicitly, but comment Tokens aren't retained). 574 if (Word.PartOfSpelledToken && 575 isStringLiteral(Word.PartOfSpelledToken->kind())) 576 return {}; 577 578 const auto &SM = AST.getSourceManager(); 579 // Look up the selected word in the index. 580 FuzzyFindRequest Req; 581 Req.Query = Word.Text.str(); 582 Req.ProximityPaths = {MainFilePath}; 583 // Find the namespaces to query by lexing the file. 584 Req.Scopes = 585 visibleNamespaces(sourcePrefix(Word.Location, SM), AST.getLangOpts()); 586 // FIXME: For extra strictness, consider AnyScope=false. 587 Req.AnyScope = true; 588 // We limit the results to 3 further below. This limit is to avoid fetching 589 // too much data, while still likely having enough for 3 results to remain 590 // after additional filtering. 591 Req.Limit = 10; 592 bool TooMany = false; 593 using ScoredLocatedSymbol = std::pair<float, LocatedSymbol>; 594 std::vector<ScoredLocatedSymbol> ScoredResults; 595 Index->fuzzyFind(Req, [&](const Symbol &Sym) { 596 // Only consider exact name matches, including case. 597 // This is to avoid too many false positives. 598 // We could relax this in the future (e.g. to allow for typos) if we make 599 // the query more accurate by other means. 600 if (Sym.Name != Word.Text) 601 return; 602 603 // Exclude constructor results. They have the same name as the class, 604 // but we don't have enough context to prefer them over the class. 605 if (Sym.SymInfo.Kind == index::SymbolKind::Constructor) 606 return; 607 608 auto MaybeDeclLoc = 609 indexToLSPLocation(Sym.CanonicalDeclaration, MainFilePath); 610 if (!MaybeDeclLoc) { 611 log("locateSymbolNamedTextuallyAt: {0}", MaybeDeclLoc.takeError()); 612 return; 613 } 614 LocatedSymbol Located; 615 Located.PreferredDeclaration = *MaybeDeclLoc; 616 Located.Name = (Sym.Name + Sym.TemplateSpecializationArgs).str(); 617 Located.ID = Sym.ID; 618 if (Sym.Definition) { 619 auto MaybeDefLoc = indexToLSPLocation(Sym.Definition, MainFilePath); 620 if (!MaybeDefLoc) { 621 log("locateSymbolNamedTextuallyAt: {0}", MaybeDefLoc.takeError()); 622 return; 623 } 624 Located.PreferredDeclaration = *MaybeDefLoc; 625 Located.Definition = *MaybeDefLoc; 626 } 627 628 if (ScoredResults.size() >= 5) { 629 // If we have more than 5 results, don't return anything, 630 // as confidence is too low. 631 // FIXME: Alternatively, try a stricter query? 632 TooMany = true; 633 return; 634 } 635 636 SymbolQualitySignals Quality; 637 Quality.merge(Sym); 638 SymbolRelevanceSignals Relevance; 639 Relevance.Name = Sym.Name; 640 Relevance.Query = SymbolRelevanceSignals::Generic; 641 Relevance.merge(Sym); 642 auto Score = evaluateSymbolAndRelevance(Quality.evaluateHeuristics(), 643 Relevance.evaluateHeuristics()); 644 dlog("locateSymbolNamedTextuallyAt: {0}{1} = {2}\n{3}{4}\n", Sym.Scope, 645 Sym.Name, Score, Quality, Relevance); 646 647 ScoredResults.push_back({Score, std::move(Located)}); 648 }); 649 650 if (TooMany) { 651 vlog("Heuristic index lookup for {0} returned too many candidates, ignored", 652 Word.Text); 653 return {}; 654 } 655 656 llvm::sort(ScoredResults, 657 [](const ScoredLocatedSymbol &A, const ScoredLocatedSymbol &B) { 658 return A.first > B.first; 659 }); 660 std::vector<LocatedSymbol> Results; 661 for (auto &Res : std::move(ScoredResults)) 662 Results.push_back(std::move(Res.second)); 663 if (Results.empty()) 664 vlog("No heuristic index definition for {0}", Word.Text); 665 else 666 log("Found definition heuristically in index for {0}", Word.Text); 667 return Results; 668 } 669 670 const syntax::Token *findNearbyIdentifier(const SpelledWord &Word, 671 const syntax::TokenBuffer &TB) { 672 // Don't use heuristics if this is a real identifier. 673 // Unlikely identifiers are OK if they were used as identifiers nearby. 674 if (Word.ExpandedToken) 675 return nullptr; 676 // We don't want to handle words in string literals. (It'd be nice to list 677 // *allowed* token kinds explicitly, but comment Tokens aren't retained). 678 if (Word.PartOfSpelledToken && 679 isStringLiteral(Word.PartOfSpelledToken->kind())) 680 return {}; 681 682 const SourceManager &SM = TB.sourceManager(); 683 // We prefer the closest possible token, line-wise. Backwards is penalized. 684 // Ties are implicitly broken by traversal order (first-one-wins). 685 auto File = SM.getFileID(Word.Location); 686 unsigned WordLine = SM.getSpellingLineNumber(Word.Location); 687 auto Cost = [&](SourceLocation Loc) -> unsigned { 688 assert(SM.getFileID(Loc) == File && "spelled token in wrong file?"); 689 unsigned Line = SM.getSpellingLineNumber(Loc); 690 return Line >= WordLine ? Line - WordLine : 2 * (WordLine - Line); 691 }; 692 const syntax::Token *BestTok = nullptr; 693 unsigned BestCost = -1; 694 // Search bounds are based on word length: 695 // - forward: 2^N lines 696 // - backward: 2^(N-1) lines. 697 unsigned MaxDistance = 698 1U << std::min<unsigned>(Word.Text.size(), 699 std::numeric_limits<unsigned>::digits - 1); 700 // Line number for SM.translateLineCol() should be one-based, also 701 // SM.translateLineCol() can handle line number greater than 702 // number of lines in the file. 703 // - LineMin = max(1, WordLine + 1 - 2^(N-1)) 704 // - LineMax = WordLine + 1 + 2^N 705 unsigned LineMin = 706 WordLine + 1 <= MaxDistance / 2 ? 1 : WordLine + 1 - MaxDistance / 2; 707 unsigned LineMax = WordLine + 1 + MaxDistance; 708 SourceLocation LocMin = SM.translateLineCol(File, LineMin, 1); 709 assert(LocMin.isValid()); 710 SourceLocation LocMax = SM.translateLineCol(File, LineMax, 1); 711 assert(LocMax.isValid()); 712 713 // Updates BestTok and BestCost if Tok is a good candidate. 714 // May return true if the cost is too high for this token. 715 auto Consider = [&](const syntax::Token &Tok) { 716 if (Tok.location() < LocMin || Tok.location() > LocMax) 717 return true; // we are too far from the word, break the outer loop. 718 if (!(Tok.kind() == tok::identifier && Tok.text(SM) == Word.Text)) 719 return false; 720 // No point guessing the same location we started with. 721 if (Tok.location() == Word.Location) 722 return false; 723 // We've done cheap checks, compute cost so we can break the caller's loop. 724 unsigned TokCost = Cost(Tok.location()); 725 if (TokCost >= BestCost) 726 return true; // causes the outer loop to break. 727 // Allow locations that might be part of the AST, and macros (even if empty) 728 // but not things like disabled preprocessor sections. 729 if (!(tokenSpelledAt(Tok.location(), TB) || TB.expansionStartingAt(&Tok))) 730 return false; 731 // We already verified this token is an improvement. 732 BestCost = TokCost; 733 BestTok = &Tok; 734 return false; 735 }; 736 auto SpelledTokens = TB.spelledTokens(File); 737 // Find where the word occurred in the token stream, to search forward & back. 738 auto *I = llvm::partition_point(SpelledTokens, [&](const syntax::Token &T) { 739 assert(SM.getFileID(T.location()) == SM.getFileID(Word.Location)); 740 return T.location() < Word.Location; // Comparison OK: same file. 741 }); 742 // Search for matches after the cursor. 743 for (const syntax::Token &Tok : llvm::makeArrayRef(I, SpelledTokens.end())) 744 if (Consider(Tok)) 745 break; // costs of later tokens are greater... 746 // Search for matches before the cursor. 747 for (const syntax::Token &Tok : 748 llvm::reverse(llvm::makeArrayRef(SpelledTokens.begin(), I))) 749 if (Consider(Tok)) 750 break; 751 752 if (BestTok) 753 vlog( 754 "Word {0} under cursor {1} isn't a token (after PP), trying nearby {2}", 755 Word.Text, Word.Location.printToString(SM), 756 BestTok->location().printToString(SM)); 757 758 return BestTok; 759 } 760 761 std::vector<LocatedSymbol> locateSymbolAt(ParsedAST &AST, Position Pos, 762 const SymbolIndex *Index) { 763 const auto &SM = AST.getSourceManager(); 764 auto MainFilePath = 765 getCanonicalPath(SM.getFileEntryForID(SM.getMainFileID()), SM); 766 if (!MainFilePath) { 767 elog("Failed to get a path for the main file, so no references"); 768 return {}; 769 } 770 771 if (auto File = locateFileReferent(Pos, AST, *MainFilePath)) 772 return {std::move(*File)}; 773 774 auto CurLoc = sourceLocationInMainFile(SM, Pos); 775 if (!CurLoc) { 776 elog("locateSymbolAt failed to convert position to source location: {0}", 777 CurLoc.takeError()); 778 return {}; 779 } 780 781 const syntax::Token *TouchedIdentifier = nullptr; 782 auto TokensTouchingCursor = 783 syntax::spelledTokensTouching(*CurLoc, AST.getTokens()); 784 for (const syntax::Token &Tok : TokensTouchingCursor) { 785 if (Tok.kind() == tok::identifier) { 786 if (auto Macro = locateMacroReferent(Tok, AST, *MainFilePath)) 787 // Don't look at the AST or index if we have a macro result. 788 // (We'd just return declarations referenced from the macro's 789 // expansion.) 790 return {*std::move(Macro)}; 791 792 TouchedIdentifier = &Tok; 793 break; 794 } 795 796 if (Tok.kind() == tok::kw_auto || Tok.kind() == tok::kw_decltype) { 797 // go-to-definition on auto should find the definition of the deduced 798 // type, if possible 799 if (auto Deduced = getDeducedType(AST.getASTContext(), Tok.location())) { 800 auto LocSym = locateSymbolForType(AST, *Deduced); 801 if (!LocSym.empty()) 802 return LocSym; 803 } 804 } 805 } 806 807 ASTNodeKind NodeKind; 808 auto ASTResults = locateASTReferent(*CurLoc, TouchedIdentifier, AST, 809 *MainFilePath, Index, NodeKind); 810 if (!ASTResults.empty()) 811 return ASTResults; 812 813 // If the cursor can't be resolved directly, try fallback strategies. 814 auto Word = 815 SpelledWord::touching(*CurLoc, AST.getTokens(), AST.getLangOpts()); 816 if (Word) { 817 // Is the same word nearby a real identifier that might refer to something? 818 if (const syntax::Token *NearbyIdent = 819 findNearbyIdentifier(*Word, AST.getTokens())) { 820 if (auto Macro = locateMacroReferent(*NearbyIdent, AST, *MainFilePath)) { 821 log("Found macro definition heuristically using nearby identifier {0}", 822 Word->Text); 823 return {*std::move(Macro)}; 824 } 825 ASTResults = locateASTReferent(NearbyIdent->location(), NearbyIdent, AST, 826 *MainFilePath, Index, NodeKind); 827 if (!ASTResults.empty()) { 828 log("Found definition heuristically using nearby identifier {0}", 829 NearbyIdent->text(SM)); 830 return ASTResults; 831 } 832 vlog("No definition found using nearby identifier {0} at {1}", Word->Text, 833 Word->Location.printToString(SM)); 834 } 835 // No nearby word, or it didn't refer to anything either. Try the index. 836 auto TextualResults = 837 locateSymbolTextually(*Word, AST, Index, *MainFilePath, NodeKind); 838 if (!TextualResults.empty()) 839 return TextualResults; 840 } 841 842 return {}; 843 } 844 845 std::vector<DocumentLink> getDocumentLinks(ParsedAST &AST) { 846 const auto &SM = AST.getSourceManager(); 847 auto MainFilePath = 848 getCanonicalPath(SM.getFileEntryForID(SM.getMainFileID()), SM); 849 if (!MainFilePath) { 850 elog("Failed to get a path for the main file, so no links"); 851 return {}; 852 } 853 854 std::vector<DocumentLink> Result; 855 for (auto &Inc : AST.getIncludeStructure().MainFileIncludes) { 856 if (Inc.Resolved.empty()) 857 continue; 858 auto HashLoc = SM.getComposedLoc(SM.getMainFileID(), Inc.HashOffset); 859 const auto *HashTok = AST.getTokens().spelledTokenAt(HashLoc); 860 assert(HashTok && "got inclusion at wrong offset"); 861 const auto *IncludeTok = std::next(HashTok); 862 const auto *FileTok = std::next(IncludeTok); 863 // FileTok->range is not sufficient here, as raw lexing wouldn't yield 864 // correct tokens for angled filenames. Hence we explicitly use 865 // Inc.Written's length. 866 auto FileRange = 867 syntax::FileRange(SM, FileTok->location(), Inc.Written.length()) 868 .toCharRange(SM); 869 870 Result.push_back( 871 DocumentLink({halfOpenToRange(SM, FileRange), 872 URIForFile::canonicalize(Inc.Resolved, *MainFilePath)})); 873 } 874 875 return Result; 876 } 877 878 namespace { 879 880 /// Collects references to symbols within the main file. 881 class ReferenceFinder : public index::IndexDataConsumer { 882 public: 883 struct Reference { 884 syntax::Token SpelledTok; 885 index::SymbolRoleSet Role; 886 SymbolID Target; 887 888 Range range(const SourceManager &SM) const { 889 return halfOpenToRange(SM, SpelledTok.range(SM).toCharRange(SM)); 890 } 891 }; 892 893 ReferenceFinder(const ParsedAST &AST, 894 const llvm::ArrayRef<const NamedDecl *> Targets, bool PerToken) 895 : PerToken(PerToken), AST(AST) { 896 for (const NamedDecl *ND : Targets) { 897 const Decl *CD = ND->getCanonicalDecl(); 898 TargetDeclToID[CD] = getSymbolID(CD); 899 } 900 } 901 902 std::vector<Reference> take() && { 903 llvm::sort(References, [](const Reference &L, const Reference &R) { 904 auto LTok = L.SpelledTok.location(); 905 auto RTok = R.SpelledTok.location(); 906 return std::tie(LTok, L.Role) < std::tie(RTok, R.Role); 907 }); 908 // We sometimes see duplicates when parts of the AST get traversed twice. 909 References.erase(std::unique(References.begin(), References.end(), 910 [](const Reference &L, const Reference &R) { 911 auto LTok = L.SpelledTok.location(); 912 auto RTok = R.SpelledTok.location(); 913 return std::tie(LTok, L.Role) == 914 std::tie(RTok, R.Role); 915 }), 916 References.end()); 917 return std::move(References); 918 } 919 920 bool 921 handleDeclOccurrence(const Decl *D, index::SymbolRoleSet Roles, 922 llvm::ArrayRef<index::SymbolRelation> Relations, 923 SourceLocation Loc, 924 index::IndexDataConsumer::ASTNodeInfo ASTNode) override { 925 auto DeclID = TargetDeclToID.find(D->getCanonicalDecl()); 926 if (DeclID == TargetDeclToID.end()) 927 return true; 928 const SourceManager &SM = AST.getSourceManager(); 929 if (!isInsideMainFile(Loc, SM)) 930 return true; 931 const auto &TB = AST.getTokens(); 932 933 llvm::SmallVector<SourceLocation, 1> Locs; 934 if (PerToken) { 935 // Check whether this is one of the few constructs where the reference 936 // can be split over several tokens. 937 if (auto *OME = llvm::dyn_cast_or_null<ObjCMessageExpr>(ASTNode.OrigE)) { 938 OME->getSelectorLocs(Locs); 939 } else if (auto *OMD = 940 llvm::dyn_cast_or_null<ObjCMethodDecl>(ASTNode.OrigD)) { 941 OMD->getSelectorLocs(Locs); 942 } 943 // Sanity check: we expect the *first* token to match the reported loc. 944 // Otherwise, maybe it was e.g. some other kind of reference to a Decl. 945 if (!Locs.empty() && Locs.front() != Loc) 946 Locs.clear(); // First token doesn't match, assume our guess was wrong. 947 } 948 if (Locs.empty()) 949 Locs.push_back(Loc); 950 951 for (SourceLocation L : Locs) { 952 L = SM.getFileLoc(L); 953 if (const auto *Tok = TB.spelledTokenAt(L)) 954 References.push_back({*Tok, Roles, DeclID->getSecond()}); 955 } 956 return true; 957 } 958 959 private: 960 bool PerToken; // If true, report 3 references for split ObjC selector names. 961 std::vector<Reference> References; 962 const ParsedAST &AST; 963 llvm::DenseMap<const Decl *, SymbolID> TargetDeclToID; 964 }; 965 966 std::vector<ReferenceFinder::Reference> 967 findRefs(const llvm::ArrayRef<const NamedDecl*> TargetDecls, ParsedAST &AST, 968 bool PerToken) { 969 ReferenceFinder RefFinder(AST, TargetDecls, PerToken); 970 index::IndexingOptions IndexOpts; 971 IndexOpts.SystemSymbolFilter = 972 index::IndexingOptions::SystemSymbolFilterKind::All; 973 IndexOpts.IndexFunctionLocals = true; 974 IndexOpts.IndexParametersInDeclarations = true; 975 IndexOpts.IndexTemplateParameters = true; 976 indexTopLevelDecls(AST.getASTContext(), AST.getPreprocessor(), 977 AST.getLocalTopLevelDecls(), RefFinder, IndexOpts); 978 return std::move(RefFinder).take(); 979 } 980 981 const Stmt *getFunctionBody(DynTypedNode N) { 982 if (const auto *FD = N.get<FunctionDecl>()) 983 return FD->getBody(); 984 if (const auto *FD = N.get<BlockDecl>()) 985 return FD->getBody(); 986 if (const auto *FD = N.get<LambdaExpr>()) 987 return FD->getBody(); 988 if (const auto *FD = N.get<ObjCMethodDecl>()) 989 return FD->getBody(); 990 return nullptr; 991 } 992 993 const Stmt *getLoopBody(DynTypedNode N) { 994 if (const auto *LS = N.get<ForStmt>()) 995 return LS->getBody(); 996 if (const auto *LS = N.get<CXXForRangeStmt>()) 997 return LS->getBody(); 998 if (const auto *LS = N.get<WhileStmt>()) 999 return LS->getBody(); 1000 if (const auto *LS = N.get<DoStmt>()) 1001 return LS->getBody(); 1002 return nullptr; 1003 } 1004 1005 // AST traversal to highlight control flow statements under some root. 1006 // Once we hit further control flow we prune the tree (or at least restrict 1007 // what we highlight) so we capture e.g. breaks from the outer loop only. 1008 class FindControlFlow : public RecursiveASTVisitor<FindControlFlow> { 1009 // Types of control-flow statements we might highlight. 1010 enum Target { 1011 Break = 1, 1012 Continue = 2, 1013 Return = 4, 1014 Case = 8, 1015 Throw = 16, 1016 Goto = 32, 1017 All = Break | Continue | Return | Case | Throw | Goto, 1018 }; 1019 int Ignore = 0; // bitmask of Target - what are we *not* highlighting? 1020 SourceRange Bounds; // Half-open, restricts reported targets. 1021 std::vector<SourceLocation> &Result; 1022 const SourceManager &SM; 1023 1024 // Masks out targets for a traversal into D. 1025 // Traverses the subtree using Delegate() if any targets remain. 1026 template <typename Func> 1027 bool filterAndTraverse(DynTypedNode D, const Func &Delegate) { 1028 auto RestoreIgnore = llvm::make_scope_exit( 1029 [OldIgnore(Ignore), this] { Ignore = OldIgnore; }); 1030 if (getFunctionBody(D)) 1031 Ignore = All; 1032 else if (getLoopBody(D)) 1033 Ignore |= Continue | Break; 1034 else if (D.get<SwitchStmt>()) 1035 Ignore |= Break | Case; 1036 // Prune tree if we're not looking for anything. 1037 return (Ignore == All) ? true : Delegate(); 1038 } 1039 1040 void found(Target T, SourceLocation Loc) { 1041 if (T & Ignore) 1042 return; 1043 if (SM.isBeforeInTranslationUnit(Loc, Bounds.getBegin()) || 1044 SM.isBeforeInTranslationUnit(Bounds.getEnd(), Loc)) 1045 return; 1046 Result.push_back(Loc); 1047 } 1048 1049 public: 1050 FindControlFlow(SourceRange Bounds, std::vector<SourceLocation> &Result, 1051 const SourceManager &SM) 1052 : Bounds(Bounds), Result(Result), SM(SM) {} 1053 1054 // When traversing function or loops, limit targets to those that still 1055 // refer to the original root. 1056 bool TraverseDecl(Decl *D) { 1057 return !D || filterAndTraverse(DynTypedNode::create(*D), [&] { 1058 return RecursiveASTVisitor::TraverseDecl(D); 1059 }); 1060 } 1061 bool TraverseStmt(Stmt *S) { 1062 return !S || filterAndTraverse(DynTypedNode::create(*S), [&] { 1063 return RecursiveASTVisitor::TraverseStmt(S); 1064 }); 1065 } 1066 1067 // Add leaves that we found and want. 1068 bool VisitReturnStmt(ReturnStmt *R) { 1069 found(Return, R->getReturnLoc()); 1070 return true; 1071 } 1072 bool VisitBreakStmt(BreakStmt *B) { 1073 found(Break, B->getBreakLoc()); 1074 return true; 1075 } 1076 bool VisitContinueStmt(ContinueStmt *C) { 1077 found(Continue, C->getContinueLoc()); 1078 return true; 1079 } 1080 bool VisitSwitchCase(SwitchCase *C) { 1081 found(Case, C->getKeywordLoc()); 1082 return true; 1083 } 1084 bool VisitCXXThrowExpr(CXXThrowExpr *T) { 1085 found(Throw, T->getThrowLoc()); 1086 return true; 1087 } 1088 bool VisitGotoStmt(GotoStmt *G) { 1089 // Goto is interesting if its target is outside the root. 1090 if (const auto *LD = G->getLabel()) { 1091 if (SM.isBeforeInTranslationUnit(LD->getLocation(), Bounds.getBegin()) || 1092 SM.isBeforeInTranslationUnit(Bounds.getEnd(), LD->getLocation())) 1093 found(Goto, G->getGotoLoc()); 1094 } 1095 return true; 1096 } 1097 }; 1098 1099 // Given a location within a switch statement, return the half-open range that 1100 // covers the case it's contained in. 1101 // We treat `case X: case Y: ...` as one case, and assume no other fallthrough. 1102 SourceRange findCaseBounds(const SwitchStmt &Switch, SourceLocation Loc, 1103 const SourceManager &SM) { 1104 // Cases are not stored in order, sort them first. 1105 // (In fact they seem to be stored in reverse order, don't rely on this) 1106 std::vector<const SwitchCase *> Cases; 1107 for (const SwitchCase *Case = Switch.getSwitchCaseList(); Case; 1108 Case = Case->getNextSwitchCase()) 1109 Cases.push_back(Case); 1110 llvm::sort(Cases, [&](const SwitchCase *L, const SwitchCase *R) { 1111 return SM.isBeforeInTranslationUnit(L->getKeywordLoc(), R->getKeywordLoc()); 1112 }); 1113 1114 // Find the first case after the target location, the end of our range. 1115 auto CaseAfter = llvm::partition_point(Cases, [&](const SwitchCase *C) { 1116 return !SM.isBeforeInTranslationUnit(Loc, C->getKeywordLoc()); 1117 }); 1118 SourceLocation End = CaseAfter == Cases.end() ? Switch.getEndLoc() 1119 : (*CaseAfter)->getKeywordLoc(); 1120 1121 // Our target can be before the first case - cases are optional! 1122 if (CaseAfter == Cases.begin()) 1123 return SourceRange(Switch.getBeginLoc(), End); 1124 // The start of our range is usually the previous case, but... 1125 auto CaseBefore = std::prev(CaseAfter); 1126 // ... rewind CaseBefore to the first in a `case A: case B: ...` sequence. 1127 while (CaseBefore != Cases.begin() && 1128 (*std::prev(CaseBefore))->getSubStmt() == *CaseBefore) 1129 --CaseBefore; 1130 return SourceRange((*CaseBefore)->getKeywordLoc(), End); 1131 } 1132 1133 // Returns the locations of control flow statements related to N. e.g.: 1134 // for => branches: break/continue/return/throw 1135 // break => controlling loop (forwhile/do), and its related control flow 1136 // return => all returns/throws from the same function 1137 // When an inner block is selected, we include branches bound to outer blocks 1138 // as these are exits from the inner block. e.g. return in a for loop. 1139 // FIXME: We don't analyze catch blocks, throw is treated the same as return. 1140 std::vector<SourceLocation> relatedControlFlow(const SelectionTree::Node &N) { 1141 const SourceManager &SM = 1142 N.getDeclContext().getParentASTContext().getSourceManager(); 1143 std::vector<SourceLocation> Result; 1144 1145 // First, check if we're at a node that can resolve to a root. 1146 enum class Cur { None, Break, Continue, Return, Case, Throw } Cursor; 1147 if (N.ASTNode.get<BreakStmt>()) { 1148 Cursor = Cur::Break; 1149 } else if (N.ASTNode.get<ContinueStmt>()) { 1150 Cursor = Cur::Continue; 1151 } else if (N.ASTNode.get<ReturnStmt>()) { 1152 Cursor = Cur::Return; 1153 } else if (N.ASTNode.get<CXXThrowExpr>()) { 1154 Cursor = Cur::Throw; 1155 } else if (N.ASTNode.get<SwitchCase>()) { 1156 Cursor = Cur::Case; 1157 } else if (const GotoStmt *GS = N.ASTNode.get<GotoStmt>()) { 1158 // We don't know what root to associate with, but highlight the goto/label. 1159 Result.push_back(GS->getGotoLoc()); 1160 if (const auto *LD = GS->getLabel()) 1161 Result.push_back(LD->getLocation()); 1162 Cursor = Cur::None; 1163 } else { 1164 Cursor = Cur::None; 1165 } 1166 1167 const Stmt *Root = nullptr; // Loop or function body to traverse. 1168 SourceRange Bounds; 1169 // Look up the tree for a root (or just at this node if we didn't find a leaf) 1170 for (const auto *P = &N; P; P = P->Parent) { 1171 // return associates with enclosing function 1172 if (const Stmt *FunctionBody = getFunctionBody(P->ASTNode)) { 1173 if (Cursor == Cur::Return || Cursor == Cur::Throw) { 1174 Root = FunctionBody; 1175 } 1176 break; // other leaves don't cross functions. 1177 } 1178 // break/continue associate with enclosing loop. 1179 if (const Stmt *LoopBody = getLoopBody(P->ASTNode)) { 1180 if (Cursor == Cur::None || Cursor == Cur::Break || 1181 Cursor == Cur::Continue) { 1182 Root = LoopBody; 1183 // Highlight the loop keyword itself. 1184 // FIXME: for do-while, this only covers the `do`.. 1185 Result.push_back(P->ASTNode.getSourceRange().getBegin()); 1186 break; 1187 } 1188 } 1189 // For switches, users think of case statements as control flow blocks. 1190 // We highlight only occurrences surrounded by the same case. 1191 // We don't detect fallthrough (other than 'case X, case Y'). 1192 if (const auto *SS = P->ASTNode.get<SwitchStmt>()) { 1193 if (Cursor == Cur::Break || Cursor == Cur::Case) { 1194 Result.push_back(SS->getSwitchLoc()); // Highlight the switch. 1195 Root = SS->getBody(); 1196 // Limit to enclosing case, if there is one. 1197 Bounds = findCaseBounds(*SS, N.ASTNode.getSourceRange().getBegin(), SM); 1198 break; 1199 } 1200 } 1201 // If we didn't start at some interesting node, we're done. 1202 if (Cursor == Cur::None) 1203 break; 1204 } 1205 if (Root) { 1206 if (!Bounds.isValid()) 1207 Bounds = Root->getSourceRange(); 1208 FindControlFlow(Bounds, Result, SM).TraverseStmt(const_cast<Stmt *>(Root)); 1209 } 1210 return Result; 1211 } 1212 1213 DocumentHighlight toHighlight(const ReferenceFinder::Reference &Ref, 1214 const SourceManager &SM) { 1215 DocumentHighlight DH; 1216 DH.range = Ref.range(SM); 1217 if (Ref.Role & index::SymbolRoleSet(index::SymbolRole::Write)) 1218 DH.kind = DocumentHighlightKind::Write; 1219 else if (Ref.Role & index::SymbolRoleSet(index::SymbolRole::Read)) 1220 DH.kind = DocumentHighlightKind::Read; 1221 else 1222 DH.kind = DocumentHighlightKind::Text; 1223 return DH; 1224 } 1225 1226 llvm::Optional<DocumentHighlight> toHighlight(SourceLocation Loc, 1227 const syntax::TokenBuffer &TB) { 1228 Loc = TB.sourceManager().getFileLoc(Loc); 1229 if (const auto *Tok = TB.spelledTokenAt(Loc)) { 1230 DocumentHighlight Result; 1231 Result.range = halfOpenToRange( 1232 TB.sourceManager(), 1233 CharSourceRange::getCharRange(Tok->location(), Tok->endLocation())); 1234 return Result; 1235 } 1236 return llvm::None; 1237 } 1238 1239 } // namespace 1240 1241 std::vector<DocumentHighlight> findDocumentHighlights(ParsedAST &AST, 1242 Position Pos) { 1243 const SourceManager &SM = AST.getSourceManager(); 1244 // FIXME: show references to macro within file? 1245 auto CurLoc = sourceLocationInMainFile(SM, Pos); 1246 if (!CurLoc) { 1247 llvm::consumeError(CurLoc.takeError()); 1248 return {}; 1249 } 1250 std::vector<DocumentHighlight> Result; 1251 auto TryTree = [&](SelectionTree ST) { 1252 if (const SelectionTree::Node *N = ST.commonAncestor()) { 1253 DeclRelationSet Relations = 1254 DeclRelation::TemplatePattern | DeclRelation::Alias; 1255 auto TargetDecls= 1256 targetDecl(N->ASTNode, Relations, AST.getHeuristicResolver()); 1257 if (!TargetDecls.empty()) { 1258 // FIXME: we may get multiple DocumentHighlights with the same location 1259 // and different kinds, deduplicate them. 1260 for (const auto &Ref : findRefs(TargetDecls, AST, /*PerToken=*/true)) 1261 Result.push_back(toHighlight(Ref, SM)); 1262 return true; 1263 } 1264 auto ControlFlow = relatedControlFlow(*N); 1265 if (!ControlFlow.empty()) { 1266 for (SourceLocation Loc : ControlFlow) 1267 if (auto Highlight = toHighlight(Loc, AST.getTokens())) 1268 Result.push_back(std::move(*Highlight)); 1269 return true; 1270 } 1271 } 1272 return false; 1273 }; 1274 1275 unsigned Offset = 1276 AST.getSourceManager().getDecomposedSpellingLoc(*CurLoc).second; 1277 SelectionTree::createEach(AST.getASTContext(), AST.getTokens(), Offset, 1278 Offset, TryTree); 1279 return Result; 1280 } 1281 1282 std::vector<LocatedSymbol> findImplementations(ParsedAST &AST, Position Pos, 1283 const SymbolIndex *Index) { 1284 // We rely on index to find the implementations in subclasses. 1285 // FIXME: Index can be stale, so we may loose some latest results from the 1286 // main file. 1287 if (!Index) 1288 return {}; 1289 const SourceManager &SM = AST.getSourceManager(); 1290 auto MainFilePath = 1291 getCanonicalPath(SM.getFileEntryForID(SM.getMainFileID()), SM); 1292 if (!MainFilePath) { 1293 elog("Failed to get a path for the main file, so no implementations."); 1294 return {}; 1295 } 1296 auto CurLoc = sourceLocationInMainFile(SM, Pos); 1297 if (!CurLoc) { 1298 elog("Failed to convert position to source location: {0}", 1299 CurLoc.takeError()); 1300 return {}; 1301 } 1302 DeclRelationSet Relations = 1303 DeclRelation::TemplatePattern | DeclRelation::Alias; 1304 llvm::DenseSet<SymbolID> IDs; 1305 RelationKind QueryKind = RelationKind::OverriddenBy; 1306 for (const NamedDecl *ND : getDeclAtPosition(AST, *CurLoc, Relations)) { 1307 if (const auto *CXXMD = llvm::dyn_cast<CXXMethodDecl>(ND)) { 1308 if (CXXMD->isVirtual()) { 1309 IDs.insert(getSymbolID(ND)); 1310 QueryKind = RelationKind::OverriddenBy; 1311 } 1312 } else if (const auto *RD = dyn_cast<CXXRecordDecl>(ND)) { 1313 IDs.insert(getSymbolID(RD)); 1314 QueryKind = RelationKind::BaseOf; 1315 } 1316 } 1317 return findImplementors(std::move(IDs), QueryKind, Index, *MainFilePath); 1318 } 1319 1320 namespace { 1321 // Recursively finds all the overridden methods of `CMD` in complete type 1322 // hierarchy. 1323 void getOverriddenMethods(const CXXMethodDecl *CMD, 1324 llvm::DenseSet<SymbolID> &OverriddenMethods) { 1325 if (!CMD) 1326 return; 1327 for (const CXXMethodDecl *Base : CMD->overridden_methods()) { 1328 if (auto ID = getSymbolID(Base)) 1329 OverriddenMethods.insert(ID); 1330 getOverriddenMethods(Base, OverriddenMethods); 1331 } 1332 } 1333 } // namespace 1334 1335 ReferencesResult findReferences(ParsedAST &AST, Position Pos, uint32_t Limit, 1336 const SymbolIndex *Index) { 1337 ReferencesResult Results; 1338 const SourceManager &SM = AST.getSourceManager(); 1339 auto MainFilePath = 1340 getCanonicalPath(SM.getFileEntryForID(SM.getMainFileID()), SM); 1341 if (!MainFilePath) { 1342 elog("Failed to get a path for the main file, so no references"); 1343 return Results; 1344 } 1345 auto URIMainFile = URIForFile::canonicalize(*MainFilePath, *MainFilePath); 1346 auto CurLoc = sourceLocationInMainFile(SM, Pos); 1347 if (!CurLoc) { 1348 llvm::consumeError(CurLoc.takeError()); 1349 return {}; 1350 } 1351 1352 llvm::DenseSet<SymbolID> IDsToQuery, OverriddenMethods; 1353 1354 const auto *IdentifierAtCursor = 1355 syntax::spelledIdentifierTouching(*CurLoc, AST.getTokens()); 1356 llvm::Optional<DefinedMacro> Macro; 1357 if (IdentifierAtCursor) 1358 Macro = locateMacroAt(*IdentifierAtCursor, AST.getPreprocessor()); 1359 if (Macro) { 1360 // Handle references to macro. 1361 if (auto MacroSID = getSymbolID(Macro->Name, Macro->Info, SM)) { 1362 // Collect macro references from main file. 1363 const auto &IDToRefs = AST.getMacros().MacroRefs; 1364 auto Refs = IDToRefs.find(MacroSID); 1365 if (Refs != IDToRefs.end()) { 1366 for (const auto &Ref : Refs->second) { 1367 ReferencesResult::Reference Result; 1368 Result.Loc.range = Ref.Rng; 1369 Result.Loc.uri = URIMainFile; 1370 if (Ref.IsDefinition) { 1371 Result.Attributes |= ReferencesResult::Declaration; 1372 Result.Attributes |= ReferencesResult::Definition; 1373 } 1374 Results.References.push_back(std::move(Result)); 1375 } 1376 } 1377 IDsToQuery.insert(MacroSID); 1378 } 1379 } else { 1380 // Handle references to Decls. 1381 1382 DeclRelationSet Relations = 1383 DeclRelation::TemplatePattern | DeclRelation::Alias; 1384 std::vector<const NamedDecl *> Decls = 1385 getDeclAtPosition(AST, *CurLoc, Relations); 1386 llvm::SmallVector<const NamedDecl *> TargetsInMainFile; 1387 for (const NamedDecl *D : Decls) { 1388 auto ID = getSymbolID(D); 1389 if (!ID) 1390 continue; 1391 TargetsInMainFile.push_back(D); 1392 // Not all symbols can be referenced from outside (e.g. function-locals). 1393 // TODO: we could skip TU-scoped symbols here (e.g. static functions) if 1394 // we know this file isn't a header. The details might be tricky. 1395 if (D->getParentFunctionOrMethod()) 1396 continue; 1397 IDsToQuery.insert(ID); 1398 } 1399 1400 RelationsRequest OverriddenBy; 1401 if (Index) { 1402 OverriddenBy.Predicate = RelationKind::OverriddenBy; 1403 for (const NamedDecl *ND : Decls) { 1404 // Special case: For virtual methods, report decl/def of overrides and 1405 // references to all overridden methods in complete type hierarchy. 1406 if (const auto *CMD = llvm::dyn_cast<CXXMethodDecl>(ND)) { 1407 if (CMD->isVirtual()) { 1408 if (auto ID = getSymbolID(CMD)) 1409 OverriddenBy.Subjects.insert(ID); 1410 getOverriddenMethods(CMD, OverriddenMethods); 1411 } 1412 } 1413 } 1414 } 1415 1416 // We traverse the AST to find references in the main file. 1417 auto MainFileRefs = findRefs(TargetsInMainFile, AST, /*PerToken=*/false); 1418 // We may get multiple refs with the same location and different Roles, as 1419 // cross-reference is only interested in locations, we deduplicate them 1420 // by the location to avoid emitting duplicated locations. 1421 MainFileRefs.erase(std::unique(MainFileRefs.begin(), MainFileRefs.end(), 1422 [](const ReferenceFinder::Reference &L, 1423 const ReferenceFinder::Reference &R) { 1424 return L.SpelledTok.location() == 1425 R.SpelledTok.location(); 1426 }), 1427 MainFileRefs.end()); 1428 for (const auto &Ref : MainFileRefs) { 1429 ReferencesResult::Reference Result; 1430 Result.Loc.range = Ref.range(SM); 1431 Result.Loc.uri = URIMainFile; 1432 if (Ref.Role & static_cast<unsigned>(index::SymbolRole::Declaration)) 1433 Result.Attributes |= ReferencesResult::Declaration; 1434 // clang-index doesn't report definitions as declarations, but they are. 1435 if (Ref.Role & static_cast<unsigned>(index::SymbolRole::Definition)) 1436 Result.Attributes |= 1437 ReferencesResult::Definition | ReferencesResult::Declaration; 1438 Results.References.push_back(std::move(Result)); 1439 } 1440 // Add decl/def of overridding methods. 1441 if (Index && !OverriddenBy.Subjects.empty()) { 1442 Index->relations(OverriddenBy, [&](const SymbolID &Subject, 1443 const Symbol &Object) { 1444 if (Limit && Results.References.size() >= Limit) { 1445 Results.HasMore = true; 1446 return; 1447 } 1448 const auto LSPLocDecl = 1449 toLSPLocation(Object.CanonicalDeclaration, *MainFilePath); 1450 const auto LSPLocDef = toLSPLocation(Object.Definition, *MainFilePath); 1451 if (LSPLocDecl && LSPLocDecl != LSPLocDef) { 1452 ReferencesResult::Reference Result; 1453 Result.Loc = std::move(*LSPLocDecl); 1454 Result.Attributes = 1455 ReferencesResult::Declaration | ReferencesResult::Override; 1456 Results.References.push_back(std::move(Result)); 1457 } 1458 if (LSPLocDef) { 1459 ReferencesResult::Reference Result; 1460 Result.Loc = std::move(*LSPLocDef); 1461 Result.Attributes = ReferencesResult::Declaration | 1462 ReferencesResult::Definition | 1463 ReferencesResult::Override; 1464 Results.References.push_back(std::move(Result)); 1465 } 1466 }); 1467 } 1468 } 1469 // Now query the index for references from other files. 1470 auto QueryIndex = [&](llvm::DenseSet<SymbolID> IDs, bool AllowAttributes, 1471 bool AllowMainFileSymbols) { 1472 if (IDs.empty() || !Index || Results.HasMore) 1473 return; 1474 RefsRequest Req; 1475 Req.IDs = std::move(IDs); 1476 if (Limit) { 1477 if (Limit < Results.References.size()) { 1478 // We've already filled our quota, still check the index to correctly 1479 // return the `HasMore` info. 1480 Req.Limit = 0; 1481 } else { 1482 // Query index only for the remaining size. 1483 Req.Limit = Limit - Results.References.size(); 1484 } 1485 } 1486 Results.HasMore |= Index->refs(Req, [&](const Ref &R) { 1487 auto LSPLoc = toLSPLocation(R.Location, *MainFilePath); 1488 // Avoid indexed results for the main file - the AST is authoritative. 1489 if (!LSPLoc || 1490 (!AllowMainFileSymbols && LSPLoc->uri.file() == *MainFilePath)) 1491 return; 1492 ReferencesResult::Reference Result; 1493 Result.Loc = std::move(*LSPLoc); 1494 if (AllowAttributes) { 1495 if ((R.Kind & RefKind::Declaration) == RefKind::Declaration) 1496 Result.Attributes |= ReferencesResult::Declaration; 1497 // FIXME: our index should definitely store def | decl separately! 1498 if ((R.Kind & RefKind::Definition) == RefKind::Definition) 1499 Result.Attributes |= 1500 ReferencesResult::Declaration | ReferencesResult::Definition; 1501 } 1502 Results.References.push_back(std::move(Result)); 1503 }); 1504 }; 1505 QueryIndex(std::move(IDsToQuery), /*AllowAttributes=*/true, 1506 /*AllowMainFileSymbols=*/false); 1507 // For a virtual method: Occurrences of BaseMethod should be treated as refs 1508 // and not as decl/def. Allow symbols from main file since AST does not report 1509 // these. 1510 QueryIndex(std::move(OverriddenMethods), /*AllowAttributes=*/false, 1511 /*AllowMainFileSymbols=*/true); 1512 return Results; 1513 } 1514 1515 std::vector<SymbolDetails> getSymbolInfo(ParsedAST &AST, Position Pos) { 1516 const SourceManager &SM = AST.getSourceManager(); 1517 auto CurLoc = sourceLocationInMainFile(SM, Pos); 1518 if (!CurLoc) { 1519 llvm::consumeError(CurLoc.takeError()); 1520 return {}; 1521 } 1522 1523 std::vector<SymbolDetails> Results; 1524 1525 // We also want the targets of using-decls, so we include 1526 // DeclRelation::Underlying. 1527 DeclRelationSet Relations = DeclRelation::TemplatePattern | 1528 DeclRelation::Alias | DeclRelation::Underlying; 1529 for (const NamedDecl *D : getDeclAtPosition(AST, *CurLoc, Relations)) { 1530 SymbolDetails NewSymbol; 1531 std::string QName = printQualifiedName(*D); 1532 auto SplitQName = splitQualifiedName(QName); 1533 NewSymbol.containerName = std::string(SplitQName.first); 1534 NewSymbol.name = std::string(SplitQName.second); 1535 1536 if (NewSymbol.containerName.empty()) { 1537 if (const auto *ParentND = 1538 dyn_cast_or_null<NamedDecl>(D->getDeclContext())) 1539 NewSymbol.containerName = printQualifiedName(*ParentND); 1540 } 1541 llvm::SmallString<32> USR; 1542 if (!index::generateUSRForDecl(D, USR)) { 1543 NewSymbol.USR = std::string(USR.str()); 1544 NewSymbol.ID = SymbolID(NewSymbol.USR); 1545 } 1546 Results.push_back(std::move(NewSymbol)); 1547 } 1548 1549 const auto *IdentifierAtCursor = 1550 syntax::spelledIdentifierTouching(*CurLoc, AST.getTokens()); 1551 if (!IdentifierAtCursor) 1552 return Results; 1553 1554 if (auto M = locateMacroAt(*IdentifierAtCursor, AST.getPreprocessor())) { 1555 SymbolDetails NewMacro; 1556 NewMacro.name = std::string(M->Name); 1557 llvm::SmallString<32> USR; 1558 if (!index::generateUSRForMacro(NewMacro.name, M->Info->getDefinitionLoc(), 1559 SM, USR)) { 1560 NewMacro.USR = std::string(USR.str()); 1561 NewMacro.ID = SymbolID(NewMacro.USR); 1562 } 1563 Results.push_back(std::move(NewMacro)); 1564 } 1565 1566 return Results; 1567 } 1568 1569 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const LocatedSymbol &S) { 1570 OS << S.Name << ": " << S.PreferredDeclaration; 1571 if (S.Definition) 1572 OS << " def=" << *S.Definition; 1573 return OS; 1574 } 1575 1576 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, 1577 const ReferencesResult::Reference &R) { 1578 OS << R.Loc; 1579 if (R.Attributes & ReferencesResult::Declaration) 1580 OS << " [decl]"; 1581 if (R.Attributes & ReferencesResult::Definition) 1582 OS << " [def]"; 1583 if (R.Attributes & ReferencesResult::Override) 1584 OS << " [override]"; 1585 return OS; 1586 } 1587 1588 template <typename HierarchyItem> 1589 static llvm::Optional<HierarchyItem> declToHierarchyItem(const NamedDecl &ND) { 1590 ASTContext &Ctx = ND.getASTContext(); 1591 auto &SM = Ctx.getSourceManager(); 1592 SourceLocation NameLoc = nameLocation(ND, Ctx.getSourceManager()); 1593 SourceLocation BeginLoc = SM.getSpellingLoc(SM.getFileLoc(ND.getBeginLoc())); 1594 SourceLocation EndLoc = SM.getSpellingLoc(SM.getFileLoc(ND.getEndLoc())); 1595 const auto DeclRange = 1596 toHalfOpenFileRange(SM, Ctx.getLangOpts(), {BeginLoc, EndLoc}); 1597 if (!DeclRange) 1598 return llvm::None; 1599 auto FilePath = 1600 getCanonicalPath(SM.getFileEntryForID(SM.getFileID(NameLoc)), SM); 1601 auto TUPath = getCanonicalPath(SM.getFileEntryForID(SM.getMainFileID()), SM); 1602 if (!FilePath || !TUPath) 1603 return llvm::None; // Not useful without a uri. 1604 1605 Position NameBegin = sourceLocToPosition(SM, NameLoc); 1606 Position NameEnd = sourceLocToPosition( 1607 SM, Lexer::getLocForEndOfToken(NameLoc, 0, SM, Ctx.getLangOpts())); 1608 1609 index::SymbolInfo SymInfo = index::getSymbolInfo(&ND); 1610 // FIXME: This is not classifying constructors, destructors and operators 1611 // correctly. 1612 SymbolKind SK = indexSymbolKindToSymbolKind(SymInfo.Kind); 1613 1614 HierarchyItem HI; 1615 HI.name = printName(Ctx, ND); 1616 HI.kind = SK; 1617 HI.range = Range{sourceLocToPosition(SM, DeclRange->getBegin()), 1618 sourceLocToPosition(SM, DeclRange->getEnd())}; 1619 HI.selectionRange = Range{NameBegin, NameEnd}; 1620 if (!HI.range.contains(HI.selectionRange)) { 1621 // 'selectionRange' must be contained in 'range', so in cases where clang 1622 // reports unrelated ranges we need to reconcile somehow. 1623 HI.range = HI.selectionRange; 1624 } 1625 1626 HI.uri = URIForFile::canonicalize(*FilePath, *TUPath); 1627 1628 // Compute the SymbolID and store it in the 'data' field. 1629 // This allows typeHierarchy/resolve to be used to 1630 // resolve children of items returned in a previous request 1631 // for parents. 1632 if (auto ID = getSymbolID(&ND)) 1633 HI.data = ID.str(); 1634 1635 return HI; 1636 } 1637 1638 static llvm::Optional<TypeHierarchyItem> 1639 declToTypeHierarchyItem(const NamedDecl &ND) { 1640 auto Result = declToHierarchyItem<TypeHierarchyItem>(ND); 1641 if (Result) 1642 Result->deprecated = ND.isDeprecated(); 1643 return Result; 1644 } 1645 1646 static llvm::Optional<CallHierarchyItem> 1647 declToCallHierarchyItem(const NamedDecl &ND) { 1648 auto Result = declToHierarchyItem<CallHierarchyItem>(ND); 1649 if (Result && ND.isDeprecated()) 1650 Result->tags.push_back(SymbolTag::Deprecated); 1651 return Result; 1652 } 1653 1654 template <typename HierarchyItem> 1655 static llvm::Optional<HierarchyItem> symbolToHierarchyItem(const Symbol &S, 1656 PathRef TUPath) { 1657 auto Loc = symbolToLocation(S, TUPath); 1658 if (!Loc) { 1659 elog("Failed to convert symbol to hierarchy item: {0}", Loc.takeError()); 1660 return llvm::None; 1661 } 1662 HierarchyItem HI; 1663 HI.name = std::string(S.Name); 1664 HI.kind = indexSymbolKindToSymbolKind(S.SymInfo.Kind); 1665 HI.selectionRange = Loc->range; 1666 // FIXME: Populate 'range' correctly 1667 // (https://github.com/clangd/clangd/issues/59). 1668 HI.range = HI.selectionRange; 1669 HI.uri = Loc->uri; 1670 // Store the SymbolID in the 'data' field. The client will 1671 // send this back in requests to resolve additional levels 1672 // of the hierarchy. 1673 HI.data = S.ID.str(); 1674 1675 return HI; 1676 } 1677 1678 static llvm::Optional<TypeHierarchyItem> 1679 symbolToTypeHierarchyItem(const Symbol &S, PathRef TUPath) { 1680 auto Result = symbolToHierarchyItem<TypeHierarchyItem>(S, TUPath); 1681 if (Result) 1682 Result->deprecated = (S.Flags & Symbol::Deprecated); 1683 return Result; 1684 } 1685 1686 static llvm::Optional<CallHierarchyItem> 1687 symbolToCallHierarchyItem(const Symbol &S, PathRef TUPath) { 1688 auto Result = symbolToHierarchyItem<CallHierarchyItem>(S, TUPath); 1689 if (Result && (S.Flags & Symbol::Deprecated)) 1690 Result->tags.push_back(SymbolTag::Deprecated); 1691 return Result; 1692 } 1693 1694 static void fillSubTypes(const SymbolID &ID, 1695 std::vector<TypeHierarchyItem> &SubTypes, 1696 const SymbolIndex *Index, int Levels, PathRef TUPath) { 1697 RelationsRequest Req; 1698 Req.Subjects.insert(ID); 1699 Req.Predicate = RelationKind::BaseOf; 1700 Index->relations(Req, [&](const SymbolID &Subject, const Symbol &Object) { 1701 if (Optional<TypeHierarchyItem> ChildSym = 1702 symbolToTypeHierarchyItem(Object, TUPath)) { 1703 if (Levels > 1) { 1704 ChildSym->children.emplace(); 1705 fillSubTypes(Object.ID, *ChildSym->children, Index, Levels - 1, TUPath); 1706 } 1707 SubTypes.emplace_back(std::move(*ChildSym)); 1708 } 1709 }); 1710 } 1711 1712 using RecursionProtectionSet = llvm::SmallSet<const CXXRecordDecl *, 4>; 1713 1714 static void fillSuperTypes(const CXXRecordDecl &CXXRD, ASTContext &ASTCtx, 1715 std::vector<TypeHierarchyItem> &SuperTypes, 1716 RecursionProtectionSet &RPSet) { 1717 // typeParents() will replace dependent template specializations 1718 // with their class template, so to avoid infinite recursion for 1719 // certain types of hierarchies, keep the templates encountered 1720 // along the parent chain in a set, and stop the recursion if one 1721 // starts to repeat. 1722 auto *Pattern = CXXRD.getDescribedTemplate() ? &CXXRD : nullptr; 1723 if (Pattern) { 1724 if (!RPSet.insert(Pattern).second) { 1725 return; 1726 } 1727 } 1728 1729 for (const CXXRecordDecl *ParentDecl : typeParents(&CXXRD)) { 1730 if (Optional<TypeHierarchyItem> ParentSym = 1731 declToTypeHierarchyItem(*ParentDecl)) { 1732 ParentSym->parents.emplace(); 1733 fillSuperTypes(*ParentDecl, ASTCtx, *ParentSym->parents, RPSet); 1734 SuperTypes.emplace_back(std::move(*ParentSym)); 1735 } 1736 } 1737 1738 if (Pattern) { 1739 RPSet.erase(Pattern); 1740 } 1741 } 1742 1743 const CXXRecordDecl *findRecordTypeAt(ParsedAST &AST, Position Pos) { 1744 auto RecordFromNode = 1745 [&AST](const SelectionTree::Node *N) -> const CXXRecordDecl * { 1746 if (!N) 1747 return nullptr; 1748 1749 // Note: explicitReferenceTargets() will search for both template 1750 // instantiations and template patterns, and prefer the former if available 1751 // (generally, one will be available for non-dependent specializations of a 1752 // class template). 1753 auto Decls = explicitReferenceTargets(N->ASTNode, DeclRelation::Underlying, 1754 AST.getHeuristicResolver()); 1755 if (Decls.empty()) 1756 return nullptr; 1757 1758 const NamedDecl *D = Decls[0]; 1759 1760 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 1761 // If this is a variable, use the type of the variable. 1762 return VD->getType().getTypePtr()->getAsCXXRecordDecl(); 1763 } 1764 1765 if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) { 1766 // If this is a method, use the type of the class. 1767 return Method->getParent(); 1768 } 1769 1770 // We don't handle FieldDecl because it's not clear what behaviour 1771 // the user would expect: the enclosing class type (as with a 1772 // method), or the field's type (as with a variable). 1773 1774 return dyn_cast<CXXRecordDecl>(D); 1775 }; 1776 1777 const SourceManager &SM = AST.getSourceManager(); 1778 const CXXRecordDecl *Result = nullptr; 1779 auto Offset = positionToOffset(SM.getBufferData(SM.getMainFileID()), Pos); 1780 if (!Offset) { 1781 llvm::consumeError(Offset.takeError()); 1782 return Result; 1783 } 1784 SelectionTree::createEach(AST.getASTContext(), AST.getTokens(), *Offset, 1785 *Offset, [&](SelectionTree ST) { 1786 Result = RecordFromNode(ST.commonAncestor()); 1787 return Result != nullptr; 1788 }); 1789 return Result; 1790 } 1791 1792 // Return the type most associated with an AST node. 1793 // This isn't precisely defined: we want "go to type" to do something useful. 1794 static QualType typeForNode(const SelectionTree::Node *N) { 1795 // If we're looking at a namespace qualifier, walk up to what it's qualifying. 1796 // (If we're pointing at a *class* inside a NNS, N will be a TypeLoc). 1797 while (N && N->ASTNode.get<NestedNameSpecifierLoc>()) 1798 N = N->Parent; 1799 if (!N) 1800 return QualType(); 1801 1802 // If we're pointing at a type => return it. 1803 if (const TypeLoc *TL = N->ASTNode.get<TypeLoc>()) { 1804 if (llvm::isa<DeducedType>(TL->getTypePtr())) 1805 if (auto Deduced = getDeducedType( 1806 N->getDeclContext().getParentASTContext(), TL->getBeginLoc())) 1807 return *Deduced; 1808 // Exception: an alias => underlying type. 1809 if (llvm::isa<TypedefType>(TL->getTypePtr())) 1810 return TL->getTypePtr()->getLocallyUnqualifiedSingleStepDesugaredType(); 1811 return TL->getType(); 1812 } 1813 1814 // Constructor initializers => the type of thing being initialized. 1815 if (const auto *CCI = N->ASTNode.get<CXXCtorInitializer>()) { 1816 if (const FieldDecl *FD = CCI->getAnyMember()) 1817 return FD->getType(); 1818 if (const Type *Base = CCI->getBaseClass()) 1819 return QualType(Base, 0); 1820 } 1821 1822 // Base specifier => the base type. 1823 if (const auto *CBS = N->ASTNode.get<CXXBaseSpecifier>()) 1824 return CBS->getType(); 1825 1826 if (const Decl *D = N->ASTNode.get<Decl>()) { 1827 struct Visitor : ConstDeclVisitor<Visitor, QualType> { 1828 QualType VisitValueDecl(const ValueDecl *D) { return D->getType(); } 1829 // Declaration of a type => that type. 1830 QualType VisitTypeDecl(const TypeDecl *D) { 1831 return QualType(D->getTypeForDecl(), 0); 1832 } 1833 // Exception: alias declaration => the underlying type, not the alias. 1834 QualType VisitTypedefNameDecl(const TypedefNameDecl *D) { 1835 return D->getUnderlyingType(); 1836 } 1837 // Look inside templates. 1838 QualType VisitTemplateDecl(const TemplateDecl *D) { 1839 return Visit(D->getTemplatedDecl()); 1840 } 1841 } V; 1842 return V.Visit(D); 1843 } 1844 1845 if (const Stmt *S = N->ASTNode.get<Stmt>()) { 1846 struct Visitor : ConstStmtVisitor<Visitor, QualType> { 1847 // Null-safe version of visit simplifies recursive calls below. 1848 QualType type(const Stmt *S) { return S ? Visit(S) : QualType(); } 1849 1850 // In general, expressions => type of expression. 1851 QualType VisitExpr(const Expr *S) { 1852 return S->IgnoreImplicitAsWritten()->getType(); 1853 } 1854 // Exceptions for void expressions that operate on a type in some way. 1855 QualType VisitCXXDeleteExpr(const CXXDeleteExpr *S) { 1856 return S->getDestroyedType(); 1857 } 1858 QualType VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *S) { 1859 return S->getDestroyedType(); 1860 } 1861 QualType VisitCXXThrowExpr(const CXXThrowExpr *S) { 1862 return S->getSubExpr()->getType(); 1863 } 1864 QualType VisitCoyieldExpr(const CoyieldExpr *S) { 1865 return type(S->getOperand()); 1866 } 1867 // Treat a designated initializer like a reference to the field. 1868 QualType VisitDesignatedInitExpr(const DesignatedInitExpr *S) { 1869 // In .foo.bar we want to jump to bar's type, so find *last* field. 1870 for (auto &D : llvm::reverse(S->designators())) 1871 if (D.isFieldDesignator()) 1872 if (const auto *FD = D.getField()) 1873 return FD->getType(); 1874 return QualType(); 1875 } 1876 1877 // Control flow statements that operate on data: use the data type. 1878 QualType VisitSwitchStmt(const SwitchStmt *S) { 1879 return type(S->getCond()); 1880 } 1881 QualType VisitWhileStmt(const WhileStmt *S) { return type(S->getCond()); } 1882 QualType VisitDoStmt(const DoStmt *S) { return type(S->getCond()); } 1883 QualType VisitIfStmt(const IfStmt *S) { return type(S->getCond()); } 1884 QualType VisitCaseStmt(const CaseStmt *S) { return type(S->getLHS()); } 1885 QualType VisitCXXForRangeStmt(const CXXForRangeStmt *S) { 1886 return S->getLoopVariable()->getType(); 1887 } 1888 QualType VisitReturnStmt(const ReturnStmt *S) { 1889 return type(S->getRetValue()); 1890 } 1891 QualType VisitCoreturnStmt(const CoreturnStmt *S) { 1892 return type(S->getOperand()); 1893 } 1894 QualType VisitCXXCatchStmt(const CXXCatchStmt *S) { 1895 return S->getCaughtType(); 1896 } 1897 QualType VisitObjCAtThrowStmt(const ObjCAtThrowStmt *S) { 1898 return type(S->getThrowExpr()); 1899 } 1900 QualType VisitObjCAtCatchStmt(const ObjCAtCatchStmt *S) { 1901 return S->getCatchParamDecl() ? S->getCatchParamDecl()->getType() 1902 : QualType(); 1903 } 1904 } V; 1905 return V.Visit(S); 1906 } 1907 1908 return QualType(); 1909 } 1910 1911 // Given a type targeted by the cursor, return one or more types that are more interesting 1912 // to target. 1913 static void unwrapFindType( 1914 QualType T, const HeuristicResolver* H, llvm::SmallVector<QualType>& Out) { 1915 if (T.isNull()) 1916 return; 1917 1918 // If there's a specific type alias, point at that rather than unwrapping. 1919 if (const auto* TDT = T->getAs<TypedefType>()) 1920 return Out.push_back(QualType(TDT, 0)); 1921 1922 // Pointers etc => pointee type. 1923 if (const auto *PT = T->getAs<PointerType>()) 1924 return unwrapFindType(PT->getPointeeType(), H, Out); 1925 if (const auto *RT = T->getAs<ReferenceType>()) 1926 return unwrapFindType(RT->getPointeeType(), H, Out); 1927 if (const auto *AT = T->getAsArrayTypeUnsafe()) 1928 return unwrapFindType(AT->getElementType(), H, Out); 1929 1930 // Function type => return type. 1931 if (auto *FT = T->getAs<FunctionType>()) 1932 return unwrapFindType(FT->getReturnType(), H, Out); 1933 if (auto *CRD = T->getAsCXXRecordDecl()) { 1934 if (CRD->isLambda()) 1935 return unwrapFindType(CRD->getLambdaCallOperator()->getReturnType(), H, Out); 1936 // FIXME: more cases we'd prefer the return type of the call operator? 1937 // std::function etc? 1938 } 1939 1940 // For smart pointer types, add the underlying type 1941 if (H) 1942 if (const auto* PointeeType = H->getPointeeType(T.getNonReferenceType().getTypePtr())) { 1943 unwrapFindType(QualType(PointeeType, 0), H, Out); 1944 return Out.push_back(T); 1945 } 1946 1947 return Out.push_back(T); 1948 } 1949 1950 // Convenience overload, to allow calling this without the out-parameter 1951 static llvm::SmallVector<QualType> unwrapFindType( 1952 QualType T, const HeuristicResolver* H) { 1953 llvm::SmallVector<QualType> Result; 1954 unwrapFindType(T, H, Result); 1955 return Result; 1956 } 1957 1958 1959 std::vector<LocatedSymbol> findType(ParsedAST &AST, Position Pos) { 1960 const SourceManager &SM = AST.getSourceManager(); 1961 auto Offset = positionToOffset(SM.getBufferData(SM.getMainFileID()), Pos); 1962 std::vector<LocatedSymbol> Result; 1963 if (!Offset) { 1964 elog("failed to convert position {0} for findTypes: {1}", Pos, 1965 Offset.takeError()); 1966 return Result; 1967 } 1968 // The general scheme is: position -> AST node -> type -> declaration. 1969 auto SymbolsFromNode = 1970 [&AST](const SelectionTree::Node *N) -> std::vector<LocatedSymbol> { 1971 std::vector<LocatedSymbol> LocatedSymbols; 1972 1973 // NOTE: unwrapFindType might return duplicates for something like 1974 // unique_ptr<unique_ptr<T>>. Let's *not* remove them, because it gives you some 1975 // information about the type you may have not known before 1976 // (since unique_ptr<unique_ptr<T>> != unique_ptr<T>). 1977 for (const QualType& Type : unwrapFindType(typeForNode(N), AST.getHeuristicResolver())) 1978 llvm::copy(locateSymbolForType(AST, Type), std::back_inserter(LocatedSymbols)); 1979 1980 return LocatedSymbols; 1981 }; 1982 SelectionTree::createEach(AST.getASTContext(), AST.getTokens(), *Offset, 1983 *Offset, [&](SelectionTree ST) { 1984 Result = SymbolsFromNode(ST.commonAncestor()); 1985 return !Result.empty(); 1986 }); 1987 return Result; 1988 } 1989 1990 std::vector<const CXXRecordDecl *> typeParents(const CXXRecordDecl *CXXRD) { 1991 std::vector<const CXXRecordDecl *> Result; 1992 1993 // If this is an invalid instantiation, instantiation of the bases 1994 // may not have succeeded, so fall back to the template pattern. 1995 if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(CXXRD)) { 1996 if (CTSD->isInvalidDecl()) 1997 CXXRD = CTSD->getSpecializedTemplate()->getTemplatedDecl(); 1998 } 1999 2000 // Can't query bases without a definition. 2001 if (!CXXRD->hasDefinition()) 2002 return Result; 2003 2004 for (auto Base : CXXRD->bases()) { 2005 const CXXRecordDecl *ParentDecl = nullptr; 2006 2007 const Type *Type = Base.getType().getTypePtr(); 2008 if (const RecordType *RT = Type->getAs<RecordType>()) { 2009 ParentDecl = RT->getAsCXXRecordDecl(); 2010 } 2011 2012 if (!ParentDecl) { 2013 // Handle a dependent base such as "Base<T>" by using the primary 2014 // template. 2015 if (const TemplateSpecializationType *TS = 2016 Type->getAs<TemplateSpecializationType>()) { 2017 TemplateName TN = TS->getTemplateName(); 2018 if (TemplateDecl *TD = TN.getAsTemplateDecl()) { 2019 ParentDecl = dyn_cast<CXXRecordDecl>(TD->getTemplatedDecl()); 2020 } 2021 } 2022 } 2023 2024 if (ParentDecl) 2025 Result.push_back(ParentDecl); 2026 } 2027 2028 return Result; 2029 } 2030 2031 llvm::Optional<TypeHierarchyItem> 2032 getTypeHierarchy(ParsedAST &AST, Position Pos, int ResolveLevels, 2033 TypeHierarchyDirection Direction, const SymbolIndex *Index, 2034 PathRef TUPath) { 2035 const CXXRecordDecl *CXXRD = findRecordTypeAt(AST, Pos); 2036 if (!CXXRD) 2037 return llvm::None; 2038 2039 bool WantParents = Direction == TypeHierarchyDirection::Parents || 2040 Direction == TypeHierarchyDirection::Both; 2041 bool WantChildren = Direction == TypeHierarchyDirection::Children || 2042 Direction == TypeHierarchyDirection::Both; 2043 2044 // If we're looking for children, we're doing the lookup in the index. 2045 // The index does not store relationships between implicit 2046 // specializations, so if we have one, use the template pattern instead. 2047 // Note that this needs to be done before the declToTypeHierarchyItem(), 2048 // otherwise the type hierarchy item would misleadingly contain the 2049 // specialization parameters, while the children would involve classes 2050 // that derive from other specializations of the template. 2051 if (WantChildren) { 2052 if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(CXXRD)) 2053 CXXRD = CTSD->getTemplateInstantiationPattern(); 2054 } 2055 2056 Optional<TypeHierarchyItem> Result = declToTypeHierarchyItem(*CXXRD); 2057 if (!Result) 2058 return Result; 2059 2060 if (WantParents) { 2061 Result->parents.emplace(); 2062 2063 RecursionProtectionSet RPSet; 2064 fillSuperTypes(*CXXRD, AST.getASTContext(), *Result->parents, RPSet); 2065 } 2066 2067 if (WantChildren && ResolveLevels > 0) { 2068 Result->children.emplace(); 2069 2070 if (Index) { 2071 if (auto ID = getSymbolID(CXXRD)) 2072 fillSubTypes(ID, *Result->children, Index, ResolveLevels, TUPath); 2073 } 2074 } 2075 2076 return Result; 2077 } 2078 2079 void resolveTypeHierarchy(TypeHierarchyItem &Item, int ResolveLevels, 2080 TypeHierarchyDirection Direction, 2081 const SymbolIndex *Index) { 2082 // We only support typeHierarchy/resolve for children, because for parents 2083 // we ignore ResolveLevels and return all levels of parents eagerly. 2084 if (Direction == TypeHierarchyDirection::Parents || ResolveLevels == 0) 2085 return; 2086 2087 Item.children.emplace(); 2088 2089 if (Index && Item.data) { 2090 // We store the item's SymbolID in the 'data' field, and the client 2091 // passes it back to us in typeHierarchy/resolve. 2092 if (Expected<SymbolID> ID = SymbolID::fromStr(*Item.data)) { 2093 fillSubTypes(*ID, *Item.children, Index, ResolveLevels, Item.uri.file()); 2094 } 2095 } 2096 } 2097 2098 std::vector<CallHierarchyItem> 2099 prepareCallHierarchy(ParsedAST &AST, Position Pos, PathRef TUPath) { 2100 std::vector<CallHierarchyItem> Result; 2101 const auto &SM = AST.getSourceManager(); 2102 auto Loc = sourceLocationInMainFile(SM, Pos); 2103 if (!Loc) { 2104 elog("prepareCallHierarchy failed to convert position to source location: " 2105 "{0}", 2106 Loc.takeError()); 2107 return Result; 2108 } 2109 for (const NamedDecl *Decl : getDeclAtPosition(AST, *Loc, {})) { 2110 if (!(isa<DeclContext>(Decl) && 2111 cast<DeclContext>(Decl)->isFunctionOrMethod()) && 2112 Decl->getKind() != Decl::Kind::FunctionTemplate) 2113 continue; 2114 if (auto CHI = declToCallHierarchyItem(*Decl)) 2115 Result.emplace_back(std::move(*CHI)); 2116 } 2117 return Result; 2118 } 2119 2120 std::vector<CallHierarchyIncomingCall> 2121 incomingCalls(const CallHierarchyItem &Item, const SymbolIndex *Index) { 2122 std::vector<CallHierarchyIncomingCall> Results; 2123 if (!Index || Item.data.empty()) 2124 return Results; 2125 auto ID = SymbolID::fromStr(Item.data); 2126 if (!ID) { 2127 elog("incomingCalls failed to find symbol: {0}", ID.takeError()); 2128 return Results; 2129 } 2130 // In this function, we find incoming calls based on the index only. 2131 // In principle, the AST could have more up-to-date information about 2132 // occurrences within the current file. However, going from a SymbolID 2133 // to an AST node isn't cheap, particularly when the declaration isn't 2134 // in the main file. 2135 // FIXME: Consider also using AST information when feasible. 2136 RefsRequest Request; 2137 Request.IDs.insert(*ID); 2138 Request.WantContainer = true; 2139 // We could restrict more specifically to calls by introducing a new RefKind, 2140 // but non-call references (such as address-of-function) can still be 2141 // interesting as they can indicate indirect calls. 2142 Request.Filter = RefKind::Reference; 2143 // Initially store the ranges in a map keyed by SymbolID of the caller. 2144 // This allows us to group different calls with the same caller 2145 // into the same CallHierarchyIncomingCall. 2146 llvm::DenseMap<SymbolID, std::vector<Range>> CallsIn; 2147 // We can populate the ranges based on a refs request only. As we do so, we 2148 // also accumulate the container IDs into a lookup request. 2149 LookupRequest ContainerLookup; 2150 Index->refs(Request, [&](const Ref &R) { 2151 auto Loc = indexToLSPLocation(R.Location, Item.uri.file()); 2152 if (!Loc) { 2153 elog("incomingCalls failed to convert location: {0}", Loc.takeError()); 2154 return; 2155 } 2156 auto It = CallsIn.try_emplace(R.Container, std::vector<Range>{}).first; 2157 It->second.push_back(Loc->range); 2158 2159 ContainerLookup.IDs.insert(R.Container); 2160 }); 2161 // Perform the lookup request and combine its results with CallsIn to 2162 // get complete CallHierarchyIncomingCall objects. 2163 Index->lookup(ContainerLookup, [&](const Symbol &Caller) { 2164 auto It = CallsIn.find(Caller.ID); 2165 assert(It != CallsIn.end()); 2166 if (auto CHI = symbolToCallHierarchyItem(Caller, Item.uri.file())) 2167 Results.push_back( 2168 CallHierarchyIncomingCall{std::move(*CHI), std::move(It->second)}); 2169 }); 2170 // Sort results by name of container. 2171 llvm::sort(Results, [](const CallHierarchyIncomingCall &A, 2172 const CallHierarchyIncomingCall &B) { 2173 return A.from.name < B.from.name; 2174 }); 2175 return Results; 2176 } 2177 2178 llvm::DenseSet<const Decl *> getNonLocalDeclRefs(ParsedAST &AST, 2179 const FunctionDecl *FD) { 2180 if (!FD->hasBody()) 2181 return {}; 2182 llvm::DenseSet<const Decl *> DeclRefs; 2183 findExplicitReferences( 2184 FD, 2185 [&](ReferenceLoc Ref) { 2186 for (const Decl *D : Ref.Targets) { 2187 if (!index::isFunctionLocalSymbol(D) && !D->isTemplateParameter() && 2188 !Ref.IsDecl) 2189 DeclRefs.insert(D); 2190 } 2191 }, 2192 AST.getHeuristicResolver()); 2193 return DeclRefs; 2194 } 2195 2196 } // namespace clangd 2197 } // namespace clang 2198