以自制语言插入C ++代码并使用llvm-3.2进行编译

时间:2013-05-07 00:52:58

标签: c++ llvm

我正在尝试使用flex,bison和llvm(3.2)为我创建的编程语言创建一个编译器,我想允许程序员插入C ++代码。

示例:

//some code using my own language
extern
{
    int i = 42;
    // Other code..
    std::cout << "I'm here !" << std::endl;
}
//some other code using my own language

在语法分析之后,我有一个包含AST中C ++代码的对象。如何将其插入IR代码?

奖金:

我也想做点什么:

myInt i = 42; // myInt : 64bits
extern
{
    std::cout << i << std::endl;
}

这可能吗?

2 个答案:

答案 0 :(得分:0)

您尝试做的事情可能非常复杂,您应该仔细考虑建议的语义。除非您正在生成C ++代码,否则还需要编译C ++代码的块。编译C ++块的最简单方法是使用clang作为库。它可以从C ++代码为您生成LLVM IR。但要做任何远程有用的IR,它必须与你的编译器生成的实际IR 相关联,这就是事情可以任意复杂的地方 - 这一切都取决于更严格定义的语义。 / p>

答案 1 :(得分:0)

我看到两种相对“可行”的方式来实现这个目标:

  1. 预翻译您的翻译单元以发出C / C ++源代码和可编译代码。例如。改变这个:

    myInt i = 42; // myInt : 64bits
    extern
    {
        std::cout << i << std::endl;
    }
    

    分为2个文件:

    1. 具有函数的cppsource:

      void ____genfunc1 (int i) {
          std::cout << i << std::endl;
      }
      
    2. 用你的语言“清理”源文件(虽然我猜你也可以直接发出LLVM IR),其措辞如下:

      myInt i = 42; // myInt : 64bits
      ___native_call (____genfunc1, i);
      
    3. 你的“___native_call”函数必须将对象编组到/从C / C ++编译(并且可能执行其他运行时mumbo-jumbo - 获取/释放监视器,在不同的内存空间之间递增/递减引用计数器/复制值)和调用函数本身。

      通过这种方式,您可以获得2个传递给链接器的对象以生成可执行文件。 请注意,尝试混合不同语言存在无数陷阱,特别是如果它们代表截然不同的抽象级别。

    4. 将编译器转换为将发出C ++源文件的预处理器 - 例如将您的语言翻译成C ++。调试信息管理可能会成为地狱,一次:)

    5. 无论哪种方式,这将是笨重的,并可能使最终用户感到困惑。为什么不简单地支持适当的ABI并让用户将C ++代码保存在C ++文件中?