Что такое правильная абстракция для модуля компиляции в LLVM?
В LLVM у нас есть LLVMContext
, которая является единицей хранения, и мы имеем llvm::Module
, где новые символы (функции и типы) строятся.
мой вопрос Какую правильную абстракцию llvm использовать для модулей компиляции? это Module
? или это на самом деле предназначено для большей области, то есть: цель общей библиотеки
Мне кажется, что модуль компиляции должен удовлетворять результат "все или ничего"; либо он компилирует весь свой контент без ошибок, либо существуют ошибки, и его необходимо исправить и собрать заново, прежде чем какие-либо символы в CU будут пригодны для использования. В моей голове, это определение того, что должна представлять единица компиляции
если модуль является правильной абстракцией для CU, как мне представить символы в другом (правильно скомпилированном) Module
объекты для нового модуля, который собирается построить, чтобы он мог их найти? мне нужно добавить декларации или есть какой-то другой быстрый способ для этого?
точка на соответствующую строку в clang
был бы очень полезен
2 ответа
Модуль является правильной абстракцией для модуля компиляции. Вы можете связать вместе модули, чтобы сделать весь анализ программы оттуда.
Это попытка ответить на мой собственный вопрос:
Класс llvm::Linker
имеет возможность взять несколько модулей и вернуть один составной модуль обратно, содержащий все символы в существующих модулях. После того, как соединение установлено и составной модуль создан, мне все еще не ясно, каковы правила относительно владения входными модулями.
В любом случае, этот класс должен позволить вам пойти по пути увеличения модуля. Допустим, вы пытаетесь реализовать REPL, что означает, что вы добавляете новые символы в глобальное пространство имен:
План REPL будет работать следующим образом:
- написать некоторую функцию в REPL
- скомпилируйте функцию как единый модуль, назовите его "base"
- написать еще несколько функций в REPL
- скомпилировать новые функции в новом модуле
- если модуль новых функций успешно компилируется, свяжите "base" и новый модуль в новом модуле, назовите его "base.2"
промыть и повторить
Если вы заменяете символ или функцию по имени, вы хотите, чтобы более старые символы видели переопределенную версию вашего символа. Поэтому, когда вы определяете новую функцию, вы должны убедиться, что
getOrInsertFunction
вызывается как в существующем "базовом" модуле, так и в новом.