IndexDecl.cpp revision 21ee5707e6e59d982d2f2ae28e079c7ff46dc519
147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner//===- CIndexHigh.cpp - Higher level API functions ------------------------===// 247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner// 347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner// The LLVM Compiler Infrastructure 447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner// 547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner// This file is distributed under the University of Illinois Open Source 647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner// License. See LICENSE.TXT for details. 747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner// 847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner//===----------------------------------------------------------------------===// 947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 1047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include "IndexingContext.h" 1147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 1247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include "clang/AST/DeclVisitor.h" 1347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 1447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnerusing namespace clang; 1547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnerusing namespace cxindex; 1647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 1747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnernamespace { 1847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 1947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnerclass IndexingDeclVisitor : public DeclVisitor<IndexingDeclVisitor, bool> { 2047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner IndexingContext &IndexCtx; 2147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 2247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnerpublic: 2347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner explicit IndexingDeclVisitor(IndexingContext &indexCtx) 2447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner : IndexCtx(indexCtx) { } 2547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 2647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner bool VisitFunctionDecl(FunctionDecl *D) { 2747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner IndexCtx.handleFunction(D); 2847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D); 2947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (D->isThisDeclarationADefinition()) { 3047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner const Stmt *Body = D->getBody(); 3147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (Body) { 3247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner IndexCtx.indexBody(Body, D); 3347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 3447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 3547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return true; 3647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 3747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 3847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner bool VisitVarDecl(VarDecl *D) { 3947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner IndexCtx.handleVar(D); 4047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D); 4147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return true; 4247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 4347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 4447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner bool VisitFieldDecl(FieldDecl *D) { 4547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner IndexCtx.handleField(D); 4647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D); 4747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return true; 4847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 4947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 5047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner bool VisitEnumConstantDecl(EnumConstantDecl *D) { 5147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner IndexCtx.handleEnumerator(D); 5247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return true; 5347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 5447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 5547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner bool VisitTypedefDecl(TypedefDecl *D) { 5647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner IndexCtx.handleTypedef(D); 5747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D); 5847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return true; 5947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 6047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 6147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner bool VisitTagDecl(TagDecl *D) { 6247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner // Non-free standing tags are handled in indexTypeSourceInfo. 6347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (D->isFreeStanding()) 6447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner IndexCtx.indexTagDecl(D); 6547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return true; 6647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 6747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 6847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner bool VisitObjCClassDecl(ObjCClassDecl *D) { 6947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner IndexCtx.handleObjCClass(D); 7047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return true; 7147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 7247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 7347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) { 7447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner ObjCForwardProtocolDecl::protocol_loc_iterator LI = D->protocol_loc_begin(); 7547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner for (ObjCForwardProtocolDecl::protocol_iterator 7647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I, ++LI) { 7747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner SourceLocation Loc = *LI; 7847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner ObjCProtocolDecl *PD = *I; 7947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 8047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner bool isRedeclaration = PD->getLocation() != Loc; 8147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner IndexCtx.handleObjCForwardProtocol(PD, Loc, isRedeclaration); 8247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 8347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return true; 8447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 8547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 8647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) { 8747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner // Forward decls are handled at VisitObjCClassDecl. 8847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (D->isForwardDecl()) 8947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return true; 9047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 9147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner IndexCtx.handleObjCInterface(D); 9247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 9347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner IndexCtx.indexTUDeclsInObjCContainer(); 9447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner IndexCtx.indexDeclContext(D); 9547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return true; 9647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 9747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 9847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner bool VisitObjCProtocolDecl(ObjCProtocolDecl *D) { 9947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner // Forward decls are handled at VisitObjCForwardProtocolDecl. 10047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (D->isForwardDecl()) 10147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return true; 10247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 10347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner IndexCtx.handleObjCProtocol(D); 10447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 10547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner IndexCtx.indexTUDeclsInObjCContainer(); 10647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner IndexCtx.indexDeclContext(D); 10747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return true; 10847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 10947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 11047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner bool VisitObjCImplementationDecl(ObjCImplementationDecl *D) { 11147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner IndexCtx.handleObjCImplementation(D); 11247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 11347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner IndexCtx.indexTUDeclsInObjCContainer(); 11447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner IndexCtx.indexDeclContext(D); 11547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return true; 11647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 11747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 11847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner bool VisitObjCCategoryDecl(ObjCCategoryDecl *D) { 11947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner IndexCtx.handleObjCCategory(D); 12047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 12147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner IndexCtx.indexTUDeclsInObjCContainer(); 12247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner IndexCtx.indexDeclContext(D); 12347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return true; 12447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 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::indexTopLevelDecl(Decl *D) { 176 if (isNotFromSourceFile(D->getLocation())) 177 return; 178 179 if (isa<ObjCMethodDecl>(D)) 180 return; // Wait for the objc container. 181 182 indexDecl(D); 183} 184 185void IndexingContext::indexDeclGroupRef(DeclGroupRef DG) { 186 for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) 187 indexTopLevelDecl(*I); 188} 189 190void IndexingContext::indexTUDeclsInObjCContainer() { 191 for (unsigned i = 0, e = TUDeclsInObjCContainer.size(); i != e; ++i) 192 indexDeclGroupRef(TUDeclsInObjCContainer[i]); 193 TUDeclsInObjCContainer.clear(); 194} 195