IndexTypeSourceInfo.cpp revision f59edb96b2d0bfe612b732f19519ab84bb995bd4
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#include "RecursiveASTVisitor.h" 12 13using namespace clang; 14using namespace cxindex; 15 16namespace { 17 18class TypeIndexer : public cxindex::RecursiveASTVisitor<TypeIndexer> { 19 IndexingContext &IndexCtx; 20 const NamedDecl *Parent; 21 const DeclContext *ParentDC; 22 23public: 24 TypeIndexer(IndexingContext &indexCtx, const NamedDecl *parent, 25 const DeclContext *DC) 26 : IndexCtx(indexCtx), Parent(parent), ParentDC(DC) { } 27 28 bool shouldWalkTypesOfTypeLocs() const { return false; } 29 30 bool VisitTypedefTypeLoc(TypedefTypeLoc TL) { 31 IndexCtx.handleReference(TL.getTypedefNameDecl(), TL.getNameLoc(), 32 Parent, ParentDC); 33 return true; 34 } 35 36 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { 37 IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC); 38 return true; 39 } 40 41 bool VisitTagTypeLoc(TagTypeLoc TL) { 42 TagDecl *D = TL.getDecl(); 43 if (D->getParentFunctionOrMethod()) 44 return true; 45 46 if (TL.isDefinition()) { 47 IndexCtx.indexTagDecl(D); 48 return true; 49 } 50 51 if (D->getLocation() == TL.getNameLoc()) 52 IndexCtx.handleTagDecl(D); 53 else 54 IndexCtx.handleReference(D, TL.getNameLoc(), 55 Parent, ParentDC); 56 return true; 57 } 58 59 bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { 60 IndexCtx.handleReference(TL.getIFaceDecl(), TL.getNameLoc(), 61 Parent, ParentDC); 62 return true; 63 } 64 65 bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) { 66 for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) { 67 IndexCtx.handleReference(TL.getProtocol(i), TL.getProtocolLoc(i), 68 Parent, ParentDC); 69 } 70 return true; 71 } 72 73 bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) { 74 if (const TemplateSpecializationType *T = TL.getTypePtr()) { 75 if (IndexCtx.shouldIndexImplicitTemplateInsts()) { 76 if (CXXRecordDecl *RD = T->getAsCXXRecordDecl()) 77 IndexCtx.handleReference(RD, TL.getTemplateNameLoc(), 78 Parent, ParentDC); 79 } else { 80 if (const TemplateDecl *D = T->getTemplateName().getAsTemplateDecl()) 81 IndexCtx.handleReference(D, TL.getTemplateNameLoc(), 82 Parent, ParentDC); 83 } 84 } 85 return true; 86 } 87 88 bool TraverseStmt(Stmt *S) { 89 IndexCtx.indexBody(S, Parent, ParentDC); 90 return true; 91 } 92}; 93 94} // anonymous namespace 95 96void IndexingContext::indexTypeSourceInfo(TypeSourceInfo *TInfo, 97 const NamedDecl *Parent, 98 const DeclContext *DC) { 99 if (!TInfo || TInfo->getTypeLoc().isNull()) 100 return; 101 102 indexTypeLoc(TInfo->getTypeLoc(), Parent, DC); 103} 104 105void IndexingContext::indexTypeLoc(TypeLoc TL, 106 const NamedDecl *Parent, 107 const DeclContext *DC) { 108 if (TL.isNull()) 109 return; 110 111 if (DC == 0) 112 DC = Parent->getLexicalDeclContext(); 113 TypeIndexer(*this, Parent, DC).TraverseTypeLoc(TL); 114} 115 116void IndexingContext::indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, 117 const NamedDecl *Parent, 118 const DeclContext *DC) { 119 if (!NNS) 120 return; 121 122 if (NestedNameSpecifierLoc Prefix = NNS.getPrefix()) 123 indexNestedNameSpecifierLoc(Prefix, Parent, DC); 124 125 if (DC == 0) 126 DC = Parent->getLexicalDeclContext(); 127 SourceLocation Loc = NNS.getSourceRange().getBegin(); 128 129 switch (NNS.getNestedNameSpecifier()->getKind()) { 130 case NestedNameSpecifier::Identifier: 131 case NestedNameSpecifier::Global: 132 break; 133 134 case NestedNameSpecifier::Namespace: 135 handleReference(NNS.getNestedNameSpecifier()->getAsNamespace(), 136 Loc, Parent, DC); 137 break; 138 case NestedNameSpecifier::NamespaceAlias: 139 handleReference(NNS.getNestedNameSpecifier()->getAsNamespaceAlias(), 140 Loc, Parent, DC); 141 break; 142 143 case NestedNameSpecifier::TypeSpec: 144 case NestedNameSpecifier::TypeSpecWithTemplate: 145 indexTypeLoc(NNS.getTypeLoc(), Parent, DC); 146 break; 147 } 148} 149 150void IndexingContext::indexTagDecl(const TagDecl *D) { 151 if (handleTagDecl(D)) { 152 if (D->isThisDeclarationADefinition()) 153 indexDeclContext(D); 154 } 155} 156