LLVM新建全局变量
在LLVM中,有原生的AST Clone,却没有一个比较好的Stmt copy功能,基于Scout在LLVM上进行的修改,我们实现了自己的Stmt Clone功能。
要进行Stmt Clone,肯定需要新建新的AST节点,首先用一个立即介绍如何进行AST节点的构建,以新建一个全局的variable为例。
首先分析下需求,新建variable,自然的有几个问题:
1.变量如何新建
2.新建的变量应该处于程序的哪个部分
以如下的代码为例子:
int main()
{
return ;
}
我们有两个地方可以插入新建的variable,一个是将其作为全局变量进行插入,一个是作为main函数的局部变量进行插入,这里选择作为全局变量进行插入。那么插入后,示例代码会变成:
int main()
{
return ;
}
int a;
(想要有个比较系统的了解的,建议看下tools/clang/lib/StaticAnalyzer,StaticAnalyzer是一个良好的例子)
std::string keyName = "a";
int value = ; IdentifierTable& idTable = Context->Idents;
IdentifierInfo& idInfo =idTable.get(keyName);
const SourceLocation nopos;
VarDecl *tmpVar = VarDecl::Create(*Context, Context->getTranslationUnitDecl(), nopos, nopos, &idInfo, Context->IntTy, Context->CreateTypeSourceInfo(Context->IntTy), SC_None);
Context->getTranslationUnitDecl()->addDeclInternal (tmpVar);
IntegerLiteral *init = IntegerLiteral::Create(*Context,llvm::APInt(Context->getIntWidth(Context->IntTy),value,true),
Context->IntTy,nopos);
if (init != )
{
tmpVar->setInit(init);
}
如果想新建一个int *a;这种的,稍微比较麻烦,因为需要自己新建类型。在context中只提供了基础类型的:
// Builtin Types.
CanQualType VoidTy;
CanQualType BoolTy;
CanQualType CharTy;
CanQualType WCharTy; // [C++ 3.9.1p5].
CanQualType WideCharTy; // Same as WCharTy in C++, integer type in C99.
CanQualType WIntTy; // [C99 7.24.1], integer type unchanged by default promotions.
CanQualType Char16Ty; // [C++0x 3.9.1p5], integer type in C99.
CanQualType Char32Ty; // [C++0x 3.9.1p5], integer type in C99.
CanQualType SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy, Int128Ty;
CanQualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy;
CanQualType UnsignedLongLongTy, UnsignedInt128Ty;
CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty;
CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON
CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
CanQualType Float128ComplexTy;
CanQualType VoidPtrTy, NullPtrTy;
CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy;
CanQualType BuiltinFnTy;
CanQualType PseudoObjectTy, ARCUnbridgedCastTy;
CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy;
CanQualType ObjCBuiltinBoolTy;
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
CanQualType SingletonId;
#include "clang/Basic/OpenCLImageTypes.def"
CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy;
CanQualType OCLQueueTy, OCLNDRangeTy, OCLReserveIDTy;
CanQualType OMPArraySectionTy; // Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
mutable QualType AutoDeductTy; // Deduction against 'auto'.
mutable QualType AutoRRefDeductTy; // Deduction against 'auto &&'. // Decl used to help define __builtin_va_list for some targets.
// The decl is built when constructing 'BuiltinVaListDecl'.
mutable Decl *VaListTagDecl;
新建int *a;第一步自然是在源码中手动插入这样的代码,使用clang -fsyntax-only -Xclang -ast-dump test.cpp来查看这个新建的AST节点是如何表达的,再寻找对应的新建方式。
VarDecl 0xccec418 <test.cpp:2:1, col:6> col:6 a 'int *'
经过查找,我们发现,假如我们在遍历AST树根节点的子节点的时候,添加如下的处理代码:
else if(isa<VarDecl>(*D))
{
VarDecl *var = dyn_cast<VarDecl>(*D);
var->dump();
QualType varTp = var->getType(); while (true) {
varTp.dump();
const PointerType *pointTp = varTp->getAs<PointerType>();
if(pointTp==NULL)
{
const Type* ET = varTp->getArrayElementTypeNoTypeQual();
ET->dump();
break;
}
varTp = pointTp ->getPointeeType(); }
std::cout <<"********"<<std::endl;
}
输出的代码如下:
VarDecl 0xde9dcf0 <test.cpp::, col:> col: a 'int *'
PointerType 0xd732d00 'int *'
`-BuiltinType 0xd6a8140 'int'
BuiltinType 0xd6a8140 'int'
<<<NULL>>>
********
这里就比较明显了,这个VarDecl的QUALType是 PointerType,而PointerType对应的Pointee是int。
这样模仿上边的代码,如果新建一个int **aaaa;的节点,可以使用:
std::string keyName = "aaaa";
IdentifierTable& idTable = Context->Idents;
IdentifierInfo& idInfo =idTable.get(keyName);
const SourceLocation nopos;
QualType PointerTy_1 = Context->getPointerType(Context->getIntTypeForBitwidth(, ));
QualType PointerTy_2 = Context->getPointerType(PointerTy_1);
VarDecl *tmpVar = VarDecl::Create(*Context, Context->getTranslationUnitDecl(), nopos, nopos, &idInfo, PointerTy_2, Context->CreateTypeSourceInfo(PointerTy_2), SC_None);
Context->getTranslationUnitDecl()->addDecl (tmpVar);
本来想写Stmt Clone的,太多了,不好讲,先鸽。
LLVM新建全局变量的更多相关文章
- Android+Sqlite 实现古诗阅读应用(三)
		
往期传送门: Android+Sqlite 实现古诗阅读应用(一) Android+Sqlite 实现古诗阅读应用(二) 加入截图分享的功能. 很多应用都有分享的功能,我也想在我的古诗App里加入这个 ...
 - Axure一点
		
自己的感受:非常的考脑,上课要集中120分精神. Axure(快速制作网页原型) 1:全局变量:a:在菜单栏中可以新建全局变量. b:控制全部网页. c:取到输入框的值,设置User的值等于输入框的值 ...
 - nxlog4go 简介 - 基于log4go的下一代go语言日志系统
		
nxlog4go的项目网址: https://github.com/ccpaging/nxlog4go 项目历史 ccpaging's log4go forked from https://githu ...
 - Android NDK开发三:java和C\C++交互
		
转自:http://www.cnblogs.com/shangdahao/archive/2013/05/02/3053971.html 1.定义native方法并加载动态链接库: public cl ...
 - robotframework·RIDE基础
		
date:2018520 day09 一.学习环境 1.安装python27 2.安装robotframework(cmd→[pip install robotframework]) 3.安装WxPy ...
 - 10 - 函数嵌套-作用域-闭包-LEGB-函数销毁
		
目录 1 函数嵌套 2 作用域 2.1 global关键字 3 闭包 3.1 nonlocal关键字 4 默认值的作用域 5 变量名解析原则LEGB 6 函数的销毁 1 函数嵌套 一个 ...
 - vue多套样式切换
		
最近根据设计要求app需要根据不同环境切换不同样式,网上找了很多方法都不理想,后面自己脑洞大开这么完成的,请大佬多指教! 一.新建全局变量js文件和公用样式文件,在main.js中引入 import ...
 - ifix 在切换菜单按钮弹出”已打开该画面“bug修复
		
在ifix项目中,实际上会用到点击按钮弹出按钮菜单,点击另一按钮弹出另一按钮菜单的情况.一般在使用过程中切换菜单可有如下两种普遍做法: 1.使用ClosePicture "Middle&qu ...
 - Atitit s2018.2 s2 doc list on home ntpc.docx    \Atiitt uke制度体系  法律 法规 规章 条例 国王诏书.docx \Atiitt 手写文字识别  讯飞科大 语音云.docx \Atitit 代码托管与虚拟主机.docx \Atitit 企业文化  每日心灵 鸡汤 值班 发布.docx \Atitit 几大研发体系对比 Stage-Gat
		
Atitit s2018.2 s2 doc list on home ntpc.docx \Atiitt uke制度体系 法律 法规 规章 条例 国王诏书.docx \Atiitt 手写文字识别 ...
 
随机推荐
- as 什么意思?
			
You can denote particular console messages and variable values as having different types using four ...
 - Markdown 图片的简单处理
			
0. 前言 最近写 md 文章的时候发现,在 markdown 里插入一些很长的图片的时候,会显得很不好看,于是去查了一下如何实现 markdown 里图片的并排显示,参考了各个博客内的内容和 mar ...
 - ubuntu下virtualbox的安装、卸载
			
一.添加VirtualBox的源并安装5.1版本 virtualbox官网:https://www.virtualbox.org/wiki/Download_Old_Builds 虽然也可以直接安装d ...
 - windows下node.js安装配置
			
转自 http://www.cnblogs.com/yzadd/p/6547668.html
 - 【ARTS】01_27_左耳听风-201900513~201900519
			
ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 Algo ...
 - paramiko实现putty功能
			
paramiko模块提供了ssh及sft进行远程登录服务器执行命令和上传下载文件的功能.这是一个第三方的软件包,使用之前需要安装. context:python3.5 执行命令 1.基于用户名和密码方 ...
 - DOTS原则和愿景
			
Unity Data Oriented Tech Stack基于一系列原则.这些原则为我们正在努力实现的目标提供了良好的背景.一些原则清楚地反映在代码中.其他则只是我们为自己设定的目标. 默认情况下的 ...
 - 深度优先dfs与广度bfs优先搜索总结+例题
			
DFS(Deep First Search)深度优先搜索 深度优先遍历(dfs)是对一个连通图进行遍历的算法.它的思想是从一个顶点开始,沿着一条路一直走到底,如果发现不能到达目标解,那就返回到上一个节 ...
 - 《C专家编程》读书笔记之第8~11章
			
八.为什么程序员无法分清万圣节和圣诞节 1. 整形提升是指char,short int和位段类型(无论signed或unsigned)以及枚举类型将被提升为int或unsigned int(如果int ...
 - poj3107(树的重心,树形dp)
			
题目链接:https://vjudge.net/problem/POJ-3107 题意:求树的可能的重心,升序输出. 思路:因为学树形dp之前学过点分治了,而点分治的前提是求树的重心,所以这题就简单水 ...