Clang-Repl — Clang 22.0.0git 文档

Clang-Repl 概述

  • 是一个交互式 C++ 解释器,支持增量编译,以读取-求值-打印循环(REPL)风格进行交互式编程。
  • 使用 Clang 库将高级编程语言编译为 LLVM IR,再由 LLVM 即时(JIT)基础设施执行。
  • 适合探索性编程和对洞察时间要求高的场合,受Cling启发,可将其部分内容向上游推进。

基本数据流

  • 由交互式提示符或允许增量处理输入的接口控制输入基础设施。
  • 将输入发送到 Clang 基础结构中的底层增量设施。
  • 编译为 AST 表示,可进一步转换以附加特定行为。
  • 降低为 LLVM IR,作为 LLVM JIT 编译基础设施的输入格式,将指定函数转换为目标架构的机器代码并执行。

构建指令

  • cd llvm-projectmkdir buildcd buildcmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DLLVM_ENABLE_PROJECTS=clang -G "Unix Makefiles"../llvm(注意这里的 RelWithDebInfo - 调试/发布)。
  • cmake --build. --target clang clang-repl -j ncmake --build. --target clang clang-repl
  • Clang-repl构建在 llvm-project/build/bin 下,进入该目录运行 ./clang-repl 进入交互模式。

使用方法

  • 基本用法:可包含头文件,定义函数,进行输入输出等操作。
  • 函数定义和调用:定义并调用函数,如 int sum(int a, int b){ return a+b; }; int c = sum(9,10); std::cout << c << std::endl;
  • 迭代结构:如 forwhile 循环。
  • 类和结构:定义类并进行操作,class Rectangle {int width, height; public: void set_values (int,int); int area() {return width*height;}}; 等。
  • Lambda 表达式:auto welcome = []() { std::cout << "Welcome to REPL" << std::endl;}; welcome();
  • 使用动态库:%lib print.so,包含头文件并调用函数,如 print(9);。生成动态库的命令为 clang++-17 -c -o print.o print.cppclang-17 -shared print.o -o print.so

关闭或终止%quit

执行结果处理

  • 捕获执行结果:通过 Value 对象捕获程序执行结果,可存储在 LastValue 中,用于连接解释器和编译代码,实现语言互操作性,如 cppyy 项目利用此功能在 C++ 和 Python 之间传输值。

    • 值合成:选择要合成的表达式,根据类型决定是否分配内存。
    • 存储位置LastValue 是类成员,可在后续输入中访问,无值打印时为无效状态。
    • 提高效率和用户体验Value 对象用于创建类型和内存的映射,实现高效的类型转换,提高用户体验。
  • 转储捕获的执行结果:创建临时转储以显示所需数据的值和类型,方便交互式编程,类似于 Python 的工作方式,使用 Automatic Printf 扩展 libclangInterpreter 库实现,无需多次使用 printf 函数。

    • 解析机制Interpreter.cpp 中的 ParseAndExecute() 函数可接受 Value 参数捕获结果,若省略则验证并推送最后一个值到 dump() 函数。
    • 注释令牌:使用 annot_repl_input_end 令牌处理缺少分号的情况,识别用户输入的结束位置,存储并返回表达式语句以便自动打印。
    • AST 转换:Sema 遇到该令牌时进行 AST 转换,在 CodeGen 过程前设置相关标记,在 AST 消费者中遍历顶级声明以合成表达式。

更多技术细节可访问RFC on LLVM Discourse

阅读 6
0 条评论