gcc源碼分析(AST抽象語法樹)

文章目錄

  • 三、AST相關
    • 1、AST(抽象語法樹)
      • 1.1 樹結點的聲明
      • 1.2 樹結點的結構
        • 1.2.1 tree_node聯合體
        • 1.2.2 tree_base結構體
        • 1.2.3 tree_common結構體
        • 1.2.4 常量結構體
        • 1.2.5 **標識符節點**
    • 2、符號綁定,作用域與block樹節點
      • 2.1 lang_identifier結構體
      • 2.2 c_binding結構體
      • 2.3 scope與作用域
    • 3、 作用域
      • 3.1 作用域的初始化
      • 3.2 push_scope
      • 3.3 bind
      • 3.4 pop_scope

三、AST相關

抽象語法樹是編譯系統中最常見的一種樹形的中間表示形式,用來對前端語言的源代碼進行規范的抽象表示。不同的高級程序設計語言通過其相應的詞法/語法分析過程,會得到不同形式的抽象語法樹,這些抽象語法樹與編程語言的特征緊密相關,一般都包含了部分語言相關的AST節點表示。從這個角度上來講,AST是編程語言相關的, C語言的源代碼經過C語言特定的詞法/語法分析過程,將生成C語言的AST。

1、AST(抽象語法樹)

在gcc中GENERIC是指規范的AST,,即GENERIC形式的AST均能在gcc/tree. h中所表示的樹節點表示。引入GENERIC的目的是尋找一種與前端語言無關的AST統一表示,是一種通用的處理tree_identifier而已。AST這種樹形的中間表示,主要包括:樹節點的種類及其語義、樹節點的存儲、AST操作以及AST的生成過程等。

1.1 樹結點的聲明

樹節點聲明中最基本的4個概念:

  • 標識(TREE_CODE):DEFTREECODE宏定義中的SYM參數,描述了該節點代表的是一個什么樣的節點。
  • 名稱(NAME):DEFTREECODE宏定義中的NAME參數,表示該樹節點的名稱,使用字符串來描述,主要用來進行AST中間結果的顯示,方便用戶直觀地了解該樹節點的信息。
  • 類型(TREE_CODE CLASS, TCC):DEFTREECODE宏定義中的TYPE參數,描述了該樹節點的TREE_CODE所屬的類型。
  • 長度:DEFTREECODE宏定義中的LEN參數,用來描述該樹節點所包含的操作數的數目。

用下面這種宏去定義:

DEFTREECODE (ERROR_MARK, "error_mark", tcc_exceptional, 0)

樹節點的類型主要包括了常量節點、類型節點、聲明節點、比較表達式節點、單目運算表達式節點、雙目運算表達式節點等。

1.2 樹結點的結構

1.2.1 tree_node聯合體

tree_node聯合體定義了全部樹結點結構體。

## gcc/tree-core.h
union GTY ((ptr_alias (union lang_tree_node),desc ("tree_node_structure (&%h)"), variable_size)) tree_node {struct tree_base GTY ((tag ("TS_BASE"))) base;struct tree_typed GTY ((tag ("TS_TYPED"))) typed;
.......
}
1.2.2 tree_base結構體

其中最關鍵的是tree_base結構體:該結構體定義了所有樹節點最基本的屬性,是構成其他樹節點存儲結構的基類(類似于面向對象的概念,這個思想在gcc中大量使用)。其主要包括了code字段,用來存儲TREE_CODE,并標識該樹節點的語義,其取值在枚舉類型enum tree_code中取值。tree_base結構體中還定義了大量的標志字段,分別描述該樹節點的某些語法、語義的信息,例如常量標志、無符號標志、只讀標志等。

struct GTY(()) tree_base {ENUM_BITFIELD(tree_code) code : 16;unsigned side_effects_flag : 1;unsigned constant_flag : 1;unsigned addressable_flag : 1;unsigned volatile_flag : 1;unsigned readonly_flag : 1;unsigned asm_written_flag: 1;unsigned nowarning_flag : 1;unsigned visited : 1;unsigned used_flag : 1;unsigned nothrow_flag : 1;unsigned static_flag : 1;unsigned public_flag : 1;unsigned private_flag : 1;unsigned protected_flag : 1;unsigned deprecated_flag : 1;unsigned default_def_flag : 1;.......
}
1.2.3 tree_common結構體

