From 4710e5b12b58dda87d82c5875f13ab9c8979cd8c Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 28 May 2010 00:49:12 +0000 Subject: Do not produce types as valid code completions when we're in an expression context in C/Objective-C, or when we're in an @interface/@implementation/@protocol in Objective-C(++). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@104908 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaCodeComplete.cpp | 60 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 3 deletions(-) (limited to 'lib/Sema/SemaCodeComplete.cpp') diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index 42a92b72d9..0e8fb59368 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -212,6 +212,7 @@ namespace { /// //@{ bool IsOrdinaryName(NamedDecl *ND) const; + bool IsOrdinaryNonTypeName(NamedDecl *ND) const; bool IsOrdinaryNonValueName(NamedDecl *ND) const; bool IsNestedNameSpecifier(NamedDecl *ND) const; bool IsEnum(NamedDecl *ND) const; @@ -646,6 +647,8 @@ void ResultBuilder::ExitScope() { /// \brief Determines whether this given declaration will be found by /// ordinary name lookup. bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const { + ND = cast(ND->getUnderlyingDecl()); + unsigned IDNS = Decl::IDNS_Ordinary; if (SemaRef.getLangOptions().CPlusPlus) IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace; @@ -655,15 +658,34 @@ bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const { return ND->getIdentifierNamespace() & IDNS; } +/// \brief Determines whether this given declaration will be found by +/// ordinary name lookup but is not a type name. +bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const { + ND = cast(ND->getUnderlyingDecl()); + if (isa(ND) || isa(ND)) + return false; + + unsigned IDNS = Decl::IDNS_Ordinary; + if (SemaRef.getLangOptions().CPlusPlus) + IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace; + else if (SemaRef.getLangOptions().ObjC1 && isa(ND)) + return true; + + return ND->getIdentifierNamespace() & IDNS; +} + /// \brief Determines whether this given declaration will be found by /// ordinary name lookup. bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const { + ND = cast(ND->getUnderlyingDecl()); + unsigned IDNS = Decl::IDNS_Ordinary; if (SemaRef.getLangOptions().CPlusPlus) IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace; return (ND->getIdentifierNamespace() & IDNS) && - !isa(ND) && !isa(ND); + !isa(ND) && !isa(ND) && + !isa(ND); } /// \brief Determines whether the given declaration is suitable as the @@ -973,6 +995,34 @@ static void AddTypedefResult(ResultBuilder &Results) { Results.AddResult(CodeCompleteConsumer::Result(Pattern)); } +static bool WantTypesInContext(Action::CodeCompletionContext CCC, + const LangOptions &LangOpts) { + if (LangOpts.CPlusPlus) + return true; + + switch (CCC) { + case Action::CCC_Namespace: + case Action::CCC_Class: + case Action::CCC_ObjCInstanceVariableList: + case Action::CCC_Template: + case Action::CCC_MemberTemplate: + case Action::CCC_Statement: + case Action::CCC_RecoveryInFunction: + return true; + + case Action::CCC_ObjCInterface: + case Action::CCC_ObjCImplementation: + case Action::CCC_Expression: + case Action::CCC_Condition: + return false; + + case Action::CCC_ForInit: + return LangOpts.ObjC1 || LangOpts.C99; + } + + return false; +} + /// \brief Add language constructs that show up for "ordinary" names. static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC, Scope *S, @@ -1431,7 +1481,8 @@ static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC, } } - AddTypeSpecifierResults(SemaRef.getLangOptions(), Results); + if (WantTypesInContext(CCC, SemaRef.getLangOptions())) + AddTypeSpecifierResults(SemaRef.getLangOptions(), Results); if (SemaRef.getLangOptions().CPlusPlus) Results.AddResult(Result("operator")); @@ -2057,7 +2108,10 @@ void Sema::CodeCompleteOrdinaryName(Scope *S, case CCC_Statement: case CCC_ForInit: case CCC_Condition: - Results.setFilter(&ResultBuilder::IsOrdinaryName); + if (WantTypesInContext(CompletionContext, getLangOptions())) + Results.setFilter(&ResultBuilder::IsOrdinaryName); + else + Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName); break; case CCC_RecoveryInFunction: -- cgit v1.2.3-18-g5258