1 //===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the Clang-C Source Indexing library.
12 //===----------------------------------------------------------------------===//
14 #include "clang-c/Index.h"
15 #include "clang/Index/Program.h"
16 #include "clang/Index/Indexer.h"
17 #include "clang/Index/ASTLocation.h"
18 #include "clang/Index/Utils.h"
19 #include "clang/AST/DeclVisitor.h"
20 #include "clang/AST/StmtVisitor.h"
21 #include "clang/AST/Decl.h"
22 #include "clang/Basic/FileManager.h"
23 #include "clang/Basic/SourceManager.h"
24 #include "clang/Frontend/ASTUnit.h"
25 #include "llvm/Config/config.h"
26 #include "llvm/Support/Compiler.h"
27 #include "llvm/Support/MemoryBuffer.h"
28 #include "llvm/System/Path.h"
29 #include "llvm/System/Program.h"
30 #include "llvm/Support/raw_ostream.h"
36 #define WIN32_LEAN_AND_MEAN
42 using namespace clang;
46 static enum CXCursorKind TranslateDeclRefExpr(DeclRefExpr *DRE)
48 NamedDecl *D = DRE->getDecl();
50 return CXCursor_VarRef;
51 else if (isa<FunctionDecl>(D))
52 return CXCursor_FunctionRef;
53 else if (isa<EnumConstantDecl>(D))
54 return CXCursor_EnumConstantRef;
56 return CXCursor_NotImplemented;
60 // Will be useful one day.
61 class CRefVisitor : public StmtVisitor<CRefVisitor> {
63 CXDeclIterator Callback;
66 void Call(enum CXCursorKind CK, Stmt *SRef) {
67 CXCursor C = { CK, CDecl, SRef };
68 Callback(CDecl, C, CData);
72 CRefVisitor(CXDecl C, CXDeclIterator cback, CXClientData D) :
73 CDecl(C), Callback(cback), CData(D) {}
75 void VisitStmt(Stmt *S) {
76 for (Stmt::child_iterator C = S->child_begin(), CEnd = S->child_end();
80 void VisitDeclRefExpr(DeclRefExpr *Node) {
81 Call(TranslateDeclRefExpr(Node), Node);
83 void VisitMemberExpr(MemberExpr *Node) {
84 Call(CXCursor_MemberRef, Node);
86 void VisitObjCMessageExpr(ObjCMessageExpr *Node) {
87 Call(CXCursor_ObjCSelectorRef, Node);
89 void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
90 Call(CXCursor_ObjCIvarRef, Node);
95 /// IgnoreDiagnosticsClient - A DiagnosticsClient that just ignores emitted
96 /// warnings and errors.
97 class VISIBILITY_HIDDEN IgnoreDiagnosticsClient : public DiagnosticClient {
99 virtual ~IgnoreDiagnosticsClient() {}
100 virtual void HandleDiagnostic(Diagnostic::Level, const DiagnosticInfo &) {}
103 // Translation Unit Visitor.
104 class TUVisitor : public DeclVisitor<TUVisitor> {
105 CXTranslationUnit TUnit;
106 CXTranslationUnitIterator Callback;
109 // MaxPCHLevel - the maximum PCH level of declarations that we will pass on
110 // to the visitor. Declarations with a PCH level greater than this value will
112 unsigned MaxPCHLevel;
114 void Call(enum CXCursorKind CK, NamedDecl *ND) {
115 // Filter any declarations that have a PCH level greater than what we allow.
116 if (ND->getPCHLevel() > MaxPCHLevel)
119 CXCursor C = { CK, ND, 0 };
120 Callback(TUnit, C, CData);
123 TUVisitor(CXTranslationUnit CTU,
124 CXTranslationUnitIterator cback, CXClientData D,
125 unsigned MaxPCHLevel) :
126 TUnit(CTU), Callback(cback), CData(D), MaxPCHLevel(MaxPCHLevel) {}
128 void VisitTranslationUnitDecl(TranslationUnitDecl *D) {
129 VisitDeclContext(dyn_cast<DeclContext>(D));
131 void VisitDeclContext(DeclContext *DC) {
132 for (DeclContext::decl_iterator
133 I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I)
136 void VisitTypedefDecl(TypedefDecl *ND) {
137 Call(CXCursor_TypedefDecl, ND);
139 void VisitTagDecl(TagDecl *ND) {
140 switch (ND->getTagKind()) {
141 case TagDecl::TK_struct:
142 Call(CXCursor_StructDecl, ND);
144 case TagDecl::TK_class:
145 Call(CXCursor_ClassDecl, ND);
147 case TagDecl::TK_union:
148 Call(CXCursor_UnionDecl, ND);
150 case TagDecl::TK_enum:
151 Call(CXCursor_EnumDecl, ND);
155 void VisitVarDecl(VarDecl *ND) {
156 Call(CXCursor_VarDecl, ND);
158 void VisitFunctionDecl(FunctionDecl *ND) {
159 Call(ND->isThisDeclarationADefinition() ? CXCursor_FunctionDefn
160 : CXCursor_FunctionDecl, ND);
162 void VisitObjCInterfaceDecl(ObjCInterfaceDecl *ND) {
163 Call(CXCursor_ObjCInterfaceDecl, ND);
165 void VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
166 Call(CXCursor_ObjCCategoryDecl, ND);
168 void VisitObjCProtocolDecl(ObjCProtocolDecl *ND) {
169 Call(CXCursor_ObjCProtocolDecl, ND);
171 void VisitObjCImplementationDecl(ObjCImplementationDecl *ND) {
172 Call(CXCursor_ObjCClassDefn, ND);
174 void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *ND) {
175 Call(CXCursor_ObjCCategoryDefn, ND);
179 // Declaration visitor.
180 class CDeclVisitor : public DeclVisitor<CDeclVisitor> {
182 CXDeclIterator Callback;
185 // MaxPCHLevel - the maximum PCH level of declarations that we will pass on
186 // to the visitor. Declarations with a PCH level greater than this value will
188 unsigned MaxPCHLevel;
190 void Call(enum CXCursorKind CK, NamedDecl *ND) {
191 // Disable the callback when the context is equal to the visiting decl.
192 if (CDecl == ND && !clang_isReference(CK))
195 // Filter any declarations that have a PCH level greater than what we allow.
196 if (ND->getPCHLevel() > MaxPCHLevel)
199 CXCursor C = { CK, ND, 0 };
200 Callback(CDecl, C, CData);
203 CDeclVisitor(CXDecl C, CXDeclIterator cback, CXClientData D,
204 unsigned MaxPCHLevel) :
205 CDecl(C), Callback(cback), CData(D), MaxPCHLevel(MaxPCHLevel) {}
207 void VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
208 // Issue callbacks for the containing class.
209 Call(CXCursor_ObjCClassRef, ND);
210 // FIXME: Issue callbacks for protocol refs.
211 VisitDeclContext(dyn_cast<DeclContext>(ND));
213 void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
214 // Issue callbacks for super class.
215 if (D->getSuperClass())
216 Call(CXCursor_ObjCSuperClassRef, D);
218 for (ObjCProtocolDecl::protocol_iterator I = D->protocol_begin(),
219 E = D->protocol_end(); I != E; ++I)
220 Call(CXCursor_ObjCProtocolRef, *I);
221 VisitDeclContext(dyn_cast<DeclContext>(D));
223 void VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
224 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
225 E = PID->protocol_end(); I != E; ++I)
226 Call(CXCursor_ObjCProtocolRef, *I);
228 VisitDeclContext(dyn_cast<DeclContext>(PID));
230 void VisitTagDecl(TagDecl *D) {
231 VisitDeclContext(dyn_cast<DeclContext>(D));
233 void VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
234 VisitDeclContext(dyn_cast<DeclContext>(D));
236 void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
237 VisitDeclContext(dyn_cast<DeclContext>(D));
239 void VisitDeclContext(DeclContext *DC) {
240 for (DeclContext::decl_iterator
241 I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I)
244 void VisitEnumConstantDecl(EnumConstantDecl *ND) {
245 Call(CXCursor_EnumConstantDecl, ND);
247 void VisitFieldDecl(FieldDecl *ND) {
248 Call(CXCursor_FieldDecl, ND);
250 void VisitVarDecl(VarDecl *ND) {
251 Call(CXCursor_VarDecl, ND);
253 void VisitParmVarDecl(ParmVarDecl *ND) {
254 Call(CXCursor_ParmDecl, ND);
256 void VisitObjCPropertyDecl(ObjCPropertyDecl *ND) {
257 Call(CXCursor_ObjCPropertyDecl, ND);
259 void VisitObjCIvarDecl(ObjCIvarDecl *ND) {
260 Call(CXCursor_ObjCIvarDecl, ND);
262 void VisitFunctionDecl(FunctionDecl *ND) {
263 if (ND->isThisDeclarationADefinition()) {
264 VisitDeclContext(dyn_cast<DeclContext>(ND));
266 // Not currently needed.
267 CompoundStmt *Body = dyn_cast<CompoundStmt>(ND->getBody());
268 CRefVisitor RVisit(CDecl, Callback, CData);
273 void VisitObjCMethodDecl(ObjCMethodDecl *ND) {
275 Call(ND->isInstanceMethod() ? CXCursor_ObjCInstanceMethodDefn
276 : CXCursor_ObjCClassMethodDefn, ND);
277 VisitDeclContext(dyn_cast<DeclContext>(ND));
279 Call(ND->isInstanceMethod() ? CXCursor_ObjCInstanceMethodDecl
280 : CXCursor_ObjCClassMethodDecl, ND);
284 class CIndexer : public Indexer {
286 explicit CIndexer(Program *prog) : Indexer(*prog),
287 OnlyLocalDecls(false),
288 DisplayDiagnostics(false) {}
290 virtual ~CIndexer() { delete &getProgram(); }
292 /// \brief Whether we only want to see "local" declarations (that did not
293 /// come from a previous precompiled header). If false, we want to see all
295 bool getOnlyLocalDecls() const { return OnlyLocalDecls; }
296 void setOnlyLocalDecls(bool Local = true) { OnlyLocalDecls = Local; }
298 void setDisplayDiagnostics(bool Display = true) {
299 DisplayDiagnostics = Display;
301 bool getDisplayDiagnostics() const { return DisplayDiagnostics; }
303 /// \brief Get the path of the clang binary.
304 const llvm::sys::Path& getClangPath();
307 bool DisplayDiagnostics;
309 llvm::sys::Path ClangPath;
312 const llvm::sys::Path& CIndexer::getClangPath() {
313 // Did we already compute the path?
314 if (!ClangPath.empty())
317 // Find the location where this library lives (libCIndex.dylib).
319 MEMORY_BASIC_INFORMATION mbi;
321 VirtualQuery((void *)(uintptr_t)clang_createTranslationUnit, &mbi,
323 GetModuleFileNameA((HINSTANCE)mbi.AllocationBase, path, MAX_PATH);
325 llvm::sys::Path CIndexPath(path);
327 // This silly cast below avoids a C++ warning.
329 if (dladdr((void *)(uintptr_t)clang_createTranslationUnit, &info) == 0)
330 assert(0 && "Call to dladdr() failed");
332 llvm::sys::Path CIndexPath(info.dli_fname);
335 // We now have the CIndex directory, locate clang relative to it.
336 CIndexPath.eraseComponent();
337 CIndexPath.eraseComponent();
338 CIndexPath.appendComponent("bin");
339 CIndexPath.appendComponent("clang");
342 ClangPath = CIndexPath;
350 CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
351 int displayDiagnostics)
353 CIndexer *CIdxr = new CIndexer(new Program());
354 if (excludeDeclarationsFromPCH)
355 CIdxr->setOnlyLocalDecls();
356 if (displayDiagnostics)
357 CIdxr->setDisplayDiagnostics();
361 void clang_disposeIndex(CXIndex CIdx)
363 assert(CIdx && "Passed null CXIndex");
364 delete static_cast<CIndexer *>(CIdx);
367 // FIXME: need to pass back error info.
368 CXTranslationUnit clang_createTranslationUnit(
369 CXIndex CIdx, const char *ast_filename)
371 assert(CIdx && "Passed null CXIndex");
372 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
373 std::string astName(ast_filename);
376 CXTranslationUnit TU =
377 ASTUnit::LoadFromPCHFile(astName, &ErrMsg,
378 CXXIdx->getDisplayDiagnostics() ?
379 NULL : new IgnoreDiagnosticsClient(),
380 CXXIdx->getOnlyLocalDecls(),
381 /* UseBumpAllocator = */ true);
383 if (!ErrMsg.empty()) {
384 (llvm::errs() << "clang_createTranslationUnit: " << ErrMsg
391 CXTranslationUnit clang_createTranslationUnitFromSourceFile(
393 const char *source_filename,
394 int num_command_line_args, const char **command_line_args) {
395 assert(CIdx && "Passed null CXIndex");
396 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
398 // Build up the arguments for invoking 'clang'.
399 std::vector<const char *> argv;
401 // First add the complete path to the 'clang' executable.
402 llvm::sys::Path ClangPath = static_cast<CIndexer *>(CIdx)->getClangPath();
403 argv.push_back(ClangPath.c_str());
405 // Add the '-emit-ast' option as our execution mode for 'clang'.
406 argv.push_back("-emit-ast");
408 // The 'source_filename' argument is optional. If the caller does not
409 // specify it then it is assumed that the source file is specified
410 // in the actual argument list.
412 argv.push_back(source_filename);
414 // Generate a temporary name for the AST file.
415 argv.push_back("-o");
416 char astTmpFile[L_tmpnam];
417 argv.push_back(tmpnam(astTmpFile));
419 // Process the compiler options, stripping off '-o', '-c', '-fsyntax-only'.
420 for (int i = 0; i < num_command_line_args; ++i)
421 if (const char *arg = command_line_args[i]) {
422 if (strcmp(arg, "-o") == 0) {
423 ++i; // Also skip the matching argument.
426 if (strcmp(arg, "-emit-ast") == 0 ||
427 strcmp(arg, "-c") == 0 ||
428 strcmp(arg, "-fsyntax-only") == 0) {
432 // Keep the argument.
436 // Add the null terminator.
437 argv.push_back(NULL);
439 #ifndef LLVM_ON_WIN32
440 llvm::sys::Path DevNull("/dev/null");
442 const llvm::sys::Path *Redirects[] = { &DevNull, &DevNull, &DevNull, NULL };
443 llvm::sys::Program::ExecuteAndWait(ClangPath, &argv[0], /* env */ NULL,
444 /* redirects */ !CXXIdx->getDisplayDiagnostics() ? &Redirects[0] : NULL,
445 /* secondsToWait */ 0, /* memoryLimits */ 0, &ErrMsg);
447 if (!ErrMsg.empty()) {
448 llvm::errs() << "clang_createTranslationUnitFromSourceFile: " << ErrMsg
449 << '\n' << "Arguments: \n";
450 for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
452 if (*I) llvm::errs() << ' ' << *I << '\n';
454 (llvm::errs() << '\n').flush();
457 // FIXME: I don't know what is the equivalent '/dev/null' redirect for
458 // Windows for this API.
459 llvm::sys::Program::ExecuteAndWait(ClangPath, &argv[0]);
462 // Finally, we create the translation unit from the ast file.
463 ASTUnit *ATU = static_cast<ASTUnit *>(
464 clang_createTranslationUnit(CIdx, astTmpFile));
466 ATU->unlinkTemporaryFile();
470 void clang_disposeTranslationUnit(
471 CXTranslationUnit CTUnit)
473 assert(CTUnit && "Passed null CXTranslationUnit");
474 delete static_cast<ASTUnit *>(CTUnit);
477 const char *clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit)
479 assert(CTUnit && "Passed null CXTranslationUnit");
480 ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit);
481 return CXXUnit->getOriginalSourceFileName().c_str();
484 void clang_loadTranslationUnit(CXTranslationUnit CTUnit,
485 CXTranslationUnitIterator callback,
488 assert(CTUnit && "Passed null CXTranslationUnit");
489 ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit);
490 ASTContext &Ctx = CXXUnit->getASTContext();
492 TUVisitor DVisit(CTUnit, callback, CData,
493 CXXUnit->getOnlyLocalDecls()? 1 : Decl::MaxPCHLevel);
494 DVisit.Visit(Ctx.getTranslationUnitDecl());
497 void clang_loadDeclaration(CXDecl Dcl,
498 CXDeclIterator callback,
501 assert(Dcl && "Passed null CXDecl");
503 CDeclVisitor DVisit(Dcl, callback, CData,
504 static_cast<Decl *>(Dcl)->getPCHLevel());
505 DVisit.Visit(static_cast<Decl *>(Dcl));
508 // Some notes on CXEntity:
510 // - Since the 'ordinary' namespace includes functions, data, typedefs,
511 // ObjC interfaces, thecurrent algorithm is a bit naive (resulting in one
512 // entity for 2 different types). For example:
514 // module1.m: @interface Foo @end Foo *x;
515 // module2.m: void Foo(int);
517 // - Since the unique name spans translation units, static data/functions
518 // within a CXTranslationUnit are *not* currently represented by entities.
519 // As a result, there will be no entity for the following:
521 // module.m: static void Foo() { }
525 const char *clang_getDeclarationName(CXEntity)
529 const char *clang_getURI(CXEntity)
534 CXEntity clang_getEntity(const char *URI)
540 // CXDecl Operations.
542 CXEntity clang_getEntityFromDecl(CXDecl)
546 const char *clang_getDeclSpelling(CXDecl AnonDecl)
548 assert(AnonDecl && "Passed null CXDecl");
549 NamedDecl *ND = static_cast<NamedDecl *>(AnonDecl);
551 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND)) {
552 return OMD->getSelector().getAsString().c_str();
554 if (ND->getIdentifier())
555 return ND->getIdentifier()->getNameStart();
560 unsigned clang_getDeclLine(CXDecl AnonDecl)
562 assert(AnonDecl && "Passed null CXDecl");
563 NamedDecl *ND = static_cast<NamedDecl *>(AnonDecl);
564 SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
565 return SourceMgr.getSpellingLineNumber(ND->getLocation());
568 unsigned clang_getDeclColumn(CXDecl AnonDecl)
570 assert(AnonDecl && "Passed null CXDecl");
571 NamedDecl *ND = static_cast<NamedDecl *>(AnonDecl);
572 SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
573 return SourceMgr.getSpellingColumnNumber(ND->getLocation());
576 const char *clang_getDeclSource(CXDecl AnonDecl)
578 assert(AnonDecl && "Passed null CXDecl");
579 NamedDecl *ND = static_cast<NamedDecl *>(AnonDecl);
580 SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
581 return SourceMgr.getBufferName(ND->getLocation());
584 const char *clang_getCursorSpelling(CXCursor C)
586 assert(C.decl && "CXCursor has null decl");
587 NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
589 if (clang_isReference(C.kind)) {
591 case CXCursor_ObjCSuperClassRef: {
592 ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ND);
593 assert(OID && "clang_getCursorLine(): Missing interface decl");
594 return OID->getSuperClass()->getIdentifier()->getNameStart();
596 case CXCursor_ObjCClassRef: {
597 if (ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ND)) {
598 return OID->getIdentifier()->getNameStart();
600 ObjCCategoryDecl *OID = dyn_cast<ObjCCategoryDecl>(ND);
601 assert(OID && "clang_getCursorLine(): Missing category decl");
602 return OID->getClassInterface()->getIdentifier()->getNameStart();
604 case CXCursor_ObjCProtocolRef: {
605 ObjCProtocolDecl *OID = dyn_cast<ObjCProtocolDecl>(ND);
606 assert(OID && "clang_getCursorLine(): Missing protocol decl");
607 return OID->getIdentifier()->getNameStart();
609 case CXCursor_ObjCSelectorRef: {
610 ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(
611 static_cast<Stmt *>(C.stmt));
612 assert(OME && "clang_getCursorLine(): Missing message expr");
613 return OME->getSelector().getAsString().c_str();
615 case CXCursor_VarRef:
616 case CXCursor_FunctionRef:
617 case CXCursor_EnumConstantRef: {
618 DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
619 static_cast<Stmt *>(C.stmt));
620 assert(DRE && "clang_getCursorLine(): Missing decl ref expr");
621 return DRE->getDecl()->getIdentifier()->getNameStart();
624 return "<not implemented>";
627 return clang_getDeclSpelling(C.decl);
630 const char *clang_getCursorKindSpelling(enum CXCursorKind Kind)
633 case CXCursor_FunctionDecl: return "FunctionDecl";
634 case CXCursor_TypedefDecl: return "TypedefDecl";
635 case CXCursor_EnumDecl: return "EnumDecl";
636 case CXCursor_EnumConstantDecl: return "EnumConstantDecl";
637 case CXCursor_StructDecl: return "StructDecl";
638 case CXCursor_UnionDecl: return "UnionDecl";
639 case CXCursor_ClassDecl: return "ClassDecl";
640 case CXCursor_FieldDecl: return "FieldDecl";
641 case CXCursor_VarDecl: return "VarDecl";
642 case CXCursor_ParmDecl: return "ParmDecl";
643 case CXCursor_ObjCInterfaceDecl: return "ObjCInterfaceDecl";
644 case CXCursor_ObjCCategoryDecl: return "ObjCCategoryDecl";
645 case CXCursor_ObjCProtocolDecl: return "ObjCProtocolDecl";
646 case CXCursor_ObjCPropertyDecl: return "ObjCPropertyDecl";
647 case CXCursor_ObjCIvarDecl: return "ObjCIvarDecl";
648 case CXCursor_ObjCInstanceMethodDecl: return "ObjCInstanceMethodDecl";
649 case CXCursor_ObjCClassMethodDecl: return "ObjCClassMethodDecl";
650 case CXCursor_FunctionDefn: return "FunctionDefn";
651 case CXCursor_ObjCInstanceMethodDefn: return "ObjCInstanceMethodDefn";
652 case CXCursor_ObjCClassMethodDefn: return "ObjCClassMethodDefn";
653 case CXCursor_ObjCClassDefn: return "ObjCClassDefn";
654 case CXCursor_ObjCCategoryDefn: return "ObjCCategoryDefn";
655 case CXCursor_ObjCSuperClassRef: return "ObjCSuperClassRef";
656 case CXCursor_ObjCProtocolRef: return "ObjCProtocolRef";
657 case CXCursor_ObjCClassRef: return "ObjCClassRef";
658 case CXCursor_ObjCSelectorRef: return "ObjCSelectorRef";
660 case CXCursor_VarRef: return "VarRef";
661 case CXCursor_FunctionRef: return "FunctionRef";
662 case CXCursor_EnumConstantRef: return "EnumConstantRef";
663 case CXCursor_MemberRef: return "MemberRef";
665 case CXCursor_InvalidFile: return "InvalidFile";
666 case CXCursor_NoDeclFound: return "NoDeclFound";
667 case CXCursor_NotImplemented: return "NotImplemented";
668 default: return "<not implemented>";
672 static enum CXCursorKind TranslateKind(Decl *D) {
673 switch (D->getKind()) {
674 case Decl::Function: return CXCursor_FunctionDecl;
675 case Decl::Typedef: return CXCursor_TypedefDecl;
676 case Decl::Enum: return CXCursor_EnumDecl;
677 case Decl::EnumConstant: return CXCursor_EnumConstantDecl;
678 case Decl::Record: return CXCursor_StructDecl; // FIXME: union/class
679 case Decl::Field: return CXCursor_FieldDecl;
680 case Decl::Var: return CXCursor_VarDecl;
681 case Decl::ParmVar: return CXCursor_ParmDecl;
682 case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl;
683 case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl;
684 case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl;
685 case Decl::ObjCMethod: {
686 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D);
687 if (MD->isInstanceMethod())
688 return CXCursor_ObjCInstanceMethodDecl;
689 return CXCursor_ObjCClassMethodDecl;
693 return CXCursor_NotImplemented;
696 // CXCursor Operations.
698 void clang_initCXLookupHint(CXLookupHint *hint) {
699 memset(hint, 0, sizeof(*hint));
702 CXCursor clang_getCursor(CXTranslationUnit CTUnit, const char *source_name,
703 unsigned line, unsigned column) {
704 return clang_getCursorWithHint(CTUnit, source_name, line, column, NULL);
707 CXCursor clang_getCursorWithHint(CXTranslationUnit CTUnit,
708 const char *source_name,
709 unsigned line, unsigned column,
712 assert(CTUnit && "Passed null CXTranslationUnit");
713 ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit);
715 // FIXME: Make this better.
716 CXDecl RelativeToDecl = hint ? hint->decl : NULL;
718 FileManager &FMgr = CXXUnit->getFileManager();
719 const FileEntry *File = FMgr.getFile(source_name,
720 source_name+strlen(source_name));
722 CXCursor C = { CXCursor_InvalidFile, 0, 0 };
725 SourceLocation SLoc =
726 CXXUnit->getSourceManager().getLocation(File, line, column);
728 ASTLocation ALoc = ResolveLocationInAST(CXXUnit->getASTContext(), SLoc,
729 static_cast<NamedDecl *>(RelativeToDecl));
731 Decl *Dcl = ALoc.getParentDecl();
732 if (ALoc.isNamedRef())
733 Dcl = ALoc.AsNamedRef().ND;
734 Stmt *Stm = ALoc.dyn_AsStmt();
737 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Stm)) {
738 CXCursor C = { TranslateDeclRefExpr(DRE), Dcl, Stm };
740 } else if (ObjCMessageExpr *MExp = dyn_cast<ObjCMessageExpr>(Stm)) {
741 CXCursor C = { CXCursor_ObjCSelectorRef, Dcl, MExp };
744 // Fall through...treat as a decl, not a ref.
746 if (ALoc.isNamedRef()) {
747 if (isa<ObjCInterfaceDecl>(Dcl)) {
748 CXCursor C = { CXCursor_ObjCClassRef, Dcl, ALoc.getParentDecl() };
751 if (isa<ObjCProtocolDecl>(Dcl)) {
752 CXCursor C = { CXCursor_ObjCProtocolRef, Dcl, ALoc.getParentDecl() };
756 CXCursor C = { TranslateKind(Dcl), Dcl, 0 };
759 CXCursor C = { CXCursor_NoDeclFound, 0, 0 };
763 CXCursor clang_getCursorFromDecl(CXDecl AnonDecl)
765 assert(AnonDecl && "Passed null CXDecl");
766 NamedDecl *ND = static_cast<NamedDecl *>(AnonDecl);
768 CXCursor C = { TranslateKind(ND), ND, 0 };
772 unsigned clang_isInvalid(enum CXCursorKind K)
774 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
777 unsigned clang_isDeclaration(enum CXCursorKind K)
779 return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
782 unsigned clang_isReference(enum CXCursorKind K)
784 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
787 unsigned clang_isDefinition(enum CXCursorKind K)
789 return K >= CXCursor_FirstDefn && K <= CXCursor_LastDefn;
792 CXCursorKind clang_getCursorKind(CXCursor C)
797 static Decl *getDeclFromExpr(Stmt *E) {
798 if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
799 return RefExpr->getDecl();
800 if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
801 return ME->getMemberDecl();
802 if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
803 return RE->getDecl();
805 if (CallExpr *CE = dyn_cast<CallExpr>(E))
806 return getDeclFromExpr(CE->getCallee());
807 if (CastExpr *CE = dyn_cast<CastExpr>(E))
808 return getDeclFromExpr(CE->getSubExpr());
809 if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
810 return OME->getMethodDecl();
815 CXDecl clang_getCursorDecl(CXCursor C)
817 if (clang_isDeclaration(C.kind))
820 if (clang_isReference(C.kind)) {
822 if (C.kind == CXCursor_ObjCClassRef ||
823 C.kind == CXCursor_ObjCProtocolRef)
824 return static_cast<Stmt *>(C.stmt);
826 return getDeclFromExpr(static_cast<Stmt *>(C.stmt));
834 static SourceLocation getLocationFromCursor(CXCursor C,
835 SourceManager &SourceMgr,
837 if (clang_isReference(C.kind)) {
839 case CXCursor_ObjCClassRef: {
840 if (isa<ObjCInterfaceDecl>(ND)) {
841 // FIXME: This is a hack (storing the parent decl in the stmt slot).
842 NamedDecl *parentDecl = static_cast<NamedDecl *>(C.stmt);
843 return parentDecl->getLocation();
845 ObjCCategoryDecl *OID = dyn_cast<ObjCCategoryDecl>(ND);
846 assert(OID && "clang_getCursorLine(): Missing category decl");
847 return OID->getClassInterface()->getLocation();
849 case CXCursor_ObjCSuperClassRef: {
850 ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ND);
851 assert(OID && "clang_getCursorLine(): Missing interface decl");
852 return OID->getSuperClassLoc();
854 case CXCursor_ObjCProtocolRef: {
855 ObjCProtocolDecl *OID = dyn_cast<ObjCProtocolDecl>(ND);
856 assert(OID && "clang_getCursorLine(): Missing protocol decl");
857 return OID->getLocation();
859 case CXCursor_ObjCSelectorRef: {
860 ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(
861 static_cast<Stmt *>(C.stmt));
862 assert(OME && "clang_getCursorLine(): Missing message expr");
863 return OME->getLeftLoc(); /* FIXME: should be a range */
865 case CXCursor_VarRef:
866 case CXCursor_FunctionRef:
867 case CXCursor_EnumConstantRef: {
868 DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
869 static_cast<Stmt *>(C.stmt));
870 assert(DRE && "clang_getCursorLine(): Missing decl ref expr");
871 return DRE->getLocation();
874 return SourceLocation();
876 } else { // We have a declaration or a definition.
878 switch (ND->getKind()) {
879 case Decl::ObjCInterface: {
880 SLoc = dyn_cast<ObjCInterfaceDecl>(ND)->getClassLoc();
883 case Decl::ObjCProtocol: {
884 SLoc = ND->getLocation(); /* FIXME: need to get the name location. */
888 SLoc = ND->getLocation();
892 if (SLoc.isInvalid())
893 return SourceLocation();
894 return SourceMgr.getSpellingLoc(SLoc); // handles macro instantiations.
898 unsigned clang_getCursorLine(CXCursor C)
900 assert(C.decl && "CXCursor has null decl");
901 NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
902 SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
904 SourceLocation SLoc = getLocationFromCursor(C, SourceMgr, ND);
905 return SourceMgr.getSpellingLineNumber(SLoc);
908 unsigned clang_getCursorColumn(CXCursor C)
910 assert(C.decl && "CXCursor has null decl");
911 NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
912 SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
914 SourceLocation SLoc = getLocationFromCursor(C, SourceMgr, ND);
915 return SourceMgr.getSpellingColumnNumber(SLoc);
917 const char *clang_getCursorSource(CXCursor C)
919 assert(C.decl && "CXCursor has null decl");
920 NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
921 SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
923 SourceLocation SLoc = getLocationFromCursor(C, SourceMgr, ND);
925 return SourceMgr.getBufferName(SLoc);
927 // Retrieve the file in which the macro was instantiated, then provide that
929 // FIXME: Do we want to give specific macro-instantiation information?
930 const llvm::MemoryBuffer *Buffer
931 = SourceMgr.getBuffer(SourceMgr.getDecomposedSpellingLoc(SLoc).first);
935 return Buffer->getBufferIdentifier();
938 void clang_getDefinitionSpellingAndExtent(CXCursor C,
939 const char **startBuf,
942 unsigned *startColumn,
946 assert(C.decl && "CXCursor has null decl");
947 NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
948 FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
949 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
951 SourceManager &SM = FD->getASTContext().getSourceManager();
952 *startBuf = SM.getCharacterData(Body->getLBracLoc());
953 *endBuf = SM.getCharacterData(Body->getRBracLoc());
954 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
955 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
956 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
957 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());