[cfe-commits] r93134 - in /cfe/trunk: include/clang-c/Index.h include/clang/Parse/Action.h include/clang/Sema/CodeCompleteConsumer.h lib/Parse/ParseDecl.cpp lib/Parse/ParseExpr.cpp lib/Parse/ParseExprCXX.cpp lib/Parse/ParseStmt.cpp lib/Parse/Parser.cpp lib/Sema/CodeCompleteConsumer.cpp lib/Sema/Sema.h lib/Sema/SemaCodeComplete.cpp test/CodeCompletion/ordinary-name.cpp tools/CIndex/CIndexCodeCompletion.cpp tools/c-index-test/c-index-test.c

Douglas Gregor dgregor at apple.com
Sun Jan 10 15:08:15 PST 2010


Author: dgregor
Date: Sun Jan 10 17:08:15 2010
New Revision: 93134

URL: http://llvm.org/viewvc/llvm-project?rev=93134&view=rev
Log:
Improve code completion by introducing patterns for the various C and
C++ grammatical constructs that show up in top-level (namespace-level)
declarations, member declarations, template declarations, statements,
expressions, conditions, etc. For example, we now provide a pattern
for

  static_cast<type>(expr)

when we can have an expression, or

  using namespace identifier;

when we can have a using directive.

Also, improves the results of code completion at the beginning of a
top-level declaration. Previously, we would see value names (function
names, global variables, etc.); now we see types, namespace names,
etc., but no values.


Added:
    cfe/trunk/test/CodeCompletion/ordinary-name.cpp   (with props)
Modified:
    cfe/trunk/include/clang-c/Index.h
    cfe/trunk/include/clang/Parse/Action.h
    cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Parse/ParseExpr.cpp
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Parse/ParseStmt.cpp
    cfe/trunk/lib/Parse/Parser.cpp
    cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp
    cfe/trunk/tools/CIndex/CIndexCodeCompletion.cpp
    cfe/trunk/tools/c-index-test/c-index-test.c

Modified: cfe/trunk/include/clang-c/Index.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=93134&r1=93133&r2=93134&view=diff

==============================================================================
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Sun Jan 10 17:08:15 2010
@@ -581,7 +581,28 @@
    * the text buffer. Rather, it is meant to illustrate the type that an 
    * expression using the given completion string would have.
    */
