From: Douglas Gregor Date: Wed, 28 Jul 2010 21:50:18 +0000 (+0000) Subject: When performing code completion for a case statement in a switch whose X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f9578436414e4a5e4af8b77567b89c1679f99519;p=clang When performing code completion for a case statement in a switch whose condition is not of enumeration type, provide code-completion results containing all values of integral or enumeral type. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109677 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index e1829d29b3..b0b777073c 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -4526,7 +4526,8 @@ public: //@{ virtual void CodeCompleteOrdinaryName(Scope *S, CodeCompletionContext CompletionContext); - virtual void CodeCompleteExpression(Scope *S, QualType T); + virtual void CodeCompleteExpression(Scope *S, QualType T, + bool IntegralConstantExpression = false); virtual void CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *Base, SourceLocation OpLoc, bool IsArrow); diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index 55288750fd..bc0335556f 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -227,6 +227,7 @@ namespace { //@{ bool IsOrdinaryName(NamedDecl *ND) const; bool IsOrdinaryNonTypeName(NamedDecl *ND) const; + bool IsIntegralConstantValue(NamedDecl *ND) const; bool IsOrdinaryNonValueName(NamedDecl *ND) const; bool IsNestedNameSpecifier(NamedDecl *ND) const; bool IsEnum(NamedDecl *ND) const; @@ -821,6 +822,17 @@ bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const { return ND->getIdentifierNamespace() & IDNS; } +bool ResultBuilder::IsIntegralConstantValue(NamedDecl *ND) const { + if (!IsOrdinaryNonTypeName(ND)) + return 0; + + if (ValueDecl *VD = dyn_cast(ND->getUnderlyingDecl())) + if (VD->getType()->isIntegralOrEnumerationType()) + return true; + + return false; +} + /// \brief Determines whether this given declaration will be found by /// ordinary name lookup. bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const { @@ -2271,11 +2283,17 @@ void Sema::CodeCompleteOrdinaryName(Scope *S, /// \brief Perform code-completion in an expression context when we know what /// type we're looking for. -void Sema::CodeCompleteExpression(Scope *S, QualType T) { +/// +/// \param IntegralConstantExpression Only permit integral constant +/// expressions. +void Sema::CodeCompleteExpression(Scope *S, QualType T, + bool IntegralConstantExpression) { typedef CodeCompleteConsumer::Result Result; ResultBuilder Results(*this); - if (WantTypesInContext(CCC_Expression, getLangOptions())) + if (IntegralConstantExpression) + Results.setFilter(&ResultBuilder::IsIntegralConstantValue); + else if (WantTypesInContext(CCC_Expression, getLangOptions())) Results.setFilter(&ResultBuilder::IsOrdinaryName); else Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName); @@ -2476,8 +2494,10 @@ void Sema::CodeCompleteCase(Scope *S) { return; SwitchStmt *Switch = getSwitchStack().back(); - if (!Switch->getCond()->getType()->isEnumeralType()) + if (!Switch->getCond()->getType()->isEnumeralType()) { + CodeCompleteExpression(S, Switch->getCond()->getType(), true); return; + } // Code-complete the cases of a switch statement over an enumeration type // by providing the list of diff --git a/test/CodeCompletion/enum-switch-case.c b/test/CodeCompletion/enum-switch-case.c index 082072600f..d5df371152 100644 --- a/test/CodeCompletion/enum-switch-case.c +++ b/test/CodeCompletion/enum-switch-case.c @@ -18,11 +18,28 @@ void test(enum Color color) { case Green: break; - + } + + unsigned c2; + switch (c2) { + case + } + // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:19:10 %s -o - | FileCheck -check-prefix=CC1 %s // CHECK-CC1: Blue // CHECK-CC1-NEXT: Green // CHECK-CC1-NEXT: Indigo // CHECK-CC1-NEXT: Orange // CHECK-CC1-NEXT: Violet - + + // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:25:10 %s -o - | FileCheck -check-prefix=CC2 %s + // CHECK-CC2: COMPLETION: Blue : [#enum Color#]Blue + // CHECK-CC2-NEXT: COMPLETION: c2 : [#unsigned int#]c2 + // CHECK-CC2-NEXT: COMPLETION: color : [#enum Color#]color + // CHECK-CC2-NEXT: COMPLETION: Green : [#enum Color#]Green + // CHECK-CC2-NEXT: COMPLETION: Indigo : [#enum Color#]Indigo + // CHECK-CC2-NEXT: COMPLETION: Orange : [#enum Color#]Orange + // CHECK-CC2-NEXT: COMPLETION: Red : [#enum Color#]Red + // CHECK-CC2-NEXT: COMPLETION: Pattern : sizeof(<#expression-or-type#>) + // CHECK-CC2-NEXT: COMPLETION: Violet : [#enum Color#]Violet + // CHECK-CC2-NEXT: COMPLETION: Yellow : [#enum Color#]Yellow