Qwinci created this revision.
Herald added subscribers: usaxena95, kadircet, arphaman.
Herald added a project: All.
Qwinci requested review of this revision.
Herald added projects: clang, clang-tools-extra.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D125120

Files:
  clang-tools-extra/clangd/CodeComplete.cpp
  clang/include/clang/Sema/CodeCompleteConsumer.h
  clang/lib/Sema/CodeCompleteConsumer.cpp
  clang/lib/Sema/SemaCodeComplete.cpp

Index: clang/lib/Sema/SemaCodeComplete.cpp
===================================================================
--- clang/lib/Sema/SemaCodeComplete.cpp
+++ clang/lib/Sema/SemaCodeComplete.cpp
@@ -3722,6 +3722,7 @@
                                        const PrintingPolicy &Policy,
                                        const FunctionDecl *Function,
                                        const FunctionProtoType *Prototype,
+                                       FunctionProtoTypeLoc PrototypeLoc,
                                        CodeCompletionBuilder &Result,
                                        unsigned CurrentArg, unsigned Start = 0,
                                        bool InOptional = false) {
@@ -3743,7 +3744,7 @@
       if (!FirstParameter)
         Opt.AddChunk(CodeCompletionString::CK_Comma);
       // Optional sections are nested.
-      AddOverloadParameterChunks(Context, Policy, Function, Prototype, Opt,
+      AddOverloadParameterChunks(Context, Policy, Function, Prototype, PrototypeLoc, Opt,
                                  CurrentArg, P, /*InOptional=*/true);
       Result.AddOptionalChunk(Opt.TakeString());
       return;
@@ -3764,6 +3765,14 @@
       if (Param->hasDefaultArg())
         Placeholder += GetDefaultValueString(Param, Context.getSourceManager(),
                                              Context.getLangOpts());
+    } else if (!PrototypeLoc.isNull()) {
+      if (P < PrototypeLoc.getNumParams()) {
+        const ParmVarDecl *Param = PrototypeLoc.getParam(P);
+        Placeholder = FormatFunctionParameter(Policy, Param);
+        if (Param->hasDefaultArg())
+          Placeholder += GetDefaultValueString(Param, Context.getSourceManager(),
+                                            Context.getLangOpts());
+      }
     } else {
       Placeholder = Prototype->getParamType(P).getAsString(Policy);
     }
@@ -3912,7 +3921,7 @@
   if (getKind() == CK_Aggregate)
     AddOverloadAggregateChunks(getAggregate(), Policy, Result, CurrentArg);
   else
-    AddOverloadParameterChunks(S.getASTContext(), Policy, FDecl, Proto, Result,
+    AddOverloadParameterChunks(S.getASTContext(), Policy, FDecl, Proto, ProtoTypeLoc, Result,
                                CurrentArg);
   Result.AddChunk(Braced ? CodeCompletionString::CK_RightBrace
                          : CodeCompletionString::CK_RightParen);
@@ -5991,6 +6000,16 @@
   return getParamType(SemaRef, Candidates, CurrentArg);
 }
 
+static FunctionProtoTypeLoc GetPrototypeLoc(Expr *Fn) {
+  if (const auto *T = Fn->getType().getTypePtr()->getAs<TypedefType>()) {
+    const auto *D = T->getDecl();
+    if (auto F = D->getTypeSourceInfo()->getTypeLoc().getAs<FunctionProtoTypeLoc>()) {
+      return F;
+    }
+  }
+  return FunctionProtoTypeLoc();
+}
+
 QualType Sema::ProduceCallSignatureHelp(Expr *Fn, ArrayRef<Expr *> Args,
                                         SourceLocation OpenParLoc) {
   Fn = unwrapParenList(Fn);
@@ -6072,6 +6091,8 @@
     } else {
       // Lastly we check whether expression's type is function pointer or
       // function.
+
+      FunctionProtoTypeLoc P = GetPrototypeLoc(NakedFn);
       QualType T = NakedFn->getType();
       if (!T->getPointeeType().isNull())
         T = T->getPointeeType();
@@ -6080,8 +6101,13 @@
         if (!TooManyArguments(FP->getNumParams(),
                               ArgsWithoutDependentTypes.size(),
                               /*PartialOverloading=*/true) ||
-            FP->isVariadic())
-          Results.push_back(ResultCandidate(FP));
+            FP->isVariadic()) {
+              if (!P.isNull()) {
+                Results.push_back(ResultCandidate(P));
+              } else {
+                Results.push_back(ResultCandidate(FP));
+              }
+            }
       } else if (auto FT = T->getAs<FunctionType>())
         // No prototype and declaration, it may be a K & R style function.
         Results.push_back(ResultCandidate(FT));
Index: clang/lib/Sema/CodeCompleteConsumer.cpp
===================================================================
--- clang/lib/Sema/CodeCompleteConsumer.cpp
+++ clang/lib/Sema/CodeCompleteConsumer.cpp
@@ -506,7 +506,8 @@
 
   case CK_FunctionType:
     return Type;
-
+  case CK_FunctionProtoTypeLoc:
+    return ProtoTypeLoc.getTypePtr();
   case CK_Template:
   case CK_Aggregate:
     return nullptr;
@@ -515,6 +516,12 @@
   llvm_unreachable("Invalid CandidateKind!");
 }
 
+ const FunctionProtoTypeLoc CodeCompleteConsumer::OverloadCandidate::getFunctionProtoTypeLoc() const {
+   if (Kind == CK_FunctionProtoTypeLoc)
+     return ProtoTypeLoc;
+   return FunctionProtoTypeLoc();
+ }
+
 unsigned CodeCompleteConsumer::OverloadCandidate::getNumParams() const {
   if (Kind == CK_Template)
     return Template->getTemplateParameters()->size();
@@ -530,6 +537,9 @@
   if (const auto *FT = getFunctionType())
     if (const auto *FPT = dyn_cast<FunctionProtoType>(FT))
       return FPT->getNumParams();
+  if (!ProtoTypeLoc.isNull()) {
+    return ProtoTypeLoc.getNumParams();
+  }
 
   return 0;
 }
@@ -589,6 +599,12 @@
     if (N < FD->param_size())
       return FD->getParamDecl(N);
   }
+  else if (!ProtoTypeLoc.isNull()) {
+    if (N < ProtoTypeLoc.getNumParams()) {
+      return ProtoTypeLoc.getParam(N);
+    }
+  }
+
   return nullptr;
 }
 
Index: clang/include/clang/Sema/CodeCompleteConsumer.h
===================================================================
--- clang/include/clang/Sema/CodeCompleteConsumer.h
+++ clang/include/clang/Sema/CodeCompleteConsumer.h
@@ -1016,6 +1016,8 @@
       /// for which we only have a function prototype.
       CK_FunctionType,
 
+      CK_FunctionProtoTypeLoc,
+
       /// The candidate is a template, template arguments are being completed.
       CK_Template,
 
@@ -1040,6 +1042,8 @@
       /// when Kind == CK_FunctionType.
       const FunctionType *Type;
 
+      FunctionProtoTypeLoc ProtoTypeLoc;
+
       /// The template overload candidate, available when
       /// Kind == CK_Template.
       const TemplateDecl *Template;
@@ -1065,6 +1069,11 @@
       assert(Type != nullptr);
     }
 
+    OverloadCandidate(FunctionProtoTypeLoc Prototype)
+        : Kind(CK_FunctionProtoTypeLoc), ProtoTypeLoc(Prototype) {
+          
+        }
+
     OverloadCandidate(const RecordDecl *Aggregate)
         : Kind(CK_Aggregate), AggregateType(Aggregate) {
       assert(Aggregate != nullptr);
@@ -1090,6 +1099,9 @@
     /// function is stored.
     const FunctionType *getFunctionType() const;
 
+    /// Retrieve the function ProtoTypeLoc candidate.
+    const FunctionProtoTypeLoc getFunctionProtoTypeLoc() const;
+
     const TemplateDecl *getTemplate() const {
       assert(getKind() == CK_Template && "Not a template");
       return Template;
Index: clang-tools-extra/clangd/CodeComplete.cpp
===================================================================
--- clang-tools-extra/clangd/CodeComplete.cpp
+++ clang-tools-extra/clangd/CodeComplete.cpp
@@ -942,6 +942,7 @@
 
     for (unsigned I = 0; I < NumCandidates; ++I) {
       OverloadCandidate Candidate = Candidates[I];
+
       // We want to avoid showing instantiated signatures, because they may be
       // long in some cases (e.g. when 'T' is substituted with 'std::string', we
       // would get 'std::basic_string<char>').
@@ -1007,10 +1008,12 @@
         auto KindPriority = [&](OC::CandidateKind K) {
           switch (K) {
           case OC::CK_Aggregate:
-            return 1;
+            return 0;
           case OC::CK_Function:
-            return 2;
+            return 1;
           case OC::CK_FunctionType:
+            return 2;
+          case OC::CK_FunctionProtoTypeLoc:
             return 3;
           case OC::CK_FunctionTemplate:
             return 4;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to