-  CXCompletionChunk_ResultType
+  CXCompletionChunk_ResultType,
+  /**
+   * \brief A colon (':').
+   */
+  CXCompletionChunk_Colon,
+  /**
+   * \brief A semicolon (';').
+   */
+  CXCompletionChunk_SemiColon,
+  /**
+   * \brief An '=' sign.
+   */
+  CXCompletionChunk_Equal,
+  /**
+   * Horizontal space (' ').
+   */
+  CXCompletionChunk_HorizontalSpace,
+  /**
+   * Vertical space ('\n'), after which it is generally a good idea to
+   * perform indentation.
+   */
+  CXCompletionChunk_VerticalSpace
 };
   
 /**

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=93134&r1=93133&r2=93134&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Sun Jan 10 17:08:15 2010
@@ -2340,11 +2340,40 @@
   /// \todo Code completion for attributes.
   //@{
   
+  /// \brief Describes the context in which code completion occurs.
+  enum CodeCompletionContext {
+    /// \brief Code completion occurs at top-level or namespace context.
+    CCC_Namespace,
+    /// \brief Code completion occurs within a class, struct, or union.
+    CCC_Class,
+    /// \brief Code completion occurs following one or more template
+    /// headers.
+    CCC_Template,
+    /// \brief Code completion occurs following one or more template
+    /// headers within a class.
+    CCC_MemberTemplate,
+    /// \brief Code completion occurs within an expression.
+    CCC_Expression,
+    /// \brief Code completion occurs within a statement, which may
+    /// also be an expression or a declaration.
+    CCC_Statement,
+    /// \brief Code completion occurs at the beginning of the
+    /// initialization statement (or expression) in a for loop.
+    CCC_ForInit,
+    /// \brief Code completion ocurs within the condition of an if,
+    /// while, switch, or for statement.
+    CCC_Condition
+  };
+    
   /// \brief Code completion for an ordinary name that occurs within the given
   /// scope.
   ///
   /// \param S the scope in which the name occurs.
-  virtual void CodeCompleteOrdinaryName(Scope *S) { }
+  ///
+  /// \param CompletionContext the context in which code completion
+  /// occurs.
+  virtual void CodeCompleteOrdinaryName(Scope *S, 
+                                    CodeCompletionContext CompletionContext) { }
   
   /// \brief Code completion for a member access expression.
   ///

Modified: cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h?rev=93134&r1=93133&r2=93134&view=diff

==============================================================================
--- cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h (original)
+++ cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h Sun Jan 10 17:08:15 2010
@@ -85,7 +85,18 @@
     /// \brief A right angle bracket ('>').
     CK_RightAngle,
     /// \brief A comma separator (',').
-    CK_Comma
+    CK_Comma,
+    /// \brief A colon (':').
+    CK_Colon,
+    /// \brief A semicolon (';').
+    CK_SemiColon,
+    /// \brief An '=' sign.
+    CK_Equal,
+    /// \brief Horizontal whitespace (' ').
+    CK_HorizontalSpace,
+    /// \brief Verticle whitespace ('\n' or '\r\n', depending on the
+    /// platform).
+    CK_VerticalSpace
   };
   
   /// \brief One piece of the code completion string.

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=93134&r1=93133&r2=93134&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Sun Jan 10 17:08:15 2010
@@ -814,7 +814,14 @@
                                         AccessSpecifier AS,
                                         DeclSpecContext DSContext) {
   if (Tok.is(tok::code_completion)) {
-    Actions.CodeCompleteOrdinaryName(CurScope);
+    Action::CodeCompletionContext CCC = Action::CCC_Namespace;
+    if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate)
+      CCC = DSContext == DSC_class? Action::CCC_MemberTemplate 
+                                  : Action::CCC_Template;
+    else if (DSContext == DSC_class)
+      CCC = Action::CCC_Class;
+
+    Actions.CodeCompleteOrdinaryName(CurScope, CCC);
     ConsumeToken();
   }
   

Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=93134&r1=93133&r2=93134&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Sun Jan 10 17:08:15 2010
@@ -200,11 +200,6 @@
 ///         expression ',' assignment-expression
 ///
 Parser::OwningExprResult Parser::ParseExpression() {
-  if (Tok.is(tok::code_completion)) {
-    Actions.CodeCompleteOrdinaryName(CurScope);
-    ConsumeToken();
-  }
-
   OwningExprResult LHS(ParseAssignmentExpression());
   if (LHS.isInvalid()) return move(LHS);
 
@@ -248,6 +243,11 @@
 /// ParseAssignmentExpression - Parse an expr that doesn't include commas.
 ///
 Parser::OwningExprResult Parser::ParseAssignmentExpression() {
+  if (Tok.is(tok::code_completion)) {
+    Actions.CodeCompleteOrdinaryName(CurScope, Action::CCC_Expression);
+    ConsumeToken();
+  }
+
   if (Tok.is(tok::kw_throw))
     return ParseThrowExpression();
 

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=93134&r1=93133&r2=93134&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Sun Jan 10 17:08:15 2010
@@ -585,6 +585,11 @@
 /// \returns true if there was a parsing, false otherwise.
 bool Parser::ParseCXXCondition(OwningExprResult &ExprResult,
                                DeclPtrTy &DeclResult) {
+  if (Tok.is(tok::code_completion)) {
+    Actions.CodeCompleteOrdinaryName(CurScope, Action::CCC_Condition);
+    ConsumeToken();
+  }
+
   if (!isCXXConditionDeclaration()) {
     ExprResult = ParseExpression(); // expression
     DeclResult = DeclPtrTy();

Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=93134&r1=93133&r2=93134&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Sun Jan 10 17:08:15 2010
@@ -95,7 +95,7 @@
     }
 
   case tok::code_completion:
-    Actions.CodeCompleteOrdinaryName(CurScope);
+    Actions.CodeCompleteOrdinaryName(CurScope, Action::CCC_Statement);
     ConsumeToken();
     return ParseStatementOrDeclaration(OnlyStatement);
       
@@ -955,7 +955,9 @@
   DeclPtrTy SecondVar;
   
   if (Tok.is(tok::code_completion)) {
-    Actions.CodeCompleteOrdinaryName(CurScope);
+    Actions.CodeCompleteOrdinaryName(CurScope, 
+                                     C99orCXXorObjC? Action::CCC_ForInit
+                                                   : Action::CCC_Expression);
     ConsumeToken();
   }
   

Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=93134&r1=93133&r2=93134&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Sun Jan 10 17:08:15 2010
@@ -455,7 +455,7 @@
     SingleDecl = ParseObjCMethodDefinition();
     break;
   case tok::code_completion:
-    Actions.CodeCompleteOrdinaryName(CurScope);
+    Actions.CodeCompleteOrdinaryName(CurScope, Action::CCC_Namespace);
     ConsumeToken();
     return ParseExternalDeclaration(Attr);
   case tok::kw_using:

Modified: cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp?rev=93134&r1=93133&r2=93134&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp (original)
+++ cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp Sun Jan 10 17:08:15 2010
@@ -85,6 +85,26 @@
   case CK_Comma:
     this->Text = ", ";
     break;
+
+  case CK_Colon:
+    this->Text = ": ";
+    break;
+
+  case CK_SemiColon:
+    this->Text = ";";
+    break;
+
+  case CK_Equal:
+    this->Text = " = ";
+    break;
+
+  case CK_HorizontalSpace:
+    this->Text = " ";
+    break;
+
+  case CK_VerticalSpace:
+    this->Text = "\n";
+    break;
   }
 }
 
@@ -140,6 +160,11 @@
   case CK_LeftAngle:
   case CK_RightAngle:
   case CK_Comma:
+  case CK_Colon:
+  case CK_SemiColon:
+  case CK_Equal:
+  case CK_HorizontalSpace:
+  case CK_VerticalSpace:
     return Chunk(Kind, Text);
       
   case CK_Optional: {
@@ -177,6 +202,11 @@
   case CK_LeftAngle:
   case CK_RightAngle:
   case CK_Comma:
+  case CK_Colon:
+  case CK_SemiColon:
+  case CK_Equal:
+  case CK_HorizontalSpace:
+  case CK_VerticalSpace:
     break;
   }
 }
@@ -271,6 +301,11 @@
     case CK_LeftAngle:
     case CK_RightAngle:
     case CK_Comma:
+    case CK_Colon:
+    case CK_SemiColon:
+    case CK_Equal:
+    case CK_HorizontalSpace:
+    case CK_VerticalSpace:
       break;
     }
   }
@@ -326,6 +361,11 @@
     case CK_LeftAngle:
     case CK_RightAngle:
     case CK_Comma:
+    case CK_Colon:
+    case CK_SemiColon:
+    case CK_Equal:
+    case CK_HorizontalSpace:
+    case CK_VerticalSpace:
       Result->AddChunk(Chunk(Kind));
       break;      
     }

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=93134&r1=93133&r2=93134&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Sun Jan 10 17:08:15 2010
@@ -3806,7 +3806,8 @@
 
   /// \name Code completion
   //@{
-  virtual void CodeCompleteOrdinaryName(Scope *S);
+  virtual void CodeCompleteOrdinaryName(Scope *S, 
+                                     CodeCompletionContext CompletionContext);
   virtual void CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *Base,
                                                SourceLocation OpLoc,
                                                bool IsArrow);

Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=93134&r1=93133&r2=93134&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Sun Jan 10 17:08:15 2010
@@ -158,6 +158,7 @@
     /// 
     //@{
     bool IsOrdinaryName(NamedDecl *ND) const;
+    bool IsOrdinaryNonValueName(NamedDecl *ND) const;
     bool IsNestedNameSpecifier(NamedDecl *ND) const;
     bool IsEnum(NamedDecl *ND) const;
     bool IsClassOrStruct(NamedDecl *ND) const;
@@ -517,6 +518,17 @@
   return ND->getIdentifierNamespace() & IDNS;
 }
 
+/// \brief Determines whether this given declaration will be found by
+/// ordinary name lookup.
+bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
+  unsigned IDNS = Decl::IDNS_Ordinary;
+  if (SemaRef.getLangOptions().CPlusPlus)
+    IDNS |= Decl::IDNS_Tag;
+  
+  return (ND->getIdentifierNamespace() & IDNS) && 
+    !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND);
+}
+
 /// \brief Determines whether the given declaration is suitable as the 
 /// start of a C++ nested-name-specifier, e.g., a class or namespace.
 bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
@@ -797,22 +809,32 @@
   Results.MaybeAddResult(Result("enum", Rank));
   Results.MaybeAddResult(Result("struct", Rank));
   Results.MaybeAddResult(Result("union", Rank));
-  
+  Results.MaybeAddResult(Result("const", Rank));
+  Results.MaybeAddResult(Result("volatile", Rank));
+
   if (LangOpts.C99) {
     // C99-specific
     Results.MaybeAddResult(Result("_Complex", Rank));
     Results.MaybeAddResult(Result("_Imaginary", Rank));
     Results.MaybeAddResult(Result("_Bool", Rank));
+    Results.MaybeAddResult(Result("restrict", Rank));
   }
   
   if (LangOpts.CPlusPlus) {
     // C++-specific
     Results.MaybeAddResult(Result("bool", Rank));
     Results.MaybeAddResult(Result("class", Rank));
-    Results.MaybeAddResult(Result("typename", Rank));
     Results.MaybeAddResult(Result("wchar_t", Rank));
     
+    // typename qualified-id
+    CodeCompletionString *Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("typename");
+    Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+    Pattern->AddPlaceholderChunk("qualified-id");
+    Results.MaybeAddResult(Result(Pattern, Rank));
+
     if (LangOpts.CPlusPlus0x) {
+      Results.MaybeAddResult(Result("auto", Rank));
       Results.MaybeAddResult(Result("char16_t", Rank));
       Results.MaybeAddResult(Result("char32_t", Rank));
       Results.MaybeAddResult(Result("decltype", Rank));
@@ -825,10 +847,487 @@
     //    Results.MaybeAddResult(Result("_Decimal32", Rank));
     //    Results.MaybeAddResult(Result("_Decimal64", Rank));
     //    Results.MaybeAddResult(Result("_Decimal128", Rank));
-    Results.MaybeAddResult(Result("typeof", Rank));
+    
+    CodeCompletionString *Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("typeof");
+    Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+    Pattern->AddPlaceholderChunk("expression-or-type");
+    Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+    Results.MaybeAddResult(Result(Pattern, Rank));
+  }
+}
+
+static void AddStorageSpecifiers(Action::CodeCompletionContext CCC,
+                                 const LangOptions &LangOpts, 
+                                 unsigned Rank, 
+                                 ResultBuilder &Results) {
+  typedef CodeCompleteConsumer::Result Result;
+  // Note: we don't suggest either "auto" or "register", because both
+  // are pointless as storage specifiers. Elsewhere, we suggest "auto"
+  // in C++0x as a type specifier.
+  Results.MaybeAddResult(Result("extern", Rank));
+  Results.MaybeAddResult(Result("static", Rank));
+}
+
+static void AddFunctionSpecifiers(Action::CodeCompletionContext CCC,
+                                  const LangOptions &LangOpts, 
+                                  unsigned Rank, 
+                                  ResultBuilder &Results) {
+  typedef CodeCompleteConsumer::Result Result;
+  switch (CCC) {
+  case Action::CCC_Class:
+  case Action::CCC_MemberTemplate:
+    if (LangOpts.CPlusPlus) {
+      Results.MaybeAddResult(Result("explicit", Rank));
+      Results.MaybeAddResult(Result("friend", Rank));
+      Results.MaybeAddResult(Result("mutable", Rank));
+      Results.MaybeAddResult(Result("virtual", Rank));
+    }    
+    // Fall through
+
+  case Action::CCC_Namespace:
+  case Action::CCC_Template:
+    if (LangOpts.CPlusPlus || LangOpts.C99)
+      Results.MaybeAddResult(Result("inline", Rank));
+    break;
+
+  case Action::CCC_Expression:
+  case Action::CCC_Statement:
+  case Action::CCC_ForInit:
+  case Action::CCC_Condition:
+    break;
   }
 }
 
+/// \brief Add language constructs that show up for "ordinary" names.
+static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
+                                   Scope *S,
+                                   Sema &SemaRef,
+                                   unsigned Rank, 
+                                   ResultBuilder &Results) {
+  typedef CodeCompleteConsumer::Result Result;
+  switch (CCC) {
+  case Action::CCC_Namespace:
+    if (SemaRef.getLangOptions().CPlusPlus) {
+      // namespace <identifier> { }
+      CodeCompletionString *Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("namespace");
+      Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      Pattern->AddPlaceholderChunk("identifier");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
+      Pattern->AddPlaceholderChunk("declarations");
+      Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
+      Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
+      Results.MaybeAddResult(Result(Pattern, Rank));
+
+      // namespace identifier = identifier ;
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("namespace");
+      Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      Pattern->AddPlaceholderChunk("identifier");
+      Pattern->AddChunk(CodeCompletionString::CK_Equal);
+      Pattern->AddPlaceholderChunk("identifier");
+      Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
+      Results.MaybeAddResult(Result(Pattern, Rank));
+
+      // Using directives
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("using");
+      Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      Pattern->AddTextChunk("namespace");
+      Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      Pattern->AddPlaceholderChunk("identifier");
+      Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
+      Results.MaybeAddResult(Result(Pattern, Rank));
+
+      // asm(string-literal)      
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("asm");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+      Pattern->AddPlaceholderChunk("string-literal");
+      Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+      Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
+      Results.MaybeAddResult(Result(Pattern, Rank));
+
+      // Explicit template instantiation
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("template");
+      Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      Pattern->AddPlaceholderChunk("declaration");
+      Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
+      Results.MaybeAddResult(Result(Pattern, Rank));
+    }
+    // Fall through
+
+  case Action::CCC_Class:
+    Results.MaybeAddResult(Result("typedef", Rank));
+    if (SemaRef.getLangOptions().CPlusPlus) {
+      // Using declaration
+      CodeCompletionString *Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("using");
+      Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      Pattern->AddPlaceholderChunk("qualified-id");
+      Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
+      Results.MaybeAddResult(Result(Pattern, Rank));
+      
+      // using typename qualified-id; (only in a dependent context)
+      if (SemaRef.CurContext->isDependentContext()) {
+        Pattern = new CodeCompletionString;
+        Pattern->AddTypedTextChunk("using");
+        Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+        Pattern->AddTextChunk("typename");
+        Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+        Pattern->AddPlaceholderChunk("qualified-id");
+        Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
+        Results.MaybeAddResult(Result(Pattern, Rank));
+      }
+
+      if (CCC == Action::CCC_Class) {
+        // public:
+        Pattern = new CodeCompletionString;
+        Pattern->AddTypedTextChunk("public");
+        Pattern->AddChunk(CodeCompletionString::CK_Colon);
+        Results.MaybeAddResult(Result(Pattern, Rank));
+
+        // protected:
+        Pattern = new CodeCompletionString;
+        Pattern->AddTypedTextChunk("protected");
+        Pattern->AddChunk(CodeCompletionString::CK_Colon);
+        Results.MaybeAddResult(Result(Pattern, Rank));
+
+        // private:
+        Pattern = new CodeCompletionString;
+        Pattern->AddTypedTextChunk("private");
+        Pattern->AddChunk(CodeCompletionString::CK_Colon);
+        Results.MaybeAddResult(Result(Pattern, Rank));
+      }
+    }
+    // Fall through
+
+  case Action::CCC_Template:
+  case Action::CCC_MemberTemplate:
+    if (SemaRef.getLangOptions().CPlusPlus) {
+      // template < parameters >
+      CodeCompletionString *Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("template");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
+      Pattern->AddPlaceholderChunk("parameters");
+      Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
+      Results.MaybeAddResult(Result(Pattern, Rank));
+    }
+
+    AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Rank, Results);
+    AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Rank, Results);
+    break;
+
+  case Action::CCC_Statement: {
+    Results.MaybeAddResult(Result("typedef", Rank));
+
+    CodeCompletionString *Pattern = 0;
+    if (SemaRef.getLangOptions().CPlusPlus) {
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("try");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
+      Pattern->AddPlaceholderChunk("statements");
+      Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
+      Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
+      Pattern->AddTextChunk("catch");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+      Pattern->AddPlaceholderChunk("declaration");
+      Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+      Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
+      Pattern->AddPlaceholderChunk("statements");
+      Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
+      Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
+      Results.MaybeAddResult(Result(Pattern, Rank));
+    }
+
+    // if (condition) { statements }
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("if");
+    Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+    if (SemaRef.getLangOptions().CPlusPlus)
+      Pattern->AddPlaceholderChunk("condition");
+    else
+      Pattern->AddPlaceholderChunk("expression");
+    Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+    Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
+    Pattern->AddPlaceholderChunk("statements");
+    Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
+    Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
+    Results.MaybeAddResult(Result(Pattern, Rank));
+
+    // switch (condition) { }
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("switch");
+    Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+    if (SemaRef.getLangOptions().CPlusPlus)
+      Pattern->AddPlaceholderChunk("condition");
+    else
+      Pattern->AddPlaceholderChunk("expression");
+    Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+    Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
+    Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
+    Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
+    Results.MaybeAddResult(Result(Pattern, Rank));
+
+    // Switch-specific statements.
+    if (!SemaRef.getSwitchStack().empty()) {
+      // case expression:
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("case");
+      Pattern->AddPlaceholderChunk("expression");
+      Pattern->AddChunk(CodeCompletionString::CK_Colon);
+      Results.MaybeAddResult(Result(Pattern, Rank));
+
+      // default:
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("default");
+      Pattern->AddChunk(CodeCompletionString::CK_Colon);
+      Results.MaybeAddResult(Result(Pattern, Rank));
+    }
+
+    /// while (condition) { statements }
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("while");
+    Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+    if (SemaRef.getLangOptions().CPlusPlus)
+      Pattern->AddPlaceholderChunk("condition");
+    else
+      Pattern->AddPlaceholderChunk("expression");
+    Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+    Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
+    Pattern->AddPlaceholderChunk("statements");
+    Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
+    Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
+    Results.MaybeAddResult(Result(Pattern, Rank));
+
+    // do { statements } while ( expression );
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("do");
+    Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
+    Pattern->AddPlaceholderChunk("statements");
+    Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
+    Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
+    Pattern->AddTextChunk("while");
+    Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+    Pattern->AddPlaceholderChunk("expression");
+    Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+    Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
+    Results.MaybeAddResult(Result(Pattern, Rank));
+
+    // for ( for-init-statement ; condition ; expression ) { statements }
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("for");
+    Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+    if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
+      Pattern->AddPlaceholderChunk("init-statement");
+    else
+      Pattern->AddPlaceholderChunk("init-expression");
+    Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
+    Pattern->AddPlaceholderChunk("condition");
+    Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
+    Pattern->AddPlaceholderChunk("inc-expression");
+    Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+    Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
+    Pattern->AddPlaceholderChunk("statements");
+    Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
+    Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
+    Results.MaybeAddResult(Result(Pattern, Rank));
+    
+    if (S->getContinueParent()) {
+      // continue ;
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("continue");
+      Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
+      Results.MaybeAddResult(Result(Pattern, Rank));
+    }
+
+    if (S->getBreakParent()) {
+      // break ;
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("break");
+      Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
+      Results.MaybeAddResult(Result(Pattern, Rank));
+    }
+
+    // "return expression ;" or "return ;", depending on whether we
+    // know the function is void or not.
+    bool isVoid = false;
+    if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
+      isVoid = Function->getResultType()->isVoidType();
+    else if (ObjCMethodDecl *Method
+                                 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
+      isVoid = Method->getResultType()->isVoidType();
+    else if (SemaRef.CurBlock && !SemaRef.CurBlock->ReturnType.isNull())
+      isVoid = SemaRef.CurBlock->ReturnType->isVoidType();
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("return");
+    if (!isVoid)
+      Pattern->AddPlaceholderChunk("expression");
+    Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
+    Results.MaybeAddResult(Result(Pattern, Rank));
+
+    // goto identifier ;
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("goto");
+    Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+    Pattern->AddPlaceholderChunk("identifier");
+    Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
+    Results.MaybeAddResult(Result(Pattern, Rank));    
+
+    // Using directives
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("using");
+    Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+    Pattern->AddTextChunk("namespace");
+    Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+    Pattern->AddPlaceholderChunk("identifier");
+    Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
+    Results.MaybeAddResult(Result(Pattern, Rank));
+  }
+
+  // Fall through (for statement expressions).
+  case Action::CCC_ForInit:
+  case Action::CCC_Condition:
+    AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Rank, Results);
+    // Fall through: conditions and statements can have expressions.
+
+  case Action::CCC_Expression: {
+    CodeCompletionString *Pattern = 0;
+    if (SemaRef.getLangOptions().CPlusPlus) {
+      // 'this', if we're in a non-static member function.
+      if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
+        if (!Method->isStatic())
+          Results.MaybeAddResult(Result("this", Rank));
+      
+      // true, false
+      Results.MaybeAddResult(Result("true", Rank));
+      Results.MaybeAddResult(Result("false", Rank));
+
+      // dynamic_cast < type-id > ( expression )
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("dynamic_cast");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
+      Pattern->AddPlaceholderChunk("type-id");
+      Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
+      Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+      Pattern->AddPlaceholderChunk("expression");
+      Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+      Results.MaybeAddResult(Result(Pattern, Rank));      
+      
+      // static_cast < type-id > ( expression )
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("static_cast");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
+      Pattern->AddPlaceholderChunk("type-id");
+      Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
+      Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+      Pattern->AddPlaceholderChunk("expression");
+      Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+      Results.MaybeAddResult(Result(Pattern, Rank));      
+
+      // reinterpret_cast < type-id > ( expression )
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("reinterpret_cast");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
+      Pattern->AddPlaceholderChunk("type-id");
+      Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
+      Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+      Pattern->AddPlaceholderChunk("expression");
+      Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+      Results.MaybeAddResult(Result(Pattern, Rank));      
+
+      // const_cast < type-id > ( expression )
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("const_cast");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
+      Pattern->AddPlaceholderChunk("type-id");
+      Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
+      Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+      Pattern->AddPlaceholderChunk("expression");
+      Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+      Results.MaybeAddResult(Result(Pattern, Rank));      
+
+      // typeid ( expression-or-type )
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("typeid");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+      Pattern->AddPlaceholderChunk("expression-or-type");
+      Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+      Results.MaybeAddResult(Result(Pattern, Rank));      
+
+      // new T ( ... )
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("new");
+      Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      Pattern->AddPlaceholderChunk("type-id");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+      Pattern->AddPlaceholderChunk("expressions");
+      Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+      Results.MaybeAddResult(Result(Pattern, Rank));      
+
+      // new T [ ] ( ... )
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("new");
+      Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      Pattern->AddPlaceholderChunk("type-id");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
+      Pattern->AddPlaceholderChunk("size");
+      Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
+      Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+      Pattern->AddPlaceholderChunk("expressions");
+      Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+      Results.MaybeAddResult(Result(Pattern, Rank));      
+
+      // delete expression
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("delete");
+      Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      Pattern->AddPlaceholderChunk("expression");
+      Results.MaybeAddResult(Result(Pattern, Rank));      
+
+      // delete [] expression
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("delete");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
+      Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
+      Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      Pattern->AddPlaceholderChunk("expression");
+      Results.MaybeAddResult(Result(Pattern, Rank));
+
+      // throw expression
+      Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("throw");
+      Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      Pattern->AddPlaceholderChunk("expression");
+      Results.MaybeAddResult(Result(Pattern, Rank));
+    }
+
+    if (SemaRef.getLangOptions().ObjC1) {
+      // Add "super", if we're in an Objective-C class with a superclass.
+      if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl())
+        if (Method->getClassInterface()->getSuperClass())
+          Results.MaybeAddResult(Result("super", Rank));
+    }
+
+    // sizeof expression
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("sizeof");
+    Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+    Pattern->AddPlaceholderChunk("expression-or-type");
+    Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+    Results.MaybeAddResult(Result(Pattern, Rank));
+    break;
+  }
+  }
+
+  AddTypeSpecifierResults(SemaRef.getLangOptions(), Rank, Results);
+
+  if (SemaRef.getLangOptions().CPlusPlus)
+    Results.MaybeAddResult(Result("operator", Rank));
+}
+
 /// \brief If the given declaration has an associated type, add it as a result 
 /// type chunk.
 static void AddResultTypeChunk(ASTContext &Context,
@@ -1422,22 +1921,35 @@
     Results[I].Destroy();
 }
 
-void Sema::CodeCompleteOrdinaryName(Scope *S) {
+void Sema::CodeCompleteOrdinaryName(Scope *S, 
+                                    CodeCompletionContext CompletionContext) {
   typedef CodeCompleteConsumer::Result Result;
-  ResultBuilder Results(*this, &ResultBuilder::IsOrdinaryName);
+  ResultBuilder Results(*this);
+
+  // Determine how to filter results, e.g., so that the names of
+  // values (functions, enumerators, function templates, etc.) are
+  // only allowed where we can have an expression.
+  switch (CompletionContext) {
+  case CCC_Namespace:
+  case CCC_Class:
+  case CCC_Template:
+  case CCC_MemberTemplate:
+    Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
+    break;
+
+  case CCC_Expression:
+  case CCC_Statement:
+  case CCC_ForInit:
+  case CCC_Condition:
+    Results.setFilter(&ResultBuilder::IsOrdinaryName);
+    break;
+  }
+
   unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(), 
                                            0, CurContext, Results);
 
   Results.EnterNewScope();
-  AddTypeSpecifierResults(getLangOptions(), NextRank, Results);
-  
-  if (getLangOptions().ObjC1) {
-    // Add the "super" keyword, if appropriate.
-    if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
-      if (Method->getClassInterface()->getSuperClass())
-        Results.MaybeAddResult(Result("super", NextRank));
-  }
-
+  AddOrdinaryNameResults(CompletionContext, S, *this, NextRank, Results);
   Results.ExitScope();
 
   if (CodeCompleter->includeMacros())
@@ -1561,9 +2073,6 @@
                                               E = ObjCPtr->qual_end();
          I != E; ++I)
       AddObjCProperties(*I, true, CurContext, Results);
-    
-    // FIXME: We could (should?) also look for "implicit" properties, identified
-    // only by the presence of nullary and unary selectors.
   } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
              (!IsArrow && BaseType->isObjCInterfaceType())) {
     // Objective-C instance variable access.
@@ -1746,7 +2255,7 @@
   // Ignore type-dependent call expressions entirely.
   if (Fn->isTypeDependent() || 
       Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
-    CodeCompleteOrdinaryName(S);
+    CodeCompleteOrdinaryName(S, CCC_Expression);
     return;
   }
 
@@ -1784,7 +2293,7 @@
   }
 
   if (Results.empty())
-    CodeCompleteOrdinaryName(S);
+    CodeCompleteOrdinaryName(S, CCC_Expression);
   else
     CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(), 
                                              Results.size());
@@ -1968,7 +2477,7 @@
     // Since we have an interface or protocol, we can end it.
     Results.MaybeAddResult(Result("end", 0));
 
-    if (LangOpts.ObjC2) {
+    if (getLangOptions().ObjC2) {
       // @property
       Results.MaybeAddResult(Result("property", 0));
     }

Added: cfe/trunk/test/CodeCompletion/ordinary-name.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeCompletion/ordinary-name.cpp?rev=93134&view=auto

==============================================================================
--- cfe/trunk/test/CodeCompletion/ordinary-name.cpp (added)
+++ cfe/trunk/test/CodeCompletion/ordinary-name.cpp Sun Jan 10 17:08:15 2010
@@ -0,0 +1,170 @@
+struct X { int x; };
+void z(int);
+typedef struct t TYPEDEF;
+
+void foo() {
+  int y = 17;
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:6:14 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
+  // CHECK-CC1: COMPLETION: y : 0 : [#int#]y
+  // CHECK-CC1-NEXT: COMPLETION: foo : 2 : [#void#]foo()
+  // CHECK-CC1-NEXT: COMPLETION: t : 2 : t
+  // CHECK-CC1-NEXT: COMPLETION: TYPEDEF : 2 : TYPEDEF
+  // CHECK-CC1-NEXT: COMPLETION: X : 2 : X
+  // CHECK-CC1-NOT: x
+  // CHECK-CC1-NEXT: COMPLETION: z : 2 : [#void#]z(<#int#>)
+  // CHECK-CC1-NEXT: COMPLETION: bool : 3
+  // CHECK-CC1-NEXT: COMPLETION: char : 3
+  // CHECK-CC1-NEXT: COMPLETION: class : 3
+  // CHECK-CC1-NEXT: COMPLETION: const : 3
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : 3 : const_cast<<#type-id#>>(<#expression#>)
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : 3 : delete <#expression#>
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : 3 : delete[] <#expression#>
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : 3 : do{<#statements#>
+  // CHECK-CC1: COMPLETION: double : 3
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : 3 : dynamic_cast<<#type-id#>>(<#expression#>)
+  // CHECK-CC1-NEXT: COMPLETION: enum : 3
+  // CHECK-CC1-NEXT: COMPLETION: extern : 3
+  // CHECK-CC1-NEXT: COMPLETION: false : 3
+  // CHECK-CC1-NEXT: COMPLETION: float : 3
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : 3 : for(<#init-statement#>;<#condition#>;<#inc-expression#>){<#statements#>
+  // CHECK-CC1: COMPLETION: Pattern : 3 : goto <#identifier#>;
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : 3 : if(<#condition#>){<#statements#>
+  // CHECK-CC1: COMPLETION: int : 3
+  // CHECK-CC1-NEXT: COMPLETION: long : 3
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : 3 : new <#type-id#>(<#expressions#>)
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : 3 : new <#type-id#>[<#size#>](<#expressions#>)
+  // CHECK-CC1-NEXT: COMPLETION: operator : 3
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : 3 : reinterpret_cast<<#type-id#>>(<#expression#>)
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : 3 : return;
+  // CHECK-CC1-NEXT: COMPLETION: short : 3
+  // CHECK-CC1-NEXT: COMPLETION: signed : 3
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : 3 : sizeof(<#expression-or-type#>)
+  // CHECK-CC1-NEXT: COMPLETION: static : 3
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : 3 : static_cast<<#type-id#>>(<#expression#>)
+  // CHECK-CC1-NEXT: COMPLETION: struct : 3
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : 3 : switch(<#condition#>){
+  // CHECK-CC1: COMPLETION: Pattern : 3 : throw <#expression#>
+  // CHECK-CC1-NEXT: COMPLETION: true : 3
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : 3 : try{<#statements#>
+  // CHECK-CC1: COMPLETION: typedef : 3
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : 3 : typeid(<#expression-or-type#>)
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : 3 : typename <#qualified-id#>
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : 3 : typeof(<#expression-or-type#>)
+  // CHECK-CC1-NEXT: COMPLETION: union : 3
+  // CHECK-CC1-NEXT: COMPLETION: unsigned : 3
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : 3 : using namespace <#identifier#>;
+  // CHECK-CC1-NEXT: COMPLETION: void : 3
+  // CHECK-CC1-NEXT: COMPLETION: volatile : 3
+  // CHECK-CC1-NEXT: COMPLETION: wchar_t : 3
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : 3 : while(<#condition#>){<#statements#>
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:4:1 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
+  // CHECK-CC2: COMPLETION: t : 1 : t
+  // CHECK-CC2-NEXT: COMPLETION: TYPEDEF : 1 : TYPEDEF
+  // CHECK-CC2-NEXT: COMPLETION: X : 1 : X
+  // CHECK-CC2-NOT: COMPLETION: z
+  // CHECK-CC2-NEXT: COMPLETION: Pattern : 2 : asm(<#string-literal#>);
+  // CHECK-CC2-NEXT: COMPLETION: bool : 2
+  // CHECK-CC2-NEXT: COMPLETION: char : 2
+  // CHECK-CC2-NEXT: COMPLETION: class : 2
+  // CHECK-CC2-NEXT: COMPLETION: const : 2
+  // CHECK-CC2-NEXT: COMPLETION: double : 2
+  // CHECK-CC2-NEXT: COMPLETION: enum : 2
+  // CHECK-CC2-NEXT: COMPLETION: extern : 2
+  // CHECK-CC2-NEXT: COMPLETION: float : 2
+  // CHECK-CC2-NEXT: COMPLETION: inline : 2
+  // CHECK-CC2-NEXT: COMPLETION: int : 2
+  // CHECK-CC2-NEXT: COMPLETION: long : 2
+  // CHECK-CC2-NEXT: COMPLETION: Pattern : 2 : namespace <#identifier#>{<#declarations#>
+  // CHECK-CC2: COMPLETION: Pattern : 2 : namespace <#identifier#> = <#identifier#>;
+  // CHECK-CC2-NEXT: COMPLETION: operator : 2
+  // CHECK-CC2-NEXT: COMPLETION: short : 2
+  // CHECK-CC2-NEXT: COMPLETION: signed : 2
+  // CHECK-CC2-NEXT: COMPLETION: static : 2
+  // CHECK-CC2-NEXT: COMPLETION: struct : 2
+  // CHECK-CC2-NEXT: COMPLETION: Pattern : 2 : template <#declaration#>;
+  // CHECK-CC2-NEXT: COMPLETION: Pattern : 2 : template<<#parameters#>>
+  // CHECK-CC2-NEXT: COMPLETION: typedef : 2
+  // CHECK-CC2-NEXT: COMPLETION: Pattern : 2 : typename <#qualified-id#>
+  // CHECK-CC2-NEXT: COMPLETION: Pattern : 2 : typeof(<#expression-or-type#>)
+  // CHECK-CC2-NEXT: COMPLETION: union : 2
+  // CHECK-CC2-NEXT: COMPLETION: unsigned : 2
+  // CHECK-CC2-NEXT: COMPLETION: Pattern : 2 : using namespace <#identifier#>;
+  // CHECK-CC2-NEXT: COMPLETION: Pattern : 2 : using <#qualified-id#>;
+  // CHECK-CC2-NEXT: COMPLETION: void : 2
+  // CHECK-CC2-NEXT: COMPLETION: volatile : 2
+  // CHECK-CC2-NEXT: COMPLETION: wchar_t : 2
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:1:19 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s
+  // CHECK-CC3: COMPLETION: X : 1 : X
+  // CHECK-CC3-NEXT: COMPLETION: bool : 4
+  // CHECK-CC3-NEXT: COMPLETION: char : 4
+  // CHECK-CC3-NEXT: COMPLETION: class : 4
+  // CHECK-CC3-NEXT: COMPLETION: const : 4
+  // CHECK-CC3-NEXT: COMPLETION: double : 4
+  // CHECK-CC3-NEXT: COMPLETION: enum : 4
+  // CHECK-CC3-NEXT: COMPLETION: explicit : 4
+  // CHECK-CC3-NEXT: COMPLETION: extern : 4
+  // CHECK-CC3-NEXT: COMPLETION: float : 4
+  // CHECK-CC3-NEXT: COMPLETION: friend : 4
+  // CHECK-CC3-NEXT: COMPLETION: inline : 4
+  // CHECK-CC3-NEXT: COMPLETION: int : 4
+  // CHECK-CC3-NEXT: COMPLETION: long : 4
+  // CHECK-CC3-NEXT: COMPLETION: mutable : 4
+  // CHECK-CC3-NEXT: COMPLETION: operator : 4
+  // CHECK-CC3-NEXT: COMPLETION: Pattern : 4 : private: 
+  // CHECK-CC3-NEXT: COMPLETION: Pattern : 4 : protected: 
+  // CHECK-CC3-NEXT: COMPLETION: Pattern : 4 : public: 
+  // CHECK-CC3-NEXT: COMPLETION: short : 4
+  // CHECK-CC3-NEXT: COMPLETION: signed : 4
+  // CHECK-CC3-NEXT: COMPLETION: static : 4
+  // CHECK-CC3-NEXT: COMPLETION: struct : 4
+  // CHECK-CC3-NEXT: COMPLETION: Pattern : 4 : template<<#parameters#>>
+  // CHECK-CC3-NEXT: COMPLETION: typedef : 4
+  // CHECK-CC3-NEXT: COMPLETION: Pattern : 4 : typename <#qualified-id#>
+  // CHECK-CC3-NEXT: COMPLETION: Pattern : 4 : typeof(<#expression-or-type#>)
+  // CHECK-CC3-NEXT: COMPLETION: union : 4
+  // CHECK-CC3-NEXT: COMPLETION: unsigned : 4
+  // CHECK-CC3-NEXT: COMPLETION: Pattern : 4 : using <#qualified-id#>;
+  // CHECK-CC3-NEXT: COMPLETION: virtual : 4
+  // CHECK-CC3-NEXT: COMPLETION: void : 4
+  // CHECK-CC3-NEXT: COMPLETION: volatile : 4
+  // CHECK-CC3-NEXT: COMPLETION: wchar_t : 4
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:6:11 %s -o - | FileCheck -check-prefix=CHECK-CC4 %s
+  // CHECK-CC4: COMPLETION: y : 0 : [#int#]y
+  // CHECK-CC4-NEXT: COMPLETION: foo : 2 : [#void#]foo()
+  // CHECK-CC4-NEXT: COMPLETION: t : 2 : t
+  // CHECK-CC4-NEXT: COMPLETION: TYPEDEF : 2 : TYPEDEF
+  // CHECK-CC4-NEXT: COMPLETION: X : 2 : X
+  // CHECK-CC4-NEXT: COMPLETION: z : 2 : [#void#]z(<#int#>)
+  // CHECK-CC4-NEXT: COMPLETION: bool : 3
+  // CHECK-CC4-NEXT: COMPLETION: char : 3
+  // CHECK-CC4-NEXT: COMPLETION: class : 3
+  // CHECK-CC4-NEXT: COMPLETION: const : 3
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : 3 : const_cast<<#type-id#>>(<#expression#>)
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : 3 : delete <#expression#>
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : 3 : delete[] <#expression#>
+  // CHECK-CC4-NEXT: COMPLETION: double : 3
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : 3 : dynamic_cast<<#type-id#>>(<#expression#>)
+  // CHECK-CC4-NEXT: COMPLETION: enum : 3
+  // CHECK-CC4-NEXT: COMPLETION: false : 3
+  // CHECK-CC4-NEXT: COMPLETION: float : 3
+  // CHECK-CC4-NEXT: COMPLETION: int : 3
+  // CHECK-CC4-NEXT: COMPLETION: long : 3
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : 3 : new <#type-id#>(<#expressions#>)
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : 3 : new <#type-id#>[<#size#>](<#expressions#>)
+  // CHECK-CC4-NEXT: COMPLETION: operator : 3
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : 3 : reinterpret_cast<<#type-id#>>(<#expression#>)
+  // CHECK-CC4-NEXT: COMPLETION: short : 3
+  // CHECK-CC4-NEXT: COMPLETION: signed : 3
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : 3 : sizeof(<#expression-or-type#>)
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : 3 : static_cast<<#type-id#>>(<#expression#>)
+  // CHECK-CC4-NEXT: COMPLETION: struct : 3
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : 3 : throw <#expression#>
+  // CHECK-CC4-NEXT: COMPLETION: true : 3
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : 3 : typeid(<#expression-or-type#>)
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : 3 : typename <#qualified-id#>
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : 3 : typeof(<#expression-or-type#>)
+  // CHECK-CC4-NEXT: COMPLETION: union : 3
+  // CHECK-CC4-NEXT: COMPLETION: unsigned : 3
+  // CHECK-CC4-NEXT: COMPLETION: void : 3
+  // CHECK-CC4-NEXT: COMPLETION: volatile : 3
+  // CHECK-CC4-NEXT: COMPLETION: wchar_t : 3

Propchange: cfe/trunk/test/CodeCompletion/ordinary-name.cpp

------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/CodeCompletion/ordinary-name.cpp

------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/CodeCompletion/ordinary-name.cpp

------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: cfe/trunk/tools/CIndex/CIndexCodeCompletion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndexCodeCompletion.cpp?rev=93134&r1=93133&r2=93134&view=diff

==============================================================================
--- cfe/trunk/tools/CIndex/CIndexCodeCompletion.cpp (original)
+++ cfe/trunk/tools/CIndex/CIndexCodeCompletion.cpp Sun Jan 10 17:08:15 2010
@@ -62,6 +62,16 @@
     return CXCompletionChunk_RightAngle;
   case CodeCompletionString::CK_Comma:
     return CXCompletionChunk_Comma;
+  case CodeCompletionString::CK_Colon:
+    return CXCompletionChunk_Colon;
+  case CodeCompletionString::CK_SemiColon:
+    return CXCompletionChunk_SemiColon;
+  case CodeCompletionString::CK_Equal:
+    return CXCompletionChunk_Equal;
+  case CodeCompletionString::CK_HorizontalSpace:
+    return CXCompletionChunk_HorizontalSpace;
+  case CodeCompletionString::CK_VerticalSpace:
+    return CXCompletionChunk_VerticalSpace;
   }
 
   // Should be unreachable, but let's be careful.
@@ -90,6 +100,11 @@
   case CodeCompletionString::CK_RightAngle:
   case CodeCompletionString::CK_Comma:
   case CodeCompletionString::CK_ResultType:
+  case CodeCompletionString::CK_Colon:
+  case CodeCompletionString::CK_SemiColon:
+  case CodeCompletionString::CK_Equal:
+  case CodeCompletionString::CK_HorizontalSpace:
+  case CodeCompletionString::CK_VerticalSpace:
     return (*CCStr)[chunk_number].Text;
 
   case CodeCompletionString::CK_Optional:
@@ -124,6 +139,11 @@
   case CodeCompletionString::CK_RightAngle:
   case CodeCompletionString::CK_Comma:
   case CodeCompletionString::CK_ResultType:
+  case CodeCompletionString::CK_Colon:
+  case CodeCompletionString::CK_SemiColon:
+  case CodeCompletionString::CK_Equal:
+  case CodeCompletionString::CK_HorizontalSpace:
+  case CodeCompletionString::CK_VerticalSpace:
     return 0;
 
   case CodeCompletionString::CK_Optional:

Modified: cfe/trunk/tools/c-index-test/c-index-test.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=93134&r1=93133&r2=93134&view=diff

==============================================================================
--- cfe/trunk/tools/c-index-test/c-index-test.c (original)
+++ cfe/trunk/tools/c-index-test/c-index-test.c Sun Jan 10 17:08:15 2010
@@ -378,6 +378,11 @@
   case CXCompletionChunk_RightAngle: return "RightAngle";
   case CXCompletionChunk_Comma: return "Comma";
   case CXCompletionChunk_ResultType: return "ResultType";
+  case CXCompletionChunk_Colon: return "Colon";
+  case CXCompletionChunk_SemiColon: return "SemiColon";
+  case CXCompletionChunk_Equal: return "Equal";
+  case CXCompletionChunk_HorizontalSpace: return "HorizontalSpace";
+  case CXCompletionChunk_VerticalSpace: return "VerticalSpace";
   }
   
   return "Unknown";





More information about the cfe-commits mailing list