IndexTypeSourceInfo.cpp revision 6d968363877388f0a0268711d59367907b465ae1
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 (const TemplateDecl *D = T->getTemplateName().getAsTemplateDecl()) 77 IndexCtx.handleReference(D, TL.getTemplateNameLoc(), 78 Parent, ParentDC); 79 if (CXXRecordDecl *RD = T->getAsCXXRecordDecl()) 80 IndexCtx.handleReference(RD, TL.getTemplateNameLoc(), 81 Parent, ParentDC); 82 } 83 return true; 84 } 85}; 86 87} // anonymous namespace 88 89void IndexingContext::indexTypeSourceInfo(TypeSourceInfo *TInfo, 90 const NamedDecl *Parent, 91 const DeclContext *DC) { 92 if (!TInfo || TInfo->getTypeLoc().isNull()) 93 return; 94 95 indexTypeLoc(TInfo->getTypeLoc(), Parent, DC); 96} 97 98void IndexingContext::indexTypeLoc(TypeLoc TL, 99 const NamedDecl *Parent, 100 const DeclContext *DC) { 101 if (TL.isNull()) 102 return; 103 104 if (DC == 0) 105 DC = Parent->getLexicalDeclContext(); 106 TypeIndexer(*this, Parent, DC).TraverseTypeLoc(TL); 107} 108 109void IndexingContext::indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, 110 const NamedDecl *Parent, 111 const DeclContext *DC) { 112 if (!NNS) 113 return; 114 115 if (NestedNameSpecifierLoc Prefix = NNS.getPrefix()) 116 indexNestedNameSpecifierLoc(Prefix, Parent, DC); 117 118 if (DC == 0) 119 DC = Parent->getLexicalDeclContext(); 120 SourceLocation Loc = NNS.getSourceRange().getBegin(); 121 122 switch (NNS.getNestedNameSpecifier()->getKind()) { 123 case NestedNameSpecifier::Identifier: 124 case NestedNameSpecifier::Global: 125 break; 126 127 case NestedNameSpecifier::Namespace: 128 handleReference(NNS.getNestedNameSpecifier()->getAsNamespace(), 129 Loc, Parent, DC); 130 break; 131 case NestedNameSpecifier::NamespaceAlias: 132 handleReference(NNS.getNestedNameSpecifier()->getAsNamespaceAlias(), 133 Loc, Parent, DC); 134 break; 135 136 case NestedNameSpecifier::TypeSpec: 137 case NestedNameSpecifier::TypeSpecWithTemplate: 138 indexTypeLoc(NNS.getTypeLoc(), Parent, DC); 139 break; 140 } 141} 142 143void IndexingContext::indexTagDecl(const TagDecl *D) { 144 if (handleTagDecl(D)) { 145 if (D->isThisDeclarationADefinition()) 146 indexDeclContext(D); 147 } 148} 149