AST는 기본 수준을 찾기에 적합합니다. Clang은 libtooling과 함께 사용되는 AST Matchers 및 Callbacks를 사용하여이 프로세스를 자동화하고 확장 할 수 있습니다. 예를 들어, AST의 정규 조합
fieldDecl(hasType(tyoedefType().bind("typedef"))).bind("field")
대신의 타입 정의로 선언 된 C 구조체의 필드와 일치합니다 내장 타입입니다. bind()
호출은 AST 노드를 콜백에 액세스 가능하게 만듭니다.
typedef-report Foo.h -- # Note two dashes
실행이되면
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
연타 도구에 넣어 내장되어
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을 생산 : 여기에 그 run()
방법 필드 선언의 기본 형식을 가져옵니다 콜백입니다 Code Analysis and Refactoring Examples with Clang Tools project (앱/TypedefFinder.cc 참조)에 전체 작동 예제 앱을 게시하십시오.