Extend clang_getCursor() to take a 'relativeDecl' argument (so speed up searching). Without a 'relativeDecl', the algorithm is n-squared. For example, running the following command on 'Large.m' takes hours without a 'relatvieDecl'.

snaroff% time ../../Debug/bin/c-index-test Large.ast all > Large.out
snaroff% cat Large.m
#import <Cocoa/Cocoa.h>
#import <QuickTime/QuickTime.h>
#import <OpenGL/OpenGL.h>

With a 'relativeDecl', it takes <30 seconds:-)

llvm-svn: 84760
This commit is contained in:
Steve Naroff 2009-10-21 13:56:23 +00:00
parent 45f99d6621
commit 20bad0b7c6
5 changed files with 23 additions and 8 deletions

View File

@ -240,8 +240,16 @@ const char *clang_getDeclSource(CXDecl);
/*
* CXCursor Operations.
*/
/**
Usage: clang_getCursor() will translate a source/line/column position
into an AST cursor (to derive semantic information from the source code).
If 'RelativeToDecl' is NULL, the entire translation unit will be searched.
Note that searching the entire translation unit can be slow.
Otherwise, the "search" for the AST cursor will start at 'RelativeToDecl'.
*/
CXCursor clang_getCursor(CXTranslationUnit, const char *source_name,
unsigned line, unsigned column);
unsigned line, unsigned column,
CXDecl RelativeToDecl);
enum CXCursorKind clang_getCursorKind(CXCursor);
unsigned clang_isDeclaration(enum CXCursorKind);

View File

@ -18,6 +18,7 @@
namespace clang {
class ASTContext;
class SourceLocation;
class Decl;
namespace idx {
class ASTLocation;
@ -26,7 +27,8 @@ namespace idx {
///
/// \returns the resolved ASTLocation or an invalid ASTLocation if the source
/// location could not be resolved.
ASTLocation ResolveLocationInAST(ASTContext &Ctx, SourceLocation Loc);
ASTLocation ResolveLocationInAST(ASTContext &Ctx, SourceLocation Loc,
Decl *RelativeToDecl = 0);
} // end namespace idx

View File

@ -497,9 +497,12 @@ void LocResolverBase::print(Stmt *Node) {
/// \brief Returns the AST node that a source location points to.
///
ASTLocation idx::ResolveLocationInAST(ASTContext &Ctx, SourceLocation Loc) {
ASTLocation idx::ResolveLocationInAST(ASTContext &Ctx, SourceLocation Loc,
Decl *RelativeToDecl) {
if (Loc.isInvalid())
return ASTLocation();
if (RelativeToDecl)
return DeclLocResolver(Ctx, Loc).Visit(RelativeToDecl);
return DeclLocResolver(Ctx, Loc).Visit(Ctx.getTranslationUnitDecl());
}

View File

@ -655,7 +655,8 @@ static enum CXCursorKind TranslateKind(Decl *D) {
// CXCursor Operations.
//
CXCursor clang_getCursor(CXTranslationUnit CTUnit, const char *source_name,
unsigned line, unsigned column)
unsigned line, unsigned column,
CXDecl RelativeToDecl)
{
assert(CTUnit && "Passed null CXTranslationUnit");
ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit);
@ -670,7 +671,8 @@ CXCursor clang_getCursor(CXTranslationUnit CTUnit, const char *source_name,
SourceLocation SLoc =
CXXUnit->getSourceManager().getLocation(File, line, column);
ASTLocation ALoc = ResolveLocationInAST(CXXUnit->getASTContext(), SLoc);
ASTLocation ALoc = ResolveLocationInAST(CXXUnit->getASTContext(), SLoc,
static_cast<NamedDecl *>(RelativeToDecl));
Decl *Dcl = ALoc.getParentDecl();
if (ALoc.isNamedRef())

View File

@ -53,7 +53,7 @@ static void TranslationUnitVisitor(CXTranslationUnit Unit, CXCursor Cursor,
unsigned curLine = startLine, curColumn = startColumn;
CXCursor Ref;
while (startBuf <= endBuf) {
while (startBuf < endBuf) {
if (*startBuf == '\n') {
startBuf++;
curLine++;
@ -62,7 +62,7 @@ static void TranslationUnitVisitor(CXTranslationUnit Unit, CXCursor Cursor,
curColumn++;
Ref = clang_getCursor(Unit, clang_getCursorSource(Cursor),
curLine, curColumn);
curLine, curColumn, Cursor.decl);
if (Ref.kind == CXCursor_NoDeclFound) {
/* Nothing found here; that's fine. */
} else if (Ref.kind != CXCursor_FunctionDecl) {