1 //===- CIndexHigh.cpp - Higher level API functions ------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "IndexingContext.h"
12 #include "RecursiveASTVisitor.h"
14 using namespace clang
;
15 using namespace cxindex
;
19 class TypeIndexer
: public cxindex::RecursiveASTVisitor
<TypeIndexer
> {
20 IndexingContext
&IndexCtx
;
21 const NamedDecl
*Parent
;
22 const DeclContext
*ParentDC
;
25 TypeIndexer(IndexingContext
&indexCtx
, const NamedDecl
*parent
,
26 const DeclContext
*DC
)
27 : IndexCtx(indexCtx
), Parent(parent
), ParentDC(DC
) { }
29 bool shouldWalkTypesOfTypeLocs() const { return false; }
31 bool VisitTypedefTypeLoc(TypedefTypeLoc TL
) {
32 IndexCtx
.handleReference(TL
.getTypedefNameDecl(), TL
.getNameLoc(),
37 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS
) {
38 IndexCtx
.indexNestedNameSpecifierLoc(NNS
, Parent
, ParentDC
);
42 bool VisitTagTypeLoc(TagTypeLoc TL
) {
43 TagDecl
*D
= TL
.getDecl();
44 if (D
->getParentFunctionOrMethod())
47 if (TL
.isDefinition()) {
48 IndexCtx
.indexTagDecl(D
);
52 if (D
->getLocation() == TL
.getNameLoc())
53 IndexCtx
.handleTagDecl(D
);
55 IndexCtx
.handleReference(D
, TL
.getNameLoc(),
60 bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL
) {
61 IndexCtx
.handleReference(TL
.getIFaceDecl(), TL
.getNameLoc(),
66 bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL
) {
67 for (unsigned i
= 0, e
= TL
.getNumProtocols(); i
!= e
; ++i
) {
68 IndexCtx
.handleReference(TL
.getProtocol(i
), TL
.getProtocolLoc(i
),
74 bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL
) {
75 if (const TemplateSpecializationType
*T
= TL
.getTypePtr()) {
76 if (IndexCtx
.shouldIndexImplicitTemplateInsts()) {
77 if (CXXRecordDecl
*RD
= T
->getAsCXXRecordDecl())
78 IndexCtx
.handleReference(RD
, TL
.getTemplateNameLoc(),
81 if (const TemplateDecl
*D
= T
->getTemplateName().getAsTemplateDecl())
82 IndexCtx
.handleReference(D
, TL
.getTemplateNameLoc(),
89 bool TraverseStmt(Stmt
*S
) {
90 IndexCtx
.indexBody(S
, Parent
, ParentDC
);
95 } // anonymous namespace
97 void IndexingContext::indexTypeSourceInfo(TypeSourceInfo
*TInfo
,
98 const NamedDecl
*Parent
,
99 const DeclContext
*DC
) {
100 if (!TInfo
|| TInfo
->getTypeLoc().isNull())
103 indexTypeLoc(TInfo
->getTypeLoc(), Parent
, DC
);
106 void IndexingContext::indexTypeLoc(TypeLoc TL
,
107 const NamedDecl
*Parent
,
108 const DeclContext
*DC
) {
113 DC
= Parent
->getLexicalDeclContext();
114 TypeIndexer(*this, Parent
, DC
).TraverseTypeLoc(TL
);
117 void IndexingContext::indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS
,
118 const NamedDecl
*Parent
,
119 const DeclContext
*DC
) {
123 if (NestedNameSpecifierLoc Prefix
= NNS
.getPrefix())
124 indexNestedNameSpecifierLoc(Prefix
, Parent
, DC
);
127 DC
= Parent
->getLexicalDeclContext();
128 SourceLocation Loc
= NNS
.getSourceRange().getBegin();
130 switch (NNS
.getNestedNameSpecifier()->getKind()) {
131 case NestedNameSpecifier::Identifier
:
132 case NestedNameSpecifier::Global
:
135 case NestedNameSpecifier::Namespace
:
136 handleReference(NNS
.getNestedNameSpecifier()->getAsNamespace(),
139 case NestedNameSpecifier::NamespaceAlias
:
140 handleReference(NNS
.getNestedNameSpecifier()->getAsNamespaceAlias(),
144 case NestedNameSpecifier::TypeSpec
:
145 case NestedNameSpecifier::TypeSpecWithTemplate
:
146 indexTypeLoc(NNS
.getTypeLoc(), Parent
, DC
);
151 void IndexingContext::indexTagDecl(const TagDecl
*D
) {
152 if (handleTagDecl(D
)) {
153 if (D
->isThisDeclarationADefinition())