Переход от AST к LLVM IR является улицей с односторонним движением.
Взгляните на это изображение.
Файл исходного кода языка программирования высокого уровня (который может быть C, C ++ или Rust) преобразуется в Clang AST. Это структура данных, в которой содержится информация о конструкциях исходного кода самого языка программирования. AST - это c для языка программирования. Это описание проанализированного файла исходного кода языка программирования, так же как дерево Javascript DOM является описанием документа HTML. Это означает, что AST содержит информацию c для этого языка программирования. Если языком программирования является Rust, Rust AST может, например, содержать конструкции функционального кодирования.
LLVM IR, однако, иногда описывается как переносимый высокоуровневый язык ассемблера, поскольку он имеет конструкции, которые могут быть тесно связаны с системное оборудование.
Интерфейсный модуль преобразует язык программирования высокого уровня в LLVM IR. Он делает это, генерируя специфику языка c AST, а затем рекурсивно просматривая этот AST и генерируя конструкции кода LLVM, представляющие каждый узел в AST. Затем у нас есть код LLVM IR. Затем внутренний модуль преобразует LLVM IR в код сборки c, специфичный для архитектуры.
Существует несколько модулей внешнего интерфейса, по одному для каждого языка высокого уровня, который вы хотите преобразовать. в LLVM IR. После завершения этого преобразования сгенерированный LLVM IR не имеет возможности узнать, на каком языке программирования он появился. Вы можете взять код C ++ и тот же код, написанный на Rust, и после генерации LLVM IR вы не сможете отличить их друг от друга.
После того, как LLVM IR был сгенерирован, любая спецификация языка высокого уровня c информация пропала. Это включает информацию о том, как сгенерировать AST, потому что AST требует знаний о конструкциях кодирования, c специфичных для этого языка программирования.
Переход от высокоуровневого (более абстрактного) представления исходного кода к среднему уровню , например, LLVM IR, и даже на более низкий уровень, например код сборки, относительно просто .
Если пойти другим путем, из кода c машины очень низкого уровня, к более абстрактному исходному коду языка программирования высокого уровня намного сложнее. Это связано с тем, что в языках программирования высокого уровня вы можете решить одну и ту же проблему разными способами, в то время как представление кода на языке ассемблера более ограничено, поэтому у вас нет возможности узнать, какие спецификации c кодирование высокого уровня создает код низкого уровня. изначально исходил из.
Вот почему в принципе вы не можете go из LLVM IR в AST. Если кто-то действительно попытается сделать такую вещь, это не будет точно такое же представление исходного кода языка высокого уровня, и оно будет не очень читабельным.