github, git, google: clang-前端插件-给各种无花括号的“块”加花括号-基于llvm15--clang-plugin-add-brace-----google镜像

[复制链接]
发表于 2026-4-8 07:28:27 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
处置惩罚的语句

case

术语约定或备忘

      
  • case起止范围: 从冒号到下一个’case’开头, 简称有: case内 、case内容  
  • Ast: Abstract syntax tree: 抽象语法树
没插入花括号的case

   若case内, 以下任一条建立,则 跳过该case 即 不会对该case内容用花括号包裹.
  
       
  • 有#define、   
  • 有#include、   
  • 有直属变量声明、   
  • 空case、   
  • 有宏调用  
  详述

预处置惩罚回调网络#include指令、宏界说

   CollectIncMacro_PPCb:Collect Inlucde Macro PPCallbacks : 网络Inlucde和Macro的预处置惩罚回调
     网络 #include、 #define , 以判断case起止范围内 有无 #include、 #define
    遍历switch内某case起止范围内每条语句

   RangeHasMacroAstVst: Range Has Macro Call Ast Vistor: 给定范围有无宏调用Ast遍历器
     名义上遍历整个switch下的Stmt,现实遍历 给定范围内( 即 case起止范围 内) 的语句,举行以下盘算:
   
  1. 1. hasMacro: case起止范围 有无宏调用,
  2.   从而帮助过滤掉 有宏调用 的case
  3. 2. caseKSubStmtCnt:    case起止范围 语句个数(即 case子语句个数),
  4.   从而帮助 过滤掉 空case
  5. 3. VarDeclDirectlyInCaseKCnt:   直接写在'case'内的变量声明语句个数,
  6.   即 直属变量声明个数
  7.   从而 帮助过滤掉 有直属变量声明 的case。
  8.   直接写在'case'内的变量声明语句个数,包括以下两种情况:
  9.   3.1. 直接写在'case'内,其父亲是case语句的
  10.   3.2. 直接写在'case'内, 但是其父亲是switch块的.  
  11.     即 存在 在case内的语句 但却不属于该case  而是直接属于switch, 此现象,直接导致 case的子语句 是伪命题,
  12.       才使得 RangeHasMacroAstVst 不可能 实现无遗漏地 遍历 case下的子语句 ,
  13.         只能扩大遍历范围到整个switch 并只关注case起止范围内的语句 才能 实现无遗漏地、精准地 遍历 case下的子语句。
复制代码
现实运行花括号插件

   到此 加花括号插件竣工了,在llvm-project上正常运行:
  1. sudo docker exec -it ubuntu2204_clang15Compile bash
复制代码
  弹出docker实例ubuntu2204_clang15Compile的bash下令行,以下下令都在此下令行下实行
  1. cd /pubx/
  2. git clone https://gitcode.net/pubz/llvm-project/-/commits/brc-dev-no_tick
  3. #即 https://gitcode.net/pubz/llvm-project/-/commit/bee38a325d0957a28b4d06cb4be3c251d143cdf0
  4. #克隆仓库llvm-project后目录结构如下: /pubx/llvm-project/.git/config
复制代码

      
  • 步调1: 对每个被直接编译的源文件中单语句加花括号
   对llvm-project的每个源文件的编译过程应用插件libBrcPlugin.so 以 对 该源文件中单语句加花括号
  1. source /pubx/llvm-project/doc_clang15_build/brc_build1_plugin.sh
复制代码
  brc_build1_plugin.sh
  
      
  • 步调2: 对加了花括号后的llvm-project再次做正常的平凡编译
  1. source /pubx/llvm-project/doc_clang15_build/brc_build2_directly.sh
复制代码
  brc_build2_directly.sh
  
      
  • 步调3: 验证
  1. //编写c语言源文件 hello.c,内容如下:
  2. #include <stdio.h>
  3. int main(int argc, char** argv){
  4.    
  5.    
  6.   int a,b;
  7.   printf("a,b:");
  8.   scanf("%d,%d",&a,&b);
  9.   int sum=a+b, diff=a-b, div=a/b, mod=a%b;
  10.   printf("sum=%d,diff=%d,div=%d,mod=%d\n",sum,diff,div,mod);
  11.   return 0;
  12. }
复制代码
  1. /pubx/build-llvm15/bin/clang-15  hello.c  -o hello.app
  2. ./hello.app
  3. a,b:45,21
  4. sum=66,diff=24,div=2,mod=3
