bgschiller
bgschiller

Reputation: 2127

Clang AST Match call to make_unique with specific class

I'm trying to use clang's AST matchers to target code like the following:

#include<memory>

namespace Demo {
    class Widget {};
}

int main () {
    auto w = std::make_unique<Demo::Widget>();
}

In clang-query, I've tried the following:

callExpr(callee(functionDecl(
  // including only this arg gives matches
  hasName("make_unique"),
  // adding this second arg produces zero matches
  hasTemplateArgument(0, refersToType(asString("Demo::Widget")))
)))

I've also tried swapping out refersToType(...) for

refersToDeclaration(cxxRecordDecl(isSameOrDerivedFrom("Demo::Widget")))

which also gives zero matches. What can I use to target calls to std::make_unique templated on a particular type?

Upvotes: 0

Views: 411

Answers (2)

steveire
steveire

Reputation: 11074

You need refersToType(asString("class Demo::Widget")))

Unfortunately this is not very discoverable. I showed some tooling to make this discoverable here: https://steveire.wordpress.com/2019/04/30/the-future-of-ast-matching-refactoring-tools-eurollvm-and-accu/ but it's not generally available yet.

Upvotes: 1

Benjamin Bannier
Benjamin Bannier

Reputation: 58594

Going via the template argument's actual type works with clang-10.0.0,

clang-query> match callExpr(callee(functionDecl(hasName("make_unique"),
                             hasAnyTemplateArgument(refersToType(hasDeclaration(
                                 namedDecl(hasName("Demo::Widget"))))))))

Match #1:

/tmp/test.cpp:8:18: note: "root" binds here
        auto w = std::make_unique<Demo::Widget>();
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 match.

Upvotes: 1

Related Questions