首页 > 解决方案 > TypedefDecl AST 访问者删除父结构引用

问题描述

我一直在努力从旧版本的 Clang 中移植一些代码。我们有 Clang 转换,它遍历 AST,执行一些基本的功能修改并删除等效表示以进行进一步编译。我们在正确复制 TypedefDecl 节点和维护其父引用时遇到问题。考虑以下:

typedef struct {
    char * buf;
    size_t pos, len, size, flags;
} BufferBase;
typedef BufferBase *Buffer;

使用标准的 Clang 方法,我们可以看到以下 AST 片段的解析:

RecordDecl 0x564021ec3828 <foo.c:3:9, line:6:1> line:3:9 struct definition
| |-FieldDecl 0x564021ec38e8 <line:4:5, col:12> col:12 buf 'char *'
| |-FieldDecl 0x564021ec3948 <line:5:5, col:12> col:12 pos
'size_t':'unsigned long'
| |-FieldDecl 0x564021ec39a8 <col:5, col:17> col:17 len 'size_t':'unsigned long'
| |-FieldDecl 0x564021ec3a08 <col:5, col:22> col:22 size
'size_t':'unsigned long'
| `-FieldDecl 0x564021ec3a68 <col:5, col:28> col:28 flags
'size_t':'unsigned long'
|-TypedefDecl 0x564021ec3b18 <line:3:1, line:6:3> col:3 referenced
BufferBase 'struct BufferBase':'BufferBase'
| `-ElaboratedType 0x564021ec3ac0 'struct BufferBase' sugar
|   `-RecordType 0x564021ec38b0 'BufferBase'
|     `-Record 0x564021ec3828 ''
`-TypedefDecl 0x564021ec3c18 <line:7:1, col:21> col:21 Buffer 'BufferBase *'
  `-PointerType 0x564021ec3be0 'BufferBase *'
    `-TypedefType 0x564021ec3b90 'BufferBase' sugar
      |-Typedef 0x564021ec3b18 'BufferBase'
      `-ElaboratedType 0x564021ec3ac0 'struct BufferBase' sugar
        `-RecordType 0x564021ec38b0 'BufferBase'
          `-Record 0x564021ec3828 ''

在我们的 AST 修改代码中,我们尝试利用现有的 TypedefDecl 创建具有相同属性的新副本。

QualType TransformType(TypeLocBuilder& TLB, TypeLoc Ty) {
      if(SemaRef.Context.hasSameType(Ty.getType(), From)) {
        Ty = SemaRef.Context.getTrivialTypeSourceInfo(To)->getTypeLoc();
      }
      return TreeTransformS::TransformType(TLB, Ty);
}

[..snipped..]
} else if(TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
  DeclContext *NewDC = DC;
  IdentifierInfo *Name = TD->getIdentifier();
  TypeSourceInfo *Ty = TransformType(TD->getTypeSourceInfo());
  // create the AST node
  TypedefDecl *Result = TypedefDecl::Create(SemaRef.Context, NewDC,
TD->getBeginLoc(), TD->getLocation(), Name, Ty);
 Result->dump();
}

但是,如果我们在 Create 之后立即转储 AST,我们会得到一个匿名结构,如下所示:

TypedefDecl 0x55a568c31800 <foo.c:16:1, line:19:3> col:3 BufferBase
'struct (anonymous struct at foo.c:16:9)':'struct (anonymous at
foo.c:16:9)'
`-ElaboratedType 0x55a568c317b0 'struct (anonymous struct at foo.c:16:9)' sugar
  `-RecordType 0x55a568c314f0 'struct (anonymous at foo.c:16:9)'
    `-Record 0x55a568c31468 ''

我们缺少什么来保持结构定义和 typedef 之间的联系?该Create函数似乎删除了对父结构定义的引用,因此生成的 AST 包含一个匿名结构和一个损坏的 typedef。

标签: clang

解决方案


推荐阅读