[cfe-commits] r114082 - in /cfe/trunk: include/clang/Basic/IdentifierTable.h lib/Sema/SemaCodeComplete.cpp test/Index/complete-objc-message.m
Douglas Gregor
dgregor at apple.com
Thu Sep 16 09:06:31 PDT 2010
Author: dgregor
Date: Thu Sep 16 11:06:31 2010
New Revision: 114082
URL: http://llvm.org/viewvc/llvm-project?rev=114082&view=rev
Log:
Don't add two code-completion results for the same selector; it
doesn't add any value. Instead, we'll just take the first method with
that selector that we find and create a completion for it.
Modified:
cfe/trunk/include/clang/Basic/IdentifierTable.h
cfe/trunk/lib/Sema/SemaCodeComplete.cpp
cfe/trunk/test/Index/complete-objc-message.m
Modified: cfe/trunk/include/clang/Basic/IdentifierTable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/IdentifierTable.h?rev=114082&r1=114081&r2=114082&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/IdentifierTable.h (original)
+++ cfe/trunk/include/clang/Basic/IdentifierTable.h Thu Sep 16 11:06:31 2010
@@ -570,6 +570,17 @@
template <>
struct isPodLike<clang::Selector> { static const bool value = true; };
+template<>
+class PointerLikeTypeTraits<clang::Selector> {
+public:
+ static inline const void *getAsVoidPointer(clang::Selector P) {
+ return P.getAsOpaquePtr();
+ }
+ static inline clang::Selector getFromVoidPointer(const void *P) {
+ return clang::Selector(reinterpret_cast<uintptr_t>(P));
+ }
+ enum { NumLowBitsAvailable = 0 };
+};
// Provide PointerLikeTypeTraits for IdentifierInfo pointers, which
// are not guaranteed to be 8-byte aligned.
Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=114082&r1=114081&r2=114082&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Thu Sep 16 11:06:31 2010
@@ -22,6 +22,7 @@
#include "clang/AST/ExprObjC.h"
#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/Preprocessor.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
@@ -3824,7 +3825,13 @@
return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
NumSelIdents);
}
-
+
+namespace {
+ /// \brief A set of selectors, which is used to avoid introducing multiple
+ /// completions with the same selector into the result set.
+ typedef llvm::SmallPtrSet<Selector, 16> VisitedSelectorSet;
+}
+
/// \brief Add all of the Objective-C methods in the given Objective-C
/// container to the set of results.
///
@@ -3848,6 +3855,7 @@
IdentifierInfo **SelIdents,
unsigned NumSelIdents,
DeclContext *CurContext,
+ VisitedSelectorSet &Selectors,
ResultBuilder &Results,
bool InOriginalClass = true) {
typedef CodeCompletionResult Result;
@@ -3860,6 +3868,9 @@
if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
continue;
+ if (!Selectors.insert((*M)->getSelector()))
+ continue;
+
Result R = Result(*M, 0);
R.StartParameter = NumSelIdents;
R.AllParametersAreInformative = (WantKind != MK_Any);
@@ -3877,7 +3888,7 @@
E = Protocols.end();
I != E; ++I)
AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
- CurContext, Results, false);
+ CurContext, Selectors, Results, false);
}
ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
@@ -3890,13 +3901,14 @@
E = Protocols.end();
I != E; ++I)
AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
- CurContext, Results, false);
+ CurContext, Selectors, Results, false);
// Add methods in categories.
for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
CatDecl = CatDecl->getNextClassCategory()) {
AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
- NumSelIdents, CurContext, Results, InOriginalClass);
+ NumSelIdents, CurContext, Selectors, Results,
+ InOriginalClass);
// Add a categories protocol methods.
const ObjCList<ObjCProtocolDecl> &Protocols
@@ -3905,23 +3917,26 @@
E = Protocols.end();
I != E; ++I)
AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
- NumSelIdents, CurContext, Results, false);
+ NumSelIdents, CurContext, Selectors, Results, false);
// Add methods in category implementations.
if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
- NumSelIdents, CurContext, Results, InOriginalClass);
+ NumSelIdents, CurContext, Selectors, Results,
+ InOriginalClass);
}
// Add methods in superclass.
if (IFace->getSuperClass())
AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
- SelIdents, NumSelIdents, CurContext, Results, false);
+ SelIdents, NumSelIdents, CurContext, Selectors, Results,
+ false);
// Add methods in our implementation, if any.
if (ObjCImplementationDecl *Impl = IFace->getImplementation())
AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
- NumSelIdents, CurContext, Results, InOriginalClass);
+ NumSelIdents, CurContext, Selectors, Results,
+ InOriginalClass);
}
@@ -3958,7 +3973,9 @@
}
}
- AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
+ VisitedSelectorSet Selectors;
+ AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Selectors,
+ Results);
Results.ExitScope();
HandleCodeCompleteResults(this, CodeCompleter,
CodeCompletionContext::CCC_Other,
@@ -3999,7 +4016,9 @@
}
}
- AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
+ VisitedSelectorSet Selectors;
+ AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext,
+ Selectors, Results);
Results.ExitScope();
HandleCodeCompleteResults(this, CodeCompleter,
@@ -4357,9 +4376,10 @@
if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl())
Results.setPreferredSelector(CurMethod->getSelector());
+ VisitedSelectorSet Selectors;
if (CDecl)
AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents,
- SemaRef.CurContext, Results);
+ SemaRef.CurContext, Selectors, Results);
else {
// We're messaging "id" as a type; provide all class/factory methods.
@@ -4450,6 +4470,9 @@
ReceiverType = Context.getObjCObjectPointerType(
Context.getObjCInterfaceType(IFace));
+ // Keep track of the selectors we've already added.
+ VisitedSelectorSet Selectors;
+
// Handle messages to Class. This really isn't a message to an instance
// method, so we treat it the same way we would treat a message send to a
// class method.
@@ -4458,7 +4481,7 @@
if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
- CurContext, Results);
+ CurContext, Selectors, Results);
}
}
// Handle messages to a qualified ID ("id<foo>").
@@ -4469,21 +4492,21 @@
E = QualID->qual_end();
I != E; ++I)
AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
- Results);
+ Selectors, Results);
}
// Handle messages to a pointer to interface type.
else if (const ObjCObjectPointerType *IFacePtr
= ReceiverType->getAsObjCInterfacePointerType()) {
// Search the class, its superclasses, etc., for instance methods.
AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
- NumSelIdents, CurContext, Results);
+ NumSelIdents, CurContext, Selectors, Results);
// Search protocols for instance methods.
for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
E = IFacePtr->qual_end();
I != E; ++I)
AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
- Results);
+ Selectors, Results);
}
// Handle messages to "id".
else if (ReceiverType->isObjCIdType()) {
@@ -4512,7 +4535,10 @@
if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
NumSelIdents))
continue;
-
+
+ if (!Selectors.insert(MethList->Method->getSelector()))
+ continue;
+
Result R(MethList->Method, 0);
R.StartParameter = NumSelIdents;
R.AllParametersAreInformative = false;
Modified: cfe/trunk/test/Index/complete-objc-message.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-objc-message.m?rev=114082&r1=114081&r2=114082&view=diff
==============================================================================
--- cfe/trunk/test/Index/complete-objc-message.m (original)
+++ cfe/trunk/test/Index/complete-objc-message.m Thu Sep 16 11:06:31 2010
@@ -141,6 +141,15 @@
(Overload2 Method:1 Arg1:1 OtherArg:ovl]);
}
+ at interface C : B
+- (void)method2;
+- (void)method3;
+ at end
+
+void test_redundancy(C *c) {
+ [c method2];
+};
+
// RUN: c-index-test -code-completion-at=%s:23:19 %s | FileCheck -check-prefix=CHECK-CC1 %s
// CHECK-CC1: {TypedText categoryClassMethod}
// CHECK-CC1: {TypedText classMethod1:}{Placeholder (id)}{HorizontalSpace }{Text withKeyword:}{Placeholder (int)}
@@ -242,6 +251,11 @@
// CHECK-CCI: ObjCInstanceMethodDecl:{ResultType void}{TypedText method1} (22)
// CHECK-CCI: ObjCInstanceMethodDecl:{ResultType void}{TypedText method2} (20)
+// RUN: c-index-test -code-completion-at=%s:150:5 %s | FileCheck -check-prefix=CHECK-REDUNDANT %s
+// CHECK-REDUNDANT: ObjCInstanceMethodDecl:{ResultType void}{TypedText method2} (20)
+// CHECK-REDUNDANT-NOT: ObjCInstanceMethodDecl:{ResultType void}{TypedText method2}
+// CHECK-REDUNDANT: ObjCInstanceMethodDecl:{ResultType void}{TypedText method3} (20)
+
// Test code completion with a missing opening bracket:
// RUN: c-index-test -code-completion-at=%s:135:5 %s | FileCheck -check-prefix=CHECK-CCI %s
// RUN: c-index-test -code-completion-at=%s:139:7 %s | FileCheck -check-prefix=CHECK-CC7 %s
More information about the cfe-commits
mailing list