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 12dec35a9848b3580855ea53eaeeafd3e17a5fb934Argyrios Kyrtzidis#include "RecursiveASTVisitor.h" 134e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis 144e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisusing namespace clang; 154e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisusing namespace cxindex; 164e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis 174e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisnamespace { 184e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis 1998180d49bdbb9a41e9cacf12a3a8be30a60ba707Argyrios Kyrtzidisclass TypeIndexer : public cxindex::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 } 73145f7b2093a0050621141acd089e09edf6118a09Argyrios Kyrtzidis 74145f7b2093a0050621141acd089e09edf6118a09Argyrios Kyrtzidis bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) { 756d968363877388f0a0268711d59367907b465ae1Argyrios Kyrtzidis if (const TemplateSpecializationType *T = TL.getTypePtr()) { 7658d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis if (IndexCtx.shouldIndexImplicitTemplateInsts()) { 7758d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis if (CXXRecordDecl *RD = T->getAsCXXRecordDecl()) 7858d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis IndexCtx.handleReference(RD, TL.getTemplateNameLoc(), 7958d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis Parent, ParentDC); 8058d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis } else { 8158d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis if (const TemplateDecl *D = T->getTemplateName().getAsTemplateDecl()) 8258d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis IndexCtx.handleReference(D, TL.getTemplateNameLoc(), 8358d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis Parent, ParentDC); 8458d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis } 856d968363877388f0a0268711d59367907b465ae1Argyrios Kyrtzidis } 86145f7b2093a0050621141acd089e09edf6118a09Argyrios Kyrtzidis return true; 87145f7b2093a0050621141acd089e09edf6118a09Argyrios Kyrtzidis } 88f8490eeb966103516da4e3ecb05e1a36b3e6e3ecArgyrios Kyrtzidis 89f8490eeb966103516da4e3ecb05e1a36b3e6e3ecArgyrios Kyrtzidis bool TraverseStmt(Stmt *S) { 90f8490eeb966103516da4e3ecb05e1a36b3e6e3ecArgyrios Kyrtzidis IndexCtx.indexBody(S, Parent, ParentDC); 91f8490eeb966103516da4e3ecb05e1a36b3e6e3ecArgyrios Kyrtzidis return true; 92f8490eeb966103516da4e3ecb05e1a36b3e6e3ecArgyrios Kyrtzidis } 934e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis}; 944e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis 954e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis} // anonymous namespace 964e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis 974e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisvoid IndexingContext::indexTypeSourceInfo(TypeSourceInfo *TInfo, 984e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis const NamedDecl *Parent, 994e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis const DeclContext *DC) { 1004e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis if (!TInfo || TInfo->getTypeLoc().isNull()) 1014e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis return; 1024e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis 1034e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis indexTypeLoc(TInfo->getTypeLoc(), Parent, DC); 1044e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis} 1054e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis 1064e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisvoid IndexingContext::indexTypeLoc(TypeLoc TL, 1074e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis const NamedDecl *Parent, 1084e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis const DeclContext *DC) { 109e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis if (TL.isNull()) 110e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis return; 111e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis 112e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis if (DC == 0) 113e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis DC = Parent->getLexicalDeclContext(); 1144e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis TypeIndexer(*this, Parent, DC).TraverseTypeLoc(TL); 1154e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis} 1164e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis 117e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidisvoid IndexingContext::indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, 118e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis const NamedDecl *Parent, 119e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis const DeclContext *DC) { 120e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis if (!NNS) 121e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis return; 122e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis 123e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis if (NestedNameSpecifierLoc Prefix = NNS.getPrefix()) 124e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis indexNestedNameSpecifierLoc(Prefix, Parent, DC); 125e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis 126e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis if (DC == 0) 127e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis DC = Parent->getLexicalDeclContext(); 128e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis SourceLocation Loc = NNS.getSourceRange().getBegin(); 129e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis 130e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis switch (NNS.getNestedNameSpecifier()->getKind()) { 131e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis case NestedNameSpecifier::Identifier: 132e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis case NestedNameSpecifier::Global: 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