以编程方式构建clang AST

3
我正在编写一个转译器,可以将源语言翻译成C ++。为此,我使用了flex、bison和clang-AST。我将从空的AST开始,在解析每个语义动作时,我会向clang-AST添加节点。
问题在于,我找不到以编程方式构建AST的方法。假设我想为以下代码生成AST,但不使用RecursiveASTVisitor(因为我的源语言不是C ++)。
#include <iostream>

int main()
{
  std::cout << "Hello World " << std::endl;

  return 0;
}

因此,可以生成AST的相应代码如下所示。
#include "clang/AST/ASTContext.h"

int main(int argc, const char **argv)
{

    //Create an empty context
    clang::ASTContext *context = new clang::ASTContext(NULL, NULL, NULL, NULL, NULL);

    //Declare a main function
    clang::FunctionDecl *FD = clang::FunctionDecl::Create(Context, "main");

    //Declare params
    std::vector<clang::ParmVarDecl*> NewParamInfo;
    NewParamInfo.push_back(clang::ParmVarDecl::Create(Context, FD, "argc"));
    NewParamInfo.push_back(clang::ParmVarDecl::Create(Context, FD, "argv"));

    //set params to function
    FD->setParams(ArrayRef<clang::ParmVarDecl*>(NewParamInfo));

    //Declare a compund stament
    clang::CompoundStmt *CS = new (Context) clang::CompoundStmt(clang::SourceLocation());

    //Declare a Statement to print
    clang::Stmt *S = new (Context) clang::ReturnStmt("std::cout << \"Hello World \" << std::endl;");

    //Add print statement to compund statement
    CS->setStmts(Context, S, 1);

    //Add compund statement to body of function
    FD->setBody(CS);

    return 0;
}

上述代码并不是可用的代码,查看llvm或clang文档非常麻烦,有没有人能帮助我完成类似的工作?


2
据我所知,目前没有公共 API 可以修改或构建 AST。如果你的目标是将其他语言转换成 C++,为什么要手动构建 AST 呢?直接生成 C++ 源代码即可,无需使用 clang。 - llllllllll
1
为什么要将代码转译成C++?这是不寻常的(你需要解释为什么想这样做)。请注意,实际上,C++编译速度较慢。最好将其转译成C,如果您真的想生成C++,则应该解释原因并在文件中发出C++代码。 - Basile Starynkevitch
1
如果你编写一个编译器,最好让它发出LLVM或类似的东西(例如libgccjit...)。我认为发出C++ AST没有任何意义。如果你想要发出C++,就发出源代码吧。 - Basile Starynkevitch
请注意,#include <iostream> 正在拉取数万行代码(而您的AST生成程序中没有相应的功能)。 - Basile Starynkevitch
我猜测 clang::ReturnStmt("std::cout << \"Hello World \" << std::endl;") 并不是你想要的。 - Basile Starynkevitch
1个回答

1
  • 有一种方法是从头开始编写clang的AST,不使用API而是使用其内部函数;理论上你可以采用这种方法,但你将会在使用非公开的、不是API的函数时遭受变动。但是,对于你打算实现的目的来说,不清楚是否需要使用clang自身为开发C++20、C++2b及其后续版本所需的最新AST构建函数。
  • 但是,还有一种重构API,正如Clang:将函数的AST从原始文件写入新文件中提到的那样,但你打算实现的目的并不是重构本身,但你可以略微调整思路,利用相对稳定的重构API在clang中构建出你所需的AST,作为从零开始的“重构”。
许多评论者嘲笑使用clang的AST作为数据结构。他们会避免使用clang的AST来“发射源代码”,但是要发射非平凡的源代码,必须重新发明自己的AST。为什么要重新发明C++ AST轮子呢?只需通过重构API构建clang的AST,而不是从头设计自己的AST。然后,在您打算转换的所有“重构”完成后,通过使用访问器遍历它从clang AST中读取生成的C++源代码作为最后一步。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接