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