]> granicus.if.org Git - clang/commitdiff
[Sema] Ignore decls in namespaces when global decls are not wanted.
authorEric Liu <ioeric@google.com>
Wed, 13 Dec 2017 10:26:49 +0000 (10:26 +0000)
committerEric Liu <ioeric@google.com>
Wed, 13 Dec 2017 10:26:49 +0000 (10:26 +0000)
Summary: ... in qualified code completion and decl lookup.

Reviewers: ilya-biryukov, arphaman

Reviewed By: ilya-biryukov

Subscribers: cfe-commits

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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@320563 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Driver/CC1Options.td
include/clang/Sema/CodeCompleteConsumer.h
include/clang/Sema/CodeCompleteOptions.h
lib/Frontend/CompilerInvocation.cpp
lib/Sema/SemaCodeComplete.cpp
test/CodeCompletion/ignore-ns-level-decls.cpp [new file with mode: 0644]

index 4f980c202baaeb1a7518dba496cb2641fdc07108..c81fbfd9d5c4cbf1c8169fe64596886259f9144d 100644 (file)
@@ -437,6 +437,8 @@ def code_completion_patterns : Flag<["-"], "code-completion-patterns">,
   HelpText<"Include code patterns in code-completion results">;
 def no_code_completion_globals : Flag<["-"], "no-code-completion-globals">,
   HelpText<"Do not include global declarations in code-completion results.">;
+def no_code_completion_ns_level_decls : Flag<["-"], "no-code-completion-ns-level-decls">,
+  HelpText<"Do not include declarations inside namespaces (incl. global namespace) in the code-completion results.">;
 def code_completion_brief_comments : Flag<["-"], "code-completion-brief-comments">,
   HelpText<"Include brief documentation comments in code-completion results.">;
 def disable_free : Flag<["-"], "disable-free">,
index fb09b99bbdfe723e072add94c6b1b04985d65cb4..5d280b5608e7150936f3424b5590c2d040af1866 100644 (file)
@@ -919,8 +919,13 @@ public:
   }
 
   /// \brief Whether to include global (top-level) declaration results.
-  bool includeGlobals() const {
-    return CodeCompleteOpts.IncludeGlobals;
+  bool includeGlobals() const { return CodeCompleteOpts.IncludeGlobals; }
+
+  /// \brief Whether to include declarations in namespace contexts (including
+  /// the global namespace). If this is false, `includeGlobals()` will be
+  /// ignored.
+  bool includeNamespaceLevelDecls() const {
+    return CodeCompleteOpts.IncludeNamespaceLevelDecls;
   }
 
   /// \brief Whether to include brief documentation comments within the set of
index fc7713c795712bbfb6086a58193bceff77a26987..091d8ca60505ef761d12e56270a5c44997d45fbd 100644 (file)
@@ -24,15 +24,20 @@ public:
   /// Show top-level decls in code completion results.
   unsigned IncludeGlobals : 1;
 
+  /// Show decls in namespace (including the global namespace) in code
+  /// completion results. If this is 0, `IncludeGlobals` will be ignored.
+  ///
+  /// Currently, this only works when completing qualified IDs (i.e.
+  /// `Sema::CodeCompleteQualifiedId`).
+  /// FIXME: consider supporting more completion cases with this option.
+  unsigned IncludeNamespaceLevelDecls : 1;
+
   /// Show brief documentation comments in code completion results.
   unsigned IncludeBriefComments : 1;
 
-  CodeCompleteOptions() :
-      IncludeMacros(0),
-      IncludeCodePatterns(0),
-      IncludeGlobals(1),
-      IncludeBriefComments(0)
-  { }
+  CodeCompleteOptions()
+      : IncludeMacros(0), IncludeCodePatterns(0), IncludeGlobals(1),
+        IncludeNamespaceLevelDecls(1), IncludeBriefComments(0) {}
 };
 
 } // namespace clang
index 3aa615b490fd959c76d766cde2c1d512f19d2de8..be907d9ba858fb354fae3f0c88a1ff10c75268ae 100644 (file)
@@ -1380,6 +1380,8 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
     = Args.hasArg(OPT_code_completion_patterns);
   Opts.CodeCompleteOpts.IncludeGlobals
     = !Args.hasArg(OPT_no_code_completion_globals);
+  Opts.CodeCompleteOpts.IncludeNamespaceLevelDecls
+    = !Args.hasArg(OPT_no_code_completion_ns_level_decls);
   Opts.CodeCompleteOpts.IncludeBriefComments
     = Args.hasArg(OPT_code_completion_brief_comments);
 
index 3dd3c9f59e4c4f10da5048b4f792d516a4fab5e2..ee11c5c94e04269daaebb4c33c2a704f14fd58b4 100644 (file)
@@ -4647,10 +4647,13 @@ void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
     MaybeAddOverrideCalls(*this, Ctx, Results);
   Results.ExitScope();
 
-  CodeCompletionDeclConsumer Consumer(Results, CurContext);
-  LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer,
-                     /*IncludeGlobalScope=*/true,
-                     /*IncludeDependentBases=*/true);
+  if (CodeCompleter->includeNamespaceLevelDecls() ||
+      (!Ctx->isNamespace() && !Ctx->isTranslationUnit())) {
+    CodeCompletionDeclConsumer Consumer(Results, CurContext);
+    LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer,
+                       /*IncludeGlobalScope=*/true,
+                       /*IncludeDependentBases=*/true);
+  }
 
   auto CC = Results.getCompletionContext();
   CC.setCXXScopeSpecifier(SS);
diff --git a/test/CodeCompletion/ignore-ns-level-decls.cpp b/test/CodeCompletion/ignore-ns-level-decls.cpp
new file mode 100644 (file)
index 0000000..59cee65
--- /dev/null
@@ -0,0 +1,21 @@
+namespace ns {
+  struct bar {
+  };
+
+  struct baz {
+  };
+
+  int func(int a, bar b, baz c);
+}
+
+void test() {
+  ns::
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:12:7 %s -o - | FileCheck %s --check-prefix=CHECK-1
+// CHECK-1-DAG: COMPLETION: bar : bar
+// CHECK-1-DAG: COMPLETION: baz : baz
+// CHECK-1-DAG: COMPLETION: func : [#int#]func(<#int a#>, <#bar b#>, <#baz c#>)
+
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:12:7 -no-code-completion-ns-level-decls %s -o - | FileCheck %s --allow-empty --check-prefix=CHECK-EMPTY
+// CHECK-EMPTY-NOT: COMPLETION: bar : bar
+// CHECK-EMPTY: {{^}}{{$}}
+}