[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