tree chain字段可以將多個有一定關系的樹節點連接成一個鏈表。tree type字段的值在不同的樹節點中有不同的含義。例如,在所有表達式節點中,type字段指向表達式的類型節點;在指針類型節點(其TREE_CODE為POINTER_TYPE)中,此字段指向指針所指向的類型節點;在數組引用節點(其TREE_CODE為ARRAY_TYPE)中,此字段指向數組元素的類型節點;在TREE_CODE為VECTOR_TYPE的樹節點中,該字段指向向量元素的類型節點。通常使用TREE_TYPE(node)宏來訪問node節點的type字段。

struct GTY(()) tree_typed {struct tree_base base;tree type;
};struct GTY(()) tree_common {struct tree_typed typed;tree chain;/**將多個有一定關系的樹節點連接成一個鏈表/
};
1.2.4 常量結構體

gcc中定義了struct tree_int_cst、struct tree_real_cst、struct tree_fixed_cst、struct tree_vector、struct tree_string、struct tree_complex等幾種結構體,分別存儲整型常量、實數常量、定點數常量、向量常量、字符串常量以及復數常量。

//1、整型常量
struct GTY(()) tree_int_cst {struct tree_typed typed;HOST_WIDE_INT val[1];
};  
//2、實數常量
/*結構體struct tree_real_cst用來存儲實數常量*/
struct GTY(()) tree_real_cst {struct tree_typed typed;struct real_value * real_cst_ptr;
};
//3、定點數常量
struct GTY(()) tree_fixed_cst {struct tree_typed typed;struct fixed_value * fixed_cst_ptr;
};
/*
常用的宏定義:#define TREE_FIXED_CST_PTR(NODE) (FIXED_CST_CHECK (NODE)->fixed_cst.fixed_cst_ptr)#define TREE_FIXED_CST(NODE) (*TREE_FIXED_CST_PTR (NODE))
*/
//4、字符串常量
/*字符串使用struct tree_string結構體來存儲*/
struct GTY(()) tree_string {struct tree_typed typed;int length;char str[1];
};
/*這部分可以分析內存信息:字符串常量節點所描述的字符串常量就存儲在struct tree_string中以str成員指向的地址空間中*/
//5.復數常量
struct GTY(()) tree_complex {struct tree_typed typed;tree real;tree imag;
};
/*
下面兩個宏分別用來訪問該實數常量的實部(real字段)和虛部(imag字段),這兩個字段均為指向樹節點的指針。#define TREE_REALPART(NODE) (COMPLEX_CST_CHECK (NODE)->complex.real)#define TREE_IMAGPART(NODE) (COMPLEX_CST_CHECK (NODE)->complex.imag)
*/
//6、向量常量
struct GTY(()) tree_vector {struct tree_typed typed;tree GTY ((length ("TYPE_VECTOR_SUBPARTS (TREE_TYPE ((tree)&%h))"))) elts[1];    //用以獲取節點的各個向量
};
1.2.5 標識符節點

標識符節點使用struct tree_identifier結構體存儲,定義如下:

struct GTY(()) tree_identifier {struct tree_common common;/*struct tree_common common結構體字段描述了該樹節點的基本屬性。*/struct ht_identifier id;
};struct GTY(()) ht_identifier {const unsigned char *str;unsigned int len;unsigned int hash_value;
};

上述的struct ht_identifier在libcpp/include/symtab.h中予以定義,該結構體中的str和len字段分別描述該標識符對應的字符串名稱及其長度,hash_value是該標識符名稱的一個hash值,該hash值在標識符的查找、比較等操作中使用。

注:AST是源代碼在GCC系統中的一種中間表示形式,該中間形式是通過GCC前端的詞法/語法分析所構造的。

其他的樹結點的結構不做詳細介紹,有興趣可自行查看。

2、符號綁定,作用域與block樹節點

2.1 lang_identifier結構體

在前面已知gcc中通過一個tree_identifier結構體來代表一個標識符的樹節點,但實際分配時會為標識符分配一個擴展的lang_identifier節點,其結構如下:

struct GTY(()) lang_identifier {struct

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/15070.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/15070.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/15070.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

HLS視頻加密,讓您的視頻內容更安全!

背景介紹 HLS視頻加密是一種基于HTTP Live Streaming(HLS)協議的加密技術。它的核心思想是將視頻切片進行加密處理,在客戶端播放時需要先獲取解密密鑰才能正常偶發。通過這種方式,HLS加密可以有效防止未經授權的第三方竊取視頻內…

測試短信推薦參考

短信測試參考 國外: smstome 支持多個國家號碼 官網地址: https://smstome.com/ quackr.io 支持多個國家號碼 官網地址: https://quackr.io/ receive-smss 支持多個國家號碼 地址: https://receive-smss.com/ receive-sms-fr…

C#字典的常用方法

C#的字典(Dictionary)類是一個通用的集合類,它實現了鍵值對的存儲和訪問。以下是一些常用的字典方法: Add(key, value):向字典中添加一個指定的鍵值對。Remove(key):從字典中移除具有指定鍵的元素。Contai…

LLM大模型的7種推理框架分析

LLM的7種推理框架 Hugging Face的transformers 這是一個Python庫,可以簡化本地運行LLM的過程。 Transformers的優點: 自動模型下載提供代碼片段非常適合實驗和學習 Transformers的缺點: 需要對ML和NLP有深入了解需要編碼和配置技能 2.L…

深度學習之基于Tensorflow低光增強的深層Retinex分解

歡迎大家點贊、收藏、關注、評論啦 ,由于篇幅有限,只展示了部分核心代碼。 文章目錄 一項目簡介 二、功能三、系統四. 總結 一項目簡介 一、項目背景與意義 在圖像處理領域,低光照環境下的圖像增強是一個具有挑戰性的問題。為了提高圖像的可…

紐曼新品X1000:輕巧便攜僅重9.9公斤的1度電應急電源

在戶外救援行動和應急設備中,電力供應的穩定性和安全性直接影響到救援工作的效率和成功率。在現代救援工作中,常見的光學聲波探測儀、通信聯絡設備、氣象檢測儀、生命探測儀、照明設備等裝備均需有持續的電力供應,才能保障救援工作的有序開展…

西門子WINCC8.0VBS腳本學習講解

WinCC VBS腳本置位/復位/取反 二進制變量 "TAG1_BOOL1" 進行置位復位取反操作 步驟:按鈕-->對象屬性-->事件-->單擊鼠標VBS動作填入代碼如下: 對二進制變量進行復位 對二進制變量進行置位 對二進制變量進行取反 VBS腳本數學運算/讀寫批處理 …

第十六講:數據在內存中的存儲

第十六講:數據在內存中的存儲 1.整數在內存中的存儲1.1存儲方式1.2大小端字節序1.3大小端字節序排序規則1.4為什么要有大小端1.5練習1.5.1練習11.5.2練習21.5.3練習31.5.4練習41.5.5練習51.5.6練習61.5.7練習7 2.浮點數在內存中的存儲2.1練習2.2浮點數的存儲2.3浮點…

如何將數據從一部手機傳輸到另一部手機[安全快速]

概括 手機之間無需使用藍牙即可傳輸文件,配合專業的文件傳輸工具更高效。本文將向您介紹幾種使用不同的數據傳輸工具快速安全地將數據從一部手機傳輸到另一部手機的方法,特別是當有大文件或大量文件時。現在,我們來看看。 需要在朋友或家人之…

Rust 賦能前端 -- 寫一個 File 轉 Img 的功能

所有耀眼的成績,都需要苦熬,熬得過,出眾;熬不過,出局 大家好,我是柒八九。一個專注于前端開發技術/Rust及AI應用知識分享的Coder 此篇文章所涉及到的技術有 Rustwasm-bindgen/js-sys/web-sysWeb WorkerWebAssemblyWebpack/Vite配置WebAssemblyOffscreenCanvas腳手架生成項…

校園二手書交易|基于SprinBoot+vue的校園二手書交易管理系統(源碼+數據庫+文檔)

校園二手書交易管理系統 目錄 基于SprinBootvue的校園二手書交易管理系統 一、前言 二、系統設計 三、系統功能設計 1系統功能模塊 2管理員功能模塊 3 賣家用戶功能模塊 4 用戶功能模塊 四、數據庫設計 五、核心代碼 六、論文參考 七、最新計算機畢設選題推薦 八…

Linux:iptables防火墻部署優化之連接轉移(目的地地址轉化)

Linux:iptables防火墻部署優化之連接轉移(目的地地址轉化) 文章目錄 Linux:iptables防火墻部署優化之連接轉移(目的地地址轉化)node1操作檢測ip情況關閉firewalld防火墻服務,并鎖定該服務開啟ip…

什么是分布式會話

分布式會話是指在分布式系統中實現用戶會話管理的一種機制。在傳統的單服務器架構中,用戶的會話數據通常存儲在單個服務器或應用服務器的內存中。然而,隨著業務的發展和用戶量的增加,單服務器架構往往無法滿足高可用性和高并發的需求&#xf…

Minio WebUploader上傳文件的高級用法之進度條顯示、文件過濾、圖片預覽、圖片壓縮

系列文章目錄 第十章 Minio WebUploader上傳文件的高級用法之進度條顯示、文件過濾、圖片預覽、圖片壓縮 Minio WebUploader上傳文件的高級用法之進度條顯示、文件過濾、圖片預覽、圖片壓縮 系列文章目錄進度條顯示文件過濾圖片預覽圖片壓縮 進度條顯示 使用進程文件上傳時&a…

基于springboot+html的二手交易平臺(附源碼)

基于springboothtml的二手交易平臺 介紹部分界面截圖如下聯系我 介紹 本系統是基于springboothtml的二手交易平臺,數據庫為mysql,可用于畢設或學習,附數據庫 部分界面截圖如下 聯系我 VX:Zzllh_

java Iterable和 Iterator接口區別和聯系

Iterable 和 Iterator 是 Java 集合框架中用于遍歷集合元素的兩個接口,它們之間既有區別也有聯系。下面詳細介紹它們的區別和聯系。 Iterable 接口 定義 Iterable 接口位于 java.lang 包中,定義如下: public interface Iterable<T> {Iterator<T> iterator()…

在家庭影院音頻中應用的D類音頻放大器

家庭影院的主要組成部分包括顯示設備、音響設備、信號源和接線設備等。家庭影院的音響信號需要進行處理和輸出&#xff0c;以獲得高質量的音效。音響設備通常需要一臺功率適當的數字、模擬混合的處理器&#xff0c;對音源進行降噪、均衡、擴展等處理操作&#xff0c;以達到高品…

核心交換機與終端通信正常,接入交換機無法Ping通同一VLAN內終端

環境: 思科3560交換機 問題描述: 核心交換機與PC通信正常,接入交換機無法Ping通同一VLAN內PC h3c核心交換機配置vlan2 vlanif2 IP192.168.1.1 下掛接入交換機配置了vlan2 pc接到接入交換機25口這個端口配置access vlan2,pc的ip是192.168.1.3從 核心交換機上ping192.168.…

【智能算法應用】北方蒼鷹算法求解二維柵格路徑規劃問題

目錄 1.算法原理2.二維路徑規劃數學模型3.結果展示4.參考文獻5.代碼獲取 1.算法原理 【智能算法】北方蒼鷹優化算法&#xff08;NGO)原理及實現 2.二維路徑規劃數學模型 柵格法模型最早由 W.E. Howden 于 1968 年提出&#xff0c;障礙物的柵格用黑色表示&#xff0c;可通過的…

ping 探測網段哪些地址被用

#!/bin/bash# 遍歷192.168.3.1到192.168.3.254 for i in {1..254} doip"192.168.3.$i"# 對每個IP地址進行三次ping操作if ping -c 3 -W 1 $ip > /dev/null 2>&1thenecho "$ip: yes"fi done$ sh test.sh 192.168.3.1: yes 192.168.3.95: yes 192.…