解析数据结构clang / LLVM

时间:2017-02-10 10:12:03

标签: clang llvm llvm-clang llvm-ir

我想知道从C源文件解析和获取数据结构的最佳解决方案是什么。假设我有:

typedef int M_Int;
typedef float* P_Float;

typedef struct Foo {
  M_Int a;
  P_Float p_f;
} Foo;

展开数据结构以获取struct a的变量p_fFoo的基元的最佳方法是什么?

对于非常简单的示例,解析AST可能是最好的方法,但是当代码变得更复杂时,使用IR代码以更低级别的方式工作可能更好吗?

2 个答案:

答案 0 :(得分:0)

您可以使用llvm调试信息来获取所需的信息。如果使用-g选项编译C代码,它将生成包含所有信息的调试信息。理解llvm debuginfo很棘手,主要是因为没有太多关于它们的结构以及如何访问它们的文档。以下是一些链接:

1)http://llvm.org/docs/SourceLevelDebugging.html

2)这是我正在使用调试信息的项目的链接。这可能不太有用,因为没有太多文档但是查看debuginfo类的用法可能会有用。我们试图获得C函数的所有指针参数(包括结构参数的字段名称)的字段名称。与debuginfo访问相关的所有代码都在此文件中:https://github.com/jiten-thakkar/DataStructureAnalysis/blob/dsa_llvm3.8/lib/dsaGenerator/DSAGenerator.cpp

答案 1 :(得分:0)

要查找基础类型,AST是一个很好的工作级别。 Clang可以使用AST Matchers和Callbacks自动化和扩展这个过程,与libtooling一起使用。例如,AST匹配器组合

bind()

将匹配使用typedef而不是内置类型声明的C结构中的字段。 run()调用使AST节点可以被回调访问。这是一个回调,其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

将其放入Clang工具并构建,运行

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 *'

产生

groupBy

我在Code Analysis and Refactoring Examples with Clang Tools project中设置了一个完整的工作示例应用(请参阅apps / TypedefFinder.cc)。