blob: 1b2069d30d3c9cd7d8ba30d52173e1febb194d0a [file] [log] [blame]
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +00001//===- CIndexHigh.cpp - Higher level API functions ------------------------===//
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
12#include "clang/AST/RecursiveASTVisitor.h"
13
14using namespace clang;
15using namespace cxindex;
16
17namespace {
18
19class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
20 IndexingContext &IndexCtx;
21 const NamedDecl *Parent;
22 const DeclContext *ParentDC;
23
24public:
25 TypeIndexer(IndexingContext &indexCtx, const NamedDecl *parent,
26 const DeclContext *DC)
27 : IndexCtx(indexCtx), Parent(parent), ParentDC(DC) { }
28
29 bool shouldWalkTypesOfTypeLocs() const { return false; }
30
31 bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
32 IndexCtx.handleReference(TL.getTypedefNameDecl(), TL.getNameLoc(),
33 Parent, ParentDC);
34 return true;
35 }
36
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000037 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
38 IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
39 return true;
40 }
41
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000042 bool VisitTagTypeLoc(TagTypeLoc TL) {
43 TagDecl *D = TL.getDecl();
Argyrios Kyrtzidisd6c82092011-11-16 02:35:01 +000044 if (D->getParentFunctionOrMethod())
45 return true;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000046
47 if (TL.isDefinition()) {
48 IndexCtx.indexTagDecl(D);
49 return true;
50 }
51
52 if (D->getLocation() == TL.getNameLoc())
53 IndexCtx.handleTagDecl(D);
54 else
55 IndexCtx.handleReference(D, TL.getNameLoc(),
56 Parent, ParentDC);
57 return true;
58 }
59
60 bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
61 IndexCtx.handleReference(TL.getIFaceDecl(), TL.getNameLoc(),
62 Parent, ParentDC);
63 return true;
64 }
65
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),
69 Parent, ParentDC);
70 }
71 return true;
72 }
73};
74
75} // anonymous namespace
76
77void IndexingContext::indexTypeSourceInfo(TypeSourceInfo *TInfo,
78 const NamedDecl *Parent,
79 const DeclContext *DC) {
80 if (!TInfo || TInfo->getTypeLoc().isNull())
81 return;
82
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000083 indexTypeLoc(TInfo->getTypeLoc(), Parent, DC);
84}
85
86void IndexingContext::indexTypeLoc(TypeLoc TL,
87 const NamedDecl *Parent,
88 const DeclContext *DC) {
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000089 if (TL.isNull())
90 return;
91
92 if (DC == 0)
93 DC = Parent->getLexicalDeclContext();
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000094 TypeIndexer(*this, Parent, DC).TraverseTypeLoc(TL);
95}
96
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000097void IndexingContext::indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
98 const NamedDecl *Parent,
99 const DeclContext *DC) {
100 if (!NNS)
101 return;
102
103 if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
104 indexNestedNameSpecifierLoc(Prefix, Parent, DC);
105
106 if (DC == 0)
107 DC = Parent->getLexicalDeclContext();
108 SourceLocation Loc = NNS.getSourceRange().getBegin();
109
110 switch (NNS.getNestedNameSpecifier()->getKind()) {
111 case NestedNameSpecifier::Identifier:
112 case NestedNameSpecifier::Global:
113 break;
114
115 case NestedNameSpecifier::Namespace:
116 handleReference(NNS.getNestedNameSpecifier()->getAsNamespace(),
117 Loc, Parent, DC);
118 break;
119 case NestedNameSpecifier::NamespaceAlias:
120 handleReference(NNS.getNestedNameSpecifier()->getAsNamespaceAlias(),
121 Loc, Parent, DC);
122 break;
123
124 case NestedNameSpecifier::TypeSpec:
125 case NestedNameSpecifier::TypeSpecWithTemplate:
126 indexTypeLoc(NNS.getTypeLoc(), Parent, DC);
127 break;
128 }
129}
130
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000131void IndexingContext::indexTagDecl(const TagDecl *D) {
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000132 if (handleTagDecl(D)) {
133 if (D->isThisDeclarationADefinition())
134 indexDeclContext(D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000135 }
136}