IndexBody.cpp revision 76da55d3a49e1805f51b1ced7c5da5bcd7f759d8
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#include "RecursiveASTVisitor.h" 12 13using namespace clang; 14using namespace cxindex; 15 16namespace { 17 18class BodyIndexer : public cxindex::RecursiveASTVisitor<BodyIndexer> { 19 IndexingContext &IndexCtx; 20 const NamedDecl *Parent; 21 const DeclContext *ParentDC; 22 23 typedef RecursiveASTVisitor<BodyIndexer> base; 24public: 25 BodyIndexer(IndexingContext &indexCtx, 26 const NamedDecl *Parent, const DeclContext *DC) 27 : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) { } 28 29 bool shouldWalkTypesOfTypeLocs() const { return false; } 30 31 bool TraverseTypeLoc(TypeLoc TL) { 32 IndexCtx.indexTypeLoc(TL, Parent, ParentDC); 33 return true; 34 } 35 36 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { 37 IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC); 38 return true; 39 } 40 41 bool VisitDeclRefExpr(DeclRefExpr *E) { 42 IndexCtx.handleReference(E->getDecl(), E->getLocation(), 43 Parent, ParentDC, E); 44 return true; 45 } 46 47 bool VisitMemberExpr(MemberExpr *E) { 48 IndexCtx.handleReference(E->getMemberDecl(), E->getMemberLoc(), 49 Parent, ParentDC, E); 50 return true; 51 } 52 53 bool VisitDesignatedInitExpr(DesignatedInitExpr *E) { 54 for (DesignatedInitExpr::reverse_designators_iterator 55 D = E->designators_rbegin(), DEnd = E->designators_rend(); 56 D != DEnd; ++D) { 57 if (D->isFieldDesignator()) 58 IndexCtx.handleReference(D->getField(), D->getFieldLoc(), 59 Parent, ParentDC, E); 60 } 61 return true; 62 } 63 64 bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { 65 IndexCtx.handleReference(E->getDecl(), E->getLocation(), 66 Parent, ParentDC, E); 67 return true; 68 } 69 70 bool VisitObjCMessageExpr(ObjCMessageExpr *E) { 71 if (TypeSourceInfo *Cls = E->getClassReceiverTypeInfo()) 72 IndexCtx.indexTypeSourceInfo(Cls, Parent, ParentDC); 73 74 if (ObjCMethodDecl *MD = E->getMethodDecl()) 75 IndexCtx.handleReference(MD, E->getSelectorStartLoc(), 76 Parent, ParentDC, E, 77 E->isImplicit() ? CXIdxEntityRef_Implicit 78 : CXIdxEntityRef_Direct); 79 return true; 80 } 81 82 bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { 83 if (E->isExplicitProperty()) 84 IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(), 85 Parent, ParentDC, E); 86 87 // No need to do a handleReference for the objc method, because there will 88 // be a message expr as part of PseudoObjectExpr. 89 return true; 90 } 91 92 bool VisitMSPropertyRefExpr(MSPropertyRefExpr *E) { 93 IndexCtx.handleReference(E->getPropertyDecl(), E->getMemberLoc(), Parent, 94 ParentDC, E, CXIdxEntityRef_Direct); 95 return true; 96 } 97 98 bool VisitObjCProtocolExpr(ObjCProtocolExpr *E) { 99 IndexCtx.handleReference(E->getProtocol(), E->getProtocolIdLoc(), 100 Parent, ParentDC, E, CXIdxEntityRef_Direct); 101 return true; 102 } 103 104 bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) { 105 if (ObjCMethodDecl *MD = E->getBoxingMethod()) 106 IndexCtx.handleReference(MD, E->getLocStart(), 107 Parent, ParentDC, E, CXIdxEntityRef_Implicit); 108 return true; 109 } 110 111 bool VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) { 112 if (ObjCMethodDecl *MD = E->getDictWithObjectsMethod()) 113 IndexCtx.handleReference(MD, E->getLocStart(), 114 Parent, ParentDC, E, CXIdxEntityRef_Implicit); 115 return true; 116 } 117 118 bool VisitObjCArrayLiteral(ObjCArrayLiteral *E) { 119 if (ObjCMethodDecl *MD = E->getArrayWithObjectsMethod()) 120 IndexCtx.handleReference(MD, E->getLocStart(), 121 Parent, ParentDC, E, CXIdxEntityRef_Implicit); 122 return true; 123 } 124 125 bool VisitCXXConstructExpr(CXXConstructExpr *E) { 126 IndexCtx.handleReference(E->getConstructor(), E->getLocation(), 127 Parent, ParentDC, E); 128 return true; 129 } 130 131 bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E) { 132 if (E->getOperatorLoc().isInvalid()) 133 return true; // implicit. 134 return base::TraverseCXXOperatorCallExpr(E); 135 } 136 137 bool VisitDeclStmt(DeclStmt *S) { 138 if (IndexCtx.shouldIndexFunctionLocalSymbols()) { 139 IndexCtx.indexDeclGroupRef(S->getDeclGroup()); 140 return true; 141 } 142 143 DeclGroupRef DG = S->getDeclGroup(); 144 for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) { 145 const Decl *D = *I; 146 if (!D) 147 continue; 148 if (!IndexCtx.isFunctionLocalDecl(D)) 149 IndexCtx.indexTopLevelDecl(D); 150 } 151 152 return true; 153 } 154 155 bool TraverseLambdaCapture(LambdaExpr::Capture C) { 156 if (C.capturesThis()) 157 return true; 158 159 if (IndexCtx.shouldIndexFunctionLocalSymbols()) 160 IndexCtx.handleReference(C.getCapturedVar(), C.getLocation(), 161 Parent, ParentDC); 162 return true; 163 } 164 165}; 166 167} // anonymous namespace 168 169void IndexingContext::indexBody(const Stmt *S, const NamedDecl *Parent, 170 const DeclContext *DC) { 171 if (!S) 172 return; 173 174 if (DC == 0) 175 DC = Parent->getLexicalDeclContext(); 176 BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast<Stmt*>(S)); 177} 178