Clang и LLVM IR: на каком языке думают компиляторы. Первый этап - препроцессинг. Это самая простая часть: компилятор берёт ваш main.c и выполняет текстовые директивы. Он выкидывает коментарии, вставляет заголовочные файлы (#include), раскрывает макросы (#define) и обрабатываеи условную компиляцию (#ifdef). В Clang остановиться после препроцессора можно флагом -E: clang -E main.c -o main.i Теперь у нас есть один большой .i-файл с чистым кодом на C. На этом этапе часто кроются проблемы с макросами или неверными путями к заголовочным файлам. Следующий шаг - собственно компиляция. Здесь Clang делает синтаксический и семантический анализ. Ошибки вроде забытой точки с запятой или несоответствия типов отлавливаются именно сейчас. Но Clang идёт дальше: вместо того чтобы сразу генерировать ассемблер, он создаёт промежуточное представление LLVM IR (Intermediate Representation). LLVM IR - это нечто среднее между C и ассемблером, но не привязанное к конкретному процессору. Его можно представит