IndexDecl.cpp revision 37f40572c4c78a8c57a7b45266f8b86db172a7c1
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(TypedefNameDecl *D) { 56 IndexCtx.handleTypedefName(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) 113 return true; 114 115 if (Class->isImplicitInterfaceDecl()) 116 IndexCtx.handleObjCInterface(Class); 117 118 IndexCtx.handleObjCImplementation(D); 119 120 IndexCtx.indexTUDeclsInObjCContainer(); 121 IndexCtx.indexDeclContext(D); 122 return true; 123 } 124 125 bool VisitObjCCategoryDecl(ObjCCategoryDecl *D) { 126 IndexCtx.handleObjCCategory(D); 127 128 IndexCtx.indexTUDeclsInObjCContainer(); 129 IndexCtx.indexDeclContext(D); 130 return true; 131 } 132 133 bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { 134 const ObjCCategoryDecl *Cat = D->getCategoryDecl(); 135 if (!Cat) 136 return true; 137 138 IndexCtx.handleObjCCategoryImpl(D); 139 140 IndexCtx.indexTUDeclsInObjCContainer(); 141 IndexCtx.indexDeclContext(D); 142 return true; 143 } 144 145 bool VisitObjCMethodDecl(ObjCMethodDecl *D) { 146 IndexCtx.handleObjCMethod(D); 147 IndexCtx.indexTypeSourceInfo(D->getResultTypeSourceInfo(), D); 148 for (ObjCMethodDecl::param_iterator 149 I = D->param_begin(), E = D->param_end(); I != E; ++I) 150 IndexCtx.indexTypeSourceInfo((*I)->getTypeSourceInfo(), D); 151 152 if (D->isThisDeclarationADefinition()) { 153 const Stmt *Body = D->getBody(); 154 if (Body) { 155 IndexCtx.indexBody(Body, D); 156 } 157 } 158 return true; 159 } 160 161 bool VisitObjCPropertyDecl(ObjCPropertyDecl *D) { 162 IndexCtx.handleObjCProperty(D); 163 IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D); 164 return true; 165 } 166 167 bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) { 168 ObjCPropertyDecl *PD = D->getPropertyDecl(); 169 IndexCtx.handleSynthesizedObjCProperty(D); 170 171 if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 172 return true; 173 assert(D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize); 174 175 if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) { 176 if (!IvarD->getSynthesize()) 177 IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), 0, 178 D->getDeclContext()); 179 } 180 181 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) { 182 if (MD->isSynthesized()) 183 IndexCtx.handleSynthesizedObjCMethod(MD, D->getLocation()); 184 } 185 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) { 186 if (MD->isSynthesized()) 187 IndexCtx.handleSynthesizedObjCMethod(MD, D->getLocation()); 188 } 189 return true; 190 } 191 192 bool VisitClassTemplateDecl(ClassTemplateDecl *D) { 193 IndexCtx.handleClassTemplate(D); 194 if (D->isThisDeclarationADefinition()) 195 IndexCtx.indexDeclContext(D->getTemplatedDecl()); 196 return true; 197 } 198 199 bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { 200 IndexCtx.handleFunctionTemplate(D); 201 FunctionDecl *FD = D->getTemplatedDecl(); 202 IndexCtx.indexTypeSourceInfo(FD->getTypeSourceInfo(), D); 203 if (FD->isThisDeclarationADefinition()) { 204 const Stmt *Body = FD->getBody(); 205 if (Body) { 206 IndexCtx.indexBody(Body, FD); 207 } 208 } 209 return true; 210 } 211 212 bool VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) { 213 IndexCtx.handleTypeAliasTemplate(D); 214 IndexCtx.indexTypeSourceInfo(D->getTemplatedDecl()->getTypeSourceInfo(), D); 215 return true; 216 } 217}; 218 219} // anonymous namespace 220 221void IndexingContext::indexDecl(const Decl *D) { 222 bool Handled = IndexingDeclVisitor(*this).Visit(const_cast<Decl*>(D)); 223 if (!Handled && isa<DeclContext>(D)) 224 indexDeclContext(cast<DeclContext>(D)); 225} 226 227void IndexingContext::indexDeclContext(const DeclContext *DC) { 228 for (DeclContext::decl_iterator 229 I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) { 230 indexDecl(*I); 231 } 232} 233 234void IndexingContext::indexTopLevelDecl(Decl *D) { 235 if (isNotFromSourceFile(D->getLocation())) 236 return; 237 238 if (isa<ObjCMethodDecl>(D)) 239 return; // Wait for the objc container. 240 241 indexDecl(D); 242} 243 244void IndexingContext::indexDeclGroupRef(DeclGroupRef DG) { 245 for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) 246 indexTopLevelDecl(*I); 247} 248 249void IndexingContext::indexTUDeclsInObjCContainer() { 250 for (unsigned i = 0, e = TUDeclsInObjCContainer.size(); i != e; ++i) 251 indexDeclGroupRef(TUDeclsInObjCContainer[i]); 252 TUDeclsInObjCContainer.clear(); 253} 254