[clang-tools-extra] b5871df - [clangd] Refactor forwarding call detection logic

Kadir Cetinkaya via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 21 09:05:26 PDT 2022


Author: Kadir Cetinkaya
Date: 2022-07-21T17:58:56+02:00
New Revision: b5871dfaf31873e6172f8a3fcd1e01e54498c811

URL: https://github.com/llvm/llvm-project/commit/b5871dfaf31873e6172f8a3fcd1e01e54498c811
DIFF: https://github.com/llvm/llvm-project/commit/b5871dfaf31873e6172f8a3fcd1e01e54498c811.diff

LOG: [clangd] Refactor forwarding call detection logic

Differential Revision: https://reviews.llvm.org/D130261

Added: 
    

Modified: 
    clang-tools-extra/clangd/AST.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/AST.cpp b/clang-tools-extra/clangd/AST.cpp
index 53adf230beae..44c6f49f55c2 100644
--- a/clang-tools-extra/clangd/AST.cpp
+++ b/clang-tools-extra/clangd/AST.cpp
@@ -791,51 +791,46 @@ class ForwardingCallVisitor
         })) {
       return;
     }
-    auto OptPackLocation = findPack(Args);
-    if (OptPackLocation) {
-      size_t PackLocation = OptPackLocation.value();
-      ArrayRef<ParmVarDecl *> MatchingParams =
-          Callee->parameters().slice(PackLocation, Parameters.size());
-      // Check whether the function has a parameter pack as the last template
-      // parameter
-      if (const auto *TTPT = getFunctionPackType(Callee)) {
-        // In this case: Separate the parameters into head, pack and tail
-        auto IsExpandedPack = [&](const ParmVarDecl *P) {
-          return getUnderylingPackType(P) == TTPT;
-        };
-        ForwardingInfo FI;
-        FI.Head = MatchingParams.take_until(IsExpandedPack);
-        FI.Pack = MatchingParams.drop_front(FI.Head.size())
-                      .take_while(IsExpandedPack);
-        FI.Tail = MatchingParams.drop_front(FI.Head.size() + FI.Pack.size());
-        FI.PackTarget = Callee;
-        Info = FI;
-        return;
-      }
-      // Default case: assume all parameters were fully resolved
+    auto PackLocation = findPack(Args);
+    if (!PackLocation)
+      return;
+    ArrayRef<ParmVarDecl *> MatchingParams =
+        Callee->parameters().slice(*PackLocation, Parameters.size());
+    // Check whether the function has a parameter pack as the last template
+    // parameter
+    if (const auto *TTPT = getFunctionPackType(Callee)) {
+      // In this case: Separate the parameters into head, pack and tail
+      auto IsExpandedPack = [&](const ParmVarDecl *P) {
+        return getUnderylingPackType(P) == TTPT;
+      };
       ForwardingInfo FI;
-      FI.Head = MatchingParams;
+      FI.Head = MatchingParams.take_until(IsExpandedPack);
+      FI.Pack =
+          MatchingParams.drop_front(FI.Head.size()).take_while(IsExpandedPack);
+      FI.Tail = MatchingParams.drop_front(FI.Head.size() + FI.Pack.size());
+      FI.PackTarget = Callee;
       Info = FI;
+      return;
     }
+    // Default case: assume all parameters were fully resolved
+    ForwardingInfo FI;
+    FI.Head = MatchingParams;
+    Info = FI;
   }
 
   // Returns the beginning of the expanded pack represented by Parameters
   // in the given arguments, if it is there.
   llvm::Optional<size_t> findPack(typename CallExpr::arg_range Args) {
     // find the argument directly referring to the first parameter
-    auto FirstMatch = std::find_if(Args.begin(), Args.end(), [&](Expr *Arg) {
-      const auto *RefArg = unwrapArgument(Arg);
-      if (RefArg) {
-        if (Parameters.front() == dyn_cast<ParmVarDecl>(RefArg->getDecl())) {
-          return true;
-        }
+    for (auto It = Args.begin(); It != Args.end(); ++It) {
+      const Expr *Arg = *It;
+      if (const auto *RefArg = unwrapForward(Arg)) {
+        if (Parameters.front() != RefArg->getDecl())
+          continue;
+        return std::distance(Args.begin(), It);
       }
-      return false;
-    });
-    if (FirstMatch == Args.end()) {
-      return llvm::None;
     }
-    return std::distance(Args.begin(), FirstMatch);
+    return llvm::None;
   }
 
   static FunctionDecl *getCalleeDeclOrUniqueOverload(CallExpr *E) {
@@ -847,7 +842,7 @@ class ForwardingCallVisitor
       }
     }
     // Ignore the callee if the number of arguments is wrong (deal with va_args)
-    if (Callee->getNumParams() == E->getNumArgs())
+    if (Callee && Callee->getNumParams() == E->getNumArgs())
       return Callee;
     return nullptr;
   }
@@ -873,31 +868,17 @@ class ForwardingCallVisitor
     return MatchingDecl;
   }
 
-  // Removes any implicit cast expressions around the given expression.
-  static const Expr *unwrapImplicitCast(const Expr *E) {
-    while (const auto *Cast = dyn_cast<ImplicitCastExpr>(E)) {
-      E = Cast->getSubExpr();
-    }
-    return E;
-  }
-
-  // Maps std::forward(E) to E, nullptr otherwise
-  static const Expr *unwrapForward(const Expr *E) {
+  // Tries to get to the underlying argument by unwrapping implicit nodes and
+  // std::forward.
+  static const DeclRefExpr *unwrapForward(const Expr *E) {
+    E = E->IgnoreImplicitAsWritten();
     if (const auto *Call = dyn_cast<CallExpr>(E)) {
       const auto Callee = Call->getBuiltinCallee();
       if (Callee == Builtin::BIforward) {
-        return Call->getArg(0);
+        return dyn_cast<DeclRefExpr>(
+            Call->getArg(0)->IgnoreImplicitAsWritten());
       }
     }
-    return E;
-  }
-
-  // Maps std::forward(DeclRefExpr) to DeclRefExpr, removing any intermediate
-  // implicit casts, nullptr otherwise
-  static const DeclRefExpr *unwrapArgument(const Expr *E) {
-    E = unwrapImplicitCast(E);
-    E = unwrapForward(E);
-    E = unwrapImplicitCast(E);
     return dyn_cast<DeclRefExpr>(E);
   }
 };


        


More information about the cfe-commits mailing list