IndexBody.cpp revision 98180d49bdbb9a41e9cacf12a3a8be30a60ba707
1//===- CIndexHigh.cpp - Higher level API functions ------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "IndexingContext.h" 11 12#include "RecursiveASTVisitor.h" 13 14using namespace clang; 15using namespace cxindex; 16 17namespace { 18 19class BodyIndexer : public cxindex::RecursiveASTVisitor<BodyIndexer> { 20 IndexingContext &IndexCtx; 21 const NamedDecl *Parent; 22 const DeclContext *ParentDC; 23 24 typedef RecursiveASTVisitor<BodyIndexer> base; 25public: 26 BodyIndexer(IndexingContext &indexCtx, 27 const NamedDecl *Parent, const DeclContext *DC) 28 : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) { } 29 30 bool shouldWalkTypesOfTypeLocs() const { return false; } 31 32 bool TraverseTypeLoc(TypeLoc TL) { 33 IndexCtx.indexTypeLoc(TL, Parent, ParentDC); 34 return true; 35 } 36 37 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { 38 IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC); 39 return true; 40 } 41 42 bool VisitDeclRefExpr(DeclRefExpr *E) { 43 IndexCtx.handleReference(E->getDecl(), E->getLocation(), 44 Parent, ParentDC, E); 45 return true; 46 } 47 48 bool VisitMemberExpr(MemberExpr *E) { 49 IndexCtx.handleReference(E->getMemberDecl(), E->getMemberLoc(), 50 Parent, ParentDC, E); 51 return true; 52 } 53 54 bool VisitDesignatedInitExpr(DesignatedInitExpr *E) { 55 for (DesignatedInitExpr::reverse_designators_iterator 56 D = E->designators_rbegin(), DEnd = E->designators_rend(); 57 D != DEnd; ++D) { 58 if (D->isFieldDesignator()) 59 IndexCtx.handleReference(D->getField(), D->getFieldLoc(), 60 Parent, ParentDC, E); 61 } 62 return true; 63 } 64 65 bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { 66 IndexCtx.handleReference(E->getDecl(), E->getLocation(), 67 Parent, ParentDC, E); 68 return true; 69 } 70 71 bool VisitObjCMessageExpr(ObjCMessageExpr *E) { 72 if (TypeSourceInfo *Cls = E->getClassReceiverTypeInfo()) 73 IndexCtx.indexTypeSourceInfo(Cls, Parent, ParentDC); 74 75 if (ObjCMethodDecl *MD = E->getMethodDecl()) 76 IndexCtx.handleReference(MD, E->getSelectorStartLoc(), 77 Parent, ParentDC, E, 78 E->isImplicit() ? CXIdxEntityRef_Implicit 79 : CXIdxEntityRef_Direct); 80 return true; 81 } 82 83 bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { 84 if (E->isExplicitProperty()) 85 IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(), 86 Parent, ParentDC, E); 87 88 // No need to do a handleReference for the objc method, because there will 89 // be a message expr as part of PseudoObjectExpr. 90 return true; 91 } 92 93 bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) { 94 if (ObjCMethodDecl *MD = E->getBoxingMethod()) 95 IndexCtx.handleReference(MD, E->getLocStart(), 96 Parent, ParentDC, E, CXIdxEntityRef_Implicit); 97 return true; 98 } 99 100 bool VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) { 101 if (ObjCMethodDecl *MD = E->getDictWithObjectsMethod()) 102 IndexCtx.handleReference(MD, E->getLocStart(), 103 Parent, ParentDC, E, CXIdxEntityRef_Implicit); 104 return true; 105 } 106 107 bool VisitObjCArrayLiteral(ObjCArrayLiteral *E) { 108 if (ObjCMethodDecl *MD = E->getArrayWithObjectsMethod()) 109 IndexCtx.handleReference(MD, E->getLocStart(), 110 Parent, ParentDC, E, CXIdxEntityRef_Implicit); 111 return true; 112 } 113 114 bool VisitCXXConstructExpr(CXXConstructExpr *E) { 115 IndexCtx.handleReference(E->getConstructor(), E->getLocation(), 116 Parent, ParentDC, E); 117 return true; 118 } 119 120 bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E) { 121 if (E->getOperatorLoc().isInvalid()) 122 return true; // implicit. 123 return base::TraverseCXXOperatorCallExpr(E); 124 } 125 126 bool VisitDeclStmt(DeclStmt *S) { 127 if (IndexCtx.shouldIndexFunctionLocalSymbols()) 128 IndexCtx.indexDeclGroupRef(S->getDeclGroup()); 129 return true; 130 } 131 132 bool TraverseLambdaCapture(LambdaExpr::Capture C) { 133 if (C.capturesThis()) 134 return true; 135 136 if (IndexCtx.shouldIndexFunctionLocalSymbols()) 137 IndexCtx.handleReference(C.getCapturedVar(), C.getLocation(), 138 Parent, ParentDC); 139 return true; 140 } 141 142}; 143 144} // anonymous namespace 145 146void IndexingContext::indexBody(const Stmt *S, const NamedDecl *Parent, 147 const DeclContext *DC) { 148 if (!S) 149 return; 150 151 if (DC == 0) 152 DC = Parent->getLexicalDeclContext(); 153 BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast<Stmt*>(S)); 154} 155