Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clang 叮当声:编写一个函数';将AST从原始文件转换为新文件_Clang_Libtooling - Fatal编程技术网

Clang 叮当声:编写一个函数';将AST从原始文件转换为新文件

Clang 叮当声:编写一个函数';将AST从原始文件转换为新文件,clang,libtooling,Clang,Libtooling,我是Clang的新手,正在尝试通过libtooling分析AST。 我想找到一个特定的函数,并将其AST从原始源文件移动到一个新文件 我知道如何通过MatchFinder查找函数。 现在,我想知道如何将其AST写入新文件(.c或.cpp) 提前谢谢 摘要:要获取源文本,请使用SourceManager;要从原始文件中删除该函数,请生成一个替换项,并使用重构工具应用它 首先,这里有一种获取函数定义源代码的方法,假设AST匹配器如下所示: auto matcher(std::string const

我是Clang的新手,正在尝试通过libtooling分析AST。 我想找到一个特定的函数,并将其AST从原始源文件移动到一个新文件

我知道如何通过MatchFinder查找函数。 现在,我想知道如何将其AST写入新文件(.c或.cpp)


提前谢谢

摘要:要获取源文本,请使用
SourceManager
;要从原始文件中删除该函数,请生成一个
替换项
,并使用
重构工具
应用它

首先,这里有一种获取函数定义源代码的方法,假设AST匹配器如下所示:

auto matcher(std::string const & fname) {
  return functionDecl(hasName(fname)).bind("f_decl");
}
回调的run方法首先获取对匹配的AST节点的访问权,获取函数声明所涵盖的源范围,并获取对SouceManager的引用,该引用将SourceLocation对象与实际源关联:

virtual void run(MatchResult_t const & result) override {
  using namespace clang;
  FunctionDecl * f_decl = const_cast<FunctionDecl *>(
      result.Nodes.getNodeAs<FunctionDecl>("f_decl"));
  if(f_decl) {
    SourceManager &sm(result.Context->getSourceManager());
    SourceRange decl_range(f_decl->getSourceRange());
    SourceLocation decl_begin(decl_range.getBegin());
    SourceLocation decl_start_end(decl_range.getEnd());
    SourceLocation decl_end_end( end_of_the_end( decl_start_end,sm));
回到
run()
,使用准确的起始和结束位置,您可以将指针放入SourceManager的字符缓冲区:

    const char * buff_begin( sm.getCharacterData(decl_begin));
    const char * buff_end( sm.getCharacterData(decl_end_end));
    std::string const func_string(buff_begin,buff_end);
func_字符串包含函数的源代码;您可以写入新文件等

为了消除原始文件中函数的源代码,我们可以生成一个替换,并让重构工具为我们应用它。要创建替换,我们需要在
run()
中再添加两行代码:

替换ctor将获取SourceManager、从何处开始替换、覆盖多少以及覆盖内容。此替换将不使用任何内容覆盖整个原始函数定义

我们如何让重构工具替换它?我们可以通过引用重构工具的Replacements成员来构造回调类。在
运行中
,我们会得出以下结论:

    repls_.insert(repl);

我在apps/FunctionMover.cc中添加了一个工作示例应用程序。

您想为函数编写AST,还是编写底层源代码?@那些叫我Tim的人,我想将一个特定函数划分到另一个文件。因此,过程可能是,1)在AST级别(通过MatchFinder)查找此函数,2)将其写入另一个文件,3)将其从原始文件中删除。
    uint32_t const decl_length =
      sm.getFileOffset(decl_end_end) - sm.getFileOffset(decl_begin);
    Replacement repl(sm,decl_begin,decl_length,"");
    repls_.insert(repl);