2022-10-20

規(guī)則檢查器-環(huán)境介紹及抽象語法樹初步認(rèn)識

本文主要簡單介紹芬萍,llvm和clang環(huán)境搭建柬祠,抽象語法樹及checker的簡單認(rèn)識

llvm/clang背景

- llvm介紹

llvm是一個模塊化和可重用的編譯器和工具鏈技術(shù)的集合负芋。

LLVM最初是在2000年由伊利諾伊大學(xué)香檳分校(UUIC)的學(xué)生Chris Lattner及其碩士顧問Vikram Adve創(chuàng)建的研究項目惩猫,并在2003年發(fā)布第一個正式版本,目的是提供一種基于SSA的現(xiàn)代編譯策略,這種策略能夠支持任何編程語言的靜態(tài)和動態(tài)編譯迟赃。

LLVM是當(dāng)今最流行的開源編譯器框架項目左刽,你可以使用它編寫自己的編譯器欠痴。

LLVM的命名最早源自于底層虛擬機(jī)(Low Level Virtual Machine)的首字母縮寫喇辽,由于這個項目的范圍并不局限于創(chuàng)建一個虛擬機(jī)菩咨,這個縮寫導(dǎo)致了廣泛的疑惑特占。LLVM開始成長之后是目,成為眾多編譯工具及低端工具技術(shù)的統(tǒng)稱,使得這個名字變得更不貼切长踊,開發(fā)者因而決定放棄這個縮寫的意涵,現(xiàn)今LLVM已單純成為一個品牌阱佛,適用于LLVM下的所有項目

- Clang介紹

Clang:是一個C凑术、C++、Objective-C和Objective-C++編程語言的編譯器前端泄鹏。它采用了底層虛擬機(jī)(LLVM)作為其后端。它的目標(biāo)是提供一個GNU編譯器套裝(GCC)的替代品车猬。作者是克里斯·拉特納(Chris Lattner)韩脏,在蘋果公司的贊助支持下進(jìn)行開發(fā)赡矢,而源代碼授權(quán)是使用類BSD的伊利諾伊大學(xué)厄巴納-香檳分校開源碼許可。Clang主要由C++編寫空民。

Clang項目包括Clang前端和Clang靜態(tài)分析器等。這個軟件項目在2005年由蘋果電腦發(fā)起浊猾,是LLVM(Low Level Virtual Machine)編譯器工具集的前端(front-end),目的是輸出代碼對應(yīng)的抽象語法樹(Abstract Syntax Tree, AST)偷办,并將代碼編譯成LLVM Bitcode。接著在后端(back-end)使用LLVM編譯成平臺相關(guān)的機(jī)器語言逐工。

Clang本身性能優(yōu)異棕硫,其生成的AST所耗用掉的內(nèi)存僅僅是GCC的20%左右纬纪。2014年1月發(fā)行的FreeBSD10.0版將Clang/LLVM作為默認(rèn)編譯器摘仅。

- Clang-Tidy介紹

clang-tidy是一個源碼分析工具,用于檢查? C矾端、 C++和 Objective-C 程序的bugs.

該工具是完全開源的,并且是Clang項目的一部分. 和Clang其他部分一樣,該工具作為C++庫的方式實現(xiàn)滚粟,可以方便的集成于其他工具和程序.

什么是LLVM IR

- LLVM IR 是一門低級語言,語法類似于匯編,是編譯中程序的間表示

- 任何高級編程語言(如C++)都可以用LLVM IR表示

- 基于LLVM IR可以很方便地進(jìn)行代碼優(yōu)化

參考鏈接:https://www.cnblogs.com/Tu9oh0st/p/16358531.html


LLVM/CLANG 關(guān)系介紹

Clang為前端llvm架構(gòu)前端

1.源代碼通過clang的詞法分析生成tokens

2.通過clang的語法分析生成了AST抽象語法樹

3.通過clang的語義分析生成中間表示IR

Clang-tidy

LLVM后端

1.負(fù)責(zé)優(yōu)化IR代碼

2.負(fù)責(zé)生成目標(biāo)程序

LLVM/CLANG 環(huán)境準(zhǔn)備


1.查看環(huán)境依賴钢坦,升級低版本檢查工具?Getting Started with the LLVM System - Requirements

2. cmake版本過低:

去https://cmake.org/files/下載所需版本的源碼。也可以使用wget下載,例如:

wget https://cmake.org/files/v3.22/cmake-3.22.1.tar.gz

- 解壓:tar -xvzf cmake-3.22.1.tar.gz

