Tweak code-completion results by suppressing class template

specializations and class template partial specializations (they're
never named directly). Also, member access expressions only refer to
value declarations (fields, functions, enumerators, etc.) and
Objective-C property declarations; filter out everything else.

llvm-svn: 91133
This commit is contained in:
Douglas Gregor
2009-12-11 17:31:05 +00:00
parent b41a5c9308
commit 99fe2ad8c8
3 changed files with 19 additions and 13 deletions

View File

@@ -364,11 +364,15 @@ void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
(IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))) (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend)))
return; return;
// Class template (partial) specializations are never added as results // Class template (partial) specializations are never added as results.
if (isa<ClassTemplateSpecializationDecl>(CanonDecl) || if (isa<ClassTemplateSpecializationDecl>(CanonDecl) ||
isa<ClassTemplatePartialSpecializationDecl>(CanonDecl)) isa<ClassTemplatePartialSpecializationDecl>(CanonDecl))
return; return;
// Using declarations themselves are never added as results.
if (isa<UsingDecl>(CanonDecl))
return;
if (const IdentifierInfo *Id = R.Declaration->getIdentifier()) { if (const IdentifierInfo *Id = R.Declaration->getIdentifier()) {
// __va_list_tag is a freak of nature. Find it and skip it. // __va_list_tag is a freak of nature. Find it and skip it.
if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list")) if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
@@ -571,18 +575,19 @@ bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND); return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
} }
/// \brief Brief determines whether the given declaration is a namespace or /// \brief Determines whether the given declaration is a type.
/// namespace alias.
bool ResultBuilder::IsType(NamedDecl *ND) const { bool ResultBuilder::IsType(NamedDecl *ND) const {
return isa<TypeDecl>(ND); return isa<TypeDecl>(ND);
} }
/// \brief Since every declaration found within a class is a member that we /// \brief Determines which members of a class should be visible via
/// care about, always returns true. This predicate exists mostly to /// "." or "->". Only value declarations, nested name specifiers, and
/// communicate to the result builder that we are performing a lookup for /// using declarations thereof should show up.
/// member access.
bool ResultBuilder::IsMember(NamedDecl *ND) const { bool ResultBuilder::IsMember(NamedDecl *ND) const {
return true; if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
ND = Using->getTargetDecl();
return isa<ValueDecl>(ND) || isa<ObjCPropertyDecl>(ND);
} }
// Find the next outer declaration context corresponding to this scope. // Find the next outer declaration context corresponding to this scope.
@@ -1479,6 +1484,8 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
// We could have the start of a nested-name-specifier. Add those // We could have the start of a nested-name-specifier. Add those
// results as well. // results as well.
// FIXME: We should really walk base classes to produce
// nested-name-specifiers so that we produce more-precise results.
Results.setFilter(&ResultBuilder::IsNestedNameSpecifier); Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
CollectLookupResults(S, Context.getTranslationUnitDecl(), NextRank, CollectLookupResults(S, Context.getTranslationUnitDecl(), NextRank,
CurContext, Results); CurContext, Results);

View File

