我們在前一篇 Clang AST dump 中交代了指令可以利用 clang 完整 dump AST。其實已經可以自己寫程式 traverse AST 了。但又何必再 parse 一次呢? 可以直接利用 libclang 使用建立好的 AST。
演算法筆記
我們在前一篇 Clang AST dump 中交代了指令可以利用 clang 完整 dump AST。其實已經可以自己寫程式 traverse AST 了。但又何必再 parse 一次呢? 可以直接利用 libclang 使用建立好的 AST。
這邊不筆記一下不行,人老了沒辦法記這麼詳細了,發揮打遊戲查攻略的精神搜尋資料和嘗試錯誤!! 這也太難,光是編譯就可以讓一堆人打退堂鼓了…
我就是想在 win7 + mingw 環境下用 clang ! 官網都不提供只好自己來編譯了。
Requirement: 確定都有寫進 system path
Downloads: 一堆 source code 還要放在特定的結構目錄下才能正常編譯
Steps
ar -rcT libclang.a *.a
這樣編譯好的 clang.exe 基本上還是使用 mingw 的 standard library,需要 mingw 的 runtime 才能執行,使用 clang.exe 前確保 mingw 有設定進 system path
設計一個 main.cpp ,嘗試用 clang 把 AST 印出來,兩種指令都可以,如果有引入其他 lib 可能會 dump 出一堆東西(如 #include<time.h>),畢竟 clang 預設指令不含 preprocessor,不會去認這是不是 standard library
#define NUM 10 int REG_A; float REG_B = NUM; int REG_C[NUM] = {0}; extern void autog(); void autoGen(const float &in) { REG_A = NUM; }
clang-check.exe -ast-dump main.cpp -- TranslationUnitDecl 0x351a40 <<invalid sloc>> <invalid sloc> |-TypedefDecl 0x351f90 <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128' | `-BuiltinType 0x351ca0 '__int128' |-TypedefDecl 0x352000 <<invalid sloc>> <invalid sloc> implicit __uint128_t 'unsigned __int128' | `-BuiltinType 0x351cc0 'unsigned __int128' |-TypedefDecl 0x352098 <<invalid sloc>> <invalid sloc> implicit __builtin_ms_va_list 'char *' | `-PointerType 0x352060 'char *' | `-BuiltinType 0x351ae0 'char' |-TypedefDecl 0x352100 <<invalid sloc>> <invalid sloc> implicit __builtin_va_list 'char *' | `-PointerType 0x352060 'char *' | `-BuiltinType 0x351ae0 'char' |-VarDecl 0x352170 <D:\workspace\clangparser\Release\main.cpp:2:1, col:7> col:7 used REG_A 'int' |-VarDecl 0x352238 <line:3:1, line:1:13> line:3:7 REG_B 'float' cinit | `-ImplicitCastExpr 0x3522c0 <line:1:13> 'float' <IntegralToFloating> | `-IntegerLiteral 0x3522a0 <col:13> 'int' 10 |-VarDecl 0x352360 <line:4:1, col:22> col:7 REG_C 'int [10]' cinit | `-InitListExpr 0x352430 <col:20, col:22> 'int [10]' | |-array filler | | `-ImplicitValueInitExpr 0x352478 <<invalid sloc>> 'int' | `-IntegerLiteral 0x3523c8 <col:21> 'int' 0 |-FunctionDecl 0x3524e0 <line:6:1, col:19> col:13 autog 'void (void)' extern `-FunctionDecl 0x3526a0 <line:8:1, line:10:1> line:8:6 autoGen 'void (const float &)' |-ParmVarDecl 0x3525d0 <col:14, col:27> col:27 in 'const float &' `-CompoundStmt 0x4d6e300 <col:31, line:10:1> `-BinaryOperator 0x4d6e2d8 <line:9:2, line:1:13> 'int' lvalue '=' |-DeclRefExpr 0x4d6e290 <line:9:2> 'int' lvalue Var 0x352170 'REG_A' 'int' `-IntegerLiteral 0x4d6e2b8 <line:1:13> 'int' 10
clang -Xclang -ast-dump -fsyntax-only main.cpp TranslationUnitDecl 0x37a6ed0 <<invalid sloc>> <invalid sloc> |-TypedefDecl 0x37a7420 <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128' | `-BuiltinType 0x37a7130 '__int128' |-TypedefDecl 0x37a7490 <<invalid sloc>> <invalid sloc> implicit __uint128_t 'unsigned __int128' | `-BuiltinType 0x37a7150 'unsigned __int128' |-TypedefDecl 0x37a7528 <<invalid sloc>> <invalid sloc> implicit __builtin_ms_va_list 'char *' | `-PointerType 0x37a74f0 'char *' | `-BuiltinType 0x37a6f70 'char' |-TypedefDecl 0x37a7590 <<invalid sloc>> <invalid sloc> implicit __builtin_va_list 'char *' | `-PointerType 0x37a74f0 'char *' | `-BuiltinType 0x37a6f70 'char' |-VarDecl 0x37a7600 <main.cpp:2:1, col:7> col:7 used REG_A 'int' |-VarDecl 0x37a76c8 <line:3:1, line:1:13> line:3:7 REG_B 'float' cinit | `-ImplicitCastExpr 0x37a7750 <line:1:13> 'float' <IntegralToFloating> | `-IntegerLiteral 0x37a7730 <col:13> 'int' 10 |-VarDecl 0x37a77f0 <line:4:1, col:22> col:7 REG_C 'int [10]' cinit | `-InitListExpr 0x37a78c0 <col:20, col:22> 'int [10]' | |-array filler | | `-ImplicitValueInitExpr 0x37a7908 <<invalid sloc>> 'int' | `-IntegerLiteral 0x37a7858 <col:21> 'int' 0 |-FunctionDecl 0x37a7970 <line:6:1, col:19> col:13 autog 'void (void)' extern `-FunctionDecl 0x37a7b30 <line:8:1, line:10:1> line:8:6 autoGen 'void (const float &)' |-ParmVarDecl 0x37a7a60 <col:14, col:27> col:27 in 'const float &' `-CompoundStmt 0x5362c40 <col:31, line:10:1> `-BinaryOperator 0x5362c18 <line:9:2, line:1:13> 'int' lvalue '=' |-DeclRefExpr 0x5362bd0 <line:9:2> 'int' lvalue Var 0x37a7600 'REG_A' 'int' `-IntegerLiteral 0x5362bf8 <line:1:13> 'int' 10