[cfe-dev] AST matcher: ForEach FunctionDecl -> ParmVarDecl
Stephen Kelly via cfe-dev
cfe-dev at lists.llvm.org
Sun Dec 30 06:41:31 PST 2018
On 30/12/2018 14:00, FarSight Studios via cfe-dev wrote:
> I am trying to match call expressions where the caller arguments are the
> parameters of another, outer function.
You need to write your own matcher.
These untested/uncompiled snippets should get you started:
bool callArgsAreFuncParams(CallExpr const& C, FunctionDecl const& F)
{
// TODO: Handle variadic args
// TODO: Handle default arguments in call
if (C.argumentCount() != F.parameterCount())
return false;
for (auto i = 0; i < C.argumentCount(); ++i)
{
if (C.getArg(i).getDecl() != F.getParameter(i))
return false;
}
return true;
}
AST_MATCHER(CallExpr, forwardsAllParameters) {
const auto &Parents = Finder->getASTContext().getParents(Node, true);
llvm::SmallVector<ast_type_traits::DynTypedNode, 8>
Stack(Parents.begin(),
Parents.end());
while(!Stack.empty()) {
const auto &CurNode = Stack.back();
Stack.pop_back();
if(const auto *FuncDeclNode = CurNode.get<FunctionDecl>()) {
if (callArgsAreFuncParams(Node, *FuncDeclNode))
return true;
} else if(const auto *LambdaExprNode = CurNode.get<LambdaExpr>()) {
if (callArgsAreFuncParams(Node, *LambdaExprNode->getCallOperator()))
return true;
} else {
for (const auto &Parent :
Finder->getASTContext().getParents(CurNode, true))
Stack.push_back(Parent);
}
}
return false;
}
auto fullMatcher = callExpr(
forwardsAllParameters(),
forFunction(functionDecl().bind("outerFunction"))
).bind("innerCall")
It would also be possible to design the matcher such that it is used
like this:
forwardsAllParametersFrom(functionDecl().bind("outerFunction"))
That's left as an exercise for the reader.
Thanks,
Stephen.
More information about the cfe-dev
mailing list