14e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===- CIndexHigh.cpp - Higher level API functions ------------------------===//
24e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//
34e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//                     The LLVM Compiler Infrastructure
44e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//
54e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source
64e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis// License. See LICENSE.TXT for details.
74e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//
84e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
94e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
104e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis#include "IndexingContext.h"
11651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "clang/AST/DataRecursiveASTVisitor.h"
124e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
134e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisusing namespace clang;
144e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisusing namespace cxindex;
154e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
164e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisnamespace {
174e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
18651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass TypeIndexer : public DataRecursiveASTVisitor<TypeIndexer> {
194e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  IndexingContext &IndexCtx;
204e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  const NamedDecl *Parent;
214e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  const DeclContext *ParentDC;
224e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
234e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidispublic:
244e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  TypeIndexer(IndexingContext &indexCtx, const NamedDecl *parent,
254e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis              const DeclContext *DC)
264e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    : IndexCtx(indexCtx), Parent(parent), ParentDC(DC) { }
274e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
284e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  bool shouldWalkTypesOfTypeLocs() const { return false; }
294e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
304e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
314e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    IndexCtx.handleReference(TL.getTypedefNameDecl(), TL.getNameLoc(),
324e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                             Parent, ParentDC);
334e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return true;
344e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
354e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
36e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
37e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
38e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    return true;
39e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  }
40e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis
414e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  bool VisitTagTypeLoc(TagTypeLoc TL) {
424e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    TagDecl *D = TL.getDecl();
43d6c8209fd1567db9c2721f441b50cb23cdf8d835Argyrios Kyrtzidis    if (D->getParentFunctionOrMethod())
44d6c8209fd1567db9c2721f441b50cb23cdf8d835Argyrios Kyrtzidis      return true;
454e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
464e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    if (TL.isDefinition()) {
474e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      IndexCtx.indexTagDecl(D);
484e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      return true;
494e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    }
504e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
514e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    if (D->getLocation() == TL.getNameLoc())
524e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      IndexCtx.handleTagDecl(D);
534e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    else
544e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      IndexCtx.handleReference(D, TL.getNameLoc(),
554e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                               Parent, ParentDC);
564e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return true;
574e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
584e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
594e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
604e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    IndexCtx.handleReference(TL.getIFaceDecl(), TL.getNameLoc(),
614e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                             Parent, ParentDC);
624e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return true;
634e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
644e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
654e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
664e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) {
674e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      IndexCtx.handleReference(TL.getProtocol(i), TL.getProtocolLoc(i),
684e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                               Parent, ParentDC);
694e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    }
704e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return true;
714e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
72145f7b2093a0050621141acd089e09edf6118a09Argyrios Kyrtzidis
73145f7b2093a0050621141acd089e09edf6118a09Argyrios Kyrtzidis  bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) {
746d968363877388f0a0268711d59367907b465ae1Argyrios Kyrtzidis    if (const TemplateSpecializationType *T = TL.getTypePtr()) {
7558d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis      if (IndexCtx.shouldIndexImplicitTemplateInsts()) {
7658d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis        if (CXXRecordDecl *RD = T->getAsCXXRecordDecl())
7758d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis          IndexCtx.handleReference(RD, TL.getTemplateNameLoc(),
7858d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis                                   Parent, ParentDC);
7958d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis      } else {
8058d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis        if (const TemplateDecl *D = T->getTemplateName().getAsTemplateDecl())
8158d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis          IndexCtx.handleReference(D, TL.getTemplateNameLoc(),
8258d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis                                   Parent, ParentDC);
8358d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis      }
846d968363877388f0a0268711d59367907b465ae1Argyrios Kyrtzidis    }
85145f7b2093a0050621141acd089e09edf6118a09Argyrios Kyrtzidis    return true;
86145f7b2093a0050621141acd089e09edf6118a09Argyrios Kyrtzidis  }
87f8490eeb966103516da4e3ecb05e1a36b3e6e3ecArgyrios Kyrtzidis
88f8490eeb966103516da4e3ecb05e1a36b3e6e3ecArgyrios Kyrtzidis  bool TraverseStmt(Stmt *S) {
89f8490eeb966103516da4e3ecb05e1a36b3e6e3ecArgyrios Kyrtzidis    IndexCtx.indexBody(S, Parent, ParentDC);
90f8490eeb966103516da4e3ecb05e1a36b3e6e3ecArgyrios Kyrtzidis    return true;
91f8490eeb966103516da4e3ecb05e1a36b3e6e3ecArgyrios Kyrtzidis  }
924e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis};
934e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
944e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis} // anonymous namespace
954e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
964e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisvoid IndexingContext::indexTypeSourceInfo(TypeSourceInfo *TInfo,
974e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                          const NamedDecl *Parent,
984e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                          const DeclContext *DC) {
994e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  if (!TInfo || TInfo->getTypeLoc().isNull())
1004e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return;
1014e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
1024e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  indexTypeLoc(TInfo->getTypeLoc(), Parent, DC);
1034e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis}
1044e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
1054e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisvoid IndexingContext::indexTypeLoc(TypeLoc TL,
1064e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                   const NamedDecl *Parent,
1074e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                   const DeclContext *DC) {
108e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  if (TL.isNull())
109e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    return;
110e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis
111ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (!DC)
112e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    DC = Parent->getLexicalDeclContext();
1134e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  TypeIndexer(*this, Parent, DC).TraverseTypeLoc(TL);
1144e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis}
1154e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
116e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidisvoid IndexingContext::indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
117e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis                                                  const NamedDecl *Parent,
118e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis                                                  const DeclContext *DC) {
119e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  if (!NNS)
120e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    return;
121e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis
122e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
123e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    indexNestedNameSpecifierLoc(Prefix, Parent, DC);
124e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis
125ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (!DC)
126e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    DC = Parent->getLexicalDeclContext();
127e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  SourceLocation Loc = NNS.getSourceRange().getBegin();
128e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis
129e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  switch (NNS.getNestedNameSpecifier()->getKind()) {
130e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  case NestedNameSpecifier::Identifier:
131e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  case NestedNameSpecifier::Global:
132e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    break;
133e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis
134e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  case NestedNameSpecifier::Namespace:
135e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    handleReference(NNS.getNestedNameSpecifier()->getAsNamespace(),
136e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis                    Loc, Parent, DC);
137e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    break;
138e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  case NestedNameSpecifier::NamespaceAlias:
139e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    handleReference(NNS.getNestedNameSpecifier()->getAsNamespaceAlias(),
140e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis                    Loc, Parent, DC);
141e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    break;
142e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis
143e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  case NestedNameSpecifier::TypeSpec:
144e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  case NestedNameSpecifier::TypeSpecWithTemplate:
145e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    indexTypeLoc(NNS.getTypeLoc(), Parent, DC);
146e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    break;
147e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  }
148e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis}
149e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis
1504e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisvoid IndexingContext::indexTagDecl(const TagDecl *D) {
151b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis  if (handleTagDecl(D)) {
152b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis    if (D->isThisDeclarationADefinition())
153b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis      indexDeclContext(D);
1544e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
1554e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis}
156