- 進(jìn)入解壓目錄颗管,配置成功之后顯示:CMake has bootstrapped. Now run make.

chmod 777 ./configure

./configure

- 配置完成后,編譯:make

- 編譯完成后比吭,安裝: sudo make install

- 最后使用新安裝的cmake替換舊版本绣溜,其中/usr/local/bin/cmake為新安裝的cmake目錄底哗。

sudo update-alternatives --install /usr/bin/cmake cmake /usr/local/bin/cmake 1 --force


3.下載ninja和gcc

sudo apt install ninja-build

sudo apt install gcc g++

4.下載 LLVM工程:

- 創(chuàng)建文件夾并下載llvm工程:git clone https://github.com/llvm/llvm-project.git


- 編譯 LLVM 和 Clang:

cd llvm-project

mkdir build?(in-tree build is not supported)

cd build

- 下方命令會同時以release模式編譯 LLVM前标、Clang以及Clang-tidy:

方式一:cmake -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles" ../llvm

make (等的花都謝了音比,編的好慢盎纭!)

方式二:以ninja方式編譯:

cmake -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" -DCMAKE_BUILD_TYPE=Release -G "Ninja" ../llvm

ninja(小內(nèi)存ninja -j2)

sudo ninja install 安裝到系統(tǒng)

5.LLVM安裝完成狀態(tài)驗證

通過執(zhí)行clang-tidy -list-checks -checks=*命令秫舌,我們可以查看當(dāng)前可用的所有check娇未。

而如果想要執(zhí)行某個檢查,那就執(zhí)行?clang-tidy --checks='check名字' 被測文件

- 添加 llvm/build/bin 到path:

export PATH=/XXXl/llvm-project/build/bin/:$PATH

clang --help

clang file.c -fsyntax-only?(正確性檢查)

clang file.c -S -emit-llvm -o -?(打印未優(yōu)化的llvm代碼)

clang file.c -S -emit-llvm -o - -O3

clang file.c -S -O3 -o -?(輸出本地機(jī)器碼)

運行測試套件:

make check-clang



抽象語法樹

抽象語法樹(Abstract Syntax Tree卸亮,AST)

Clang的AST非常類似于編寫的C++代碼和C++標(biāo)準(zhǔn)段直。AST中每一個節(jié)點都是一個Decl或者Stmt類的一個實例螺垢。

1. 聲明類Decl

Decl用于表示在一個聲明或者定義功茴,包括變量墨林、typedef定義酌呆、函數(shù)和結(jié)構(gòu)體等。它是一個基類,不同的聲明表達(dá)式都繼承自它。如VarDecl類、 FunctionDecl類电湘。

2.語句類Stmt

- Stmt用于表示在源代碼中的語句胡桨,包括簡單語句和復(fù)雜語句呢诬,程序中的函數(shù)都是由語句組成的尚镰。

3.Stmt也是一個基類阀圾,不同的語句都繼承自它。

- 在C語言中最簡單的語句形式是表達(dá)式狗唉。

- 大多數(shù)C語言語句是這類形式的初烘,其他簡單語句是跳轉(zhuǎn)語句包括return、continue分俯、goto.

-? 復(fù)雜語句由簡答語句組成肾筐,可分為兩類:跳轉(zhuǎn)語句和循環(huán)語句,跳轉(zhuǎn)語句包括if/else缸剪、switch吗铐,循環(huán)語句包括while、do-while和for循環(huán)結(jié)構(gòu)杏节。

查看抽象語法樹

系統(tǒng)提供一個內(nèi)置的ast-dump方法唬渗,可以把整段代碼按照AST結(jié)構(gòu)翻譯成人類可以讀懂的格式典阵。這種格式基于遍歷整段代碼,然后按照代碼結(jié)構(gòu)對AST節(jié)點進(jìn)行相應(yīng)層次結(jié)構(gòu)的組合镊逝。

Demo:test.cc

