kadircet created this revision.
kadircet added reviewers: sammccall, ilya-biryukov, ioeric.
Herald added a subscriber: cfe-commits.

Factors out member decleration gathering and uses it in parsing to call 
signature
help. Doesn't support signature help for base class constructors, the code was 
too
coupled with diagnostic handling, but still can be factored out but just needs
more afford.


Repository:
  rC Clang

https://reviews.llvm.org/D51917

Files:
  include/clang/Sema/Sema.h
  lib/Parse/ParseDeclCXX.cpp
  lib/Sema/SemaDeclCXX.cpp
  test/CodeCompletion/ctor-initializer.cpp

Index: test/CodeCompletion/ctor-initializer.cpp
===================================================================
--- test/CodeCompletion/ctor-initializer.cpp
+++ test/CodeCompletion/ctor-initializer.cpp
@@ -64,3 +64,26 @@
   // CHECK-CC8: COMPLETION: Pattern : member2(<#args#>
   int member1, member2;
 };
+
+struct Base2 {
+  Base2(int);
+};
+
+struct Composition1 {
+  Composition1() : b2_elem() {}
+  // RUN: %clang_cc1 -fsyntax-only -std=c++98 -code-completion-at=%s:73:28 %s -o - | FileCheck -check-prefix=CHECK-CC9 %s
+  // RUN: %clang_cc1 -fsyntax-only -std=c++14 -code-completion-at=%s:73:28 %s -o - | FileCheck -check-prefix=CHECK-CC9 %s
+  // CHECK-CC9: OVERLOAD: Base2(<#int#>)
+  // CHECK-CC9: OVERLOAD: Base2(<#const Base2 &#>)
+  Composition1(Base2);
+  Base2 b2_elem;
+};
+
+struct Composition2 {
+  Composition2() : c1_elem(Base2(1)) {}
+  // RUN: %clang_cc1 -fsyntax-only -std=c++98 -code-completion-at=%s:83:34 %s -o - | FileCheck -check-prefix=CHECK-CC9 %s
+  // RUN: %clang_cc1 -fsyntax-only -std=c++14 -code-completion-at=%s:83:34 %s -o - | FileCheck -check-prefix=CHECK-CC9 %s
+  // RUN: %clang_cc1 -fsyntax-only -std=c++98 -code-completion-at=%s:83:35 %s -o - | FileCheck -check-prefix=CHECK-CC9 %s
+  // RUN: %clang_cc1 -fsyntax-only -std=c++14 -code-completion-at=%s:83:35 %s -o - | FileCheck -check-prefix=CHECK-CC9 %s
+  Composition1 c1_elem;
+};
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -3777,6 +3777,23 @@
 
 }
 
+ValueDecl *clang::tryGetMember(CXXRecordDecl *ClassDecl, CXXScopeSpec &SS,
+                        ParsedType TemplateTypeTy,
+                        IdentifierInfo *MemberOrBase) {
+  if (!SS.getScopeRep() && !TemplateTypeTy) {
+    // Look for a member, first.
+    DeclContext::lookup_result Result = ClassDecl->lookup(MemberOrBase);
+    if (!Result.empty()) {
+      ValueDecl *Member;
+      if ((Member = dyn_cast<FieldDecl>(Result.front())) ||
+          (Member = dyn_cast<IndirectFieldDecl>(Result.front()))) {
+        return Member;
+      }
+    }
+  }
+  return nullptr;
+}
+
 /// Handle a C++ member initializer.
 MemInitResult
 Sema::BuildMemInitializer(Decl *ConstructorD,
@@ -3820,21 +3837,14 @@
   //   of a single identifier refers to the class member. A
   //   mem-initializer-id for the hidden base class may be specified
   //   using a qualified name. ]
-  if (!SS.getScopeRep() && !TemplateTypeTy) {
-    // Look for a member, first.
-    DeclContext::lookup_result Result = ClassDecl->lookup(MemberOrBase);
-    if (!Result.empty()) {
-      ValueDecl *Member;
-      if ((Member = dyn_cast<FieldDecl>(Result.front())) ||
-          (Member = dyn_cast<IndirectFieldDecl>(Result.front()))) {
-        if (EllipsisLoc.isValid())
-          Diag(EllipsisLoc, diag::err_pack_expansion_member_init)
-            << MemberOrBase
-            << SourceRange(IdLoc, Init->getSourceRange().getEnd());
-
-        return BuildMemberInitializer(Member, Init, IdLoc);
-      }
-    }
+  if (ValueDecl *Member =
+          tryGetMember(ClassDecl, SS, TemplateTypeTy, MemberOrBase)) {
+    if (EllipsisLoc.isValid())
+      Diag(EllipsisLoc, diag::err_pack_expansion_member_init)
+          << MemberOrBase
+          << SourceRange(IdLoc, Init->getSourceRange().getEnd());
+
+    return BuildMemberInitializer(Member, Init, IdLoc);
   }
   // It didn't name a member, so see if it names a class.
   QualType BaseType;
Index: lib/Parse/ParseDeclCXX.cpp
===================================================================
--- lib/Parse/ParseDeclCXX.cpp
+++ lib/Parse/ParseDeclCXX.cpp
@@ -3449,6 +3449,7 @@
   if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
     Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
 
+    // FIXME: Add support for signature help inside initializer lists.
     ExprResult InitList = ParseBraceInitializer();
     if (InitList.isInvalid())
       return true;
@@ -3466,7 +3467,26 @@
     // Parse the optional expression-list.
     ExprVector ArgExprs;
     CommaLocsTy CommaLocs;
-    if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) {
+    auto SignatureHelpCaller = [&] {
+      if (CalledSignatureHelp)
+        return;
+      CXXConstructorDecl *Constructor =
+          dyn_cast<CXXConstructorDecl>(ConstructorDecl);
+      if (!Constructor)
+        return;
+      // FIXME: Add support for Base class constructors as well.
+      if (ValueDecl *MemberDecl =
+              tryGetMember(Constructor->getParent(), SS, TemplateTypeTy, II)) {
+        Actions.ProduceConstructorSignatureHelp(
+            getCurScope(), MemberDecl->getType(), MemberDecl->getLocation(),
+            ArgExprs, T.getOpenLocation());
+        CalledSignatureHelp = true;
+      }
+    };
+    if (Tok.isNot(tok::r_paren) &&
+        ParseExpressionList(ArgExprs, CommaLocs, SignatureHelpCaller)) {
+      if (PP.isCodeCompletionReached())
+        SignatureHelpCaller();
       SkipUntil(tok::r_paren, StopAtSemi);
       return true;
     }
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -10795,6 +10795,9 @@
   Decl *D;
 };
 
+ValueDecl *tryGetMember(CXXRecordDecl *ClassDecl, CXXScopeSpec &SS,
+                        ParsedType TemplateTypeTy,
+                        IdentifierInfo *MemberOrBase);
 } // end namespace clang
 
 namespace llvm {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to