summaryrefslogtreecommitdiffstats
path: root/tools/CIndex/CIndex.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/CIndex/CIndex.cpp')
-rw-r--r--tools/CIndex/CIndex.cpp106
1 files changed, 71 insertions, 35 deletions
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp
index 64dfcfe..4798e28 100644
--- a/tools/CIndex/CIndex.cpp
+++ b/tools/CIndex/CIndex.cpp
@@ -116,6 +116,10 @@ class TUVisitor : public DeclVisitor<TUVisitor> {
if (ND->getPCHLevel() > MaxPCHLevel)
return;
+ // Filter any implicit declarations (since the source info will be bogus).
+ if (ND->isImplicit())
+ return;
+
CXCursor C = { CK, ND, 0 };
Callback(TUnit, C, CData);
}
@@ -380,10 +384,8 @@ CXTranslationUnit clang_createTranslationUnit(
CXXIdx->getOnlyLocalDecls(),
/* UseBumpAllocator = */ true);
- if (!ErrMsg.empty()) {
- (llvm::errs() << "clang_createTranslationUnit: " << ErrMsg
- << '\n').flush();
- }
+ if (!ErrMsg.empty())
+ llvm::errs() << "clang_createTranslationUnit: " << ErrMsg << '\n';
return TU;
}
@@ -436,8 +438,9 @@ CXTranslationUnit clang_createTranslationUnitFromSourceFile(
// Add the null terminator.
argv.push_back(NULL);
-#ifndef LLVM_ON_WIN32
- llvm::sys::Path DevNull("/dev/null");
+ // Invoke 'clang'.
+ llvm::sys::Path DevNull; // leave empty, causes redirection to /dev/null
+ // on Unix or NUL (Windows).
std::string ErrMsg;
const llvm::sys::Path *Redirects[] = { &DevNull, &DevNull, &DevNull, NULL };
llvm::sys::Program::ExecuteAndWait(ClangPath, &argv[0], /* env */ NULL,
@@ -448,16 +451,12 @@ CXTranslationUnit clang_createTranslationUnitFromSourceFile(
llvm::errs() << "clang_createTranslationUnitFromSourceFile: " << ErrMsg
<< '\n' << "Arguments: \n";
for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
- I!=E; ++I)
- if (*I) llvm::errs() << ' ' << *I << '\n';
-
- (llvm::errs() << '\n').flush();
+ I!=E; ++I) {
+ if (*I)
+ llvm::errs() << ' ' << *I << '\n';
+ }
+ llvm::errs() << '\n';
}
-#else
- // FIXME: I don't know what is the equivalent '/dev/null' redirect for
- // Windows for this API.
- llvm::sys::Program::ExecuteAndWait(ClangPath, &argv[0]);
-#endif
// Finally, we create the translation unit from the ast file.
ASTUnit *ATU = static_cast<ASTUnit *>(
@@ -550,7 +549,13 @@ const char *clang_getDeclSpelling(CXDecl AnonDecl)
if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND)) {
return OMD->getSelector().getAsString().c_str();
- }
+ }
+ if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
+ // No, this isn't the same as the code below. getIdentifier() is non-virtual
+ // and returns different names. NamedDecl returns the class name and
+ // ObjCCategoryImplDecl returns the category name.
+ return CIMP->getIdentifier()->getNameStart();
+
if (ND->getIdentifier())
return ND->getIdentifier()->getNameStart();
else
@@ -576,9 +581,40 @@ unsigned clang_getDeclColumn(CXDecl AnonDecl)
const char *clang_getDeclSource(CXDecl AnonDecl)
{
assert(AnonDecl && "Passed null CXDecl");
+ FileEntry *FEnt = static_cast<FileEntry *>(clang_getDeclSourceFile(AnonDecl));
+ assert (FEnt && "Cannot find FileEntry for Decl");
+ return clang_getFileName(FEnt);
+}
+
+static const FileEntry *getFileEntryFromSourceLocation(SourceManager &SMgr,
+ SourceLocation SLoc)
+{
+ FileID FID;
+ if (SLoc.isFileID())
+ FID = SMgr.getFileID(SLoc);
+ else
+ FID = SMgr.getDecomposedSpellingLoc(SLoc).first;
+ return SMgr.getFileEntryForID(FID);
+}
+
+CXFile clang_getDeclSourceFile(CXDecl AnonDecl)
+{
+ assert(AnonDecl && "Passed null CXDecl");
NamedDecl *ND = static_cast<NamedDecl *>(AnonDecl);
SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
- return SourceMgr.getBufferName(ND->getLocation());
+ return (void *)getFileEntryFromSourceLocation(SourceMgr, ND->getLocation());
+}
+
+const char *clang_getFileName(CXFile SFile) {
+ assert(SFile && "Passed null CXFile");
+ FileEntry *FEnt = static_cast<FileEntry *>(SFile);
+ return FEnt->getName();
+}
+
+time_t clang_getFileTime(CXFile SFile) {
+ assert(SFile && "Passed null CXFile");
+ FileEntry *FEnt = static_cast<FileEntry *>(SFile);
+ return FEnt->getModificationTime();
}
const char *clang_getCursorSpelling(CXCursor C)
@@ -695,26 +731,12 @@ static enum CXCursorKind TranslateKind(Decl *D) {
//
// CXCursor Operations.
//
-void clang_initCXLookupHint(CXLookupHint *hint) {
- memset(hint, 0, sizeof(*hint));
-}
-
CXCursor clang_getCursor(CXTranslationUnit CTUnit, const char *source_name,
- unsigned line, unsigned column) {
- return clang_getCursorWithHint(CTUnit, source_name, line, column, NULL);
-}
-
-CXCursor clang_getCursorWithHint(CXTranslationUnit CTUnit,
- const char *source_name,
- unsigned line, unsigned column,
- CXLookupHint *hint)
+ unsigned line, unsigned column)
{
assert(CTUnit && "Passed null CXTranslationUnit");
ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit);
- // FIXME: Make this better.
- CXDecl RelativeToDecl = hint ? hint->decl : NULL;
-
FileManager &FMgr = CXXUnit->getFileManager();
const FileEntry *File = FMgr.getFile(source_name,
source_name+strlen(source_name));
@@ -725,9 +747,13 @@ CXCursor clang_getCursorWithHint(CXTranslationUnit CTUnit,
SourceLocation SLoc =
CXXUnit->getSourceManager().getLocation(File, line, column);
- ASTLocation ALoc = ResolveLocationInAST(CXXUnit->getASTContext(), SLoc,
- static_cast<NamedDecl *>(RelativeToDecl));
-
+ ASTLocation LastLoc = CXXUnit->getLastASTLocation();
+
+ ASTLocation ALoc = ResolveLocationInAST(CXXUnit->getASTContext(), SLoc,
+ &LastLoc);
+ if (ALoc.isValid())
+ CXXUnit->setLastASTLocation(ALoc);
+
Decl *Dcl = ALoc.getParentDecl();
if (ALoc.isNamedRef())
Dcl = ALoc.AsNamedRef().ND;
@@ -935,6 +961,16 @@ const char *clang_getCursorSource(CXCursor C)
return Buffer->getBufferIdentifier();
}
+CXFile clang_getCursorSourceFile(CXCursor C)
+{
+ assert(C.decl && "CXCursor has null decl");
+ NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
+ SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
+
+ return (void *)getFileEntryFromSourceLocation(SourceMgr,
+ getLocationFromCursor(C,SourceMgr, ND));
+}
+
void clang_getDefinitionSpellingAndExtent(CXCursor C,
const char **startBuf,
const char **endBuf,
OpenPOWER on IntegriCloud