20
20
#include " clang/AST/Stmt.h"
21
21
#include " clang/AST/StmtVisitor.h"
22
22
#include " clang/AST/Type.h"
23
+ #include " clang/ASTMatchers/LowLevelHelpers.h"
23
24
#include " clang/Basic/SourceLocation.h"
24
25
#include " clang/Lex/Lexer.h"
25
26
#include " clang/Lex/Preprocessor.h"
@@ -300,98 +301,6 @@ static void findStmtsInUnspecifiedLvalueContext(
300
301
OnResult (BO->getLHS ());
301
302
}
302
303
303
- // / Note: Copied and modified from ASTMatchers.
304
- // / Matches all arguments and their respective types for a \c CallExpr.
305
- // / It is very similar to \c forEachArgumentWithParam but
306
- // / it works on calls through function pointers as well.
307
- // /
308
- // / The difference is, that function pointers do not provide access to a
309
- // / \c ParmVarDecl, but only the \c QualType for each argument.
310
- // /
311
- // / Given
312
- // / \code
313
- // / void f(int i);
314
- // / int y;
315
- // / f(y);
316
- // / void (*f_ptr)(int) = f;
317
- // / f_ptr(y);
318
- // / \endcode
319
- // / callExpr(
320
- // / forEachArgumentWithParamType(
321
- // / declRefExpr(to(varDecl(hasName("y")))),
322
- // / qualType(isInteger()).bind("type)
323
- // / ))
324
- // / matches f(y) and f_ptr(y)
325
- // / with declRefExpr(...)
326
- // / matching int y
327
- // / and qualType(...)
328
- // / matching int
329
- static void forEachArgumentWithParamType (
330
- const CallExpr &Node,
331
- const llvm::function_ref<void (QualType /* Param*/ , const Expr * /* Arg*/ )>
332
- OnParamAndArg) {
333
- // The first argument of an overloaded member operator is the implicit object
334
- // argument of the method which should not be matched against a parameter, so
335
- // we skip over it here.
336
- unsigned ArgIndex = 0 ;
337
- if (const auto *CE = dyn_cast<CXXOperatorCallExpr>(&Node)) {
338
- const auto *MD = dyn_cast_or_null<CXXMethodDecl>(CE->getDirectCallee ());
339
- if (MD && !MD->isExplicitObjectMemberFunction ()) {
340
- // This is an overloaded operator call.
341
- // We need to skip the first argument, which is the implicit object
342
- // argument of the method which should not be matched against a
343
- // parameter.
344
- ++ArgIndex;
345
- }
346
- }
347
-
348
- const FunctionProtoType *FProto = nullptr ;
349
-
350
- if (const auto *Call = dyn_cast<CallExpr>(&Node)) {
351
- if (const auto *Value =
352
- dyn_cast_or_null<ValueDecl>(Call->getCalleeDecl ())) {
353
- QualType QT = Value->getType ().getCanonicalType ();
354
-
355
- // This does not necessarily lead to a `FunctionProtoType`,
356
- // e.g. K&R functions do not have a function prototype.
357
- if (QT->isFunctionPointerType ())
358
- FProto = QT->getPointeeType ()->getAs <FunctionProtoType>();
359
-
360
- if (QT->isMemberFunctionPointerType ()) {
361
- const auto *MP = QT->getAs <MemberPointerType>();
362
- assert (MP && " Must be member-pointer if its a memberfunctionpointer" );
363
- FProto = MP->getPointeeType ()->getAs <FunctionProtoType>();
364
- assert (FProto &&
365
- " The call must have happened through a member function "
366
- " pointer" );
367
- }
368
- }
369
- }
370
-
371
- unsigned ParamIndex = 0 ;
372
- unsigned NumArgs = Node.getNumArgs ();
373
- if (FProto && FProto->isVariadic ())
374
- NumArgs = std::min (NumArgs, FProto->getNumParams ());
375
-
376
- const auto GetParamType =
377
- [&FProto, &Node](unsigned int ParamIndex) -> std::optional<QualType> {
378
- if (FProto && FProto->getNumParams () > ParamIndex) {
379
- return FProto->getParamType (ParamIndex);
380
- }
381
- const auto *FD = Node.getDirectCallee ();
382
- if (FD && FD->getNumParams () > ParamIndex) {
383
- return FD->getParamDecl (ParamIndex)->getType ();
384
- }
385
- return std::nullopt;
386
- };
387
-
388
- for (; ArgIndex < NumArgs; ++ArgIndex, ++ParamIndex) {
389
- auto ParamType = GetParamType (ParamIndex);
390
- if (ParamType)
391
- OnParamAndArg (*ParamType, Node.getArg (ArgIndex)->IgnoreParenCasts ());
392
- }
393
- }
394
-
395
304
// Finds any expression `e` such that `InnerMatcher` matches `e` and
396
305
// `e` is in an Unspecified Pointer Context (UPC).
397
306
static void findStmtsInUnspecifiedPointerContext (
@@ -408,7 +317,7 @@ static void findStmtsInUnspecifiedPointerContext(
408
317
if (const auto *FnDecl = CE->getDirectCallee ();
409
318
FnDecl && FnDecl->hasAttr <UnsafeBufferUsageAttr>())
410
319
return ;
411
- forEachArgumentWithParamType (
320
+ ast_matchers::matchEachArgumentWithParamType (
412
321
*CE, [&InnerMatcher](QualType Type, const Expr *Arg) {
413
322
if (Type->isAnyPointerType ())
414
323
InnerMatcher (Arg);
0 commit comments