IndexTypeSourceInfo.cpp revision b395c63b473bf1b3783bff371a993332e8c4c5e3
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 VisitTagTypeLoc(TagTypeLoc TL) {
38    TagDecl *D = TL.getDecl();
39    if (D->getParentFunctionOrMethod())
40      return true;
41
42    if (TL.isDefinition()) {
43      IndexCtx.indexTagDecl(D);
44      return true;
45    }
46
47    if (D->getLocation() == TL.getNameLoc())
48      IndexCtx.handleTagDecl(D);
49    else
50      IndexCtx.handleReference(D, TL.getNameLoc(),
51                               Parent, ParentDC);
52    return true;
53  }
54
55  bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
56    IndexCtx.handleReference(TL.getIFaceDecl(), TL.getNameLoc(),
57                             Parent, ParentDC);
58    return true;
59  }
60
61  bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
62    for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) {
63      IndexCtx.handleReference(TL.getProtocol(i), TL.getProtocolLoc(i),
64                               Parent, ParentDC);
65    }
66    return true;
67  }
68};
69
70} // anonymous namespace
71
72void IndexingContext::indexTypeSourceInfo(TypeSourceInfo *TInfo,
73                                          const NamedDecl *Parent,
74                                          const DeclContext *DC) {
75  if (!TInfo || TInfo->getTypeLoc().isNull())
76    return;
77
78  if (DC == 0)
79    DC = Parent->getDeclContext();
80  indexTypeLoc(TInfo->getTypeLoc(), Parent, DC);
81}
82
83void IndexingContext::indexTypeLoc(TypeLoc TL,
84                                   const NamedDecl *Parent,
85                                   const DeclContext *DC) {
86  TypeIndexer(*this, Parent, DC).TraverseTypeLoc(TL);
87}
88
89void IndexingContext::indexTagDecl(const TagDecl *D) {
90  if (handleTagDecl(D)) {
91    if (D->isThisDeclarationADefinition())
92      indexDeclContext(D);
93  }
94}
95