diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-08-04 20:04:59 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-08-04 20:04:59 +0000 |
commit | 8fa0a80b4482ad94e82c4a19e23de17fd69140b5 (patch) | |
tree | 690f18df1cf27cab3b3abc41040ffadba2e8fc1d | |
parent | 0e7bf40027f75c0c62fb002af7eab0882de6d332 (diff) |
Add a new libclang API to return a CXCompletionString for an arbitrary
cursor, from Connor Wakamo! Addresses <rdar://problem/9087798>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@136911 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang-c/Index.h | 12 | ||||
-rw-r--r-- | include/clang/Frontend/ASTUnit.h | 14 | ||||
-rw-r--r-- | lib/Frontend/ASTUnit.cpp | 4 | ||||
-rw-r--r-- | test/Index/get-cursor.cpp | 12 | ||||
-rw-r--r-- | tools/c-index-test/c-index-test.c | 6 | ||||
-rw-r--r-- | tools/libclang/CXCursor.cpp | 36 | ||||
-rw-r--r-- | tools/libclang/libclang.darwin.exports | 1 | ||||
-rw-r--r-- | tools/libclang/libclang.exports | 1 |
8 files changed, 86 insertions, 0 deletions
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index e52ed46131..e16a21ef35 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -2899,6 +2899,18 @@ CINDEX_LINKAGE enum CXAvailabilityKind clang_getCompletionAvailability(CXCompletionString completion_string); /** + * \brief Retrieve a completion string for an arbitrary declaration or macro + * definition cursor. + * + * \param cursor The cursor to query. + * + * \returns A non-context-sensitive completion string for declaration and macro + * definition cursors, or NULL for other kinds of cursors. + */ +CINDEX_LINKAGE CXCompletionString +clang_getCursorCompletionString(CXCursor cursor); + +/** * \brief Contains the results of code-completion. * * This data structure contains the results of code completion, as diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h index 6a3f9d5d42..4f81de53be 100644 --- a/include/clang/Frontend/ASTUnit.h +++ b/include/clang/Frontend/ASTUnit.h @@ -310,10 +310,24 @@ public: return CachedCompletionAllocator; } + /// \brief Retrieve the allocator used to cache global code completions. + /// Creates the allocator if it doesn't already exist. + llvm::IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> + getCursorCompletionAllocator() { + if (!CursorCompletionAllocator.getPtr()) { + CursorCompletionAllocator = new GlobalCodeCompletionAllocator; + } + return CursorCompletionAllocator; + } + private: /// \brief Allocator used to store cached code completions. llvm::IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> CachedCompletionAllocator; + + /// \brief Allocator used to store code completions for arbitrary cursors. + llvm::IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> + CursorCompletionAllocator; /// \brief The set of cached code-completion results. std::vector<CachedCodeCompletionResult> CachedCompletionResults; diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index f19acd093a..d9635c5de4 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -1903,6 +1903,10 @@ bool ASTUnit::Reparse(RemappedFile *RemappedFiles, unsigned NumRemappedFiles) { CurrentTopLevelHashValue != CompletionCacheTopLevelHashValue) CacheCodeCompletionResults(); + // We now need to clear out the completion allocator for + // clang_getCursorCompletionString; it'll be recreated if necessary. + CursorCompletionAllocator = 0; + return Result; } diff --git a/test/Index/get-cursor.cpp b/test/Index/get-cursor.cpp index 2aa76c4725..441ed1cdab 100644 --- a/test/Index/get-cursor.cpp +++ b/test/Index/get-cursor.cpp @@ -35,6 +35,14 @@ void test() { X foo; } +// RUN: c-index-test -cursor-at=%s:6:4 %s | FileCheck -check-prefix=CHECK-COMPLETION-1 %s +// CHECK-COMPLETION-1: CXXConstructor=X:6:3 +// CHECK-COMPLETION-1-NEXT: Completion string: {TypedText X}{LeftParen (}{Placeholder int}{Comma , }{Placeholder int}{RightParen )} + +// RUN: c-index-test -cursor-at=%s:31:16 %s | FileCheck -check-prefix=CHECK-COMPLETION-2 %s +// CHECK-COMPLETION-2: CXXMethod=getAnotherX:31:5 (Definition) +// CHECK-COMPLETION-2-NEXT: Completion string: {ResultType X}{TypedText getAnotherX}{LeftParen (}{RightParen )} + // RUN: c-index-test -cursor-at=%s:12:20 %s | FileCheck -check-prefix=CHECK-VALUE-REF %s // RUN: c-index-test -cursor-at=%s:13:21 %s | FileCheck -check-prefix=CHECK-VALUE-REF %s // RUN: c-index-test -cursor-at=%s:13:28 %s | FileCheck -check-prefix=CHECK-VALUE-REF %s @@ -68,3 +76,7 @@ void test() { // RUN: c-index-test -cursor-at=%s:35:5 %s | FileCheck -check-prefix=CHECK-DECL %s // CHECK-DECL: VarDecl=foo:35:5 + +// RUN: c-index-test -cursor-at=%s:21:3 %s | FileCheck -check-prefix=CHECK-MEMBER %s +// CHECK-MEMBER: FieldDecl=member:21:7 (Definition) +// CHECK-MEMBER-NEXT: Completion string: {ResultType int}{TypedText member} diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index b737a38229..0fec79848c 100644 --- a/tools/c-index-test/c-index-test.c +++ b/tools/c-index-test/c-index-test.c @@ -1333,7 +1333,13 @@ int inspect_cursor_at(int argc, const char **argv) { clang_getLocation(TU, file, Locations[Loc].line, Locations[Loc].column)); if (I + 1 == Repeats) { + CXCompletionString completionString = clang_getCursorCompletionString( + Cursor); PrintCursor(TU, Cursor); + if (completionString != NULL) { + printf("\nCompletion string: "); + print_completion_string(completionString, stdout); + } printf("\n"); free(Locations[Loc].filename); } diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp index b3c57dc934..bbc93438a5 100644 --- a/tools/libclang/CXCursor.cpp +++ b/tools/libclang/CXCursor.cpp @@ -577,4 +577,40 @@ unsigned clang_CXCursorSet_insert(CXCursorSet set, CXCursor cursor) { entry = 1; return flag; } + +CXCompletionString clang_getCursorCompletionString(CXCursor cursor) { + enum CXCursorKind kind = clang_getCursorKind(cursor); + if (clang_isDeclaration(kind)) { + Decl *decl = getCursorDecl(cursor); + if (isa<NamedDecl>(decl)) { + NamedDecl *namedDecl = (NamedDecl *)decl; + ASTUnit *unit = getCursorASTUnit(cursor); + if (unit->hasSema()) { + Sema &S = unit->getSema(); + CodeCompletionAllocator *Allocator + = unit->getCursorCompletionAllocator().getPtr(); + CodeCompletionResult Result(namedDecl); + CodeCompletionString *String + = Result.CreateCodeCompletionString(S, *Allocator); + return String; + } + } + } + else if (kind == CXCursor_MacroDefinition) { + MacroDefinition *definition = getCursorMacroDefinition(cursor); + const IdentifierInfo *MacroInfo = definition->getName(); + ASTUnit *unit = getCursorASTUnit(cursor); + if (unit->hasSema()) { + Sema &S = unit->getSema(); + CodeCompletionAllocator *Allocator + = unit->getCursorCompletionAllocator().getPtr(); + CodeCompletionResult Result((IdentifierInfo *)MacroInfo); + CodeCompletionString *String + = Result.CreateCodeCompletionString(S, *Allocator); + return String; + } + } + return NULL; +} + } // end: extern "C" diff --git a/tools/libclang/libclang.darwin.exports b/tools/libclang/libclang.darwin.exports index 59905364d8..a858f624c8 100644 --- a/tools/libclang/libclang.darwin.exports +++ b/tools/libclang/libclang.darwin.exports @@ -55,6 +55,7 @@ _clang_getCompletionChunkText _clang_getCompletionPriority _clang_getCursor _clang_getCursorAvailability +_clang_getCursorCompletionString _clang_getCursorDefinition _clang_getCursorDisplayName _clang_getCursorExtent diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports index ab9face5ec..85e9f02695 100644 --- a/tools/libclang/libclang.exports +++ b/tools/libclang/libclang.exports @@ -55,6 +55,7 @@ clang_getCompletionChunkText clang_getCompletionPriority clang_getCursor clang_getCursorAvailability +clang_getCursorCompletionString clang_getCursorDefinition clang_getCursorDisplayName clang_getCursorExtent |