[CodeComplete] Add a trailing semicolons to some pattern completions
authorIlya Biryukov <ibiryukov@google.com>
Mon, 6 May 2019 13:18:00 +0000 (13:18 +0000)
committerIlya Biryukov <ibiryukov@google.com>
Mon, 6 May 2019 13:18:00 +0000 (13:18 +0000)
Summary:
Where semicolon is required in any case. Here's a list of completions
that now have a semicolon:
  - namespace <name> = <target>;
  - using namespace <name>;
  - using <qualifier>::<name>;
  - continue;
  - break;
  - goto <label>;
  - return;
  - return <expression>;

Reviewers: gribozavr

Reviewed By: gribozavr

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D61589

llvm-svn: 360042

clang/lib/Sema/SemaCodeComplete.cpp
clang/test/CodeCompletion/ordinary-name-cxx11.cpp
clang/test/CodeCompletion/ordinary-name.cpp
clang/test/CodeCompletion/patterns.cpp [new file with mode: 0644]

index c2d8040..4d23bf6 100644 (file)
@@ -1923,6 +1923,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, Scope *S,
       Builder.AddPlaceholderChunk("name");
       Builder.AddChunk(CodeCompletionString::CK_Equal);
       Builder.AddPlaceholderChunk("namespace");
+      Builder.AddChunk(CodeCompletionString::CK_SemiColon);
       Results.AddResult(Result(Builder.TakeString()));
 
       // Using directives
@@ -1931,6 +1932,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, Scope *S,
       Builder.AddTextChunk("namespace");
       Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
       Builder.AddPlaceholderChunk("identifier");
+      Builder.AddChunk(CodeCompletionString::CK_SemiColon);
       Results.AddResult(Result(Builder.TakeString()));
 
       // asm(string-literal)
@@ -1965,6 +1967,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, Scope *S,
       Builder.AddPlaceholderChunk("qualifier");
       Builder.AddTextChunk("::");
       Builder.AddPlaceholderChunk("name");
+      Builder.AddChunk(CodeCompletionString::CK_SemiColon);
       Results.AddResult(Result(Builder.TakeString()));
 
       // using typename qualifier::name (only in a dependent context)
@@ -1976,6 +1979,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, Scope *S,
         Builder.AddPlaceholderChunk("qualifier");
         Builder.AddTextChunk("::");
         Builder.AddPlaceholderChunk("name");
+        Builder.AddChunk(CodeCompletionString::CK_SemiColon);
         Results.AddResult(Result(Builder.TakeString()));
       }
 
@@ -2165,12 +2169,14 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, Scope *S,
     if (S->getContinueParent()) {
       // continue ;
       Builder.AddTypedTextChunk("continue");
+      Builder.AddChunk(CodeCompletionString::CK_SemiColon);
       Results.AddResult(Result(Builder.TakeString()));
     }
 
     if (S->getBreakParent()) {
       // break ;
       Builder.AddTypedTextChunk("break");
+      Builder.AddChunk(CodeCompletionString::CK_SemiColon);
       Results.AddResult(Result(Builder.TakeString()));
     }
 
@@ -2189,12 +2195,14 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, Scope *S,
       Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
       Builder.AddPlaceholderChunk("expression");
     }
+    Builder.AddChunk(CodeCompletionString::CK_SemiColon);
     Results.AddResult(Result(Builder.TakeString()));
 
     // goto identifier ;
     Builder.AddTypedTextChunk("goto");
     Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
     Builder.AddPlaceholderChunk("label");
+    Builder.AddChunk(CodeCompletionString::CK_SemiColon);
     Results.AddResult(Result(Builder.TakeString()));
 
     // Using directives
@@ -2203,6 +2211,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, Scope *S,
     Builder.AddTextChunk("namespace");
     Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
     Builder.AddPlaceholderChunk("identifier");
+    Builder.AddChunk(CodeCompletionString::CK_SemiColon);
     Results.AddResult(Result(Builder.TakeString()));
 
     AddStaticAssertResult(Builder, Results, SemaRef.getLangOpts());
