Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

llcppsigfetch:fix macro expansion underlying type #858

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

luoliwoshang
Copy link
Contributor

@luoliwoshang luoliwoshang commented Nov 8, 2024

Fix luoliwoshang#78

Desc

一个宏定义在另外一个头文件中,当头文件其中一个类型引用后,可以获得其Underlying类型,但是为了判断其实际的匿名性质,访问其定义节点,对其Token序列化,返回Token序列为空,导致无法通过Token序列获取其实际的匿名性质。

最小复现

func TestMacroExpansionOtherFileTokenEmpty() {

fsid.h

#define __FSID_T_TYPE struct {  int __val[2]; }

typedef.h

#include "fsid.h"
typedef __FSID_T_TYPE NewType;

对于这个类型声明节点,其range 仍然为原始宏名称的开始和结束的位置.
luoliwoshang/CTest@d564aa5

underlying type: struct NewType
type declaration: NewType
type declaration kind: StructDecl
range start: 2:9, range end: 2:22

Resolve(1) Fail

https://discourse.llvm.org/t/querying-information-about-preprocessing-directives-in-libclang/19007/3
这里提到可以通过 clang_getCursorReferenced 来 将从宏实例化游标映射宏定义。

/** For a cursor that is a reference, retrieve a cursor representing the
 * entity that it references.
 *
 * Reference cursors refer to other entities in the AST. For example, an
 * Objective-C superclass reference cursor refers to an Objective-C class.
 * This function produces the cursor for the Objective-C class from the
 * cursor for the superclass reference. If the input cursor is a declaration or
 * definition, it returns that declaration or definition unchanged.
 * Otherwise, returns the NULL cursor.
 */
CINDEX_LINKAGE CXCursor clang_getCursorReferenced(CXCursor);

对于这个实际的StructDecl Cursor定义,实际上就是从宏定义来的,那么尝试去获得宏对应的StructDeclclang_getCursorReferenced 是否为一个宏定义,发现获取的仅仅是一个同样的StructDecl。所以该方案失败。
同样的 clang_getCursorDefinition的并不奏效

Resolve(2) (Not Perfect) **Current r

对于整个AST树节点遍历发现,在定义前,会存在CXCursor_MacroExpansion 宏展开节点,对于一个宏展开节点,他的源文件范围与Typedef中引用的宏对应的结构体声明的范围一致。
luoliwoshang/CTest@5dd9fb9

macro expansion: __FSID_T_TYPE
macro expansion range start: 2:9, range end: 2:22
underlying type: struct NewType
type declaration: NewType
type declaration kind: StructDecl
Cursor at range start:
  Kind: StructDecl
  Spelling: NewType
range start: 2:9, range end: 2:22

获取宏展开的节点信息并进行缓存,对于序列化为空的一个类型引用,则可以认为是一个宏展开,那么就可以通过比对当前Token为空的声明节点的偏移量和宏展开节点的偏移量,如果一致,那么就可以认为是同一个节点,则可以通过宏的序列获得实际的声明Token序列。

即流程为收集宏展开节点与宏定义映射->Token序列为空的类型声明->检查是否为一个宏展开->通过映射关系找到实际的宏->获得其Token序列继续检查其实际的匿名性质

当前这个方案能解决目前这个情况

#define __FSID_T_TYPE struct {  int __val[2]; }

typedef.h

#include "fsid.h"
typedef __FSID_T_TYPE NewType;

但是如果存在一个用例,这个宏再嵌套一层,就也不能正确识别了,这块可能会再结合clang的预处理来完善这个修复。

Copy link

codecov bot commented Nov 8, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 97.62%. Comparing base (c0ec5e5) to head (561c932).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #858   +/-   ##
=======================================
  Coverage   97.62%   97.62%           
=======================================
  Files          20       20           
  Lines        5971     5971           
=======================================
  Hits         5829     5829           
  Misses        120      120           
  Partials       22       22           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@luoliwoshang luoliwoshang marked this pull request as draft November 9, 2024 02:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

llcppg:unexpected llcppsigfetch index out of range in ubuntu
1 participant