ROSE 编译器框架/常见问题解答
我们收集了一个关于 ROSE 的常见问题解答列表,这些问题主要来自 rose-public 邮件列表 链接
在 Google 搜索中使用以下命令
site:https://mailman.nersc.gov/pipermail/rose-public $(ADD_YOUR_SEARCH_TERM_HERE)
ROSE_Install_path/include/rose/rosePublicConfig.h
/* Define to the version of this package. */ #define ROSE_PACKAGE_VERSION "0.9.8.54"
在你的代码中检查这一点
bool checkRoseVersionNumber(const std::string &need) { std::vector<std::string> needParts = rose::StringUtility::split('.', need); std::vector<std::string> haveParts = rose::StringUtility::split('.', ROSE_PACKAGE_VERSION); for (size_t i=0; i < needParts.size() && i < haveParts.size(); ++i) { if (needParts[i] != haveParts[i]) return needParts[i] < haveParts[i]; } // E.g., need = "1.2" and have = "1.2.x", or vice versa return true; }
当你提交给 [email protected] 邮件列表的问题没有得到回复时,你可能会感到非常沮丧。你可能会想知道为什么 ROSE 工作人员有时无法提供帮助。
以下是一些可能的解释
- 他们与研究和开发领域中的其他人一样忙碌。他们可能日夜不停地工作以满足提案、论文、项目评审、交付成果等的截止日期。
- 鉴于 ROSE 由合作者、前工作人员、博士后和实习生做出的贡献的广度和深度,他们并不了解自己编译器的每个角落。此外,大多数贡献缺乏良好的文档,这是未来应该改进的地方。
- 有些问题很困难,是开放的研究和开发问题。他们可能也一无所知。
- 他们有时只是感到懒惰,或者正在休假。
及时获得问题答案和解决问题的可能替代方案
- 请先完成自己的功课(例如,Google 搜索)。
- ROSE 团队正在通过内部代码审查流程积极解决文档问题,以强制执行未来贡献的良好文档记录。
- 帮助他人,就是帮助自己。在 [email protected] 邮件列表上回答问题,并为这个社区可编辑的维基教科书做出贡献。
- 找到与 ROSE 团队正式合作或为其提供资金的方式。当资金流动时,事情会进展更快 :-) 这很悲哀,但却是这个忙碌世界中的真实情况。
截至 2012 年 7 月 11 日,不包括 EDG 子模块和所有源代码注释,ROSE 的核心(rose/src)大约有 **674,000 行** C/C++ 源代码。
包括测试、项目和教程目录,ROSE 的代码量约为 **200 万行**。
下面显示了一些详细信息
[rose/src]./cloc-1.56.pl . 3076 text files. 2871 unique files. 716 files ignored. http://cloc.sourceforge.net v 1.56 T=26.0 s (91.7 files/s, 39573.3 lines/s) ------------------------------------------------------------------------------- Language files blank comment code ------------------------------------------------------------------------------- C++ 908 75280 93960 354636 C 123 12010 3717 199087 C/C++ Header 915 28302 38412 121373 Bourne Shell 17 3346 4347 25326 Perl 4 743 1078 7888 Java 18 1999 4517 7096 m4 1 747 20 6489 Python 34 1984 1174 5363 make 148 1682 1071 3666 C# 11 899 274 2546 SQL 1 0 0 1817 Pascal 5 650 31 1779 CMake 168 1748 4880 1702 yacc 3 352 186 1544 Visual Basic 6 228 421 1180 Ruby 11 281 181 809 Teamcenter def 3 3 0 606 lex 2 103 47 331 CSS 1 95 32 314 Fortran 90 1 34 6 244 Tcl/Tk 2 29 6 212 HTML 1 8 0 15 ------------------------------------------------------------------------------- SUM: 2383 130523 154360 744023 -------------------------------------------------------------------------------
仅显示顶层信息(以 MB 为单位):du -msl * | sort -nr
170 tests 109 projects 90 src 19 docs 16 winspecific 16 ROSE_ResearchPapers 15 binaries 7 scripts 5 LicenseInformation 4 tutorial 4 autom4te.cache 2 libltdl 2 exampleTranslators 2 configure 2 config 2 ChangeLog
按大小(兆字节)对目录进行排序
du -m | sort -nr >~/size.txt
709 . 250 ./.git 245 ./.git/objects 243 ./.git/objects/pack 170 ./tests 109 ./projects 90 ./src 76 ./tests/CompileTests 50 ./tests/RunTests 40 ./tests/RunTests/FortranTests 34 ./tests/RunTests/FortranTests/LANL_POP 29 ./tests/RunTests/FortranTests/LANL_POP/netcdf-4.1.1 27 ./src/3rdPartyLibraries 23 ./tests/roseTests 23 ./src/frontend 22 ./tests/CompileTests/Fortran_tests 21 ./tests/CompilerOptionsTests 19 ./docs 18 ./tests/CompileTests/RoseExample_tests 18 ./src/midend 18 ./docs/Rose 16 ./winspecific 16 ./ROSE_ResearchPapers 15 ./tests/CompileTests/Fortran_tests/gfortranTestSuite 15 ./binaries/samples 15 ./binaries 14 ./tests/CompileTests/Fortran_tests/gfortranTestSuite/gfortran.dg 14 ./src/roseExtensions 11 ./projects/traceAnalysis 10 ./tests/CompileTests/A++Code 10 ./tests/CompilerOptionsTests/testCpreprocessorOption 10 ./tests/CompilerOptionsTests/A++Code 10 ./src/roseExtensions/qtWidgets 10 ./src/frontend/Disassemblers 10 ./projects/symbolicAnalysisFramework 10 ./projects/SATIrE 10 ./projects/compass 9 ./winspecific/MSVS_ROSE 9 ./tests/RunTests/A++Tests 9 ./tests/roseTests/binaryTests 9 ./src/frontend/SageIII 9 ./projects/symbolicAnalysisFramework/src 9 ./docs/Rose/powerpoints 8 ./winspecific/MSVS_project_ROSETTA_empty 8 ./projects/simulator 7 ./tests/RunTests/FortranTests/LANL_POP_OLD 7 ./tests/CompileTests/Cxx_tests 7 ./src/midend/programTransformation 7 ./src/midend/programAnalysis 7 ./src/3rdPartyLibraries/libharu-2.1.0 7 ./scripts 7 ./projects/symbolicAnalysisFramework/src/mpiAnal 7 ./projects/RTC 6 ./winspecific/MSVS_ROSE/Debug 6 ./tests/RunTests/FortranTests/LANL_POP/netcdf-4.1.1/ncdap_test 6 ./tests/roseTests/programAnalysisTests 6 ./src/3rdPartyLibraries/ckpt 6 ./src/3rdPartyLibraries/antlr-jars 6 ./projects/SATIrE/src 5 ./tests/RunTests/FortranTests/LANL_POP/pop-distro 5 ./tests/RunTests/FortranTests/LANL_POP/netcdf-4.1.1/libcf 5 ./tests/CompileTests/ElsaTestCases 5 ./src/ROSETTA 5 ./src/3rdPartyLibraries/qrose 5 ./projects/DatalogAnalysis 5 ./projects/backstroke 5 ./LicenseInformation 5 ./docs/Rose/AstProcessing
按大小列出文件
find . -type f -print0 | xargs -0 ls -s | sort -k1,1rn
241568 ./.git/objects/pack/pack-f366503d291fc33cb201781e641d688390e7f309.pack 13484 ./tests/CompileTests/RoseExample_tests/Cxx_Grammar.h 10240 ./projects/traceAnalysis/vmp-hw-part.trace 6324 ./tests/RunTests/FortranTests/LANL_POP_OLD/poptest.tgz 5828 ./winspecific/MSVS_ROSE/Debug/MSVS_ROSETTA.pdb 4732 ./.git/objects/pack/pack-f366503d291fc33cb201781e641d688390e7f309.idx 4488 ./binaries/samples/bgl-helloworld-mpicc 4488 ./binaries/samples/bgl-helloworld-mpixlc 4080 ./LicenseInformation/edison_group.pdf 3968 ./projects/RTC/tags 3952 ./src/frontend/Disassemblers/x86-InstructionSetReference-NZ.pdf 3908 ./tests/CompileTests/RoseExample_tests/trial_Cxx_Grammar.C 3572 ./winspecific/MSVS_project_ROSETTA_empty/MSVS_project_ROSETTA_empty.ncb 3424 ./src/frontend/Disassemblers/x86-InstructionSetReference-AM.pdf 2868 ./.git/index 2864 ./projects/compassDistribution/COMPASS_SUBMIT.tar.gz 2864 ./projects/COMPASS_SUBMIT.tar.gz 2740 ./ROSE_ResearchPapers/2007-CommunicatingSoftwareArchitectureUsingAUnifiedSingle-ViewVisualization-ICECC S.pdf 2592 ./docs/Rose/powerpoints/rose_compiler_users.pptx 2428 ./src/3rdPartyLibraries/ckpt/wrapckpt.c 2408 ./projects/DatalogAnalysis/jars/weka.jar 2220 ./scripts/graph.tar 1900 ./src/3rdPartyLibraries/antlr-jars/antlr-3.3-complete.jar 1884 ./src/3rdPartyLibraries/antlr-jars/antlr-3.2.jar 1848 ./src/midend/programTransformation/ompLowering/run_me_defs.inc 1772 ./src/3rdPartyLibraries/qrose/docs/QROSE.pdf 1732 ./tests/CompileTests/Cxx_tests/longFile.C 1724 ./src/midend/programTransformation/ompLowering/run_me_task_defs.inc 1656 ./ChangeLog 1548 ./tests/roseTests/binaryTests/yicesSemanticsExe.ans 1548 ./tests/roseTests/binaryTests/yicesSemanticsLib.ans 1480 ./ROSE_ResearchPapers/1997-ExpressionTemplatePerformanceIssues-IPPS.pdf 1408 ./docs/Rose/powerpoints/ExaCT_AllHands_March2012_ROSE.pptx ...
三个可能的原因
- 托管 EDG 二进制文件的网站已关闭(有一种手动方式获取二进制文件)。
- 我们不支持你使用的平台,因此没有适合你的 EDG 二进制文件。
- 你从非官方的仓库克隆了 ROSE,因此构建过程无法确定适合你的 EDG 二进制文件的正确版本。(下面提到了一个解决方案)。
rosecompiler.org 网站可能正在维护中。
因此你可能会遇到以下错误消息
make[3]: Entering directory `/home/leo/workspace/github-rose/buildtree/src/frontend/CxxFrontend' test -d /nfs/casc/overture/ROSE/git/ROSE_EDG_Binaries && cp /nfs/casc/overture/ROSE/git/ROSE_EDG_Binaries/roseBinaryEDG-3-3-i686-pc-linux-gnu-GNU-4.4-32fe4e698c2e4a90dba3ee5533951d4c.tar.gz . || wget http://www.rosecompiler.org/edg_binaries/roseBinaryEDG-3-3-i686-pc-linux-gnu-GNU-4.4-32fe4e698c2e4a90dba3ee5533951d4c.tar.gz --2012-08-05 12:58:29-- http://www.rosecompiler.org/edg_binaries/roseBinaryEDG-3-3-i686-pc-linux-gnu-GNU-4.4-32fe4e698c2e4a90dba3ee5533951d4c.tar.gz Resolving www.rosecompiler.org... 128.55.6.204 Connecting to www.rosecompiler.org|128.55.6.204|:80... failed: No route to host. make[3]: *** [roseBinaryEDG-3-3-i686-pc-linux-gnu-GNU-4.4-32fe4e698c2e4a90dba3ee5533951d4c.tar.gz] Error 4
在这种情况下,你应该索取丢失的 tar 包,或在我们的备份位置找到它
你无需克隆整个 edge 二进制仓库,因为它很大。你只需下载你需要的那个(在 github.com 上单击原始文件链接)。
获得 tar 包后,将其复制到你的构建树的 CxxFrontend 子目录
- buildtree/src/frontend/CxxFrontend
然后你应该能够正常地通过键入 make 来构建 rose。
待办事项:使用替代路径自动搜索以获取 edg 二进制文件
另一个可能的原因是您从非官方存储库克隆了本地 rose 存储库。
- 为了保持 rose 源代码和 EDG 二进制文件之间的正确匹配,我们需要一个规范的存储库可用。
make[3]: Leaving directory `/global/project/projectdirs/rosecompiler/rose-project-workspace/xomp-instr/buildtree/src/frontend/CxxFrontend/Clang' Unable to find a remote tracking a canonical repository. Please add a canonical repository as a remote and ensure it is up to date. Currently configured remotes are: origin => [email protected]/myrose.git Potential canonical repositories include: anything ending with "rose.git" (case insensitive) Unable to find a remote tracking a canonical repository. Please add a canonical repository as a remote and ensure it is up to date. Currently configured remotes are: origin => [email protected]/myrose.git Potential canonical repositories include: anything ending with "rose.git" (case insensitive) make[3]: Entering directory `/global/project/projectdirs/rosecompiler/rose-project-workspace/xomp-instr/buildtree/src/frontend/CxxFrontend' test -d /nfs/casc/overture/ROSE/git/ROSE_EDG_Binaries && cp /nfs/casc/overture/ROSE/git/ROSE_EDG_Binaries/roseBinaryEDG-3-3-x86_64-pc-linux-gnu-GNU-4.3-.tar.gz . || wget http://www.rosecompiler.org/edg_binaries/roseBinaryEDG-3-3-x86_64-pc-linux-gnu-GNU-4.3-.tar.gz --2013-02-15 17:26:42-- http://www.rosecompiler.org/edg_binaries/roseBinaryEDG-3-3-x86_64-pc-linux-gnu-GNU-4.3-.tar.gz Resolving www.rosecompiler.org... 128.55.6.204 Connecting to www.rosecompiler.org|128.55.6.204|:80... connected. HTTP request sent, awaiting response... 404 Not Found 2013-02-15 17:26:42 ERROR 404: Not Found. make[3]: *** [roseBinaryEDG-3-3-x86_64-pc-linux-gnu-GNU-4.3-.tar.gz] Error 1 make[3]: Leaving directory `/global/project/projectdirs/rosecompiler/rose-project-workspace/xomp-instr/buildtree/src/frontend/CxxFrontend' make[2]: *** [all-recursive] Error 1 make[2]: Leaving directory `/global/project/projectdirs/rosecompiler/rose-project-workspace/xomp-instr/buildtree/src/frontend/CxxFrontend' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/global/project/projectdirs/rosecompiler/rose-project-workspace/xomp-instr/buildtree/src/frontend' make: *** [all-recursive] Error 1 make: Leaving directory `/global/project/projectdirs/rosecompiler/rose-project-workspace/xomp-instr/buildtree/src'
解决方案:将官方 rose 存储库添加为本地存储库的另一个远程存储库
- 添加一个规范的存储库,比如 github 上的这个:git add remote official-rose https://github.com/rose-compiler/rose.git
- git fetch official-rose // 从规范的存储库中检索哈希值等
- 现在你可以再次构建 rose。它应该找到你刚刚添加的规范存储库,并使用它来查找匹配的 EDG 二进制文件
来自 http://rosecompiler.org/ROSE_UserManual/ROSE-UserManual.pdf 第 5 页
用于将 EDG 的 AST 转换为 SAGE III 的连接代码是松散地从 EDG C++ 源代码生成器派生的,并且构成了 SAGE III 从 EDG 到 SAGE III 的 IR 的翻译器基础。
根据我们拥有的许可,EDG 源代码和发行版中从 EDG AST 的翻译被排除在源代码发布之外,并通过二进制格式提供。EDG 工作的任何部分对 ROSE 用户都是不可见的。EDG 源代码仅供拥有 EDG 研究或商业许可证的人使用。
手册的第 2.6 章“获取用于研究用途的免费 EDG 许可证”包含有关如何获取 EDG 许可证的说明。
获得许可证后,请联系 ROSE 工作人员以验证您的许可证。之后,他们将为您提供有关如何继续操作的更多说明。
问题 编译 ROSE 需要几个小时,如何加快此过程?
答案
- 如果您有多核处理器,请尝试使用 make -j4(使用四个进程或更多您喜欢的进程进行构建)。
- 还可以尝试仅通过键入make -C src/ -j4在 src/ 下构建 librose.so
- 或者仅尝试在配置期间构建您感兴趣的语言支持,例如
- ../sourcetree/configure --enable-only-c # 如果你只对 C/C++ 支持感兴趣
- ../sourcetree/configure --enable-only-fortran # 如果你只对 Fortran 支持感兴趣
- ../sourcetree/configure --help # 显示所有其他选项以仅启用几种语言。
https://mailman.nersc.gov/pipermail/rose-public/2011-July/001015.html
ROSE 不处理不完整的代码。虽然这在未来可能是可能的。它将取决于语言,并且可能在很大程度上依赖于我们在内部使用的一些特定语言工具。然而,这并不是我们工作的重点。如果您想展示我们正在使用的一些内部工具或我们可以使用的替代工具如何处理不完整的代码,这可能很有趣,我们可以讨论它。
例如,我们目前没有使用 Clang,但如果它处理不完整的代码,这对于未来可能很有趣。我记得一些最新的 EDG 工作可能处理一些不完整的代码,如果这是真的,那可能也很有趣。我还没有尝试使用 OFP 处理不完整的代码,所以我不确定它的效果如何。同样,我不知道 ECJ Java 支持的不完整代码处理能力。如果您知道这些问题中的任何一个,我们可以进一步讨论。
我对此有一些疑问,即从不完整的代码分析中可以获得多少有意义的信息,因此这让我有点担心。我预计它非常依赖于语言,并且可能会对不完整的代码有一些限制。因此,更好地理解这个主题将是我的另一个要求。
https://mailman.nersc.gov/pipermail/rose-public/2011-April/000856.html
问题:我正在尝试分析 Linux 内核。我不确定 ROSE 可以处理的代码库的大小,也找不到有关它是否已在 Linux 内核源代码上进行过尝试的参考资料。截至目前,我正在尝试在源代码上运行标识转换器,我想知道是否可以使用 ROSE 完成,以及之前是否成功测试过。
简短回答:目前不行
长答案:我们默认使用 EDG 3.3,此版本的 EDG 不处理 Linux 内核代码的 asm() 语句中使用的 GNU 特定寄存器修饰符。可能还有其他问题,但这至少是我们之前在这方面工作时发现的问题。但我们正在努力将 EDG 前端升级到更新的版本 4.4。
https://mailman.nersc.gov/pipermail/rose-public/2010-November/000544.html
还没有。
我知道 ROSE 无法处理 Boost 的某些部分的情况。在每种情况下,这都是 EDG 问题,因为我们使用的是旧版本的 EDG。我们正在尝试升级到更新版本的 EDG (4.x),但该版本的 EDG 在 ROSE 中的使用没有包含足够的 C++ 支持,因此还没有准备好。C 支持已在内部测试,但我们需要更多时间来完成这项工作。
从 AST 中检索信息的常用步骤是
- 准备一个最简单的(最好只有 5-10 行),可编译的示例代码,其中包含您要查找的代码功能(例如 array[i][j],如果您好奇如何在 AST 中查找多维数组的使用),避免包含任何头文件(#include file.h)以使代码保持简洁。
- 请注意:示例代码中不要包含任何头文件。头文件(例如 #include <stdio.h>)可能会将数千个节点引入 AST。
- 使用 dotGeneratorWholeASTGraph 生成输入代码的详细 AST 点图
- 使用 zgrviewer-0.8.2 的 run.sh 可视化点图
- 在点图中以视觉/手动方式定位您想要的信息,了解要查找的内容以及查找位置
一些示例 AST 图可以在 https://github.com/chunhualiao/rose-ast 获取
一旦您知道如何手动在 AST 中查找子节点。您可以使用代码使用 AST 成员函数、遍历或 SageInteface 函数等来遍历 AST,以检索您想要的信息
- ROSE 默认情况下为名为 X 的子节点提供 get_X() 之类的成员访问函数。例如,对于 SgBinaryOp,在 AST 图中有一个名为 lhs_operand 的子节点,使用 get_lhs_operand()。
- 这些名称在 AST 图中显示为从父节点到子节点的边的标签。
要通过索引获取子节点,请使用该函数(尽管不推荐这样做)
virtual SgNode * get_traversalSuccessorByIndex (size_t idx)
或者相关且类似命名的函数。
https://mailman.nersc.gov/pipermail/rose-public/2010-April/000144.html
问题:我想在处理过程中从分析/转换中排除 #include 文件中的函数。
默认情况下,AST 遍历可能会访问所有 AST 节点,包括来自头文件的节点。
因此,AST 处理类提供了三个函数
- T traverse (SgNode * node, ..):遍历完整的 AST,表示来自包含文件的代码的节点
- T traverseInputFiles(SgProject* projectNode,..) 遍历表示命令行上指定的文件的 AST 的子树
- T traverseWithinFile(SgNode* node,..):仅表示与起始节点相同文件的代码的节点
https://mailman.nersc.gov/pipermail/rose-public/2011-April/000930.html
true/false 两个部分以前都是 SgBasicBlock。
后来,我们决定对块(用 {...})和单语句(不用 { ..})体进行更忠实的表示。因此它们现在是 SgStatement(SgBasicBlock 是 SgStatement 的子类)。
但似乎文档尚未更新以与更改保持一致。
您必须在代码中检查主体是块还是单个语句。或者您可以使用以下函数来确保所有主体必须是 SgBasicBlock。
// 以上所有 ensureBasicBlockAs*() 的包装器,用于确保 s 的父节点是一个包含语句列表作为子节点的范围语句,否则在两者之间生成一个 SgBasicBlock。
SgLocatedNode * SageInterface::ensureBasicBlockAsParent (SgStatement *s)
这被称为 ROSE AST 中的预处理信息。它们附加在附近的 AST 节点之前、之后或内部(只有具有源位置信息的节点)。
提供了一个示例翻译器来遍历输入代码的 AST 并转储有关找到的预处理信息的信息。此翻译器的源代码为 https://github.com/rose-compiler/rose/blob/master/exampleTranslators/defaultTranslator/preprocessingInfoDumper.C 。
要使用翻译器
buildtree/exampleTranslators/defaultTranslator/preprocessingInfoDumper -c main.cxx ----------------------------------------------- Found an IR node with preprocessing Info attached: (memory address: 0x2b7e1852c7d0 Sage type: SgFunctionDeclaration) in file /export/tmp.liao6/workspace/userSupport/main.cxx (line 3 column 1) -------------PreprocessingInfo #0 ----------- : classification = CpreprocessorIncludeDeclaration: String format = #include "all_headers.h" relative position is = before
如果您仔细查看整个 AST 图,您会发现同一个类的定义声明和非定义声明。
符号通常与非定义声明相关联。类定义与定义声明相关联。
您可能希望在尝试获取定义之前从非定义声明获取定义声明,就像此函数一样
SgFunctionDefinition* getFunctionDefinitionFromDeclaration(const SgFunctionDeclaration* funcDecl) { //Get the defining declaration (we don't know if funcDecl is the defining or nonDefining declaration SgFunctionDeclaration* funcDefDecl = isSgFunctionDeclaration(funcDecl->get_definingDeclaration()); ROSE_ASSERT(funcDefDecl != NULL); //Get the definition from the defining declaration SgFunctionDefinition* funcDef = isSgFunctionDefinition(funcDefDecl->get_definition()); ROSE_ASSERT(funcDef != NULL); return funcDef; }
第一步是熟悉表示数组类型 (SgArrayType) 和数组引用 (SgPntrArrRefExp) 的 AST。然后您可以从 AST 中检索必要的信息。
为了理解数组类型和数组引用,这里有一个示例,
// cat ~/temp/array.c int a[5][10][15]; // array declaration, a type is declared int foo() { return a[0][1][2]; // a reference to array element }
数组类型由 SgArrayType 表示。
int a[5][10][15],对应三个相互关联的 SgArrayType
List a->get_type() 将返回第一个
- SgArrayType_1: (index=5, base_type = SgArrayType_2)
- SgArrayType_2: (index=10, base_type = SgArrayType_3)
- SgArrayType_3: (index=15, base_type = SgTypeInt )
因此,从第一个到元素类型的遍历将获得所有维度大小 5-10-15
子树看起来像
SgArrayType_1 / \ 5 SgArrayType_2 / \ 10 SgArrayType_3 / \ 15 SgTypeInt
数组引用由 SgPntrArrRefExp 表示
像这样的引用:a[0][1][2]
- SgPntrArrRefExp_1
- SgPntrArrRefExp_2
- SgPntrArrRefExp_3
子树应该看起来像以下内容
a[0][1][2] //SgPntrArrRefExp / \ a[0][1] 2 // SgIntVal / \ a[0] 1 / \ a 0 SgVarRefExp
在 http://rosecompiler.org/ROSE_HTML_Reference/namespaceSageInterface.html 中有许多与数组处理相关的函数
您可以直接搜索“array”来找到它们
//Check if an expression is an array access (SgPntrArrRefExp). If so, return its name expression and subscripts if requested. Users can use convertRefToInitializedName() to get the possible name. It does not check if the expression is a top level SgPntrArrRefExp. SageInterface::isArrayReference (SgExpression *ref, SgExpression **arrayNameExp=NULL, std::vector< SgExpression * > **subscripts=NULL) // returns the array dimensions in an array as defined for arrtype std::vector< SgExpression * > SageInterface::get_C_array_dimensions (const SgArrayType &arrtype) // Get the number of dimensions of an array type. int SageInterface::getDimensionCount (SgType *t) // Get the element type of an array. SgType * SageInterface::getArrayElementType (SgType *t)
可以在 https://github.com/rose-compiler/rose-develop/blob/master/src/midend/programTransformation/ompLowering/omp_lowering.cpp 中找到使用这些函数的示例代码
例如,void linearizeArrayAccess(SgPntrArrRefExp* top_array_ref) 使用多维下标重写数组引用,以使用一维下标的引用
- a[i][j] 更改为 a[i*col_size +j]
- a [i][j][k] 更改为 a [(i*col_size + j)*K_size +k]
处理一维数组引用的示例代码
For 1-D array element access a[0], the AST with 3 nodes looks like: a[0] // node 1: SgPntrArrRefExp / \ a 0 //node 3: SgIntVal | // node 2: SgVarRefExp So the code searching for SgVarRefExp will find a. The next step is to check its type. SgVarRefExp *vref = ... ROSE_ASSERT (vref != NULL); SgType* t = vref->get_type(); if (SgArrayType* atype= isSgArrayType(t)) // now you have array type { // obtain the dimension vector vector<SgExpression*> dimensions = SageInterface::get_C_array_dimensions (* atype); // dimensions.size() should be 1 if you only handle 1-D array types if (dimensions.size() ==1) { SgPntrArrRefExp * arr_ref_exp = vref->get_parent(); // now you get a[0] from a. //do your things you want , with a (vref) and a[o] (arr_ref_exp) } } else if (SageInterface::isScalarType(t))// if scalar types, handle them differently { ... }
ROSE 开发者指南 (http://www.rosecompiler.org/ROSE_DeveloperInstructions.pdf) 中有一节名为“1.7 添加新的 SAGE III IR 节点(仅限开发者)”。
但在决定添加新节点之前,您可能要考虑 AstAttribute(附加到 AST 的用户定义对象)是否足以解决您的问题。
例如,ROSE 中 OpenMP 实现的第一个版本(rose/projects/OpenMP_Translator)最初使用 AstAttribute 来表示从编译指示解析的信息。只有在第二个版本中,我们才引入了专门的 AST 节点。
在 ROSE 中添加新的 IR 节点时,有两个独立的步骤。
- 第一步(声明):在 ROSE 中为新的 IR 节点添加类声明/实现。此步骤主要与 ROSETTA 相关。
- 第二步(创建):在某个时间点创建这些新的 IR 节点:例如,在前端、中端甚至后端(如果需要)中的某个地方。因此,此步骤将逐案决定。
如果新的 IR 类型来自它们在 EDG 中的对应类型,则需要修改 EDG/SAGE 连接代码。如果不是,则 EDG/SAGE 连接代码可能不相关。
如果您试图添加新节点来表示编译指示信息,则可以创建新的节点,而无需涉及 EDG 或它与 ROSE 的连接。您只需解析原始 AST 中的编译指示字符串并创建您自己的节点以获取 AST 的新版本。然后应该完成。
演示 AST 合并的测试位于目录中
tests/nonsmoke/functional/CompileTests/mergeAST_tests
(运行“make check”以查看数百个测试)。
AST 节点可以有一个父节点,它与它的范围不同。
例如:结构声明的父节点是 typedef 声明。但结构的范围是 typedef 声明的范围。
typedef struct frame {int x;} s_frame;
有一些实验性的支持将简单的代码文本解析为 AST 片段。它不是为了解析整个源代码。但这种支持应该能够扩展以处理更多类型的输入。
关于这项工作的一些文档
- http://rosecompiler.org/ROSE_HTML_Reference/namespaceAstFromString.html
- http://rosecompiler.org/ROSE_Tutorial/ROSE-Tutorial.pdf 第 33 章 解析器构建块
使用解析器构建块的示例项目
- projects/pragmaParsing 应该可以工作。
通常我们只对用户代码感兴趣。AST 表示来自用户和系统头文件的所有代码。我们需要跳过来自系统头文件的内容。
// Final most complete version, skip all header files, we cannot unparse changed AST from header files , at least by default if (Inliner::skipHeaders) { string filename= funcall->get_file_info()->get_filename(); string suffix = StringUtility ::fileNameSuffix(filename); //vector.tcc: This is an internal header file, included by other library headers if (suffix=="h" ||suffix=="hpp"|| suffix=="hh"||suffix=="H" ||suffix=="hxx"||suffix=="h++" ||suffix=="tcc") return false; // also check if it is compiler generated, mostly template instantiations. They are not from user code. if (funcall->get_file_info()->isCompilerGenerated() ) return false; // check if the file is within include-staging/ header directories if (insideSystemHeader(funcall)) return false; } //------------partial solutions bool processStatements(SgNode* n) { ROSE_ASSERT (n!=NULL); // Skip compiler generated code, system headers, etc. if (isSgLocatedNode(n)) { if (isSgLocatedNode(n)->get_file_info()->isCompilerGenerated()) return false; } ... }
这是基于 Sg_File_Info 的
Inside of Sg_File_Info::display(debug.......) isTransformation = false isCompilerGenerated = true (no position information) isOutputInCodeGeneration = false isShared = false isFrontendSpecific = true (part of ROSE support for gnu compatability) isSourcePositionUnavailableInFrontend = false isCommentOrDirective = false isToken = false file_id = 2 filename = /home/liao6/daily-test-rose/upcwork/install/include/gcc_HEADERS/rose_edg_required_macros_and_functions.h line = 167 column = 1 .... shared[1] int gsj; Inside of Sg_File_Info::display(debug.......) isTransformation = false isCompilerGenerated = false isOutputInCodeGeneration = false isShared = false isFrontendSpecific = false isSourcePositionUnavailableInFrontend = false isCommentOrDirective = false isToken = false filename = /home/liao6/svnrepos/mycode/rose/upc/unshared.upc line = 6 column = 1 file_id = 1 filename = /home/liao6/svnrepos/mycode/rose/upc/unshared.upc line = 6 column = 1
另一种方法是 rose 为所有系统头文件创建副本并将它们存储在专用路径中
bool insideSystemHeader (SgLocatedNode* node) { bool rtval = false; ROSE_ASSERT (node != NULL); Sg_File_Info* finfo = node->get_file_info(); if (finfo!=NULL) { string fname = finfo->get_filenameString(); string buildtree_str1 = string("include-staging/gcc_HEADERS"); string buildtree_str2 = string("include-staging/g++_HEADERS"); string installtree_str1 = string("include/edg/gcc_HEADERS"); string installtree_str2 = string("include/edg/g++_HEADERS"); // if the file name has a sys header path of either source or build tree if ((fname.find (buildtree_str1, 0) != string::npos) || (fname.find (buildtree_str2, 0) != string::npos) || (fname.find (installtree_str1, 0) != string::npos) || (fname.find (installtree_str2, 0) != string::npos) ) rtval = true; } return rtval; }
https://mailman.nersc.gov/pipermail/rose-public/2011-January/000604.html
问题:Rose identityTranslator 会“自动”执行一些修改。
这些修改是
- 扩展 assert 宏。
- 在 typedef 类型的常量周围添加额外的括号(例如,c=Typedef_Example(12); 在输出中转换为 c = Typedef_Example((12));)。
- 将 NULL 转换为 0。
我可以避免这些修改吗?
答案:不能。
目前没有简单的方法可以避免这些更改。其中一些是由 cpp 预处理器引入的。另一些是由 ROSE 使用的 EDG 前端引入的。100% 忠实的源代码到源代码翻译可能需要对预处理指令处理和 EDG 内部进行重大更改。
我们内部讨论过将原始标记字符串保存到 AST 中,并使用它们获取忠实的未解析代码。但据我所知,这项工作仍处于起步阶段。
https://mailman.nersc.gov/pipermail/rose-public/2010-July/000319.html
问题:我正在尝试构建一个工具,当源代码中存在属于特定组的函数(例如,所有以 foo_ 开头的函数)时,它会插入一个或多个函数调用。在 AST 遍历过程中,如何找到正确的位置,即,ROSE 中是否存在搜索字符串模式或类似功能的函数?
答案
- 在 ROSE 教程的第 28 章 AST 构建中,有一些示例使用遍历或 queryTree 将函数调用插入 AST。我将通过检查节点的特定 SgFunctionDefinition(或您需要的任何内容)来处理此问题,然后检查节点的名称以找到其位置。
- 您可以
- 使用 AST 查询机制查找所有函数并将它们存储在容器中。例如 Rose_STL_Container<SgNode*> nodeList = NodeQuery::querySubTree(root_node,V_Sg????);
- 然后迭代容器以检查每个函数,查看函数名称是否与您想要的匹配。
- 使用 SageBuilder 命名空间的 buildFunctionCallStmt() 创建函数调用语句。
- 使用 SageInterface 命名空间的 insertStatement () 进行插入。
有一个 SageInterface 函数可以做到这一点
// Insert include "filename" or include <filename> (system header) into the global scope containing the current scope, right after other include XXX. PreprocessingInfo * SageInterface::insertHeader (const std::string &filename, PreprocessingInfo::RelativePositionType position=PreprocessingInfo::after, bool isSystemHeader=false, SgScopeStatement *scope=NULL)
https://mailman.nersc.gov/pipermail/rose-public/2011-April/000919.html
我们需要更具体地说明您要复制的函数。它仅仅是一个原型函数声明(ROSE 中的非定义声明)还是带有定义的函数(ROSE 中的定义声明)?
- 使用以下函数可以复制非定义函数声明
// Build a prototype for an existing function declaration (defining or nondefining is fine). SgFunctionDeclaration* SageBuilder::buildNondefiningFunctionDeclaration (const SgFunctionDeclaration *funcdecl, SgScopeStatement *scope=NULL)
- 语义上,复制定义函数声明是一个问题,因为它引入了相同函数的重新定义。
至少这是一个技巧,先引入错误的东西,然后再纠正它。以下是一个用于执行此技巧的示例翻译器(复制一个定义函数,重命名它,修复其符号)
#include <rose.h> #include <stdio.h> using namespace SageInterface; int main(int argc, char** argv) { SgProject* project = frontend(argc, argv); AstTests::runAllTests(project); // Find a defining function named "bar" under project SgFunctionDeclaration* func= findDeclarationStatement<SgFunctionDeclaration> (project, "bar", NULL, true); ROSE_ASSERT (func != NULL); // Make a copy and set it to a new name SgFunctionDeclaration* func_copy = isSgFunctionDeclaration(copyStatement (func)); func_copy->set_name("bar_copy"); // Insert it to a scope SgGlobal * glb = getFirstGlobalScope(project); appendStatement (func_copy,glb); #if 0 // fix up the missing symbol, this should be optional now since SageInterface::appendStatement() should handle it transparently. SgFunctionSymbol *func_symbol = glb->lookup_function_symbol ("bar_copy", func_copy->get_type()); if (func_symbol == NULL); { func_symbol = new SgFunctionSymbol (func_copy); glb ->insert_symbol("bar_copy", func_symbol); } #endif AstTests::runAllTests(project); backend(project); return 0; }
- 另一个要考虑的是,如果您想将函数复制到另一个文件中。您必须更改克隆的文件位置信息。
ROSE 的反解析器在决定打印出 AST 部分的文本格式之前,会检查 AST 部分的 Sg_File_Info 对象。默认情况下,只有来自输入文件相同文件的 AST 或由转换生成的 AST 才会被反解析。例如,一些 AST 子树来自包含的头文件。但通常不希望反解析包含的头文件的内容。
如果文件信息仍然是原始文件信息,则解决方案是将复制的 AST 设置为由转换生成
// Recursively set source position info(Sg_File_Info) as transformation generated. SageInterface::setSourcePositionForTransformation (SgNode *root)
https://mailman.nersc.gov/pipermail/rose-public/2011-May/000971.html
不能。ROSE 目前不会反解析来自头文件的 AST。一个暑期项目尝试过这样做。但它没有完成并且没有经过良好的测试。
该选项为 -rose:unparseHeaderFiles -rose:unparseHeaderFilesRootFolder UNPARSED_HEADERS_DIR,位于 tests/CompilerTests/UnparseHeadersTests 中
https://mailman.nersc.gov/pipermail/rose-public/2010-August/000344.html
我认为 ROSE 不支持出于安全/实用原因写入修改后的头文件。修改后的头文件必须保存到另一个文件中,因为写入原始头文件非常危险(想象调试一个破坏输入头文件的头文件翻译器)。然后,所有使用修改后的头文件的其他文件/头文件都必须更新以使用新的头文件。
此外,所有参与的文件都必须可由用户的翻译器写入。
因此,当前的反解析器通过检查存储在 Sg_File_Info 对象中的文件标志(compiler_generated 和/或 output_in_code_generation 等)来跳过来自头文件的 AST 子树。
https://mailman.nersc.gov/pipermail/rose-public/2011-June/001008.html
//Get the actual arguments SgExprListExp* actualArguments = NULL; if (isSgFunctionCallExp(callSite)) actualArguments = isSgFunctionCallExp(callSite)->get_args(); else if (isSgConstructorInitializer(callSite)) actualArguments = isSgConstructorInitializer(callSite)->get_args(); ROSE_ASSERT(actualArguments != NULL); const SgExpressionPtrList& actualArgList = actualArguments->get_expressions(); //Get the formal arguments. SgInitializedNamePtrList formalArgList; if (calleeDef != NULL) formalArgList = calleeDef->get_declaration()->get_args(); //The number of actual arguments can be less than the number of formal arguments (with implicit arguments) or greater //than the number of formal arguments (with varargs)
ROSE 翻译器的预期行为
使用 ROSE 构建的翻译器旨在像编译器(gcc、g++、gfortran 等,具体取决于输入文件类型)一样工作。因此,翻译器的用户只需要更改输入文件的构建系统,以使用翻译器而不是原始编译器。
如果原始编译器隐式地包含或链接任何东西,您可能需要在更改后显式地设置包含或链接路径。例如,如果 mpiCC 透明地链接到 /path/to/mpilib.a,则您需要将此链接标志添加到修改后的 Makefile 中。
On 07/25/2012 11:20 AM, Fernando Rannou wrote: > > Hello > > > > We are trying to use ROSE to refactor a big project consisting of > > several *.cc and *.hh files, located at various directories. Each > > class is defined in a *.hh file and implemented in a *.cc file. > > Classes include (#include) other class definitions. But we have only > > found single file examples. > > > > Is this possible? If so, how? > > > > > > Thanks
https://mailman.nersc.gov/pipermail/rose-public/2012-August/001742.html 问题:我想知道 ROSE 是否可以将两个文件(.c 和 .cl)生成到它将 C 翻译成 OpenCL 时?
回答:ROSE 的轮廓器有一个选项可以将生成的函数输出到一个新文件。
... // Generate the outlined function into a separated new source file // -rose:outline:new_file extern bool useNewFile; ...
您可能想检查此选项在轮廓器源文件中是如何使用的,以获得您想要的内容。
问题:ROSE 的二进制分析功能如何?它仅仅是反汇编吗?如果与 ROSE 源代码分析结合使用,是否可以将二进制代码与源代码关联?
答案
ROSE 有各种二进制反汇编器(x86、ARM、MIPS、PowerPC),它们与源代码分析一样,以 AST 的形式创建二进制的内部表示。尽管源代码和二进制代码的 AST 节点类型在很大程度上是不同的,但可以使用类似于源代码分析的概念来分析二进制 AST。ROSE 有几个二进制分析。以下是我想到的一些
- 控制流图,虚拟的和使用 Boost 图形库的。
- 函数调用图。
- 对控制流图的操作:支配者、后支配者
- 指针检测分析,它试图弄清楚哪些内存位置用作高级语言中的指针。
- 指令分区:弄清楚如何将指令分组到基本块中,以及如何在只有指令列表的情况下将基本块分组到函数中。它在自动分区剥离的、混淆的代码方面的准确性已证明优于使用调试信息和符号表的最佳反汇编器。
- x86 指令语义。这是一个正在积极开发的领域,但目前仅支持 32 位整数指令。我们计划添加浮点数、SIMD、64 位、其他架构和更简单的 API。但即使按目前的状况,它也足够完整,可以模拟完整的 ELF 可执行文件(甚至 "vi")。请参见下一项
- 用于 ELF 可执行文件的 x86 模拟器。这个项目能够模拟 Linux 内核如何加载可执行文件以及可执行文件发出的各种系统调用。它足够完整,可以模拟许多 Linux 程序,但也提供回调点供用户插入各种类型的分析。例如,您可以使用它在动态链接后反汇编整个进程。在 projects/simulator 目录中有很多示例。与 Qemu、Bochs、valgrind、VirtualBox、VMware 等以速度为主要设计驱动的模拟器相比,ROSE 模拟器旨在为用户提供对尽可能多的执行方面的访问权限。
- 指令语义的插件。指令语义的编写方式允许插入不同的“语义域”。ROSE 具有符号域、区间域和部分符号域。符号域可与 SMT 求解器(目前支持 Yices)结合使用。区间域实际上是区间集,并且是二元算术感知的(即,在固定字长上正确处理溢出等)。部分符号域使用单节点表达式来优化速度和大小,但以准确性为代价。用户可以编写其他域,并且新的 API(正在开发中)将使此操作更加容易。
- 数据流分析的示例(例如,前面提到的指针分析),但尚未形成一个明确的框架(有人正在开发)。目前,数据流类型分析是使用指令语义支持来实现的:当每个指令“执行”时,它所执行的域会导致数据在机器状态中流动。每种分析都提供自己的流方程来处理来自两个或多个方向的控制流汇合点;并提供自己的“下一条指令”函数来迭代控制流图。
- 各种格式的克隆检测:各种形式的句法克隆检测,包括一种使用局部敏感哈希的克隆检测;以及通过模拟器中的模糊测试进行的语义克隆检测。
由 Robb 撰写
您询问关于将源代码分析和二进制分析相结合的问题……这当然是可以实现的,因为 ROSE 可以同时在内存中保存二进制和源代码 AST。但我不知道有哪种分析将它们“缝合”在一起。我们确实支持从 ELF 可执行文件中解析 DWARF 信息,因此您可能可以使用它将两个 AST 缝合在一起。
--Robb
症状
git clone https://github.com/rose-compiler/rose.git Cloning into rose... error: SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed while accessing https://github.com/rose-compiler/rose.git/info/refs fatal: HTTP request failed
原因可能是您位于一个修改了原始 SSL 证书的防火墙之后。
解决方案:告诉 cURL 不要检查 SSL 证书
#Solution 1: Environment variable (temporary) $ env GIT_SSL_NO_VERIFY=true git pull # Solution 2: git-config (permanent) # set local configuration $ git config --local http.sslVerify false # Solution 2: set global configuration $ git config --global http.sslVerify false
https://mailman.nersc.gov/pipermail/rose-public/2010-April/000115.html
可能没有一个广为人知的最佳集成开发环境。但开发人员报告称他们正在使用
- vim
- emacs
- KDevelop
- Source Navigator
- Eclipse
- Netbeans
问题是 ROSE 规模庞大,并且包含一些非常大的生成的源代码文件(例如,CxxGrammar.h 和 CxxGrammar.C 在构建树中生成)。因此,许多代码浏览器可能难以处理 ROSE。
我们确实维护了一些初步的 Windows 支持,通过利用 cmake 来构建 ROSE/src 以生成 librose.so。但是,这项工作尚未完成。
要在 Windows 下构建 librose,请在顶层源代码树中键入以下命令行
mkdir ROSE-build-cmake cd ROSE-build-cmake cmake .. -DBOOST_ROOT=${ROSE_TEST_BOOST_PATH} // Example: boost installation path /opt/boost_1_40_0-inst
https://mailman.nersc.gov/pipermail/rose-public/2011-December/001349.html
我们尚未完成 Windows 工作。它在我们待办事项列表中。我们已经开始使用 MS Visual Studio(使用我们维护并在 ROSE 发布过程中进行测试的 Cmake 构建生成的项目文件)在内部编译 ROSE,但它没有通过我们的测试。因此它还没有准备好。Windows 版 EDG 二进制文件的发布是另一项工作,将在之后完成。目前我们不知道何时完成这项工作,它很重要,但对于我们的 DOE 特定工作来说并不优先,但对于其他工作来说很重要。所需的工作我们可以讨论。如果您想打电话给我,那将是最好的解决方法。给我发一封邮件,不要发到主列表,我们可以安排一下。
https://mailman.nersc.gov/pipermail/rose-public/2011-March/000798.html
在 Windows 下,ROSE 使用 CMake。这是一个目前正在开发的项目。截至 2010 年 11 月,我们能够编译和链接 src 目录。我们还能够运行链接到 librose 并在前端和后端执行的示例程序。{\em 但是,这是一个内部功能,目前尚未公开提供,因为我们没有分发所需的 Windows 生成的 EDG 二进制文件。此外,目前对 Windows 的支持仍不完整,ROSE 尚未通过其在 Windows 下的内部测试。}