[cfe-commits] r111093 - in /cfe/trunk: include/clang/Driver/CC1Options.td include/clang/Frontend/CompilerInstance.h include/clang/Frontend/FrontendOptions.h include/clang/Sema/CodeCompleteConsumer.h include/clang/Sema/Sema.h lib/Frontend/ASTUnit.cpp lib/Frontend/CompilerInstance.cpp lib/Frontend/CompilerInvocation.cpp lib/Sema/SemaCodeComplete.cpp lib/Sema/SemaLookup.cpp test/Index/complete-exprs.c tools/libclang/CIndexCodeCompletion.cpp

Douglas Gregor dgregor at apple.com
Sat Aug 14 23:18:01 PDT 2010


Author: dgregor
Date: Sun Aug 15 01:18:01 2010
New Revision: 111093

URL: http://llvm.org/viewvc/llvm-project?rev=111093&view=rev
Log:
Extend the code-completion caching infrastructure to include global
declarations (in addition to macros). Each kind of declaration maps to
a certain set of completion contexts, and the ASTUnit completion logic
introduces the completion strings for those declarations if the actual
code-completion occurs in one of the contexts where it matters. 

There are a few new code-completion-context kinds. Without these,
certain completions (e.g., after "using namespace") would need to
suppress all global completions, which would be unfortunate.

Note that we don't get the priorities right for global completions,
because we don't have enough type information. We'll need a way to
compare types in an ASTContext-agnostic way before this can be
implemented.


Modified:
    cfe/trunk/include/clang/Driver/CC1Options.td
    cfe/trunk/include/clang/Frontend/CompilerInstance.h
    cfe/trunk/include/clang/Frontend/FrontendOptions.h
    cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Frontend/ASTUnit.cpp
    cfe/trunk/lib/Frontend/CompilerInstance.cpp
    cfe/trunk/lib/Frontend/CompilerInvocation.cpp
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp
    cfe/trunk/lib/Sema/SemaLookup.cpp
    cfe/trunk/test/Index/complete-exprs.c
    cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp

Modified: cfe/trunk/include/clang/Driver/CC1Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=111093&r1=111092&r2=111093&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)
+++ cfe/trunk/include/clang/Driver/CC1Options.td Sun Aug 15 01:18:01 2010
@@ -264,6 +264,8 @@
   HelpText<"Include macros in code-completion results">;
 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 disable_free : Flag<"-disable-free">,
   HelpText<"Disable freeing of memory on exit">;
 def help : Flag<"-help">,

Modified: cfe/trunk/include/clang/Frontend/CompilerInstance.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CompilerInstance.h?rev=111093&r1=111092&r2=111093&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/CompilerInstance.h (original)
+++ cfe/trunk/include/clang/Frontend/CompilerInstance.h Sun Aug 15 01:18:01 2010
@@ -544,7 +544,8 @@
   createCodeCompletionConsumer(Preprocessor &PP, const std::string &Filename,
                                unsigned Line, unsigned Column,
                                bool UseDebugPrinter, bool ShowMacros,
-                               bool ShowCodePatterns, llvm::raw_ostream &OS);
+                               bool ShowCodePatterns, bool ShowGlobals,
+                               llvm::raw_ostream &OS);
 
   /// \brief Create the Sema object to be used for parsing.
   void createSema(bool CompleteTranslationUnit,

Modified: cfe/trunk/include/clang/Frontend/FrontendOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/FrontendOptions.h?rev=111093&r1=111092&r2=111093&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/FrontendOptions.h (original)
+++ cfe/trunk/include/clang/Frontend/FrontendOptions.h Sun Aug 15 01:18:01 2010
@@ -69,6 +69,8 @@
                                            /// results.
   unsigned ShowCodePatternsInCodeCompletion : 1; ///< Show code patterns in code
                                                  /// completion results.
+  unsigned ShowGlobalSymbolsInCodeCompletion : 1; ///< Show top-level decls in
+                                                  /// code completion results.
   unsigned ShowStats : 1;                  ///< Show frontend performance
                                            /// metrics and statistics.
   unsigned ShowTimers : 1;                 ///< Show timers for individual
@@ -122,6 +124,7 @@
     ShowHelp = 0;
     ShowMacrosInCodeCompletion = 0;
     ShowCodePatternsInCodeCompletion = 0;
+    ShowGlobalSymbolsInCodeCompletion = 1;
     ShowStats = 0;
     ShowTimers = 0;
     ShowVersion = 0;

Modified: cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h?rev=111093&r1=111092&r2=111093&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h (original)
+++ cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h Sun Aug 15 01:18:01 2010
@@ -127,7 +127,12 @@
     /// to indicate a struct or class name.
     CCC_ClassOrStructTag,
     /// \brief Code completion occurred where a protocol name is expected.
-    CCC_ObjCProtocolName
+    CCC_ObjCProtocolName,
+    /// \brief Code completion occurred where a namespace or namespace alias
+    /// is expected.
+    CCC_Namespace,
+    /// \brief Code completion occurred where a type name is expected.
+    CCC_Type
   };
 
 private:
@@ -382,6 +387,10 @@
   /// the completion results.
   bool IncludeCodePatterns;
   
+  /// \brief Whether to include global (top-level) declarations and names in
+  /// the completion results.
+  bool IncludeGlobals;
+  
   /// \brief Whether the output format for the code-completion consumer is
   /// binary.
   bool OutputIsBinary;
@@ -588,12 +597,12 @@
   };
   
   CodeCompleteConsumer() : IncludeMacros(false), IncludeCodePatterns(false),
-                           OutputIsBinary(false) { }
+                           IncludeGlobals(true), OutputIsBinary(false) { }
   
   CodeCompleteConsumer(bool IncludeMacros, bool IncludeCodePatterns,
-                       bool OutputIsBinary)
+                       bool IncludeGlobals, bool OutputIsBinary)
     : IncludeMacros(IncludeMacros), IncludeCodePatterns(IncludeCodePatterns),
-      OutputIsBinary(OutputIsBinary) { }
+      IncludeGlobals(IncludeGlobals), OutputIsBinary(OutputIsBinary) { }
   
   /// \brief Whether the code-completion consumer wants to see macros.
   bool includeMacros() const { return IncludeMacros; }
@@ -601,6 +610,9 @@
   /// \brief Whether the code-completion consumer wants to see code patterns.
   bool includeCodePatterns() const { return IncludeCodePatterns; }
   
+  /// \brief Whether to include global (top-level) declaration results.
+  bool includeGlobals() const { return IncludeGlobals; }
+  
   /// \brief Determine whether the output of this consumer is binary.
   bool isOutputBinary() const { return OutputIsBinary; }
   
@@ -639,8 +651,10 @@
   /// \brief Create a new printing code-completion consumer that prints its
   /// results to the given raw output stream.
   PrintingCodeCompleteConsumer(bool IncludeMacros, bool IncludeCodePatterns,
+                               bool IncludeGlobals,
                                llvm::raw_ostream &OS)
-    : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, false), OS(OS) {}
+    : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, IncludeGlobals,
+                           false), OS(OS) {}
   
   /// \brief Prints the finalized code-completion results.
   virtual void ProcessCodeCompleteResults(Sema &S, 
@@ -664,8 +678,9 @@
   /// results to the given raw output stream in a format readable to the CIndex
   /// library.
   CIndexCodeCompleteConsumer(bool IncludeMacros, bool IncludeCodePatterns,
-                             llvm::raw_ostream &OS)
-    : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, true), OS(OS) {}
+                             bool IncludeGlobals, llvm::raw_ostream &OS)
+    : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, IncludeGlobals,
+                           true), OS(OS) {}
   
   /// \brief Prints the finalized code-completion results.
   virtual void ProcessCodeCompleteResults(Sema &S, 

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=111093&r1=111092&r2=111093&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Sun Aug 15 01:18:01 2010
@@ -1486,7 +1486,9 @@
     /// C99 6.2.2p4-5 and C++ [basic.link]p6.
     LookupRedeclarationWithLinkage,
     /// Look up the name of an Objective-C protocol.
-    LookupObjCProtocolName
+    LookupObjCProtocolName,
+    /// \brief Look up any declaration with any name.
+    LookupAnyName
   };
 
   /// \brief Specifies whether (or how) name lookup is being performed for a
@@ -1534,9 +1536,11 @@
                                ADLResult &Functions);
 
   void LookupVisibleDecls(Scope *S, LookupNameKind Kind,
-                          VisibleDeclConsumer &Consumer);
+                          VisibleDeclConsumer &Consumer,
+                          bool IncludeGlobalScope = true);
   void LookupVisibleDecls(DeclContext *Ctx, LookupNameKind Kind,
-                          VisibleDeclConsumer &Consumer);
+                          VisibleDeclConsumer &Consumer,
+                          bool IncludeGlobalScope = true);
   
   /// \brief The context in which typo-correction occurs.
   ///

Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=111093&r1=111092&r2=111093&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Sun Aug 15 01:18:01 2010
@@ -88,6 +88,79 @@
   TemporaryFiles.clear();
 }
 
+/// \brief Determine the set of code-completion contexts in which this 
+/// declaration should be shown.
+static unsigned getDeclShowContexts(NamedDecl *ND,
+                                    const LangOptions &LangOpts) {
+  if (isa<UsingShadowDecl>(ND))
+    ND = dyn_cast<NamedDecl>(ND->getUnderlyingDecl());
+  if (!ND)
+    return 0;
+  
+  unsigned Contexts = 0;
+  if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND) || 
+      isa<ClassTemplateDecl>(ND) || isa<TemplateTemplateParmDecl>(ND)) {
+    // Types can appear in these contexts.
+    if (LangOpts.CPlusPlus || !isa<TagDecl>(ND))
+      Contexts |= (1 << (CodeCompletionContext::CCC_TopLevel - 1))
+                | (1 << (CodeCompletionContext::CCC_ObjCIvarList - 1))
+                | (1 << (CodeCompletionContext::CCC_ClassStructUnion - 1))
+                | (1 << (CodeCompletionContext::CCC_Statement - 1))
+                | (1 << (CodeCompletionContext::CCC_Type - 1));
+
+    // In C++, types can appear in expressions contexts (for functional casts).
+    if (LangOpts.CPlusPlus)
+      Contexts |= (1 << (CodeCompletionContext::CCC_Expression - 1));
+    
+    // In Objective-C, message sends can send interfaces. In Objective-C++,
+    // all types are available due to functional casts.
+    if (LangOpts.CPlusPlus || isa<ObjCInterfaceDecl>(ND))
+      Contexts |= (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1));
+
+    // Deal with tag names.
+    if (isa<EnumDecl>(ND)) {
+      Contexts |= (1 << (CodeCompletionContext::CCC_EnumTag - 1));
+      
+      // Part of the nested-name-specifier.
+      if (LangOpts.CPlusPlus0x)
+        Contexts |= (1 << (CodeCompletionContext::CCC_MemberAccess - 1));
+    } else if (RecordDecl *Record = dyn_cast<RecordDecl>(ND)) {
+      if (Record->isUnion())
+        Contexts |= (1 << (CodeCompletionContext::CCC_UnionTag - 1));
+      else
+        Contexts |= (1 << (CodeCompletionContext::CCC_ClassOrStructTag - 1));
+      
+      // Part of the nested-name-specifier.
+      if (LangOpts.CPlusPlus)
+        Contexts |= (1 << (CodeCompletionContext::CCC_MemberAccess - 1));
+    }
+  } else if (isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND)) {
+    // Values can appear in these contexts.
+    Contexts = (1 << (CodeCompletionContext::CCC_Statement - 1))
+             | (1 << (CodeCompletionContext::CCC_Expression - 1))
+             | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1));
+  } else if (isa<ObjCProtocolDecl>(ND)) {
+    Contexts = (1 << (CodeCompletionContext::CCC_ObjCProtocolName - 1));
+  } else if (isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) {
+    Contexts = (1 << (CodeCompletionContext::CCC_TopLevel - 1))
+             | (1 << (CodeCompletionContext::CCC_ObjCIvarList - 1))
+             | (1 << (CodeCompletionContext::CCC_ClassStructUnion - 1))
+             | (1 << (CodeCompletionContext::CCC_Statement - 1))
+             | (1 << (CodeCompletionContext::CCC_Expression - 1))
+             | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1))
+             | (1 << (CodeCompletionContext::CCC_Namespace - 1));
+   
+    // Part of the nested-name-specifier.
+    Contexts |= (1 << (CodeCompletionContext::CCC_MemberAccess - 1))
+             | (1 << (CodeCompletionContext::CCC_EnumTag - 1))
+             | (1 << (CodeCompletionContext::CCC_UnionTag - 1))
+             | (1 << (CodeCompletionContext::CCC_ClassOrStructTag - 1))
+             | (1 << (CodeCompletionContext::CCC_Type - 1));
+  }
+  
+  return Contexts;
+}
+
 void ASTUnit::CacheCodeCompletionResults() {
   if (!TheSema)
     return;
@@ -111,10 +184,17 @@
   // Translate global code completions into cached completions.
   for (unsigned I = 0, N = Results.size(); I != N; ++I) {
     switch (Results[I].Kind) {
-    case Result::RK_Declaration:
-      // FIXME: Handle declarations!
+    case Result::RK_Declaration: {
+      CachedCodeCompletionResult CachedResult;
+      CachedResult.Completion = Results[I].CreateCodeCompletionString(*TheSema);
+      CachedResult.ShowInContexts = getDeclShowContexts(Results[I].Declaration,
+                                                        Ctx->getLangOptions());
+      CachedResult.Priority = Results[I].Priority;
+      CachedResult.Kind = Results[I].CursorKind;
+      CachedCompletionResults.push_back(CachedResult);
       break;
-      
+    }
+        
     case Result::RK_Keyword:
     case Result::RK_Pattern:
       // Ignore keywords and patterns; we don't care, since they are so
@@ -1287,8 +1367,9 @@
     
   public:
     AugmentedCodeCompleteConsumer(ASTUnit &AST, CodeCompleteConsumer &Next,
-                                  bool IncludeMacros, bool IncludeCodePatterns)
-      : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns,
+                                  bool IncludeMacros, bool IncludeCodePatterns,
+                                  bool IncludeGlobals)
+      : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, IncludeGlobals,
                              Next.isOutputBinary()), AST(AST), Next(Next) 
     { 
       // Compute the set of contexts in which we will look when we don't have
@@ -1387,6 +1468,8 @@
   FrontendOpts.ShowMacrosInCodeCompletion
     = IncludeMacros && CachedCompletionResults.empty();
   FrontendOpts.ShowCodePatternsInCodeCompletion = IncludeCodePatterns;
+  FrontendOpts.ShowGlobalSymbolsInCodeCompletion
+    = CachedCompletionResults.empty();
   FrontendOpts.CodeCompletionAt.FileName = File;
   FrontendOpts.CodeCompletionAt.Line = Line;
   FrontendOpts.CodeCompletionAt.Column = Column;
@@ -1447,7 +1530,8 @@
   // code-completion results.
   AugmentedCodeCompleteConsumer 
   AugmentedConsumer(*this, Consumer, FrontendOpts.ShowMacrosInCodeCompletion,
-                    FrontendOpts.ShowCodePatternsInCodeCompletion);
+                    FrontendOpts.ShowCodePatternsInCodeCompletion,
+                    FrontendOpts.ShowGlobalSymbolsInCodeCompletion);
   Clang.setCodeCompletionConsumer(&AugmentedConsumer);
 
   // If we have a precompiled preamble, try to use it. We only allow

Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=111093&r1=111092&r2=111093&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Sun Aug 15 01:18:01 2010
@@ -328,6 +328,7 @@
                                    getFrontendOpts().DebugCodeCompletionPrinter,
                                    getFrontendOpts().ShowMacrosInCodeCompletion,
                              getFrontendOpts().ShowCodePatternsInCodeCompletion,
+                           getFrontendOpts().ShowGlobalSymbolsInCodeCompletion,
                                    llvm::outs()));
     if (!CompletionConsumer)
       return;
@@ -356,15 +357,18 @@
                                                bool UseDebugPrinter,
                                                bool ShowMacros,
                                                bool ShowCodePatterns,
+                                               bool ShowGlobals,
                                                llvm::raw_ostream &OS) {
   if (EnableCodeCompletion(PP, Filename, Line, Column))
     return 0;
 
   // Set up the creation routine for code-completion.
   if (UseDebugPrinter)
-    return new PrintingCodeCompleteConsumer(ShowMacros, ShowCodePatterns, OS);
+    return new PrintingCodeCompleteConsumer(ShowMacros, ShowCodePatterns, 
+                                            ShowGlobals, OS);
   else
-    return new CIndexCodeCompleteConsumer(ShowMacros, ShowCodePatterns, OS);
+    return new CIndexCodeCompleteConsumer(ShowMacros, ShowCodePatterns, 
+                                          ShowGlobals, OS);
 }
 
 void CompilerInstance::createSema(bool CompleteTranslationUnit,

Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=111093&r1=111092&r2=111093&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Sun Aug 15 01:18:01 2010
@@ -363,6 +363,8 @@
     Res.push_back("-code-completion-macros");
   if (Opts.ShowCodePatternsInCodeCompletion)
     Res.push_back("-code-completion-patterns");
+  if (!Opts.ShowGlobalSymbolsInCodeCompletion)
+    Res.push_back("-no-code-completion-globals");
   if (Opts.ShowStats)
     Res.push_back("-print-stats");
   if (Opts.ShowTimers)
@@ -1047,6 +1049,8 @@
   Opts.ShowMacrosInCodeCompletion = Args.hasArg(OPT_code_completion_macros);
   Opts.ShowCodePatternsInCodeCompletion
     = Args.hasArg(OPT_code_completion_patterns);
+  Opts.ShowGlobalSymbolsInCodeCompletion
+    = !Args.hasArg(OPT_no_code_completion_globals);
   Opts.ShowStats = Args.hasArg(OPT_print_stats);
   Opts.ShowTimers = Args.hasArg(OPT_ftime_report);
   Opts.ShowVersion = Args.hasArg(OPT_version);

Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=111093&r1=111092&r2=111093&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Sun Aug 15 01:18:01 2010
@@ -2308,7 +2308,8 @@
   }
 
   CodeCompletionDeclConsumer Consumer(Results, CurContext);
-  LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+                     CodeCompleter->includeGlobals());
 
   Results.EnterNewScope();
   AddOrdinaryNameResults(CompletionContext, S, *this, Results);
@@ -2340,7 +2341,8 @@
   Results.setPreferredType(T.getNonReferenceType());
   
   CodeCompletionDeclConsumer Consumer(Results, CurContext);
-  LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+                     CodeCompleter->includeGlobals());
   
   Results.EnterNewScope();
   AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
@@ -2432,7 +2434,8 @@
     // Access to a C/C++ class, struct, or union.
     Results.allowNestedNameSpecifiers();
     CodeCompletionDeclConsumer Consumer(Results, CurContext);
-    LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer);
+    LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
+                       CodeCompleter->includeGlobals());
 
     if (getLangOptions().CPlusPlus) {
       if (!Results.empty()) {
@@ -2480,7 +2483,8 @@
     if (Class) {
       CodeCompletionDeclConsumer Consumer(Results, CurContext);
       Results.setFilter(&ResultBuilder::IsObjCIvar);
-      LookupVisibleDecls(Class, LookupMemberName, Consumer);
+      LookupVisibleDecls(Class, LookupMemberName, Consumer,
+                         CodeCompleter->includeGlobals());
     }
   }
   
@@ -2530,11 +2534,14 @@
 
   // First pass: look for tags.
   Results.setFilter(Filter);
-  LookupVisibleDecls(S, LookupTagName, Consumer);
+  LookupVisibleDecls(S, LookupTagName, Consumer,
+                     CodeCompleter->includeGlobals());
 
-  // Second pass: look for nested name specifiers.
-  Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
-  LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
+  if (CodeCompleter->includeGlobals()) {
+    // Second pass: look for nested name specifiers.
+    Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
+    LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
+  }
   
   HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
                             Results.data(),Results.size());
@@ -2836,7 +2843,8 @@
   // After "using", we can see anything that would start a 
   // nested-name-specifier.
   CodeCompletionDeclConsumer Consumer(Results, CurContext);
-  LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+                     CodeCompleter->includeGlobals());
   Results.ExitScope();
   
   HandleCodeCompleteResults(this, CodeCompleter, 
@@ -2853,10 +2861,11 @@
   ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
   Results.EnterNewScope();
   CodeCompletionDeclConsumer Consumer(Results, CurContext);
-  LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+                     CodeCompleter->includeGlobals());
   Results.ExitScope();
   HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_Other,
+                            CodeCompletionContext::CCC_Namespace,
                             Results.data(),Results.size());
 }
 
@@ -2903,9 +2912,10 @@
   // After "namespace", we expect to see a namespace or alias.
   ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
   CodeCompletionDeclConsumer Consumer(Results, CurContext);
-  LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+                     CodeCompleter->includeGlobals());
   HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_Other,
+                            CodeCompletionContext::CCC_Namespace,
                             Results.data(),Results.size());
 }
 
@@ -2926,14 +2936,15 @@
   // Add any type names visible from the current scope
   Results.allowNestedNameSpecifiers();
   CodeCompletionDeclConsumer Consumer(Results, CurContext);
-  LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+                     CodeCompleter->includeGlobals());
   
   // Add any type specifiers
   AddTypeSpecifierResults(getLangOptions(), Results);
   Results.ExitScope();
   
   HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_Other,
+                            CodeCompletionContext::CCC_Type,
                             Results.data(),Results.size());
 }
 
@@ -3514,7 +3525,8 @@
   Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
   CodeCompletionDeclConsumer Consumer(Results, CurContext);
   Results.EnterNewScope();
-  LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+                     CodeCompleter->includeGlobals());
   
   // If we are in an Objective-C method inside a class that has a superclass,
   // add "super" as an option.
@@ -4341,13 +4353,12 @@
                  llvm::SmallVectorImpl<CodeCompleteConsumer::Result> &Results) {
   ResultBuilder Builder(*this);
 
-#if 0
-  // FIXME: We need a name lookup that means "look for everything", 
-  CodeCompletionDeclConsumer Consumer(Builder, 
-                                      Context.getTranslationUnitDecl());
-  LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupOrdinaryName, 
-                     Consumer);
-#endif
+  if (!CodeCompleter || CodeCompleter->includeGlobals()) {
+    CodeCompletionDeclConsumer Consumer(Builder, 
+                                        Context.getTranslationUnitDecl());
+    LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName, 
+                       Consumer);
+  }
   
   if (!CodeCompleter || CodeCompleter->includeMacros())
     AddMacroResults(PP, Builder);

Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=111093&r1=111092&r2=111093&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Sun Aug 15 01:18:01 2010
@@ -254,6 +254,12 @@
   case Sema::LookupObjCProtocolName:
     IDNS = Decl::IDNS_ObjCProtocol;
     break;
+      
+  case Sema::LookupAnyName:
+    IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Member 
+      | Decl::IDNS_Using | Decl::IDNS_Namespace | Decl::IDNS_ObjCProtocol
+      | Decl::IDNS_Type;
+    break;
   }
   return IDNS;
 }
@@ -1199,6 +1205,17 @@
   return Found;
 }
 
+/// \brief Callback that looks for any member of a class with the given name.
+static bool LookupAnyMember(const CXXBaseSpecifier *Specifier, 
+                            CXXBasePath &Path,
+                            void *Name) {
+  RecordDecl *BaseRecord = Specifier->getType()->getAs<RecordType>()->getDecl();
+  
+  DeclarationName N = DeclarationName::getFromOpaquePtr(Name);
+  Path.Decls = BaseRecord->lookup(N);
+  return Path.Decls.first != Path.Decls.second;
+}
+
 /// \brief Perform qualified name lookup into a given context.
 ///
 /// Qualified name lookup (C++ [basic.lookup.qual]) is used to find
@@ -1294,6 +1311,10 @@
       BaseCallback = &CXXRecordDecl::FindTagMember;
       break;
 
+    case LookupAnyName:
+      BaseCallback = &LookupAnyMember;
+      break;
+      
     case LookupUsingDeclName:
       // This lookup is for redeclarations only.
       
@@ -2223,6 +2244,10 @@
     return !VisitedContexts.insert(Ctx);
   }
 
+  bool alreadyVisitedContext(DeclContext *Ctx) {
+    return VisitedContexts.count(Ctx);
+  }
+
   /// \brief Determine whether the given declaration is hidden in the
   /// current scope.
   ///
@@ -2503,7 +2528,9 @@
   if (!S)
     return;
 
-  if (!S->getEntity() || !S->getParent() ||
+  if (!S->getEntity() || 
+      (!S->getParent() && 
+       !Visited.alreadyVisitedContext((DeclContext *)S->getEntity())) ||
       ((DeclContext *)S->getEntity())->isFunctionOrMethod()) {
     // Walk through the declarations in this Scope.
     for (Scope::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
@@ -2581,7 +2608,8 @@
 }
 
 void Sema::LookupVisibleDecls(Scope *S, LookupNameKind Kind,
-                              VisibleDeclConsumer &Consumer) {
+                              VisibleDeclConsumer &Consumer,
+                              bool IncludeGlobalScope) {
   // Determine the set of using directives available during
   // unqualified name lookup.
   Scope *Initial = S;
@@ -2598,14 +2626,19 @@
   // Look for visible declarations.
   LookupResult Result(*this, DeclarationName(), SourceLocation(), Kind);
   VisibleDeclsRecord Visited;
+  if (!IncludeGlobalScope)
+    Visited.visitedContext(Context.getTranslationUnitDecl());
   ShadowContextRAII Shadow(Visited);
   ::LookupVisibleDecls(Initial, Result, UDirs, Consumer, Visited);
 }
 
 void Sema::LookupVisibleDecls(DeclContext *Ctx, LookupNameKind Kind,
-                              VisibleDeclConsumer &Consumer) {
+                              VisibleDeclConsumer &Consumer,
+                              bool IncludeGlobalScope) {
   LookupResult Result(*this, DeclarationName(), SourceLocation(), Kind);
   VisibleDeclsRecord Visited;
+  if (!IncludeGlobalScope)
+    Visited.visitedContext(Context.getTranslationUnitDecl());
   ShadowContextRAII Shadow(Visited);
   ::LookupVisibleDecls(Ctx, Result, /*QualifiedNameLookup=*/true, 
                        /*InBaseClass=*/false, Consumer, Visited);

Modified: cfe/trunk/test/Index/complete-exprs.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-exprs.c?rev=111093&r1=111092&r2=111093&view=diff
==============================================================================
--- cfe/trunk/test/Index/complete-exprs.c (original)
+++ cfe/trunk/test/Index/complete-exprs.c Sun Aug 15 01:18:01 2010
@@ -19,6 +19,12 @@
 // CHECK-CC1-NOT: NotImplemented:{TypedText float} (40)
 // CHECK-CC1: ParmDecl:{ResultType int}{TypedText j} (2)
 // CHECK-CC1: NotImplemented:{TypedText sizeof}{LeftParen (}{Placeholder expression-or-type}{RightParen )} (30)
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:7:9 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC1a %s
+// FIXME: Priorities aren't right
+// CHECK-CC1a: ParmDecl:{ResultType int}{TypedText j} (2)
+// CHECK-CC1a: NotImplemented:{TypedText sizeof}{LeftParen (}{Placeholder expression-or-type}{RightParen )} (30)
+// CHECK-CC1a: FunctionDecl:{ResultType int}{TypedText f}{LeftParen (}{Placeholder int}{RightParen )} (50)
+// CHECK-CC1a: macro definition:{TypedText __VERSION__} (70)
 // RUN: c-index-test -code-completion-at=%s:7:14 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC3 %s
 // RUN: env CINDEXTEST_EDITING=1 c-index-test -code-completion-at=%s:7:14 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC3 %s
 // CHECK-CC3: macro definition:{TypedText __VERSION__} (70)

Modified: cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp?rev=111093&r1=111092&r2=111093&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp (original)
+++ cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp Sun Aug 15 01:18:01 2010
@@ -547,7 +547,8 @@
 
   public:
     explicit CaptureCompletionResults(AllocatedCXCodeCompleteResults &Results)
-      : CodeCompleteConsumer(true, false, false), AllocatedResults(Results) { }
+      : CodeCompleteConsumer(true, false, true, false), 
+        AllocatedResults(Results) { }
 
     virtual void ProcessCodeCompleteResults(Sema &S, 
                                             CodeCompletionContext Context,





More information about the cfe-commits mailing list