复制代码
  加完花括号的llvm-project源码编译出的编译器clang-15 对 hello.c 实行编译, 编译出二进制文件 hello.app,
  而该二进制文件 hello.app 正常运行
  由此分析 ,花括号加的位置根本正确。
  #统计
  1. find /pubx/llvm-project/ -not -path '*/.git/*' -type f  \( -name "*.cpp" -or -name "*.c"  \)   | xargs -I% grep -Hn    BrcXxx    % > /pubx/BrcXxx.log
  2. #把上一条bash命令抽成bash函数
  3. findBrcCommentThenSave() {
  4.    
  5.    
  6.   set -x #bash启用显示执行的命令
  7.   keyword=$1
  8.   find /pubx/llvm-project/ -not -path '*/.git/*' -type f \( -name "*.cpp" -or -name "*.c" \) | xargs -I% grep -Hn "$keyword" % |tee  /pubx/"${keyword}.log"
  9.   set +x #bash禁止显示执行的命令
  10. }
复制代码
  1. findBrcCommentThenSave BrcThen
  2. findBrcCommentThenSave BrcSw
  3. findBrcCommentThenSave BrcElse
  4. findBrcCommentThenSave BrcFor
  5. findBrcCommentThenSave BrcForRange
  6. findBrcCommentThenSave BrcWhl
  7. findBrcCommentThenSave BrcSw
复制代码
  各种语句分别加了多少花括号
  1. ls -S /pubx/Brc* | xargs -I% sh -c  'wc -l %; '
  2. '''
  3. 93201 /pubx/BrcThen.log
  4. 29832 /pubx/BrcSw.log
  5. 5539 /pubx/BrcElse.log
  6. 3603 /pubx/BrcFor.log
  7. 2187 /pubx/BrcForRange.log
  8. 663 /pubx/BrcWhl.log
  9. '''
复制代码
  各种语句加了花括号的,有多少含有return
     这些单语句return,由于没有被花括号包裹,才没有被t_clock_tick插入栈变量开释语句。
而tick插件栈变量分配、开释不均衡,详细为 栈变量共24万、终极残留2万没开释。 此不均衡是 由于 这些约莫5万个单return语句没开释栈变量 导致的吗?
如下所示,被BrcPlugin插入花括号的语句中 约莫5万个含有return.
   
  1. ls -S /pubx/Brc* | xargs -I% sh -c  'echo -n "%    "; grep return % |wc -l '
  2. '''
  3. /pubx/BrcThen.log    50438
  4. /pubx/BrcSw.log    2681
  5. /pubx/BrcElse.log    815
  6. /pubx/BrcFor.log    6
  7. /pubx/BrcForRange.log    4
  8. /pubx/BrcWhl.log    2
  9. '''
复制代码
实现

