//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Clang-C Source Indexing library.
//
//===----------------------------------------------------------------------===//
#include "clang-c/Index.h"
#include "clang/Index/Program.h"
#include "clang/Index/Indexer.h"
#include "clang/Index/ASTLocation.h"
#include "clang/Index/Utils.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/Decl.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/ASTUnit.h"
#include "llvm/Config/config.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/System/Path.h"
#include "llvm/System/Program.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdio>
#include <vector>
#ifdef LLVM_ON_WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#include <dlfcn.h>
#endif
using namespace clang;
using namespace idx;
namespace {
static enum CXCursorKind TranslateDeclRefExpr(DeclRefExpr *DRE)
{
NamedDecl *D = DRE->getDecl();
if (isa<VarDecl>(D))
return CXCursor_VarRef;
else if (isa<FunctionDecl>(D))
return CXCursor_FunctionRef;
else if (isa<EnumConstantDecl>(D))
return CXCursor_EnumConstantRef;
else
return CXCursor_NotImplemented;
}
#if 0
// Will be useful one day.
class CRefVisitor : public StmtVisitor<CRefVisitor> {
CXDecl CDecl;
CXDeclIterator Callback;
CXClientData CData;
void Call(enum CXCursorKind CK, Stmt *SRef) {
CXCursor C = { CK, CDecl, SRef };
Callback(CDecl, C, CData);
}
public:
CRefVisitor(CXDecl C, CXDeclIterator cback, CXClientData D) :
CDecl(C), Callback(cback), CData(D) {}
void VisitStmt(Stmt *S) {
for (Stmt::child_iterator C = S->child_begin(), CEnd = S->child_end();
C != CEnd; ++C)
Visit(*C);
}
void VisitDeclRefExpr(DeclRefExpr *Node) {
Call(TranslateDeclRefExpr(Node), Node);
}
void VisitMemberExpr(MemberExpr *Node) {
Call(CXCursor_MemberRef, Node);
}
void VisitObjCMessageExpr(ObjCMessageExpr *Node) {
Call(CXCursor_ObjCSelectorRef, Node);
}
void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
Call(CXCursor_ObjCIvarRef, Node);
}
};
#endif
/// IgnoreDiagnosticsClient - A DiagnosticsClient that just ignores emitted
/// warnings and errors.
class VISIBILITY_HIDDEN IgnoreDiagnosticsClient : public DiagnosticClient {
public:
virtual ~IgnoreDiagnosticsClient() {}
virtual void HandleDiagnostic(Diagnostic::Level, const DiagnosticInfo &) {}
};
// Translation Unit Visitor.
class TUVisitor : public DeclVisitor<TUVisitor> {
CXTranslationUnit TUnit;
CXTranslationUnitIterator Callback;
CXClientData CData;
// MaxPCHLevel - the maximum PCH level of declarations that we will pass on
// to the visitor. Declarations with a PCH level greater than this value will
// be suppressed.
unsigned MaxPCHLevel;
void Call(enum CXCursorKind CK, NamedDecl *ND) {
// Filter any declarations that have a PCH level greater than what we allow.
if (ND->getPCHLevel() > MaxPCHLevel)
return;
CXCursor C = { CK, ND, 0 };
Callback(TUnit, C, CData);
}
public:
TUVisitor(CXTranslationUnit CTU,
CXTranslationUnitIterator cback, CXClientData D,
unsigned MaxPCHLevel) :
TUnit(CTU), Callback(cback), CData(D), MaxPCHLevel(MaxPCHLevel) {}
void VisitTranslationUnitDecl(TranslationUnitDecl *D) {
VisitDeclContext(dyn_cast<DeclContext>(D));
}
void VisitDeclContext(DeclContext *DC) {
for (DeclContext::decl_iterator
I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I)
Visit(*I);
}
void VisitTypedefDecl(TypedefDecl *ND) {
Call(CXCursor_TypedefDecl, ND);
}
void VisitTagDecl(TagDecl *ND) {
switch (ND->getTagKind()) {
case TagDecl::TK_struct:
Call(CXCursor_StructDecl, ND);
break;
case TagDecl::TK_class:
Call(CXCursor_ClassDecl, ND);
break;
case TagDecl::TK_union:
Call(CXCursor_UnionDecl, ND);
break;
case TagDecl::TK_enum:
Call(CXCursor_EnumDecl, ND);
break;
}
}
void VisitVarDecl(VarDecl *ND) {
Call(CXCursor_VarDecl, ND);
}
void VisitFunctionDecl(FunctionDecl *ND) {
Call(ND->isThisDeclarationADefinition() ? CXCursor_FunctionDefn
: CXCursor_FunctionDecl, ND);
}
void VisitObjCInterfaceDecl(ObjCInterfaceDecl *ND) {
Call(CXCursor_ObjCInterfaceDecl, ND);
}
void VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
Call(CXCursor_ObjCCategoryDecl, ND);
}
void VisitObjCProtocolDecl(ObjCProtocolDecl *ND) {
Call(CXCursor_ObjCProtocolDecl, ND);
}
void VisitObjCImplementationDecl(ObjCImplementationDecl *ND) {
Call(CXCursor_ObjCClassDefn, ND);
}