Home | History | Annotate | Download | only in libclang
      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 
     14 using namespace clang;
     15 using namespace cxindex;
     16 
     17 namespace {
     18 
     19 class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
     20   IndexingContext &IndexCtx;
     21   const DeclContext *ParentDC;
     22 
     23 public:
     24   BodyIndexer(IndexingContext &indexCtx, const DeclContext *DC)
     25     : IndexCtx(indexCtx), ParentDC(DC) { }
     26 
     27   bool shouldWalkTypesOfTypeLocs() const { return false; }
     28 
     29   bool TraverseTypeLoc(TypeLoc TL) {
     30     IndexCtx.indexTypeLoc(TL, 0, ParentDC);
     31     return true;
     32   }
     33 
     34   bool VisitDeclRefExpr(DeclRefExpr *E) {
     35     const NamedDecl *D = E->getDecl();
     36     if (!D)
     37       return true;
     38     if (D->getParentFunctionOrMethod())
     39       return true;
     40 
     41     IndexCtx.handleReference(D, E->getLocation(), 0, ParentDC, E);
     42     return true;
     43   }
     44 
     45   bool VisitMemberExpr(MemberExpr *E) {
     46     const NamedDecl *D = E->getMemberDecl();
     47     if (!D)
     48       return true;
     49     if (D->getParentFunctionOrMethod())
     50       return true;
     51 
     52     IndexCtx.handleReference(D, E->getMemberLoc(), 0, ParentDC, E);
     53     return true;
     54   }
     55 
     56   bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
     57     const NamedDecl *D = E->getDecl();
     58     if (!D)
     59       return true;
     60     if (D->getParentFunctionOrMethod())
     61       return true;
     62 
     63     IndexCtx.handleReference(D, E->getLocation(), 0, ParentDC, E);
     64     return true;
     65   }
     66 
     67   bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
     68     if (ObjCMethodDecl *MD = E->getMethodDecl())
     69       IndexCtx.handleReference(MD, E->getSelectorStartLoc(), 0, ParentDC, E);
     70     return true;
     71   }
     72 
     73   bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
     74     if (E->isImplicitProperty()) {
     75       if (ObjCMethodDecl *MD = E->getImplicitPropertyGetter())
     76         IndexCtx.handleReference(MD, E->getLocation(), 0, ParentDC, E,
     77                                  CXIdxEntityRef_ImplicitProperty);
     78       if (ObjCMethodDecl *MD = E->getImplicitPropertySetter())
     79         IndexCtx.handleReference(MD, E->getLocation(), 0, ParentDC, E,
     80                                  CXIdxEntityRef_ImplicitProperty);
     81     } else {
     82       IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(), 0,
     83                                ParentDC, E);
     84     }
     85     return true;
     86   }
     87 };
     88 
     89 } // anonymous namespace
     90 
     91 void IndexingContext::indexBody(const Stmt *S, const DeclContext *DC) {
     92   BodyIndexer(*this, DC).TraverseStmt(const_cast<Stmt*>(S));
     93 }
     94