IndexTypeSourceInfo.cpp revision e422e45a6a89d450b8eca10f671b49874e87617a
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"
114e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
124e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis#include "clang/AST/RecursiveASTVisitor.h"
134e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
144e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisusing namespace clang;
154e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisusing namespace cxindex;
164e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
174e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisnamespace {
184e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
194e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisclass TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
204e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  IndexingContext &IndexCtx;
214e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  const NamedDecl *Parent;
224e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  const DeclContext *ParentDC;
234e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
244e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidispublic:
254e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  TypeIndexer(IndexingContext &indexCtx, const NamedDecl *parent,
264e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis              const DeclContext *DC)
274e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    : IndexCtx(indexCtx), Parent(parent), ParentDC(DC) { }
284e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
294e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  bool shouldWalkTypesOfTypeLocs() const { return false; }
304e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
314e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
324e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    IndexCtx.handleReference(TL.getTypedefNameDecl(), TL.getNameLoc(),
334e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                             Parent, ParentDC);
344e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return true;
354e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
364e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
37e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
38e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
39e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    return true;
40e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  }
41e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis
424e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  bool VisitTagTypeLoc(TagTypeLoc TL) {
434e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    TagDecl *D = TL.getDecl();
44d6c8209fd1567db9c2721f441b50cb23cdf8d835Argyrios Kyrtzidis    if (D->getParentFunctionOrMethod())
45d6c8209fd1567db9c2721f441b50cb23cdf8d835Argyrios Kyrtzidis      return true;
464e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
474e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    if (TL.isDefinition()) {
484e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      IndexCtx.indexTagDecl(D);
494e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      return true;
504e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    }
514e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
524e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    if (D->getLocation() == TL.getNameLoc())
534e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      IndexCtx.handleTagDecl(D);
544e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    else
554e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      IndexCtx.handleReference(D, TL.getNameLoc(),
564e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                               Parent, ParentDC);
574e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return true;
584e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
594e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
604e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
614e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    IndexCtx.handleReference(TL.getIFaceDecl(), TL.getNameLoc(),
624e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                             Parent, ParentDC);
634e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return true;
644e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
654e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
664e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
674e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) {
684e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      IndexCtx.handleReference(TL.getProtocol(i), TL.getProtocolLoc(i),
694e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                               Parent, ParentDC);
704e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    }
714e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return true;
724e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
734e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis};
744e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
754e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis} // anonymous namespace
764e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
774e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisvoid IndexingContext::indexTypeSourceInfo(TypeSourceInfo *TInfo,
784e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                          const NamedDecl *Parent,
794e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                          const DeclContext *DC) {
804e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  if (!TInfo || TInfo->getTypeLoc().isNull())
814e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return;
824e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
834e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  indexTypeLoc(TInfo->getTypeLoc(), Parent, DC);
844e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis}
854e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
864e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisvoid IndexingContext::indexTypeLoc(TypeLoc TL,
874e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                   const NamedDecl *Parent,
884e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                   const DeclContext *DC) {
89e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  if (TL.isNull())
90e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    return;
91e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis
92e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  if (DC == 0)
93e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    DC = Parent->getLexicalDeclContext();
944e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  TypeIndexer(*this, Parent, DC).TraverseTypeLoc(TL);
954e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis}
964e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
97e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidisvoid IndexingContext::indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
98e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis                                                  const NamedDecl *Parent,
99e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis                                                  const DeclContext *DC) {
100e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  if (!NNS)
101e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    return;
102e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis
103e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
104e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    indexNestedNameSpecifierLoc(Prefix, Parent, DC);
105e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis
106e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  if (DC == 0)
107e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    DC = Parent->getLexicalDeclContext();
108e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  SourceLocation Loc = NNS.getSourceRange().getBegin();
109e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis
110e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  switch (NNS.getNestedNameSpecifier()->getKind()) {
111e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  case NestedNameSpecifier::Identifier:
112e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  case NestedNameSpecifier::Global:
113e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    break;
114e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis
115e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  case NestedNameSpecifier::Namespace:
116e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    handleReference(NNS.getNestedNameSpecifier()->getAsNamespace(),
117e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis                    Loc, Parent, DC);
118e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    break;
119e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  case NestedNameSpecifier::NamespaceAlias:
120e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    handleReference(NNS.getNestedNameSpecifier()->getAsNamespaceAlias(),
121e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis                    Loc, Parent, DC);
122e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    break;
123e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis
124e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  case NestedNameSpecifier::TypeSpec:
125e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  case NestedNameSpecifier::TypeSpecWithTemplate:
126e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    indexTypeLoc(NNS.getTypeLoc(), Parent, DC);
127e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    break;
128e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  }
129e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis}
130e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis
1314e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisvoid IndexingContext::indexTagDecl(const TagDecl *D) {
132b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis  if (handleTagDecl(D)) {
133b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis    if (D->isThisDeclarationADefinition())
134b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis      indexDeclContext(D);
1354e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
1364e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis}
137