[PATCH] Implementation for completion in call context for C++

Manuel Klimek klimek at google.com
Tue Jan 20 04:39:25 PST 2015


================
Comment at: include/clang/Sema/Sema.h:8775-8776
@@ -8766,1 +8774,4 @@
 
+bool TooManyArguments(size_t NumParams, size_t NumArgs,
+                      bool PartialOverloading = false);
+
----------------
Ok, after thinking about it for a bit, I believe we should put this into Sema (and add a comment).

================
Comment at: lib/Sema/SemaCodeComplete.cpp:3843-3844
@@ +3842,4 @@
+
+QualType getThisParamType(Sema &S, ArrayRef<ResultCandidate> Results,
+                          ArrayRef<Expr *> Args) {
+  QualType ParamType;
----------------
I think the names are a bit off, we need a comment, and slightly modify the function (the Args array is not used for anything but the size).
How about:

// Get the type of the Nth parameter from a given candidate set.
// Given the overloads 'Candidates' for a function call matching all arguments up to
// N, return the type of the Nth parameter if it is the same for all overload candidates.
// Otherwise return a default-constructed QualType.
QualType getParamType(Sema &S, ArrayRef<ResultCandidate> Candidates, int N)

================
Comment at: lib/Sema/SemaCodeComplete.cpp:3893-3896
@@ +3892,6 @@
+  else if (auto UME = dyn_cast<UnresolvedMemberExpr>(NakedFn)) {
+    TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = nullptr;
+    if (UME->hasExplicitTemplateArgs()) {
+      UME->copyTemplateArgumentsInto(TemplateArgsBuffer);
+      TemplateArgs = &TemplateArgsBuffer;
+    }
----------------
I now understand the need for copying, but not why you need an extra variable for the pointer instead of just passing &TemplateArgsBuffer below.

================
Comment at: lib/Sema/SemaCodeComplete.cpp:3942-3953
@@ -3868,51 +3941,14 @@
+
   QualType ParamType;
-  
-  if (!CandidateSet.empty()) {
-    // Sort the overload candidate set by placing the best overloads first.
-    std::stable_sort(
-        CandidateSet.begin(), CandidateSet.end(),
-        [&](const OverloadCandidate &X, const OverloadCandidate &Y) {
-          return isBetterOverloadCandidate(*this, X, Y, Loc);
-        });
+  if (!CandidateSet.empty())
+    ParamType = getThisParamType(*this, Results, Args);
 
-    // Add the remaining viable overload candidates as code-completion reslults.
-    for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
-                                     CandEnd = CandidateSet.end();
-         Cand != CandEnd; ++Cand) {
-      if (Cand->Viable)
-        Results.push_back(ResultCandidate(Cand->Function));
-    }
-
-    // From the viable candidates, try to determine the type of this parameter.
-    for (unsigned I = 0, N = Results.size(); I != N; ++I) {
-      if (const FunctionType *FType = Results[I].getFunctionType())
-        if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
-          if (Args.size() < Proto->getNumParams()) {
-            if (ParamType.isNull())
-              ParamType = Proto->getParamType(Args.size());
-            else if (!Context.hasSameUnqualifiedType(
-                          ParamType.getNonReferenceType(),
-                          Proto->getParamType(Args.size())
-                              .getNonReferenceType())) {
-              ParamType = QualType();
-              break;
-            }
-          }
-    }
-  } else {
-    // Try to determine the parameter type from the type of the expression
-    // being called.
-    QualType FunctionType = Fn->getType();
-    if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
-      FunctionType = Ptr->getPointeeType();
-    else if (const BlockPointerType *BlockPtr
-                                    = FunctionType->getAs<BlockPointerType>())
-      FunctionType = BlockPtr->getPointeeType();
-    else if (const MemberPointerType *MemPtr
-                                    = FunctionType->getAs<MemberPointerType>())
-      FunctionType = MemPtr->getPointeeType();
-    
-    if (const FunctionProtoType *Proto
-                                  = FunctionType->getAs<FunctionProtoType>()) {
-      if (Args.size() < Proto->getNumParams())
-        ParamType = Proto->getParamType(Args.size());
+  if (ParamType.isNull())
+    CodeCompleteOrdinaryName(S, PCC_Expression);
+  else
+    CodeCompleteExpression(S, ParamType);
+
+  if (!Results.empty())
+    CodeCompleter->ProcessOverloadCandidates(*this, Args.size(), Results.data(),
+                                             Results.size());
+}
----------------
This seems to also be pretty much the same as in the function below; I'd pull out a function for that, too.

================
Comment at: lib/Sema/SemaCodeComplete.cpp:3961-3963
@@ +3960,5 @@
+
+  // A complete type is needed to lookup for constructors
+  if(RequireCompleteType(Loc, Type, 0))
+    return;
+
----------------
Space after 'if'; generally, use clang-format with -style=LLVM

================
Comment at: lib/Sema/SemaCodeComplete.cpp:3966
@@ +3965,3 @@
+  // FIXME: Provide support for variadic template constructors.
+  // FIXME: Provide support for highlighting what parameters are optional.
+
----------------
perhaps "highlighting optional parameters"?

http://reviews.llvm.org/D6880

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/






More information about the cfe-commits mailing list