Skip to content

Commit

Permalink
Merge pull request #126 from luoliwoshang/llcppsymg/samename
Browse files Browse the repository at this point in the history
llcppg:allow same func decl & check methodset avoid duplicate
  • Loading branch information
tsingbx authored Jan 3, 2025
2 parents acc2920 + 81acd8d commit 3a66c49
Show file tree
Hide file tree
Showing 14 changed files with 359 additions and 25 deletions.
3 changes: 2 additions & 1 deletion _llcppgtest/gpgerror/llcppg.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"cflags": "$(pkg-config --cflags gpg-error)",
"libs": "$(pkg-config --libs gpg-error)",
"include": [
"gpgrt.h"
"gpgrt.h",
"gpg-error.h"
],
"trimPrefixes": ["gpg_err_","gpgrt_set_","gpg_","GPG_ERR_"],
"cplusplus": false
Expand Down
5 changes: 5 additions & 0 deletions _xtool/llcppsymg/_cmptest/symg_test/gpgerror/gpg-error.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include <stddef.h>
typedef unsigned int gpg_error_t;
const char *gpg_strerror (gpg_error_t err);
int gpg_strerror_r (gpg_error_t err, char *buf, size_t buflen);
const char *gpg_strsource (gpg_error_t err);
5 changes: 5 additions & 0 deletions _xtool/llcppsymg/_cmptest/symg_test/gpgerror/gpgrt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include <stddef.h>
typedef unsigned int gpg_error_t;
const char *gpg_strerror (gpg_error_t err);
int gpg_strerror_r (gpg_error_t err, char *buf, size_t buflen);
const char *gpg_strsource (gpg_error_t err);
9 changes: 9 additions & 0 deletions _xtool/llcppsymg/_cmptest/symg_test/gpgerror/llcppg.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "gpgerror",
"include": [
"gpgrt.h",
"gpg-error.h"
],
"trimPrefixes": ["gpg_err_","gpg_","GPG_ERR_"],
"cplusplus": false
}
14 changes: 14 additions & 0 deletions _xtool/llcppsymg/_cmptest/symg_test/llgo.expect
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,20 @@
"c++": "isl_pw_qpolynomial_get_ctx(isl_pw_qpolynomial *)",
"go": "(*IslPwQpolynomial).IslPwQpolynomialGetCtx"
}]
=== Test Case: gpgerror ===
[{
"mangle": "gpg_strsource",
"c++": "gpg_strsource(gpg_error_t)",
"go": "ErrorT.Strsource"
}, {
"mangle": "gpg_strerror_r",
"c++": "gpg_strerror_r(gpg_error_t, char *, size_t)",
"go": "ErrorT.StrerrorR"
}, {
"mangle": "gpg_strerror",
"c++": "gpg_strerror(gpg_error_t)",
"go": "ErrorT.Strerror"
}]

#stderr

Expand Down
9 changes: 9 additions & 0 deletions _xtool/llcppsymg/_cmptest/symg_test/symg.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ func TestParseHeaderFile() {
"isl_pw_qpolynomial_get_ctx",
},
},
{
name: "gpgerror",
path: "./gpgerror",
dylibSymbols: []string{
"gpg_strsource",
"gpg_strerror_r",
"gpg_strerror",
},
},
}

