IndexDecl.cpp revision e7bbab91f5cc899104d0a1dee6059d8413c70eeb
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 "clang/AST/DeclVisitor.h" 13 14using namespace clang; 15using namespace cxindex; 16 17namespace { 18 19class IndexingDeclVisitor : public DeclVisitor<IndexingDeclVisitor, bool> { 20 IndexingContext &IndexCtx; 21 22public: 23 explicit IndexingDeclVisitor(IndexingContext &indexCtx) 24 : IndexCtx(indexCtx) { } 25 26 bool VisitFunctionDecl(FunctionDecl *D) { 27 IndexCtx.handleFunction(D); 28 IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D); 29 if (D->isThisDeclarationADefinition()) { 30 const Stmt *Body = D->getBody(); 31 if (Body) { 32 IndexCtx.indexBody(Body, D); 33 } 34 } 35 return true; 36 } 37 38 bool VisitVarDecl(VarDecl *D) { 39 IndexCtx.handleVar(D); 40 IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D); 41 return true; 42 } 43 44 bool VisitFieldDecl(FieldDecl *D) { 45 IndexCtx.handleField(D); 46 IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D); 47 return true; 48 } 49 50 bool VisitEnumConstantDecl(EnumConstantDecl *D) { 51 IndexCtx.handleEnumerator(D); 52 return true; 53 } 54 55 bool VisitTypedefDecl(TypedefDecl *D) { 56 IndexCtx.handleTypedef(D); 57 IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D); 58 return true; 59 } 60 61 bool VisitTagDecl(TagDecl *D) { 62 // Non-free standing tags are handled in indexTypeSourceInfo. 63 if (D->isFreeStanding()) 64 IndexCtx.indexTagDecl(D); 65 return true; 66 } 67 68 bool VisitObjCClassDecl(ObjCClassDecl *D) { 69 IndexCtx.handleObjCClass(D); 70 return true; 71 } 72 73 bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) { 74 ObjCForwardProtocolDecl::protocol_loc_iterator LI = D->protocol_loc_begin(); 75 for (ObjCForwardProtocolDecl::protocol_iterator 76 I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I, ++LI) { 77 SourceLocation Loc = *LI; 78 ObjCProtocolDecl *PD = *I; 79 80 bool isRedeclaration = PD->getLocation() != Loc; 81 IndexCtx.handleObjCForwardProtocol(PD, Loc, isRedeclaration); 82 } 83 return true; 84 } 85 86 bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) { 87 // Forward decls are handled at VisitObjCClassDecl. 88 if (D->isForwardDecl()) 89 return true; 90 91 IndexCtx.handleObjCInterface(D); 92 93 IndexCtx.indexTUDeclsInObjCContainer(); 94 IndexCtx.indexDeclContext(D); 95 return true; 96 } 97 98 bool VisitObjCProtocolDecl(ObjCProtocolDecl *D) { 99 // Forward decls are handled at VisitObjCForwardProtocolDecl. 100 if (D->isForwardDecl()) 101 return true; 102 103 IndexCtx.handleObjCProtocol(D); 104 105 IndexCtx.indexTUDeclsInObjCContainer(); 106 IndexCtx.indexDeclContext(D); 107 return true; 108 } 109 110 bool VisitObjCImplementationDecl(ObjCImplementationDecl *D) { 111 const ObjCInterfaceDecl *Class = D->getClassInterface(); 112 if (Class->isImplicitInterfaceDecl()) 113 IndexCtx.handleObjCInterface(Class); 114 115 IndexCtx.handleObjCImplementation(D); 116 117 IndexCtx.indexTUDeclsInObjCContainer(); 118 IndexCtx.indexDeclContext(D); 119 return true; 120 } 121 122 bool VisitObjCCategoryDecl(ObjCCategoryDecl *D) { 123 IndexCtx.handleObjCCategory(D); 124 125 IndexCtx.indexTUDeclsInObjCContainer(); 126 IndexCtx.indexDeclContext(D); 127 return true; 128 } 129 130 bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { 131 if (D->getCategoryDecl()->getLocation().isInvalid()) 132 return true; 133 134 IndexCtx.handleObjCCategoryImpl(D); 135 136 IndexCtx.indexTUDeclsInObjCContainer(); 137 IndexCtx.indexDeclContext(D); 138 return true; 139 } 140 141 bool VisitObjCMethodDecl(ObjCMethodDecl *D) { 142 IndexCtx.handleObjCMethod(D); 143 IndexCtx.indexTypeSourceInfo(D->getResultTypeSourceInfo(), D); 144 for (ObjCMethodDecl::param_iterator 145 I = D->param_begin(), E = D->param_end(); I != E; ++I) 146 IndexCtx.indexTypeSourceInfo((*I)->getTypeSourceInfo(), D); 147 148 if (D->isThisDeclarationADefinition()) { 149 const Stmt *Body = D->getBody(); 150 if (Body) { 151 IndexCtx.indexBody(Body, D); 152 } 153 } 154 return true; 155 } 156 157 bool VisitObjCPropertyDecl(ObjCPropertyDecl *D) { 158 IndexCtx.handleObjCProperty(D); 159 IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D); 160 return true; 161 } 162}; 163 164} // anonymous namespace 165 166void IndexingContext::indexDecl(const Decl *D) { 167 bool Handled = IndexingDeclVisitor(*this).Visit(const_cast<Decl*>(D)); 168 if (!Handled && isa<DeclContext>(D)) 169 indexDeclContext(cast<DeclContext>(D)); 170} 171 172void IndexingContext::indexDeclContext(const DeclContext *DC) { 173 for (DeclContext::decl_iterator 174 I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) { 175 indexDecl(*I); 176 } 177} 178 179void IndexingContext::indexTopLevelDecl(Decl *D) { 180 if (isNotFromSourceFile(D->getLocation())) 181 return; 182 183 if (isa<ObjCMethodDecl>(D)) 184 return; // Wait for the objc container. 185 186 indexDecl(D); 187} 188 189void IndexingContext::indexDeclGroupRef(DeclGroupRef DG) { 190 for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) 191 indexTopLevelDecl(*I); 192} 193 194void IndexingContext::indexTUDeclsInObjCContainer() { 195 for (unsigned i = 0, e = TUDeclsInObjCContainer.size(); i != e; ++i) 196 indexDeclGroupRef(TUDeclsInObjCContainer[i]); 197 TUDeclsInObjCContainer.clear(); 198} 199