Index: cfe/trunk/include/clang/Driver/CC1Options.td =================================================================== --- cfe/trunk/include/clang/Driver/CC1Options.td +++ cfe/trunk/include/clang/Driver/CC1Options.td @@ -437,6 +437,8 @@ 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: cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h =================================================================== --- cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h +++ cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h @@ -919,8 +919,13 @@ } /// \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: cfe/trunk/include/clang/Sema/CodeCompleteOptions.h =================================================================== --- cfe/trunk/include/clang/Sema/CodeCompleteOptions.h +++ cfe/trunk/include/clang/Sema/CodeCompleteOptions.h @@ -24,15 +24,20 @@ /// 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: cfe/trunk/lib/Frontend/CompilerInvocation.cpp =================================================================== --- cfe/trunk/lib/Frontend/CompilerInvocation.cpp +++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp @@ -1380,6 +1380,8 @@ = 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: cfe/trunk/lib/Sema/SemaCodeComplete.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaCodeComplete.cpp +++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp @@ -4647,10 +4647,13 @@ 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); Index: cfe/trunk/test/CodeCompletion/ignore-ns-level-decls.cpp =================================================================== --- cfe/trunk/test/CodeCompletion/ignore-ns-level-decls.cpp +++ cfe/trunk/test/CodeCompletion/ignore-ns-level-decls.cpp @@ -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: {{^}}{{$}} +}