1 //===- IndexDecl.cpp - Indexing declarations ------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "IndexingContext.h" 11 #include "clang/Index/IndexDataConsumer.h" 12 #include "clang/AST/DeclVisitor.h" 13 14 using namespace clang; 15 using namespace index; 16 17 #define TRY_DECL(D,CALL_EXPR) \ 18 do { \ 19 if (!IndexCtx.shouldIndex(D)) return true; \ 20 if (!CALL_EXPR) \ 21 return false; \ 22 } while (0) 23 24 #define TRY_TO(CALL_EXPR) \ 25 do { \ 26 if (!CALL_EXPR) \ 27 return false; \ 28 } while (0) 29 30 namespace { 31 32 class IndexingDeclVisitor : public ConstDeclVisitor<IndexingDeclVisitor, bool> { 33 IndexingContext &IndexCtx; 34 35 public: 36 explicit IndexingDeclVisitor(IndexingContext &indexCtx) 37 : IndexCtx(indexCtx) { } 38 39 bool Handled = true; 40 41 bool VisitDecl(const Decl *D) { 42 Handled = false; 43 return true; 44 } 45 46 /// \brief Returns true if the given method has been defined explicitly by the 47 /// user. 48 static bool hasUserDefined(const ObjCMethodDecl *D, 49 const ObjCImplDecl *Container) { 50 const ObjCMethodDecl *MD = Container->getMethod(D->getSelector(), 51 D->isInstanceMethod()); 52 return MD && !MD->isImplicit() && MD->isThisDeclarationADefinition(); 53 } 54 55 void handleTemplateArgumentLoc(const TemplateArgumentLoc &TALoc, 56 const NamedDecl *Parent, 57 const DeclContext *DC) { 58 const TemplateArgumentLocInfo &LocInfo = TALoc.getLocInfo(); 59 switch (TALoc.getArgument().getKind()) { 60 case TemplateArgument::Expression: 61 IndexCtx.indexBody(LocInfo.getAsExpr(), Parent, DC); 62 break; 63 case TemplateArgument::Type: 64 IndexCtx.indexTypeSourceInfo(LocInfo.getAsTypeSourceInfo(), Parent, DC); 65 break; 66 case TemplateArgument::Template: 67 case TemplateArgument::TemplateExpansion: 68 IndexCtx.indexNestedNameSpecifierLoc(TALoc.getTemplateQualifierLoc(), 69 Parent, DC); 70 if (const TemplateDecl *TD = TALoc.getArgument() 71 .getAsTemplateOrTemplatePattern() 72 .getAsTemplateDecl()) { 73 if (const NamedDecl *TTD = TD->getTemplatedDecl()) 74 IndexCtx.handleReference(TTD, TALoc.getTemplateNameLoc(), Parent, DC); 75 } 76 break; 77 default: 78 break; 79 } 80 } 81 82 void handleDeclarator(const DeclaratorDecl *D, 83 const NamedDecl *Parent = nullptr, 84 bool isIBType = false) { 85 if (!Parent) Parent = D; 86 87 IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), Parent, 88 Parent->getLexicalDeclContext(), 89 /*isBase=*/false, isIBType); 90 IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent); 91 if (IndexCtx.shouldIndexFunctionLocalSymbols()) { 92 // Only index parameters in definitions, parameters in declarations are 93 // not useful. 94 if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) { 95 auto *DC = Parm->getDeclContext(); 96 if (auto *FD = dyn_cast<FunctionDecl>(DC)) { 97 if (FD->isThisDeclarationADefinition()) 98 IndexCtx.handleDecl(Parm); 99 } else if (auto *MD = dyn_cast<ObjCMethodDecl>(DC)) { 100 if (MD->isThisDeclarationADefinition()) 101 IndexCtx.handleDecl(Parm); 102 } else { 103 IndexCtx.handleDecl(Parm); 104 } 105 } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 106 if (FD->isThisDeclarationADefinition()) { 107 for (auto PI : FD->parameters()) { 108 IndexCtx.handleDecl(PI); 109 } 110 } 111 } 112 } else { 113 // Index the default parameter value for function definitions. 114 if (const auto *FD = dyn_cast<FunctionDecl>(D)) { 115 if (FD->isThisDeclarationADefinition()) { 116 for (const auto *PV : FD->parameters()) { 117 if (PV->hasDefaultArg() && !PV->hasUninstantiatedDefaultArg() && 118 !PV->hasUnparsedDefaultArg()) 119 IndexCtx.indexBody(PV->getDefaultArg(), D); 120 } 121 } 122 } 123 } 124 } 125 126 bool handleObjCMethod(const ObjCMethodDecl *D, 127 const ObjCPropertyDecl *AssociatedProp = nullptr) { 128 SmallVector<SymbolRelation, 4> Relations; 129 SmallVector<const ObjCMethodDecl*, 4> Overriden; 130 131 D->getOverriddenMethods(Overriden); 132 for(auto overridden: Overriden) { 133 Relations.emplace_back((unsigned) SymbolRole::RelationOverrideOf, 134 overridden); 135 } 136 if (AssociatedProp) 137 Relations.emplace_back((unsigned)SymbolRole::RelationAccessorOf, 138 AssociatedProp); 139 140 // getLocation() returns beginning token of a method declaration, but for 141 // indexing purposes we want to point to the base name. 142 SourceLocation MethodLoc = D->getSelectorStartLoc(); 143 if (MethodLoc.isInvalid()) 144 MethodLoc = D->getLocation(); 145 146 SourceLocation AttrLoc; 147 148 // check for (getter=/setter=) 149 if (AssociatedProp) { 150 bool isGetter = !D->param_size(); 151 AttrLoc = isGetter ? 152 AssociatedProp->getGetterNameLoc(): 153 AssociatedProp->getSetterNameLoc(); 154 } 155 156 SymbolRoleSet Roles = (SymbolRoleSet)SymbolRole::Dynamic; 157 if (D->isImplicit()) { 158 if (AttrLoc.isValid()) { 159 MethodLoc = AttrLoc; 160 } else { 161 Roles |= (SymbolRoleSet)SymbolRole::Implicit; 162 } 163 } else if (AttrLoc.isValid()) { 164 IndexCtx.handleReference(D, AttrLoc, cast<NamedDecl>(D->getDeclContext()), 165 D->getDeclContext(), 0); 166 } 167 168 TRY_DECL(D, IndexCtx.handleDecl(D, MethodLoc, Roles, Relations)); 169 IndexCtx.indexTypeSourceInfo(D->getReturnTypeSourceInfo(), D); 170 bool hasIBActionAndFirst = D->hasAttr<IBActionAttr>(); 171 for (const auto *I : D->parameters()) { 172 handleDeclarator(I, D, /*isIBType=*/hasIBActionAndFirst); 173 hasIBActionAndFirst = false; 174 } 175 176 if (D->isThisDeclarationADefinition()) { 177 const Stmt *Body = D->getBody(); 178 if (Body) { 179 IndexCtx.indexBody(Body, D, D); 180 } 181 } 182 return true; 183 } 184 185 /// Gather the declarations which the given declaration \D overrides in a 186 /// pseudo-override manner. 187 /// 188 /// Pseudo-overrides occur when a class template specialization declares 189 /// a declaration that has the same name as a similar declaration in the 190 /// non-specialized template. 191 void 192 gatherTemplatePseudoOverrides(const NamedDecl *D, 193 SmallVectorImpl<SymbolRelation> &Relations) { 194 if (!IndexCtx.getLangOpts().CPlusPlus) 195 return; 196 const auto *CTSD = 197 dyn_cast<ClassTemplateSpecializationDecl>(D->getLexicalDeclContext()); 198 if (!CTSD) 199 return; 200 llvm::PointerUnion<ClassTemplateDecl *, 201 ClassTemplatePartialSpecializationDecl *> 202 Template = CTSD->getSpecializedTemplateOrPartial(); 203 if (const auto *CTD = Template.dyn_cast<ClassTemplateDecl *>()) { 204 const CXXRecordDecl *Pattern = CTD->getTemplatedDecl(); 205 bool TypeOverride = isa<TypeDecl>(D); 206 for (const NamedDecl *ND : Pattern->lookup(D->getDeclName())) { 207 if (const auto *CTD = dyn_cast<ClassTemplateDecl>(ND)) 208 ND = CTD->getTemplatedDecl(); 209 if (ND->isImplicit()) 210 continue; 211 // Types can override other types. 212 if (!TypeOverride) { 213 if (ND->getKind() != D->getKind()) 214 continue; 215 } else if (!isa<TypeDecl>(ND)) 216 continue; 217 if (const auto *FD = dyn_cast<FunctionDecl>(ND)) { 218 const auto *DFD = cast<FunctionDecl>(D); 219 // Function overrides are approximated using the number of parameters. 220 if (FD->getStorageClass() != DFD->getStorageClass() || 221 FD->getNumParams() != DFD->getNumParams()) 222 continue; 223 } 224 Relations.emplace_back( 225 SymbolRoleSet(SymbolRole::RelationSpecializationOf), ND); 226 } 227 } 228 } 229 230 bool VisitFunctionDecl(const FunctionDecl *D) { 231 SymbolRoleSet Roles{}; 232 SmallVector<SymbolRelation, 4> Relations; 233 if (auto *CXXMD = dyn_cast<CXXMethodDecl>(D)) { 234 if (CXXMD->isVirtual()) 235 Roles |= (unsigned)SymbolRole::Dynamic; 236 for (auto I = CXXMD->begin_overridden_methods(), 237 E = CXXMD->end_overridden_methods(); I != E; ++I) { 238 Relations.emplace_back((unsigned)SymbolRole::RelationOverrideOf, *I); 239 } 240 } 241 gatherTemplatePseudoOverrides(D, Relations); 242 if (const auto *Base = D->getPrimaryTemplate()) 243 Relations.push_back( 244 SymbolRelation(SymbolRoleSet(SymbolRole::RelationSpecializationOf), 245 Base->getTemplatedDecl())); 246 247 TRY_DECL(D, IndexCtx.handleDecl(D, Roles, Relations)); 248 handleDeclarator(D); 249 250 if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) { 251 IndexCtx.handleReference(Ctor->getParent(), Ctor->getLocation(), 252 Ctor->getParent(), Ctor->getDeclContext()); 253 254 // Constructor initializers. 255 for (const auto *Init : Ctor->inits()) { 256 if (Init->isWritten()) { 257 IndexCtx.indexTypeSourceInfo(Init->getTypeSourceInfo(), D); 258 if (const FieldDecl *Member = Init->getAnyMember()) 259 IndexCtx.handleReference(Member, Init->getMemberLocation(), D, D, 260 (unsigned)SymbolRole::Write); 261 IndexCtx.indexBody(Init->getInit(), D, D); 262 } 263 } 264 } else if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(D)) { 265 if (auto TypeNameInfo = Dtor->getNameInfo().getNamedTypeInfo()) { 266 IndexCtx.handleReference(Dtor->getParent(), 267 TypeNameInfo->getTypeLoc().getLocStart(), 268 Dtor->getParent(), Dtor->getDeclContext()); 269 } 270 } else if (const auto *Guide = dyn_cast<CXXDeductionGuideDecl>(D)) { 271 IndexCtx.handleReference(Guide->getDeducedTemplate()->getTemplatedDecl(), 272 Guide->getLocation(), Guide, 273 Guide->getDeclContext()); 274 } 275 // Template specialization arguments. 276 if (const ASTTemplateArgumentListInfo *TemplateArgInfo = 277 D->getTemplateSpecializationArgsAsWritten()) { 278 for (const auto &Arg : TemplateArgInfo->arguments()) 279 handleTemplateArgumentLoc(Arg, D, D->getLexicalDeclContext()); 280 } 281 282 if (D->isThisDeclarationADefinition()) { 283 const Stmt *Body = D->getBody(); 284 if (Body) { 285 IndexCtx.indexBody(Body, D, D); 286 } 287 } 288 return true; 289 } 290 291 bool VisitVarDecl(const VarDecl *D) { 292 SmallVector<SymbolRelation, 4> Relations; 293 gatherTemplatePseudoOverrides(D, Relations); 294 TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations)); 295 handleDeclarator(D); 296 IndexCtx.indexBody(D->getInit(), D); 297 return true; 298 } 299 300 bool VisitDecompositionDecl(const DecompositionDecl *D) { 301 for (const auto *Binding : D->bindings()) 302 TRY_DECL(Binding, IndexCtx.handleDecl(Binding)); 303 return Base::VisitDecompositionDecl(D); 304 } 305 306 bool VisitFieldDecl(const FieldDecl *D) { 307 SmallVector<SymbolRelation, 4> Relations; 308 gatherTemplatePseudoOverrides(D, Relations); 309 TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations)); 310 handleDeclarator(D); 311 if (D->isBitField()) 312 IndexCtx.indexBody(D->getBitWidth(), D); 313 else if (D->hasInClassInitializer()) 314 IndexCtx.indexBody(D->getInClassInitializer(), D); 315 return true; 316 } 317 318 bool VisitObjCIvarDecl(const ObjCIvarDecl *D) { 319 if (D->getSynthesize()) { 320 // handled in VisitObjCPropertyImplDecl 321 return true; 322 } 323 TRY_DECL(D, IndexCtx.handleDecl(D)); 324 handleDeclarator(D); 325 return true; 326 } 327 328 bool VisitMSPropertyDecl(const MSPropertyDecl *D) { 329 handleDeclarator(D); 330 return true; 331 } 332 333 bool VisitEnumConstantDecl(const EnumConstantDecl *D) { 334 TRY_DECL(D, IndexCtx.handleDecl(D)); 335 IndexCtx.indexBody(D->getInitExpr(), D); 336 return true; 337 } 338 339 bool VisitTypedefNameDecl(const TypedefNameDecl *D) { 340 if (!D->isTransparentTag()) { 341 SmallVector<SymbolRelation, 4> Relations; 342 gatherTemplatePseudoOverrides(D, Relations); 343 TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations)); 344 IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D); 345 } 346 return true; 347 } 348 349 bool VisitTagDecl(const TagDecl *D) { 350 // Non-free standing tags are handled in indexTypeSourceInfo. 351 if (D->isFreeStanding()) { 352 if (D->isThisDeclarationADefinition()) { 353 SmallVector<SymbolRelation, 4> Relations; 354 gatherTemplatePseudoOverrides(D, Relations); 355 IndexCtx.indexTagDecl(D, Relations); 356 } else { 357 auto *Parent = dyn_cast<NamedDecl>(D->getDeclContext()); 358 SmallVector<SymbolRelation, 1> Relations; 359 gatherTemplatePseudoOverrides(D, Relations); 360 return IndexCtx.handleReference(D, D->getLocation(), Parent, 361 D->getLexicalDeclContext(), 362 SymbolRoleSet(), Relations); 363 } 364 } 365 return true; 366 } 367 368 bool handleReferencedProtocols(const ObjCProtocolList &ProtList, 369 const ObjCContainerDecl *ContD, 370 SourceLocation SuperLoc) { 371 ObjCInterfaceDecl::protocol_loc_iterator LI = ProtList.loc_begin(); 372 for (ObjCInterfaceDecl::protocol_iterator 373 I = ProtList.begin(), E = ProtList.end(); I != E; ++I, ++LI) { 374 SourceLocation Loc = *LI; 375 ObjCProtocolDecl *PD = *I; 376 SymbolRoleSet roles{}; 377 if (Loc == SuperLoc) 378 roles |= (SymbolRoleSet)SymbolRole::Implicit; 379 TRY_TO(IndexCtx.handleReference(PD, Loc, ContD, ContD, roles, 380 SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, ContD})); 381 } 382 return true; 383 } 384 385 bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) { 386 if (D->isThisDeclarationADefinition()) { 387 TRY_DECL(D, IndexCtx.handleDecl(D)); 388 SourceLocation SuperLoc = D->getSuperClassLoc(); 389 if (auto *SuperD = D->getSuperClass()) { 390 bool hasSuperTypedef = false; 391 if (auto *TInfo = D->getSuperClassTInfo()) { 392 if (auto *TT = TInfo->getType()->getAs<TypedefType>()) { 393 if (auto *TD = TT->getDecl()) { 394 hasSuperTypedef = true; 395 TRY_TO(IndexCtx.handleReference(TD, SuperLoc, D, D, 396 SymbolRoleSet())); 397 } 398 } 399 } 400 SymbolRoleSet superRoles{}; 401 if (hasSuperTypedef) 402 superRoles |= (SymbolRoleSet)SymbolRole::Implicit; 403 TRY_TO(IndexCtx.handleReference(SuperD, SuperLoc, D, D, superRoles, 404 SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, D})); 405 } 406 TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D, 407 SuperLoc)); 408 TRY_TO(IndexCtx.indexDeclContext(D)); 409 } else { 410 return IndexCtx.handleReference(D, D->getLocation(), nullptr, 411 D->getDeclContext(), SymbolRoleSet()); 412 } 413 return true; 414 } 415 416 bool VisitObjCProtocolDecl(const ObjCProtocolDecl *D) { 417 if (D->isThisDeclarationADefinition()) { 418 TRY_DECL(D, IndexCtx.handleDecl(D)); 419 TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D, 420 /*superLoc=*/SourceLocation())); 421 TRY_TO(IndexCtx.indexDeclContext(D)); 422 } else { 423 return IndexCtx.handleReference(D, D->getLocation(), nullptr, 424 D->getDeclContext(), SymbolRoleSet()); 425 } 426 return true; 427 } 428 429 bool VisitObjCImplementationDecl(const ObjCImplementationDecl *D) { 430 const ObjCInterfaceDecl *Class = D->getClassInterface(); 431 if (!Class) 432 return true; 433 434 if (Class->isImplicitInterfaceDecl()) 435 IndexCtx.handleDecl(Class); 436 437 TRY_DECL(D, IndexCtx.handleDecl(D)); 438 439 // Visit implicit @synthesize property implementations first as their 440 // location is reported at the name of the @implementation block. This 441 // serves no purpose other than to simplify the FileCheck-based tests. 442 for (const auto *I : D->property_impls()) { 443 if (I->getLocation().isInvalid()) 444 IndexCtx.indexDecl(I); 445 } 446 for (const auto *I : D->decls()) { 447 if (!isa<ObjCPropertyImplDecl>(I) || 448 cast<ObjCPropertyImplDecl>(I)->getLocation().isValid()) 449 IndexCtx.indexDecl(I); 450 } 451 452 return true; 453 } 454 455 bool VisitObjCCategoryDecl(const ObjCCategoryDecl *D) { 456 if (!IndexCtx.shouldIndex(D)) 457 return true; 458 const ObjCInterfaceDecl *C = D->getClassInterface(); 459 if (!C) 460 return true; 461 TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D, SymbolRoleSet(), 462 SymbolRelation{ 463 (unsigned)SymbolRole::RelationExtendedBy, D 464 })); 465 SourceLocation CategoryLoc = D->getCategoryNameLoc(); 466 if (!CategoryLoc.isValid()) 467 CategoryLoc = D->getLocation(); 468 TRY_TO(IndexCtx.handleDecl(D, CategoryLoc)); 469 TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D, 470 /*superLoc=*/SourceLocation())); 471 TRY_TO(IndexCtx.indexDeclContext(D)); 472 return true; 473 } 474 475 bool VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) { 476 const ObjCCategoryDecl *Cat = D->getCategoryDecl(); 477 if (!Cat) 478 return true; 479 const ObjCInterfaceDecl *C = D->getClassInterface(); 480 if (C) 481 TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D, 482 SymbolRoleSet())); 483 SourceLocation CategoryLoc = D->getCategoryNameLoc(); 484 if (!CategoryLoc.isValid()) 485 CategoryLoc = D->getLocation(); 486 TRY_DECL(D, IndexCtx.handleDecl(D, CategoryLoc)); 487 IndexCtx.indexDeclContext(D); 488 return true; 489 } 490 491 bool VisitObjCMethodDecl(const ObjCMethodDecl *D) { 492 // Methods associated with a property, even user-declared ones, are 493 // handled when we handle the property. 494 if (D->isPropertyAccessor()) 495 return true; 496 497 handleObjCMethod(D); 498 return true; 499 } 500 501 bool VisitObjCPropertyDecl(const ObjCPropertyDecl *D) { 502 if (ObjCMethodDecl *MD = D->getGetterMethodDecl()) 503 if (MD->getLexicalDeclContext() == D->getLexicalDeclContext()) 504 handleObjCMethod(MD, D); 505 if (ObjCMethodDecl *MD = D->getSetterMethodDecl()) 506 if (MD->getLexicalDeclContext() == D->getLexicalDeclContext()) 507 handleObjCMethod(MD, D); 508 TRY_DECL(D, IndexCtx.handleDecl(D)); 509 if (IBOutletCollectionAttr *attr = D->getAttr<IBOutletCollectionAttr>()) 510 IndexCtx.indexTypeSourceInfo(attr->getInterfaceLoc(), D, 511 D->getLexicalDeclContext(), false, true); 512 IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D); 513 return true; 514 } 515 516 bool VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) { 517 ObjCPropertyDecl *PD = D->getPropertyDecl(); 518 auto *Container = cast<ObjCImplDecl>(D->getDeclContext()); 519 SourceLocation Loc = D->getLocation(); 520 SymbolRoleSet Roles = 0; 521 SmallVector<SymbolRelation, 1> Relations; 522 523 if (ObjCIvarDecl *ID = D->getPropertyIvarDecl()) 524 Relations.push_back({(SymbolRoleSet)SymbolRole::RelationAccessorOf, ID}); 525 if (Loc.isInvalid()) { 526 Loc = Container->getLocation(); 527 Roles |= (SymbolRoleSet)SymbolRole::Implicit; 528 } 529 TRY_DECL(D, IndexCtx.handleDecl(D, Loc, Roles, Relations)); 530 531 if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 532 return true; 533 534 assert(D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize); 535 SymbolRoleSet AccessorMethodRoles = 536 SymbolRoleSet(SymbolRole::Dynamic) | SymbolRoleSet(SymbolRole::Implicit); 537 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) { 538 if (MD->isPropertyAccessor() && 539 !hasUserDefined(MD, Container)) 540 IndexCtx.handleDecl(MD, Loc, AccessorMethodRoles, {}, Container); 541 } 542 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) { 543 if (MD->isPropertyAccessor() && 544 !hasUserDefined(MD, Container)) 545 IndexCtx.handleDecl(MD, Loc, AccessorMethodRoles, {}, Container); 546 } 547 if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) { 548 if (IvarD->getSynthesize()) { 549 // For synthesized ivars, use the location of its name in the 550 // corresponding @synthesize. If there isn't one, use the containing 551 // @implementation's location, rather than the property's location, 552 // otherwise the header file containing the @interface will have different 553 // indexing contents based on whether the @implementation was present or 554 // not in the translation unit. 555 SymbolRoleSet IvarRoles = 0; 556 SourceLocation IvarLoc = D->getPropertyIvarDeclLoc(); 557 if (D->getLocation().isInvalid()) { 558 IvarLoc = Container->getLocation(); 559 IvarRoles = (SymbolRoleSet)SymbolRole::Implicit; 560 } else if (D->getLocation() == IvarLoc) { 561 IvarRoles = (SymbolRoleSet)SymbolRole::Implicit; 562 } 563 TRY_DECL(IvarD, IndexCtx.handleDecl(IvarD, IvarLoc, IvarRoles)); 564 } else { 565 IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), nullptr, 566 D->getDeclContext(), SymbolRoleSet()); 567 } 568 } 569 return true; 570 } 571 572 bool VisitNamespaceDecl(const NamespaceDecl *D) { 573 TRY_DECL(D, IndexCtx.handleDecl(D)); 574 IndexCtx.indexDeclContext(D); 575 return true; 576 } 577 578 bool VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) { 579 TRY_DECL(D, IndexCtx.handleDecl(D)); 580 IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), D); 581 IndexCtx.handleReference(D->getAliasedNamespace(), D->getTargetNameLoc(), D, 582 D->getLexicalDeclContext()); 583 return true; 584 } 585 586 bool VisitUsingDecl(const UsingDecl *D) { 587 const DeclContext *DC = D->getDeclContext()->getRedeclContext(); 588 const NamedDecl *Parent = dyn_cast<NamedDecl>(DC); 589 590 IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent, 591 D->getLexicalDeclContext()); 592 for (const auto *I : D->shadows()) 593 IndexCtx.handleReference(I->getUnderlyingDecl(), D->getLocation(), Parent, 594 D->getLexicalDeclContext(), SymbolRoleSet()); 595 return true; 596 } 597 598 bool VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) { 599 const DeclContext *DC = D->getDeclContext()->getRedeclContext(); 600 const NamedDecl *Parent = dyn_cast<NamedDecl>(DC); 601 602 // NNS for the local 'using namespace' directives is visited by the body 603 // visitor. 604 if (!D->getParentFunctionOrMethod()) 605 IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent, 606 D->getLexicalDeclContext()); 607 608 return IndexCtx.handleReference(D->getNominatedNamespaceAsWritten(), 609 D->getLocation(), Parent, 610 D->getLexicalDeclContext(), 611 SymbolRoleSet()); 612 } 613 614 bool VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) { 615 TRY_DECL(D, IndexCtx.handleDecl(D)); 616 const DeclContext *DC = D->getDeclContext()->getRedeclContext(); 617 const NamedDecl *Parent = dyn_cast<NamedDecl>(DC); 618 IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent, 619 D->getLexicalDeclContext()); 620 return true; 621 } 622 623 bool VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) { 624 TRY_DECL(D, IndexCtx.handleDecl(D)); 625 const DeclContext *DC = D->getDeclContext()->getRedeclContext(); 626 const NamedDecl *Parent = dyn_cast<NamedDecl>(DC); 627 IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent, 628 D->getLexicalDeclContext()); 629 return true; 630 } 631 632 bool VisitClassTemplateSpecializationDecl(const 633 ClassTemplateSpecializationDecl *D) { 634 // FIXME: Notify subsequent callbacks if info comes from implicit 635 // instantiation. 636 llvm::PointerUnion<ClassTemplateDecl *, 637 ClassTemplatePartialSpecializationDecl *> 638 Template = D->getSpecializedTemplateOrPartial(); 639 const Decl *SpecializationOf = 640 Template.is<ClassTemplateDecl *>() 641 ? (Decl *)Template.get<ClassTemplateDecl *>() 642 : Template.get<ClassTemplatePartialSpecializationDecl *>(); 643 if (!D->isThisDeclarationADefinition()) 644 IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), D); 645 IndexCtx.indexTagDecl( 646 D, SymbolRelation(SymbolRoleSet(SymbolRole::RelationSpecializationOf), 647 SpecializationOf)); 648 if (TypeSourceInfo *TSI = D->getTypeAsWritten()) 649 IndexCtx.indexTypeSourceInfo(TSI, /*Parent=*/nullptr, 650 D->getLexicalDeclContext()); 651 return true; 652 } 653 654 static bool shouldIndexTemplateParameterDefaultValue(const NamedDecl *D) { 655 if (!D) 656 return false; 657 // We want to index the template parameters only once when indexing the 658 // canonical declaration. 659 if (const auto *FD = dyn_cast<FunctionDecl>(D)) 660 return FD->getCanonicalDecl() == FD; 661 else if (const auto *TD = dyn_cast<TagDecl>(D)) 662 return TD->getCanonicalDecl() == TD; 663 else if (const auto *VD = dyn_cast<VarDecl>(D)) 664 return VD->getCanonicalDecl() == VD; 665 return true; 666 } 667 668 bool VisitTemplateDecl(const TemplateDecl *D) { 669 // FIXME: Template parameters. 670 671 // Index the default values for the template parameters. 672 const NamedDecl *Parent = D->getTemplatedDecl(); 673 if (D->getTemplateParameters() && 674 shouldIndexTemplateParameterDefaultValue(Parent)) { 675 const TemplateParameterList *Params = D->getTemplateParameters(); 676 for (const NamedDecl *TP : *Params) { 677 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(TP)) { 678 if (TTP->hasDefaultArgument()) 679 IndexCtx.indexTypeSourceInfo(TTP->getDefaultArgumentInfo(), Parent); 680 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TP)) { 681 if (NTTP->hasDefaultArgument()) 682 IndexCtx.indexBody(NTTP->getDefaultArgument(), Parent); 683 } else if (const auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(TP)) { 684 if (TTPD->hasDefaultArgument()) 685 handleTemplateArgumentLoc(TTPD->getDefaultArgument(), Parent, 686 /*DC=*/nullptr); 687 } 688 } 689 } 690 691 return Visit(D->getTemplatedDecl()); 692 } 693 694 bool VisitFriendDecl(const FriendDecl *D) { 695 if (auto ND = D->getFriendDecl()) { 696 // FIXME: Ignore a class template in a dependent context, these are not 697 // linked properly with their redeclarations, ending up with duplicate 698 // USRs. 699 // See comment "Friend templates are visible in fairly strange ways." in 700 // SemaTemplate.cpp which precedes code that prevents the friend template 701 // from becoming visible from the enclosing context. 702 if (isa<ClassTemplateDecl>(ND) && D->getDeclContext()->isDependentContext()) 703 return true; 704 return Visit(ND); 705 } 706 if (auto Ty = D->getFriendType()) { 707 IndexCtx.indexTypeSourceInfo(Ty, cast<NamedDecl>(D->getDeclContext())); 708 } 709 return true; 710 } 711 712 bool VisitImportDecl(const ImportDecl *D) { 713 return IndexCtx.importedModule(D); 714 } 715 716 bool VisitStaticAssertDecl(const StaticAssertDecl *D) { 717 IndexCtx.indexBody(D->getAssertExpr(), 718 dyn_cast<NamedDecl>(D->getDeclContext()), 719 D->getLexicalDeclContext()); 720 return true; 721 } 722 }; 723 724 } // anonymous namespace 725 726 bool IndexingContext::indexDecl(const Decl *D) { 727 if (D->isImplicit() && shouldIgnoreIfImplicit(D)) 728 return true; 729 730 if (isTemplateImplicitInstantiation(D)) 731 return true; 732 733 IndexingDeclVisitor Visitor(*this); 734 bool ShouldContinue = Visitor.Visit(D); 735 if (!ShouldContinue) 736 return false; 737 738 if (!Visitor.Handled && isa<DeclContext>(D)) 739 return indexDeclContext(cast<DeclContext>(D)); 740 741 return true; 742 } 743 744 bool IndexingContext::indexDeclContext(const DeclContext *DC) { 745 for (const auto *I : DC->decls()) 746 if (!indexDecl(I)) 747 return false; 748 return true; 749 } 750 751 bool IndexingContext::indexTopLevelDecl(const Decl *D) { 752 if (D->getLocation().isInvalid()) 753 return true; 754 755 if (isa<ObjCMethodDecl>(D)) 756 return true; // Wait for the objc container. 757 758 return indexDecl(D); 759 } 760 761 bool IndexingContext::indexDeclGroupRef(DeclGroupRef DG) { 762 for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) 763 if (!indexTopLevelDecl(*I)) 764 return false; 765 return true; 766 } 767