Clang はコンパイラのフロントエンドであり、前処理、字句解析、および構文解析に使用されます。結果を抽象構文ツリー AST に変換し、それを LLVM コンパイラのバックエンドに渡して、最終的に実行可能ファイルを生成します。プログラム。
コード コンパイル プロセスは、前処理、字句解析、構文解析、意味解析、オブジェクト コード、リンク、および実行可能プログラムの生成に分けられます。この記事では、clang コマンドを使用して、MacOS プラットフォーム上で C++ コードの一部のコンパイルを完了します。
新しいファイル main.cpp を作成し、C++ コードを記述します。
#include <iostream>
#define STR "Hello world"
int main(int argc, const char * argv[]) {
std::string a = STR;
std::cout << a << std::endl;
return 0;
}
まず、clang コマンドを使用して、このコード セグメントのコンパイル プロセスを表示します。コードは C++ であるため、clang++ を使用する必要があります。
clang++ -ccc-print-phases main.cpp
端末出力情報
+- 0: input, "main.cpp", c++
+- 1: preprocessor, {
0}, c++-cpp-output
+- 2: compiler, {
1}, ir
+- 3: backend, {
2}, assembler
+- 4: assembler, {
3}, object
+- 5: linker, {
4}, image
6: bind-arch, "x86_64", {
5}, image
入力は入力ソース コード ファイルを指し、プリプロセッサは前処理を行い、コンパイラはコンパイラのフロント エンドを指し、コンパイラは字句解析、構文解析、意味解析を実行します。次に、バックエンドがアセンブリを生成し、オブジェクト ファイルを生成します。リンカーはイメージを生成するためのリンクです。最後に、bind-arch はアーキテクチャ情報を処理し、アーキテクチャ関連のイメージ ファイルを生成します。
1. プリプロセッサの前処理プロセスを表示する
clang++ -E main.cpp -o main.i
生成された main.i ファイルは非常に長いので、一番下にスライドしてソース コード部分を表示します。
int main(int argc, const char * argv[]) {
std::string a = "Hello world";
std::cout << a << std::endl;
return 0;
}
前処理の段階ではマクロ定義が展開されており、コード部分はまだ処理されていないことがわかります。
2. 字句解析を表示する
clang++ -fmodules -E -Xclang -dump-tokens main.cpp
生成された字句解析結果は非常に長いため、ここでは短いセクションのみを示します
identifier 'std' [StartOfLine] [LeadingSpace] Loc=<main.cpp:14:5>
coloncolon '::' Loc=<main.cpp:14:8>
identifier 'cout' Loc=<main.cpp:14:10>
lessless '<<' [LeadingSpace] Loc=<main.cpp:14:15>
identifier 'a' [LeadingSpace] Loc=<main.cpp:14:18>
lessless '<<' [LeadingSpace] Loc=<main.cpp:14:20>
identifier 'std' [LeadingSpace] Loc=<main.cpp:14:23>
coloncolon '::' Loc=<main.cpp:14:26>
identifier 'endl' Loc=<main.cpp:14:28>
semi ';' Loc=<main.cpp:14:32>
return 'return' [StartOfLine] [LeadingSpace] Loc=<main.cpp:15:5>
numeric_constant '0' [LeadingSpace] Loc=<main.cpp:15:12>
semi ';' Loc=<main.cpp:15:13>
r_brace '}' [StartOfLine] Loc=<main.cpp:16:1>
eof '' Loc=<main.cpp:16:2>
字句解析とは、ソースコードを解析してトークンを1つずつ生成し、その結果からstd、::、cout、aなどの記号をすべて認識します。左側はトークンのタイプ (識別子 identifier、セミコロン、eof など) で、ファイルの終わりです。ソースコード内の各シンボルの行番号と列番号が右側に記録されます。
3. 構文解析
clang++ -fmodules -fsyntax-only -Xclang -ast-dump main.cpp
4. 意味解析
clang++ -S -emit-llvm main.cpp
現在のディレクトリに main.ll 構文解析ファイルが生成されます。
5. アセンブリファイル
clang++ -S main.cpp
現在のディレクトリに main.s のアセンブリ ファイルが生成されます。
6. ターゲットファイルの生成
clang++ -c main.s
現在のディレクトリには、バイナリ形式の main.o オブジェクト ファイルが生成されます。
7. 実行可能ファイルの生成
clang++ main.cpp -o main
メインファイルはカレントディレクトリに生成されます。コマンドラインで ./main を実行してプログラムを実行し、Hello world を出力します。