当前位置: 首页 > article >正文

GCC RISCV 后端 -- C语言语法分析过程

        在 GCC 编译一个 C 源代码时,先会通过宏处理,形成 一个叫转译单元(translation_unit),接着进行语法分析,C 的语法分析入口是

static void c_parser_translation_unit(c_parser *parser);

        接着就通过类似递归下降解析器(Recursive descent parser)的方式进行语法解析。当完成一个函数的解析后,会将该函数加入到符号表(Symbol Table)中的调用图(Call Graph)的节点集(nodes)中。通过下面 gdb 的 backtrace 可以看到:

#0  cgraph_node::get_create (decl=0x7ffff79b2700) at <gcc-project>/gcc/cgraph.cc:537
#1  0x00000000012d06d4 in c_genericize (fndecl=0x7ffff79b2700) at <gcc-project>/gcc/c-family/c-gimplify.cc:796
#2  0x00000000011587ec in finish_function (end_loc=33408) at <gcc-project>/gcc/c/c-decl.cc:11501
#3  0x00000000011d9734 in c_parser_declaration_or_fndef at <gcc-project>/gcc/c/c-parser.cc:3010
#4  0x00000000011d680e in c_parser_external_declaration (parser=0x7ffff7fbc5b0) at <gcc-project>/gcc/c/c-parser.cc:2088
#5  0x00000000011d6254 in c_parser_translation_unit (parser=0x7ffff7fbc5b0) at <gcc-project>/gcc/c/c-parser.cc:1952
#6  0x000000000123cf9e in c_parse_file () at <gcc-project>/gcc/c/c-parser.cc:29613
#7  0x00000000012f68c8 in c_common_parse_file () at <gcc-project>/gcc/c-family/c-opts.cc:1379
#8  0x0000000001bd64d3 in compile_file () at <gcc-project>/gcc/toplev.cc:452
#9  0x0000000001bd9b1e in do_compile () at <gcc-project>/gcc/toplev.cc:2200
#10 0x0000000001bd9fb9 in toplev::main (this=0x7fffffffd3d2, argc=19, argv=0x7fffffffd518) at <gcc-project>/gcc/toplev.cc:2354
#11 0x0000000004482a35 in main (argc=19, argv=0x7fffffffd518) at <gcc-project>/gcc/main.cc:39

        cgraph_node::get_create 就是对于一个解析后的函数所构建的调用图中的节点,调用节点(cgraph_node)。

        由此可见,符号表(Symbol Table)会包含整个转译单元中的符号,对于函数的话,会形成对应的调用节点(cgraph_node:symtab_node)。

        此时,加入以调用节点加入到符号表中的函数是已经解析好,以GENERIC 中间语言所表示的。

        加入后,cc1 调用 cgraph_node::finalize_function 进一步处理。如下图所描述的。

        这里,关键是说明 C 源代码在解析(Parse)后,所存在的形式,如何提供到后面基于过程(Pass)机制的处理。

        那么此时,在compile_file函数中,如下图:

        经过 lang_hooks.parse_file (); 后,gcc 已经将C的源代码解析完毕(Parsed)并以调用图的方式存放符号表(Symbol Table)中。

        在接着的 symtab->finalize_compilation_unit (); 就开始通过以处理过程(Passes)的方式,将GENERIC中间语言转换成最终的汇编语言。 

 


http://www.kler.cn/a/574590.html

相关文章:

  • C# OnnxRuntime部署DAMO-YOLO人头检测
  • 《基于WebGPU的下一代科学可视化——告别WebGL性能桎梏》
  • Unity 小功能
  • Linux 开发工具
  • 【微知】Mellanox驱动中to是什么?有哪些超时时间?(time out,心跳2s,reset 1分钟)
  • Docker的常用镜像
  • 如何将一台服务器的pip环境迁移到另一个机器?
  • MoE 架构:专家齐聚,智启未来 —— 解锁传统稠密模型的瓶颈
  • 某书x-s参数更新自动化获取密钥iv脚本
  • 网页制作11-html,css,javascript初认识のCCS样式列表(下)
  • Go学习笔记:基础语法6
  • 庭田科技携手西门子工业软件成功举办振动噪声技术研讨会
  • 从“0”开始入门PCB之(5)完结篇!--快速入门原理图DRC,PCB的符号与布局,2D与3D效果,PCB的图层和布线,PCB板框
  • 攻防世界WEB(新手模式)19-file_include
  • 机器视觉运动控制一体机在天地盖同步跟随贴合解决方案
  • 三数之和~
  • 快手,蓝禾,得物,优博讯,三七互娱,顺丰,oppo,游卡,汤臣倍健,康冠科技,作业帮25届春招内推
  • std::string的模拟实现
  • Windows 图形显示驱动开发-WDDM 3.2-本机 GPU 围栏对象(三)
  • 数据结构与算法:希尔排序