• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
TypeIndexer(IndexingContext & indexCtx,const NamedDecl * parent,const DeclContext * DC)25   TypeIndexer(IndexingContext &indexCtx, const NamedDecl *parent,
26               const DeclContext *DC)
27     : IndexCtx(indexCtx), Parent(parent), ParentDC(DC) { }
28 
shouldWalkTypesOfTypeLocs() const29   bool shouldWalkTypesOfTypeLocs() const { return false; }
30 
VisitTypedefTypeLoc(TypedefTypeLoc TL)31   bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
32     IndexCtx.handleReference(TL.getTypedefNameDecl(), TL.getNameLoc(),
33                              Parent, ParentDC);
34     return true;
35   }
36 
TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS)37   bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
38     IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
39     return true;
40   }
41 
VisitTagTypeLoc(TagTypeLoc TL)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 
VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL)60   bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
61     IndexCtx.handleReference(TL.getIFaceDecl(), TL.getNameLoc(),
62                              Parent, ParentDC);
63     return true;
64   }
65 
VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL)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 
VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL)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 
TraverseStmt(Stmt * S)89   bool TraverseStmt(Stmt *S) {
90     IndexCtx.indexBody(S, Parent, ParentDC);
91     return true;
92   }
93 };
94 
95 } // anonymous namespace
96 
indexTypeSourceInfo(TypeSourceInfo * TInfo,const NamedDecl * Parent,const DeclContext * DC)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 
indexTypeLoc(TypeLoc TL,const NamedDecl * Parent,const DeclContext * DC)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 
indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,const NamedDecl * Parent,const DeclContext * DC)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 
indexTagDecl(const TagDecl * D)151 void IndexingContext::indexTagDecl(const TagDecl *D) {
152   if (handleTagDecl(D)) {
153     if (D->isThisDeclarationADefinition())
154       indexDeclContext(D);
155   }
156 }
157