ASTは、基本的なタイプを見つけるのに適しています。 Clangは、libtoolingと組み合わせて使用されるAST MatchersおよびCallbacksを使用して、このプロセスを自動化および拡張できます。例えば、ASTマッチャー組み合わせ
fieldDecl(hasType(tyoedefType().bind("typedef"))).bind("field")
代わりに内蔵型のtypedefを用いて宣言されているC構造体のフィールドと一致します。 bind()
コールは、コールバックがASTノードにアクセスできるようにします。ここではそのrun()
方法フィールド宣言の基になる型を取得しますコールバックです:これはクランツールに入れて構築されると
virtual void run(clang::ast_matchers::MatchFinder::MatchResult const & result) override
{
using namespace clang;
FieldDecl * f_decl =
const_cast<FieldDecl *>(result.Nodes.getNodeAs<FieldDecl>("field"));
TypedefType * tt = const_cast<TypedefType *>(
result.Nodes.getNodeAs<TypedefType>("typedef"));
if(f_decl && tt) {
QualType ut = tt->getDecl()->getUnderlyingType();
TypedefNameDecl * tnd = tt->getDecl();
std::string struct_name = f_decl->getParent()->getNameAsString();
std::string fld_name = f_decl->getNameAsString();
std::string ut_name = ut.getAsString();
std::string tnd_name = tnd->getNameAsString();
std::cout << "Struct '" << struct_name << "' declares field '"
<< fld_name << " with typedef name = '" << tnd_name << "'"
<< ", underlying type = '" << ut_name << "'" << std::endl;
}
else {
// error handling
}
return;
} // run
、
typedef-report Foo.h -- # Note two dashes
を実行すると、
Struct 'Foo' declares field 'a' with typedef name = 'M_Int', underlying type = 'int'
Struct 'Foo' declares field 'p_f' with typedef name = 'P_Float', underlying type = 'float *'
Iを生成しますCode Analysis and Refactoring Examples with Clang Tools project(apps/TypedefFinder.ccを参照)に完全な実例のアプリケーションを載せてください。