index 0125ffb..7816243 100644 (file)
@@ -23,7 +23,7 @@ void foo() {
   // CHECK-CC1-NEXT: COMPLETION: float
   // CHECK-CC1-NEXT: COMPLETION: foo : [#void#]foo()
   // CHECK-CC1-NEXT: COMPLETION: Pattern : for(<#init-statement#>;<#condition#>;<#inc-expression#>){
-  // CHECK-CC1: COMPLETION: Pattern : goto <#label#>
+  // CHECK-CC1: COMPLETION: Pattern : goto <#label#>;
   // CHECK-CC1-NEXT: COMPLETION: Pattern : if(<#condition#>){<#statements#>
   // CHECK-CC1: COMPLETION: int
   // CHECK-CC1-NEXT: COMPLETION: long
@@ -33,7 +33,7 @@ void foo() {
   // CHECK-CC1-NEXT: COMPLETION: Pattern : [#std::nullptr_t#]nullptr
   // CHECK-CC1-NEXT: COMPLETION: operator
   // CHECK-CC1-NEXT: COMPLETION: Pattern : reinterpret_cast<<#type#>>(<#expression#>)
-  // CHECK-CC1-NEXT: COMPLETION: Pattern : return
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : return;
   // CHECK-CC1-NEXT: COMPLETION: short
   // CHECK-CC1-NEXT: COMPLETION: signed
   // CHECK-CC1-NEXT: COMPLETION: Pattern : [#size_t#]sizeof(<#expression-or-type#>)
@@ -56,7 +56,7 @@ void foo() {
   // CHECK-CC1-NEXT: COMPLETION: Pattern : typeof(<#type#>)
   // CHECK-CC1-NEXT: COMPLETION: union
   // CHECK-CC1-NEXT: COMPLETION: unsigned
-  // CHECK-CC1-NEXT: COMPLETION: Pattern : using namespace <#identifier#>
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : using namespace <#identifier#>;
   // CHECK-CC1-NEXT: COMPLETION: void
   // CHECK-CC1-NEXT: COMPLETION: volatile
   // CHECK-CC1-NEXT: COMPLETION: wchar_t
@@ -84,7 +84,7 @@ void foo() {
   // CHECK-CC2-NEXT: COMPLETION: int
   // CHECK-CC2-NEXT: COMPLETION: long
   // CHECK-CC2-NEXT: COMPLETION: Pattern : namespace <#identifier#>{<#declarations#>
-  // CHECK-CC2: COMPLETION: Pattern : namespace <#name#> = <#namespace#>
+  // CHECK-CC2: COMPLETION: Pattern : namespace <#name#> = <#namespace#>;
   // CHECK-CC2-NEXT: COMPLETION: operator
   // CHECK-CC2-NEXT: COMPLETION: short
   // CHECK-CC2-NEXT: COMPLETION: signed
@@ -102,8 +102,8 @@ void foo() {
   // CHECK-CC2-NEXT: COMPLETION: Pattern : typeof(<#type#>)
   // CHECK-CC2-NEXT: COMPLETION: union
   // CHECK-CC2-NEXT: COMPLETION: unsigned
-  // CHECK-CC2-NEXT: COMPLETION: Pattern : using namespace <#identifier#>
-  // CHECK-CC2-NEXT: COMPLETION: Pattern : using <#qualifier#>::<#name#>
+  // CHECK-CC2-NEXT: COMPLETION: Pattern : using namespace <#identifier#>;
+  // CHECK-CC2-NEXT: COMPLETION: Pattern : using <#qualifier#>::<#name#>;
   // CHECK-CC2-NEXT: COMPLETION: void
   // CHECK-CC2-NEXT: COMPLETION: volatile
   // CHECK-CC2-NEXT: COMPLETION: wchar_t
@@ -218,7 +218,7 @@ void foo() {
   // CHECK-NO-RTTI-NEXT: COMPLETION: float
   // CHECK-NO-RTTI-NEXT: COMPLETION: foo : [#void#]foo()
   // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : for(<#init-statement#>;<#condition#>;<#inc-expression#>){
-  // CHECK-NO-RTTI: COMPLETION: Pattern : goto <#label#>
+  // CHECK-NO-RTTI: COMPLETION: Pattern : goto <#label#>;
   // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : if(<#condition#>){<#statements#>
   // CHECK-NO-RTTI: COMPLETION: int
   // CHECK-NO-RTTI-NEXT: COMPLETION: long
@@ -228,7 +228,7 @@ void foo() {
   // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : [#std::nullptr_t#]nullptr
   // CHECK-NO-RTTI-NEXT: COMPLETION: operator
   // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : reinterpret_cast<<#type#>>(<#expression#>)
-  // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : return
+  // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : return;
   // CHECK-NO-RTTI-NEXT: COMPLETION: short
   // CHECK-NO-RTTI-NEXT: COMPLETION: signed
   // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : [#size_t#]sizeof(<#expression-or-type#>)
@@ -250,7 +250,7 @@ void foo() {
   // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : typeof(<#type#>)
   // CHECK-NO-RTTI-NEXT: COMPLETION: union
   // CHECK-NO-RTTI-NEXT: COMPLETION: unsigned
-  // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : using namespace <#identifier#>
+  // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : using namespace <#identifier#>;
   // CHECK-NO-RTTI-NEXT: COMPLETION: void
   // CHECK-NO-RTTI-NEXT: COMPLETION: volatile
   // CHECK-NO-RTTI-NEXT: COMPLETION: wchar_t
index ba613bc..90f9a6f 100644 (file)
@@ -21,7 +21,7 @@ void foo() {
   // CHECK-CC1-NEXT: COMPLETION: float
   // CHECK-CC1-NEXT: COMPLETION: foo : [#void#]foo()
   // CHECK-CC1-NEXT: COMPLETION: Pattern : for(<#init-statement#>;<#condition#>;<#inc-expression#>){
-  // CHECK-CC1: COMPLETION: Pattern : goto <#label#>
+  // CHECK-CC1: COMPLETION: Pattern : goto <#label#>;
   // CHECK-CC1-NEXT: COMPLETION: Pattern : if(<#condition#>){<#statements#>
   // CHECK-CC1: COMPLETION: int
   // CHECK-CC1-NEXT: COMPLETION: long
@@ -29,7 +29,7 @@ void foo() {
   // CHECK-CC1-NEXT: COMPLETION: Pattern : new <#type#>[<#size#>](<#expressions#>)
   // CHECK-CC1-NEXT: COMPLETION: operator
   // CHECK-CC1-NEXT: COMPLETION: Pattern : reinterpret_cast<<#type#>>(<#expression#>)
-  // CHECK-CC1-NEXT: COMPLETION: Pattern : return
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : return;
   // CHECK-CC1-NEXT: COMPLETION: short
   // CHECK-CC1-NEXT: COMPLETION: signed
   // CHECK-CC1-NEXT: COMPLETION: Pattern : [#size_t#]sizeof(<#expression-or-type#>)
@@ -49,7 +49,7 @@ void foo() {
   // CHECK-CC1-NEXT: COMPLETION: Pattern : typeof(<#type#>)
   // CHECK-CC1-NEXT: COMPLETION: union
   // CHECK-CC1-NEXT: COMPLETION: unsigned
-  // CHECK-CC1-NEXT: COMPLETION: Pattern : using namespace <#identifier#>
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : using namespace <#identifier#>;
   // CHECK-CC1-NEXT: COMPLETION: void
   // CHECK-CC1-NEXT: COMPLETION: volatile
   // CHECK-CC1-NEXT: COMPLETION: wchar_t
@@ -72,7 +72,7 @@ void foo() {
   // CHECK-CC2-NEXT: COMPLETION: int
   // CHECK-CC2-NEXT: COMPLETION: long
   // CHECK-CC2-NEXT: COMPLETION: Pattern : namespace <#identifier#>{<#declarations#>
-  // CHECK-CC2: COMPLETION: Pattern : namespace <#name#> = <#namespace#>
+  // CHECK-CC2: COMPLETION: Pattern : namespace <#name#> = <#namespace#>;
   // CHECK-CC2-NEXT: COMPLETION: operator
   // CHECK-CC2-NEXT: COMPLETION: short
   // CHECK-CC2-NEXT: COMPLETION: signed
@@ -88,8 +88,8 @@ void foo() {
   // CHECK-CC2-NEXT: COMPLETION: Pattern : typeof(<#type#>)
   // CHECK-CC2-NEXT: COMPLETION: union
   // CHECK-CC2-NEXT: COMPLETION: unsigned
-  // CHECK-CC2-NEXT: COMPLETION: Pattern : using namespace <#identifier#>
-  // CHECK-CC2-NEXT: COMPLETION: Pattern : using <#qualifier#>::<#name#>
+  // CHECK-CC2-NEXT: COMPLETION: Pattern : using namespace <#identifier#>;
+  // CHECK-CC2-NEXT: COMPLETION: Pattern : using <#qualifier#>::<#name#>;
   // CHECK-CC2-NEXT: COMPLETION: void
   // CHECK-CC2-NEXT: COMPLETION: volatile
   // CHECK-CC2-NEXT: COMPLETION: wchar_t
@@ -125,7 +125,7 @@ void foo() {
   // CHECK-CC3-NEXT: COMPLETION: Pattern : typeof(<#type#>)
   // CHECK-CC3-NEXT: COMPLETION: union
   // CHECK-CC3-NEXT: COMPLETION: unsigned
-  // CHECK-CC3-NEXT: COMPLETION: Pattern : using <#qualifier#>::<#name#>
+  // CHECK-CC3-NEXT: COMPLETION: Pattern : using <#qualifier#>::<#name#>;
   // CHECK-CC3-NEXT: COMPLETION: virtual
   // CHECK-CC3-NEXT: COMPLETION: void
   // CHECK-CC3-NEXT: COMPLETION: volatile
@@ -190,7 +190,7 @@ void foo() {
   // CHECK-NO-RTTI-NEXT: COMPLETION: float
   // CHECK-NO-RTTI-NEXT: COMPLETION: foo : [#void#]foo()
   // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : for(<#init-statement#>;<#condition#>;<#inc-expression#>){
-  // CHECK-NO-RTTI: COMPLETION: Pattern : goto <#label#>
+  // CHECK-NO-RTTI: COMPLETION: Pattern : goto <#label#>;
   // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : if(<#condition#>){<#statements#>
   // CHECK-NO-RTTI: COMPLETION: int
   // CHECK-NO-RTTI-NEXT: COMPLETION: long
@@ -198,7 +198,7 @@ void foo() {
   // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : new <#type#>[<#size#>](<#expressions#>)
   // CHECK-NO-RTTI-NEXT: COMPLETION: operator
   // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : reinterpret_cast<<#type#>>(<#expression#>)
-  // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : return
+  // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : return;
   // CHECK-NO-RTTI-NEXT: COMPLETION: short
   // CHECK-NO-RTTI-NEXT: COMPLETION: signed
   // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : [#size_t#]sizeof(<#expression-or-type#>)
@@ -218,7 +218,7 @@ void foo() {
   // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : typeof(<#type#>)
   // CHECK-NO-RTTI-NEXT: COMPLETION: union
   // CHECK-NO-RTTI-NEXT: COMPLETION: unsigned
-  // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : using namespace <#identifier#>
+  // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : using namespace <#identifier#>;
   // CHECK-NO-RTTI-NEXT: COMPLETION: void
   // CHECK-NO-RTTI-NEXT: COMPLETION: volatile
   // CHECK-NO-RTTI-NEXT: COMPLETION: wchar_t
diff --git a/clang/test/CodeCompletion/patterns.cpp b/clang/test/CodeCompletion/patterns.cpp
new file mode 100644 (file)
index 0000000..1958529
--- /dev/null
@@ -0,0 +1,39 @@
+void loops() {
+  while (true) {
+    // line 3
+  }
+  for (;;) {
+    // line 6
+  }
+  do {
+    // line 9
+  } while (true);
+  // line 11
+}
+// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:3:1 %s -o - | FileCheck -check-prefix=LOOP %s
+// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:6:1 %s -o - | FileCheck -check-prefix=LOOP %s
+// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:9:1 %s -o - | FileCheck -check-prefix=LOOP %s
+// LOOP: COMPLETION: Pattern : break;{{$}}
+// LOOP: COMPLETION: Pattern : continue;{{$}}
+// LOOP: COMPLETION: Pattern : goto <#label#>;{{$}}
+// LOOP: COMPLETION: Pattern : return;{{$}}
+//
+// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:11:1 %s -o - | FileCheck -check-prefix=OUTSIDE-LOOP %s
+// OUTSIDE-LOOP-NOT: COMPLETION: Pattern : break;{{$}}
+// OUTSIDE-LOOP-NOT: COMPLETION: Pattern : continue;{{$}}
+// OUTSIDE-LOOP: COMPLETION: Pattern : goto <#label#>;{{$}}
+// OUTSIDE-LOOP: COMPLETION: Pattern : return;{{$}}
+
+int value_return() {
+  // line 28
+}
+void void_return() {
+  // line 31
+}
+// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:28:1 %s -o - | FileCheck -check-prefix=RETURN-VAL %s
+// RETURN-VAL-NOT: COMPLETION: Pattern : return;{{$}}
+// RETURN-VAL: COMPLETION: Pattern : return <#expression#>;{{$}}
+
+// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:31:1 %s -o - | FileCheck -check-prefix=RETURN-VOID %s
+// RETURN-VOID-NOT: COMPLETION: Pattern : return <#expression#>;{{$}}
+// RETURN-VOID: COMPLETION: Pattern : return;{{$}}