@@ -37,6 +37,6 @@ void test(const Proxy &p) {
// CHECK-CC1: memfun1 : 0 : [#Base3::#]memfun1(<#double#>) // CHECK-CC1: memfun1 : 0 : [#Base3::#]memfun1(<#double#>)
// CHECK-CC1: memfun2 : 0 : [#Base3::#]memfun2(<#int#>) // CHECK-CC1: memfun2 : 0 : [#Base3::#]memfun2(<#int#>)
// CHECK-CC1: memfun3 : 0 : memfun3(<#int#>) // CHECK-CC1: memfun3 : 0 : memfun3(<#int#>)
// CHECK-CC1: Base1 : 0 : Base1::
// CHECK-CC1: memfun1 : 0 (Hidden) : Base2::memfun1(<#int#>) // CHECK-CC1: memfun1 : 0 (Hidden) : Base2::memfun1(<#int#>)
// CHECK-CC1: Base1 : 3 : Base1::

View File

@@ -33,20 +33,19 @@ void test_overloaded() {
overloaded(Z(), 0); overloaded(Z(), 0);
} }
// CHECK-MEMBER: EnumDecl:{Informative X::}{TypedText E}
// CHECK-MEMBER: FieldDecl:{TypedText member} // CHECK-MEMBER: FieldDecl:{TypedText member}
// CHECK-MEMBER: FunctionDecl:{Informative Y::}{TypedText memfunc}{LeftParen (}{Optional {Placeholder int i}}{RightParen )} // CHECK-MEMBER: FunctionDecl:{Informative Y::}{TypedText memfunc}{LeftParen (}{Optional {Placeholder int i}}{RightParen )}
// CHECK-MEMBER: EnumConstantDecl:{Informative E::}{TypedText Val1} // CHECK-MEMBER: EnumConstantDecl:{Informative E::}{TypedText Val1}
// CHECK-MEMBER: FunctionDecl:{Informative X::}{TypedText ~X}{LeftParen (}{RightParen )} // CHECK-MEMBER: FunctionDecl:{Informative X::}{TypedText ~X}{LeftParen (}{RightParen )}
// CHECK-MEMBER: FunctionDecl:{TypedText operator int}{LeftParen (}{RightParen )} // CHECK-MEMBER: FunctionDecl:{TypedText operator int}{LeftParen (}{RightParen )}
// CHECK-MEMBER: FunctionDecl:{TypedText operator=}{LeftParen (}{Placeholder struct Z const &}{RightParen )} // CHECK-MEMBER: FunctionDecl:{TypedText operator=}{LeftParen (}{Placeholder struct Z const &}{RightParen )}
// CHECK-MEMBER: StructDecl:{TypedText X}{Text ::}
// CHECK-MEMBER: StructDecl:{TypedText Y}{Text ::}
// CHECK-MEMBER: StructDecl:{TypedText Z}{Text ::}
// CHECK-MEMBER: FieldDecl:{Text X::}{TypedText member} // CHECK-MEMBER: FieldDecl:{Text X::}{TypedText member}
// CHECK-MEMBER: FieldDecl:{Text Y::}{TypedText member} // CHECK-MEMBER: FieldDecl:{Text Y::}{TypedText member}
// CHECK-MEMBER: FunctionDecl:{Text X::}{TypedText operator=}{LeftParen (}{Placeholder struct X const &}{RightParen )} // CHECK-MEMBER: FunctionDecl:{Text X::}{TypedText operator=}{LeftParen (}{Placeholder struct X const &}{RightParen )}
// CHECK-MEMBER: FunctionDecl:{Text Y::}{TypedText operator=}{LeftParen (}{Placeholder struct Y const &}{RightParen )} // CHECK-MEMBER: FunctionDecl:{Text Y::}{TypedText operator=}{LeftParen (}{Placeholder struct Y const &}{RightParen )}
// CHECK-MEMBER: StructDecl:{TypedText X}{Text ::}
// CHECK-MEMBER: StructDecl:{TypedText Y}{Text ::}
// CHECK-MEMBER: StructDecl:{TypedText Z}{Text ::}
// CHECK-OVERLOAD: NotImplemented:{Text overloaded}{LeftParen (}{Text struct Z z}{Comma , }{CurrentParameter int second}{RightParen )} // CHECK-OVERLOAD: NotImplemented:{Text overloaded}{LeftParen (}{Text struct Z z}{Comma , }{CurrentParameter int second}{RightParen )}
// CHECK-OVERLOAD: NotImplemented:{Text overloaded}{LeftParen (}{Text int i}{Comma , }{CurrentParameter long second}{RightParen )} // CHECK-OVERLOAD: NotImplemented:{Text overloaded}{LeftParen (}{Text int i}{Comma , }{CurrentParameter long second}{RightParen )}