diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Sema/SemaCodeComplete.cpp | 23 | ||||
-rw-r--r-- | clang/test/CodeCompletion/member-access.cpp | 2 | ||||
-rw-r--r-- | clang/test/Index/code-completion.cpp | 7 |
3 files changed, 19 insertions, 13 deletions
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 63c8bdcc6c2..b1452b91528 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -364,11 +364,15 @@ void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) { (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")) @@ -571,18 +575,19 @@ bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const { 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. @@ -1479,6 +1484,8 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE, // 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); diff --git a/clang/test/CodeCompletion/member-access.cpp b/clang/test/CodeCompletion/member-access.cpp index e445b4503aa..6fefb64c705 100644 --- a/clang/test/CodeCompletion/member-access.cpp +++ b/clang/test/CodeCompletion/member-access.cpp @@ -37,6 +37,6 @@ void test(const Proxy &p) { // CHECK-CC1: memfun1 : 0 : [#Base3::#]memfun1(<#double#>) // CHECK-CC1: memfun2 : 0 : [#Base3::#]memfun2(<#int#>) // CHECK-CC1: memfun3 : 0 : memfun3(<#int#>) - // CHECK-CC1: Base1 : 0 : Base1:: // CHECK-CC1: memfun1 : 0 (Hidden) : Base2::memfun1(<#int#>) + // CHECK-CC1: Base1 : 3 : Base1:: diff --git a/clang/test/Index/code-completion.cpp b/clang/test/Index/code-completion.cpp index 44bd9d28932..c286c82d048 100644 --- a/clang/test/Index/code-completion.cpp +++ b/clang/test/Index/code-completion.cpp @@ -33,20 +33,19 @@ void test_overloaded() { 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 )} |