blob: f8d223a51092b132be2e777814a1359872e50acb [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;
31public:
32 TUVisitor(CXTranslationUnit CTU, CXTranslationUnitIterator cback) :
33 TUnit(CTU), Callback(cback) {}
34
35 void VisitTranslationUnitDecl(TranslationUnitDecl *D) {
36 VisitDeclContext(dyn_cast<DeclContext>(D));
37 }
38 void VisitDeclContext(DeclContext *DC) {
39 for (DeclContext::decl_iterator
40 I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I)
41 Visit(*I);
42 }
43 void VisitTypedefDecl(TypedefDecl *ND) {
44 CXCursor C = { CXCursor_TypedefDecl, ND };
45 Callback(TUnit, C);
46 }
47 void VisitTagDecl(TagDecl *ND) {
48 CXCursor C = { ND->isEnum() ? CXCursor_EnumDecl : CXCursor_RecordDecl, ND };
49 Callback(TUnit, C);
50 }
51 void VisitFunctionDecl(FunctionDecl *ND) {
52 CXCursor C = { CXCursor_FunctionDecl, ND };
53 Callback(TUnit, C);
54 }
55 void VisitObjCInterfaceDecl(ObjCInterfaceDecl *ND) {
56 CXCursor C = { CXCursor_ObjCInterfaceDecl, ND };
57 Callback(TUnit, C);
58 }
59 void VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
60 CXCursor C = { CXCursor_ObjCCategoryDecl, ND };
61 Callback(TUnit, C);
62 }
63 void VisitObjCProtocolDecl(ObjCProtocolDecl *ND) {
64 CXCursor C = { CXCursor_ObjCProtocolDecl, ND };
65 Callback(TUnit, C);
66 }
67};
68
69// Top-level declaration visitor.
70class TLDeclVisitor : public DeclVisitor<TLDeclVisitor> {
71public:
72 void VisitDeclContext(DeclContext *DC) {
73 for (DeclContext::decl_iterator
74 I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I)
75 Visit(*I);
76 }
77 void VisitEnumConstantDecl(EnumConstantDecl *ND) {
78 }
79 void VisitFieldDecl(FieldDecl *ND) {
80 }
81 void VisitObjCIvarDecl(ObjCIvarDecl *ND) {
82 }
83};
84
85}
86
Steve Naroff600866c2009-08-27 19:51:58 +000087extern "C" {
Ted Kremenekd2fa5662009-08-26 22:36:44 +000088
Steve Naroff600866c2009-08-27 19:51:58 +000089CXIndex clang_createIndex()
Steve Naroff50398192009-08-28 15:28:48 +000090{
91 return new Indexer(*new Program(), *new FileManager());
Steve Naroff600866c2009-08-27 19:51:58 +000092}
93
Steve Naroff50398192009-08-28 15:28:48 +000094// FIXME: need to pass back error info.
95CXTranslationUnit clang_createTranslationUnit(
96 CXIndex CIdx, const char *ast_filename)
Steve Naroff600866c2009-08-27 19:51:58 +000097{
Steve Naroff50398192009-08-28 15:28:48 +000098 assert(CIdx && "Passed null CXIndex");
99 Indexer *CXXIdx = static_cast<Indexer *>(CIdx);
100 std::string astName(ast_filename);
101 std::string ErrMsg;
102
103 return ASTUnit::LoadFromPCHFile(astName, CXXIdx->getFileManager(), &ErrMsg);
Steve Naroff600866c2009-08-27 19:51:58 +0000104}
105
Daniel Dunbar1eb79b52009-08-28 16:30:07 +0000106
Steve Naroff600866c2009-08-27 19:51:58 +0000107void clang_loadTranslationUnit(
Steve Naroff89922f82009-08-31 00:59:03 +0000108 CXTranslationUnit CTUnit, CXTranslationUnitIterator callback)
Steve Naroff600866c2009-08-27 19:51:58 +0000109{
Steve Naroff50398192009-08-28 15:28:48 +0000110 assert(CTUnit && "Passed null CXTranslationUnit");
111 ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit);
112 ASTContext &Ctx = CXXUnit->getASTContext();
113
Steve Naroff89922f82009-08-31 00:59:03 +0000114 TUVisitor DVisit(CTUnit, callback);
Steve Naroff50398192009-08-28 15:28:48 +0000115 DVisit.Visit(Ctx.getTranslationUnitDecl());
Steve Naroff600866c2009-08-27 19:51:58 +0000116}
117
Steve Naroff89922f82009-08-31 00:59:03 +0000118void clang_loadDeclaration(CXDecl, CXDeclIterator)
Steve Naroff600866c2009-08-27 19:51:58 +0000119{
120}
121
Steve Naroff7e8f8182009-08-28 12:07:44 +0000122// Some notes on CXEntity:
123//
124// - Since the 'ordinary' namespace includes functions, data, typedefs,
125// ObjC interfaces, thecurrent algorithm is a bit naive (resulting in one
126// entity for 2 different types). For example:
127//
128// module1.m: @interface Foo @end Foo *x;
129// module2.m: void Foo(int);
130//
131// - Since the unique name spans translation units, static data/functions
132// within a CXTranslationUnit are *not* currently represented by entities.
133// As a result, there will be no entity for the following:
134//
135// module.m: static void Foo() { }
136//
137
138
Steve Naroff600866c2009-08-27 19:51:58 +0000139const char *clang_getDeclarationName(CXEntity)
140{
141 return "";
142}
143const char *clang_getURI(CXEntity)
144{
145 return "";
146}
147
148CXEntity clang_getEntity(const char *URI)
149{
150 return 0;
151}
152
153//
154// CXDecl Operations.
155//
156CXCursor clang_getCursorFromDecl(CXDecl)
157{
Steve Naroff89922f82009-08-31 00:59:03 +0000158 return CXCursor();
Steve Naroff600866c2009-08-27 19:51:58 +0000159}
160CXEntity clang_getEntityFromDecl(CXDecl)
161{
162 return 0;
163}
Steve Naroff89922f82009-08-31 00:59:03 +0000164const char *clang_getDeclSpelling(CXDecl AnonDecl)
Steve Naroff600866c2009-08-27 19:51:58 +0000165{
Steve Naroff89922f82009-08-31 00:59:03 +0000166 assert(AnonDecl && "Passed null CXDecl");
167 NamedDecl *ND = static_cast<NamedDecl *>(AnonDecl);
168 if (ND->getIdentifier())
169 return ND->getIdentifier()->getName();
170 else
171 return "";
Steve Naroff600866c2009-08-27 19:51:58 +0000172}
Steve Naroff89922f82009-08-31 00:59:03 +0000173const char *clang_getKindSpelling(enum CXCursorKind Kind)
Steve Naroff600866c2009-08-27 19:51:58 +0000174{
Steve Naroff89922f82009-08-31 00:59:03 +0000175 switch (Kind) {
176 case CXCursor_FunctionDecl: return "FunctionDecl";
177 case CXCursor_TypedefDecl: return "TypedefDecl";
178 case CXCursor_EnumDecl: return "EnumDecl";
179 case CXCursor_EnumConstantDecl: return "EnumConstantDecl";
180 case CXCursor_RecordDecl: return "RecordDecl";
181 case CXCursor_FieldDecl: return "FieldDecl";
182 case CXCursor_VarDecl: return "VarDecl";
183 case CXCursor_ParmDecl: return "ParmDecl";
184 case CXCursor_ObjCInterfaceDecl: return "ObjCInterfaceDecl";
185 case CXCursor_ObjCCategoryDecl: return "ObjCCategoryDecl";
186 case CXCursor_ObjCProtocolDecl: return "ObjCProtocolDecl";
187 case CXCursor_ObjCPropertyDecl: return "ObjCPropertyDecl";
188 case CXCursor_ObjCIvarDecl: return "ObjCIvarDecl";
189 case CXCursor_ObjCMethodDecl: return "ObjCMethodDecl";
190 default: return "<not implemented>";
191 }
Steve Naroff600866c2009-08-27 19:51:58 +0000192}
Steve Naroff89922f82009-08-31 00:59:03 +0000193
Steve Naroff600866c2009-08-27 19:51:58 +0000194//
195// CXCursor Operations.
196//
197CXCursor clang_getCursor(CXTranslationUnit, const char *source_name,
198 unsigned line, unsigned column)
199{
Steve Naroff89922f82009-08-31 00:59:03 +0000200 return CXCursor();
Steve Naroff600866c2009-08-27 19:51:58 +0000201}
202
203CXCursorKind clang_getCursorKind(CXCursor)
204{
Steve Naroff89922f82009-08-31 00:59:03 +0000205 return CXCursor_Invalid;
Steve Naroff600866c2009-08-27 19:51:58 +0000206}
207
Steve Naroff89922f82009-08-31 00:59:03 +0000208unsigned clang_isDeclaration(enum CXCursorKind K)
209{
210 return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
211}
Steve Naroff2d4d6292009-08-31 14:26:51 +0000212
213unsigned clang_getCursorLine(CXCursor C)
Steve Naroff600866c2009-08-27 19:51:58 +0000214{
Steve Naroff2d4d6292009-08-31 14:26:51 +0000215 assert(C.decl && "CXCursor has null decl");
216 NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
217 SourceLocation SLoc = ND->getLocation();
218 if (SLoc.isInvalid())
219 return 0;
220 SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
221 SLoc = SourceMgr.getSpellingLoc(SLoc); // handles macro instantiations.
222 return SourceMgr.getSpellingLineNumber(SLoc);
Steve Naroff600866c2009-08-27 19:51:58 +0000223}
Steve Naroff2d4d6292009-08-31 14:26:51 +0000224unsigned clang_getCursorColumn(CXCursor C)
Steve Naroff600866c2009-08-27 19:51:58 +0000225{
Steve Naroff2d4d6292009-08-31 14:26:51 +0000226 assert(C.decl && "CXCursor has null decl");
227 NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
228 SourceLocation SLoc = ND->getLocation();
229 if (SLoc.isInvalid())
230 return 0;
231 SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
232 SLoc = SourceMgr.getSpellingLoc(SLoc); // handles macro instantiations.
233 return SourceMgr.getSpellingColumnNumber(SLoc);
Steve Naroff600866c2009-08-27 19:51:58 +0000234}
Steve Naroff2d4d6292009-08-31 14:26:51 +0000235const char *clang_getCursorSource(CXCursor C)
Steve Naroff600866c2009-08-27 19:51:58 +0000236{
Steve Naroff2d4d6292009-08-31 14:26:51 +0000237 assert(C.decl && "CXCursor has null decl");
238 NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
239 SourceLocation SLoc = ND->getLocation();
240 if (SLoc.isInvalid())
241 return "<invalid source location>";
242 SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
243 SLoc = SourceMgr.getSpellingLoc(SLoc); // handles macro instantiations.
244 return SourceMgr.getBufferName(SLoc);
Steve Naroff600866c2009-08-27 19:51:58 +0000245}
246
247// If CXCursorKind == Cursor_Reference, then this will return the referenced declaration.
248// If CXCursorKind == Cursor_Declaration, then this will return the declaration.
249CXDecl clang_getCursorDecl(CXCursor)
250{
251 return 0;
252}
253
254} // end extern "C"