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

type Struct (unnamed at /usr/local/...) #66

Closed
tsingbx opened this issue Dec 20, 2024 · 3 comments · Fixed by #131
Closed

type Struct (unnamed at /usr/local/...) #66

tsingbx opened this issue Dec 20, 2024 · 3 comments · Fixed by #131
Assignees
Labels
bug Something isn't working

Comments

@tsingbx
Copy link
Contributor

tsingbx commented Dec 20, 2024

llcppgtest msgpack-c

type Union (unnamed at /usr/local/Cellar/msgpack/6.0.2/include/msgpack/object.h:75:9) struct {
	Array ObjectArray
}

llcppgtest mpfr

type Struct (unnamed at /usr/local/Cellar/mpfr/4.2.1/include/mpfr.h:232:9) struct 
@luoliwoshang luoliwoshang added the bug Something isn't working label Dec 20, 2024
@luoliwoshang luoliwoshang self-assigned this Dec 24, 2024
@luoliwoshang
Copy link
Contributor

luoliwoshang commented Dec 25, 2024

相同的问题出现在

typedef struct {
	/**
	 * \brief       Filter ID
	 *
	 * Use constants whose name begin with 'LZMA_FILTER_' to specify
	 * different filters. In an array of lzma_filter structures, use
	 * LZMA_VLI_UNKNOWN to indicate end of filters.
	 *
	 * \note        This is not an enum, because on some systems enums
	 *              cannot be 64-bit.
	 */
	lzma_vli id;

	/**
	 * \brief       Pointer to filter-specific options structure
	 *
	 * If the filter doesn't need options, set this to NULL. If id is
	 * set to LZMA_VLI_UNKNOWN, options is ignored, and thus
	 * doesn't need be initialized.
	 */
	void *options;

} lzma_filter;

这里的Typedef额外的匿名类型没有正确的被移除

type Struct (unnamed at /opt/homebrew/Cellar/xz/5.6.3/include/lzma/filter.h:41:9) struct {
	Id      c.Int
	Options unsafe.Pointer
}
type LzmaFilter struct {
	Id      c.Int
	Options unsafe.Pointer
}

但是对于typedef一个匿名类型的情况,在llcppsigfetch的测试用例中是能正确表达的,没有出现unnamed的情况

`typedef struct {
int x;
} MyStruct`,

TestTypeDefDecl Case 7:
{
"temp.h": {
"_Type": "File",
"decls": [{
"_Type": "TypeDecl",
"Loc": {
"_Type": "Location",
"File": "temp.h"
},
"Doc": null,
"Parent": null,
"Name": {
"_Type": "Ident",
"Name": "MyStruct"
},
"Type": {
"_Type": "RecordType",
"Tag": 0,
"Fields": {
"_Type": "FieldList",
"List": [{
"_Type": "Field",
"Type": {
"_Type": "BuiltinType",
"Kind": 6,
"Flags": 0
},
"Doc": null,
"Comment": null,
"IsStatic": false,
"Access": 1,
"Names": [{
"_Type": "Ident",
"Name": "x"
}]
}]
},
"Methods": []
}
}],
"includes": [],
"macros": []
}
}

使用出现问题的源代码,可以复现

llcppsigfetch -temp=true --extract "          typedef struct {
                        lzma_vli id;
                        void *options;
                } lzma_filter;"

got

[
    {
        "incPath": "",
        "path": "temp.h",
        "doc": {
            "_Type": "File",
            "decls": [
                {
                    "_Type": "TypeDecl",
                    "Loc": {
                        "_Type": "Location",
                        "File": "temp.h"
                    },
                    "Doc": null,
                    "Parent": null,
                    "Name": {
                        "_Type": "Ident",
                        "Name": "(unnamed struct at temp.h:1:19)"
                    },
                    "Type": {
                        "_Type": "RecordType",
                        "Tag": 0,
                        "Fields": {
                            "_Type": "FieldList",
                            "List": [
                                {
                                    "_Type": "Field",
                                    "Type": {
                                        "_Type": "BuiltinType",
                                        "Kind": 6,
                                        "Flags": 0
                                    },
                                    "Doc": null,
                                    "Comment": null,
                                    "IsStatic": false,
                                    "Access": 1,
                                    "Names": [
                                        {
                                            "_Type": "Ident",
                                            "Name": "id"
                                        }
                                    ]
                                },
                                {
                                    "_Type": "Field",
                                    "Type": {
                                        "_Type": "PointerType",
                                        "X": {
                                            "_Type": "BuiltinType",
                                            "Kind": 0,
                                            "Flags": 0
                                        }
                                    },
                                    "Doc": null,
                                    "Comment": null,
                                    "IsStatic": false,
                                    "Access": 1,
                                    "Names": [
                                        {
                                            "_Type": "Ident",
                                            "Name": "options"
                                        }
                                    ]
                                }
                            ]
                        },
                        "Methods": []
                    }
                },
                {
                    "_Type": "TypedefDecl",
                    "Loc": {
                        "_Type": "Location",
                        "File": "temp.h"
                    },
                    "Doc": null,
                    "Parent": null,
                    "Name": {
                        "_Type": "Ident",
                        "Name": "lzma_filter"
                    },
                    "Type": {
                        "_Type": "RecordType",
                        "Tag": 0,
                        "Fields": {
                            "_Type": "FieldList",
                            "List": [
                                {
                                    "_Type": "Field",
                                    "Type": {
                                        "_Type": "BuiltinType",
                                        "Kind": 6,
                                        "Flags": 0
                                    },
                                    "Doc": null,
                                    "Comment": null,
                                    "IsStatic": false,
                                    "Access": 1,
                                    "Names": [
                                        {
                                            "_Type": "Ident",
                                            "Name": "id"
                                        }
                                    ]
                                },
                                {
                                    "_Type": "Field",
                                    "Type": {
                                        "_Type": "PointerType",
                                        "X": {
                                            "_Type": "BuiltinType",
                                            "Kind": 0,
                                            "Flags": 0
                                        }
                                    },
                                    "Doc": null,
                                    "Comment": null,
                                    "IsStatic": false,
                                    "Access": 1,
                                    "Names": [
                                        {
                                            "_Type": "Ident",
                                            "Name": "options"
                                        }
                                    ]
                                }
                            ]
                        },
                        "Methods": []
                    }
                }
            ],
            "includes": [],
            "macros": []
        },
        "isSys": false
    }
]

