[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