From: Steve Naroff Date: Wed, 28 Oct 2009 20:44:47 +0000 (+0000) Subject: Remove _clang_initCXLookupHint() and _clang_getCursorWithHint(). Related to . Localize the optimization to ResolveLocationInAST(). The last valid AST location is now stored with ASTUnit. There still isn't optimal, however it's an improvement (with a much cleaner API). Having the client manage an "hint" is error prone and complex. I wanted to land the major changes before finishing up the optimizations. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85425 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index 0d41edb2e0..5e5504161f 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -276,21 +276,6 @@ CINDEX_LINKAGE CXFile clang_getDeclSourceFile(CXDecl); CINDEX_LINKAGE CXCursor clang_getCursor(CXTranslationUnit, const char *source_name, unsigned line, unsigned column); -/** - Usage: clang_getCursorWithHint() provides the same functionality as - clang_getCursor() except that it takes an option 'hint' argument. - The 'hint' is a temporary CXLookupHint object (whose lifetime is managed by - the caller) that should be initialized with clang_initCXLookupHint(). - - FIXME: Add a better comment once getCursorWithHint() has more functionality. - */ -typedef CXCursor CXLookupHint; -CINDEX_LINKAGE CXCursor clang_getCursorWithHint(CXTranslationUnit, const char *source_name, - unsigned line, unsigned column, - CXLookupHint *hint); - -CINDEX_LINKAGE void clang_initCXLookupHint(CXLookupHint *hint); - CINDEX_LINKAGE enum CXCursorKind clang_getCursorKind(CXCursor); CINDEX_LINKAGE unsigned clang_isDeclaration(enum CXCursorKind); CINDEX_LINKAGE unsigned clang_isReference(enum CXCursorKind); diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h index 15ddb76fbd..7dfabbadd8 100644 --- a/include/clang/Frontend/ASTUnit.h +++ b/include/clang/Frontend/ASTUnit.h @@ -18,6 +18,7 @@ #include "llvm/ADT/OwningPtr.h" #include "clang/Frontend/TextDiagnosticBuffer.h" #include "clang/Basic/FileManager.h" +#include "clang/Index/ASTLocation.h" #include namespace clang { @@ -32,6 +33,8 @@ namespace clang { class ASTContext; class Decl; +using namespace idx; + /// \brief Utility class for loading a ASTContext from a PCH file. /// class ASTUnit { @@ -50,6 +53,9 @@ class ASTUnit { // FIXME: This is temporary; eventually, CIndex will always do this. bool OnlyLocalDecls; + // Critical optimization when using clang_getCursor(). + ASTLocation LastLoc; + ASTUnit(const ASTUnit&); // DO NOT IMPLEMENT ASTUnit &operator=(const ASTUnit &); // DO NOT IMPLEMENT @@ -79,6 +85,9 @@ public: bool getOnlyLocalDecls() const { return OnlyLocalDecls; } + void setLastASTLocation(ASTLocation ALoc) { LastLoc = ALoc; } + ASTLocation getLastASTLocation() const { return LastLoc; } + /// \brief Create a ASTUnit from a PCH file. /// /// \param Filename - The PCH file to load. diff --git a/include/clang/Index/Utils.h b/include/clang/Index/Utils.h index 36cf56dea2..f8e01f7286 100644 --- a/include/clang/Index/Utils.h +++ b/include/clang/Index/Utils.h @@ -18,7 +18,6 @@ namespace clang { class ASTContext; class SourceLocation; - class Decl; namespace idx { class ASTLocation; @@ -28,7 +27,7 @@ namespace idx { /// \returns the resolved ASTLocation or an invalid ASTLocation if the source /// location could not be resolved. ASTLocation ResolveLocationInAST(ASTContext &Ctx, SourceLocation Loc, - Decl *RelativeToDecl = 0); + ASTLocation *LastLoc = 0); } // end namespace idx diff --git a/lib/Index/ResolveLocation.cpp b/lib/Index/ResolveLocation.cpp index 4e992f752b..ec8c1dcb38 100644 --- a/lib/Index/ResolveLocation.cpp +++ b/lib/Index/ResolveLocation.cpp @@ -59,11 +59,6 @@ protected: return CheckRange(Node) == BeforeLoc; } - template - bool ContainsLocation(T Node) { - return CheckRange(Node) == ContainsLoc; - } - template bool isAfterLocation(T Node) { return CheckRange(Node) == AfterLoc; @@ -72,6 +67,11 @@ protected: public: LocResolverBase(ASTContext &ctx, SourceLocation loc) : Ctx(ctx), Loc(loc) {} + + template + bool ContainsLocation(T Node) { + return CheckRange(Node) == ContainsLoc; + } #ifndef NDEBUG /// \brief Debugging output. @@ -543,11 +543,40 @@ void LocResolverBase::print(Stmt *Node) { /// \brief Returns the AST node that a source location points to. /// ASTLocation idx::ResolveLocationInAST(ASTContext &Ctx, SourceLocation Loc, - Decl *RelativeToDecl) { + ASTLocation *LastLoc) { if (Loc.isInvalid()) return ASTLocation(); - if (RelativeToDecl) - return DeclLocResolver(Ctx, Loc).Visit(RelativeToDecl); + if (LastLoc && LastLoc->isValid()) { + DeclContext *DC = 0; + + if (Decl *Dcl = LastLoc->dyn_AsDecl()) { + DC = Dcl->getDeclContext(); + } else if (LastLoc->isStmt()) { + Decl *Parent = LastLoc->getParentDecl(); + if (FunctionDecl *FD = dyn_cast(Parent)) + DC = FD; + else { + // This is needed to handle statements within an initializer. + // Example: + // void func() { long double fabsf = __builtin_fabsl(__x); } + // In this case, the 'parent' of __builtin_fabsl is fabsf. + DC = Parent->getDeclContext(); + } + } else { // We have 'N_NamedRef' or 'N_Type' + DC = LastLoc->getParentDecl()->getDeclContext(); + } + assert(DC && "Missing DeclContext"); + + FunctionDecl *FD = dyn_cast(DC); + DeclLocResolver DLocResolver(Ctx, Loc); + + if (FD && FD->isThisDeclarationADefinition() && + DLocResolver.ContainsLocation(FD)) { + return DLocResolver.VisitFunctionDecl(FD); + } + // Fall through and try the slow path... + // FIXME: Optimize more cases. + } return DeclLocResolver(Ctx, Loc).Visit(Ctx.getTranslationUnitDecl()); } diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp index 5ffa6d78e8..71d76536c4 100644 --- a/tools/CIndex/CIndex.cpp +++ b/tools/CIndex/CIndex.cpp @@ -116,6 +116,10 @@ class TUVisitor : public DeclVisitor { 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); } @@ -721,26 +725,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(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)); @@ -751,9 +741,13 @@ CXCursor clang_getCursorWithHint(CXTranslationUnit CTUnit, SourceLocation SLoc = CXXUnit->getSourceManager().getLocation(File, line, column); - ASTLocation ALoc = ResolveLocationInAST(CXXUnit->getASTContext(), SLoc, - static_cast(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; diff --git a/tools/CIndex/CIndex.exports b/tools/CIndex/CIndex.exports index b726aa00e9..d2933cb336 100644 --- a/tools/CIndex/CIndex.exports +++ b/tools/CIndex/CIndex.exports @@ -7,7 +7,6 @@ _clang_getCursorFromDecl _clang_getCursorKind _clang_getCursorLine _clang_getCursorSource -_clang_getCursorWithHint _clang_getDeclarationName _clang_getDeclSpelling _clang_getDeclLine @@ -21,7 +20,6 @@ _clang_loadTranslationUnit _clang_createTranslationUnit _clang_createTranslationUnitFromSourceFile _clang_disposeTranslationUnit -_clang_initCXLookupHint _clang_isDeclaration _clang_isReference _clang_isDefinition diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index 56b29ac136..8791ee20a5 100644 --- a/tools/c-index-test/c-index-test.c +++ b/tools/c-index-test/c-index-test.c @@ -70,7 +70,6 @@ static void TranslationUnitVisitor(CXTranslationUnit Unit, CXCursor Cursor, CXCursor Ref; while (startBuf < endBuf) { - CXLookupHint hint; if (*startBuf == '\n') { startBuf++; curLine++; @@ -78,11 +77,8 @@ static void TranslationUnitVisitor(CXTranslationUnit Unit, CXCursor Cursor, } else if (*startBuf != '\t') curColumn++; - clang_initCXLookupHint(&hint); - hint.decl = Cursor.decl; - - Ref = clang_getCursorWithHint(Unit, clang_getCursorSource(Cursor), - curLine, curColumn, &hint); + Ref = clang_getCursor(Unit, clang_getCursorSource(Cursor), + curLine, curColumn); if (Ref.kind == CXCursor_NoDeclFound) { /* Nothing found here; that's fine. */ } else if (Ref.kind != CXCursor_FunctionDecl) {