int f(int x) {

int result=(x/42);?

return result;

默認(rèn)情況下壮啊,Clang 是許多工具的前端;-Xclang 用于將選項直接傳遞給 C++的前端。

-fsyntax-only 只進(jìn)行語法檢查蹋半,不進(jìn)行編譯他巨。

查看一下上面代碼對應(yīng)生成的抽象語法樹AST:

clang -Xclang -ast-dump -fsyntax-only test.cc

?- 在一個翻譯單元中的頂層聲明始終是translation unitdeclaration

- 聲明是一個“f”的函數(shù),則f的主體是一個符合語句類型的節(jié)點(CompoundStmt)减江,它的子節(jié)點則是聲明語句(DeclStmt)節(jié)點,和返回語句(ReturnStmt)節(jié)點捻爷。

- Clang的AST節(jié)點是基于層級關(guān)系組合在一起的辈灼。


自定義檢查器注冊

注冊接口介紹

1. 基于抽象語法樹匹配的缺陷檢測主要分為兩個部分:

- 一部分是匹配機(jī)制的實現(xiàn),由基于抽象語法樹匹配器的注冊組成也榄。

- 一部分是匹配對象的實現(xiàn)巡莹,主要包括聲明類Decl、語句類Stmt甜紫。

void registerMatchers(ast matchers::MatchFinder*Finder)override

void check(const ast matchers::MatchFinder::MatchResult &Result)override;


2.通過add_new_check.py腳本添加自定義check

此處為check創(chuàng)建到misc類別降宅,自定義為CcTestCheckCheck,用于測試

./add_new_check.py misc cc-test-check(會自動將cc-test-check生成對應(yīng)的基礎(chǔ)demo囚霸,主要修改CcTestCheckCheck.cpp實現(xiàn)功能)

使能自定義checker

- 編寫checker后重新編譯項目:?

cd <path of llvm>/build/

ninja開始編譯

sudo ninja install安裝到系統(tǒng)

- 安裝后查看編寫的 checker

clang-tidy --list-checks --checks=misc*


- 運用編寫的checker

clang-tidy --checks=-*,misc-cc-test-check test.cc --?


- Note:如果要dump內(nèi)容包含引用頭文件腰根,建議加上-nostdinc++

clang -Xclang -ast-dump -nostdinc++ -fsyntax-only CcTestCheckCheck.cpp

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市拓型,隨后出現(xiàn)的幾起案子额嘿,更是在濱河造成了極大的恐慌,老刑警劉巖劣挫,帶你破解...
    沈念sama閱讀 216,919評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件册养,死亡現(xiàn)場離奇詭異,居然都是意外死亡压固,警方通過查閱死者的電腦和手機(jī)球拦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來帐我,“玉大人坎炼,你說我怎么就攤上這事》俑眨” “怎么了点弯?”我有些...
    開封第一講書人閱讀 163,316評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長矿咕。 經(jīng)常有香客問我抢肛,道長狼钮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,294評論 1 292
  • 正文 為了忘掉前任捡絮,我火速辦了婚禮熬芜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘福稳。我一直安慰自己涎拉,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,318評論 6 390
  • 文/花漫 我一把揭開白布的圆。 她就那樣靜靜地躺著鼓拧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪越妈。 梳的紋絲不亂的頭發(fā)上季俩,一...
    開封第一講書人閱讀 51,245評論 1 299
  • 那天,我揣著相機(jī)與錄音梅掠,去河邊找鬼酌住。 笑死,一個胖子當(dāng)著我的面吹牛阎抒,可吹牛的內(nèi)容都是我干的酪我。 我是一名探鬼主播,決...
    沈念sama閱讀 40,120評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼且叁,長吁一口氣:“原來是場噩夢啊……” “哼都哭!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起谴古,我...
    開封第一講書人閱讀 38,964評論 0 275
  • 序言:老撾萬榮一對情侶失蹤质涛,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后掰担,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體汇陆,經(jīng)...
    沈念sama閱讀 45,376評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,592評論 2 333
  • 正文 我和宋清朗相戀三年带饱,在試婚紗的時候發(fā)現(xiàn)自己被綠了毡代。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,764評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡勺疼,死狀恐怖教寂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情执庐,我是刑警寧澤酪耕,帶...
    沈念sama閱讀 35,460評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站轨淌,受9級特大地震影響迂烁,放射性物質(zhì)發(fā)生泄漏看尼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,070評論 3 327
  • 文/蒙蒙 一盟步、第九天 我趴在偏房一處隱蔽的房頂上張望藏斩。 院中可真熱鬧,春花似錦却盘、人聲如沸狰域。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽兆览。三九已至,卻和暖如春塞关,著一層夾襖步出監(jiān)牢的瞬間拓颓,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評論 1 269
  • 我被黑心中介騙來泰國打工描孟, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人砰左。 一個月前我還...
    沈念sama閱讀 47,819評論 2 370
  • 正文 我出身青樓匿醒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親缠导。 傳聞我的和親對象是個殘疾皇子廉羔,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,665評論 2 354

推薦閱讀更多精彩內(nèi)容