aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-08-04 20:04:59 +0000
committerDouglas Gregor <dgregor@apple.com>2011-08-04 20:04:59 +0000
commit8fa0a80b4482ad94e82c4a19e23de17fd69140b5 (patch)
tree690f18df1cf27cab3b3abc41040ffadba2e8fc1d
parent0e7bf40027f75c0c62fb002af7eab0882de6d332 (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.h12
-rw-r--r--include/clang/Frontend/ASTUnit.h14
-rw-r--r--lib/Frontend/ASTUnit.cpp4
-rw-r--r--test/Index/get-cursor.cpp12
-rw-r--r--tools/c-index-test/c-index-test.c6
-rw-r--r--tools/libclang/CXCursor.cpp36
-rw-r--r--tools/libclang/libclang.darwin.exports1
-rw-r--r--tools/libclang/libclang.exports1
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