blob: 9577391288b2a03eba22c9243b6e0eb254fe0bbb [file] [log] [blame]
Ted Kremenekd2fa5662009-08-26 22:36:44 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
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// This file implements the Clang-C Source Indexing library.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang-c/Index.h"
Steve Naroff50398192009-08-28 15:28:48 +000015#include "clang/Index/Program.h"
16#include "clang/Index/Indexer.h"
Steve Naroff50398192009-08-28 15:28:48 +000017#include "clang/AST/DeclVisitor.h"
Benjamin Kramerd01a0bc2009-08-29 12:56:35 +000018#include "clang/Basic/FileManager.h"
Steve Naroff2d4d6292009-08-31 14:26:51 +000019#include "clang/Basic/SourceManager.h"
Benjamin Kramerd01a0bc2009-08-29 12:56:35 +000020#include "clang/Frontend/ASTUnit.h"
21#include <cstdio>
Steve Naroff50398192009-08-28 15:28:48 +000022using namespace clang;
23using namespace idx;
24
Steve Naroff89922f82009-08-31 00:59:03 +000025namespace {
26
27// Translation Unit Visitor.
28class TUVisitor : public DeclVisitor<TUVisitor> {
29 CXTranslationUnit TUnit;
30 CXTranslationUnitIterator Callback;
Steve Naroff2b8ee6c2009-09-01 15:55:40 +000031 CXClientData CData;
32
33 void Call(enum CXCursorKind CK, NamedDecl *ND) {
34 CXCursor C = { CK, ND };
35 Callback(TUnit, C, CData);
36 }
Steve Naroff89922f82009-08-31 00:59:03 +000037public:
Steve Naroff2b8ee6c2009-09-01 15:55:40 +000038 TUVisitor(CXTranslationUnit CTU,
39 CXTranslationUnitIterator cback, CXClientData D) :
40 TUnit(CTU), Callback(cback), CData(D) {}
Steve Naroff89922f82009-08-31 00:59:03 +000041
42 void VisitTranslationUnitDecl(TranslationUnitDecl *D) {
43 VisitDeclContext(dyn_cast<DeclContext>(D));
44 }
45 void VisitDeclContext(DeclContext *DC) {
46 for (DeclContext::decl_iterator
47 I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I)
48 Visit(*I);
49 }
Steve Naroff2b8ee6c2009-09-01 15:55:40 +000050 void VisitTypedefDecl(TypedefDecl *ND) {
51 Call(CXCursor_TypedefDecl, ND);
Steve Naroff89922f82009-08-31 00:59:03 +000052 }
53 void VisitTagDecl(TagDecl *ND) {
Steve Naroff2b8ee6c2009-09-01 15:55:40 +000054 Call(ND->isEnum() ? CXCursor_EnumDecl : CXCursor_RecordDecl, ND);
Steve Naroff89922f82009-08-31 00:59:03 +000055 }
56 void VisitFunctionDecl(FunctionDecl *ND) {
Steve Naroff2b8ee6c2009-09-01 15:55:40 +000057 Call(CXCursor_FunctionDecl, ND);
Steve Naroff89922f82009-08-31 00:59:03 +000058 }
59 void VisitObjCInterfaceDecl(ObjCInterfaceDecl *ND) {
Steve Naroff2b8ee6c2009-09-01 15:55:40 +000060 Call(CXCursor_ObjCInterfaceDecl, ND);
Steve Naroff89922f82009-08-31 00:59:03 +000061 }
62 void VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
Steve Naroff2b8ee6c2009-09-01 15:55:40 +000063 Call(CXCursor_ObjCCategoryDecl, ND);
Steve Naroff89922f82009-08-31 00:59:03 +000064 }
65 void VisitObjCProtocolDecl(ObjCProtocolDecl *ND) {
Steve Naroff2b8ee6c2009-09-01 15:55:40 +000066 Call(CXCursor_ObjCProtocolDecl, ND);
Steve Naroff89922f82009-08-31 00:59:03 +000067 }
68};
69
70// Top-level declaration visitor.
71class TLDeclVisitor : public DeclVisitor<TLDeclVisitor> {
72public:
73 void VisitDeclContext(DeclContext *DC) {
74 for (DeclContext::decl_iterator
75 I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I)
76 Visit(*I);
77 }
78 void VisitEnumConstantDecl(EnumConstantDecl *ND) {
79 }
80 void VisitFieldDecl(FieldDecl *ND) {
81 }
82 void VisitObjCIvarDecl(ObjCIvarDecl *ND) {
83 }
84};
85
86}
87
Steve Naroff600866c2009-08-27 19:51:58 +000088extern "C" {
Ted Kremenekd2fa5662009-08-26 22:36:44 +000089
Steve Naroff600866c2009-08-27 19:51:58 +000090CXIndex clang_createIndex()
Steve Naroff50398192009-08-28 15:28:48 +000091{
92 return new Indexer(*new Program(), *new FileManager());
Steve Naroff600866c2009-08-27 19:51:58 +000093}
94
Steve Naroff50398192009-08-28 15:28:48 +000095// FIXME: need to pass back error info.
96CXTranslationUnit clang_createTranslationUnit(
97 CXIndex CIdx, const char *ast_filename)
Steve Naroff600866c2009-08-27 19:51:58 +000098{
Steve Naroff50398192009-08-28 15:28:48 +000099 assert(CIdx && "Passed null CXIndex");
100 Indexer *CXXIdx = static_cast<Indexer *>(CIdx);
101 std::string astName(ast_filename);
102 std::string ErrMsg;
103
104 return ASTUnit::LoadFromPCHFile(astName, CXXIdx->getFileManager(), &ErrMsg);
Steve Naroff600866c2009-08-27 19:51:58 +0000105}
106
Daniel Dunbar1eb79b52009-08-28 16:30:07 +0000107
Steve Naroff600866c2009-08-27 19:51:58 +0000108void clang_loadTranslationUnit(
Steve Naroff2b8ee6c2009-09-01 15:55:40 +0000109 CXTranslationUnit CTUnit, CXTranslationUnitIterator callback,
110 CXClientData CData)
Steve Naroff600866c2009-08-27 19:51:58 +0000111{
Steve Naroff50398192009-08-28 15:28:48 +0000112 assert(CTUnit && "Passed null CXTranslationUnit");
113 ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit);
114 ASTContext &Ctx = CXXUnit->getASTContext();
115
Steve Naroff2b8ee6c2009-09-01 15:55:40 +0000116 TUVisitor DVisit(CTUnit, callback, CData);
Steve Naroff50398192009-08-28 15:28:48 +0000117 DVisit.Visit(Ctx.getTranslationUnitDecl());
Steve Naroff600866c2009-08-27 19:51:58 +0000118}
119
Steve Naroff89922f82009-08-31 00:59:03 +0000120void clang_loadDeclaration(CXDecl, CXDeclIterator)
Steve Naroff600866c2009-08-27 19:51:58 +0000121{
122}
123
Steve Naroff7e8f8182009-08-28 12:07:44 +0000124// Some notes on CXEntity:
125//
126// - Since the 'ordinary' namespace includes functions, data, typedefs,
127// ObjC interfaces, thecurrent algorithm is a bit naive (resulting in one
128// entity for 2 different types). For example:
129//
130// module1.m: @interface Foo @end Foo *x;
131// module2.m: void Foo(int);
132//
133// - Since the unique name spans translation units, static data/functions
134// within a CXTranslationUnit are *not* currently represented by entities.
135// As a result, there will be no entity for the following:
136//
137// module.m: static void Foo() { }
138//
139
140
Steve Naroff600866c2009-08-27 19:51:58 +0000141const char *clang_getDeclarationName(CXEntity)
142{
143 return "";
144}
145const char *clang_getURI(CXEntity)
146{
147 return "";
148}
149
150CXEntity clang_getEntity(const char *URI)
151{
152 return 0;
153}
154
155//
156// CXDecl Operations.
157//
158CXCursor clang_getCursorFromDecl(CXDecl)
159{
Steve Naroff89922f82009-08-31 00:59:03 +0000160 return CXCursor();
Steve Naroff600866c2009-08-27 19:51:58 +0000161}
162CXEntity clang_getEntityFromDecl(CXDecl)
163{
164 return 0;
165}
Steve Naroff89922f82009-08-31 00:59:03 +0000166const char *clang_getDeclSpelling(CXDecl AnonDecl)
Steve Naroff600866c2009-08-27 19:51:58 +0000167{
Steve Naroff89922f82009-08-31 00:59:03 +0000168 assert(AnonDecl && "Passed null CXDecl");
169 NamedDecl *ND = static_cast<NamedDecl *>(AnonDecl);
170 if (ND->getIdentifier())
171 return ND->getIdentifier()->getName();
172 else
173 return "";
Steve Naroff600866c2009-08-27 19:51:58 +0000174}
Steve Naroff89922f82009-08-31 00:59:03 +0000175const char *clang_getKindSpelling(enum CXCursorKind Kind)
Steve Naroff600866c2009-08-27 19:51:58 +0000176{
Steve Naroff89922f82009-08-31 00:59:03 +0000177 switch (Kind) {
178 case CXCursor_FunctionDecl: return "FunctionDecl";
179 case CXCursor_TypedefDecl: return "TypedefDecl";
180 case CXCursor_EnumDecl: return "EnumDecl";
181 case CXCursor_EnumConstantDecl: return "EnumConstantDecl";
182 case CXCursor_RecordDecl: return "RecordDecl";
183 case CXCursor_FieldDecl: return "FieldDecl";
184 case CXCursor_VarDecl: return "VarDecl";
185 case CXCursor_ParmDecl: return "ParmDecl";
186 case CXCursor_ObjCInterfaceDecl: return "ObjCInterfaceDecl";
187 case CXCursor_ObjCCategoryDecl: return "ObjCCategoryDecl";
188 case CXCursor_ObjCProtocolDecl: return "ObjCProtocolDecl";
189 case CXCursor_ObjCPropertyDecl: return "ObjCPropertyDecl";
190 case CXCursor_ObjCIvarDecl: return "ObjCIvarDecl";
191 case CXCursor_ObjCMethodDecl: return "ObjCMethodDecl";
192 default: return "<not implemented>";
193 }
Steve Naroff600866c2009-08-27 19:51:58 +0000194}
Steve Naroff89922f82009-08-31 00:59:03 +0000195
Steve Naroff600866c2009-08-27 19:51:58 +0000196//
197// CXCursor Operations.
198//
199CXCursor clang_getCursor(CXTranslationUnit, const char *source_name,
200 unsigned line, unsigned column)
201{
Steve Naroff89922f82009-08-31 00:59:03 +0000202 return CXCursor();
Steve Naroff600866c2009-08-27 19:51:58 +0000203}
204
205CXCursorKind clang_getCursorKind(CXCursor)
206{
Steve Naroff89922f82009-08-31 00:59:03 +0000207 return CXCursor_Invalid;
Steve Naroff600866c2009-08-27 19:51:58 +0000208}
209
Steve Naroff89922f82009-08-31 00:59:03 +0000210unsigned clang_isDeclaration(enum CXCursorKind K)
211{
212 return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
213}
Steve Naroff2d4d6292009-08-31 14:26:51 +0000214
215unsigned clang_getCursorLine(CXCursor C)
Steve Naroff600866c2009-08-27 19:51:58 +0000216{
Steve Naroff2d4d6292009-08-31 14:26:51 +0000217 assert(C.decl && "CXCursor has null decl");
218 NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
219 SourceLocation SLoc = ND->getLocation();
220 if (SLoc.isInvalid())
221 return 0;
222 SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
223 SLoc = SourceMgr.getSpellingLoc(SLoc); // handles macro instantiations.
224 return SourceMgr.getSpellingLineNumber(SLoc);
Steve Naroff600866c2009-08-27 19:51:58 +0000225}
Steve Naroff2d4d6292009-08-31 14:26:51 +0000226unsigned clang_getCursorColumn(CXCursor C)
Steve Naroff600866c2009-08-27 19:51:58 +0000227{
Steve Naroff2d4d6292009-08-31 14:26:51 +0000228 assert(C.decl && "CXCursor has null decl");
229 NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
230 SourceLocation SLoc = ND->getLocation();
231 if (SLoc.isInvalid())
232 return 0;
233 SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
234 SLoc = SourceMgr.getSpellingLoc(SLoc); // handles macro instantiations.
235 return SourceMgr.getSpellingColumnNumber(SLoc);
Steve Naroff600866c2009-08-27 19:51:58 +0000236}
Steve Naroff2d4d6292009-08-31 14:26:51 +0000237const char *clang_getCursorSource(CXCursor C)
Steve Naroff600866c2009-08-27 19:51:58 +0000238{
Steve Naroff2d4d6292009-08-31 14:26:51 +0000239 assert(C.decl && "CXCursor has null decl");
240 NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
241 SourceLocation SLoc = ND->getLocation();
242 if (SLoc.isInvalid())
243 return "<invalid source location>";
244 SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
245 SLoc = SourceMgr.getSpellingLoc(SLoc); // handles macro instantiations.
246 return SourceMgr.getBufferName(SLoc);
Steve Naroff600866c2009-08-27 19:51:58 +0000247}
248
249// If CXCursorKind == Cursor_Reference, then this will return the referenced declaration.
250// If CXCursorKind == Cursor_Declaration, then this will return the declaration.
251CXDecl clang_getCursorDecl(CXCursor)
252{
253 return 0;
254}
255
256} // end extern "C"