代码堆栈(私有堆栈) clang-plugin-add-brace.git
CMakeLists.txt

  1. cmake_minimum_required(VERSION 3.13.4)
  2. set(LIBFMT_DIR "/pubx/fmt/")
  3. #set(LIBFMT_STATIC /pubx/fmt/include)
  4. set(LIBFMT_INCLUDE "${LIBFMT_DIR}/include/")
  5. #set(LIBFMT_STATIC /pubx/fmt/build/libfmt.a)
  6. set(LIBFMT_STATIC "${LIBFMT_DIR}/build/libfmt.a")
  7. include_directories( "${CMAKE_CURRENT_SOURCE_DIR}/include")
  8. include_directories( "${CMAKE_CURRENT_SOURCE_DIR}/base_home/include/")
  9. if (NOT EXISTS "${LIBFMT_STATIC}")
  10.   MESSAGE(FATAL_ERROR "libfmt静态库${LIBFMT_STATIC} 不存在,请参照 build-libfmt.sh 构建libfmt静态库")
  11. endif()
  12. if (NOT EXISTS "${LIBFMT_INCLUDE}")
  13.   MESSAGE(FATAL_ERROR "libfmt头文件目录${LIBFMT_INCLUDE} 不存在,请参照 build-libfmt.sh 构建libfmt静态库")
  14. endif()
  15. #===============================================================================
  16. # 0. GET CLANG INSTALLATION DIR
  17. #修改默认编译器
  18. set(CT_Clang_INSTALL_DIR "/llvm_release_home/clang+llvm-15.0.0-x86_64-linux-gnu-rhel-8.4")
  19. set(CMAKE_VERBOSE_MAKEFILE ON)
  20. set(CURSES_LIBRARY "/lib64/libncurses.so.6")
  21. set(CURSES_INCLUDE_PATH "/usr/include/")
  22. set(CMAKE_EXPORT_COMPILE_COMMANDS True)
  23. #编译器还是使用自带的gcc, 否则 调试时 没有 libstdc++  的调试信息,导致std::string在gdb中不显示,参考:https://stackoverflow.com/questions/58356385/python-exception-class-gdb-error-there-is-no-member-named-m-dataplus-whe/58356946#58356946
  24. #   gdb显示std::string时报错: There is no member named _M_dataplus。 因此gdb不显示std::string的值.
  25. #set(CMAKE_C_COMPILER "/llvm_release_home/clang+llvm-15.0.0-x86_64-linux-gnu-rhel-8.4/bin/clang")
  26. #set(CMAKE_CXX_COMPILER "/llvm_release_home/clang+llvm-15.0.0-x86_64-linux-gnu-rhel-8.4/bin/clang++")
  27. set(LLVM_DIR "/llvm_release_home/clang+llvm-15.0.0-x86_64-linux-gnu-rhel-8.4")
  28. #set(xxx "")
  29. project(clang-brc)
  30. #project放到默认编译器定义之后,否则cmake会死循环
  31. set(CT_LLVM_INCLUDE_DIR "${CT_Clang_INSTALL_DIR}/include/llvm")
  32. set(CT_LLVM_CMAKE_FILE "${CT_Clang_INSTALL_DIR}/lib/cmake/clang/ClangConfig.cmake")
  33. # http://llvm.org/docs/CMake.html#embedding-llvm-in-your-project
  34. list(APPEND CMAKE_PREFIX_PATH "${CT_Clang_INSTALL_DIR}/lib/cmake/clang/")
  35. find_package(Clang REQUIRED CONFIG)
  36. # Sanity check. As Clang does not expose e.g. `CLANG_VERSION_MAJOR` through
  37. # AddClang.cmake, we have to use LLVM_VERSION_MAJOR instead.
  38. # TODO: Revisit when next version is released.
  39. if(NOT "15" VERSION_EQUAL "${LLVM_VERSION_MAJOR}")
  40.   message(FATAL_ERROR "Found LLVM ${LLVM_VERSION_MAJOR}, but need LLVM 15")
  41. endif()
  42. message(STATUS "Found Clang ${LLVM_PACKAGE_VERSION}")
  43. message(STATUS "Using ClangConfig.cmake in: ${CT_Clang_INSTALL_DIR}")
  44. message("CLANG STATUS:
  45.   Includes (clang)    ${
  46.    
  47.    CLANG_INCLUDE_DIRS}
  48.   Includes (llvm)     ${
  49.    
  50.    LLVM_INCLUDE_DIRS}"
  51. )
  52. # Set the LLVM and Clang header and library paths
  53. include_directories(SYSTEM "${LLVM_INCLUDE_DIRS};${CLANG_INCLUDE_DIRS}")
  54. #===============================================================================
  55. # 3. CLANG-brc BUILD CONFIGURATION
  56. #===============================================================================
  57. # Use the same C++ standard as LLVM does
  58. set(CMAKE_CXX_STANDARD 17 CACHE STRING "")
  59. # Build type
  60. if(NOT CMAKE_BUILD_TYPE)
  61.   set(CMAKE_BUILD_TYPE Debug CACHE
  62.       STRING "Build type (default Debug):" FORCE)
  63. endif()
  64. # Compiler flags
  65. set(CMAKE_CXX_FLAGS "${
  66.    
  67.    CMAKE_CXX_FLAGS} -Wall\
  68.     -fdiagnostics-color=always")
  69. # LLVM/Clang is normally built without RTTI. Be consistent with that.
  70. if(NOT LLVM_ENABLE_RTTI)
  71.   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
  72. endif()
  73. # -fvisibility-inlines-hidden is set when building LLVM and on Darwin warnings
  74. # are triggered if llvm-tutor is built without this flag (though otherwise it
  75. # builds fine). For consistency, add it here too.
  76. include(CheckCXXCompilerFlag)
  77. check_cxx_compiler_flag("-fvisibility-inlines-hidden"
  78.   SUPPORTS_FVISIBILITY_INLINES_HIDDEN_FLAG)
  79. if(${
  80.    
  81.    SUPPORTS_FVISIBILITY_INLINES_HIDDEN_FLAG} EQUAL "1")
  82.   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden")
  83. endif()
  84. # Set the build directories
  85. set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")
  86. set(
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表