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()) {
435 case InternalLinkage
:
437 case VisibleNoLinkage
:
438 case UniqueExternalLinkage
:
439 llvm_unreachable("Not a sema linkage");
441 case ExternalLinkage
:
449 bool CXIndexDataConsumer::shouldAbort() {
452 return CB
.abortQuery(ClientData
, nullptr);
455 void CXIndexDataConsumer::enteredMainFile(OptionalFileEntryRef File
) {
456 if (File
&& CB
.enteredMainFile
) {
457 CXIdxClientFile idxFile
=
458 CB
.enteredMainFile(ClientData
, cxfile::makeCXFile(*File
), nullptr);
459 FileMap
[*File
] = idxFile
;
463 void CXIndexDataConsumer::ppIncludedFile(SourceLocation hashLoc
,
465 OptionalFileEntryRef File
,
466 bool isImport
, bool isAngled
,
467 bool isModuleImport
) {
468 if (!CB
.ppIncludedFile
)
471 const FileEntry
*FE
= File
? &File
->getFileEntry() : nullptr;
473 ScratchAlloc
SA(*this);
474 CXIdxIncludedFileInfo Info
= { getIndexLoc(hashLoc
),
476 cxfile::makeCXFile(File
),
477 isImport
, isAngled
, isModuleImport
};
478 CXIdxClientFile idxFile
= CB
.ppIncludedFile(ClientData
, &Info
);
479 FileMap
[FE
] = idxFile
;
482 void CXIndexDataConsumer::importedModule(const ImportDecl
*ImportD
) {
483 if (!CB
.importedASTFile
)
486 Module
*Mod
= ImportD
->getImportedModule();
490 // If the imported module is part of the top-level module that we're
491 // indexing, it doesn't correspond to an imported AST file.
492 // FIXME: This assumes that AST files and top-level modules directly
493 // correspond, which is unlikely to remain true forever.
494 if (Module
*SrcMod
= ImportD
->getImportedOwningModule())
495 if (SrcMod
->getTopLevelModule() == Mod
->getTopLevelModule())
498 OptionalFileEntryRef FE
= Mod
->getASTFile();
499 CXIdxImportedASTFileInfo Info
= {cxfile::makeCXFile(FE
), Mod
,
500 getIndexLoc(ImportD
->getLocation()),
501 ImportD
->isImplicit()};
502 CXIdxClientASTFile astFile
= CB
.importedASTFile(ClientData
, &Info
);
506 void CXIndexDataConsumer::importedPCH(FileEntryRef File
) {
507 if (!CB
.importedASTFile
)
510 CXIdxImportedASTFileInfo Info
= {
511 cxfile::makeCXFile(File
),
513 getIndexLoc(SourceLocation()),
516 CXIdxClientASTFile astFile
= CB
.importedASTFile(ClientData
, &Info
);
520 void CXIndexDataConsumer::startedTranslationUnit() {
521 CXIdxClientContainer idxCont
= nullptr;
522 if (CB
.startedTranslationUnit
)
523 idxCont
= CB
.startedTranslationUnit(ClientData
, nullptr);
524 addContainerInMap(Ctx
->getTranslationUnitDecl(), idxCont
);
527 void CXIndexDataConsumer::indexDiagnostics() {
528 if (!hasDiagnosticCallback())
531 CXDiagnosticSetImpl
*DiagSet
= cxdiag::lazyCreateDiags(getCXTU());
532 handleDiagnosticSet(DiagSet
);
535 void CXIndexDataConsumer::handleDiagnosticSet(CXDiagnostic CXDiagSet
) {
539 CB
.diagnostic(ClientData
, CXDiagSet
, nullptr);
542 bool CXIndexDataConsumer::handleDecl(const NamedDecl
*D
,
543 SourceLocation Loc
, CXCursor Cursor
,
545 const DeclContext
*LexicalDC
,
546 const DeclContext
*SemaDC
) {
547 if (!CB
.indexDeclaration
|| !D
)
549 if (D
->isImplicit() && shouldIgnoreIfImplicit(D
))
552 ScratchAlloc
SA(*this);
553 getEntityInfo(D
, DInfo
.EntInfo
, SA
);
554 if ((!shouldIndexFunctionLocalSymbols() && !DInfo
.EntInfo
.USR
)
559 LexicalDC
= D
->getLexicalDeclContext();
561 if (shouldSuppressRefs())
562 markEntityOccurrenceInFile(D
, Loc
);
564 DInfo
.entityInfo
= &DInfo
.EntInfo
;
565 DInfo
.cursor
= Cursor
;
566 DInfo
.loc
= getIndexLoc(Loc
);
567 DInfo
.isImplicit
= D
->isImplicit();
569 DInfo
.attributes
= DInfo
.EntInfo
.attributes
;
570 DInfo
.numAttributes
= DInfo
.EntInfo
.numAttributes
;
573 SemaDC
= D
->getDeclContext();
574 getContainerInfo(SemaDC
, DInfo
.SemanticContainer
);
575 DInfo
.semanticContainer
= &DInfo
.SemanticContainer
;
577 if (LexicalDC
== SemaDC
) {
578 DInfo
.lexicalContainer
= &DInfo
.SemanticContainer
;
579 } else if (isTemplateImplicitInstantiation(D
)) {
580 // Implicit instantiations have the lexical context of where they were
581 // instantiated first. We choose instead the semantic context because:
582 // 1) at the time that we see the instantiation we have not seen the
583 // function where it occurred yet.
584 // 2) the lexical context of the first instantiation is not useful
585 // information anyway.
586 DInfo
.lexicalContainer
= &DInfo
.SemanticContainer
;
588 getContainerInfo(LexicalDC
, DInfo
.LexicalContainer
);
589 DInfo
.lexicalContainer
= &DInfo
.LexicalContainer
;
592 if (DInfo
.isContainer
) {
593 getContainerInfo(getEntityContainer(D
), DInfo
.DeclAsContainer
);
594 DInfo
.declAsContainer
= &DInfo
.DeclAsContainer
;
597 CB
.indexDeclaration(ClientData
, &DInfo
);
601 bool CXIndexDataConsumer::handleObjCContainer(const ObjCContainerDecl
*D
,
602 SourceLocation Loc
, CXCursor Cursor
,
603 ObjCContainerDeclInfo
&ContDInfo
) {
604 ContDInfo
.ObjCContDeclInfo
.declInfo
= &ContDInfo
;
605 return handleDecl(D
, Loc
, Cursor
, ContDInfo
);
608 bool CXIndexDataConsumer::handleFunction(const FunctionDecl
*D
) {
609 bool isDef
= D
->isThisDeclarationADefinition();
610 bool isContainer
= isDef
;
611 bool isSkipped
= false;
612 if (D
->hasSkippedBody()) {
618 DeclInfo
DInfo(!D
->isFirstDecl(), isDef
, isContainer
);
620 DInfo
.flags
|= CXIdxDeclFlag_Skipped
;
621 return handleDecl(D
, D
->getLocation(), getCursor(D
), DInfo
);
624 bool CXIndexDataConsumer::handleVar(const VarDecl
*D
) {
625 DeclInfo
DInfo(!D
->isFirstDecl(), D
->isThisDeclarationADefinition(),
626 /*isContainer=*/false);
627 return handleDecl(D
, D
->getLocation(), getCursor(D
), DInfo
);
630 bool CXIndexDataConsumer::handleField(const FieldDecl
*D
) {
631 DeclInfo
DInfo(/*isRedeclaration=*/false, /*isDefinition=*/true,
632 /*isContainer=*/false);
633 return handleDecl(D
, D
->getLocation(), getCursor(D
), DInfo
);
636 bool CXIndexDataConsumer::handleEnumerator(const EnumConstantDecl
*D
) {
637 DeclInfo
DInfo(/*isRedeclaration=*/false, /*isDefinition=*/true,
638 /*isContainer=*/false);
639 return handleDecl(D
, D
->getLocation(), getCursor(D
), DInfo
);
642 bool CXIndexDataConsumer::handleTagDecl(const TagDecl
*D
) {
643 if (const CXXRecordDecl
*CXXRD
= dyn_cast
<CXXRecordDecl
>(D
))
644 return handleCXXRecordDecl(CXXRD
, D
);
646 DeclInfo
DInfo(!D
->isFirstDecl(), D
->isThisDeclarationADefinition(),
647 D
->isThisDeclarationADefinition());
648 return handleDecl(D
, D
->getLocation(), getCursor(D
), DInfo
);
651 bool CXIndexDataConsumer::handleTypedefName(const TypedefNameDecl
*D
) {
652 DeclInfo
DInfo(!D
->isFirstDecl(), /*isDefinition=*/true,
653 /*isContainer=*/false);
654 return handleDecl(D
, D
->getLocation(), getCursor(D
), DInfo
);
657 bool CXIndexDataConsumer::handleObjCInterface(const ObjCInterfaceDecl
*D
) {
658 // For @class forward declarations, suppress them the same way as references.
659 if (!D
->isThisDeclarationADefinition()) {
660 if (shouldSuppressRefs() && markEntityOccurrenceInFile(D
, D
->getLocation()))
661 return false; // already occurred.
663 // FIXME: This seems like the wrong definition for redeclaration.
664 bool isRedeclaration
= D
->hasDefinition() || D
->getPreviousDecl();
665 ObjCContainerDeclInfo
ContDInfo(/*isForwardRef=*/true, isRedeclaration
,
666 /*isImplementation=*/false);
667 return handleObjCContainer(D
, D
->getLocation(),
668 MakeCursorObjCClassRef(D
, D
->getLocation(),
673 ScratchAlloc
SA(*this);
675 CXIdxBaseClassInfo BaseClass
;
676 EntityInfo BaseEntity
;
677 BaseClass
.cursor
= clang_getNullCursor();
678 if (ObjCInterfaceDecl
*SuperD
= D
->getSuperClass()) {
679 getEntityInfo(SuperD
, BaseEntity
, SA
);
680 SourceLocation SuperLoc
= D
->getSuperClassLoc();
681 BaseClass
.base
= &BaseEntity
;
682 BaseClass
.cursor
= MakeCursorObjCSuperClassRef(SuperD
, SuperLoc
, CXTU
);
683 BaseClass
.loc
= getIndexLoc(SuperLoc
);
685 if (shouldSuppressRefs())
686 markEntityOccurrenceInFile(SuperD
, SuperLoc
);
689 ObjCProtocolList EmptyProtoList
;
690 ObjCProtocolListInfo
ProtInfo(D
->isThisDeclarationADefinition()
691 ? D
->getReferencedProtocols()
695 ObjCInterfaceDeclInfo
InterInfo(D
);
696 InterInfo
.ObjCProtoListInfo
= ProtInfo
.getListInfo();
697 InterInfo
.ObjCInterDeclInfo
.containerInfo
= &InterInfo
.ObjCContDeclInfo
;
698 InterInfo
.ObjCInterDeclInfo
.superInfo
= D
->getSuperClass() ? &BaseClass
700 InterInfo
.ObjCInterDeclInfo
.protocols
= &InterInfo
.ObjCProtoListInfo
;
702 return handleObjCContainer(D
, D
->getLocation(), getCursor(D
), InterInfo
);
705 bool CXIndexDataConsumer::handleObjCImplementation(
706 const ObjCImplementationDecl
*D
) {
707 ObjCContainerDeclInfo
ContDInfo(/*isForwardRef=*/false,
708 /*isRedeclaration=*/true,
709 /*isImplementation=*/true);
710 return handleObjCContainer(D
, D
->getLocation(), getCursor(D
), ContDInfo
);
713 bool CXIndexDataConsumer::handleObjCProtocol(const ObjCProtocolDecl
*D
) {
714 if (!D
->isThisDeclarationADefinition()) {
715 if (shouldSuppressRefs() && markEntityOccurrenceInFile(D
, D
->getLocation()))
716 return false; // already occurred.
718 // FIXME: This seems like the wrong definition for redeclaration.
719 bool isRedeclaration
= D
->hasDefinition() || D
->getPreviousDecl();
720 ObjCContainerDeclInfo
ContDInfo(/*isForwardRef=*/true,
722 /*isImplementation=*/false);
723 return handleObjCContainer(D
, D
->getLocation(),
724 MakeCursorObjCProtocolRef(D
, D
->getLocation(),
729 ScratchAlloc
SA(*this);
730 ObjCProtocolList EmptyProtoList
;
731 ObjCProtocolListInfo
ProtListInfo(D
->isThisDeclarationADefinition()
732 ? D
->getReferencedProtocols()
736 ObjCProtocolDeclInfo
ProtInfo(D
);
737 ProtInfo
.ObjCProtoRefListInfo
= ProtListInfo
.getListInfo();
739 return handleObjCContainer(D
, D
->getLocation(), getCursor(D
), ProtInfo
);
742 bool CXIndexDataConsumer::handleObjCCategory(const ObjCCategoryDecl
*D
) {
743 ScratchAlloc
SA(*this);
745 ObjCCategoryDeclInfo
CatDInfo(/*isImplementation=*/false);
746 EntityInfo ClassEntity
;
747 const ObjCInterfaceDecl
*IFaceD
= D
->getClassInterface();
748 SourceLocation ClassLoc
= D
->getLocation();
749 SourceLocation CategoryLoc
= D
->IsClassExtension() ? ClassLoc
750 : D
->getCategoryNameLoc();
751 getEntityInfo(IFaceD
, ClassEntity
, SA
);
753 if (shouldSuppressRefs())
754 markEntityOccurrenceInFile(IFaceD
, ClassLoc
);
756 ObjCProtocolListInfo
ProtInfo(D
->getReferencedProtocols(), *this, SA
);
758 CatDInfo
.ObjCCatDeclInfo
.containerInfo
= &CatDInfo
.ObjCContDeclInfo
;
760 CatDInfo
.ObjCCatDeclInfo
.objcClass
= &ClassEntity
;
761 CatDInfo
.ObjCCatDeclInfo
.classCursor
=
762 MakeCursorObjCClassRef(IFaceD
, ClassLoc
, CXTU
);
764 CatDInfo
.ObjCCatDeclInfo
.objcClass
= nullptr;
765 CatDInfo
.ObjCCatDeclInfo
.classCursor
= clang_getNullCursor();
767 CatDInfo
.ObjCCatDeclInfo
.classLoc
= getIndexLoc(ClassLoc
);
768 CatDInfo
.ObjCProtoListInfo
= ProtInfo
.getListInfo();
769 CatDInfo
.ObjCCatDeclInfo
.protocols
= &CatDInfo
.ObjCProtoListInfo
;
771 return handleObjCContainer(D
, CategoryLoc
, getCursor(D
), CatDInfo
);
774 bool CXIndexDataConsumer::handleObjCCategoryImpl(const ObjCCategoryImplDecl
*D
) {
775 ScratchAlloc
SA(*this);
777 const ObjCCategoryDecl
*CatD
= D
->getCategoryDecl();
778 ObjCCategoryDeclInfo
CatDInfo(/*isImplementation=*/true);
779 EntityInfo ClassEntity
;
780 const ObjCInterfaceDecl
*IFaceD
= CatD
->getClassInterface();
781 SourceLocation ClassLoc
= D
->getLocation();
782 SourceLocation CategoryLoc
= D
->getCategoryNameLoc();
783 getEntityInfo(IFaceD
, ClassEntity
, SA
);
785 if (shouldSuppressRefs())
786 markEntityOccurrenceInFile(IFaceD
, ClassLoc
);
788 CatDInfo
.ObjCCatDeclInfo
.containerInfo
= &CatDInfo
.ObjCContDeclInfo
;
790 CatDInfo
.ObjCCatDeclInfo
.objcClass
= &ClassEntity
;
791 CatDInfo
.ObjCCatDeclInfo
.classCursor
=
792 MakeCursorObjCClassRef(IFaceD
, ClassLoc
, CXTU
);
794 CatDInfo
.ObjCCatDeclInfo
.objcClass
= nullptr;
795 CatDInfo
.ObjCCatDeclInfo
.classCursor
= clang_getNullCursor();
797 CatDInfo
.ObjCCatDeclInfo
.classLoc
= getIndexLoc(ClassLoc
);
798 CatDInfo
.ObjCCatDeclInfo
.protocols
= nullptr;
800 return handleObjCContainer(D
, CategoryLoc
, getCursor(D
), CatDInfo
);
803 bool CXIndexDataConsumer::handleObjCMethod(const ObjCMethodDecl
*D
,
804 SourceLocation Loc
) {
805 bool isDef
= D
->isThisDeclarationADefinition();
806 bool isContainer
= isDef
;
807 bool isSkipped
= false;
808 if (D
->hasSkippedBody()) {
814 DeclInfo
DInfo(!D
->isCanonicalDecl(), isDef
, isContainer
);
816 DInfo
.flags
|= CXIdxDeclFlag_Skipped
;
817 return handleDecl(D
, Loc
, getCursor(D
), DInfo
);
820 bool CXIndexDataConsumer::handleSynthesizedObjCProperty(
821 const ObjCPropertyImplDecl
*D
) {
822 ObjCPropertyDecl
*PD
= D
->getPropertyDecl();
823 auto *DC
= D
->getDeclContext();
824 return handleReference(PD
, D
->getLocation(), getCursor(D
),
825 dyn_cast
<NamedDecl
>(DC
), DC
);
828 bool CXIndexDataConsumer::handleSynthesizedObjCMethod(const ObjCMethodDecl
*D
,
830 const DeclContext
*LexicalDC
) {
831 DeclInfo
DInfo(/*isRedeclaration=*/true, /*isDefinition=*/true,
832 /*isContainer=*/false);
833 return handleDecl(D
, Loc
, getCursor(D
), DInfo
, LexicalDC
, D
->getDeclContext());
836 bool CXIndexDataConsumer::handleObjCProperty(const ObjCPropertyDecl
*D
) {
837 ScratchAlloc
SA(*this);
839 ObjCPropertyDeclInfo DInfo
;
840 EntityInfo GetterEntity
;
841 EntityInfo SetterEntity
;
843 DInfo
.ObjCPropDeclInfo
.declInfo
= &DInfo
;
845 if (ObjCMethodDecl
*Getter
= D
->getGetterMethodDecl()) {
846 getEntityInfo(Getter
, GetterEntity
, SA
);
847 DInfo
.ObjCPropDeclInfo
.getter
= &GetterEntity
;
849 DInfo
.ObjCPropDeclInfo
.getter
= nullptr;
851 if (ObjCMethodDecl
*Setter
= D
->getSetterMethodDecl()) {
852 getEntityInfo(Setter
, SetterEntity
, SA
);
853 DInfo
.ObjCPropDeclInfo
.setter
= &SetterEntity
;
855 DInfo
.ObjCPropDeclInfo
.setter
= nullptr;
858 return handleDecl(D
, D
->getLocation(), getCursor(D
), DInfo
);
861 bool CXIndexDataConsumer::handleNamespace(const NamespaceDecl
*D
) {
862 DeclInfo
DInfo(/*isRedeclaration=*/!D
->isOriginalNamespace(),
863 /*isDefinition=*/true,
864 /*isContainer=*/true);
865 return handleDecl(D
, D
->getLocation(), getCursor(D
), DInfo
);
868 bool CXIndexDataConsumer::handleClassTemplate(const ClassTemplateDecl
*D
) {
869 return handleCXXRecordDecl(D
->getTemplatedDecl(), D
);
872 bool CXIndexDataConsumer::handleFunctionTemplate(const FunctionTemplateDecl
*D
) {
873 DeclInfo
DInfo(/*isRedeclaration=*/!D
->isCanonicalDecl(),
874 /*isDefinition=*/D
->isThisDeclarationADefinition(),
875 /*isContainer=*/D
->isThisDeclarationADefinition());
876 return handleDecl(D
, D
->getLocation(), getCursor(D
), DInfo
);
879 bool CXIndexDataConsumer::handleTypeAliasTemplate(const TypeAliasTemplateDecl
*D
) {
880 DeclInfo
DInfo(/*isRedeclaration=*/!D
->isCanonicalDecl(),
881 /*isDefinition=*/true, /*isContainer=*/false);
882 return handleDecl(D
, D
->getLocation(), getCursor(D
), DInfo
);
885 bool CXIndexDataConsumer::handleConcept(const ConceptDecl
*D
) {
886 DeclInfo
DInfo(/*isRedeclaration=*/!D
->isCanonicalDecl(),
887 /*isDefinition=*/true, /*isContainer=*/false);
888 return handleDecl(D
, D
->getLocation(), getCursor(D
), DInfo
);
891 bool CXIndexDataConsumer::handleReference(const NamedDecl
*D
, SourceLocation Loc
,
893 const NamedDecl
*Parent
,
894 const DeclContext
*DC
,
896 CXIdxEntityRefKind Kind
,
898 if (!CB
.indexEntityReference
)
905 if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalDecl(D
))
907 if (isNotFromSourceFile(D
->getLocation()))
909 if (D
->isImplicit() && shouldIgnoreIfImplicit(D
))
912 if (shouldSuppressRefs()) {
913 if (markEntityOccurrenceInFile(D
, Loc
))
914 return false; // already occurred.
917 ScratchAlloc
SA(*this);
918 EntityInfo RefEntity
, ParentEntity
;
919 getEntityInfo(D
, RefEntity
, SA
);
923 getEntityInfo(Parent
, ParentEntity
, SA
);
925 ContainerInfo Container
;
926 getContainerInfo(DC
, Container
);
928 CXIdxEntityRefInfo Info
= { Kind
,
932 Parent
? &ParentEntity
: nullptr,
935 CB
.indexEntityReference(ClientData
, &Info
);
939 bool CXIndexDataConsumer::isNotFromSourceFile(SourceLocation Loc
) const {
942 SourceManager
&SM
= Ctx
->getSourceManager();
943 SourceLocation FileLoc
= SM
.getFileLoc(Loc
);
944 FileID FID
= SM
.getFileID(FileLoc
);
945 return SM
.getFileEntryForID(FID
) == nullptr;
948 void CXIndexDataConsumer::addContainerInMap(const DeclContext
*DC
,
949 CXIdxClientContainer container
) {
953 ContainerMapTy::iterator I
= ContainerMap
.find(DC
);
954 if (I
== ContainerMap
.end()) {
956 ContainerMap
[DC
] = container
;
959 // Allow changing the container of a previously seen DeclContext so we
960 // can handle invalid user code, like a function re-definition.
962 I
->second
= container
;
964 ContainerMap
.erase(I
);
967 CXIdxClientEntity
CXIndexDataConsumer::getClientEntity(const Decl
*D
) const {
968 return D
? EntityMap
.lookup(D
) : nullptr;
971 void CXIndexDataConsumer::setClientEntity(const Decl
*D
, CXIdxClientEntity client
) {
974 EntityMap
[D
] = client
;
977 bool CXIndexDataConsumer::handleCXXRecordDecl(const CXXRecordDecl
*RD
,
978 const NamedDecl
*OrigD
) {
979 if (RD
->isThisDeclarationADefinition()) {
980 ScratchAlloc
SA(*this);
981 CXXClassDeclInfo
CXXDInfo(/*isRedeclaration=*/!OrigD
->isCanonicalDecl(),
982 /*isDefinition=*/RD
->isThisDeclarationADefinition());
983 CXXBasesListInfo
BaseList(RD
, *this, SA
);
984 CXXDInfo
.CXXClassInfo
.declInfo
= &CXXDInfo
;
985 CXXDInfo
.CXXClassInfo
.bases
= BaseList
.getBases();
986 CXXDInfo
.CXXClassInfo
.numBases
= BaseList
.getNumBases();
988 if (shouldSuppressRefs()) {
989 // Go through bases and mark them as referenced.
990 for (unsigned i
= 0, e
= BaseList
.getNumBases(); i
!= e
; ++i
) {
991 const CXIdxBaseClassInfo
*baseInfo
= BaseList
.getBases()[i
];
992 if (baseInfo
->base
) {
993 const NamedDecl
*BaseD
= BaseList
.BaseEntities
[i
].Dcl
;
995 Loc
= SourceLocation::getFromRawEncoding(baseInfo
->loc
.int_data
);
996 markEntityOccurrenceInFile(BaseD
, Loc
);
1001 return handleDecl(OrigD
, OrigD
->getLocation(), getCursor(OrigD
), CXXDInfo
);
1004 DeclInfo
DInfo(/*isRedeclaration=*/!OrigD
->isCanonicalDecl(),
1005 /*isDefinition=*/RD
->isThisDeclarationADefinition(),
1006 /*isContainer=*/RD
->isThisDeclarationADefinition());
1007 return handleDecl(OrigD
, OrigD
->getLocation(), getCursor(OrigD
), DInfo
);
1010 bool CXIndexDataConsumer::markEntityOccurrenceInFile(const NamedDecl
*D
,
1011 SourceLocation Loc
) {
1012 if (!D
|| Loc
.isInvalid())
1015 SourceManager
&SM
= Ctx
->getSourceManager();
1016 D
= getEntityDecl(D
);
1018 std::pair
<FileID
, unsigned> LocInfo
= SM
.getDecomposedLoc(SM
.getFileLoc(Loc
));
1019 FileID FID
= LocInfo
.first
;
1020 if (FID
.isInvalid())
1023 const FileEntry
*FE
= SM
.getFileEntryForID(FID
);
1026 RefFileOccurrence
RefOccur(FE
, D
);
1027 std::pair
<llvm::DenseSet
<RefFileOccurrence
>::iterator
, bool>
1028 res
= RefFileOccurrences
.insert(RefOccur
);
1029 return !res
.second
; // already in map
1032 const NamedDecl
*CXIndexDataConsumer::getEntityDecl(const NamedDecl
*D
) const {
1034 D
= cast
<NamedDecl
>(D
->getCanonicalDecl());
1036 if (const ObjCImplementationDecl
*
1037 ImplD
= dyn_cast
<ObjCImplementationDecl
>(D
)) {
1038 return getEntityDecl(ImplD
->getClassInterface());
1040 } else if (const ObjCCategoryImplDecl
*
1041 CatImplD
= dyn_cast
<ObjCCategoryImplDecl
>(D
)) {
1042 return getEntityDecl(CatImplD
->getCategoryDecl());
1043 } else if (const FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(D
)) {
1044 if (FunctionTemplateDecl
*TemplD
= FD
->getDescribedFunctionTemplate())
1045 return getEntityDecl(TemplD
);
1046 } else if (const CXXRecordDecl
*RD
= dyn_cast
<CXXRecordDecl
>(D
)) {
1047 if (ClassTemplateDecl
*TemplD
= RD
->getDescribedClassTemplate())
1048 return getEntityDecl(TemplD
);
1055 CXIndexDataConsumer::getEntityContainer(const Decl
*D
) const {
1056 const DeclContext
*DC
= dyn_cast
<DeclContext
>(D
);
1060 if (const ClassTemplateDecl
*ClassTempl
= dyn_cast
<ClassTemplateDecl
>(D
)) {
1061 DC
= ClassTempl
->getTemplatedDecl();
1062 } else if (const FunctionTemplateDecl
*
1063 FuncTempl
= dyn_cast
<FunctionTemplateDecl
>(D
)) {
1064 DC
= FuncTempl
->getTemplatedDecl();
1070 CXIdxClientContainer
1071 CXIndexDataConsumer::getClientContainerForDC(const DeclContext
*DC
) const {
1072 return DC
? ContainerMap
.lookup(DC
) : nullptr;
1075 CXIdxClientFile
CXIndexDataConsumer::getIndexFile(const FileEntry
*File
) {
1076 return File
? FileMap
.lookup(File
) : nullptr;
1079 CXIdxLoc
CXIndexDataConsumer::getIndexLoc(SourceLocation Loc
) const {
1080 CXIdxLoc idxLoc
= { {nullptr, nullptr}, 0 };
1081 if (Loc
.isInvalid())
1084 idxLoc
.ptr_data
[0] = const_cast<CXIndexDataConsumer
*>(this);
1085 idxLoc
.int_data
= Loc
.getRawEncoding();
1089 void CXIndexDataConsumer::translateLoc(SourceLocation Loc
,
1090 CXIdxClientFile
*indexFile
, CXFile
*file
,
1091 unsigned *line
, unsigned *column
,
1093 if (Loc
.isInvalid())
1096 SourceManager
&SM
= Ctx
->getSourceManager();
1097 Loc
= SM
.getFileLoc(Loc
);
1099 std::pair
<FileID
, unsigned> LocInfo
= SM
.getDecomposedLoc(Loc
);
1100 FileID FID
= LocInfo
.first
;
1101 unsigned FileOffset
= LocInfo
.second
;
1103 if (FID
.isInvalid())
1106 OptionalFileEntryRefDegradesToFileEntryPtr FE
= SM
.getFileEntryRefForID(FID
);
1108 *indexFile
= getIndexFile(FE
);
1110 *file
= cxfile::makeCXFile(FE
);
1112 *line
= SM
.getLineNumber(FID
, FileOffset
);
1114 *column
= SM
.getColumnNumber(FID
, FileOffset
);
1116 *offset
= FileOffset
;
1119 static CXIdxEntityKind
getEntityKindFromSymbolKind(SymbolKind K
, SymbolLanguage L
);
1120 static CXIdxEntityCXXTemplateKind
1121 getEntityKindFromSymbolProperties(SymbolPropertySet K
);
1122 static CXIdxEntityLanguage
getEntityLangFromSymbolLang(SymbolLanguage L
);
1124 void CXIndexDataConsumer::getEntityInfo(const NamedDecl
*D
,
1125 EntityInfo
&EntityInfo
,
1130 D
= getEntityDecl(D
);
1131 EntityInfo
.cursor
= getCursor(D
);
1133 EntityInfo
.IndexCtx
= this;
1135 SymbolInfo SymInfo
= getSymbolInfo(D
);
1136 EntityInfo
.kind
= getEntityKindFromSymbolKind(SymInfo
.Kind
, SymInfo
.Lang
);
1137 EntityInfo
.templateKind
= getEntityKindFromSymbolProperties(SymInfo
.Properties
);
1138 EntityInfo
.lang
= getEntityLangFromSymbolLang(SymInfo
.Lang
);
1140 if (D
->hasAttrs()) {
1141 EntityInfo
.AttrList
= AttrListInfo::create(D
, *this);
1142 EntityInfo
.attributes
= EntityInfo
.AttrList
->getAttrs();
1143 EntityInfo
.numAttributes
= EntityInfo
.AttrList
->getNumAttrs();
1146 if (EntityInfo
.kind
== CXIdxEntity_Unexposed
)
1149 if (IdentifierInfo
*II
= D
->getIdentifier()) {
1150 EntityInfo
.name
= SA
.toCStr(II
->getName());
1152 } else if (isa
<TagDecl
>(D
) || isa
<FieldDecl
>(D
) || isa
<NamespaceDecl
>(D
)) {
1153 EntityInfo
.name
= nullptr; // anonymous tag/field/namespace.
1156 SmallString
<256> StrBuf
;
1158 llvm::raw_svector_ostream
OS(StrBuf
);
1161 EntityInfo
.name
= SA
.copyCStr(StrBuf
.str());
1165 SmallString
<512> StrBuf
;
1166 bool Ignore
= getDeclCursorUSR(D
, StrBuf
);
1168 EntityInfo
.USR
= nullptr;
1170 EntityInfo
.USR
= SA
.copyCStr(StrBuf
.str());
1175 void CXIndexDataConsumer::getContainerInfo(const DeclContext
*DC
,
1176 ContainerInfo
&ContInfo
) {
1177 ContInfo
.cursor
= getCursor(cast
<Decl
>(DC
));
1179 ContInfo
.IndexCtx
= this;
1182 CXCursor
CXIndexDataConsumer::getRefCursor(const NamedDecl
*D
, SourceLocation Loc
) {
1183 if (const TypeDecl
*TD
= dyn_cast
<TypeDecl
>(D
))
1184 return MakeCursorTypeRef(TD
, Loc
, CXTU
);
1185 if (const ObjCInterfaceDecl
*ID
= dyn_cast
<ObjCInterfaceDecl
>(D
))
1186 return MakeCursorObjCClassRef(ID
, Loc
, CXTU
);
1187 if (const ObjCProtocolDecl
*PD
= dyn_cast
<ObjCProtocolDecl
>(D
))
1188 return MakeCursorObjCProtocolRef(PD
, Loc
, CXTU
);
1189 if (const TemplateDecl
*Template
= dyn_cast
<TemplateDecl
>(D
))
1190 return MakeCursorTemplateRef(Template
, Loc
, CXTU
);
1191 if (const NamespaceDecl
*Namespace
= dyn_cast
<NamespaceDecl
>(D
))
1192 return MakeCursorNamespaceRef(Namespace
, Loc
, CXTU
);
1193 if (const NamespaceAliasDecl
*Namespace
= dyn_cast
<NamespaceAliasDecl
>(D
))
1194 return MakeCursorNamespaceRef(Namespace
, Loc
, CXTU
);
1195 if (const FieldDecl
*Field
= dyn_cast
<FieldDecl
>(D
))
1196 return MakeCursorMemberRef(Field
, Loc
, CXTU
);
1197 if (const VarDecl
*Var
= dyn_cast
<VarDecl
>(D
))
1198 return MakeCursorVariableRef(Var
, Loc
, CXTU
);
1200 return clang_getNullCursor();
1203 bool CXIndexDataConsumer::shouldIgnoreIfImplicit(const Decl
*D
) {
1204 if (isa
<ObjCInterfaceDecl
>(D
))
1206 if (isa
<ObjCCategoryDecl
>(D
))
1208 if (isa
<ObjCIvarDecl
>(D
))
1210 if (isa
<ObjCMethodDecl
>(D
))
1212 if (isa
<ImportDecl
>(D
))
1217 bool CXIndexDataConsumer::isTemplateImplicitInstantiation(const Decl
*D
) {
1218 if (const ClassTemplateSpecializationDecl
*
1219 SD
= dyn_cast
<ClassTemplateSpecializationDecl
>(D
)) {
1220 return SD
->getSpecializationKind() == TSK_ImplicitInstantiation
;
1222 if (const FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(D
)) {
1223 return FD
->getTemplateSpecializationKind() == TSK_ImplicitInstantiation
;
1228 static CXIdxEntityKind
getEntityKindFromSymbolKind(SymbolKind K
, SymbolLanguage Lang
) {
1230 case SymbolKind::Unknown
:
1231 case SymbolKind::Module
:
1232 case SymbolKind::Macro
:
1233 case SymbolKind::ClassProperty
:
1234 case SymbolKind::Using
:
1235 case SymbolKind::TemplateTypeParm
:
1236 case SymbolKind::TemplateTemplateParm
:
1237 case SymbolKind::NonTypeTemplateParm
:
1238 return CXIdxEntity_Unexposed
;
1240 case SymbolKind::Enum
: return CXIdxEntity_Enum
;
1241 case SymbolKind::Struct
: return CXIdxEntity_Struct
;
1242 case SymbolKind::Union
: return CXIdxEntity_Union
;
1243 case SymbolKind::TypeAlias
:
1244 if (Lang
== SymbolLanguage::CXX
)
1245 return CXIdxEntity_CXXTypeAlias
;
1246 return CXIdxEntity_Typedef
;
1247 case SymbolKind::Function
: return CXIdxEntity_Function
;
1248 case SymbolKind::Variable
: return CXIdxEntity_Variable
;
1249 case SymbolKind::Field
:
1250 if (Lang
== SymbolLanguage::ObjC
)
1251 return CXIdxEntity_ObjCIvar
;
1252 return CXIdxEntity_Field
;
1253 case SymbolKind::EnumConstant
: return CXIdxEntity_EnumConstant
;
1254 case SymbolKind::Class
:
1255 if (Lang
== SymbolLanguage::ObjC
)
1256 return CXIdxEntity_ObjCClass
;
1257 return CXIdxEntity_CXXClass
;
1258 case SymbolKind::Protocol
:
1259 if (Lang
== SymbolLanguage::ObjC
)
1260 return CXIdxEntity_ObjCProtocol
;
1261 return CXIdxEntity_CXXInterface
;
1262 case SymbolKind::Extension
: return CXIdxEntity_ObjCCategory
;
1263 case SymbolKind::InstanceMethod
:
1264 if (Lang
== SymbolLanguage::ObjC
)
1265 return CXIdxEntity_ObjCInstanceMethod
;
1266 return CXIdxEntity_CXXInstanceMethod
;
1267 case SymbolKind::ClassMethod
: return CXIdxEntity_ObjCClassMethod
;
1268 case SymbolKind::StaticMethod
: return CXIdxEntity_CXXStaticMethod
;
1269 case SymbolKind::InstanceProperty
: return CXIdxEntity_ObjCProperty
;
1270 case SymbolKind::StaticProperty
: return CXIdxEntity_CXXStaticVariable
;
1271 case SymbolKind::Namespace
: return CXIdxEntity_CXXNamespace
;
1272 case SymbolKind::NamespaceAlias
: return CXIdxEntity_CXXNamespaceAlias
;
1273 case SymbolKind::Constructor
: return CXIdxEntity_CXXConstructor
;
1274 case SymbolKind::Destructor
: return CXIdxEntity_CXXDestructor
;
1275 case SymbolKind::ConversionFunction
: return CXIdxEntity_CXXConversionFunction
;
1276 case SymbolKind::Parameter
: return CXIdxEntity_Variable
;
1277 case SymbolKind::Concept
:
1278 return CXIdxEntity_CXXConcept
;
1280 llvm_unreachable("invalid symbol kind");
1283 static CXIdxEntityCXXTemplateKind
1284 getEntityKindFromSymbolProperties(SymbolPropertySet K
) {
1285 if (K
& (SymbolPropertySet
)SymbolProperty::TemplatePartialSpecialization
)
1286 return CXIdxEntity_TemplatePartialSpecialization
;
1287 if (K
& (SymbolPropertySet
)SymbolProperty::TemplateSpecialization
)
1288 return CXIdxEntity_TemplateSpecialization
;
1289 if (K
& (SymbolPropertySet
)SymbolProperty::Generic
)
1290 return CXIdxEntity_Template
;
1291 return CXIdxEntity_NonTemplate
;
1294 static CXIdxEntityLanguage
getEntityLangFromSymbolLang(SymbolLanguage L
) {
1296 case SymbolLanguage::C
: return CXIdxEntityLang_C
;
1297 case SymbolLanguage::ObjC
: return CXIdxEntityLang_ObjC
;
1298 case SymbolLanguage::CXX
: return CXIdxEntityLang_CXX
;
1299 case SymbolLanguage::Swift
: return CXIdxEntityLang_Swift
;
1301 llvm_unreachable("invalid symbol language");