[cfe-commits] r112330 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Parse/ParseDeclCXX.cpp lib/Sema/SemaCodeComplete.cpp

Douglas Gregor dgregor at apple.com
Fri Aug 27 17:00:51 PDT 2010


Author: dgregor
Date: Fri Aug 27 19:00:50 2010
New Revision: 112330

URL: http://llvm.org/viewvc/llvm-project?rev=112330&view=rev
Log:
Basic code completion support for the base and member initializers in
a constructor.

Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=112330&r1=112329&r2=112330&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Aug 27 19:00:50 2010
@@ -4348,7 +4348,10 @@
   virtual void CodeCompleteNamespaceDecl(Scope *S);
   virtual void CodeCompleteNamespaceAliasDecl(Scope *S);
   virtual void CodeCompleteOperatorName(Scope *S);
-
+  virtual void CodeCompleteConstructorInitializer(Decl *Constructor,
+                                    CXXBaseOrMemberInitializer** Initializers,
+                                                  unsigned NumInitializers);
+  
   virtual void CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
                                            bool InInterface);
   virtual void CodeCompleteObjCAtVisibility(Scope *S);

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=112330&r1=112329&r2=112330&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Fri Aug 27 19:00:50 2010
@@ -1714,12 +1714,19 @@
   bool AnyErrors = false;
 
   do {
-    MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);
-    if (!MemInit.isInvalid())
-      MemInitializers.push_back(MemInit.get());
-    else
-      AnyErrors = true;
-
+    if (Tok.is(tok::code_completion)) {
+      Actions.CodeCompleteConstructorInitializer(ConstructorDecl, 
+                                                 MemInitializers.data(), 
+                                                 MemInitializers.size());
+      ConsumeCodeCompletionToken();
+    } else {
+      MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);
+      if (!MemInit.isInvalid())
+        MemInitializers.push_back(MemInit.get());
+      else
+        AnyErrors = true;
+    }
+    
     if (Tok.is(tok::comma))
       ConsumeToken();
     else if (Tok.is(tok::l_brace))

Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=112330&r1=112329&r2=112330&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Fri Aug 27 19:00:50 2010
@@ -3267,6 +3267,86 @@
                             Results.data(),Results.size());
 }
 
+void Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD,
+                                    CXXBaseOrMemberInitializer** Initializers,
+                                              unsigned NumInitializers) {
+  CXXConstructorDecl *Constructor
+    = static_cast<CXXConstructorDecl *>(ConstructorD);
+  if (!Constructor)
+    return;
+  
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+  
+  // Fill in any already-initialized fields or base classes.
+  llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
+  llvm::SmallPtrSet<CanQualType, 4> InitializedBases;
+  for (unsigned I = 0; I != NumInitializers; ++I) {
+    if (Initializers[I]->isBaseInitializer())
+      InitializedBases.insert(
+        Context.getCanonicalType(QualType(Initializers[I]->getBaseClass(), 0)));
+    else
+      InitializedFields.insert(cast<FieldDecl>(Initializers[I]->getMember()));
+  }
+  
+  // Add completions for base classes.
+  unsigned Priority = 1;
+  CXXRecordDecl *ClassDecl = Constructor->getParent();
+  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
+                                       BaseEnd = ClassDecl->bases_end();
+       Base != BaseEnd; ++Base) {
+    if (!InitializedBases.insert(Context.getCanonicalType(Base->getType())))
+      continue;
+    
+    CodeCompletionString *Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk(
+                           Base->getType().getAsString(Context.PrintingPolicy));
+    Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+    Pattern->AddPlaceholderChunk("args");
+    Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+    Results.AddResult(CodeCompletionResult(Pattern, Priority++));
+  }
+  
+  // Add completions for virtual base classes.
+  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
+                                       BaseEnd = ClassDecl->vbases_end();
+       Base != BaseEnd; ++Base) {
+    if (!InitializedBases.insert(Context.getCanonicalType(Base->getType())))
+      continue;
+    
+    CodeCompletionString *Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk(
+                           Base->getType().getAsString(Context.PrintingPolicy));
+    Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+    Pattern->AddPlaceholderChunk("args");
+    Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+    Results.AddResult(CodeCompletionResult(Pattern, Priority++));
+  }
+  
+  // Add completions for members.
+  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+                                  FieldEnd = ClassDecl->field_end();
+       Field != FieldEnd; ++Field) {
+    if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl())))
+      continue;
+    
+    if (!Field->getDeclName())
+      continue;
+    
+    CodeCompletionString *Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk(Field->getIdentifier()->getName());
+    Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+    Pattern->AddPlaceholderChunk("args");
+    Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+    Results.AddResult(CodeCompletionResult(Pattern, Priority++));
+  }
+  Results.ExitScope();
+  
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Name,
+                            Results.data(), Results.size());
+}
+
 // Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
 // true or false.
 #define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword





More information about the cfe-commits mailing list