如何使用 clang AST 匹配器 usingDirectiveDecl 查找具有特定名称的 using 命名空间指令?

How to use clang AST matcher usingDirectiveDecl to find using namespace directive with specific name?

我正在尝试使用 clang-query 制作 clang-tidy 匹配器的原型,以查找具有特定名称(例如 using namespace ns1::ns2;.

using namespace 指令

使用 clang-query 我尝试了这些变体,但 none 匹配任何东西:

clang-query> match usingDirectiveDecl(hasName("ns1")).bind("changeNamespaceName")
0 matches.

clang-query> match usingDirectiveDecl(hasName("ns2")).bind("changeNamespaceName")
0 matches.

clang-query> match usingDirectiveDecl(hasName("ns1::ns2")).bind("changeNamespaceName")
0 matches.

usingDirectiveDecl 是这项任务的正确匹配器吗?

查找具有特定名称的 using namespace 指令的正确方法是什么?

不幸的是,单独使用 clang-query AST 匹配器似乎无法做到这一点。 usingDirectiveDecl 匹配 using namespace 声明,但基于命名空间的进一步限制不完整。

虽然 UsingDirectiveDecl 确实有名称,但它只是占位符字符串 ::<using-directive>:

clang-query> m usingDirectiveDecl(matchesName("^::<using-directive>$"))

Match #1:

/home/scott/wrk/learn/clang/using-namespace/un1.cc:22:3: note: "root" binds here
  using namespace ns1;
  ^~~~~~~~~~~~~~~~~~~

Match #2:

/home/scott/wrk/learn/clang/using-namespace/un1.cc:28:3: note: "root" binds here
  using namespace ns1::ns2;
  ^~~~~~~~~~~~~~~~~~~~~~~~
2 matches.

事实证明,我们可以使用 hasDescendant 根据命名空间 限定符 进行过滤(如果存在的话):

clang-query> m usingDirectiveDecl(hasDescendant(nestedNameSpecifier(specifiesNamespace(matchesName("ns1")))))

Match #1:

/home/scott/wrk/learn/clang/using-namespace/un1.cc:28:3: note: "root" binds here
  using namespace ns1::ns2;
  ^~~~~~~~~~~~~~~~~~~~~~~~
1 match.

这是使用 UsingDirectiveDeclQualifierLoc 成员进行过滤。但是没有办法过滤限定词之后的内容,如果根本没有限定词也一样。原因似乎只是缺少 AST 匹配器,该匹配器会根据其 NominatedNamespace 字段限制 UsingDirectiveDecl

因此,在 clang-tidy 检查中,您能做的最好的事情是使用匹配器查找所有 using namespace 声明,然后(在后续的 C++ 代码中)检查调用 getNominatedNamespace().