在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的,太多了,不好讲,先鸽。

最新文章

  1. jQuery中width、innerWidth、outerWidth的区别
  2. java 堆栈分析4
  3. ABAP中的Table Control编程
  4. [Everyday Mathematic]20150216
  5. 缓存淘汰算法---LRU
  6. [js高手之路]HTML标签解释成DOM节点
  7. 【HTML】 HTML基础知识 表单
  8. Elasticsearch笔记八之脑裂
  9. lanya
  10. Java中代理
  11. Spring Security之动态配置资源权限
  12. docker安装solr集群5.3.1
  13. springboot之thymeleaf学习
  14. vue项目webpack打包后有的文件big 问题
  15. Java: 扩大字节缓存区的大小,提升AIO的处理性能(并发性能)
  16. C# 获取接口数据(xml格式)转为json格式
  17. Vuex 状态管理模式
  18. Delphi Firemonkey在主线程 异步调用函数(延迟调用)
  19. 新一代的USB 3.0传输规格
  20. [C++] Operator Overload

热门文章

  1. centos7.4出现yum command not found
  2. vim基础学习1---简单命令
  3. MyISAM与InnoDB之间的区别
  4. PowerDesigner设置code和name不联动的方法
  5. maven编译正常,运行报错:中没有主清单属性
  6. 关于POW机制及POW难度调节机制
  7. 【JS新手教程】弹出两层div,及在LODOP内嵌上层
  8. iOS——归档对象的创建,数据写入与读取
  9. IDEA配置Hystrix过程中报错: java.lang.IllegalStateException: No instances available for user-service
  10. ABC技术落地_成功带动lot物联网行业、金融科技行业、智能人才教育。