1 //===- CXIndexDataConsumer.cpp - Index data consumer for libclang----------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "CXIndexDataConsumer.h"
10 #include "CIndexDiagnostic.h"
12 #include "CXTranslationUnit.h"
13 #include "clang/AST/Attr.h"
14 #include "clang/AST/DeclCXX.h"
15 #include "clang/AST/DeclTemplate.h"
16 #include "clang/AST/DeclVisitor.h"
17 #include "clang/Frontend/ASTUnit.h"
19 using namespace clang
;
20 using namespace clang::index
;
21 using namespace cxindex
;
22 using namespace cxcursor
;
25 class IndexingDeclVisitor
: public ConstDeclVisitor
<IndexingDeclVisitor
, bool> {
26 CXIndexDataConsumer
&DataConsumer
;
27 SourceLocation DeclLoc
;
28 const DeclContext
*LexicalDC
;
31 IndexingDeclVisitor(CXIndexDataConsumer
&dataConsumer
, SourceLocation Loc
,
32 const DeclContext
*lexicalDC
)
33 : DataConsumer(dataConsumer
), DeclLoc(Loc
), LexicalDC(lexicalDC
) { }
35 bool VisitFunctionDecl(const FunctionDecl
*D
) {
36 DataConsumer
.handleFunction(D
);
40 bool VisitVarDecl(const VarDecl
*D
) {
41 DataConsumer
.handleVar(D
);
45 bool VisitFieldDecl(const FieldDecl
*D
) {
46 DataConsumer
.handleField(D
);
50 bool VisitMSPropertyDecl(const MSPropertyDecl
*D
) {
54 bool VisitEnumConstantDecl(const EnumConstantDecl
*D
) {
55 DataConsumer
.handleEnumerator(D
);
59 bool VisitTypedefNameDecl(const TypedefNameDecl
*D
) {
60 DataConsumer
.handleTypedefName(D
);
64 bool VisitTagDecl(const TagDecl
*D
) {
65 DataConsumer
.handleTagDecl(D
);
69 bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl
*D
) {
70 DataConsumer
.handleObjCInterface(D
);
74 bool VisitObjCProtocolDecl(const ObjCProtocolDecl
*D
) {
75 DataConsumer
.handleObjCProtocol(D
);
79 bool VisitObjCImplementationDecl(const ObjCImplementationDecl
*D
) {
80 DataConsumer
.handleObjCImplementation(D
);
84 bool VisitObjCCategoryDecl(const ObjCCategoryDecl
*D
) {
85 DataConsumer
.handleObjCCategory(D
);
89 bool VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl
*D
) {
90 DataConsumer
.handleObjCCategoryImpl(D
);
94 bool VisitObjCMethodDecl(const ObjCMethodDecl
*D
) {
95 if (isa
<ObjCImplDecl
>(LexicalDC
) && !D
->isThisDeclarationADefinition())
96 DataConsumer
.handleSynthesizedObjCMethod(D
, DeclLoc
, LexicalDC
);
98 DataConsumer
.handleObjCMethod(D
, DeclLoc
);
102 bool VisitObjCPropertyDecl(const ObjCPropertyDecl
*D
) {
103 DataConsumer
.handleObjCProperty(D
);
107 bool VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl
*D
) {
108 DataConsumer
.handleSynthesizedObjCProperty(D
);
112 bool VisitNamespaceDecl(const NamespaceDecl
*D
) {
113 DataConsumer
.handleNamespace(D
);
117 bool VisitUsingDecl(const UsingDecl
*D
) {
121 bool VisitUsingDirectiveDecl(const UsingDirectiveDecl
*D
) {
125 bool VisitClassTemplateDecl(const ClassTemplateDecl
*D
) {
126 DataConsumer
.handleClassTemplate(D
);
130 bool VisitClassTemplateSpecializationDecl(const
131 ClassTemplateSpecializationDecl
*D
) {
132 DataConsumer
.handleTagDecl(D
);
136 bool VisitFunctionTemplateDecl(const FunctionTemplateDecl
*D
) {
137 DataConsumer
.handleFunctionTemplate(D
);
141 bool VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl
*D
) {
142 DataConsumer
.handleTypeAliasTemplate(D
);
146 bool VisitImportDecl(const ImportDecl
*D
) {
147 DataConsumer
.importedModule(D
);
151 bool VisitConceptDecl(const ConceptDecl
*D
) {
152 DataConsumer
.handleConcept(D
);
157 CXSymbolRole
getSymbolRole(SymbolRoleSet Role
) {
158 // CXSymbolRole mirrors low 9 bits of clang::index::SymbolRole.
159 return CXSymbolRole(static_cast<uint32_t>(Role
) & ((1 << 9) - 1));
163 bool CXIndexDataConsumer::handleDeclOccurrence(
164 const Decl
*D
, SymbolRoleSet Roles
, ArrayRef
<SymbolRelation
> Relations
,
165 SourceLocation Loc
, ASTNodeInfo ASTNode
) {
166 Loc
= getASTContext().getSourceManager().getFileLoc(Loc
);
168 if (Roles
& (unsigned)SymbolRole::Reference
) {
169 const NamedDecl
*ND
= dyn_cast
<NamedDecl
>(D
);
173 if (auto *ObjCID
= dyn_cast_or_null
<ObjCInterfaceDecl
>(ASTNode
.OrigD
)) {
174 if (!ObjCID
->isThisDeclarationADefinition() &&
175 ObjCID
->getLocation() == Loc
) {
176 // The libclang API treats this as ObjCClassRef declaration.
177 IndexingDeclVisitor(*this, Loc
, nullptr).Visit(ObjCID
);
181 if (auto *ObjCPD
= dyn_cast_or_null
<ObjCProtocolDecl
>(ASTNode
.OrigD
)) {
182 if (!ObjCPD
->isThisDeclarationADefinition() &&
183 ObjCPD
->getLocation() == Loc
) {
184 // The libclang API treats this as ObjCProtocolRef declaration.
185 IndexingDeclVisitor(*this, Loc
, nullptr).Visit(ObjCPD
);
190 CXIdxEntityRefKind Kind
= CXIdxEntityRef_Direct
;
191 if (Roles
& (unsigned)SymbolRole::Implicit
) {
192 Kind
= CXIdxEntityRef_Implicit
;
194 CXSymbolRole CXRole
= getSymbolRole(Roles
);
198 Cursor
= cxcursor::MakeCXCursor(ASTNode
.OrigE
,
199 cast
<Decl
>(ASTNode
.ContainerDC
),
203 if (auto *OrigND
= dyn_cast
<NamedDecl
>(ASTNode
.OrigD
))
204 Cursor
= getRefCursor(OrigND
, Loc
);
206 Cursor
= MakeCXCursor(ASTNode
.OrigD
, CXTU
);
208 Cursor
= getRefCursor(ND
, Loc
);
211 handleReference(ND
, Loc
, Cursor
,
212 dyn_cast_or_null
<NamedDecl
>(ASTNode
.Parent
),
213 ASTNode
.ContainerDC
, ASTNode
.OrigE
, Kind
, CXRole
);
216 const DeclContext
*LexicalDC
= ASTNode
.ContainerDC
;
218 for (const auto &SymRel
: Relations
) {
219 if (SymRel
.Roles
& (unsigned)SymbolRole::RelationChildOf
)
220 LexicalDC
= dyn_cast
<DeclContext
>(SymRel
.RelatedSymbol
);
223 IndexingDeclVisitor(*this, Loc
, LexicalDC
).Visit(ASTNode
.OrigD
);
226 return !shouldAbort();
229 bool CXIndexDataConsumer::handleModuleOccurrence(const ImportDecl
*ImportD
,
232 SourceLocation Loc
) {
233 if (Roles
& (SymbolRoleSet
)SymbolRole::Declaration
)
234 IndexingDeclVisitor(*this, SourceLocation(), nullptr).Visit(ImportD
);
235 return !shouldAbort();
238 void CXIndexDataConsumer::finish() {
243 CXIndexDataConsumer::ObjCProtocolListInfo::ObjCProtocolListInfo(
244 const ObjCProtocolList
&ProtList
,
245 CXIndexDataConsumer
&IdxCtx
,
247 ObjCInterfaceDecl::protocol_loc_iterator LI
= ProtList
.loc_begin();
248 for (ObjCInterfaceDecl::protocol_iterator
249 I
= ProtList
.begin(), E
= ProtList
.end(); I
!= E
; ++I
, ++LI
) {
250 SourceLocation Loc
= *LI
;
251 ObjCProtocolDecl
*PD
= *I
;
252 ProtEntities
.push_back(EntityInfo());
253 IdxCtx
.getEntityInfo(PD
, ProtEntities
.back(), SA
);
254 CXIdxObjCProtocolRefInfo ProtInfo
= { nullptr,
255 MakeCursorObjCProtocolRef(PD
, Loc
, IdxCtx
.CXTU
),
256 IdxCtx
.getIndexLoc(Loc
) };
257 ProtInfos
.push_back(ProtInfo
);
259 if (IdxCtx
.shouldSuppressRefs())
260 IdxCtx
.markEntityOccurrenceInFile(PD
, Loc
);
263 for (unsigned i
= 0, e
= ProtInfos
.size(); i
!= e
; ++i
)
264 ProtInfos
[i
].protocol
= &ProtEntities
[i
];
266 for (unsigned i
= 0, e
= ProtInfos
.size(); i
!= e
; ++i
)
267 Prots
.push_back(&ProtInfos
[i
]);
271 IBOutletCollectionInfo::IBOutletCollectionInfo(
272 const IBOutletCollectionInfo
&other
)
273 : AttrInfo(CXIdxAttr_IBOutletCollection
, other
.cursor
, other
.loc
, other
.A
) {
275 IBCollInfo
.attrInfo
= this;
276 IBCollInfo
.classCursor
= other
.IBCollInfo
.classCursor
;
277 IBCollInfo
.classLoc
= other
.IBCollInfo
.classLoc
;
278 if (other
.IBCollInfo
.objcClass
) {
279 ClassInfo
= other
.ClassInfo
;
280 IBCollInfo
.objcClass
= &ClassInfo
;
282 IBCollInfo
.objcClass
= nullptr;
285 AttrListInfo::AttrListInfo(const Decl
*D
, CXIndexDataConsumer
&IdxCtx
)
286 : SA(IdxCtx
), ref_cnt(0) {
291 for (const auto *A
: D
->attrs()) {
292 CXCursor C
= MakeCXCursor(A
, D
, IdxCtx
.CXTU
);
293 CXIdxLoc Loc
= IdxCtx
.getIndexLoc(A
->getLocation());
296 Attrs
.push_back(AttrInfo(CXIdxAttr_Unexposed
, C
, Loc
, A
));
298 case CXCursor_IBActionAttr
:
299 Attrs
.push_back(AttrInfo(CXIdxAttr_IBAction
, C
, Loc
, A
));
301 case CXCursor_IBOutletAttr
:
302 Attrs
.push_back(AttrInfo(CXIdxAttr_IBOutlet
, C
, Loc
, A
));
304 case CXCursor_IBOutletCollectionAttr
:
305 IBCollAttrs
.push_back(IBOutletCollectionInfo(C
, Loc
, A
));
310 for (unsigned i
= 0, e
= IBCollAttrs
.size(); i
!= e
; ++i
) {
311 IBOutletCollectionInfo
&IBInfo
= IBCollAttrs
[i
];
312 CXAttrs
.push_back(&IBInfo
);
314 const IBOutletCollectionAttr
*
315 IBAttr
= cast
<IBOutletCollectionAttr
>(IBInfo
.A
);
316 SourceLocation InterfaceLocStart
=
317 IBAttr
->getInterfaceLoc()->getTypeLoc().getBeginLoc();
318 IBInfo
.IBCollInfo
.attrInfo
= &IBInfo
;
319 IBInfo
.IBCollInfo
.classLoc
= IdxCtx
.getIndexLoc(InterfaceLocStart
);
320 IBInfo
.IBCollInfo
.objcClass
= nullptr;
321 IBInfo
.IBCollInfo
.classCursor
= clang_getNullCursor();
322 QualType Ty
= IBAttr
->getInterface();
323 if (const ObjCObjectType
*ObjectTy
= Ty
->getAs
<ObjCObjectType
>()) {
324 if (const ObjCInterfaceDecl
*InterD
= ObjectTy
->getInterface()) {
325 IdxCtx
.getEntityInfo(InterD
, IBInfo
.ClassInfo
, SA
);
326 IBInfo
.IBCollInfo
.objcClass
= &IBInfo
.ClassInfo
;
327 IBInfo
.IBCollInfo
.classCursor
=
328 MakeCursorObjCClassRef(InterD
, InterfaceLocStart
, IdxCtx
.CXTU
);
333 for (unsigned i
= 0, e
= Attrs
.size(); i
!= e
; ++i
)
334 CXAttrs
.push_back(&Attrs
[i
]);
337 IntrusiveRefCntPtr
<AttrListInfo
>
338 AttrListInfo::create(const Decl
*D
, CXIndexDataConsumer
&IdxCtx
) {
339 ScratchAlloc
SA(IdxCtx
);
340 AttrListInfo
*attrs
= SA
.allocate
<AttrListInfo
>();
341 return new (attrs
) AttrListInfo(D
, IdxCtx
);
344 CXIndexDataConsumer::CXXBasesListInfo::CXXBasesListInfo(const CXXRecordDecl
*D
,
345 CXIndexDataConsumer
&IdxCtx
,
347 for (const auto &Base
: D
->bases()) {
348 BaseEntities
.push_back(EntityInfo());
349 const NamedDecl
*BaseD
= nullptr;
350 QualType T
= Base
.getType();
351 SourceLocation Loc
= getBaseLoc(Base
);
353 if (const TypedefType
*TDT
= T
->getAs
<TypedefType
>()) {
354 BaseD
= TDT
->getDecl();
355 } else if (const TemplateSpecializationType
*
356 TST
= T
->getAs
<TemplateSpecializationType
>()) {
357 BaseD
= TST
->getTemplateName().getAsTemplateDecl();
358 } else if (const RecordType
*RT
= T
->getAs
<RecordType
>()) {
359 BaseD
= RT
->getDecl();
363 IdxCtx
.getEntityInfo(BaseD
, BaseEntities
.back(), SA
);
364 CXIdxBaseClassInfo BaseInfo
= { nullptr,
365 MakeCursorCXXBaseSpecifier(&Base
, IdxCtx
.CXTU
),
366 IdxCtx
.getIndexLoc(Loc
) };
367 BaseInfos
.push_back(BaseInfo
);
370 for (unsigned i
= 0, e
= BaseInfos
.size(); i
!= e
; ++i
) {
371 if (BaseEntities
[i
].name
&& BaseEntities
[i
].USR
)
372 BaseInfos
[i
].base
= &BaseEntities
[i
];
375 for (unsigned i
= 0, e
= BaseInfos
.size(); i
!= e
; ++i
)
376 CXBases
.push_back(&BaseInfos
[i
]);
379 SourceLocation
CXIndexDataConsumer::CXXBasesListInfo::getBaseLoc(
380 const CXXBaseSpecifier
&Base
) const {
381 SourceLocation Loc
= Base
.getSourceRange().getBegin();
383 if (Base
.getTypeSourceInfo())
384 TL
= Base
.getTypeSourceInfo()->getTypeLoc();
388 if (QualifiedTypeLoc QL
= TL
.getAs
<QualifiedTypeLoc
>())
389 TL
= QL
.getUnqualifiedLoc();
391 if (ElaboratedTypeLoc EL
= TL
.getAs
<ElaboratedTypeLoc
>())
392 return EL
.getNamedTypeLoc().getBeginLoc();
393 if (DependentNameTypeLoc DL
= TL
.getAs
<DependentNameTypeLoc
>())
394 return DL
.getNameLoc();
395 if (DependentTemplateSpecializationTypeLoc DTL
=
396 TL
.getAs
<DependentTemplateSpecializationTypeLoc
>())
397 return DTL
.getTemplateNameLoc();
402 const char *ScratchAlloc::toCStr(StringRef Str
) {
405 if (Str
.data()[Str
.size()] == '\0')
407 return copyCStr(Str
);
410 const char *ScratchAlloc::copyCStr(StringRef Str
) {
411 char *buf
= IdxCtx
.StrScratch
.Allocate
<char>(Str
.size() + 1);
412 std::uninitialized_copy(Str
.begin(), Str
.end(), buf
);
413 buf
[Str
.size()] = '\0';
417 void CXIndexDataConsumer::setASTContext(ASTContext
&ctx
) {
419 cxtu::getASTUnit(CXTU
)->setASTContext(&ctx
);
422 void CXIndexDataConsumer::setPreprocessor(std::shared_ptr
<Preprocessor
> PP
) {
423 cxtu::getASTUnit(CXTU
)->setPreprocessor(std::move(PP
));
426 bool CXIndexDataConsumer::isFunctionLocalDecl(const Decl
*D
) {
429 if (!D
->getParentFunctionOrMethod())
432 if (const NamedDecl
*ND
= dyn_cast
<NamedDecl
>(D
)) {
433 switch (ND
->getFormalLinkage()) {
434 case Linkage::Invalid
:
435 llvm_unreachable("Linkage hasn't been computed!");
437 case Linkage::Internal
:
439 case Linkage::VisibleNone
:
440 case Linkage::UniqueExternal
:
441 llvm_unreachable("Not a sema linkage");
442 case Linkage::Module
:
443 case Linkage::External
:
451 bool CXIndexDataConsumer::shouldAbort() {
454 return CB
.abortQuery(ClientData
, nullptr);
457 void CXIndexDataConsumer::enteredMainFile(OptionalFileEntryRef File
) {
458 if (File
&& CB
.enteredMainFile
) {
459 CXIdxClientFile idxFile
=
460 CB
.enteredMainFile(ClientData
, cxfile::makeCXFile(*File
), nullptr);
461 FileMap
[*File
] = idxFile
;
465 void CXIndexDataConsumer::ppIncludedFile(SourceLocation hashLoc
,
467 OptionalFileEntryRef File
,
468 bool isImport
, bool isAngled
,
469 bool isModuleImport
) {
470 if (!CB
.ppIncludedFile
)
473 const FileEntry
*FE
= File
? &File
->getFileEntry() : nullptr;
475 ScratchAlloc
SA(*this);
476 CXIdxIncludedFileInfo Info
= { getIndexLoc(hashLoc
),
478 cxfile::makeCXFile(File
),
479 isImport
, isAngled
, isModuleImport
};
480 CXIdxClientFile idxFile
= CB
.ppIncludedFile(ClientData
, &Info
);
481 FileMap
[FE
] = idxFile
;
484 void CXIndexDataConsumer::importedModule(const ImportDecl
*ImportD
) {
485 if (!CB
.importedASTFile
)
488 Module
*Mod
= ImportD
->getImportedModule();
492 // If the imported module is part of the top-level module that we're
493 // indexing, it doesn't correspond to an imported AST file.
494 // FIXME: This assumes that AST files and top-level modules directly
495 // correspond, which is unlikely to remain true forever.
496 if (Module
*SrcMod
= ImportD
->getImportedOwningModule())
497 if (SrcMod
->getTopLevelModule() == Mod
->getTopLevelModule())
500 OptionalFileEntryRef FE
= Mod
->getASTFile();
501 CXIdxImportedASTFileInfo Info
= {cxfile::makeCXFile(FE
), Mod
,
502 getIndexLoc(ImportD
->getLocation()),
503 ImportD
->isImplicit()};
504 CXIdxClientASTFile astFile
= CB
.importedASTFile(ClientData
, &Info
);
508 void CXIndexDataConsumer::importedPCH(FileEntryRef File
) {
509 if (!CB
.importedASTFile
)
512 CXIdxImportedASTFileInfo Info
= {
513 cxfile::makeCXFile(File
),
515 getIndexLoc(SourceLocation()),
518 CXIdxClientASTFile astFile
= CB
.importedASTFile(ClientData
, &Info
);
522 void CXIndexDataConsumer::startedTranslationUnit() {
523 CXIdxClientContainer idxCont
= nullptr;
524 if (CB
.startedTranslationUnit
)
525 idxCont
= CB
.startedTranslationUnit(ClientData
, nullptr);
526 addContainerInMap(Ctx
->getTranslationUnitDecl(), idxCont
);
529 void CXIndexDataConsumer::indexDiagnostics() {
530 if (!hasDiagnosticCallback())
533 CXDiagnosticSetImpl
*DiagSet
= cxdiag::lazyCreateDiags(getCXTU());
534 handleDiagnosticSet(DiagSet
);
537 void CXIndexDataConsumer::handleDiagnosticSet(CXDiagnostic CXDiagSet
) {
541 CB
.diagnostic(ClientData
, CXDiagSet
, nullptr);
544 bool CXIndexDataConsumer::handleDecl(const NamedDecl
*D
,
545 SourceLocation Loc
, CXCursor Cursor
,
547 const DeclContext
*LexicalDC
,
548 const DeclContext
*SemaDC
) {
549 if (!CB
.indexDeclaration
|| !D
)
551 if (D
->isImplicit() && shouldIgnoreIfImplicit(D
))
554 ScratchAlloc
SA(*this);
555 getEntityInfo(D
, DInfo
.EntInfo
, SA
);
556 if ((!shouldIndexFunctionLocalSymbols() && !DInfo
.EntInfo
.USR
)
561 LexicalDC
= D
->getLexicalDeclContext();
563 if (shouldSuppressRefs())
564 markEntityOccurrenceInFile(D
, Loc
);
566 DInfo
.entityInfo
= &DInfo
.EntInfo
;
567 DInfo
.cursor
= Cursor
;
568 DInfo
.loc
= getIndexLoc(Loc
);
569 DInfo
.isImplicit
= D
->isImplicit();
571 DInfo
.attributes
= DInfo
.EntInfo
.attributes
;
572 DInfo
.numAttributes
= DInfo
.EntInfo
.numAttributes
;
575 SemaDC
= D
->getDeclContext();
576 getContainerInfo(SemaDC
, DInfo
.SemanticContainer
);
577 DInfo
.semanticContainer
= &DInfo
.SemanticContainer
;
579 if (LexicalDC
== SemaDC
) {
580 DInfo
.lexicalContainer
= &DInfo
.SemanticContainer
;
581 } else if (isTemplateImplicitInstantiation(D
)) {
582 // Implicit instantiations have the lexical context of where they were
583 // instantiated first. We choose instead the semantic context because:
584 // 1) at the time that we see the instantiation we have not seen the
585 // function where it occurred yet.
586 // 2) the lexical context of the first instantiation is not useful
587 // information anyway.
588 DInfo
.lexicalContainer
= &DInfo
.SemanticContainer
;
590 getContainerInfo(LexicalDC
, DInfo
.LexicalContainer
);
591 DInfo
.lexicalContainer
= &DInfo
.LexicalContainer
;
594 if (DInfo
.isContainer
) {
595 getContainerInfo(getEntityContainer(D
), DInfo
.DeclAsContainer
);
596 DInfo
.declAsContainer
= &DInfo
.DeclAsContainer
;
599 CB
.indexDeclaration(ClientData
, &DInfo
);
603 bool CXIndexDataConsumer::handleObjCContainer(const ObjCContainerDecl
*D
,
604 SourceLocation Loc
, CXCursor Cursor
,
605 ObjCContainerDeclInfo
&ContDInfo
) {
606 ContDInfo
.ObjCContDeclInfo
.declInfo
= &ContDInfo
;
607 return handleDecl(D
, Loc
, Cursor
, ContDInfo
);
610 bool CXIndexDataConsumer::handleFunction(const FunctionDecl
*D
) {
611 bool isDef
= D
->isThisDeclarationADefinition();
612 bool isContainer
= isDef
;
613 bool isSkipped
= false;
614 if (D
->hasSkippedBody()) {
620 DeclInfo
DInfo(!D
->isFirstDecl(), isDef
, isContainer
);
622 DInfo
.flags
|= CXIdxDeclFlag_Skipped
;
623 return handleDecl(D
, D
->getLocation(), getCursor(D
), DInfo
);
626 bool CXIndexDataConsumer::handleVar(const VarDecl
*D
) {
627 DeclInfo
DInfo(!D
->isFirstDecl(), D
->isThisDeclarationADefinition(),
628 /*isContainer=*/false);
629 return handleDecl(D
, D
->getLocation(), getCursor(D
), DInfo
);
632 bool CXIndexDataConsumer::handleField(const FieldDecl
*D
) {
633 DeclInfo
DInfo(/*isRedeclaration=*/false, /*isDefinition=*/true,
634 /*isContainer=*/false);
635 return handleDecl(D
, D
->getLocation(), getCursor(D
), DInfo
);
638 bool CXIndexDataConsumer::handleEnumerator(const EnumConstantDecl
*D
) {
639 DeclInfo
DInfo(/*isRedeclaration=*/false, /*isDefinition=*/true,
640 /*isContainer=*/false);
641 return handleDecl(D
, D
->getLocation(), getCursor(D
), DInfo
);
644 bool CXIndexDataConsumer::handleTagDecl(const TagDecl
*D
) {
645 if (const CXXRecordDecl
*CXXRD
= dyn_cast
<CXXRecordDecl
>(D
))
646 return handleCXXRecordDecl(CXXRD
, D
);
648 DeclInfo
DInfo(!D
->isFirstDecl(), D
->isThisDeclarationADefinition(),
649 D
->isThisDeclarationADefinition());
650 return handleDecl(D
, D
->getLocation(), getCursor(D
), DInfo
);
653 bool CXIndexDataConsumer::handleTypedefName(const TypedefNameDecl
*D
) {
654 DeclInfo
DInfo(!D
->isFirstDecl(), /*isDefinition=*/true,
655 /*isContainer=*/false);
656 return handleDecl(D
, D
->getLocation(), getCursor(D
), DInfo
);
659 bool CXIndexDataConsumer::handleObjCInterface(const ObjCInterfaceDecl
*D
) {
660 // For @class forward declarations, suppress them the same way as references.
661 if (!D
->isThisDeclarationADefinition()) {
662 if (shouldSuppressRefs() && markEntityOccurrenceInFile(D
, D
->getLocation()))
663 return false; // already occurred.
665 // FIXME: This seems like the wrong definition for redeclaration.
666 bool isRedeclaration
= D
->hasDefinition() || D
->getPreviousDecl();
667 ObjCContainerDeclInfo
ContDInfo(/*isForwardRef=*/true, isRedeclaration
,
668 /*isImplementation=*/false);
669 return handleObjCContainer(D
, D
->getLocation(),
670 MakeCursorObjCClassRef(D
, D
->getLocation(),
675 ScratchAlloc
SA(*this);
677 CXIdxBaseClassInfo BaseClass
;
678 EntityInfo BaseEntity
;
679 BaseClass
.cursor
= clang_getNullCursor();
680 if (ObjCInterfaceDecl
*SuperD
= D
->getSuperClass()) {
681 getEntityInfo(SuperD
, BaseEntity
, SA
);
682 SourceLocation SuperLoc
= D
->getSuperClassLoc();
683 BaseClass
.base
= &BaseEntity
;
684 BaseClass
.cursor
= MakeCursorObjCSuperClassRef(SuperD
, SuperLoc
, CXTU
);
685 BaseClass
.loc
= getIndexLoc(SuperLoc
);
687 if (shouldSuppressRefs())
688 markEntityOccurrenceInFile(SuperD
, SuperLoc
);
691 ObjCProtocolList EmptyProtoList
;
692 ObjCProtocolListInfo
ProtInfo(D
->isThisDeclarationADefinition()
693 ? D
->getReferencedProtocols()
697 ObjCInterfaceDeclInfo
InterInfo(D
);
698 InterInfo
.ObjCProtoListInfo
= ProtInfo
.getListInfo();
699 InterInfo
.ObjCInterDeclInfo
.containerInfo
= &InterInfo
.ObjCContDeclInfo
;
700 InterInfo
.ObjCInterDeclInfo
.superInfo
= D
->getSuperClass() ? &BaseClass
702 InterInfo
.ObjCInterDeclInfo
.protocols
= &InterInfo
.ObjCProtoListInfo
;
704 return handleObjCContainer(D
, D
->getLocation(), getCursor(D
), InterInfo
);
707 bool CXIndexDataConsumer::handleObjCImplementation(
708 const ObjCImplementationDecl
*D
) {
709 ObjCContainerDeclInfo
ContDInfo(/*isForwardRef=*/false,
710 /*isRedeclaration=*/true,
711 /*isImplementation=*/true);
712 return handleObjCContainer(D
, D
->getLocation(), getCursor(D
), ContDInfo
);
715 bool CXIndexDataConsumer::handleObjCProtocol(const ObjCProtocolDecl
*D
) {
716 if (!D
->isThisDeclarationADefinition()) {
717 if (shouldSuppressRefs() && markEntityOccurrenceInFile(D
, D
->getLocation()))
718 return false; // already occurred.
720 // FIXME: This seems like the wrong definition for redeclaration.
721 bool isRedeclaration
= D
->hasDefinition() || D
->getPreviousDecl();
722 ObjCContainerDeclInfo
ContDInfo(/*isForwardRef=*/true,
724 /*isImplementation=*/false);
725 return handleObjCContainer(D
, D
->getLocation(),
726 MakeCursorObjCProtocolRef(D
, D
->getLocation(),
731 ScratchAlloc
SA(*this);
732 ObjCProtocolList EmptyProtoList
;
733 ObjCProtocolListInfo
ProtListInfo(D
->isThisDeclarationADefinition()
734 ? D
->getReferencedProtocols()
738 ObjCProtocolDeclInfo
ProtInfo(D
);
739 ProtInfo
.ObjCProtoRefListInfo
= ProtListInfo
.getListInfo();
741 return handleObjCContainer(D
, D
->getLocation(), getCursor(D
), ProtInfo
);
744 bool CXIndexDataConsumer::handleObjCCategory(const ObjCCategoryDecl
*D
) {
745 ScratchAlloc
SA(*this);
747 ObjCCategoryDeclInfo
CatDInfo(/*isImplementation=*/false);
748 EntityInfo ClassEntity
;
749 const ObjCInterfaceDecl
*IFaceD
= D
->getClassInterface();
750 SourceLocation ClassLoc
= D
->getLocation();
751 SourceLocation CategoryLoc
= D
->IsClassExtension() ? ClassLoc
752 : D
->getCategoryNameLoc();
753 getEntityInfo(IFaceD
, ClassEntity
, SA
);
755 if (shouldSuppressRefs())
756 markEntityOccurrenceInFile(IFaceD
, ClassLoc
);
758 ObjCProtocolListInfo
ProtInfo(D
->getReferencedProtocols(), *this, SA
);
760 CatDInfo
.ObjCCatDeclInfo
.containerInfo
= &CatDInfo
.ObjCContDeclInfo
;
762 CatDInfo
.ObjCCatDeclInfo
.objcClass
= &ClassEntity
;
763 CatDInfo
.ObjCCatDeclInfo
.classCursor
=
764 MakeCursorObjCClassRef(IFaceD
, ClassLoc
, CXTU
);
766 CatDInfo
.ObjCCatDeclInfo
.objcClass
= nullptr;
767 CatDInfo
.ObjCCatDeclInfo
.classCursor
= clang_getNullCursor();
769 CatDInfo
.ObjCCatDeclInfo
.classLoc
= getIndexLoc(ClassLoc
);
770 CatDInfo
.ObjCProtoListInfo
= ProtInfo
.getListInfo();
771 CatDInfo
.ObjCCatDeclInfo
.protocols
= &CatDInfo
.ObjCProtoListInfo
;
773 return handleObjCContainer(D
, CategoryLoc
, getCursor(D
), CatDInfo
);
776 bool CXIndexDataConsumer::handleObjCCategoryImpl(const ObjCCategoryImplDecl
*D
) {
777 ScratchAlloc
SA(*this);
779 const ObjCCategoryDecl
*CatD
= D
->getCategoryDecl();
780 ObjCCategoryDeclInfo
CatDInfo(/*isImplementation=*/true);
781 EntityInfo ClassEntity
;
782 const ObjCInterfaceDecl
*IFaceD
= CatD
->getClassInterface();
783 SourceLocation ClassLoc
= D
->getLocation();
784 SourceLocation CategoryLoc
= D
->getCategoryNameLoc();
785 getEntityInfo(IFaceD
, ClassEntity
, SA
);
787 if (shouldSuppressRefs())
788 markEntityOccurrenceInFile(IFaceD
, ClassLoc
);
790 CatDInfo
.ObjCCatDeclInfo
.containerInfo
= &CatDInfo
.ObjCContDeclInfo
;
792 CatDInfo
.ObjCCatDeclInfo
.objcClass
= &ClassEntity
;
793 CatDInfo
.ObjCCatDeclInfo
.classCursor
=
794 MakeCursorObjCClassRef(IFaceD
, ClassLoc
, CXTU
);
796 CatDInfo
.ObjCCatDeclInfo
.objcClass
= nullptr;
797 CatDInfo
.ObjCCatDeclInfo
.classCursor
= clang_getNullCursor();
799 CatDInfo
.ObjCCatDeclInfo
.classLoc
= getIndexLoc(ClassLoc
);
800 CatDInfo
.ObjCCatDeclInfo
.protocols
= nullptr;
802 return handleObjCContainer(D
, CategoryLoc
, getCursor(D
), CatDInfo
);
805 bool CXIndexDataConsumer::handleObjCMethod(const ObjCMethodDecl
*D
,
806 SourceLocation Loc
) {
807 bool isDef
= D
->isThisDeclarationADefinition();
808 bool isContainer
= isDef
;
809 bool isSkipped
= false;
810 if (D
->hasSkippedBody()) {
816 DeclInfo
DInfo(!D
->isCanonicalDecl(), isDef
, isContainer
);
818 DInfo
.flags
|= CXIdxDeclFlag_Skipped
;
819 return handleDecl(D
, Loc
, getCursor(D
), DInfo
);
822 bool CXIndexDataConsumer::handleSynthesizedObjCProperty(
823 const ObjCPropertyImplDecl
*D
) {
824 ObjCPropertyDecl
*PD
= D
->getPropertyDecl();
825 auto *DC
= D
->getDeclContext();
826 return handleReference(PD
, D
->getLocation(), getCursor(D
),
827 dyn_cast
<NamedDecl
>(DC
), DC
);
830 bool CXIndexDataConsumer::handleSynthesizedObjCMethod(const ObjCMethodDecl
*D
,
832 const DeclContext
*LexicalDC
) {
833 DeclInfo
DInfo(/*isRedeclaration=*/true, /*isDefinition=*/true,
834 /*isContainer=*/false);
835 return handleDecl(D
, Loc
, getCursor(D
), DInfo
, LexicalDC
, D
->getDeclContext());
838 bool CXIndexDataConsumer::handleObjCProperty(const ObjCPropertyDecl
*D
) {
839 ScratchAlloc
SA(*this);
841 ObjCPropertyDeclInfo DInfo
;
842 EntityInfo GetterEntity
;
843 EntityInfo SetterEntity
;
845 DInfo
.ObjCPropDeclInfo
.declInfo
= &DInfo
;
847 if (ObjCMethodDecl
*Getter
= D
->getGetterMethodDecl()) {
848 getEntityInfo(Getter
, GetterEntity
, SA
);
849 DInfo
.ObjCPropDeclInfo
.getter
= &GetterEntity
;
851 DInfo
.ObjCPropDeclInfo
.getter
= nullptr;
853 if (ObjCMethodDecl
*Setter
= D
->getSetterMethodDecl()) {
854 getEntityInfo(Setter
, SetterEntity
, SA
);
855 DInfo
.ObjCPropDeclInfo
.setter
= &SetterEntity
;
857 DInfo
.ObjCPropDeclInfo
.setter
= nullptr;
860 return handleDecl(D
, D
->getLocation(), getCursor(D
), DInfo
);
863 bool CXIndexDataConsumer::handleNamespace(const NamespaceDecl
*D
) {
864 DeclInfo
DInfo(/*isRedeclaration=*/!D
->isFirstDecl(),
865 /*isDefinition=*/true,
866 /*isContainer=*/true);
867 return handleDecl(D
, D
->getLocation(), getCursor(D
), DInfo
);
870 bool CXIndexDataConsumer::handleClassTemplate(const ClassTemplateDecl
*D
) {
871 return handleCXXRecordDecl(D
->getTemplatedDecl(), D
);
874 bool CXIndexDataConsumer::handleFunctionTemplate(const FunctionTemplateDecl
*D
) {
875 DeclInfo
DInfo(/*isRedeclaration=*/!D
->isCanonicalDecl(),
876 /*isDefinition=*/D
->isThisDeclarationADefinition(),
877 /*isContainer=*/D
->isThisDeclarationADefinition());
878 return handleDecl(D
, D
->getLocation(), getCursor(D
), DInfo
);
881 bool CXIndexDataConsumer::handleTypeAliasTemplate(const TypeAliasTemplateDecl
*D
) {
882 DeclInfo
DInfo(/*isRedeclaration=*/!D
->isCanonicalDecl(),
883 /*isDefinition=*/true, /*isContainer=*/false);
884 return handleDecl(D
, D
->getLocation(), getCursor(D
), DInfo
);
887 bool CXIndexDataConsumer::handleConcept(const ConceptDecl
*D
) {
888 DeclInfo
DInfo(/*isRedeclaration=*/!D
->isCanonicalDecl(),
889 /*isDefinition=*/true, /*isContainer=*/false);
890 return handleDecl(D
, D
->getLocation(), getCursor(D
), DInfo
);
893 bool CXIndexDataConsumer::handleReference(const NamedDecl
*D
, SourceLocation Loc
,
895 const NamedDecl
*Parent
,
896 const DeclContext
*DC
,
898 CXIdxEntityRefKind Kind
,
900 if (!CB
.indexEntityReference
)
907 if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalDecl(D
))
909 if (isNotFromSourceFile(D
->getLocation()))
911 if (D
->isImplicit() && shouldIgnoreIfImplicit(D
))
914 if (shouldSuppressRefs()) {
915 if (markEntityOccurrenceInFile(D
, Loc
))
916 return false; // already occurred.
919 ScratchAlloc
SA(*this);
920 EntityInfo RefEntity
, ParentEntity
;
921 getEntityInfo(D
, RefEntity
, SA
);
925 getEntityInfo(Parent
, ParentEntity
, SA
);
927 ContainerInfo Container
;
928 getContainerInfo(DC
, Container
);
930 CXIdxEntityRefInfo Info
= { Kind
,
934 Parent
? &ParentEntity
: nullptr,
937 CB
.indexEntityReference(ClientData
, &Info
);
941 bool CXIndexDataConsumer::isNotFromSourceFile(SourceLocation Loc
) const {
944 SourceManager
&SM
= Ctx
->getSourceManager();
945 SourceLocation FileLoc
= SM
.getFileLoc(Loc
);
946 FileID FID
= SM
.getFileID(FileLoc
);
947 return SM
.getFileEntryForID(FID
) == nullptr;
950 void CXIndexDataConsumer::addContainerInMap(const DeclContext
*DC
,
951 CXIdxClientContainer container
) {
955 // Allow changing the container of a previously seen DeclContext so we
956 // can handle invalid user code, like a function re-definition.
958 ContainerMap
[DC
] = container
;
960 ContainerMap
.erase(DC
);
963 CXIdxClientEntity
CXIndexDataConsumer::getClientEntity(const Decl
*D
) const {
964 return D
? EntityMap
.lookup(D
) : nullptr;
967 void CXIndexDataConsumer::setClientEntity(const Decl
*D
, CXIdxClientEntity client
) {
970 EntityMap
[D
] = client
;
973 bool CXIndexDataConsumer::handleCXXRecordDecl(const CXXRecordDecl
*RD
,
974 const NamedDecl
*OrigD
) {
975 if (RD
->isThisDeclarationADefinition()) {
976 ScratchAlloc
SA(*this);
977 CXXClassDeclInfo
CXXDInfo(/*isRedeclaration=*/!OrigD
->isCanonicalDecl(),
978 /*isDefinition=*/RD
->isThisDeclarationADefinition());
979 CXXBasesListInfo
BaseList(RD
, *this, SA
);
980 CXXDInfo
.CXXClassInfo
.declInfo
= &CXXDInfo
;
981 CXXDInfo
.CXXClassInfo
.bases
= BaseList
.getBases();
982 CXXDInfo
.CXXClassInfo
.numBases
= BaseList
.getNumBases();
984 if (shouldSuppressRefs()) {
985 // Go through bases and mark them as referenced.
986 for (unsigned i
= 0, e
= BaseList
.getNumBases(); i
!= e
; ++i
) {
987 const CXIdxBaseClassInfo
*baseInfo
= BaseList
.getBases()[i
];
988 if (baseInfo
->base
) {
989 const NamedDecl
*BaseD
= BaseList
.BaseEntities
[i
].Dcl
;
991 Loc
= SourceLocation::getFromRawEncoding(baseInfo
->loc
.int_data
);
992 markEntityOccurrenceInFile(BaseD
, Loc
);
997 return handleDecl(OrigD
, OrigD
->getLocation(), getCursor(OrigD
), CXXDInfo
);
1000 DeclInfo
DInfo(/*isRedeclaration=*/!OrigD
->isCanonicalDecl(),
1001 /*isDefinition=*/RD
->isThisDeclarationADefinition(),
1002 /*isContainer=*/RD
->isThisDeclarationADefinition());
1003 return handleDecl(OrigD
, OrigD
->getLocation(), getCursor(OrigD
), DInfo
);
1006 bool CXIndexDataConsumer::markEntityOccurrenceInFile(const NamedDecl
*D
,
1007 SourceLocation Loc
) {
1008 if (!D
|| Loc
.isInvalid())
1011 SourceManager
&SM
= Ctx
->getSourceManager();
1012 D
= getEntityDecl(D
);
1014 std::pair
<FileID
, unsigned> LocInfo
= SM
.getDecomposedLoc(SM
.getFileLoc(Loc
));
1015 FileID FID
= LocInfo
.first
;
1016 if (FID
.isInvalid())
1019 const FileEntry
*FE
= SM
.getFileEntryForID(FID
);
1022 RefFileOccurrence
RefOccur(FE
, D
);
1023 std::pair
<llvm::DenseSet
<RefFileOccurrence
>::iterator
, bool>
1024 res
= RefFileOccurrences
.insert(RefOccur
);
1025 return !res
.second
; // already in map
1028 const NamedDecl
*CXIndexDataConsumer::getEntityDecl(const NamedDecl
*D
) const {
1030 D
= cast
<NamedDecl
>(D
->getCanonicalDecl());
1032 if (const ObjCImplementationDecl
*
1033 ImplD
= dyn_cast
<ObjCImplementationDecl
>(D
)) {
1034 return getEntityDecl(ImplD
->getClassInterface());
1036 } else if (const ObjCCategoryImplDecl
*
1037 CatImplD
= dyn_cast
<ObjCCategoryImplDecl
>(D
)) {
1038 return getEntityDecl(CatImplD
->getCategoryDecl());
1039 } else if (const FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(D
)) {
1040 if (FunctionTemplateDecl
*TemplD
= FD
->getDescribedFunctionTemplate())
1041 return getEntityDecl(TemplD
);
1042 } else if (const CXXRecordDecl
*RD
= dyn_cast
<CXXRecordDecl
>(D
)) {
1043 if (ClassTemplateDecl
*TemplD
= RD
->getDescribedClassTemplate())
1044 return getEntityDecl(TemplD
);
1051 CXIndexDataConsumer::getEntityContainer(const Decl
*D
) const {
1052 const DeclContext
*DC
= dyn_cast
<DeclContext
>(D
);
1056 if (const ClassTemplateDecl
*ClassTempl
= dyn_cast
<ClassTemplateDecl
>(D
)) {
1057 DC
= ClassTempl
->getTemplatedDecl();
1058 } else if (const FunctionTemplateDecl
*
1059 FuncTempl
= dyn_cast
<FunctionTemplateDecl
>(D
)) {
1060 DC
= FuncTempl
->getTemplatedDecl();
1066 CXIdxClientContainer
1067 CXIndexDataConsumer::getClientContainerForDC(const DeclContext
*DC
) const {
1068 return DC
? ContainerMap
.lookup(DC
) : nullptr;
1071 CXIdxClientFile
CXIndexDataConsumer::getIndexFile(OptionalFileEntryRef File
) {
1072 return File
? FileMap
.lookup(*File
) : nullptr;
1075 CXIdxLoc
CXIndexDataConsumer::getIndexLoc(SourceLocation Loc
) const {
1076 CXIdxLoc idxLoc
= { {nullptr, nullptr}, 0 };
1077 if (Loc
.isInvalid())
1080 idxLoc
.ptr_data
[0] = const_cast<CXIndexDataConsumer
*>(this);
1081 idxLoc
.int_data
= Loc
.getRawEncoding();
1085 void CXIndexDataConsumer::translateLoc(SourceLocation Loc
,
1086 CXIdxClientFile
*indexFile
, CXFile
*file
,
1087 unsigned *line
, unsigned *column
,
1089 if (Loc
.isInvalid())
1092 SourceManager
&SM
= Ctx
->getSourceManager();
1093 Loc
= SM
.getFileLoc(Loc
);
1095 std::pair
<FileID
, unsigned> LocInfo
= SM
.getDecomposedLoc(Loc
);
1096 FileID FID
= LocInfo
.first
;
1097 unsigned FileOffset
= LocInfo
.second
;
1099 if (FID
.isInvalid())
1102 OptionalFileEntryRef FE
= SM
.getFileEntryRefForID(FID
);
1104 *indexFile
= getIndexFile(FE
);
1106 *file
= cxfile::makeCXFile(FE
);
1108 *line
= SM
.getLineNumber(FID
, FileOffset
);
1110 *column
= SM
.getColumnNumber(FID
, FileOffset
);
1112 *offset
= FileOffset
;
1115 static CXIdxEntityKind
getEntityKindFromSymbolKind(SymbolKind K
, SymbolLanguage L
);
1116 static CXIdxEntityCXXTemplateKind
1117 getEntityKindFromSymbolProperties(SymbolPropertySet K
);
1118 static CXIdxEntityLanguage
getEntityLangFromSymbolLang(SymbolLanguage L
);
1120 void CXIndexDataConsumer::getEntityInfo(const NamedDecl
*D
,
1121 EntityInfo
&EntityInfo
,
1126 D
= getEntityDecl(D
);
1127 EntityInfo
.cursor
= getCursor(D
);
1129 EntityInfo
.IndexCtx
= this;
1131 SymbolInfo SymInfo
= getSymbolInfo(D
);
1132 EntityInfo
.kind
= getEntityKindFromSymbolKind(SymInfo
.Kind
, SymInfo
.Lang
);
1133 EntityInfo
.templateKind
= getEntityKindFromSymbolProperties(SymInfo
.Properties
);
1134 EntityInfo
.lang
= getEntityLangFromSymbolLang(SymInfo
.Lang
);
1136 if (D
->hasAttrs()) {
1137 EntityInfo
.AttrList
= AttrListInfo::create(D
, *this);
1138 EntityInfo
.attributes
= EntityInfo
.AttrList
->getAttrs();
1139 EntityInfo
.numAttributes
= EntityInfo
.AttrList
->getNumAttrs();
1142 if (EntityInfo
.kind
== CXIdxEntity_Unexposed
)
1145 if (IdentifierInfo
*II
= D
->getIdentifier()) {
1146 EntityInfo
.name
= SA
.toCStr(II
->getName());
1148 } else if (isa
<TagDecl
>(D
) || isa
<FieldDecl
>(D
) || isa
<NamespaceDecl
>(D
)) {
1149 EntityInfo
.name
= nullptr; // anonymous tag/field/namespace.
1152 SmallString
<256> StrBuf
;
1154 llvm::raw_svector_ostream
OS(StrBuf
);
1157 EntityInfo
.name
= SA
.copyCStr(StrBuf
.str());
1161 SmallString
<512> StrBuf
;
1162 bool Ignore
= getDeclCursorUSR(D
, StrBuf
);
1164 EntityInfo
.USR
= nullptr;
1166 EntityInfo
.USR
= SA
.copyCStr(StrBuf
.str());
1171 void CXIndexDataConsumer::getContainerInfo(const DeclContext
*DC
,
1172 ContainerInfo
&ContInfo
) {
1173 ContInfo
.cursor
= getCursor(cast
<Decl
>(DC
));
1175 ContInfo
.IndexCtx
= this;
1178 CXCursor
CXIndexDataConsumer::getRefCursor(const NamedDecl
*D
, SourceLocation Loc
) {
1179 if (const TypeDecl
*TD
= dyn_cast
<TypeDecl
>(D
))
1180 return MakeCursorTypeRef(TD
, Loc
, CXTU
);
1181 if (const ObjCInterfaceDecl
*ID
= dyn_cast
<ObjCInterfaceDecl
>(D
))
1182 return MakeCursorObjCClassRef(ID
, Loc
, CXTU
);
1183 if (const ObjCProtocolDecl
*PD
= dyn_cast
<ObjCProtocolDecl
>(D
))
1184 return MakeCursorObjCProtocolRef(PD
, Loc
, CXTU
);
1185 if (const TemplateDecl
*Template
= dyn_cast
<TemplateDecl
>(D
))
1186 return MakeCursorTemplateRef(Template
, Loc
, CXTU
);
1187 if (const NamespaceDecl
*Namespace
= dyn_cast
<NamespaceDecl
>(D
))
1188 return MakeCursorNamespaceRef(Namespace
, Loc
, CXTU
);
1189 if (const NamespaceAliasDecl
*Namespace
= dyn_cast
<NamespaceAliasDecl
>(D
))
1190 return MakeCursorNamespaceRef(Namespace
, Loc
, CXTU
);
1191 if (const FieldDecl
*Field
= dyn_cast
<FieldDecl
>(D
))
1192 return MakeCursorMemberRef(Field
, Loc
, CXTU
);
1193 if (const VarDecl
*Var
= dyn_cast
<VarDecl
>(D
))
1194 return MakeCursorVariableRef(Var
, Loc
, CXTU
);
1196 return clang_getNullCursor();
1199 bool CXIndexDataConsumer::shouldIgnoreIfImplicit(const Decl
*D
) {
1200 if (isa
<ObjCInterfaceDecl
>(D
))
1202 if (isa
<ObjCCategoryDecl
>(D
))
1204 if (isa
<ObjCIvarDecl
>(D
))
1206 if (isa
<ObjCMethodDecl
>(D
))
1208 if (isa
<ImportDecl
>(D
))
1213 bool CXIndexDataConsumer::isTemplateImplicitInstantiation(const Decl
*D
) {
1214 if (const ClassTemplateSpecializationDecl
*
1215 SD
= dyn_cast
<ClassTemplateSpecializationDecl
>(D
)) {
1216 return SD
->getSpecializationKind() == TSK_ImplicitInstantiation
;
1218 if (const FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(D
)) {
1219 return FD
->getTemplateSpecializationKind() == TSK_ImplicitInstantiation
;
1224 static CXIdxEntityKind
getEntityKindFromSymbolKind(SymbolKind K
, SymbolLanguage Lang
) {
1226 case SymbolKind::Unknown
:
1227 case SymbolKind::Module
:
1228 case SymbolKind::Macro
:
1229 case SymbolKind::ClassProperty
:
1230 case SymbolKind::Using
:
1231 case SymbolKind::TemplateTypeParm
:
1232 case SymbolKind::TemplateTemplateParm
:
1233 case SymbolKind::NonTypeTemplateParm
:
1234 return CXIdxEntity_Unexposed
;
1236 case SymbolKind::Enum
: return CXIdxEntity_Enum
;
1237 case SymbolKind::Struct
: return CXIdxEntity_Struct
;
1238 case SymbolKind::Union
: return CXIdxEntity_Union
;
1239 case SymbolKind::TypeAlias
:
1240 if (Lang
== SymbolLanguage::CXX
)
1241 return CXIdxEntity_CXXTypeAlias
;
1242 return CXIdxEntity_Typedef
;
1243 case SymbolKind::Function
: return CXIdxEntity_Function
;
1244 case SymbolKind::Variable
: return CXIdxEntity_Variable
;
1245 case SymbolKind::Field
:
1246 if (Lang
== SymbolLanguage::ObjC
)
1247 return CXIdxEntity_ObjCIvar
;
1248 return CXIdxEntity_Field
;
1249 case SymbolKind::EnumConstant
: return CXIdxEntity_EnumConstant
;
1250 case SymbolKind::Class
:
1251 if (Lang
== SymbolLanguage::ObjC
)
1252 return CXIdxEntity_ObjCClass
;
1253 return CXIdxEntity_CXXClass
;
1254 case SymbolKind::Protocol
:
1255 if (Lang
== SymbolLanguage::ObjC
)
1256 return CXIdxEntity_ObjCProtocol
;
1257 return CXIdxEntity_CXXInterface
;
1258 case SymbolKind::Extension
: return CXIdxEntity_ObjCCategory
;
1259 case SymbolKind::InstanceMethod
:
1260 if (Lang
== SymbolLanguage::ObjC
)
1261 return CXIdxEntity_ObjCInstanceMethod
;
1262 return CXIdxEntity_CXXInstanceMethod
;
1263 case SymbolKind::ClassMethod
: return CXIdxEntity_ObjCClassMethod
;
1264 case SymbolKind::StaticMethod
: return CXIdxEntity_CXXStaticMethod
;
1265 case SymbolKind::InstanceProperty
: return CXIdxEntity_ObjCProperty
;
1266 case SymbolKind::StaticProperty
: return CXIdxEntity_CXXStaticVariable
;
1267 case SymbolKind::Namespace
: return CXIdxEntity_CXXNamespace
;
1268 case SymbolKind::NamespaceAlias
: return CXIdxEntity_CXXNamespaceAlias
;
1269 case SymbolKind::Constructor
: return CXIdxEntity_CXXConstructor
;
1270 case SymbolKind::Destructor
: return CXIdxEntity_CXXDestructor
;
1271 case SymbolKind::ConversionFunction
: return CXIdxEntity_CXXConversionFunction
;
1272 case SymbolKind::Parameter
: return CXIdxEntity_Variable
;
1273 case SymbolKind::Concept
:
1274 return CXIdxEntity_CXXConcept
;
1276 llvm_unreachable("invalid symbol kind");
1279 static CXIdxEntityCXXTemplateKind
1280 getEntityKindFromSymbolProperties(SymbolPropertySet K
) {
1281 if (K
& (SymbolPropertySet
)SymbolProperty::TemplatePartialSpecialization
)
1282 return CXIdxEntity_TemplatePartialSpecialization
;
1283 if (K
& (SymbolPropertySet
)SymbolProperty::TemplateSpecialization
)
1284 return CXIdxEntity_TemplateSpecialization
;
1285 if (K
& (SymbolPropertySet
)SymbolProperty::Generic
)
1286 return CXIdxEntity_Template
;
1287 return CXIdxEntity_NonTemplate
;
1290 static CXIdxEntityLanguage
getEntityLangFromSymbolLang(SymbolLanguage L
) {
1292 case SymbolLanguage::C
: return CXIdxEntityLang_C
;
1293 case SymbolLanguage::ObjC
: return CXIdxEntityLang_ObjC
;
1294 case SymbolLanguage::CXX
: return CXIdxEntityLang_CXX
;
1295 case SymbolLanguage::Swift
: return CXIdxEntityLang_Swift
;
1297 llvm_unreachable("invalid symbol language");