From 3a69eafa8845e1f440cff77ecabd3daf1588adb5 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 18 Feb 2011 23:30:37 +0000 Subject: [PATCH] When code-completing a case statement for a switch on a value of enumeration type, prioritize the enumeration constants and don't provide completions for any other expressions. Fixes . llvm-svn: 125991 --- .../include/clang/Sema/CodeCompleteConsumer.h | 6 +++++ clang/lib/Frontend/ASTUnit.cpp | 5 ++-- clang/lib/Sema/CodeCompleteConsumer.cpp | 1 + clang/lib/Sema/SemaCodeComplete.cpp | 7 +++--- clang/test/Index/complete-enums.c | 23 ++++++++++++------- 5 files changed, 29 insertions(+), 13 deletions(-) diff --git a/clang/include/clang/Sema/CodeCompleteConsumer.h b/clang/include/clang/Sema/CodeCompleteConsumer.h index 2838c19b7232..882440b78c7c 100644 --- a/clang/include/clang/Sema/CodeCompleteConsumer.h +++ b/clang/include/clang/Sema/CodeCompleteConsumer.h @@ -36,6 +36,9 @@ enum { /// \brief Priority for the next initialization in a constructor initializer /// list. CCP_NextInitializer = 7, + /// \brief Priority for an enumeration constant inside a switch whose + /// condition is of the enumeration type. + CCP_EnumInCase = 7, /// \brief Priority for a send-to-super completion. CCP_SuperCompletion = 20, /// \brief Priority for a declaration that is in the local scope. @@ -153,6 +156,9 @@ public: enum Kind { /// \brief An unspecified code-completion context. CCC_Other, + /// \brief An unspecified code-completion context where we should also add + /// macro completions. + CCC_OtherWithMacros, /// \brief Code completion occurred within a "top-level" completion context, /// e.g., at namespace or global scope. CCC_TopLevel, diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index 46f5b5a48e74..4a5a51d9f1dc 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -333,8 +333,8 @@ void ASTUnit::CacheCodeCompletionResults() { | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1)) | (1 << (CodeCompletionContext::CCC_MacroNameUse - 1)) | (1 << (CodeCompletionContext::CCC_PreprocessorExpression - 1)) - | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1)); - + | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1)) + | (1 << (CodeCompletionContext::CCC_OtherWithMacros - 1)); CachedResult.Priority = Results[I].Priority; CachedResult.Kind = Results[I].CursorKind; @@ -1790,6 +1790,7 @@ static void CalculateHiddenNames(const CodeCompletionContext &Context, case CodeCompletionContext::CCC_SelectorName: case CodeCompletionContext::CCC_TypeQualifiers: case CodeCompletionContext::CCC_Other: + case CodeCompletionContext::CCC_OtherWithMacros: // We're looking for nothing, or we're looking for names that cannot // be hidden. return; diff --git a/clang/lib/Sema/CodeCompleteConsumer.cpp b/clang/lib/Sema/CodeCompleteConsumer.cpp index 253c10e7d5e9..b7037ce83e7f 100644 --- a/clang/lib/Sema/CodeCompleteConsumer.cpp +++ b/clang/lib/Sema/CodeCompleteConsumer.cpp @@ -63,6 +63,7 @@ bool CodeCompletionContext::wantConstructorResults() const { case CCC_SelectorName: case CCC_TypeQualifiers: case CCC_Other: + case CCC_OtherWithMacros: return false; } diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index a65d5fd6fc70..aef5cab98acf 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -3331,15 +3331,16 @@ void Sema::CodeCompleteCase(Scope *S) { if (EnumeratorsSeen.count(*E)) continue; - Results.AddResult(CodeCompletionResult(*E, Qualifier), - CurContext, 0, false); + CodeCompletionResult R(*E, Qualifier); + R.Priority = CCP_EnumInCase; + Results.AddResult(R, CurContext, 0, false); } Results.ExitScope(); if (CodeCompleter->includeMacros()) AddMacroResults(PP, Results); HandleCodeCompleteResults(this, CodeCompleter, - CodeCompletionContext::CCC_Expression, + CodeCompletionContext::CCC_OtherWithMacros, Results.data(),Results.size()); } diff --git a/clang/test/Index/complete-enums.c b/clang/test/Index/complete-enums.c index 5e712a11227f..33a4cd42811c 100644 --- a/clang/test/Index/complete-enums.c +++ b/clang/test/Index/complete-enums.c @@ -1,15 +1,22 @@ // Note: the run lines follow their respective tests, since line/column // matter in this test. -enum { - Red = 17, - Green, - Blue +enum Color { + Color_Red = 17, + Color_Green, + Color_Blue }; - -void f() { - +int Greeby(); +void f(Color color) { + switch (color) { + case Red: + } } // RUN: c-index-test -code-completion-at=%s:11:1 %s | FileCheck -check-prefix=CHECK-CC1 %s -// CHECK-CC1: EnumConstantDecl:{ResultType enum }{TypedText Red} +// CHECK-CC1: EnumConstantDecl:{ResultType enum Color}{TypedText Color_Red} + +// RUN: c-index-test -code-completion-at=%s:12:8 %s | FileCheck -check-prefix=CHECK-CC2 %s +// CHECK-CC2: EnumConstantDecl:{ResultType enum Color}{TypedText Color_Blue} (7) +// CHECK-CC2-NEXT: EnumConstantDecl:{ResultType enum Color}{TypedText Color_Green} (7) +// CHECK-CC2-NEXT: EnumConstantDecl:{ResultType enum Color}{TypedText Color_Red} (7)