CN113326047A - 基于静态分析的c语言代码依赖关系提取方法 - Google Patents
基于静态分析的c语言代码依赖关系提取方法 Download PDFInfo
- Publication number
- CN113326047A CN113326047A CN202110650142.2A CN202110650142A CN113326047A CN 113326047 A CN113326047 A CN 113326047A CN 202110650142 A CN202110650142 A CN 202110650142A CN 113326047 A CN113326047 A CN 113326047A
- Authority
- CN
- China
- Prior art keywords
- node
- dependency relationship
- file
- symbol
- function
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Granted
Links
- 230000003068 static effect Effects 0.000 title claims abstract description 34
- 238000000605 extraction Methods 0.000 title claims abstract description 12
- 230000006870 function Effects 0.000 claims abstract description 283
- 230000002085 persistent effect Effects 0.000 claims abstract description 8
- 238000000034 method Methods 0.000 claims description 30
- 230000001419 dependent effect Effects 0.000 claims description 5
- 239000003607 modifier Substances 0.000 claims description 3
- 238000005516 engineering process Methods 0.000 description 6
- 239000012634 fragment Substances 0.000 description 6
- 230000000694 effects Effects 0.000 description 2
- 230000008878 coupling Effects 0.000 description 1
- 238000010168 coupling process Methods 0.000 description 1
- 238000005859 coupling reaction Methods 0.000 description 1
- 238000001514 detection method Methods 0.000 description 1
- 238000010586 diagram Methods 0.000 description 1
- 230000007774 longterm Effects 0.000 description 1
- 238000012986 modification Methods 0.000 description 1
- 230000004048 modification Effects 0.000 description 1
- 230000002688 persistence Effects 0.000 description 1
- 238000007781 pre-processing Methods 0.000 description 1
- 238000011084 recovery Methods 0.000 description 1
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/40—Transformation of program code
- G06F8/41—Compilation
- G06F8/43—Checking; Contextual analysis
- G06F8/433—Dependency analysis; Data or control flow analysis
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/30—Creation or generation of source code
- G06F8/36—Software reuse
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/40—Transformation of program code
- G06F8/41—Compilation
- G06F8/43—Checking; Contextual analysis
- G06F8/436—Semantic checking
- G06F8/437—Type checking
-
- Y—GENERAL TAGGING OF NEW TECHNOLOGICAL DEVELOPMENTS; GENERAL TAGGING OF CROSS-SECTIONAL TECHNOLOGIES SPANNING OVER SEVERAL SECTIONS OF THE IPC; TECHNICAL SUBJECTS COVERED BY FORMER USPC CROSS-REFERENCE ART COLLECTIONS [XRACs] AND DIGESTS
- Y02—TECHNOLOGIES OR APPLICATIONS FOR MITIGATION OR ADAPTATION AGAINST CLIMATE CHANGE
- Y02D—CLIMATE CHANGE MITIGATION TECHNOLOGIES IN INFORMATION AND COMMUNICATION TECHNOLOGIES [ICT], I.E. INFORMATION AND COMMUNICATION TECHNOLOGIES AIMING AT THE REDUCTION OF THEIR OWN ENERGY USE
- Y02D10/00—Energy efficient computing, e.g. low power processors, power management or thermal management
Landscapes
- Engineering & Computer Science (AREA)
- General Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Software Systems (AREA)
- Physics & Mathematics (AREA)
- General Physics & Mathematics (AREA)
- Computational Linguistics (AREA)
- Stored Programmes (AREA)
Abstract
本发明公开了一种基于静态分析的C语言代码依赖关系提取方法,包括以下步骤:对C语言源代码进行静态分析,获得各条宏指令的信息以及各个变量、函数、类型的信息;对每条宏指令,基于宏指令信息提取该条宏指令产生的依赖关系;对每个变量,基于每条变量信息提取该变量产生的依赖关系;对每个函数,基于每条函数信息提取该函数产生的依赖关系;对每个类型,基于类型信息提取该类型产生的依赖关系;基于符号级的依赖关系提取文件级的依赖关系;持久化提取到的依赖关系;以实现从C语言源码中提取更加全面、更加精确、多层次的依赖关系。
Description
技术领域
本发明涉及计算机技术和软件工程领域,特别涉及基于静态分析的C语言代码依赖关系提取方法。
背景技术
随着现代软件技术的发展,软件项目规模趋于庞大,文件、模块之间的耦合关系趋于复杂,传统基于经验的软件架构设计方法的门槛也越来越高。因此,自动化地对代码进行静态分析,提取软件项目多层次的依赖关系显得越来越重要。同时,软件项目的依赖关系也是实现架构分析、软件重构等功能所必需的底层支持数据。
同时,已有的静态分析的工作通常针对特定需求,侧重特定领域提取部分依赖关系,如函数调用关系、数据流关系、类之间的依赖关系等,没有试图提取一种更全面的、更精确、多层次的依赖关系。
并且,C语言作为一门古老的计算机编程语言,它在今天仍被广泛用于嵌入式、操作系统等领域的开发。但是由于它自身设计时带有复杂的宏,并且不支持包的概念,对依赖分析带来了一定的挑战,相关的针对C语言代码的依赖分析工作更加不足。
因此,需要一种基于静态分析的C语言代码依赖关系提取方法,以实现从C语言源代码中获得更全面、准确、多层次的依赖关系。
发明内容
为此,需要提供一种基于静态分析的C语言代码依赖关系提取方法,以实现从C语言源码中提取更加全面、更加精确、多层次的依赖关系。
为实现上述目的,发明人提供了一种基于静态分析的C语言代码依赖关系提取方法,包括以下步骤:
S1:对C语言源代码进行静态分析,获得各条宏指令的信息以及各个变量、函数、类型的信息;
S2:对每条宏指令,基于宏指令信息提取该条宏指令产生的依赖关系;
S3:对每个变量,基于每条变量信息提取该变量产生的依赖关系;
S4:对每个函数,基于每条函数信息提取该函数产生的依赖关系;
S5:对每个类型,基于类型信息提取该类型产生的依赖关系;
S6:基于符号级的依赖关系提取文件级的依赖关系;
S7:持久化提取到的依赖关系。
作为本发明的一种优选方式,所述宏指令信息,包括:宏包含指令信息,宏定义指令信息,宏条件判断指令信息和宏展开指令信息。
作为本发明的一种优选方式,宏包含指令信息包括:该指令包含的文件,该指令所在的源代码文件;宏定义指令信息包括:该指令定义的宏符号名,该指令所在的源代码文件;宏条件判断指令信息包括:该指令进行条件判断使用的宏符号名,该指令所在的源代码文件;宏展开指令信息包括:该指令展开的宏符号名,该指令所在的源代码文件。
作为本发明的一种优选方式,所述对每条宏指令,基于宏指令信息提取该条宏指令产生的依赖关系,包括:提取宏包含指令信息产生的依赖关系,提取宏定义指令信息产生的依赖关系,提取宏条件判断指令信息产生的依赖关系,提取宏展开指令信息产生的依赖关系。
作为本发明的一种优选方式,所述提取宏包含指令信息产生的依赖关系,包括:T101:如果该指令所在的源代码文件为首次出现,为该指令所在的源代码文件创建文件节点;T102:如果该指令包含的文件为首次出现,为该指令包含的文件创建文件节点;T103:在该指令所在的源代码文件和该指令包含的文件之间添加依赖关系,依赖关系起点为指令所在的源代码文件对应的文件节点,终点为该指令包含的文件对应的文件节点,依赖关系类型为包含依赖。
作为本发明的一种优选方式,所述提取宏定义指令信息产生的依赖关系,包括:T201:如果该指令所在的源代码文件为首次出现,为该指令所在的源代码文件创建文件节点;T202:如果该指令定义的宏符号为首次出现,为该指令定义的宏符号创建符号节点,符号节点信息包括宏符号名和该宏定义指令所在的源代码文件;T203:如果该指令定义的宏符号已经出现过,为该定义指令之前出现的每个宏符号创建引用节点,在引用节点与符号节点之间添加依赖关系,依赖关系起点为引用节点,终点为对应的符号节点,依赖关系类型为宏定义-使用依赖。
作为本发明的一种优选方式,所述提取宏条件判断指令信息产生的依赖关系,包括:T301:如果该指令所在的源代码文件为首次出现,为该指令所在的源代码文件创建文件节点;T302:如果该指令使用宏符号进行条件判断,则为该指令进行条件判断使用的宏符号创建一个引用节点,引用节点信息包括宏符号名,该指令所在的源代码文件;T303:如果该指令使用宏符号进行条件判断,并且如果该指令进行条件判断使用的宏符号已经被定义,那么在引用节点与该指令使用宏符号对应的符号节点之间添加依赖关系,依赖关系起点为新建的引用节点,终点为对应的该指令使用宏符号对应的符号节点,依赖关系类型为宏定义-使用依赖;T304:如果该指令进行条件判断使用的宏符号未被定义,那么如果后续存在该宏符号的定义,这个依赖关系将在后续发现该宏符号定义时添加。
作为本发明的一种优选方式,所述提取宏展开指令信息产生的依赖关系,包括:T401:如果该指令所在的源代码文件为首次出现,为该指令所在的源代码文件创建文件节点;T402:为该宏展开指令对应的符号创建一个引用节点,引用节点信息包括宏符号名,该指令所在的源代码文件;T403:在该展开的宏符号对应的引用节点与该宏展开指令对应的符号节点之间添加依赖关系,依赖关系起点为新建的引用节点,终点为该宏展开指令对应的符号节点,依赖关系类型为宏定义-使用依赖。
作为本发明的一种优选方式,所述变量包括:全局变量和局部变量。
作为本发明的一种优选方式,所述变量信息包括:变量定义信息,变量声明信息,变量使用信息三种类型,各信息的内容包括该变量的名称、变量的类型和变量信息所在的源代码文件。
作为本发明的一种优选方式,所述对每个变量,基于每条变量信息提取该变量产生的依赖关系,包括:T501:如果该条变量信息所在的源代码文件为首次出现,为该指令所在的源代码文件创建文件节点;T502:对该变量的每条变量定义信息,为该变量创建符号节点,符号节点信息包括变量符号名,该变量定义信息所在的源代码文件;T503:对该变量的每条变量声明信息,为该变量创建声明节点,声明节点信息包括变量符号名,该变量声明信息所在的源代码文件;T504:对该变量的每条变量使用信息,为该变量创建引用节点,引用节点信息包括变量符号名,该变量使用信息所在的源代码文件;T505:对该变量对应的每个引用节点,在引用节点与符号节点之间添加依赖关系,依赖关系起点为该引用节点,终点为对应的符号节点,依赖关系类型为变量定义-使用依赖;T506:对该变量对应的每个引用节点,在引用节点与声明节点之间添加依赖关系,依赖关系起点为该引用节点,终点为对应的声明节点,依赖关系类型为变量声明-使用依赖;T507:如果该变量的类型为用户定义类型,那么在该变量使用的类型所对应的符号节点与该变量的符号节点之间添加依赖关系,依赖关系起点为该变量的符号节点,终点为该变量使用的类型所对应的符号节点,依赖关系类型为变量-类型使用依赖。
作为本发明的一种优选方式,所述函数信息包括:函数定义信息,函数声明信息,函数使用信息三种类型。
作为本发明的一种优选方式,函数定义信息包括:该函数的名称、函数的定义体、该条函数定义信息所在的源代码文件;函数声明信息包括:该函数的名称、参数列表、返回值、修饰符、该条函数声明信息所在的源代码文件;函数使用信息包括:该函数的名称,该条函数使用信息所在的源代码文件。
作为本发明的一种优选方式,所述对每个函数,基于每条函数信息提取该函数产生的依赖关系,包括:T601:如果该条函数信息所在的源代码文件为首次出现,为该指令所在的源代码文件创建文件节点;T602:对该函数的每条函数定义信息,为该函数创建符号节点,符号节点信息包括函数名,该函数定义信息所在的源代码文件,对于该函数定义体中出现的所有宏符号、全局变量、函数调用和自定义类型,添加该函数与这些符号之间的依赖关系;T603:对该函数的每条函数声明信息,为该函数创建声明节点,声明节点信息包括函数名,该函数声明信息所在的源代码文件,对于该函数声明中参数列表、返回值类型中出现的自定义类型,找到自定义类型对应的符号节点,对每个自定义类型对应的符号节点,在该符号节点与所在函数定义体对应的符号节点之间添加依赖关系,依赖关系起点为该自定义类型的符号节点,终点为所在函数的符号节点,依赖关系类型为函数声明依赖;T604:对该函数的每条函数使用信息,为该函数创建引用节点,引用节点信息包括函数名,该函数使用信息所在的源代码文件;T605:对该函数对应的每个引用节点,在引用节点与对应的符号节点之间添加依赖关系,依赖关系起点为该引用节点,终点为对应的符号节点,依赖关系类型为函数定义-使用依赖;T606:对该函数对应的每个引用节点,在引用节点与对应的声明节点之间添加依赖关系,依赖关系起点为该引用节点,终点为对应的声明节点,依赖关系类型为函数声明-使用依赖。
作为本发明的一种优选方式,所述对于该函数定义体中出现的所有宏符号、全局变量、函数调用和自定义类型,添加该函数与这些符号之间的依赖关系,包括:M101:对于每个出现在函数定义体中的宏符号展开,找到宏符号对应的符号节点,对每个宏符号对应的符号节点,在该符号节点与所在函数定义体对应的符号节点之间添加依赖关系,依赖关系起点为该宏符号的符号节点,终点为所在函数的符号节点,依赖关系类型为函数-宏使用依赖;M102:对于每个出现在函数定义体中的全局变量使用,找到全局变量对应的符号节点,对每个全局变量对应的符号节点,在该符号节点与所在函数定义体对应的符号节点之间添加依赖关系,依赖关系起点为该全局变量的符号节点,终点为所在函数的符号节点,依赖关系类型为函数-全局变量使用依赖;M103:对于每个出现在函数定义体中的函数调用,找到函数调用对应的符号节点,对每个函数调用对应的符号节点,在该符号节点与所在函数定义体对应的符号节点之间添加依赖关系,依赖关系起点为该函数调用的符号节点,终点为所在函数的符号节点,依赖关系类型为函数-函数调用依赖;M104:对于每个出现在函数定义体中的自定义类型使用,找到自定义类型对应的符号节点,对每个自定义类型对应的符号节点,在该符号节点与所在函数定义体对应的符号节点之间添加依赖关系,依赖关系起点为该自定义类型的符号节点,终点为所在函数的符号节点,依赖关系类型为函数-类型使用依赖。
作为本发明的一种优选方式,所述类型包括:结构体、枚举型、共用体和别名。
作为本发明的一种优选方式,所述类型信息包括:该类型的名称、该类型的定义体、该类型所在的源代码文件。
作为本发明的一种优选方式,所述对每个类型,基于类型信息提取该类型产生的依赖关系,包括:M201:对于该类型定义体中出现的每个自定义类型使用,找到该自定义类型对应的符号节点,对每个自定义类型对应的符号节点,在该符号节点与所在类型定义体对应的符号节点之间添加依赖关系,依赖关系起点为该自定义类型的符号节点,终点为所在类型的符号节点,依赖关系类型为类型-类型使用依赖;M202:对于该类型定义体中出现的每个宏符号展开,找到该宏符号对应的符号节点,对每个宏符号对应的符号节点,在该符号节点与所在类型定义体对应的符号节点之间添加依赖关系,依赖关系起点为该宏符号的符号节点,终点为所在类型的符号节点,依赖关系类型为类型-宏使用依赖。
作为本发明的一种优选方式,所述基于符号级的依赖关系提取文件级的依赖关系,包括:基于宏符号的依赖关系中提取文件级的依赖关系,基于变量符号的依赖关系中提取文件级的依赖关系,基于函数符号的依赖关系中提取文件级的依赖关系,基于类型符号的依赖关系中提取文件级的依赖关系。
作为本发明的一种优选方式,所述基于宏符号的依赖关系中提取文件级的依赖关系,包括:对于每个宏定义-使用依赖关系,它的起点为引用节点,终点为符号节点,从起始节点中获得引用文件对应的引用文件节点,从终止节点中获得定义文件对应的定义文件节点,如果引用文件和定义文件不同,那么在引用文件节点与定义文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为定义文件节点,依赖关系类型为文件间宏定义-使用依赖。
作为本发明的一种优选方式,所述基于变量符号的依赖关系中提取文件级的依赖关系,包括:M301:对于每个全局变量的每个变量定义-使用依赖,它的起点为引用节点,终点为符号节点,从起始节点中获得引用文件对应的引用文件节点,从终止节点中获得定义文件对应的定义文件节点,如果引用文件和定义文件不同,那么在引用文件节点与定义文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为定义文件节点,依赖关系类型为文件间变量定义-使用依赖;M302:对于每个全局变量的每个变量声明-使用依赖,它的起点为引用节点,终点为声明节点,从起始节点中获得引用文件对应的引用文件节点,从终止节点中获得声明文件对应的声明文件节点;如果引用文件和声明文件不同,并且引用文件直接/间接地包含了声明文件,或该变量没有跨文件的变量定义-使用依赖,那么在引用文件节点与声明文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为声明文件节点,依赖关系类型为文件间变量声明-使用依赖;如果引用文件和声明文件不同,但是该变量有跨文件的变量定义-使用依赖,则需要进一步判断声明文件和定义文件;如果声明文件和定义文件相同,那么在引用文件节点与声明文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为声明文件节点,依赖关系类型为文件间变量声明-使用依赖。
作为本发明的一种优选方式,所述基于函数符号的依赖关系中提取文件级的依赖关系,包括:M401:对于每个函数定义-使用依赖,它的起点为引用节点,终点为符号节点,从起始节点中获得引用文件对应的引用文件节点,从终止节点中获得定义文件对应的定义文件节点,如果引用文件和定义文件不同,那么在引用文件节点与定义文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为定义文件节点,依赖关系类型为文件间函数定义-使用依赖;M402:对于每个函数声明-使用依赖,它的起点为引用节点,终点为声明节点,从起始节点中获得引用文件对应的引用文件节点,从终止节点中获得声明文件对应的声明文件节点;如果引用文件和声明文件不同,并且引用文件直接/间接地包含了声明文件,或该函数没有跨文件的函数定义-使用依赖,那么在引用文件节点与声明文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为声明文件节点,依赖关系类型为文件间函数声明-使用依赖;如果引用文件和声明文件不同,但是该函数有跨文件的函数定义-使用依赖,则需要进一步判断声明文件和定义文件,如果声明文件和定义文件相同,那么在引用文件节点与声明文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为声明文件节点,依赖关系类型为文件间函数声明-使用依赖。
作为本发明的一种优选方式,基于类型符号的依赖关系中提取文件级的依赖关系,包括:M501:对于每个变量-类型使用依赖,它的起点为变量的符号节点,终点为类型的符号节点,从终止节点中获得类型定义所在的定义文件节点,根据变量的符号节点找到它对应的全部引用节点,对每个引用节点,从该引用节点中获得引用文件对应的引用文件节点,如果引用文件和定义文件不同,那么在引用文件节点与定义文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为定义文件节点,依赖关系类型为文件间类型定义-使用依赖;M502:对于每个函数声明依赖,它的起点为函数的符号节点,终点为类型的符号节点,从终止节点中获得类型定义所在的定义文件节点,根据函数的符号节点找到它对应的全部引用节点,对每个引用节点,从该引用节点中获得引用文件对应的引用文件节点,如果引用文件和定义文件不同,那么在引用文件节点与定义文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为定义文件节点,依赖关系类型为文件间类型定义-使用依赖。
作为本发明的一种优选方式,基于类型符号的依赖关系中提取文件级的依赖关系,包括:持久化节点信息,对于提取到的不同类型的符号级节点和文件级节点,将其节点的编号和所携带的信息输出到json格式的文件保存;持久化依赖边信息,每条边用一个三元组表示,即分别表示起点、终点、依赖关系的类型,将每条依赖边的信息输出到json格式的文件保存。
区别于现有技术,上述技术方案的技术效果有:
(1)与现有技术相比,本技术能通过对C语言代码的静态分析,提供13种不同类型的符号级的依赖关系和7种不同类型的文件级依赖关系,相比其他技术提取更加全面、更加精确、多层次的依赖关系,从而为上层应用提供更加强大的技术支持;
(2)本技术最终输出的依赖关系可以转换为多种数据交换格式长期保存,且利用价值大,已经成功地为构建函数调用图、头文件优化等功能提供数据支持,将来可以进一步使用本发明得到的依赖关系作为支撑数据,应用软件架构恢复、软件重构、软件质量检测等技术,因此,具有较为广阔的应用前景。
附图说明
图1为具体实施方式提供的基于静态分析的C语言代码依赖关系提取方法流程图;
图2为具体实施方式提供的函数声明-使用依赖提取文件级依赖的流程图;
图3为具体实施方式提取到的符号级依赖关系构成的异构、有向多重图;
图4为具体实施方式提取到的文件级依赖关系构成的有向多重图。
具体实施方式
为详细说明技术方案的技术内容、构造特征、所实现目的及效果,以下结合具体实施例并配合附图详予说明。
根据本方法的实施例提供的基于静态分析的C语言代码依赖关系提取方法流程图如图1,该流程具有以下步骤:
步骤(1):输入一个C语言源代码文件,对该文件中的源代码进行静态分析,获得各条宏指令的信息以及各个变量、函数、类型的信息,实施例的具体C语言描述为:
其中main.c为输入的源代码文件,h1.h,h2.h为输入文件包含的头文件,lib.c为输入文件对应的编译指令包含的库文件。
需要说明的是,由于C语言可以通过编译指令中的参数来实现链接、包含文件、定义宏等功能,最终影响编译内容,为了更精准地获得源代码中的信息,在实施例中,需要将该源代码文件及其对应的编译指令一同作为输入执行分析,在本实施例中,输入的源代码文件对应的编译指令为:
gcc main.c lib.c-o main
根据设计的依赖模型,参考C99标准(ISO/IEC 9899:1999),本方法需要获得的信息为宏指令、变量、函数和类型,可通过以下几个步骤实现:
步骤(1)-步骤(1-1):对于宏指令,在本实施例中,可能通过宏指令产生文件包含、宏符号的定义-使用等依赖关系,因此需要获得四类宏指令的信息:
宏包含指令(#include),用于引入一个包含的文件,即在当前指令位置展开文件内容。在本实施例中,需要获得的宏包含指令(#include)信息为该指令包含的文件,该指令所在的源代码文件。
宏定义指令(#define),用于定义一个宏符号。在本实施例中,需要获得的宏定义指令(#define)信息为该指令定义的宏符号名,该指令所在的源代码文件。
宏条件判断指令(#ifdef,#ifndef,#defined,#if,#elif),用于根据某一条件或者某一宏符号是否定义来进行条件编译。在本实施例中,需要获得的宏条件判断指令(#ifdef,#ifndef,#defined,#if,#elif)信息为该指令进行条件判断使用的宏符号名,该指令所在的源代码文件。
宏展开指令,用于将一个预定义的宏符号在指令位置展开;在本实施例中,需要获得的宏展开指令信息为该指令展开的宏符号名,该指令所在的源代码文件。
步骤(1-2):对于变量,考虑全局变量和局部变量;在本实施例中,变量在代码中有定义、声明、使用三种可能的出现情况,因此对一个变量,需要提取的信息包括:变量定义信息,变量声明信息和变量使用信息;每个变量,可以有多条上述三种类型的信息,每条信息的内容包括该变量的名称,该变量的类型,该条变量信息所在的源代码文件。
步骤(1-3):对于函数,在本实施例中,在代码中有定义、声明、调用三种可能的出现情况,因此对一个函数,需要提取的信息包括:
函数定义信息,在函数的定义位置提取相关信息,包括:该函数的名称,该函数的定义体,该条函数定义信息所在的源代码文件。
函数声明信息,在函数的每处声明提取相关信息,包括:该函数的名称,参数列表,返回值,修饰符,该条函数声明信息所在的源代码文件。
函数调用信息,在函数的每处调用提取相关信息,包括:该函数的名称,该条函数调用信息所在的源代码文件。
步骤(1-4):对于类型,在本实施例中,由用户定义的类型可能产生多种依赖关系,包括五类:结构体(struct),枚举型(enum),共用体(union),别名(typedef)。需要提取的类型信息包括:该类型的名称,该类型的定义体,该类型所在的源代码文件。
在本实施例中,具体提取方法可以采用LLVM Clang框架生成编译单元对应的AST树,遍历AST树访问变量、函数以及类型相关的节点获取对应信息。由于宏指令在生成AST树之前的预处理阶段已经被处理,因此可以需要通过框架的PPCallbacks类在处理完每个宏指令后,调用回调函数获得相关宏指令信息。
步骤(2):对每条宏指令,基于宏指令信息提取该条宏指令产生的依赖关系;在本实施例中,四类宏指令产生的依赖关系各不相同,可通过以下步骤实现:
步骤(2-1):提取宏包含指令(#include)信息产生的依赖关系,可通过以下步骤实现:
如果该指令所在的源代码文件为首次出现,为该指令所在的源代码文件创建文件节点;
如果该指令包含的文件为首次出现,为该指令包含的文件创建文件节点;
在该指令所在的源代码文件和该指令包含的文件之间添加依赖关系,依赖关系起点为指令所在的源代码文件对应的文件节点,终点为该指令包含的文件对应的文件节点,依赖关系类型为包含依赖。
在本实施例中,输入源代码文件main.c的第1行有以下代码片段:
#include“h1.h”
由于该指令为所在源代码文件的第一行代码,因此它所在源代码文件为首次出现,为main.c创建文件节点。
该指令包含文件h1.h,为首次出现,为h1.h创建文件节点。
在节点main.c和h1.h之间添加依赖关系,起点为main.c,终点为h1.h,依赖类型为包含依赖,描述三元组为(main.c,h1.h,包含依赖)。
步骤(2-2):提取宏定义指令(#define)信息产生的依赖关系,可通过以下步骤实现:
如果该指令所在的源代码文件为首次出现,为该指令所在的源代码文件创建文件节点;
如果该指令定义的宏符号为首次出现,为指令定义的宏符号创建符号节点,符号节点信息包括宏符号名,该宏定义指令所在的源代码文件。
如果该指令定义的宏符号已经出现过,对在该定义指令之前出现的每个宏符号创建引用节点,在引用节点与符号节点之间添加依赖关系,依赖关系起点为引用节点,终点为对应的符号节点,依赖关系类型为宏定义-使用依赖。
步骤(2-3):提取宏条件判断指令(#ifdef,#ifndef,#defined,#if,#elif)信息产生的依赖关系,可通过以下步骤实现:
如果该指令所在的源代码文件为首次出现,为该指令所在的源代码文件创建文件节点;
如果该指令使用宏符号进行条件判断,则为该指令进行条件判断使用的宏符号创建一个引用节点,引用节点信息包括宏符号名,该指令所在的源代码文件。
如果该指令使用宏符号进行条件判断,并且如果该指令进行条件判断使用的宏符号已经被定义,那么在引用节点与该指令使用宏符号对应的符号节点之间添加依赖关系,依赖关系起点为新建的引用节点,终点为对应的该指令使用宏符号对应的符号节点,依赖关系类型为宏定义-使用依赖。
如果该指令进行条件判断使用的宏符号未被定义,那么如果后续存在该宏符号的定义,这个依赖关系将在后续发现该宏符号定义时添加。
在本实施例中,h1.h文件的第2~4行有以下代码片段:
#ifndef MAX_LIMIT
#define MAX_LIMIT 256
#endif
根据#ifndef指令的信息,该指令使用MAX_LIMIT宏符号做条件判断,因此,为该符号创建引用节点,宏符号名为MAX_INT,所在文件为h1.h。
根据#define指令的信息,该指令定义了MAX_LIMIT宏符号,因此,为该符号创建符号节点,宏符号名为MAX_INT,所在文件为h1.h。
在创建的引用节点和符号节点之间添加依赖关系,起点为引用节点,终点为符号节点,依赖类型为宏定义-使用依赖。
步骤(2-4):提取宏展开指令信息产生的依赖关系,可通过以下步骤实现:
如果该指令所在的源代码文件为首次出现,为该指令所在的源代码文件创建文件节点;
为该宏展开指令对应的符号创建一个引用节点,引用节点信息包括宏符号名,该指令所在的源代码文件。
在该展开的宏符号对应的引用节点与该宏展开指令对应的符号节点之间添加依赖关系,依赖关系起点为新建的引用节点,终点为该宏展开指令对应的符号节点,依赖关系类型为宏定义-使用依赖。
步骤(3):对每个变量,基于每条变量信息提取该变量产生的依赖关系;在本实施例中,变量有定义、使用、声明三种可能的出现方式,基于三种不同的变量信息提取该变量产生的依赖关系,可通过以下步骤实现:
步骤(3-1):如果该条变量信息所在的源代码文件为首次出现,为该指令所在的源代码文件创建文件节点;
步骤(3-2):对该变量的每条变量定义信息,为该变量创建符号节点,符号节点信息包括变量符号名,该变量定义信息所在的源代码文件。
步骤(3-3):对该变量的每条变量声明信息,为该变量创建声明节点,声明节点信息包括变量符号名,该变量声明信息所在的源代码文件。
步骤(3-4):对该变量的每条变量使用信息,为该变量创建引用节点,引用节点信息包括变量符号名,该变量使用信息所在的源代码文件。
步骤(3-5):对该变量对应的每个引用节点,在引用节点与符号节点之间添加依赖关系,依赖关系起点为该引用节点,终点为对应的符号节点,依赖关系类型为变量定义-使用依赖。
步骤(3-6):对该变量对应的每个引用节点,在引用节点与声明节点之间添加依赖关系,依赖关系起点为该引用节点,终点为对应的声明节点,依赖关系类型为变量声明-使用依赖。
步骤(3-7):如果该变量的类型为用户定义类型,那么在该变量使用的类型所对应的符号节点与该变量的符号节点之间添加依赖关系,依赖关系起点为该变量的符号节点,终点为对应类型的符号节点,依赖关系类型为变量-类型使用依赖。
在本实施例中,main.c文件的第3~4行有以下代码片段:
struct s res;
res.num=1;
第四行定义了变量res,可以在此处获得一条该变量的定义信息,根据信息创建符号节点,符号节点信息包括变量符号名res,该变量定义信息所在的源代码文件main.c。
第五行使用了变量res,可以在此处获得一条该变量的使用信息,根据信息创建引用节点,引用节点信息包括变量符号名res,该变量定义信息所在的源代码文件main.c。
该变量的类型为用户定义类型,那么在使用的类型所对应的符号节点与该变量的符号节点之间添加依赖关系,依赖关系起点为res变量的符号节点,终点为对应类型的符号节点struct s,依赖关系类型为变量-类型使用依赖。
步骤(4):对每个函数,基于每条函数信息提取该函数产生的依赖关系;在本实施例中,函数有定义、使用、声明三种可能的出现方式,基于三种不同的函数信息提取该函数产生的依赖关系,可通过以下步骤实现:
步骤(4-1):如果该条函数信息所在的源代码文件为首次出现,为该指令所在的源代码文件创建文件节点;
步骤(4-2):对该函数的每条函数定义信息,为该函数创建符号节点,符号节点信息包括函数名,该函数定义信息所在的源代码文件。对于该函数定义体中出现的所有宏符号、全局变量、函数调用和自定义类型,添加该函数与这些符号之间的依赖关系,可通过以下步骤实现:
步骤(4-3):对于每个出现在函数定义体中的宏符号展开,找到宏符号对应的符号节点。对每个宏符号对应的符号节点,在该符号节点与所在函数定义体对应的符号节点之间添加依赖关系,依赖关系起点为该宏符号的符号节点,终点为所在函数的符号节点,依赖关系类型为函数-宏使用依赖。
步骤(4-4):对于每个出现在函数定义体中的全局变量使用,找到全局变量对应的符号节点。对每个全局变量对应的符号节点,在该符号节点与所在函数定义体对应的符号节点之间添加依赖关系,依赖关系起点为该全局变量的符号节点,终点为所在函数的符号节点,依赖关系类型为函数-全局变量使用依赖。
步骤(4-5):对于每个出现在函数定义体中的函数调用,找到函数调用对应的符号节点。对每个函数调用对应的符号节点,在该符号节点与所在函数定义体对应的符号节点之间添加依赖关系,依赖关系起点为该函数调用的符号节点,终点为所在函数的符号节点,依赖关系类型为函数-函数调用依赖。
步骤(4-6):对于每个出现在函数定义体中的自定义类型使用,找到自定义类型对应的符号节点。对每个自定义类型对应的符号节点,在该符号节点与所在函数定义体对应的符号节点之间添加依赖关系,依赖关系起点为该自定义类型的符号节点,终点为所在函数的符号节点,依赖关系类型为函数-类型使用依赖。
步骤(4-7):对该函数的每条函数声明信息,为该函数创建声明节点,声明节点信息包括函数名,该函数声明信息所在的源代码文件。对于该函数声明中参数列表、返回值类型中出现的自定义类型,找到自定义类型对应的符号节点。对每个自定义类型对应的符号节点,在该符号节点与所在函数定义体对应的符号节点之间添加依赖关系,依赖关系起点为该自定义类型的符号节点,终点为所在函数的符号节点,依赖关系类型为函数声明依赖。
步骤(4-8):对该函数的每条函数使用信息,为该函数创建引用节点,引用节点信息包括函数名,该函数使用信息所在的源代码文件。
步骤(4-9):对该函数对应的每个引用节点,在引用节点与对应的符号节点之间添加依赖关系,依赖关系起点为该引用节点,终点为对应的符号节点,依赖关系类型为函数定义-使用依赖。
步骤(4-10):对该函数对应的每个引用节点,在引用节点与对应的声明节点之间添加依赖关系,依赖关系起点为该引用节点,终点为对应的声明节点,依赖关系类型为函数声明-使用依赖。
在本实施例中,lib.c文件的第3~7行有以下代码片段:
这是对check函数的定义,该条函数信息所在的源代码文件为首次出现,为该指令所在的源代码文件创建文件节点lib.c;
根据该条函数定义信息创建符号节点,符号节点信息包括函数名check,该函数定义信息所在的源代码文件lib.c。
遍历该函数定义体中出现的所有宏符号、全局变量、函数调用和自定义类型,添加该函数与这些符号之间的依赖关系。在第2行中,函数实现中出现了宏符号MAX_LIMIT,找到该宏符号对应的符号节点,在该符号节点与函数check对应的符号节点之间添加依赖关系,依赖关系起点为MAX_LIMIT的符号节点,终点为check函数的符号节点,依赖关系类型为函数-宏使用依赖。
在该函数的函数声明信息中,参数列表中出现了自定义类型struct s,找到该自定义类型对应的符号节点,在该类型struct s对应的符号节点与check函数对应的符号节点之间添加依赖关系,依赖关系起点为类型struct s的符号节点,终点为check函数的符号节点,依赖关系类型为函数声明依赖。
步骤(5):基于类型信息提取该类型产生的依赖关系,可通过以下步骤实现:
步骤(5-1):对于该类型定义体中出现的每个自定义类型使用,找到该自定义类型对应的符号节点。对每个自定义类型对应的符号节点,在该符号节点与所在类型定义体对应的符号节点之间添加依赖关系,依赖关系起点为该自定义类型的符号节点,终点为所在类型的符号节点,依赖关系类型为类型-类型使用依赖。
步骤(5-2):对于该类型定义体中出现的每个宏符号展开,找到该宏符号对应的符号节点。对每个宏符号对应的符号节点,在该符号节点与所在类型定义体对应的符号节点之间添加依赖关系,依赖关系起点为该宏符号的符号节点,终点为所在类型的符号节点,依赖关系类型为类型-宏使用依赖。
在本实施例中,类型的定义体中没有产生依赖关系。
步骤(6):基于符号级的依赖关系提取文件级的依赖关系,在本实施例中,对四个文件之间的依赖关系的提取,主要基于宏、变量、函数、类型四种符号的依赖关系提取。基于宏符号的依赖关系中提取文件级的依赖关系,它仅有一种依赖关系:宏定义-使用依赖。基于变量符号的依赖关系中提取文件级的依赖关系,这里仅考虑全局变量符号的依赖关系,主要考虑:变量定义-使用依赖,变量声明-使用依赖。基于函数符号的依赖关系中提取文件级的依赖关系,主要考虑:函数定义-使用依赖,函数声明-使用依赖。基于类型符号的依赖关系中提取文件级的依赖关系,主要考虑:变量-类型使用依赖,函数声明依赖。
可通过以下步骤实现:
步骤(6-1):对于每个宏定义-使用依赖关系,它的起点为引用节点,终点为符号节点,从起始节点中获得引用文件对应的引用文件节点,从终止节点中获得定义文件对应的定义文件节点。如果引用文件和定义文件不同,那么在引用文件节点与定义文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为定义文件节点,依赖关系类型为文件间宏定义-使用依赖。
步骤(6-2):对于每个变量定义-使用依赖,它的起点为引用节点,终点为符号节点,从起始节点中获得引用文件对应的引用文件节点,从终止节点中获得定义文件对应的定义文件节点,如果引用文件和定义文件不同,那么在引用文件节点与定义文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为定义文件节点,依赖关系类型为文件间变量定义-使用依赖。
步骤(6-3):对于每个变量声明-使用依赖,它的起点为引用节点,终点为声明节点,从起始节点中获得引用文件对应的引用文件节点,从终止节点中获得声明文件对应的声明文件节点。如果引用文件和声明文件不同,并且引用文件直接/间接地包含了声明文件,或该变量没有跨文件的变量定义-使用依赖,那么在引用文件节点与声明文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为声明文件节点,依赖关系类型为文件间变量声明-使用依赖。如果引用文件和声明文件不同,但是该变量有跨文件的变量定义-使用依赖,则需要进一步判断声明文件和定义文件,如果声明文件和定义文件相同,那么在引用文件节点与声明文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为声明文件节点,依赖关系类型为文件间变量声明-使用依赖。
步骤(6-4):对于每个函数定义-使用依赖,它的起点为引用节点,终点为符号节点,从起始节点中获得引用文件对应的引用文件节点,从终止节点中获得定义文件对应的定义文件节点,如果引用文件和定义文件不同,那么在引用文件节点与定义文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为定义文件节点,依赖关系类型为文件间函数定义-使用依赖。
步骤(6-5):对于每个函数声明-使用依赖,它的起点为引用节点,终点为声明节点,从起始节点中获得引用文件对应的引用文件节点,从终止节点中获得声明文件对应的声明文件节点。如果引用文件和声明文件不同,并且引用文件直接/间接地包含了声明文件,或该函数没有跨文件的函数定义-使用依赖,那么在引用文件节点与声明文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为声明文件节点,依赖关系类型为文件间函数声明-使用依赖。如果引用文件和声明文件不同,但是该函数有跨文件的函数定义-使用依赖,则需要进一步判断声明文件和定义文件,如果声明文件和定义文件相同,那么在引用文件节点与声明文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为声明文件节点,依赖关系类型为文件间函数声明-使用依赖。
本发明基于实施例提供的函数声明-使用依赖提取文件级依赖的流程图如图2所示。
在本实施例中,main.c中第8行的代码片段为:
if(check(res))++counter;
调用了check函数,该函数的声明位于h1.h中第8行,代码片段为
int check(struct s res);
因此对该函数已经存在一个声明-使用依赖,起点为引用节点,对应的引用文件节点为main.c,终点为声明节点,对应的声明文件节点为h1.h。引用文件和声明文件不同,并且main.c节点和h1.h节点之间存在直接的包含关系,那么在main.c节点与h1.h文件节点之间添加依赖关系,依赖关系起点为main.c引用文件节点,终点为h1.h声明文件节点,依赖关系类型为文件间函数声明-使用依赖。
步骤(6-6):对于每个变量-类型使用依赖,它的起点为变量的符号节点,终点为类型的符号节点,从终止节点中获得类型定义所在的定义文件节点,根据变量的符号节点找到它对应的全部引用节点。对每个引用节点,从该引用节点中获得引用文件对应的引用文件节点,如果引用文件和定义文件不同,那么在引用文件节点与定义文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为定义文件节点,依赖关系类型为文件间类型定义-使用依赖。
步骤(6-5):对于每个函数声明依赖,它的起点为函数的符号节点,终点为类型的符号节点,从终止节点中获得类型定义所在的定义文件节点,根据函数的符号节点找到它对应的全部引用节点。对每个引用节点,从该引用节点中获得引用文件对应的引用文件节点,如果引用文件和定义文件不同,那么在引用文件节点与定义文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为定义文件节点,依赖关系类型为文件间类型定义-使用依赖。
在本实施例中,函数check与类型struct s之间存在函数声明依赖,对该函数声明依赖,起点为check函数的符号节点,终点为struct s类型的符号节点,从终止节点中获得类型定义所在的定义文件节点h2.h,根据check函数的符号节点找到它对应的引用节点,该函数仅在main.c中被调用一次,因此仅存在一个引用节点,对应的引用文件节点为main.c。引用文件和定义文件不同,那么在引用文件节点与定义文件节点之间添加依赖关系,依赖关系起点为main.c文件节点,终点为h2.h文件节点,依赖关系类型为文件间类型定义-使用依赖。
步骤(7):持久化提取到的依赖关系,主要可通过以下步骤实现:
持久化节点信息,对于提取到的不同类型的符号级节点(符号节点、声明节点和引用节点)和文件级节点,可以将其节点的编号和所携带的信息输出到json等特定格式的文件保存。
持久化依赖边信息,每条边可以用一个三元组表示,即(startnode,endnode,edgetype),分别表示起点,终点,依赖关系的类型。可以将每条依赖边的信息输出到json等特定格式的文件保存。
在本实施例中,最终提取到的符号级的依赖关系将构成一个异构的有向多重图,如图3所示,图中○代表符号节点、△代表声明节点、◎代表引用节点。在本实施例中,最终提取到的文件级的依赖关系将构成一个有向多重图,如图4所示,图中□代表文件节点。
需要说明的是,尽管在本文中已经对上述各实施例进行了描述,但并非因此限制本发明的专利保护范围。因此,基于本发明的创新理念,对本文所述实施例进行的变更和修改,或利用本发明说明书及附图内容所作的等效结构或等效流程变换,直接或间接地将以上技术方案运用在其他相关的技术领域,均包括在本发明的专利保护范围之内。
Claims (19)
1.一种基于静态分析的C语言代码依赖关系提取方法,其特征在于,包括以下步骤:
S1:对C语言源代码进行静态分析,获得各条宏指令的信息以及各个变量、函数、类型的信息;
S2:对每条宏指令,基于宏指令信息提取该条宏指令产生的依赖关系;
S3:对每个变量,基于每条变量信息提取该变量产生的依赖关系;
S4:对每个函数,基于每条函数信息提取该函数产生的依赖关系;
S5:对每个类型,基于类型信息提取该类型产生的依赖关系;
S6:基于符号级的依赖关系提取文件级的依赖关系;
S7:持久化提取到的依赖关系。
2.根据权利要求1所述的基于静态分析的C语言代码依赖关系提取方法,其特征在于:
所述宏指令信息包括:宏包含指令信息,宏定义指令信息,宏条件判断指令信息和宏展开指令信息;
宏包含指令信息包括:该指令包含的文件,该指令所在的源代码文件;
宏定义指令信息包括:该指令定义的宏符号名,该指令所在的源代码文件;
宏条件判断指令信息包括:该指令进行条件判断使用的宏符号名,该指令所在的源代码文件;
宏展开指令信息包括:该指令展开的宏符号名,该指令所在的源代码文件;
所述对每条宏指令,基于宏指令信息提取该条宏指令产生的依赖关系,包括:提取宏包含指令信息产生的依赖关系,提取宏定义指令信息产生的依赖关系,提取宏条件判断指令信息产生的依赖关系,提取宏展开指令信息产生的依赖关系。
3.根据权利要求2所述的基于静态分析的C语言代码依赖关系提取方法,其特征在于,所述提取宏包含指令信息产生的依赖关系,包括:
T101:如果该指令所在的源代码文件为首次出现,为该指令所在的源代码文件创建文件节点;
T102:如果该指令包含的文件为首次出现,为该指令包含的文件创建文件节点;
T103:在该指令所在的源代码文件和该指令包含的文件之间添加依赖关系,依赖关系起点为指令所在的源代码文件对应的文件节点,终点为该指令包含的文件对应的文件节点,依赖关系类型为包含依赖。
4.根据权利要求2所述的基于静态分析的C语言代码依赖关系提取方法,其特征在于,所述提取宏定义指令信息产生的依赖关系,包括:
T201:如果该指令所在的源代码文件为首次出现,为该指令所在的源代码文件创建文件节点;
T202:如果该指令定义的宏符号为首次出现,为该指令定义的宏符号创建符号节点,符号节点信息包括宏符号名和该宏定义指令所在的源代码文件;
T203:如果该指令定义的宏符号已经出现过,为该定义指令之前出现的每个宏符号创建引用节点,在引用节点与符号节点之间添加依赖关系,依赖关系起点为引用节点,终点为对应的符号节点,依赖关系类型为宏定义-使用依赖。
5.根据权利要求2所述的基于静态分析的C语言代码依赖关系提取方法,其特征在于,所述提取宏条件判断指令信息产生的依赖关系,包括:
T301:如果该指令所在的源代码文件为首次出现,为该指令所在的源代码文件创建文件节点;
T302:如果该指令使用宏符号进行条件判断,则为该指令进行条件判断使用的宏符号创建一个引用节点,引用节点信息包括宏符号名,该指令所在的源代码文件;
T303:如果该指令使用宏符号进行条件判断,并且如果该指令进行条件判断使用的宏符号已经被定义,那么在引用节点与该指令使用宏符号对应的符号节点之间添加依赖关系,依赖关系起点为新建的引用节点,终点为对应的该指令使用宏符号对应的符号节点,依赖关系类型为宏定义-使用依赖;
T304:如果该指令进行条件判断使用的宏符号未被定义,那么如果后续存在该宏符号的定义,这个依赖关系将在后续发现该宏符号定义时添加。
6.根据权利要求2所述的基于静态分析的C语言代码依赖关系提取方法,其特征在于,所述提取宏展开指令信息产生的依赖关系,包括:
T401:如果该指令所在的源代码文件为首次出现,为该指令所在的源代码文件创建文件节点;
T402:为该宏展开指令对应的符号创建一个引用节点,引用节点信息包括宏符号名,该指令所在的源代码文件;
T403:在该展开的宏符号对应的引用节点与该宏展开指令对应的符号节点之间添加依赖关系,依赖关系起点为新建的引用节点,终点为该宏展开指令对应的符号节点,依赖关系类型为宏定义-使用依赖。
7.根据权利要求1所述的基于静态分析的C语言代码依赖关系提取方法,其特征在于:
所述变量包括:全局变量和局部变量;
所述变量信息包括:变量定义信息,变量声明信息,变量使用信息三种类型,各信息的内容包括该变量的名称、变量的类型和变量信息所在的源代码文件。
8.根据权利要求7所述的基于静态分析的C语言代码依赖关系提取方法,其特征在于,所述对每个变量,基于每条变量信息提取该变量产生的依赖关系,包括:
T501:如果该条变量信息所在的源代码文件为首次出现,为该指令所在的源代码文件创建文件节点;
T502:对该变量的每条变量定义信息,为该变量创建符号节点,符号节点信息包括变量符号名,该变量定义信息所在的源代码文件;
T503:对该变量的每条变量声明信息,为该变量创建声明节点,声明节点信息包括变量符号名,该变量声明信息所在的源代码文件;
T504:对该变量的每条变量使用信息,为该变量创建引用节点,引用节点信息包括变量符号名,该变量使用信息所在的源代码文件;
T505:对该变量对应的每个引用节点,在引用节点与符号节点之间添加依赖关系,依赖关系起点为该引用节点,终点为对应的符号节点,依赖关系类型为变量定义-使用依赖;
T506:对该变量对应的每个引用节点,在引用节点与声明节点之间添加依赖关系,依赖关系起点为该引用节点,终点为对应的声明节点,依赖关系类型为变量声明-使用依赖;
T507:如果该变量的类型为用户定义类型,那么在该变量使用的类型所对应的符号节点与该变量的符号节点之间添加依赖关系,依赖关系起点为该变量的符号节点,终点为该变量使用的类型所对应的符号节点,依赖关系类型为变量-类型使用依赖。
9.根据权利要求1所述的基于静态分析的C语言代码依赖关系提取方法,其特征在于:所述函数信息包括函数定义信息、函数声明信息、函数使用信息三种类型;
函数定义信息包括该函数的名称、函数的定义体、该条函数定义信息所在的源代码文件;
函数声明信息包括该函数的名称、参数列表、返回值、修饰符、该条函数声明信息所在的源代码文件;
函数使用信息包括该函数的名称、该条函数使用信息所在的源代码文件。
10.根据权利要求9所述的基于静态分析的C语言代码依赖关系提取方法,其特征在于,所述对每个函数,基于每条函数信息提取该函数产生的依赖关系,包括:
T601:如果该条函数信息所在的源代码文件为首次出现,为该指令所在的源代码文件创建文件节点;
T602:对该函数的每条函数定义信息,为该函数创建符号节点,符号节点信息包括函数名,该函数定义信息所在的源代码文件,对于该函数定义体中出现的所有宏符号、全局变量、函数调用和自定义类型,添加该函数与这些符号之间的依赖关系;
T603:对该函数的每条函数声明信息,为该函数创建声明节点,声明节点信息包括函数名,该函数声明信息所在的源代码文件,对于该函数声明中参数列表、返回值类型中出现的自定义类型,找到自定义类型对应的符号节点,对每个自定义类型对应的符号节点,在该符号节点与所在函数定义体对应的符号节点之间添加依赖关系,依赖关系起点为该自定义类型的符号节点,终点为所在函数的符号节点,依赖关系类型为函数声明依赖;
T604:对该函数的每条函数使用信息,为该函数创建引用节点,引用节点信息包括函数名,该函数使用信息所在的源代码文件;
T605:对该函数对应的每个引用节点,在引用节点与对应的符号节点之间添加依赖关系,依赖关系起点为该引用节点,终点为对应的符号节点,依赖关系类型为函数定义-使用依赖;
T606:对该函数对应的每个引用节点,在引用节点与对应的声明节点之间添加依赖关系,依赖关系起点为该引用节点,终点为对应的声明节点,依赖关系类型为函数声明-使用依赖。
11.根据权利要求10所述的基于静态分析的C语言代码依赖关系提取方法,其特征在于,所述对于该函数定义体中出现的所有宏符号、全局变量、函数调用和自定义类型,添加该函数与这些符号之间的依赖关系,包括:
M101:对于每个出现在函数定义体中的宏符号展开,找到宏符号对应的符号节点,对每个宏符号对应的符号节点,在该符号节点与所在函数定义体对应的符号节点之间添加依赖关系,依赖关系起点为该宏符号的符号节点,终点为所在函数的符号节点,依赖关系类型为函数-宏使用依赖;
M102:对于每个出现在定义体中的全局变量使用,找到全局变量对应的符号节点,对每个全局变量对应的符号节点,在该符号节点与所在函数定义体对应的符号节点之间添加依赖关系,依赖关系起点为该全局变量的符号节点,终点为所在函数的符号节点,依赖关系类型为函数-全局变量使用依赖;
M103:对于每个出现在函数定义体中的函数调用,找到函数调用对应的符号节点,对每个函数调用对应的符号节点,在该符号节点与所在函数定义体对应的符号节点之间添加依赖关系,依赖关系起点为该函数调用的符号节点,终点为所在函数的符号节点,依赖关系类型为函数-函数调用依赖;
M104:对于每个出现在函数定义体中的自定义类型使用,找到自定义类型对应的符号节点,对每个自定义类型对应的符号节点,在该符号节点与所在函数定义体对应的符号节点之间添加依赖关系,依赖关系起点为该自定义类型的符号节点,终点为所在函数的符号节点,依赖关系类型为函数-类型使用依赖。
12.根据权利要求1所述的基于静态分析的C语言代码依赖关系提取方法,其特征在于:所述类型包括:结构体、枚举型、共用体和别名,所述类型信息包括:该类型的名称、该类型的定义体、该类型所在的源代码文件。
13.根据权利要求1所述的基于静态分析的C语言代码依赖关系提取方法,其特征在于,所述对每个类型,基于类型信息提取该类型产生的依赖关系,包括:
M201:对于该类型定义体中出现的每个自定义类型使用,找到该自定义类型对应的符号节点,对每个自定义类型对应的符号节点,在该符号节点与所在类型定义体对应的符号节点之间添加依赖关系,依赖关系起点为该自定义类型的符号节点,终点为所在类型的符号节点,依赖关系类型为类型-类型使用依赖;
M202:对于该类型定义体中出现的每个宏符号展开,找到该宏符号对应的符号节点,对每个宏符号对应的符号节点,在该符号节点与所在类型定义体对应的符号节点之间添加依赖关系,依赖关系起点为该宏符号的符号节点,终点为所在类型的符号节点,依赖关系类型为类型-宏使用依赖。
14.根据权利要求1所述的基于静态分析的C语言代码依赖关系提取方法,其特征在于,所述基于符号级的依赖关系提取文件级的依赖关系,包括:基于宏符号的依赖关系中提取文件级的依赖关系,基于变量符号的依赖关系中提取文件级的依赖关系,基于函数符号的依赖关系中提取文件级的依赖关系,基于类型符号的依赖关系中提取文件级的依赖关系。
15.根据权利要求14所述的基于静态分析的C语言代码依赖关系提取方法,其特征在于,所述基于宏符号的依赖关系中提取文件级的依赖关系,包括:对于每个宏定义-使用依赖关系,它的起点为引用节点,终点为符号节点,从起始节点中获得引用文件对应的引用文件节点,从终止节点中获得定义文件对应的定义文件节点,如果引用文件和定义文件不同,那么在引用文件节点与定义文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为定义文件节点,依赖关系类型为文件间宏定义-使用依赖。
16.根据权利要求14所述的基于静态分析的C语言代码依赖关系提取方法,其特征在于,所述基于变量符号的依赖关系中提取文件级的依赖关系,包括:
M301:对于每个全局变量的每个变量定义-使用依赖,它的起点为引用节点,终点为符号节点,从起始节点中获得引用文件对应的引用文件节点,从终止节点中获得定义文件对应的定义文件节点,如果引用文件和定义文件不同,那么在引用文件节点与定义文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为定义文件节点,依赖关系类型为文件间变量定义-使用依赖;
M302:对于每个全局变量的每个变量声明-使用依赖,它的起点为引用节点,终点为声明节点,从起始节点中获得引用文件对应的引用文件节点,从终止节点中获得声明文件对应的声明文件节点;如果引用文件和声明文件不同,并且引用文件直接/间接地包含了声明文件,或该变量没有跨文件的变量定义-使用依赖,那么在引用文件节点与声明文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为声明文件节点,依赖关系类型为文件间变量声明-使用依赖;如果引用文件和声明文件不同,但是该变量有跨文件的变量定义-使用依赖,则需要进一步判断声明文件和定义文件;如果声明文件和定义文件相同,那么在引用文件节点与声明文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为声明文件节点,依赖关系类型为文件间变量声明-使用依赖。
17.根据权利要求14所述的基于静态分析的C语言代码依赖关系提取方法,其特征在于,所述基于函数符号的依赖关系中提取文件级的依赖关系,包括:
M401:对于每个函数定义-使用依赖,它的起点为引用节点,终点为符号节点,从起始节点中获得引用文件对应的引用文件节点,从终止节点中获得定义文件对应的定义文件节点,如果引用文件和定义文件不同,那么在引用文件节点与定义文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为定义文件节点,依赖关系类型为文件间函数定义-使用依赖;
M402:对于每个函数声明-使用依赖,它的起点为引用节点,终点为声明节点,从起始节点中获得引用文件对应的引用文件节点,从终止节点中获得声明文件对应的声明文件节点;如果引用文件和声明文件不同,并且引用文件直接/间接地包含了声明文件,或该函数没有跨文件的函数定义-使用依赖,那么在引用文件节点与声明文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为声明文件节点,依赖关系类型为文件间函数声明-使用依赖;如果引用文件和声明文件不同,但是该函数有跨文件的函数定义-使用依赖,则需要进一步判断声明文件和定义文件,如果声明文件和定义文件相同,那么在引用文件节点与声明文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为声明文件节点,依赖关系类型为文件间函数声明-使用依赖。
18.根据权利要求14所述的基于静态分析的C语言代码依赖关系提取方法,其特征在于,基于类型符号的依赖关系中提取文件级的依赖关系,包括:
M501:对于每个变量-类型使用依赖,它的起点为变量的符号节点,终点为类型的符号节点,从终止节点中获得类型定义所在的定义文件节点,根据变量的符号节点找到它对应的全部引用节点,对每个引用节点,从该引用节点中获得引用文件对应的引用文件节点,如果引用文件和定义文件不同,那么在引用文件节点与定义文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为定义文件节点,依赖关系类型为文件间类型定义-使用依赖;
M502:对于每个函数声明依赖,它的起点为函数的符号节点,终点为类型的符号节点,从终止节点中获得类型定义所在的定义文件节点,根据函数的符号节点找到它对应的全部引用节点,对每个引用节点,从该引用节点中获得引用文件对应的引用文件节点,如果引用文件和定义文件不同,那么在引用文件节点与定义文件节点之间添加依赖关系,依赖关系起点为引用文件节点,终点为定义文件节点,依赖关系类型为文件间类型定义-使用依赖。
19.根据权利要求1所述的基于静态分析的C语言代码依赖关系提取方法,其特征在于,基于类型符号的依赖关系中提取文件级的依赖关系,包括:
持久化节点信息,对于提取到的不同类型的符号级节点和文件级节点,将其节点的编号和所携带的信息输出到json格式的文件保存;
持久化依赖边信息,每条边用一个三元组表示,即分别表示起点、终点、依赖关系的类型,将每条依赖边的信息输出到json格式的文件保存。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202110650142.2A CN113326047B (zh) | 2021-06-10 | 2021-06-10 | 基于静态分析的c语言代码依赖关系提取方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202110650142.2A CN113326047B (zh) | 2021-06-10 | 2021-06-10 | 基于静态分析的c语言代码依赖关系提取方法 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN113326047A true CN113326047A (zh) | 2021-08-31 |
CN113326047B CN113326047B (zh) | 2023-11-03 |
Family
ID=77420860
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202110650142.2A Active CN113326047B (zh) | 2021-06-10 | 2021-06-10 | 基于静态分析的c语言代码依赖关系提取方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN113326047B (zh) |
Cited By (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN115794120A (zh) * | 2023-02-06 | 2023-03-14 | 南京邮电大学 | 一种基于高阶函数的动态程序依赖簇检测方法 |
CN117111951A (zh) * | 2023-08-23 | 2023-11-24 | 北京云枢创新软件技术有限公司 | 基于使用链的宏文本展开方法、电子设备和介质 |
Citations (9)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US20140007044A1 (en) * | 2012-07-02 | 2014-01-02 | Lsi Corporation | Source Code Generator for Software Development and Testing for Multi-Processor Environments |
US20150058832A1 (en) * | 2010-09-23 | 2015-02-26 | Apple Inc. | Auto multi-threading in macroscalar compilers |
CN107992307A (zh) * | 2017-12-11 | 2018-05-04 | 北京奇虎科技有限公司 | 一种函数编译方法及装置 |
CN109086050A (zh) * | 2018-07-04 | 2018-12-25 | 烽火通信科技股份有限公司 | 一种模块依赖关系的分析方法及系统 |
CN109918294A (zh) * | 2019-01-29 | 2019-06-21 | 刘建鹏 | 一种混源软件自主可控性检测方法及系统 |
CN110262803A (zh) * | 2019-06-30 | 2019-09-20 | 潍柴动力股份有限公司 | 一种依赖关系的生成方法及装置 |
CN110363004A (zh) * | 2018-04-10 | 2019-10-22 | 腾讯科技(深圳)有限公司 | 一种代码漏洞检测方法、装置、介质及设备 |
CN111104335A (zh) * | 2019-12-25 | 2020-05-05 | 清华大学 | 一种基于多层次分析的c语言缺陷检测方法及装置 |
CN112068842A (zh) * | 2020-09-15 | 2020-12-11 | 贝壳技术有限公司 | 依赖关系的建立方法、联动编译方法及其系统 |
-
2021
- 2021-06-10 CN CN202110650142.2A patent/CN113326047B/zh active Active
Patent Citations (9)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US20150058832A1 (en) * | 2010-09-23 | 2015-02-26 | Apple Inc. | Auto multi-threading in macroscalar compilers |
US20140007044A1 (en) * | 2012-07-02 | 2014-01-02 | Lsi Corporation | Source Code Generator for Software Development and Testing for Multi-Processor Environments |
CN107992307A (zh) * | 2017-12-11 | 2018-05-04 | 北京奇虎科技有限公司 | 一种函数编译方法及装置 |
CN110363004A (zh) * | 2018-04-10 | 2019-10-22 | 腾讯科技(深圳)有限公司 | 一种代码漏洞检测方法、装置、介质及设备 |
CN109086050A (zh) * | 2018-07-04 | 2018-12-25 | 烽火通信科技股份有限公司 | 一种模块依赖关系的分析方法及系统 |
CN109918294A (zh) * | 2019-01-29 | 2019-06-21 | 刘建鹏 | 一种混源软件自主可控性检测方法及系统 |
CN110262803A (zh) * | 2019-06-30 | 2019-09-20 | 潍柴动力股份有限公司 | 一种依赖关系的生成方法及装置 |
CN111104335A (zh) * | 2019-12-25 | 2020-05-05 | 清华大学 | 一种基于多层次分析的c语言缺陷检测方法及装置 |
CN112068842A (zh) * | 2020-09-15 | 2020-12-11 | 贝壳技术有限公司 | 依赖关系的建立方法、联动编译方法及其系统 |
Non-Patent Citations (3)
Title |
---|
DEVANSH TIWARI等: "etrics Driven Architectural Analysis using Dependency Graphs for C Language Projects", 《2019 IEEE 43RD ANNUAL COMPUTER SOFTWARE AND APPLICATIONS CONFERENCE (COMPSAC)》, pages 117 - 122 * |
周国富等: "CCNeter:C程序代码Petri网自动建模工具", 《计算机科学》, vol. 38, no. 5, pages 96 - 101 * |
姜人和等: "一种基于UML关系的Java代码库构造方法", 《计算机科学》, vol. 44, no. 11, pages 69 - 79 * |
Cited By (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN115794120A (zh) * | 2023-02-06 | 2023-03-14 | 南京邮电大学 | 一种基于高阶函数的动态程序依赖簇检测方法 |
CN115794120B (zh) * | 2023-02-06 | 2023-07-04 | 南京邮电大学 | 一种基于高阶函数的动态程序依赖簇检测方法 |
CN117111951A (zh) * | 2023-08-23 | 2023-11-24 | 北京云枢创新软件技术有限公司 | 基于使用链的宏文本展开方法、电子设备和介质 |
CN117111951B (zh) * | 2023-08-23 | 2024-03-15 | 北京云枢创新软件技术有限公司 | 基于使用链的宏文本展开方法、电子设备和介质 |
Also Published As
Publication number | Publication date |
---|---|
CN113326047B (zh) | 2023-11-03 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN112100054B (zh) | 一种面向数据管控的程序静态分析方法和系统 | |
US6292938B1 (en) | Retargeting optimized code by matching tree patterns in directed acyclic graphs | |
JP3966518B2 (ja) | プログラム解析装置、その解析方法及びプログラム | |
US8201140B2 (en) | System and method for creating and using graphical object instances in a statechart environment | |
CN113326047B (zh) | 基于静态分析的c语言代码依赖关系提取方法 | |
CN110059176B (zh) | 一种基于规则的通用文本信息抽取和信息生成方法 | |
CN100405294C (zh) | 在运行时期间优化计算机程序的系统与方法 | |
JPS6375835A (ja) | 目的コ−ド、プログラム・リスト及び設計文書を生成する装置 | |
CN108037913B (zh) | xUML4MC模型到MSVL语言程序的转换方法、计算机可读存储介质 | |
CN110780879B (zh) | 一种基于智能编译技术的决策执行方法、装置、设备及介质 | |
CN111708528A (zh) | 一种小程序的生成方法、装置、设备及存储介质 | |
US10915302B2 (en) | Identification and visualization of associations among code generated from a model and sources that affect code generation | |
CN112346730B (zh) | 一种中间表示的生成方法、计算机设备及存储介质 | |
CN111158663B (zh) | 用于处理程序代码中的变量的引用的方法和系统 | |
CN113987405A (zh) | 一种基于ast的数学表达式计算算法 | |
CN111381828A (zh) | 生成代码文件的语法树的方法、装置及电子设备 | |
CN110413284A (zh) | 词法分析方法、装置、计算机设备和存储介质 | |
CN111381826A (zh) | 生成代码文件的语法树的方法、装置及电子设备 | |
CN110889574A (zh) | 用于智能合约的不确定性因素检测装置、方法及介质 | |
CN111126012B (zh) | 定制生成表达式方法及装置 | |
Srivastava et al. | Cause effect graph to decision table generation | |
CN113448553B (zh) | 一种c语言项目依赖信息管理和可视化的方法及系统 | |
JP3166699B2 (ja) | オブジェクト指向プログラム設計支援装置、方法および記録媒体 | |
CN111381814A (zh) | 生成代码文件的语法树的方法、装置及电子设备 | |
CN111381827A (zh) | 生成代码文件的语法树的方法、装置及电子设备 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant |