[cfe-commits] r111943 - in /cfe/trunk: include/clang/Lex/CodeCompletionHandler.h include/clang/Lex/Preprocessor.h include/clang/Parse/Parser.h include/clang/Sema/Action.h include/clang/Sema/Sema.h lib/Lex/Lexer.cpp lib/Lex/PPDirectives.cpp lib/Lex/Preprocessor.cpp lib/Parse/Parser.cpp lib/Sema/SemaCodeComplete.cpp test/Index/complete-preprocessor.m

Douglas Gregor dgregor at apple.com
Tue Aug 24 12:08:16 PDT 2010


Author: dgregor
Date: Tue Aug 24 14:08:16 2010
New Revision: 111943

URL: http://llvm.org/viewvc/llvm-project?rev=111943&view=rev
Log:
Introduce basic code-completion support for preprocessor directives,
e.g., after a "#" we'll suggest #if, #ifdef, etc.

Added:
    cfe/trunk/include/clang/Lex/CodeCompletionHandler.h   (with props)
    cfe/trunk/test/Index/complete-preprocessor.m
Modified:
    cfe/trunk/include/clang/Lex/Preprocessor.h
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/include/clang/Sema/Action.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Lex/Lexer.cpp
    cfe/trunk/lib/Lex/PPDirectives.cpp
    cfe/trunk/lib/Lex/Preprocessor.cpp
    cfe/trunk/lib/Parse/Parser.cpp
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp

Added: cfe/trunk/include/clang/Lex/CodeCompletionHandler.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/CodeCompletionHandler.h?rev=111943&view=auto
==============================================================================
--- cfe/trunk/include/clang/Lex/CodeCompletionHandler.h (added)
+++ cfe/trunk/include/clang/Lex/CodeCompletionHandler.h Tue Aug 24 14:08:16 2010
@@ -0,0 +1,42 @@
+//===--- CodeCompletionHandler.h - Preprocessor code completion -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the CodeCompletionHandler interface, which provides
+//  code-completion callbacks for the preprocessor.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_LEX_CODECOMPLETIONHANDLER_H
+#define LLVM_CLANG_LEX_CODECOMPLETIONHANDLER_H
+
+namespace clang {
+
+/// \brief Callback handler that receives notifications when performing code 
+/// completion within the preprocessor.
+class CodeCompletionHandler {
+public:
+  virtual ~CodeCompletionHandler();
+  
+  /// \brief Callback invoked when performing code completion for a preprocessor
+  /// directive.
+  ///
+  /// This callback will be invoked when the preprocessor processes a '#' at the
+  /// start of a line, followed by the code-completion token.
+  ///
+  /// \param InConditional Whether we're inside a preprocessor conditional
+  /// already.
+  virtual void CodeCompleteDirective(bool InConditional) { }
+  
+  /// \brief Callback invoked when performing code completion within a block of
+  /// code that was excluded due to preprocessor conditionals.
+  virtual void CodeCompleteInConditionalExclusion() { }
+};
+  
+}
+
+#endif // LLVM_CLANG_LEX_CODECOMPLETIONHANDLER_H

Propchange: cfe/trunk/include/clang/Lex/CodeCompletionHandler.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/include/clang/Lex/CodeCompletionHandler.h
------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/include/clang/Lex/CodeCompletionHandler.h
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=111943&r1=111942&r2=111943&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Tue Aug 24 14:08:16 2010
@@ -42,6 +42,7 @@
 class ScratchBuffer;
 class TargetInfo;
 class PPCallbacks;
+class CodeCompletionHandler;
 class DirectoryLookup;
 class PreprocessingRecord;
   
@@ -131,6 +132,9 @@
   /// with this preprocessor.
   std::vector<CommentHandler *> CommentHandlers;
 
+  /// \brief The code-completion handler.
+  CodeCompletionHandler *CodeComplete;
+  
   /// \brief The file that we're performing code-completion for, if any.
   const FileEntry *CodeCompletionFile;
 
@@ -373,6 +377,16 @@
   /// It is an error to remove a handler that has not been registered.
   void RemoveCommentHandler(CommentHandler *Handler);
 
+  /// \brief Set the code completion handler to the given object.
+  void setCodeCompletionHandler(CodeCompletionHandler &Handler) {
+    CodeComplete = &Handler;
+  }
+  
+  /// \brief Clear out the code completion handler.
+  void clearCodeCompletionHandler() {
+    CodeComplete = 0;
+  }
+  
   /// \brief Retrieve the preprocessing record, or NULL if there is no
   /// preprocessing record.
   PreprocessingRecord *getPreprocessingRecord() const { return Record; }

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=111943&r1=111942&r2=111943&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Tue Aug 24 14:08:16 2010
@@ -16,6 +16,7 @@
 
 #include "clang/Basic/Specifiers.h"
 #include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/CodeCompletionHandler.h"
 #include "clang/Sema/Action.h"
 #include "clang/Sema/DeclSpec.h"
 #include "llvm/ADT/OwningPtr.h"
@@ -70,7 +71,7 @@
 /// parsing units of the grammar, productions are invoked to handle whatever has
 /// been read.
 ///
-class Parser {
+class Parser : public CodeCompletionHandler {
   friend class PragmaUnusedHandler;
   friend class ColonProtectionRAIIObject;
   friend class ParenBraceBracketBalancer;
@@ -1529,6 +1530,11 @@
   //===--------------------------------------------------------------------===//
   // GNU G++: Type Traits [Type-Traits.html in the GCC manual]
   ExprResult ParseUnaryTypeTrait();
+
+  //===--------------------------------------------------------------------===//
+  // Preprocessor code-completion pass-through
+  virtual void CodeCompleteDirective(bool InConditional);
+  virtual void CodeCompleteInConditionalExclusion();
 };
 
 }  // end namespace clang

Modified: cfe/trunk/include/clang/Sema/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Action.h?rev=111943&r1=111942&r2=111943&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Action.h (original)
+++ cfe/trunk/include/clang/Sema/Action.h Tue Aug 24 14:08:16 2010
@@ -3205,6 +3205,16 @@
                                                   IdentifierInfo **SelIdents,
                                                   unsigned NumSelIdents) { }
   
+  /// \brief Code completion for a preprocessor directive.
+  ///
+  /// \brief S The scope in which the preprocessor directive is being parsed.
+  /// \brief InConditional Whether we're inside a preprocessor conditional.
+  virtual void CodeCompletePreprocessorDirective(Scope *S, bool InConditional) { 
+  }
+  
+  /// \brief Code completion while in an area of the translation unit that was
+  /// excluded due to preprocessor conditionals.
+  virtual void CodeCompleteInPreprocessorConditionalExclusion(Scope *S) { }
   //@}
 };
 

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=111943&r1=111942&r2=111943&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Aug 24 14:08:16 2010
@@ -4690,6 +4690,8 @@
                                                   ParsedType ReturnType,
                                                   IdentifierInfo **SelIdents,
                                                   unsigned NumSelIdents);
+  virtual void CodeCompletePreprocessorDirective(Scope *S, bool InConditional);
+  virtual void CodeCompleteInPreprocessorConditionalExclusion(Scope *S);
   void GatherGlobalCodeCompletions(
                   llvm::SmallVectorImpl<CodeCompleteConsumer::Result> &Results);
   //@}

Modified: cfe/trunk/lib/Lex/Lexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Lexer.cpp?rev=111943&r1=111942&r2=111943&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Lexer.cpp (original)
+++ cfe/trunk/lib/Lex/Lexer.cpp Tue Aug 24 14:08:16 2010
@@ -1523,6 +1523,22 @@
 /// This returns true if Result contains a token, false if PP.Lex should be
 /// called again.
 bool Lexer::LexEndOfFile(Token &Result, const char *CurPtr) {
+  // Check if we are performing code completion.
+  if (PP && PP->isCodeCompletionFile(FileLoc)) {
+    // We're at the end of the file, but we've been asked to consider the
+    // end of the file to be a code-completion token. Return the
+    // code-completion token.
+    Result.startToken();
+    FormTokenWithChars(Result, CurPtr, tok::code_completion);
+    
+    // Only do the eof -> code_completion translation once.
+    PP->SetCodeCompletionPoint(0, 0, 0);
+    
+    // Silence any diagnostics that occur once we hit the code-completion point.
+    PP->getDiagnostics().setSuppressAllDiagnostics(true);
+    return true;
+  }
+
   // If we hit the end of the file while parsing a preprocessor directive,
   // end the preprocessor directive first.  The next token returned will
   // then be the end of file.
@@ -1545,25 +1561,9 @@
     FormTokenWithChars(Result, BufferEnd, tok::eof);
     return true;
   }
-
-  // Otherwise, check if we are code-completing, then issue diagnostics for 
-  // unterminated #if and missing newline.
-
-  if (PP && PP->isCodeCompletionFile(FileLoc)) {
-    // We're at the end of the file, but we've been asked to consider the
-    // end of the file to be a code-completion token. Return the
-    // code-completion token.
-    Result.startToken();
-    FormTokenWithChars(Result, CurPtr, tok::code_completion);
-    
-    // Only do the eof -> code_completion translation once.
-    PP->SetCodeCompletionPoint(0, 0, 0);
-    
-    // Silence any diagnostics that occur once we hit the code-completion point.
-    PP->getDiagnostics().setSuppressAllDiagnostics(true);
-    return true;
-  }
   
+  // Issue diagnostics for unterminated #if and missing newline.
+
   // If we are in a #if directive, emit an error.
   while (!ConditionalStack.empty()) {
     if (!PP->isCodeCompletionFile(FileLoc))

Modified: cfe/trunk/lib/Lex/PPDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=111943&r1=111942&r2=111943&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Tue Aug 24 14:08:16 2010
@@ -16,6 +16,7 @@
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/MacroInfo.h"
 #include "clang/Lex/LexDiagnostic.h"
+#include "clang/Lex/CodeCompletionHandler.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/APInt.h"
@@ -177,6 +178,12 @@
   while (1) {
     CurLexer->Lex(Tok);
 
+    if (Tok.is(tok::code_completion)) {
+      if (CodeComplete)
+        CodeComplete->CodeCompleteInConditionalExclusion();
+      continue;
+    }
+    
     // If this is the end of the buffer, we have an error.
     if (Tok.is(tok::eof)) {
       // Emit errors for each unterminated conditional on the stack, including
@@ -522,7 +529,11 @@
     // Handle stuff like "# /*foo*/ define X" in -E -C mode.
     LexUnexpandedToken(Result);
     goto TryAgain;
-
+  case tok::code_completion:
+    if (CodeComplete)
+      CodeComplete->CodeCompleteDirective(
+                                    CurPPLexer->getConditionalStackDepth() > 0);
+    return;
   case tok::numeric_constant:  // # 7  GNU line marker directive.
     if (getLangOptions().AsmPreprocessor)
       break;  // # 4 is not a preprocessor directive in .S files.

Modified: cfe/trunk/lib/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=111943&r1=111942&r2=111943&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Preprocessor.cpp (original)
+++ cfe/trunk/lib/Lex/Preprocessor.cpp Tue Aug 24 14:08:16 2010
@@ -34,6 +34,7 @@
 #include "clang/Lex/PreprocessingRecord.h"
 #include "clang/Lex/ScratchBuffer.h"
 #include "clang/Lex/LexDiagnostic.h"
+#include "clang/Lex/CodeCompletionHandler.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/TargetInfo.h"
@@ -53,9 +54,9 @@
                            bool OwnsHeaders)
   : Diags(&diags), Features(opts), Target(target),FileMgr(Headers.getFileMgr()),
     SourceMgr(SM), HeaderInfo(Headers), ExternalSource(0),
-    Identifiers(opts, IILookup), BuiltinInfo(Target), CodeCompletionFile(0),
-    SkipMainFilePreamble(0, true), CurPPLexer(0), CurDirLookup(0), Callbacks(0), 
-    MacroArgCache(0), Record(0) {
+    Identifiers(opts, IILookup), BuiltinInfo(Target), CodeComplete(0),
+    CodeCompletionFile(0), SkipMainFilePreamble(0, true), CurPPLexer(0), 
+    CurDirLookup(0), Callbacks(0), MacroArgCache(0), Record(0) {
   ScratchBuf = new ScratchBuffer(SourceMgr);
   CounterValue = 0; // __COUNTER__ starts at 0.
   OwnsHeaderSearch = OwnsHeaders;
@@ -646,6 +647,8 @@
 
 CommentHandler::~CommentHandler() { }
 
+CodeCompletionHandler::~CodeCompletionHandler() { }
+
 void Preprocessor::createPreprocessingRecord() {
   if (Record)
     return;

Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=111943&r1=111942&r2=111943&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Tue Aug 24 14:08:16 2010
@@ -50,6 +50,8 @@
 
   WeakHandler.reset(new PragmaWeakHandler(actions));
   PP.AddPragmaHandler(WeakHandler.get());
+      
+  PP.setCodeCompletionHandler(*this);
 }
 
 /// If a crash happens while the parser is active, print out a line indicating
@@ -316,6 +318,7 @@
   UnusedHandler.reset();
   PP.RemovePragmaHandler(WeakHandler.get());
   WeakHandler.reset();
+  PP.clearCodeCompletionHandler();
 }
 
 /// Initialize - Warm up the parser.
@@ -1126,3 +1129,13 @@
 // performance-sensitive.
 void Parser::FieldCallback::_anchor() {
 }
+
+// Code-completion pass-through functions
+
+void Parser::CodeCompleteDirective(bool InConditional) {
+  Actions.CodeCompletePreprocessorDirective(getCurScope(), InConditional);
+}
+
+void Parser::CodeCompleteInConditionalExclusion() {
+  Actions.CodeCompleteInPreprocessorConditionalExclusion(getCurScope());
+}

Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=111943&r1=111942&r2=111943&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Tue Aug 24 14:08:16 2010
@@ -4607,6 +4607,186 @@
                             Results.data(),Results.size());
 }
 
+void Sema::CodeCompletePreprocessorDirective(Scope *S, bool InConditional) {
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+  
+  // #if <condition>
+  CodeCompletionString *Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("if");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("condition");
+  Results.AddResult(Pattern);
+  
+  // #ifdef <macro>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("ifdef");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("macro");
+  Results.AddResult(Pattern);
+
+  // #ifndef <macro>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("ifndef");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("macro");
+  Results.AddResult(Pattern);
+
+  if (InConditional) {
+    // #elif <condition>
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("elif");
+    Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+    Pattern->AddPlaceholderChunk("condition");
+    Results.AddResult(Pattern);
+
+    // #else
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("else");
+    Results.AddResult(Pattern);
+
+    // #endif
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("endif");
+    Results.AddResult(Pattern);
+  }
+  
+  // #include "header"
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("include");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddTextChunk("\"");
+  Pattern->AddPlaceholderChunk("header");
+  Pattern->AddTextChunk("\"");
+  Results.AddResult(Pattern);
+
+  // #include <header>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("include");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddTextChunk("<");
+  Pattern->AddPlaceholderChunk("header");
+  Pattern->AddTextChunk(">");
+  Results.AddResult(Pattern);
+  
+  // #define <macro>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("define");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("macro");
+  Results.AddResult(Pattern);
+  
+  // #define <macro>(<args>)
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("define");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("macro");
+  Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+  Pattern->AddPlaceholderChunk("args");
+  Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+  Results.AddResult(Pattern);
+  
+  // #undef <macro>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("undef");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("macro");
+  Results.AddResult(Pattern);
+
+  // #line <number>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("line");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("number");
+  Results.AddResult(Pattern);
+  
+  // #line <number> "filename"
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("line");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("number");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddTextChunk("\"");
+  Pattern->AddPlaceholderChunk("filename");
+  Pattern->AddTextChunk("\"");
+  Results.AddResult(Pattern);
+  
+  // #error <message>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("error");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("message");
+  Results.AddResult(Pattern);
+
+  // #pragma <arguments>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("pragma");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("arguments");
+  Results.AddResult(Pattern);
+
+  if (getLangOptions().ObjC1) {
+    // #import "header"
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("import");
+    Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+    Pattern->AddTextChunk("\"");
+    Pattern->AddPlaceholderChunk("header");
+    Pattern->AddTextChunk("\"");
+    Results.AddResult(Pattern);
+    
+    // #import <header>
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("import");
+    Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+    Pattern->AddTextChunk("<");
+    Pattern->AddPlaceholderChunk("header");
+    Pattern->AddTextChunk(">");
+    Results.AddResult(Pattern);
+  }
+  
+  // #include_next "header"
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("include_next");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddTextChunk("\"");
+  Pattern->AddPlaceholderChunk("header");
+  Pattern->AddTextChunk("\"");
+  Results.AddResult(Pattern);
+  
+  // #include_next <header>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("include_next");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddTextChunk("<");
+  Pattern->AddPlaceholderChunk("header");
+  Pattern->AddTextChunk(">");
+  Results.AddResult(Pattern);
+
+  // #warning <message>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("warning");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("message");
+  Results.AddResult(Pattern);
+
+  // Note: #ident and #sccs are such crazy anachronisms that we don't provide
+  // completions for them. And __include_macros is a Clang-internal extension
+  // that we don't want to encourage anyone to use.
+
+  // FIXME: we don't support #assert or #unassert, so don't suggest them.
+  Results.ExitScope();
+  
+  // FIXME: Create a new code-completion context for this?
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(), Results.size());
+}
+
+void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
+  CodeCompleteOrdinaryName(S, Action::PCC_RecoveryInFunction);
+}
+
 void Sema::GatherGlobalCodeCompletions(
                  llvm::SmallVectorImpl<CodeCompleteConsumer::Result> &Results) {
   ResultBuilder Builder(*this);

Added: cfe/trunk/test/Index/complete-preprocessor.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-preprocessor.m?rev=111943&view=auto
==============================================================================
--- cfe/trunk/test/Index/complete-preprocessor.m (added)
+++ cfe/trunk/test/Index/complete-preprocessor.m Tue Aug 24 14:08:16 2010
@@ -0,0 +1,47 @@
+// The line and column layout of this test is significant. Run lines
+// are at the end.
+
+#if 1
+#endif
+
+
+
+// RUN: c-index-test -code-completion-at=%s:4:2 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: NotImplemented:{TypedText define}{HorizontalSpace  }{Placeholder macro} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText define}{HorizontalSpace  }{Placeholder macro}{LeftParen (}{Placeholder args}{RightParen )} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText error}{HorizontalSpace  }{Placeholder message} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText if}{HorizontalSpace  }{Placeholder condition} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText ifdef}{HorizontalSpace  }{Placeholder macro} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText ifndef}{HorizontalSpace  }{Placeholder macro} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText import}{HorizontalSpace  }{Text "}{Placeholder header}{Text "} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText import}{HorizontalSpace  }{Text <}{Placeholder header}{Text >} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText include}{HorizontalSpace  }{Text "}{Placeholder header}{Text "} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText include}{HorizontalSpace  }{Text <}{Placeholder header}{Text >} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText include_next}{HorizontalSpace  }{Text "}{Placeholder header}{Text "} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText include_next}{HorizontalSpace  }{Text <}{Placeholder header}{Text >} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText line}{HorizontalSpace  }{Placeholder number} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText line}{HorizontalSpace  }{Placeholder number}{HorizontalSpace  }{Text "}{Placeholder filename}{Text "} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText pragma}{HorizontalSpace  }{Placeholder arguments} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText undef}{HorizontalSpace  }{Placeholder macro} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText warning}{HorizontalSpace  }{Placeholder message} (30)
+// RUN: c-index-test -code-completion-at=%s:5:2 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: NotImplemented:{TypedText define}{HorizontalSpace  }{Placeholder macro} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText define}{HorizontalSpace  }{Placeholder macro}{LeftParen (}{Placeholder args}{RightParen )} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText elif}{HorizontalSpace  }{Placeholder condition} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText else} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText endif} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText error}{HorizontalSpace  }{Placeholder message} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText if}{HorizontalSpace  }{Placeholder condition} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText ifdef}{HorizontalSpace  }{Placeholder macro} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText ifndef}{HorizontalSpace  }{Placeholder macro} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText import}{HorizontalSpace  }{Text "}{Placeholder header}{Text "} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText import}{HorizontalSpace  }{Text <}{Placeholder header}{Text >} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText include}{HorizontalSpace  }{Text "}{Placeholder header}{Text "} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText include}{HorizontalSpace  }{Text <}{Placeholder header}{Text >} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText include_next}{HorizontalSpace  }{Text "}{Placeholder header}{Text "} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText include_next}{HorizontalSpace  }{Text <}{Placeholder header}{Text >} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText line}{HorizontalSpace  }{Placeholder number} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText line}{HorizontalSpace  }{Placeholder number}{HorizontalSpace  }{Text "}{Placeholder filename}{Text "} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText pragma}{HorizontalSpace  }{Placeholder arguments} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText undef}{HorizontalSpace  }{Placeholder macro} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText warning}{HorizontalSpace  }{Placeholder message} (30)





More information about the cfe-commits mailing list