IndexDecl.cpp revision 68478b0cc1ff03c0d13ceca6800c5becf08791e7
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 VisitNamespaceDecl(NamespaceDecl *D) { 193 IndexCtx.handleNamespace(D); 194 IndexCtx.indexDeclContext(D); 195 return true; 196 } 197 198 bool VisitClassTemplateDecl(ClassTemplateDecl *D) { 199 IndexCtx.handleClassTemplate(D); 200 if (D->isThisDeclarationADefinition()) 201 IndexCtx.indexDeclContext(D->getTemplatedDecl()); 202 return true; 203 } 204 205 bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { 206 IndexCtx.handleFunctionTemplate(D); 207 FunctionDecl *FD = D->getTemplatedDecl(); 208 IndexCtx.indexTypeSourceInfo(FD->getTypeSourceInfo(), D); 209 if (FD->isThisDeclarationADefinition()) { 210 const Stmt *Body = FD->getBody(); 211 if (Body) { 212 IndexCtx.indexBody(Body, FD); 213 } 214 } 215 return true; 216 } 217 218 bool VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) { 219 IndexCtx.handleTypeAliasTemplate(D); 220 IndexCtx.indexTypeSourceInfo(D->getTemplatedDecl()->getTypeSourceInfo(), D); 221 return true; 222 } 223}; 224 225} // anonymous namespace 226 227void IndexingContext::indexDecl(const Decl *D) { 228 bool Handled = IndexingDeclVisitor(*this).Visit(const_cast<Decl*>(D)); 229 if (!Handled && isa<DeclContext>(D)) 230 indexDeclContext(cast<DeclContext>(D)); 231} 232 233void IndexingContext::indexDeclContext(const DeclContext *DC) { 234 for (DeclContext::decl_iterator 235 I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) { 236 indexDecl(*I); 237 } 238} 239 240void IndexingContext::indexTopLevelDecl(Decl *D) { 241 if (isNotFromSourceFile(D->getLocation())) 242 return; 243 244 if (isa<ObjCMethodDecl>(D)) 245 return; // Wait for the objc container. 246 247 indexDecl(D); 248} 249 250void IndexingContext::indexDeclGroupRef(DeclGroupRef DG) { 251 for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) 252 indexTopLevelDecl(*I); 253} 254 255void IndexingContext::indexTUDeclsInObjCContainer() { 256 for (unsigned i = 0, e = TUDeclsInObjCContainer.size(); i != e; ++i) 257 indexDeclGroupRef(TUDeclsInObjCContainer[i]); 258 TUDeclsInObjCContainer.clear(); 259} 260