for _, tc := range testCases {
Expand Down
8 changes: 8 additions & 0 deletions _xtool/llcppsymg/parse/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,14 @@ func (p *SymbolProcessor) collectFuncInfo(cursor clang.Cursor) {
if runtime.GOOS == "darwin" {
symbolName = strings.TrimPrefix(symbolName, "_")
}

// In C, multiple declarations of the same function are allowed.
// Functions with identical signatures will have the same mangled name.
// We treat them as the same function rather than overloads, so we only
// process the first occurrence and skip subsequent declarations.
if _, exists := p.SymbolMap[symbolName]; exists {
return
}
p.SymbolMap[symbolName] = &SymbolInfo{
GoName: p.genGoName(cursor),
ProtoName: p.genProtoName(cursor),
Expand Down
7 changes: 7 additions & 0 deletions cmd/gogensig/convert/_testdata/gpgerror/conf/llcppg.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "gpgerror",
"libs": "$(pkg-config --libs gpg-error)",
"include": ["gpg-error.h","gpgrt.h"],
"trimPrefixes": ["gpg_err_","gpgrt_set_","gpg_","GPG_ERR_"],
"cplusplus":false
}
42 changes: 42 additions & 0 deletions cmd/gogensig/convert/_testdata/gpgerror/conf/llcppg.symb.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
[
{
"mangle": "gpg_strerror",
"c++": "gpg_strerror",
"go": "ErrorT.Strerror"
},
{
"mangle": "gpg_strerror_r",
"c++": "gpg_strerror_r",
"go": "ErrorT.StrerrorR"
},
{
"mangle": "gpg_strsource",
"c++": "gpg_strsource",
"go": "ErrorT.Strsource"
},
{
"mangle":"gpgrt_lock_init",
"c++":"gpgrt_lock_init",
"go":"(*GpgrtLockT).LockInit"
},
{
"mangle":"gpgrt_lock_lock",
"c++":"gpgrt_lock_lock",
"go":"(*GpgrtLockT).LockLock"
},
{
"mangle":"gpgrt_lock_trylock",
"c++":"gpgrt_lock_trylock",
"go":"(*GpgrtLockT).LockTrylock"
},
{
"mangle":"gpgrt_lock_unlock",
"c++":"gpgrt_lock_unlock",
"go":"(*GpgrtLockT).LockUnlock"
},
{
"mangle":"gpgrt_lock_destroy",
"c++":"gpgrt_lock_destroy",
"go":"(*GpgrtLockT).LockDestroy"
}
]
72 changes: 72 additions & 0 deletions cmd/gogensig/convert/_testdata/gpgerror/gogensig.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
===== gpg-error.go =====
package gpgerror

import (
"github.com/goplus/llgo/c"
_ "unsafe"
)

type ErrorT c.Uint
// llgo:link ErrorT.Strerror C.gpg_strerror
func (recv_ ErrorT) Strerror() *int8 {
return nil
}
// llgo:link ErrorT.StrerrorR C.gpg_strerror_r
func (recv_ ErrorT) StrerrorR(buf *int8, buflen uintptr) c.Int {
return 0
}
// llgo:link ErrorT.Strsource C.gpg_strsource
func (recv_ ErrorT) Strsource() *int8 {
return nil
}

type CodeT c.Int

const (
CodeTNOERROR CodeT = 0
CodeTGENERAL CodeT = 1
CodeTUNKNOWNPACKET CodeT = 2
CodeTCODEDIM CodeT = 65536
)

type GpgrtLockT struct {
X_Vers c.Long
U struct {
X_Priv [64]int8
}
}
// llgo:link (*GpgrtLockT).LockInit C.gpgrt_lock_init
func (recv_ *GpgrtLockT) LockInit() CodeT {
return 0
}
// llgo:link (*GpgrtLockT).LockLock C.gpgrt_lock_lock
func (recv_ *GpgrtLockT) LockLock() CodeT {
return 0
}
// llgo:link (*GpgrtLockT).LockTrylock C.gpgrt_lock_trylock
func (recv_ *GpgrtLockT) LockTrylock() CodeT {
return 0
}
// llgo:link (*GpgrtLockT).LockUnlock C.gpgrt_lock_unlock
func (recv_ *GpgrtLockT) LockUnlock() CodeT {
return 0
}
// llgo:link (*GpgrtLockT).LockDestroy C.gpgrt_lock_destroy
func (recv_ *GpgrtLockT) LockDestroy() CodeT {
return 0
}

===== gpgerror_autogen_link.go =====
package gpgerror

const LLGoPackage string = "link: $(pkg-config --libs gpg-error);"

===== gpgrt.go =====
package gpgerror

import _ "unsafe"

===== llcppg.pub =====
gpg_err_code_t CodeT
gpg_error_t ErrorT
gpgrt_lock_t GpgrtLockT
57 changes: 57 additions & 0 deletions cmd/gogensig/convert/_testdata/gpgerror/hfile/gpg-error.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#include <stddef.h>
/* The error value type gpg_error_t. */

/* We would really like to use bit-fields in a struct, but using
* structs as return values can cause binary compatibility issues, in
* particular if you want to do it efficiently (also see
* -freg-struct-return option to GCC). */
typedef unsigned int gpg_error_t;
/* String functions. */

/* Return a pointer to a string containing a description of the error
* code in the error value ERR. This function is not thread-safe. */
const char *gpg_strerror (gpg_error_t err);

/* Return the error string for ERR in the user-supplied buffer BUF of
* size BUFLEN. This function is, in contrast to gpg_strerror,
* thread-safe if a thread-safe strerror_r() function is provided by
* the system. If the function succeeds, 0 is returned and BUF
* contains the string describing the error. If the buffer was not
* large enough, ERANGE is returned and BUF contains as much of the
* beginning of the error string as fits into the buffer. */
int gpg_strerror_r (gpg_error_t err, char *buf, size_t buflen);

/* Return a pointer to a string containing a description of the error
* source in the error value ERR. */
const char *gpg_strsource (gpg_error_t err);

/* Only use free slots, never change or reorder the existing
* entries. */
typedef enum
{
GPG_ERR_NO_ERROR = 0,
GPG_ERR_GENERAL = 1,
GPG_ERR_UNKNOWN_PACKET = 2,
/* This is one more than the largest allowed entry. */
GPG_ERR_CODE_DIM = 65536
} gpg_err_code_t;

typedef struct
{
long _vers;
union {
volatile char _priv[64];
long _x_align;
long *_xp_align;
} u;
} gpgrt_lock_t;



/* NB: If GPGRT_LOCK_DEFINE is not used, zero out the lock variable
before passing it to gpgrt_lock_init. */
gpg_err_code_t gpgrt_lock_init (gpgrt_lock_t *lockhd);
gpg_err_code_t gpgrt_lock_lock (gpgrt_lock_t *lockhd);
gpg_err_code_t gpgrt_lock_trylock (gpgrt_lock_t *lockhd);
gpg_err_code_t gpgrt_lock_unlock (gpgrt_lock_t *lockhd);
gpg_err_code_t gpgrt_lock_destroy (gpgrt_lock_t *lockhd);
56 changes: 56 additions & 0 deletions cmd/gogensig/convert/_testdata/gpgerror/hfile/gpgrt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include <stddef.h>
/* The error value type gpg_error_t. */

/* We would really like to use bit-fields in a struct, but using
* structs as return values can cause binary compatibility issues, in
* particular if you want to do it efficiently (also see
* -freg-struct-return option to GCC). */
typedef unsigned int gpg_error_t;

/* String functions. */

/* Return a pointer to a string containing a description of the error
* code in the error value ERR. This function is not thread-safe. */
const char *gpg_strerror (gpg_error_t err);

/* Return the error string for ERR in the user-supplied buffer BUF of
* size BUFLEN. This function is, in contrast to gpg_strerror,
* thread-safe if a thread-safe strerror_r() function is provided by
* the system. If the function succeeds, 0 is returned and BUF
* contains the string describing the error. If the buffer was not
* large enough, ERANGE is returned and BUF contains as much of the
* beginning of the error string as fits into the buffer. */
int gpg_strerror_r (gpg_error_t err, char *buf, size_t buflen);

/* Return a pointer to a string containing a description of the error
* source in the error value ERR. */
const char *gpg_strsource (gpg_error_t err);

typedef struct
{
long _vers;
union {
volatile char _priv[64];
long _x_align;
long *_xp_align;
} u;
} gpgrt_lock_t;

/* Only use free slots, never change or reorder the existing
* entries. */
typedef enum
{
GPG_ERR_NO_ERROR = 0,
GPG_ERR_GENERAL = 1,
GPG_ERR_UNKNOWN_PACKET = 2,
/* This is one more than the largest allowed entry. */
GPG_ERR_CODE_DIM = 65536
} gpg_err_code_t;

/* NB: If GPGRT_LOCK_DEFINE is not used, zero out the lock variable
before passing it to gpgrt_lock_init. */
gpg_err_code_t gpgrt_lock_init (gpgrt_lock_t *lockhd);
gpg_err_code_t gpgrt_lock_lock (gpgrt_lock_t *lockhd);
gpg_err_code_t gpgrt_lock_trylock (gpgrt_lock_t *lockhd);
gpg_err_code_t gpgrt_lock_unlock (gpgrt_lock_t *lockhd);
gpg_err_code_t gpgrt_lock_destroy (gpgrt_lock_t *lockhd);
Loading

0 comments on commit 3a66c49

Please sign in to comment.