P1: 基础结构性分析¶
基础结构性分析是莲花语义分析流程的起点。其目标并非推导程序的详细运行语义,而是通过全局遍历,系统性地清点程序结构,为后续深入分析奠定基础。
该阶段的实现位于src/lian/basics,由BasicAnalysis.run()统一驱动,分析对象为GIR语句。所有分析结果均以全局唯一的语句ID(stmt_id)为索引进行组织和存储。这一阶段主要回答“程序中有什么?”、“它们位于哪里?”以及“彼此如何组织?”这三类基础问题。
1 程序入口点识别¶
入口点识别用于确定程序分析的起始位置,由EntryPointGenerator模块负责。
该模块依据default_settings/entry.yaml配置文件中定义的规则(如方法名、修饰属性或文件位置),扫描所有函数或方法声明语句,并将满足条件的语句标记为入口点。识别结果以指令ID集合形式存储,用于指导后续调用图构建和可达性分析。
需要注意的是,入口点分析本身并不引入控制流或数据流推理,其作用仅在于为后续分析阶段提供一个可靠的分析起点集合。
2 作用域层级分析¶
作用域层级分析负责建立程序的作用域骨架,并明确每个符号的静态归属关系。该分析主要由ScopeHierarchy模块完成。
分析过程中,系统遍历每个Unit(文件)内的GIR声明语句,并在遇到类、函数或代码块边界时创建对应的Scope对象,并通过递归查找父作用域(如determineScope)确定最终的作用域归属。对于类成员、函数参数等在语法结构中容易出现歧义的符号,分析阶段会对其作用域归属进行修正,以保证后续符号解析行为的一致性。
分析结果集中存储于ScopeSpace中,用于维护所有作用域节点及其父子关系;同时会为每个Unit生成总结UnitSymbolDeclSummary,记录每个文件中标识符名称到其声明作用域的映射。这两类数据结构为后续变量解析和跨作用域引用分析提供直接支撑。
3 模块与导入关系分析¶
模块与导入关系分析用于恢复跨文件、跨模块的符号依赖结构,对应实现模块为ImportHierarchy。
分析阶段首先识别每个Unit对外可见的导出符号集合,随后解析GIR中的导入语句,解析导入项到导出项的绑定。在实现上,这一过程不仅建立Unit之间的依赖关系,还会将依赖精确到符号级别。对于通配导入(如import *)或间接导入的情况,系统会递归展开目标模块的导出项,以确保所有被引用的符号都能追溯到其原始定义。
所得到的模块与导入层级关系被组织为导入图ImportGraph,用于精确描述符号级引用关系。这种依赖结构从目录结构到文件再到公开符号,形成多层依赖视图。
4 类型层级分析¶
类型层级分析主要针对面向对象语言和静态语言中的类型别名(Type alias),用于恢复类继承结构(Class Hierarchy)及类成员的静态可见性和类型别名。该分析由TypeHierarchy模块完成。
分析过程中,系统遍历所有类声明语句,解析继承信息并构建类继承和类型别名图(TypeGraph)。在此基础上,系统进一步计算每个类在静态语义层面可用的方法集合,即合并类自身定义的方法和从父类继承的方法,生成MethodsInClass表,供后续方法调用解析使用。
这一阶段并不处理动态分派或运行时多态,仅提供稳定的类成员视图,供后续调用解析和指针分析阶段使用。
5 控制流分析¶
控制流分析用于为每个函数构建控制流图(CFG),对应实现模块为ControlFlowAnalysis。值得注意的是,控制流分析以函数为基本单位,为每个函数独立构建CFG。
分析以函数体为单位展开,语句ID作为图节点,控制流边用于描述可能的执行顺序关系。在构建过程中,系统会根据GIR中的结构化语句类型(如条件、循环、异常处理)添加相应的控制流边。对于return、break、throw等中断顺序执行的语句,则通过延迟连接的方式,在结构闭合时补全其控制流关系。
分析结果以MethodCfg的形式存储,为后续的函数内数据流分析提供执行路径基础。
6 定义-使用(Def-Use)关系分析¶
在已有作用域结构和控制流图的基础上,定义-使用分析用于识别变量在程序中的定义点与使用点,对应实现模块为StmtDefUseAnalysis。与控制流分析类似,定义-使用分析以函数为单位展开。
该阶段沿控制流遍历函数体内的GIR指令,依据指令类型识别变量的定义和使用,分析结果被记录在每条语句对应的状态StmtStatus。为变量与常量创建的统一存储空间(SymbolStateSpace),用于承载分析过程中生成的变量和常量对象。
该阶段还肩负着变量ID化的重要任务,即将程序中的每个变量分配或映射为一个唯一的符号ID。如果引用的变量在本文件内,则直接使用符号ID;如果引用的变量是跨文件或跨模块的,则需通过查询导入图(参见第3节:模块与导入关系分析)解析其所属模块,并从目标模块的符号表中获取对应的全局符号ID。
当得到所有指令的def-use关系后,可为该函数生成摘要信息MethodDefUseSummary,包含本地变量集、外部引用符号、参数列表及返回值表达式等。
7 总结¶
综上所述,基础结构性分析阶段完成了对程序静态结构的系统性清点与组织。通过统一的GIR表示,系统在不依赖类型推导、不进行不动点计算的前提下,建立了程序的入口集合、作用域与符号的层级关系、跨模块的符号依赖结构、类与类之间的继承关系、函数内部的控制流骨架以及变量的定义与使用位置。这一阶段的所有分析结果均以稳定的数据结构形式保存,作为后续语义分析的事实基础。