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" 11a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar#include "clang/AST/RecursiveASTVisitor.h" 124e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis 134e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisusing namespace clang; 144e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisusing namespace cxindex; 154e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis 164e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisnamespace { 174e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis 18a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainarclass TypeIndexer : public RecursiveASTVisitor<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 111c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen 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 125c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen 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: 132176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case NestedNameSpecifier::Super: 133e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis break; 134e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis 135e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis case NestedNameSpecifier::Namespace: 136e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis handleReference(NNS.getNestedNameSpecifier()->getAsNamespace(), 137e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis Loc, Parent, DC); 138e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis break; 139e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis case NestedNameSpecifier::NamespaceAlias: 140e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis handleReference(NNS.getNestedNameSpecifier()->getAsNamespaceAlias(), 141e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis Loc, Parent, DC); 142e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis break; 143e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis 144e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis case NestedNameSpecifier::TypeSpec: 145e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis case NestedNameSpecifier::TypeSpecWithTemplate: 146e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis indexTypeLoc(NNS.getTypeLoc(), Parent, DC); 147e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis break; 148e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis } 149e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis} 150e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis 1514e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisvoid IndexingContext::indexTagDecl(const TagDecl *D) { 152b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis if (handleTagDecl(D)) { 153b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis if (D->isThisDeclarationADefinition()) 154b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis indexDeclContext(D); 1554e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis } 1564e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis} 157