]> granicus.if.org Git - clang/commitdiff
When performing code completion for a case statement in a switch whose
authorDouglas Gregor <dgregor@apple.com>
Wed, 28 Jul 2010 21:50:18 +0000 (21:50 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 28 Jul 2010 21:50:18 +0000 (21:50 +0000)
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

lib/Sema/Sema.h
lib/Sema/SemaCodeComplete.cpp
test/CodeCompletion/enum-switch-case.c

index e1829d29b34a79973dd82d377b2096e0adffeeb3..b0b777073c7eccd9fcaa8d11d698d367cf4401ec 100644 (file)
@@ -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);
index 55288750fd5f2dbf43dbded66fd47f4f1d32dd45..bc0335556f9a32d9aae5a3fce7d066c12325003e 100644 (file)
@@ -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<ValueDecl>(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 
index 082072600ffe8847c13ee2da27fb6a4ec06e3d40..d5df37115222fc37857c248ea7e0a08582afc251 100644 (file)
@@ -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