(IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend)))
return;
- // Class template (partial) specializations are never added as results
+ // Class template (partial) specializations are never added as results.
if (isa<ClassTemplateSpecializationDecl>(CanonDecl) ||
isa<ClassTemplatePartialSpecializationDecl>(CanonDecl))
return;
+ // Using declarations themselves are never added as results.
+ if (isa<UsingDecl>(CanonDecl))
+ return;
+
if (const IdentifierInfo *Id = R.Declaration->getIdentifier()) {
// __va_list_tag is a freak of nature. Find it and skip it.
if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
}
-/// \brief Brief determines whether the given declaration is a namespace or
-/// namespace alias.
+/// \brief Determines whether the given declaration is a type.
bool ResultBuilder::IsType(NamedDecl *ND) const {
return isa<TypeDecl>(ND);
}
-/// \brief Since every declaration found within a class is a member that we
-/// care about, always returns true. This predicate exists mostly to
-/// communicate to the result builder that we are performing a lookup for
-/// member access.
+/// \brief Determines which members of a class should be visible via
+/// "." or "->". Only value declarations, nested name specifiers, and
+/// using declarations thereof should show up.
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.
// We could have the start of a nested-name-specifier. Add those
// 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);
CollectLookupResults(S, Context.getTranslationUnitDecl(), NextRank,
CurContext, Results);
overloaded(Z(), 0);
}
-// CHECK-MEMBER: EnumDecl:{Informative X::}{TypedText E}
// CHECK-MEMBER: FieldDecl:{TypedText member}
// CHECK-MEMBER: FunctionDecl:{Informative Y::}{TypedText memfunc}{LeftParen (}{Optional {Placeholder int i}}{RightParen )}
// CHECK-MEMBER: EnumConstantDecl:{Informative E::}{TypedText Val1}
// CHECK-MEMBER: FunctionDecl:{Informative X::}{TypedText ~X}{LeftParen (}{RightParen )}
// CHECK-MEMBER: FunctionDecl:{TypedText operator int}{LeftParen (}{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 Y::}{TypedText member}
// 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: 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 int i}{Comma , }{CurrentParameter long second}{RightParen )}