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