基础

当我们提到Clang时,可能有三种意思:

  1. 前端(表现为Clang Libraries)
  2. 编译器驱动 (表现为clang命令和clang driver的库)
  3. 实际的编译器(表现为clang -cc1命令,该命令并不仅仅使用了Clang的库,同时大量使用了LLVM中的库和集成的汇编器,从而实现编译器中端和后端的功能)

Clang命令行参数

Clang Driver

查看实际调用的命令

使用-###来查看实际调用命令,但是这个命令这次不会执行。

1
2
3
4
5
6
7
$ clang -### test.c -o test
clang version 7.0.0 (tags/RELEASE_700/final 355317)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/katherine/LLVM/llvm-700/build/bin
"/home/katherine/LLVM/llvm-700/build/bin/clang-7" "-cc1" "-triple" "x86_64-unknown-linux-gnu" "-emit-obj" "-mrelax-all" "-disable-free" "-main-file-name" "test.c" "-mrelocation-model" "static" "-mthread-model" "posix" "-mdisable-fp-elim" "-fmath-errno" "-masm-verbose" "-mconstructor-aliases" "-munwind-tables" "-fuse-init-array" "-target-cpu" "x86-64" "-dwarf-column-info" "-debugger-tuning=gdb" "-resource-dir" "/home/katherine/LLVM/llvm-700/build/lib/clang/7.0.0" "-internal-isystem" "/usr/local/include" "-internal-isystem" "/home/katherine/LLVM/llvm-700/build/lib/clang/7.0.0/include" "-internal-externc-isystem" "/usr/include/x86_64-linux-gnu" "-internal-externc-isystem" "/include" "-internal-externc-isystem" "/usr/include" "-fdebug-compilation-dir" "/home/katherine/LLVM/testclang/include" "-ferror-limit" "19" "-fmessage-length" "126" "-fobjc-runtime=gcc" "-fdiagnostics-show-option" "-fcolor-diagnostics" "-o" "/tmp/test-17e6e6.o" "-x" "c" "test.c" "-faddrsig"
"/usr/bin/ld" "-z" "relro" "--hash-style=gnu" "--eh-frame-hdr" "-m" "elf_x86_64" "-dynamic-linker" "/lib64/ld-linux-x86-64.so.2" "-o" "test" "/usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../x86_64-linux-gnu/crt1.o" "/usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../x86_64-linux-gnu/crti.o" "/usr/lib/gcc/x86_64-linux-gnu/7.3.0/crtbegin.o" "-L/usr/lib/gcc/x86_64-linux-gnu/7.3.0" "-L/usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../x86_64-linux-gnu" "-L/lib/x86_64-linux-gnu" "-L/lib/../lib64" "-L/usr/lib/x86_64-linux-gnu" "-L/usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../.." "-L/home/katherine/LLVM/llvm-700/build/bin/../lib" "-L/lib" "-L/usr/lib" "/tmp/test-17e6e6.o" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "/usr/lib/gcc/x86_64-linux-gnu/7.3.0/crtend.o" "/usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../x86_64-linux-gnu/crtn.o"

常用命令

测试代码

1
2
3
4
5
6
7
8
9
10
11
// main.c

#include <stdio.h>

int sum(int x, int y);

int main() {
int r = sum(3, 4);
printf("r = %d\n", r);
return 0;
}
1
2
3
4
5
// sum.c

int sum(int x, int y) {
return x + y;
}

查看帮助信息

1
$ clang --help

查看编译的阶段过程

1
2
3
4
5
6
7
8
9
10
$ clang -ccc-print-phases main.c sum.c -o sum
0: input, "main.c", c
1: preprocessor, {0}, cpp-output
2: compiler, {1}, assembler
3: assembler, {2}, object
4: input, "sum.c", c
5: preprocessor, {4}, cpp-output
6: compiler, {5}, assembler
7: assembler, {6}, object
8: linker, {3, 7}, image

预处理

1
$ clang -E main.c -o main.i

词法分析

通过driver

1
$ clang -Xclang -dump-tokens main.c

通过clang -cc1

1
$ clang -cc1 -dump-tokens main.c

语法分析,打印AST

通过driver

有色:

1
$ clang -fsyntax-only -Xclang -ast-dump main.c

通过clang -cc1

无色:

1
$ clang -cc1 -fsyntax-only -ast-dump main.c

生成AST文件

1
$ clang -emit-ast main.c

编译,生成IR

未优化的IR

1
$ clang -emit-llvm -c main.c -o main.ll

优化后的IR

1
$ clang -emit-llvm -c main.c -o main.bc -O3

链接,生成可执行代码

1
2
3
$ clang main.c sum.c -o sum
$ ./sum
r = 7