[ast_matcher] Match variable declaration by type name

Hi,

I am trying to learn more about libTooling and the ast_matcher. In my first toy example I wanted to try to match arbitrary variable declaration against a given type name, e.g.

foo var1;

baz var2;

I have tried the following matcher

varDecl(hasType(cxxRecordDecl(hasAnyName("foo", "bar")))).bind("var")

However, it seems that this is not able to match the declaration. My unit test harness looks like this

myContext runOnCode(const char* const Code = "")
{
myContext Context;
auto Factory = llvm::make_unique<myActionFactory>(&Context);
tooling::runToolOnCode(Factory->create(), Code);
return Context;
}

where myContext is a simple holder that stores the matched nodes in a set. The test looks like this

TEST(variableMatcher, variable)
{
myContext context = runOnCode("foo var1;");
auto res = context.getVariables();
EXPECT_EQ(res.size(), size_t(1));
}

Is the problem that the classes "foo" and "bar" are never declared? If so how could I instantiate the tool with the necessary declarations. Could I match differently?

As a followup is there a way to differentiate different properties of the declarations such as parentheses

foo var1;

foo (var2);

Cheers

Michael

Hi,

I am trying to learn more about libTooling and the ast_matcher. In my first toy example I wanted to try to match arbitrary variable declaration against a given type name, e.g.

foo var1;

baz var2;

I have tried the following matcher

varDecl(hasType(cxxRecordDecl(hasAnyName("foo", "bar")))).bind("var")

However, it seems that this is not able to match the declaration. My unit test harness looks like this

myContext runOnCode(const char* const Code = "")
{
myContext Context;
auto Factory = llvm::make_unique<myActionFactory>(&Context);
tooling::runToolOnCode(Factory->create(), Code);
return Context;
}

where myContext is a simple holder that stores the matched nodes in a set. The test looks like this

TEST(variableMatcher, variable)
{
myContext context = runOnCode("foo var1;");
auto res = context.getVariables();
EXPECT_EQ(res.size(), size_t(1));
}

Is the problem that the classes "foo" and "bar" are never declared? If so how could I instantiate the tool with the necessary declarations. Could I match differently?

As a followup is there a way to differentiate different properties of the declarations such as parentheses

foo var1;

foo (var2);

Cheers

Michael

Hi,

I am trying to learn more about libTooling and the ast_matcher. In my
first toy example I wanted to try to match arbitrary variable
declaration against a given type name, e.g.

foo var1;

baz var2;

I have tried the following matcher

varDecl(hasType(cxxRecordDecl(hasAnyName(“foo”, “bar”)))).bind(“var”)

However, it seems that this is not able to match the declaration. My
unit test harness looks like this

myContext runOnCode(const char* const Code = “”)
{
myContext Context;
auto Factory = llvm::make_unique(&Context);
tooling::runToolOnCode(Factory->create(), Code);
return Context;
}

where myContext is a simple holder that stores the matched nodes in a
set. The test looks like this

TEST(variableMatcher, variable)
{
myContext context = runOnCode(“foo var1;”);
auto res = context.getVariables();
EXPECT_EQ(res.size(), size_t(1));
}

Is the problem that the classes “foo” and “bar” are never declared?

Yes; parsing C++ requires knowing which names are types (and which are templates, etc.).

If
so how could I instantiate the tool with the necessary declarations.

The path of least resistance is to ensure that the translation unit you parse is self-contained, i.e., includes the necessary declarations. A useful sanity check is to compile it with clang from the command line.

– James