IndexDecl.cpp revision 6ec43adc39006a7fce94188956d0239bd54c0363
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 IndexCtx.handleObjCImplementation(D); 112 113 IndexCtx.indexTUDeclsInObjCContainer(); 114 IndexCtx.indexDeclContext(D); 115 return true; 116 } 117 118 bool VisitObjCCategoryDecl(ObjCCategoryDecl *D) { 119 IndexCtx.handleObjCCategory(D); 120 121 IndexCtx.indexTUDeclsInObjCContainer(); 122 IndexCtx.indexDeclContext(D); 123 return true; 124 } 125 126 bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { 127 if (D->getCategoryDecl()->getLocation().isInvalid()) 128 return true; 129 130 IndexCtx.handleObjCCategoryImpl(D); 131 132 IndexCtx.indexTUDeclsInObjCContainer(); 133 IndexCtx.indexDeclContext(D); 134 return true; 135 } 136 137 bool VisitObjCMethodDecl(ObjCMethodDecl *D) { 138 IndexCtx.handleObjCMethod(D); 139 IndexCtx.indexTypeSourceInfo(D->getResultTypeSourceInfo(), D); 140 for (ObjCMethodDecl::param_iterator 141 I = D->param_begin(), E = D->param_end(); I != E; ++I) 142 IndexCtx.indexTypeSourceInfo((*I)->getTypeSourceInfo(), D); 143 144 if (D->isThisDeclarationADefinition()) { 145 const Stmt *Body = D->getBody(); 146 if (Body) { 147 IndexCtx.indexBody(Body, D); 148 } 149 } 150 return true; 151 } 152 153 bool VisitObjCPropertyDecl(ObjCPropertyDecl *D) { 154 IndexCtx.handleObjCProperty(D); 155 IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D); 156 return true; 157 } 158}; 159 160} // anonymous namespace 161 162void IndexingContext::indexDecl(const Decl *D) { 163 bool Handled = IndexingDeclVisitor(*this).Visit(const_cast<Decl*>(D)); 164 if (!Handled && isa<DeclContext>(D)) 165 indexDeclContext(cast<DeclContext>(D)); 166} 167 168void IndexingContext::indexDeclContext(const DeclContext *DC) { 169 for (DeclContext::decl_iterator 170 I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) { 171 indexDecl(*I); 172 } 173} 174 175void IndexingContext::indexDeclGroupRef(DeclGroupRef DG) { 176 for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) { 177 Decl *D = *I; 178 if (isNotFromSourceFile(D->getLocation())) 179 return; 180 181 if (isa<ObjCMethodDecl>(D)) 182 continue; // Wait for the objc container. 183 184 indexDecl(D); 185 } 186} 187 188void IndexingContext::indexTUDeclsInObjCContainer() { 189 for (unsigned i = 0, e = TUDeclsInObjCContainer.size(); i != e; ++i) 190 indexDeclGroupRef(TUDeclsInObjCContainer[i]); 191 TUDeclsInObjCContainer.clear(); 192} 193