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 handleDeclarator(const DeclaratorDecl *D,
56                         const NamedDecl *Parent = nullptr,
57                         bool isIBType = false) {
58     if (!Parent) Parent = D;
59 
60     IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), Parent,
61                                  Parent->getLexicalDeclContext(),
62                                  /*isBase=*/false, isIBType);
63     IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent);
64     if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
65       // Only index parameters in definitions, parameters in declarations are
66       // not useful.
67       if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
68         auto *DC = Parm->getDeclContext();
69         if (auto *FD = dyn_cast<FunctionDecl>(DC)) {
70           if (FD->isThisDeclarationADefinition())
71             IndexCtx.handleDecl(Parm);
72         } else if (auto *MD = dyn_cast<ObjCMethodDecl>(DC)) {
73           if (MD->isThisDeclarationADefinition())
74             IndexCtx.handleDecl(Parm);
75         } else {
76           IndexCtx.handleDecl(Parm);
77         }
78       } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
79         if (FD->isThisDeclarationADefinition()) {
80           for (auto PI : FD->parameters()) {
81             IndexCtx.handleDecl(PI);
82           }
83         }
84       }
85     }
86   }
87 
88   bool handleObjCMethod(const ObjCMethodDecl *D,
89                         const ObjCPropertyDecl *AssociatedProp = nullptr) {
90     SmallVector<SymbolRelation, 4> Relations;
91     SmallVector<const ObjCMethodDecl*, 4> Overriden;
92 
93     D->getOverriddenMethods(Overriden);
94     for(auto overridden: Overriden) {
95       Relations.emplace_back((unsigned) SymbolRole::RelationOverrideOf,
96                              overridden);
97     }
98     if (AssociatedProp)
99       Relations.emplace_back((unsigned)SymbolRole::RelationAccessorOf,
100                              AssociatedProp);
101 
102     // getLocation() returns beginning token of a method declaration, but for
103     // indexing purposes we want to point to the base name.
104     SourceLocation MethodLoc = D->getSelectorStartLoc();
105     if (MethodLoc.isInvalid())
106       MethodLoc = D->getLocation();
107 
108     SourceLocation AttrLoc;
109 
110     // check for (getter=/setter=)
111     if (AssociatedProp) {
112       bool isGetter = !D->param_size();
113       AttrLoc = isGetter ?
114         AssociatedProp->getGetterNameLoc():
115         AssociatedProp->getSetterNameLoc();
116     }
117 
118     SymbolRoleSet Roles = (SymbolRoleSet)SymbolRole::Dynamic;
119     if (D->isImplicit()) {
120       if (AttrLoc.isValid()) {
121         MethodLoc = AttrLoc;
122       } else {
123         Roles |= (SymbolRoleSet)SymbolRole::Implicit;
124       }
125     } else if (AttrLoc.isValid()) {
126       IndexCtx.handleReference(D, AttrLoc, cast<NamedDecl>(D->getDeclContext()),
127                                D->getDeclContext(), 0);
128     }
129 
130     TRY_DECL(D, IndexCtx.handleDecl(D, MethodLoc, Roles, Relations));
131     IndexCtx.indexTypeSourceInfo(D->getReturnTypeSourceInfo(), D);
132     bool hasIBActionAndFirst = D->hasAttr<IBActionAttr>();
133     for (const auto *I : D->parameters()) {
134       handleDeclarator(I, D, /*isIBType=*/hasIBActionAndFirst);
135       hasIBActionAndFirst = false;
136     }
137 
138     if (D->isThisDeclarationADefinition()) {
139       const Stmt *Body = D->getBody();
140       if (Body) {
141         IndexCtx.indexBody(Body, D, D);
142       }
143     }
144     return true;
145   }
146 
147   bool VisitFunctionDecl(const FunctionDecl *D) {
148     if (D->isDeleted())
149       return true;
150 
151     SymbolRoleSet Roles{};
152     SmallVector<SymbolRelation, 4> Relations;
153     if (auto *CXXMD = dyn_cast<CXXMethodDecl>(D)) {
154       if (CXXMD->isVirtual())
155         Roles |= (unsigned)SymbolRole::Dynamic;
156       for (auto I = CXXMD->begin_overridden_methods(),
157            E = CXXMD->end_overridden_methods(); I != E; ++I) {
158         Relations.emplace_back((unsigned)SymbolRole::RelationOverrideOf, *I);
159       }
160     }
161 
162     TRY_DECL(D, IndexCtx.handleDecl(D, Roles, Relations));
163     handleDeclarator(D);
164 
165     if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
166       IndexCtx.handleReference(Ctor->getParent(), Ctor->getLocation(),
167                                Ctor->getParent(), Ctor->getDeclContext());
168 
169       // Constructor initializers.
170       for (const auto *Init : Ctor->inits()) {
171         if (Init->isWritten()) {
172           IndexCtx.indexTypeSourceInfo(Init->getTypeSourceInfo(), D);
173           if (const FieldDecl *Member = Init->getAnyMember())
174             IndexCtx.handleReference(Member, Init->getMemberLocation(), D, D,
175                                      (unsigned)SymbolRole::Write);
176           IndexCtx.indexBody(Init->getInit(), D, D);
177         }
178       }
179     } else if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(D)) {
180       if (auto TypeNameInfo = Dtor->getNameInfo().getNamedTypeInfo()) {
181         IndexCtx.handleReference(Dtor->getParent(),
182                                  TypeNameInfo->getTypeLoc().getLocStart(),
183                                  Dtor->getParent(), Dtor->getDeclContext());
184       }
185     }
186 
187     if (D->isThisDeclarationADefinition()) {
188       const Stmt *Body = D->getBody();
189       if (Body) {
190         IndexCtx.indexBody(Body, D, D);
191       }
192     }
193     return true;
194   }
195 
196   bool VisitVarDecl(const VarDecl *D) {
197     TRY_DECL(D, IndexCtx.handleDecl(D));
198     handleDeclarator(D);
199     IndexCtx.indexBody(D->getInit(), D);
200     return true;
201   }
202 
203   bool VisitFieldDecl(const FieldDecl *D) {
204     TRY_DECL(D, IndexCtx.handleDecl(D));
205     handleDeclarator(D);
206     if (D->isBitField())
207       IndexCtx.indexBody(D->getBitWidth(), D);
208     else if (D->hasInClassInitializer())
209       IndexCtx.indexBody(D->getInClassInitializer(), D);
210     return true;
211   }
212 
213   bool VisitObjCIvarDecl(const ObjCIvarDecl *D) {
214     if (D->getSynthesize()) {
215       // handled in VisitObjCPropertyImplDecl
216       return true;
217     }
218     TRY_DECL(D, IndexCtx.handleDecl(D));
219     handleDeclarator(D);
220     return true;
221   }
222 
223   bool VisitMSPropertyDecl(const MSPropertyDecl *D) {
224     handleDeclarator(D);
225     return true;
226   }
227 
228   bool VisitEnumConstantDecl(const EnumConstantDecl *D) {
229     TRY_DECL(D, IndexCtx.handleDecl(D));
230     IndexCtx.indexBody(D->getInitExpr(), D);
231     return true;
232   }
233 
234   bool VisitTypedefNameDecl(const TypedefNameDecl *D) {
235     if (!D->isTransparentTag()) {
236       TRY_DECL(D, IndexCtx.handleDecl(D));
237       IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
238     }
239     return true;
240   }
241 
242   bool VisitTagDecl(const TagDecl *D) {
243     // Non-free standing tags are handled in indexTypeSourceInfo.
244     if (D->isFreeStanding()) {
245       if (D->isThisDeclarationADefinition()) {
246         IndexCtx.indexTagDecl(D);
247       } else {
248         auto *Parent = dyn_cast<NamedDecl>(D->getDeclContext());
249         return IndexCtx.handleReference(D, D->getLocation(), Parent,
250                                         D->getLexicalDeclContext(),
251                                         SymbolRoleSet());
252       }
253     }
254     return true;
255   }
256 
257   bool handleReferencedProtocols(const ObjCProtocolList &ProtList,
258                                  const ObjCContainerDecl *ContD,
259                                  SourceLocation SuperLoc) {
260     ObjCInterfaceDecl::protocol_loc_iterator LI = ProtList.loc_begin();
261     for (ObjCInterfaceDecl::protocol_iterator
262          I = ProtList.begin(), E = ProtList.end(); I != E; ++I, ++LI) {
263       SourceLocation Loc = *LI;
264       ObjCProtocolDecl *PD = *I;
265       SymbolRoleSet roles{};
266       if (Loc == SuperLoc)
267         roles |= (SymbolRoleSet)SymbolRole::Implicit;
268       TRY_TO(IndexCtx.handleReference(PD, Loc, ContD, ContD, roles,
269           SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, ContD}));
270     }
271     return true;
272   }
273 
274   bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
275     if (D->isThisDeclarationADefinition()) {
276       TRY_DECL(D, IndexCtx.handleDecl(D));
277       SourceLocation SuperLoc = D->getSuperClassLoc();
278       if (auto *SuperD = D->getSuperClass()) {
279         bool hasSuperTypedef = false;
280         if (auto *TInfo = D->getSuperClassTInfo()) {
281           if (auto *TT = TInfo->getType()->getAs<TypedefType>()) {
282             if (auto *TD = TT->getDecl()) {
283               hasSuperTypedef = true;
284               TRY_TO(IndexCtx.handleReference(TD, SuperLoc, D, D,
285                                               SymbolRoleSet()));
286             }
287           }
288         }
289         SymbolRoleSet superRoles{};
290         if (hasSuperTypedef)
291           superRoles |= (SymbolRoleSet)SymbolRole::Implicit;
292         TRY_TO(IndexCtx.handleReference(SuperD, SuperLoc, D, D, superRoles,
293             SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, D}));
294       }
295       TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
296                                        SuperLoc));
297       TRY_TO(IndexCtx.indexDeclContext(D));
298     } else {
299       return IndexCtx.handleReference(D, D->getLocation(), nullptr,
300                                       D->getDeclContext(), SymbolRoleSet());
301     }
302     return true;
303   }
304 
305   bool VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
306     if (D->isThisDeclarationADefinition()) {
307       TRY_DECL(D, IndexCtx.handleDecl(D));
308       TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
309                                        /*superLoc=*/SourceLocation()));
310       TRY_TO(IndexCtx.indexDeclContext(D));
311     } else {
312       return IndexCtx.handleReference(D, D->getLocation(), nullptr,
313                                       D->getDeclContext(), SymbolRoleSet());
314     }
315     return true;
316   }
317 
318   bool VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
319     const ObjCInterfaceDecl *Class = D->getClassInterface();
320     if (!Class)
321       return true;
322 
323     if (Class->isImplicitInterfaceDecl())
324       IndexCtx.handleDecl(Class);
325 
326     TRY_DECL(D, IndexCtx.handleDecl(D));
327 
328     // Visit implicit @synthesize property implementations first as their
329     // location is reported at the name of the @implementation block. This
330     // serves no purpose other than to simplify the FileCheck-based tests.
331     for (const auto *I : D->property_impls()) {
332       if (I->getLocation().isInvalid())
333         IndexCtx.indexDecl(I);
334     }
335     for (const auto *I : D->decls()) {
336       if (!isa<ObjCPropertyImplDecl>(I) ||
337           cast<ObjCPropertyImplDecl>(I)->getLocation().isValid())
338         IndexCtx.indexDecl(I);
339     }
340 
341     return true;
342   }
343 
344   bool VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
345     if (!IndexCtx.shouldIndex(D))
346       return true;
347     const ObjCInterfaceDecl *C = D->getClassInterface();
348     if (!C)
349       return true;
350     TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D, SymbolRoleSet(),
351                                    SymbolRelation{
352                                      (unsigned)SymbolRole::RelationExtendedBy, D
353                                    }));
354     SourceLocation CategoryLoc = D->getCategoryNameLoc();
355     if (!CategoryLoc.isValid())
356       CategoryLoc = D->getLocation();
357     TRY_TO(IndexCtx.handleDecl(D, CategoryLoc));
358     TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
359                                      /*superLoc=*/SourceLocation()));
360     TRY_TO(IndexCtx.indexDeclContext(D));
361     return true;
362   }
363 
364   bool VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
365     const ObjCCategoryDecl *Cat = D->getCategoryDecl();
366     if (!Cat)
367       return true;
368     const ObjCInterfaceDecl *C = D->getClassInterface();
369     if (C)
370       TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D,
371                                       SymbolRoleSet()));
372     SourceLocation CategoryLoc = D->getCategoryNameLoc();
373     if (!CategoryLoc.isValid())
374       CategoryLoc = D->getLocation();
375     TRY_DECL(D, IndexCtx.handleDecl(D, CategoryLoc));
376     IndexCtx.indexDeclContext(D);
377     return true;
378   }
379 
380   bool VisitObjCMethodDecl(const ObjCMethodDecl *D) {
381     // Methods associated with a property, even user-declared ones, are
382     // handled when we handle the property.
383     if (D->isPropertyAccessor())
384       return true;
385 
386     handleObjCMethod(D);
387     return true;
388   }
389 
390   bool VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
391     if (ObjCMethodDecl *MD = D->getGetterMethodDecl())
392       if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
393         handleObjCMethod(MD, D);
394     if (ObjCMethodDecl *MD = D->getSetterMethodDecl())
395       if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
396         handleObjCMethod(MD, D);
397     TRY_DECL(D, IndexCtx.handleDecl(D));
398     if (IBOutletCollectionAttr *attr = D->getAttr<IBOutletCollectionAttr>())
399       IndexCtx.indexTypeSourceInfo(attr->getInterfaceLoc(), D,
400                                    D->getLexicalDeclContext(), false, true);
401     IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
402     return true;
403   }
404 
405   bool VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
406     ObjCPropertyDecl *PD = D->getPropertyDecl();
407     auto *Container = cast<ObjCImplDecl>(D->getDeclContext());
408     SourceLocation Loc = D->getLocation();
409     SymbolRoleSet Roles = 0;
410     SmallVector<SymbolRelation, 1> Relations;
411 
412     if (ObjCIvarDecl *ID = D->getPropertyIvarDecl())
413       Relations.push_back({(SymbolRoleSet)SymbolRole::RelationAccessorOf, ID});
414     if (Loc.isInvalid()) {
415       Loc = Container->getLocation();
416       Roles |= (SymbolRoleSet)SymbolRole::Implicit;
417     }
418     TRY_DECL(D, IndexCtx.handleDecl(D, Loc, Roles, Relations));
419 
420     if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
421       return true;
422 
423     assert(D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize);
424     if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) {
425       if (MD->isPropertyAccessor() &&
426           !hasUserDefined(MD, Container))
427         IndexCtx.handleDecl(MD, Loc, SymbolRoleSet(SymbolRole::Implicit), {},
428                             Container);
429     }
430     if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) {
431       if (MD->isPropertyAccessor() &&
432           !hasUserDefined(MD, Container))
433         IndexCtx.handleDecl(MD, Loc, SymbolRoleSet(SymbolRole::Implicit), {},
434                             Container);
435     }
436     if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) {
437       if (IvarD->getSynthesize()) {
438         // For synthesized ivars, use the location of its name in the
439         // corresponding @synthesize. If there isn't one, use the containing
440         // @implementation's location, rather than the property's location,
441         // otherwise the header file containing the @interface will have different
442         // indexing contents based on whether the @implementation was present or
443         // not in the translation unit.
444         SymbolRoleSet IvarRoles = 0;
445         SourceLocation IvarLoc = D->getPropertyIvarDeclLoc();
446         if (D->getLocation().isInvalid()) {
447           IvarLoc = Container->getLocation();
448           IvarRoles = (SymbolRoleSet)SymbolRole::Implicit;
449         } else if (D->getLocation() == IvarLoc) {
450           IvarRoles = (SymbolRoleSet)SymbolRole::Implicit;
451         }
452         TRY_DECL(IvarD, IndexCtx.handleDecl(IvarD, IvarLoc, IvarRoles));
453       } else {
454         IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), nullptr,
455                                  D->getDeclContext(), SymbolRoleSet());
456       }
457     }
458     return true;
459   }
460 
461   bool VisitNamespaceDecl(const NamespaceDecl *D) {
462     TRY_DECL(D, IndexCtx.handleDecl(D));
463     IndexCtx.indexDeclContext(D);
464     return true;
465   }
466 
467   bool VisitUsingDecl(const UsingDecl *D) {
468     const DeclContext *DC = D->getDeclContext()->getRedeclContext();
469     const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
470 
471     IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent,
472                                          D->getLexicalDeclContext());
473     for (const auto *I : D->shadows())
474       IndexCtx.handleReference(I->getUnderlyingDecl(), D->getLocation(), Parent,
475                                D->getLexicalDeclContext(), SymbolRoleSet());
476     return true;
477   }
478 
479   bool VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
480     const DeclContext *DC = D->getDeclContext()->getRedeclContext();
481     const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
482 
483     IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent,
484                                          D->getLexicalDeclContext());
485     return IndexCtx.handleReference(D->getNominatedNamespaceAsWritten(),
486                                     D->getLocation(), Parent,
487                                     D->getLexicalDeclContext(),
488                                     SymbolRoleSet());
489   }
490 
491   bool VisitClassTemplateSpecializationDecl(const
492                                            ClassTemplateSpecializationDecl *D) {
493     // FIXME: Notify subsequent callbacks if info comes from implicit
494     // instantiation.
495     if (D->isThisDeclarationADefinition()) {
496       llvm::PointerUnion<ClassTemplateDecl *,
497                          ClassTemplatePartialSpecializationDecl *>
498           Template = D->getSpecializedTemplateOrPartial();
499       const Decl *SpecializationOf =
500           Template.is<ClassTemplateDecl *>()
501               ? (Decl *)Template.get<ClassTemplateDecl *>()
502               : Template.get<ClassTemplatePartialSpecializationDecl *>();
503       IndexCtx.indexTagDecl(
504           D, SymbolRelation(SymbolRoleSet(SymbolRole::RelationSpecializationOf),
505                             SpecializationOf));
506     }
507     return true;
508   }
509 
510   bool VisitTemplateDecl(const TemplateDecl *D) {
511     // FIXME: Template parameters.
512     return Visit(D->getTemplatedDecl());
513   }
514 
515   bool VisitFriendDecl(const FriendDecl *D) {
516     if (auto ND = D->getFriendDecl()) {
517       // FIXME: Ignore a class template in a dependent context, these are not
518       // linked properly with their redeclarations, ending up with duplicate
519       // USRs.
520       // See comment "Friend templates are visible in fairly strange ways." in
521       // SemaTemplate.cpp which precedes code that prevents the friend template
522       // from becoming visible from the enclosing context.
523       if (isa<ClassTemplateDecl>(ND) && D->getDeclContext()->isDependentContext())
524         return true;
525       return Visit(ND);
526     }
527     if (auto Ty = D->getFriendType()) {
528       IndexCtx.indexTypeSourceInfo(Ty, cast<NamedDecl>(D->getDeclContext()));
529     }
530     return true;
531   }
532 
533   bool VisitImportDecl(const ImportDecl *D) {
534     return IndexCtx.importedModule(D);
535   }
536 };
537 
538 } // anonymous namespace
539 
540 bool IndexingContext::indexDecl(const Decl *D) {
541   if (D->isImplicit() && shouldIgnoreIfImplicit(D))
542     return true;
543 
544   if (isTemplateImplicitInstantiation(D))
545     return true;
546 
547   IndexingDeclVisitor Visitor(*this);
548   bool ShouldContinue = Visitor.Visit(D);
549   if (!ShouldContinue)
550     return false;
551 
552   if (!Visitor.Handled && isa<DeclContext>(D))
553     return indexDeclContext(cast<DeclContext>(D));
554 
555   return true;
556 }
557 
558 bool IndexingContext::indexDeclContext(const DeclContext *DC) {
559   for (const auto *I : DC->decls())
560     if (!indexDecl(I))
561       return false;
562   return true;
563 }
564 
565 bool IndexingContext::indexTopLevelDecl(const Decl *D) {
566   if (D->getLocation().isInvalid())
567     return true;
568 
569   if (isa<ObjCMethodDecl>(D))
570     return true; // Wait for the objc container.
571 
572   return indexDecl(D);
573 }
574 
575 bool IndexingContext::indexDeclGroupRef(DeclGroupRef DG) {
576   for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
577     if (!indexTopLevelDecl(*I))
578       return false;
579   return true;
580 }
581