summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-07-26 15:24:30 +0000
committerDouglas Gregor <dgregor@apple.com>2011-07-26 15:24:30 +0000
commitea777403f999cba29ac23eee92fecbf996528a17 (patch)
tree67a789ae9ca0c783057d625e0b1a2bee5d15dce7
parentb84dc6bca84274dc03157bbddeb6b80450cc9a4c (diff)
downloadbcm5719-llvm-ea777403f999cba29ac23eee92fecbf996528a17.tar.gz
bcm5719-llvm-ea777403f999cba29ac23eee92fecbf996528a17.zip
Add new libclang API, clang_codeCompleteGetObjCSelector(), which
provides the partial Objective-C selector used in a code completion. From Connor Wakamo! llvm-svn: 136084
-rw-r--r--clang/include/clang-c/Index.h15
-rw-r--r--clang/include/clang/Sema/CodeCompleteConsumer.h21
-rw-r--r--clang/lib/Sema/SemaCodeComplete.cpp4
-rw-r--r--clang/test/Index/complete-objc-message.m2
-rw-r--r--clang/tools/c-index-test/c-index-test.c12
-rw-r--r--clang/tools/libclang/CIndexCodeCompletion.cpp33
-rw-r--r--clang/tools/libclang/libclang.darwin.exports1
-rw-r--r--clang/tools/libclang/libclang.exports1
8 files changed, 82 insertions, 7 deletions
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index d4fa9a2453e..0a73a644a3d 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -3234,6 +3234,21 @@ enum CXCursorKind clang_codeCompleteGetContainerKind(
CINDEX_LINKAGE
CXString clang_codeCompleteGetContainerUSR(CXCodeCompleteResults *Results);
+
+/**
+ * \brief Returns the currently-entered selector for an Objective-C message
+ * send, formatted like "initWithFoo:bar:". Only guaranteed to return a
+ * non-empty string for CXCompletionContext_ObjCInstanceMessage and
+ * CXCompletionContext_ObjCClassMessage.
+ *
+ * \param Results the code completion results to query
+ *
+ * \returns the selector (or partial selector) that has been entered thus far
+ * for an Objective-C message send.
+ */
+CINDEX_LINKAGE
+CXString clang_codeCompleteGetObjCSelector(CXCodeCompleteResults *Results);
+
/**
* @}
*/
diff --git a/clang/include/clang/Sema/CodeCompleteConsumer.h b/clang/include/clang/Sema/CodeCompleteConsumer.h
index 9b5564853c2..8c7a00280b5 100644
--- a/clang/include/clang/Sema/CodeCompleteConsumer.h
+++ b/clang/include/clang/Sema/CodeCompleteConsumer.h
@@ -268,12 +268,23 @@ private:
/// \brief The type of the base object in a member access expression.
QualType BaseType;
+ /// \brief The identifiers for Objective-C selector parts.
+ IdentifierInfo **SelIdents;
+
+ /// \brief The number of Objective-C selector parts.
+ unsigned NumSelIdents;
+
public:
/// \brief Construct a new code-completion context of the given kind.
- CodeCompletionContext(enum Kind Kind) : Kind(Kind) { }
+ CodeCompletionContext(enum Kind Kind) : Kind(Kind), SelIdents(NULL),
+ NumSelIdents(0) { }
/// \brief Construct a new code-completion context of the given kind.
- CodeCompletionContext(enum Kind Kind, QualType T) : Kind(Kind) {
+ CodeCompletionContext(enum Kind Kind, QualType T,
+ IdentifierInfo **SelIdents = NULL,
+ unsigned NumSelIdents = 0) : Kind(Kind),
+ SelIdents(SelIdents),
+ NumSelIdents(NumSelIdents) {
if (Kind == CCC_DotMemberAccess || Kind == CCC_ArrowMemberAccess ||
Kind == CCC_ObjCPropertyAccess || Kind == CCC_ObjCClassMessage ||
Kind == CCC_ObjCInstanceMessage)
@@ -293,6 +304,12 @@ public:
/// \brief Retrieve the type of the base object in a member-access
/// expression.
QualType getBaseType() const { return BaseType; }
+
+ /// \brief Retrieve the Objective-C selector identifiers.
+ IdentifierInfo **getSelIdents() const { return SelIdents; }
+
+ /// \brief Retrieve the number of Objective-C selector identifiers.
+ unsigned getNumSelIdents() const { return NumSelIdents; }
/// \brief Determines whether we want C++ constructors as results within this
/// context.
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index a60fafe29c4..01e95174e2c 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -4960,7 +4960,7 @@ void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
ResultBuilder Results(*this, CodeCompleter->getAllocator(),
CodeCompletionContext(CodeCompletionContext::CCC_ObjCClassMessage,
- T));
+ T, SelIdents, NumSelIdents));
AddClassMessageCompletions(*this, S, Receiver, SelIdents, NumSelIdents,
AtArgumentExpression, IsSuper, Results);
@@ -5025,7 +5025,7 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
// Build the set of methods we can see.
ResultBuilder Results(*this, CodeCompleter->getAllocator(),
CodeCompletionContext(CodeCompletionContext::CCC_ObjCInstanceMessage,
- ReceiverType));
+ ReceiverType, SelIdents, NumSelIdents));
Results.EnterNewScope();
diff --git a/clang/test/Index/complete-objc-message.m b/clang/test/Index/complete-objc-message.m
index e80243a3005..7477f3f09ac 100644
--- a/clang/test/Index/complete-objc-message.m
+++ b/clang/test/Index/complete-objc-message.m
@@ -228,6 +228,7 @@ void test_block_invoke(A *(^block1)(int),
// RUN: c-index-test -code-completion-at=%s:95:24 %s | FileCheck -check-prefix=CHECK-CC9 %s
// CHECK-CC9: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{Informative Arg1:}{TypedText Arg2:}{Placeholder (int)}
// CHECK-CC9: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{Informative Arg1:}{TypedText OtherArg:}{Placeholder (id)}
+// CHECK-CC9: Objective-C selector: Method:Arg1:
// RUN: c-index-test -code-completion-at=%s:61:11 %s | FileCheck -check-prefix=CHECK-CCA %s
// CHECK-CCA: TypedefDecl:{TypedText Class}
// CHECK-CCA-NEXT: ObjCInterfaceDecl:{TypedText Foo}
@@ -253,6 +254,7 @@ void test_block_invoke(A *(^block1)(int),
// CHECK-CCD: ObjCClassMethodDecl:{ResultType int}{Informative Method:}{TypedText Arg1:}{Placeholder (int)}{HorizontalSpace }{TypedText OtherArg:}{Placeholder (id)}
// CHECK-CCD: ObjCClassMethodDecl:{ResultType int}{Informative Method:}{TypedText SomeArg:}{Placeholder (int)}{HorizontalSpace }{TypedText OtherArg:}{Placeholder (id)}
// CHECK-CCD-NOT: ObjCClassMethodDecl:{ResultType int}{Informative Method:}{TypedText }
+// CHECK-CCD: Objective-C selector: Method:
// RUN: c-index-test -code-completion-at=%s:116:30 %s | FileCheck -check-prefix=CHECK-CCE %s
// CHECK-CCE: ObjCClassMethodDecl:{ResultType int}{Informative Method:}{Informative Arg1:}{TypedText Arg2:}{Placeholder (int)}
// CHECK-CCE: ObjCClassMethodDecl:{ResultType int}{Informative Method:}{Informative Arg1:}{TypedText OtherArg:}{Placeholder (id)}
diff --git a/clang/tools/c-index-test/c-index-test.c b/clang/tools/c-index-test/c-index-test.c
index 6d7bf5bb15a..b737a38229e 100644
--- a/clang/tools/c-index-test/c-index-test.c
+++ b/clang/tools/c-index-test/c-index-test.c
@@ -1201,6 +1201,8 @@ int perform_code_completion(int argc, const char **argv, int timing_only) {
unsigned i, n = results->NumResults, containerIsIncomplete = 0;
unsigned long long contexts;
enum CXCursorKind containerKind;
+ CXString objCSelector;
+ const char *selectorString;
if (!timing_only) {
/* Sort the code-completion results based on the typed text. */
clang_sortCodeCompletionResults(results->Results, results->NumResults);
@@ -1218,7 +1220,8 @@ int perform_code_completion(int argc, const char **argv, int timing_only) {
contexts = clang_codeCompleteGetContexts(results);
print_completion_contexts(contexts, stdout);
- containerKind = clang_codeCompleteGetContainerKind(results, &containerIsIncomplete);
+ containerKind = clang_codeCompleteGetContainerKind(results,
+ &containerIsIncomplete);
if (containerKind != CXCursor_InvalidCode) {
/* We have found a container */
@@ -1239,6 +1242,13 @@ int perform_code_completion(int argc, const char **argv, int timing_only) {
clang_disposeString(containerUSR);
}
+ objCSelector = clang_codeCompleteGetObjCSelector(results);
+ selectorString = clang_getCString(objCSelector);
+ if (selectorString && strlen(selectorString) > 0) {
+ printf("Objective-C selector: %s\n", selectorString);
+ }
+ clang_disposeString(objCSelector);
+
clang_disposeCodeCompleteResults(results);
}
clang_disposeTranslationUnit(TU);
diff --git a/clang/tools/libclang/CIndexCodeCompletion.cpp b/clang/tools/libclang/CIndexCodeCompletion.cpp
index 59636bf2d85..84050b2cfdc 100644
--- a/clang/tools/libclang/CIndexCodeCompletion.cpp
+++ b/clang/tools/libclang/CIndexCodeCompletion.cpp
@@ -247,10 +247,17 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
/// current context.
unsigned long long Contexts;
+ /// \brief The kind of the container for the current context for completions.
enum CXCursorKind ContainerKind;
+ /// \brief The USR of the container for the current context for completions.
CXString ContainerUSR;
-
+ /// \brief a boolean value indicating whether there is complete information
+ /// about the container
unsigned ContainerIsIncomplete;
+
+ /// \brief A string containing the Objective-C selector entered thus far for a
+ /// message send.
+ std::string Selector;
};
/// \brief Tracks the number of code-completion result objects that are
@@ -495,6 +502,18 @@ namespace {
AllocatedResults.ContextKind = contextKind;
AllocatedResults.Contexts = getContextsForContextKind(contextKind, S);
+ AllocatedResults.Selector = "";
+ if (Context.getNumSelIdents() > 0) {
+ for (unsigned i = 0; i < Context.getNumSelIdents(); i++) {
+ IdentifierInfo *selIdent = Context.getSelIdents()[i];
+ if (selIdent != NULL) {
+ StringRef selectorString = Context.getSelIdents()[i]->getName();
+ AllocatedResults.Selector += selectorString.str();
+ }
+ AllocatedResults.Selector += ":";
+ }
+ }
+
QualType baseType = Context.getBaseType();
NamedDecl *D = NULL;
@@ -677,7 +696,7 @@ void clang_codeCompleteAt_Impl(void *UserData) {
}
pchName.push_back('\0');
struct stat stat_results;
- if (stat(pchName.data(), &stat_results) == 0)
+ if (stat(pchName.str().c_str(), &stat_results) == 0)
usesPCH = true;
continue;
}
@@ -810,6 +829,16 @@ CXString clang_codeCompleteGetContainerUSR(CXCodeCompleteResults *ResultsIn) {
return createCXString(clang_getCString(Results->ContainerUSR));
}
+
+
+CXString clang_codeCompleteGetObjCSelector(CXCodeCompleteResults *ResultsIn) {
+ AllocatedCXCodeCompleteResults *Results =
+ static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
+ if (!Results)
+ return createCXString("");
+
+ return createCXString(Results->Selector);
+}
} // end extern "C"
diff --git a/clang/tools/libclang/libclang.darwin.exports b/clang/tools/libclang/libclang.darwin.exports
index 96108649a10..59905364d8d 100644
--- a/clang/tools/libclang/libclang.darwin.exports
+++ b/clang/tools/libclang/libclang.darwin.exports
@@ -10,6 +10,7 @@ _clang_codeCompleteGetNumDiagnostics
_clang_codeCompleteGetContainerKind
_clang_codeCompleteGetContainerUSR
_clang_codeCompleteGetContexts
+_clang_codeCompleteGetObjCSelector
_clang_constructUSR_ObjCCategory
_clang_constructUSR_ObjCClass
_clang_constructUSR_ObjCIvar
diff --git a/clang/tools/libclang/libclang.exports b/clang/tools/libclang/libclang.exports
index 329ae5a5589..ab9face5ec3 100644
--- a/clang/tools/libclang/libclang.exports
+++ b/clang/tools/libclang/libclang.exports
@@ -10,6 +10,7 @@ clang_codeCompleteGetNumDiagnostics
clang_codeCompleteGetContainerKind
clang_codeCompleteGetContainerUSR
clang_codeCompleteGetContexts
+clang_codeCompleteGetObjCSelector
clang_constructUSR_ObjCCategory
clang_constructUSR_ObjCClass
clang_constructUSR_ObjCIvar
OpenPOWER on IntegriCloud