clang 的簡介請見
線上文章:
# 這裡的 clang 是 compiler driver,負責解析命令行,調用相關工具,並傳遞對應的命令行參數。 # -Xclang 代表其後參數是給 clang -cc1 調用的編譯器。 $ clang -Xclang -ast-dump sum.c # 這裡的 clang -cc1 調用的是實際上的編譯器。 $ clang -cc1 -ast-dump sum.c # -### 列出完整的命令行參數。 $ clang -### sum.c # -xir 指示輸入的是 LLVM IR。 $ clang -xir -c sum.ll
clang
本身是 compiler driver。$ lldb clang (lldb) b Driver.cpp:97 (lldb) r --help
llvm/tools/clang/tools/driver/driver.cpp:main
。# 可以看到實際上下給前端的命令行選項。 $ clang -c -v sum.c $ lldb clang (lldb) b X86TargetLowering::LowerOperation (lldb) r -cc1 -triple x86_64-apple-macosx10.11.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -emit-obj -mrelax-all -disable-free -main-file-name sum.c -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu core2 -target-linker-version 274.2 -v -dwarf-column-info -debugger-tuning=lldb -coverage-notes-file /Users/chenwj/Projects/temp/sum.gcno -resource-dir /Users/chenwj/Projects/install/lib/clang/5.0.0 -fdebug-compilation-dir /Users/chenwj/Projects/temp -ferror-limit 19 -fmessage-length 179 -stack-protector 1 -fblocks -fobjc-runtime=macosx-10.11.0 -fencode-extended-block-signature -fmax-type-align=16 -fdiagnostics-show-option -fcolor-diagnostics -o sum.o -x c sum.c
set follow-fork-mode child
(How to debug llvm source?)。llc
下斷點。底下是 Clang 前端主要流程:
Driver -> Lex -> Parse -> Sema -> CodeGen (LLVM IR)
分別在 include/clang 和 lib 底下有對應。Driver 負責調用編譯流程中所需的工具鏈,並傳遞相應參數。真正意義上的前端是自 Lex 以後至 CodeGen 的部分。
# 可以觀察 driver 如何調用所有工具鏈。 $ clang -v sum.c
$ clang -cc1 -dump-tokens sum.c
$ clang -cc1 -fsyntax-only -ast-dump sum.c
ActOn
供 Parse 調用,建立 AST 和進行語義檢查。lib/CodeGen
迭代 AST 生成 LLVM IR。例如: CodeGenFunction。include/clang/Basic/
。DiagnosticParseKinds.td
包含所有 lib/Parse/*
會報出的警告或錯誤。其它檔案依此類推。想要添加新的警告或是錯誤,可以在 *.td 檔中尋找類似的項目,反推應該在哪裡做相關的檢查。llvm::Value *Zero = llvm::Constant::getNullValue(Size->getType());
$ cat example.c #include "clang-c/Index.h" #include <stdio.h> int main(int argc, char *argv[]) { CXIndex Index = clang_createIndex(0, 0); CXTranslationUnit TU = clang_parseTranslationUnit(Index, 0, argv, argc, 0, 0, CXTranslationUnit_None); for (unsigned I = 0, N = clang_getNumDiagnostics(TU); I != N; ++I) { CXDiagnostic Diag = clang_getDiagnostic(TU, I); CXString String = clang_formatDiagnostic(Diag, clang_defaultDiagnosticDisplayOptions()); fprintf(stderr, "%s\n", clang_getCString(String)); clang_disposeString(String); } clang_disposeTranslationUnit(TU); clang_disposeIndex(Index); } $ clang example.c -I/PATH/TO/INCLUDE -L/PATH/TO/LIB -lclang -o example $ export LD_LIBRARY_PATH=/PATH/TO/LIB $ cat bug.c void foo() { int i = 1 } $ ./example bug.c bug.c:2:12: error: expected ';' at end of declaration
$ cd llvm/projects $ git clone http://llvm.org/git/compiler-rt.git
# 列出可用的 CHECKER 列表。 $ clang -cc1 -analyzer-checker-help $ cat bug.c #include <stdio.h> int main() { int i; printf("%d", i); } $ clang -cc1 -analyze -analyzer-checker=core bug.c bug.c:5:3: warning: Function call argument is an uninitialized value printf("%d", i); ^~~~~~~~~~~~~~~ 1 warning generated.
scan-build
。