]> git.proxmox.com Git - rustc.git/blob - src/llvm/tools/clang/tools/libclang/IndexTypeSourceInfo.cpp
Imported Upstream version 0.6
[rustc.git] / src / llvm / tools / clang / tools / libclang / IndexTypeSourceInfo.cpp
1 //===- 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 "RecursiveASTVisitor.h"
13
14 using namespace clang;
15 using namespace cxindex;
16
17 namespace {
18
19 class TypeIndexer : public cxindex::RecursiveASTVisitor<TypeIndexer> {
20 IndexingContext &IndexCtx;
21 const NamedDecl *Parent;
22 const DeclContext *ParentDC;
23
24 public:
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
37 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
38 IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
39 return true;
40 }
41
42 bool VisitTagTypeLoc(TagTypeLoc TL) {
43 TagDecl *D = TL.getDecl();
44 if (D->getParentFunctionOrMethod())
45 return true;
46
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 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(),
79 Parent, ParentDC);
80 } else {
81 if (const TemplateDecl *D = T->getTemplateName().getAsTemplateDecl())
82 IndexCtx.handleReference(D, TL.getTemplateNameLoc(),
83 Parent, ParentDC);
84 }
85 }
86 return true;
87 }
88
89 bool TraverseStmt(Stmt *S) {
90 IndexCtx.indexBody(S, Parent, ParentDC);
91 return true;
92 }
93 };
94
95 } // anonymous namespace
96
97 void IndexingContext::indexTypeSourceInfo(TypeSourceInfo *TInfo,
98 const NamedDecl *Parent,
99 const DeclContext *DC) {
100 if (!TInfo || TInfo->getTypeLoc().isNull())
101 return;
102
103 indexTypeLoc(TInfo->getTypeLoc(), Parent, DC);
104 }
105
106 void IndexingContext::indexTypeLoc(TypeLoc TL,
107 const NamedDecl *Parent,
108 const DeclContext *DC) {
109 if (TL.isNull())
110 return;
111
112 if (DC == 0)
113 DC = Parent->getLexicalDeclContext();
114 TypeIndexer(*this, Parent, DC).TraverseTypeLoc(TL);
115 }
116
117 void IndexingContext::indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
118 const NamedDecl *Parent,
119 const DeclContext *DC) {
120 if (!NNS)
121 return;
122
123 if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
124 indexNestedNameSpecifierLoc(Prefix, Parent, DC);
125
126 if (DC == 0)
127 DC = Parent->getLexicalDeclContext();
128 SourceLocation Loc = NNS.getSourceRange().getBegin();
129
130 switch (NNS.getNestedNameSpecifier()->getKind()) {
131 case NestedNameSpecifier::Identifier:
132 case NestedNameSpecifier::Global:
133 break;
134
135 case NestedNameSpecifier::Namespace:
136 handleReference(NNS.getNestedNameSpecifier()->getAsNamespace(),
137 Loc, Parent, DC);
138 break;
139 case NestedNameSpecifier::NamespaceAlias:
140 handleReference(NNS.getNestedNameSpecifier()->getAsNamespaceAlias(),
141 Loc, Parent, DC);
142 break;
143
144 case NestedNameSpecifier::TypeSpec:
145 case NestedNameSpecifier::TypeSpecWithTemplate:
146 indexTypeLoc(NNS.getTypeLoc(), Parent, DC);
147 break;
148 }
149 }
150
151 void IndexingContext::indexTagDecl(const TagDecl *D) {
152 if (handleTagDecl(D)) {
153 if (D->isThisDeclarationADefinition())
154 indexDeclContext(D);
155 }
156 }