summaryrefslogtreecommitdiff
path: root/clang/tools/libclang/IndexBody.cpp
diff options
context:
space:
mode:
authorZancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au>2012-09-24 09:58:17 +1000
committerZancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au>2012-09-24 09:58:17 +1000
commit222e2a7620e6520ffaf4fc4e69d79c18da31542e (patch)
tree7bfbc05bfa3b41c8f9d2e56d53a0bc3e310df239 /clang/tools/libclang/IndexBody.cpp
parent3d206f03985b50beacae843d880bccdc91a9f424 (diff)
Add the clang library to the repo (with some of my changes, too).
Diffstat (limited to 'clang/tools/libclang/IndexBody.cpp')
-rw-r--r--clang/tools/libclang/IndexBody.cpp154
1 files changed, 154 insertions, 0 deletions
diff --git a/clang/tools/libclang/IndexBody.cpp b/clang/tools/libclang/IndexBody.cpp
new file mode 100644
index 0000000..74a8d37
--- /dev/null
+++ b/clang/tools/libclang/IndexBody.cpp
@@ -0,0 +1,154 @@
+//===- CIndexHigh.cpp - Higher level API functions ------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "IndexingContext.h"
+
+#include "clang/AST/RecursiveASTVisitor.h"
+
+using namespace clang;
+using namespace cxindex;
+
+namespace {
+
+class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
+ IndexingContext &IndexCtx;
+ const NamedDecl *Parent;
+ const DeclContext *ParentDC;
+
+ typedef RecursiveASTVisitor<BodyIndexer> base;
+public:
+ BodyIndexer(IndexingContext &indexCtx,
+ const NamedDecl *Parent, const DeclContext *DC)
+ : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) { }
+
+ bool shouldWalkTypesOfTypeLocs() const { return false; }
+
+ bool TraverseTypeLoc(TypeLoc TL) {
+ IndexCtx.indexTypeLoc(TL, Parent, ParentDC);
+ return true;
+ }
+
+ bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
+ IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
+ return true;
+ }
+
+ bool VisitDeclRefExpr(DeclRefExpr *E) {
+ IndexCtx.handleReference(E->getDecl(), E->getLocation(),
+ Parent, ParentDC, E);
+ return true;
+ }
+
+ bool VisitMemberExpr(MemberExpr *E) {
+ IndexCtx.handleReference(E->getMemberDecl(), E->getMemberLoc(),
+ Parent, ParentDC, E);
+ return true;
+ }
+
+ bool VisitDesignatedInitExpr(DesignatedInitExpr *E) {
+ for (DesignatedInitExpr::reverse_designators_iterator
+ D = E->designators_rbegin(), DEnd = E->designators_rend();
+ D != DEnd; ++D) {
+ if (D->isFieldDesignator())
+ IndexCtx.handleReference(D->getField(), D->getFieldLoc(),
+ Parent, ParentDC, E);
+ }
+ return true;
+ }
+
+ bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
+ IndexCtx.handleReference(E->getDecl(), E->getLocation(),
+ Parent, ParentDC, E);
+ return true;
+ }
+
+ bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
+ if (TypeSourceInfo *Cls = E->getClassReceiverTypeInfo())
+ IndexCtx.indexTypeSourceInfo(Cls, Parent, ParentDC);
+
+ if (ObjCMethodDecl *MD = E->getMethodDecl())
+ IndexCtx.handleReference(MD, E->getSelectorStartLoc(),
+ Parent, ParentDC, E,
+ E->isImplicit() ? CXIdxEntityRef_Implicit
+ : CXIdxEntityRef_Direct);
+ return true;
+ }
+
+ bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
+ if (E->isExplicitProperty())
+ IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(),
+ Parent, ParentDC, E);
+
+ // No need to do a handleReference for the objc method, because there will
+ // be a message expr as part of PseudoObjectExpr.
+ return true;
+ }
+
+ bool VisitObjCNumericLiteral(ObjCNumericLiteral *E) {
+ if (ObjCMethodDecl *MD = E->getObjCNumericLiteralMethod())
+ IndexCtx.handleReference(MD, E->getLocStart(),
+ Parent, ParentDC, E, CXIdxEntityRef_Implicit);
+ return true;
+ }
+
+ bool VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
+ if (ObjCMethodDecl *MD = E->getDictWithObjectsMethod())
+ IndexCtx.handleReference(MD, E->getLocStart(),
+ Parent, ParentDC, E, CXIdxEntityRef_Implicit);
+ return true;
+ }
+
+ bool VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
+ if (ObjCMethodDecl *MD = E->getArrayWithObjectsMethod())
+ IndexCtx.handleReference(MD, E->getLocStart(),
+ Parent, ParentDC, E, CXIdxEntityRef_Implicit);
+ return true;
+ }
+
+ bool VisitCXXConstructExpr(CXXConstructExpr *E) {
+ IndexCtx.handleReference(E->getConstructor(), E->getLocation(),
+ Parent, ParentDC, E);
+ return true;
+ }
+
+ bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
+ if (E->getOperatorLoc().isInvalid())
+ return true; // implicit.
+ return base::TraverseCXXOperatorCallExpr(E);
+ }
+
+ bool VisitDeclStmt(DeclStmt *S) {
+ if (IndexCtx.shouldIndexFunctionLocalSymbols())
+ IndexCtx.indexDeclGroupRef(S->getDeclGroup());
+ return true;
+ }
+
+ bool TraverseLambdaCapture(LambdaExpr::Capture C) {
+ if (C.capturesThis())
+ return true;
+
+ if (IndexCtx.shouldIndexFunctionLocalSymbols())
+ IndexCtx.handleReference(C.getCapturedVar(), C.getLocation(),
+ Parent, ParentDC);
+ return true;
+ }
+
+};
+
+} // anonymous namespace
+
+void IndexingContext::indexBody(const Stmt *S, const NamedDecl *Parent,
+ const DeclContext *DC) {
+ if (!S)
+ return;
+
+ if (DC == 0)
+ DC = Parent->getLexicalDeclContext();
+ BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast<Stmt*>(S));
+}