@luoliwoshang
Copy link
Contributor

在这个用例的上下文中 lzma_vli 是还未定义的,typedef 一个匿名结构体,如果成员中某个类型是还没定义的,对应的Typedecl的Name就会是 (unnamed struct at temp.h:1:19),只要每个类型成员完成了定义,那就不会出现这个预期之外的匿名类型了。

llcppsigfetch -temp=true --extract " typedef long lzma_vli;         typedef struct {
                        lzma_vli id;
                        void *options;
                } lzma_filter;"

got

[
    {
        "incPath": "",
        "path": "temp.h",
        "doc": {
            "_Type": "File",
            "decls": [
                {
                    "_Type": "TypedefDecl",
                    "Loc": {
                        "_Type": "Location",
                        "File": "temp.h"
                    },
                    "Doc": null,
                    "Parent": null,
                    "Name": {
                        "_Type": "Ident",
                        "Name": "lzma_vli"
                    },
                    "Type": {
                        "_Type": "BuiltinType",
                        "Kind": 6,
                        "Flags": 4
                    }
                },
                {
                    "_Type": "TypeDecl",
                    "Loc": {
                        "_Type": "Location",
                        "File": "temp.h"
                    },
                    "Doc": null,
                    "Parent": null,
                    "Name": {
                        "_Type": "Ident",
                        "Name": "lzma_filter"
                    },
                    "Type": {
                        "_Type": "RecordType",
                        "Tag": 0,
                        "Fields": {
                            "_Type": "FieldList",
                            "List": [
                                {
                                    "_Type": "Field",
                                    "Type": {
                                        "_Type": "Ident",
                                        "Name": "lzma_vli"
                                    },
                                    "Doc": null,
                                    "Comment": null,
                                    "IsStatic": false,
                                    "Access": 1,
                                    "Names": [
                                        {
                                            "_Type": "Ident",
                                            "Name": "id"
                                        }
                                    ]
                                },
                                {
                                    "_Type": "Field",
                                    "Type": {
                                        "_Type": "PointerType",
                                        "X": {
                                            "_Type": "BuiltinType",
                                            "Kind": 0,
                                            "Flags": 0
                                        }
                                    },
                                    "Doc": null,
                                    "Comment": null,
                                    "IsStatic": false,
                                    "Access": 1,
                                    "Names": [
                                        {
                                            "_Type": "Ident",
                                            "Name": "options"
                                        }
                                    ]
                                }
                            ]
                        },
                        "Methods": []
                    }
                }
            ],
            "includes": [],
            "macros": []
        },
        "isSys": false
    }
]

@luoliwoshang
Copy link
Contributor

luoliwoshang commented Dec 25, 2024

llcppcfg 生成的默认头文件顺序导致了,在提取ast信息时,先提取了lzma/filter.h,最后再处理 lzma.h,这就导致了在处理 lzma/filterlzma_vli 还没被定义

{
	"name": "liblzma",
	"cflags": "$(pkg-config --cflags liblzma)",
	"libs": "$(pkg-config --libs liblzma)",
	"include": [
		"lzma/lzma12.h",
		"lzma/version.h",
		"lzma/base.h",
		"lzma/container.h",
		"lzma/delta.h",
		"lzma/vli.h",
		"lzma/check.h",
		"lzma/filter.h",
		"lzma/index.h",
		"lzma/index_hash.h",
		"lzma/bcj.h",
		"lzma/block.h",
		"lzma/hardware.h",
		"lzma/stream_flags.h",
		"lzma.h"
	],
	"deps": null,
	"trimPrefixes": [],
	"cplusplus": false
}

在原始头文件中也提到,lzma/xxxx.h 是实现层面,应该优先包含lzma.h 完成类型的初始化
lzma/filter.h

/* SPDX-License-Identifier: 0BSD */

/**
 * \file        lzma/filter.h
 * \brief       Common filter related types and functions
 * \note        Never include this file directly. Use <lzma.h> instead.
 */

顺序修改为如下,即可正常转换

{
	"name": "liblzma",
	"cflags": "$(pkg-config --cflags liblzma)",
	"libs": "$(pkg-config --libs liblzma)",
	"include": [
		"lzma.h",
		"lzma/index_hash.h",
		"lzma/base.h",
		"lzma/bcj.h",
		"lzma/block.h",
		"lzma/container.h",
		"lzma/delta.h",
		"lzma/index.h"
		"lzma/check.h",
		"lzma/filter.h",
		"lzma/hardware.h",
		"lzma/lzma12.h",
		"lzma/version.h",
		"lzma/vli.h",
		"lzma/stream_flags.h"
	],
	"deps": null,
	"trimPrefixes": [],
	"cplusplus": false
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants