[cfe-commits] r111139 - in /cfe/trunk: include/clang/Frontend/ASTUnit.h include/clang/Sema/CodeCompleteConsumer.h lib/Frontend/ASTUnit.cpp lib/Sema/SemaCodeComplete.cpp test/Index/complete-exprs.c test/Index/complete-macros.c

Douglas Gregor dgregor at apple.com
Mon Aug 16 09:18:59 PDT 2010


Author: dgregor
Date: Mon Aug 16 11:18:59 2010
New Revision: 111139

URL: http://llvm.org/viewvc/llvm-project?rev=111139&view=rev
Log:
When caching global completion results, keep track of the simplified
type class, so that we can adjust priorities appropriately when the
preferred type for the context and the actual type of the completion
are similar.

This gets us one step closer to parity of the cached completion
results with the non-cached completion results.

Modified:
    cfe/trunk/include/clang/Frontend/ASTUnit.h
    cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
    cfe/trunk/lib/Frontend/ASTUnit.cpp
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp
    cfe/trunk/test/Index/complete-exprs.c
    cfe/trunk/test/Index/complete-macros.c

Modified: cfe/trunk/include/clang/Frontend/ASTUnit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/ASTUnit.h?rev=111139&r1=111138&r2=111139&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/ASTUnit.h (original)
+++ cfe/trunk/include/clang/Frontend/ASTUnit.h Mon Aug 16 11:18:59 2010
@@ -232,6 +232,9 @@
     /// \brief The libclang cursor kind corresponding to this code-completion 
     /// result.
     CXCursorKind Kind;
+    
+    /// \brief The simplified type class for a non-macro completion result.
+    SimplifiedTypeClass TypeClass;
   };
   
 private:

Modified: cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h?rev=111139&r1=111138&r2=111139&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h (original)
+++ cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h Mon Aug 16 11:18:59 2010
@@ -14,6 +14,7 @@
 #define LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H
 
 #include "clang/AST/Type.h"
+#include "clang/AST/CanonicalType.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "clang-c/Index.h"
@@ -72,7 +73,38 @@
   /// Objective-C object pointer types).
   CCF_SimilarTypeMatch = 2
 };
+
+/// \brief A simplified classification of types used when determining
+/// "similar" types for code completion.
+enum SimplifiedTypeClass {
+  STC_Arithmetic,
+  STC_Array,
+  STC_Block,
+  STC_Function,
+  STC_ObjectiveC,
+  STC_Other,
+  STC_Pointer,
+  STC_Record,
+  STC_Void
+};
+  
+/// \brief Determine the simplified type class of the given canonical type.
+SimplifiedTypeClass getSimplifiedTypeClass(CanQualType T);
   
+/// \brief Determine the type that this declaration will have if it is used
+/// as a type or in an expression.
+QualType getDeclUsageType(ASTContext &C, NamedDecl *ND);
+  
+/// \brief Determine the priority to be given to a macro code completion result
+/// with the given name.
+///
+/// \param MacroName The name of the macro.
+///
+/// \param PreferredTypeIsPointer Whether the preferred type for the context
+/// of this macro is a pointer type.
+unsigned getMacroUsagePriority(llvm::StringRef MacroName, 
+                               bool PreferredTypeIsPointer = false);
+                                 
 class FunctionDecl;
 class FunctionType;
 class FunctionTemplateDecl;
@@ -138,29 +170,36 @@
 private:
   enum Kind Kind;
 
+  /// \brief The type that would prefer to see at this point (e.g., the type
+  /// of an initializer or function parameter).
+  QualType PreferredType;
+  
   /// \brief The type of the base object in a member access expression.
-  QualType Type;
+  QualType BaseType;
   
 public:
   /// \brief Construct a new code-completion context of the given kind.
-  CodeCompletionContext(enum Kind Kind) : Kind(Kind) { 
-    assert(Kind != CCC_MemberAccess && "Member access requires a type");
-  }
+  CodeCompletionContext(enum Kind Kind) : Kind(Kind) { }
   
   /// \brief Construct a new code-completion context of the given kind.
-  CodeCompletionContext(enum Kind Kind, QualType T) : Kind(Kind), Type(T) { 
-    assert(Kind == CCC_MemberAccess && "Only member access has a type");
+  CodeCompletionContext(enum Kind Kind, QualType T) : Kind(Kind) { 
+    if (Kind == CCC_MemberAccess)
+      BaseType = T;
+    else
+      PreferredType = T;
   }
   
   /// \brief Retrieve the kind of code-completion context.
   enum Kind getKind() const { return Kind; }
   
+  /// \brief Retrieve the type that this expression would prefer to have, e.g.,
+  /// if the expression is a variable initializer or a function argument, the
+  /// type of the corresponding variable or function parameter.
+  QualType getPreferredType() const { return PreferredType; }
+  
   /// \brief Retrieve the type of the base object in a member-access 
   /// expression.
-  QualType getType() const { 
-    assert(Kind == CCC_MemberAccess && "Only member access has a type");
-    return Type;
-  }
+  QualType getBaseType() const { return BaseType; }
 };
 
 

Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=111139&r1=111138&r2=111139&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Mon Aug 16 11:18:59 2010
@@ -191,6 +191,10 @@
                                                         Ctx->getLangOptions());
       CachedResult.Priority = Results[I].Priority;
       CachedResult.Kind = Results[I].CursorKind;
+      CachedResult.TypeClass
+        = getSimplifiedTypeClass(
+              Ctx->getCanonicalType(getDeclUsageType(*Ctx, 
+                                                     Results[I].Declaration)));
       CachedCompletionResults.push_back(CachedResult);
       break;
     }
@@ -215,6 +219,7 @@
         | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1));
       CachedResult.Priority = Results[I].Priority;
       CachedResult.Kind = Results[I].CursorKind;
+      CachedResult.TypeClass = STC_Void;
       CachedCompletionResults.push_back(CachedResult);
       break;
     }
@@ -1417,7 +1422,24 @@
           AddedResult = true;
         }
         
-        AllResults.push_back(Result(C->Completion, C->Priority, C->Kind));
+        // Adjust priority based on similar type classes.
+        unsigned Priority = C->Priority;
+        if (!Context.getPreferredType().isNull()) {
+          if (C->Kind == CXCursor_MacroDefinition) {
+            Priority = getMacroUsagePriority(C->Completion->getTypedText(),
+                               Context.getPreferredType()->isAnyPointerType());
+          } else {
+            CanQualType Expected
+              = S.Context.getCanonicalType(Context.getPreferredType());
+            SimplifiedTypeClass ExpectedSTC = getSimplifiedTypeClass(Expected);
+            if (ExpectedSTC == C->TypeClass) {
+              // FIXME: How can we check for an exact match?
+              Priority /= CCF_SimilarTypeMatch;
+            }
+          }
+        }
+            
+        AllResults.push_back(Result(C->Completion, Priority, C->Kind));
       }
       
       // If we did not add any cached completion results, just forward the

Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=111139&r1=111138&r2=111139&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Mon Aug 16 11:18:59 2010
@@ -476,21 +476,9 @@
   return false;
 }
 
-enum SimplifiedTypeClass {
-  STC_Arithmetic,
-  STC_Array,
-  STC_Block,
-  STC_Function,
-  STC_ObjectiveC,
-  STC_Other,
-  STC_Pointer,
-  STC_Record,
-  STC_Void
-};
-
 /// \brief A simplified classification of types used to determine whether two
 /// types are "similar enough" when adjusting priorities.
-static SimplifiedTypeClass getSimplifiedTypeClass(CanQualType T) {
+SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
   switch (T->getTypeClass()) {
   case Type::Builtin:
     switch (cast<BuiltinType>(T)->getKind()) {
@@ -561,7 +549,7 @@
 
 /// \brief Get the type that a given expression will have if this declaration
 /// is used as an expression in its "typical" code-completion form.
-static QualType getDeclUsageType(ASTContext &C, NamedDecl *ND) {
+QualType clang::getDeclUsageType(ASTContext &C, NamedDecl *ND) {
   ND = cast<NamedDecl>(ND->getUnderlyingDecl());
   
   if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
@@ -2202,6 +2190,20 @@
   };
 }
 
+unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName, 
+                                      bool PreferredTypeIsPointer) {
+  unsigned Priority = CCP_Macro;
+  
+  // Treat the "nil" and "NULL" macros as null pointer constants.
+  if (MacroName.equals("nil") || MacroName.equals("NULL")) {
+    Priority = CCP_Constant;
+    if (PreferredTypeIsPointer)
+      Priority = Priority / CCF_SimilarTypeMatch;
+  }
+  
+  return Priority;
+}
+
 static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
                             bool TargetTypeIsPointer = false) {
   typedef CodeCompleteConsumer::Result Result;
@@ -2210,16 +2212,9 @@
   for (Preprocessor::macro_iterator M = PP.macro_begin(), 
                                  MEnd = PP.macro_end();
        M != MEnd; ++M) {
-    unsigned Priority = CCP_Macro;
-    
-    // Treat the "nil" and "NULL" macros as null pointer constants.
-    if (M->first->isStr("nil") || M->first->isStr("NULL")) {
-      Priority = CCP_Constant;
-      if (TargetTypeIsPointer)
-        Priority = Priority / CCF_SimilarTypeMatch;
-    }
-      
-    Results.AddResult(Result(M->first, Priority));
+    Results.AddResult(Result(M->first, 
+                             getMacroUsagePriority(M->first->getName(),
+                                                   TargetTypeIsPointer)));
   }
   Results.ExitScope();
 }
@@ -2356,7 +2351,7 @@
   if (CodeCompleter->includeMacros())
     AddMacroResults(PP, Results, PreferredTypeIsPointer);
   HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_Expression,
+                CodeCompletionContext(CodeCompletionContext::CCC_Expression, T),
                             Results.data(),Results.size());
 }
 

Modified: cfe/trunk/test/Index/complete-exprs.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-exprs.c?rev=111139&r1=111138&r2=111139&view=diff
==============================================================================
--- cfe/trunk/test/Index/complete-exprs.c (original)
+++ cfe/trunk/test/Index/complete-exprs.c Mon Aug 16 11:18:59 2010
@@ -23,7 +23,7 @@
 // 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: FunctionDecl:{ResultType int}{TypedText f}{LeftParen (}{Placeholder int}{RightParen )} (25)
 // 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

Modified: cfe/trunk/test/Index/complete-macros.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-macros.c?rev=111139&r1=111138&r2=111139&view=diff
==============================================================================
--- cfe/trunk/test/Index/complete-macros.c (original)
+++ cfe/trunk/test/Index/complete-macros.c Mon Aug 16 11:18:59 2010
@@ -20,6 +20,8 @@
 // CHECK-CC1: macro definition:{TypedText FOO}{LeftParen (}{Placeholder Arg1}{Comma , }{Placeholder Arg2}{RightParen )}
 // RUN: c-index-test -code-completion-at=%s:13:13 %s | FileCheck -check-prefix=CHECK-CC2 %s
 // RUN: c-index-test -code-completion-at=%s:14:8 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:14:8 %s | FileCheck -check-prefix=CHECK-CC2 %s
 // CHECK-CC2: macro definition:{TypedText nil} (30)
 // RUN: c-index-test -code-completion-at=%s:15:5 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:15:5 %s | FileCheck -check-prefix=CHECK-CC3 %s
 // CHECK-CC3: macro definition:{TypedText nil} (60)





More information about the cfe-commits mailing list