blob: bac7e02514b246ec82283d08ea6c6d3585bed0b4 [file] [log] [blame]
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +00001//===- 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"
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +000013#include "clang/Analysis/Support/SaveAndRestore.h"
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000014
15using namespace clang;
16using namespace cxindex;
17
18namespace {
19
20class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
21 IndexingContext &IndexCtx;
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000022 const NamedDecl *Parent;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000023 const DeclContext *ParentDC;
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +000024 bool InPseudoObject;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000025
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +000026 typedef RecursiveASTVisitor<BodyIndexer> base;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000027public:
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000028 BodyIndexer(IndexingContext &indexCtx,
29 const NamedDecl *Parent, const DeclContext *DC)
30 : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC),
31 InPseudoObject(false) { }
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000032
33 bool shouldWalkTypesOfTypeLocs() const { return false; }
34
35 bool TraverseTypeLoc(TypeLoc TL) {
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000036 IndexCtx.indexTypeLoc(TL, Parent, ParentDC);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000037 return true;
38 }
39
40 bool VisitDeclRefExpr(DeclRefExpr *E) {
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000041 IndexCtx.handleReference(E->getDecl(), E->getLocation(),
42 Parent, ParentDC, E);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000043 return true;
44 }
45
46 bool VisitMemberExpr(MemberExpr *E) {
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000047 IndexCtx.handleReference(E->getMemberDecl(), E->getMemberLoc(),
48 Parent, ParentDC, E);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000049 return true;
50 }
51
52 bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000053 IndexCtx.handleReference(E->getDecl(), E->getLocation(),
54 Parent, ParentDC, E);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000055 return true;
56 }
Argyrios Kyrtzidis9fbbf142011-10-18 15:13:11 +000057
58 bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +000059 if (TypeSourceInfo *Cls = E->getClassReceiverTypeInfo())
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000060 IndexCtx.indexTypeSourceInfo(Cls, Parent, ParentDC);
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +000061
Argyrios Kyrtzidis9fbbf142011-10-18 15:13:11 +000062 if (ObjCMethodDecl *MD = E->getMethodDecl())
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000063 IndexCtx.handleReference(MD, E->getSelectorStartLoc(),
64 Parent, ParentDC, E,
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +000065 InPseudoObject ? CXIdxEntityRef_Implicit
66 : CXIdxEntityRef_Direct);
Argyrios Kyrtzidis9fbbf142011-10-18 15:13:11 +000067 return true;
68 }
Argyrios Kyrtzidisaca19be2011-10-18 15:50:50 +000069
70 bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
71 if (E->isImplicitProperty()) {
72 if (ObjCMethodDecl *MD = E->getImplicitPropertyGetter())
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000073 IndexCtx.handleReference(MD, E->getLocation(), Parent, ParentDC, E,
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +000074 CXIdxEntityRef_Implicit);
Argyrios Kyrtzidisaca19be2011-10-18 15:50:50 +000075 if (ObjCMethodDecl *MD = E->getImplicitPropertySetter())
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000076 IndexCtx.handleReference(MD, E->getLocation(), Parent, ParentDC, E,
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +000077 CXIdxEntityRef_Implicit);
Argyrios Kyrtzidisaca19be2011-10-18 15:50:50 +000078 } else {
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000079 IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(),
80 Parent, ParentDC, E);
Argyrios Kyrtzidisaca19be2011-10-18 15:50:50 +000081 }
82 return true;
83 }
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +000084
85 bool TraversePseudoObjectExpr(PseudoObjectExpr *E) {
86 SaveAndRestore<bool> InPseudo(InPseudoObject, true);
87 return base::TraversePseudoObjectExpr(E);
88 }
Argyrios Kyrtzidis2957e6f2011-11-22 07:24:51 +000089
90 bool VisitCXXConstructExpr(CXXConstructExpr *E) {
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000091 IndexCtx.handleReference(E->getConstructor(), E->getLocation(),
92 Parent, ParentDC, E);
Argyrios Kyrtzidis2957e6f2011-11-22 07:24:51 +000093 return true;
94 }
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000095};
96
97} // anonymous namespace
98
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000099void IndexingContext::indexBody(const Stmt *S, const NamedDecl *Parent,
100 const DeclContext *DC) {
101 if (!S)
102 return;
103
104 if (DC == 0)
105 DC = Parent->getLexicalDeclContext();
106 BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast<Stmt*>(S));
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000107}