c/clang:symbol dump demo

This commit is contained in:
luoliwoshang
2024-07-24 14:22:41 +08:00
parent 1eb9775f34
commit 0f8b202531
4 changed files with 1408 additions and 21 deletions

View File

@@ -0,0 +1,121 @@
package main
import (
"fmt"
"os"
"unsafe"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/clang"
)
type Context struct {
namespaceName string
className string
}
func newContext() *Context {
return &Context{}
}
func (c *Context) setNamespaceName(name string) {
c.namespaceName = name
}
func (c *Context) setClassName(name string) {
c.className = name
}
var context = newContext()
func print_cursor_info(cursor clang.Cursor) {
cursorStr := cursor.String()
symbol := cursor.Mangling()
defer symbol.Dispose()
defer cursorStr.Dispose()
if context.namespaceName != "" && context.className != "" {
fmt.Printf("%s:%s", context.namespaceName, context.className)
} else if context.namespaceName != "" {
fmt.Printf("%s", context.namespaceName)
}
c.Printf(c.Str("%s\n"), cursorStr.CStr())
if cursor.Kind == clang.CXXMethod || cursor.Kind == clang.FunctionDecl {
c.Printf(c.Str("symbol:%s\n"), symbol.CStr())
typeStr := cursor.ResultType().String()
defer typeStr.Dispose()
c.Printf(c.Str("Return Type: %s\n"), typeStr.CStr())
c.Printf(c.Str("Parameters(%d): ( "), cursor.NumArguments())
for i := 0; i < int(cursor.NumArguments()); i++ {
argCurSor := cursor.Argument(uint8(i))
argType := argCurSor.Type().String()
argName := argCurSor.String()
c.Printf(c.Str("%s %s"), argType.CStr(), argName.CStr())
if i < int(cursor.NumArguments())-1 {
c.Printf(c.Str(", "))
}
argType.Dispose()
argName.Dispose()
}
c.Printf(c.Str(" )\n"))
println("--------------------------------")
}
}
func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitResult {
if cursor.Kind == clang.Namespace {
nameStr := cursor.String()
context.setNamespaceName(c.GoString(nameStr.CStr()))
clang.VisitChildren(cursor, visit, nil)
context.setNamespaceName("")
} else if cursor.Kind == clang.ClassDecl {
nameStr := cursor.String()
context.setClassName(c.GoString(nameStr.CStr()))
clang.VisitChildren(cursor, visit, nil)
context.setClassName("")
} else if cursor.Kind == clang.CXXMethod || cursor.Kind == clang.FunctionDecl {
print_cursor_info(cursor)
}
return clang.ChildVisit_Continue
}
func parse(filename *c.Char) {
index := clang.CreateIndex(0, 0)
args := make([]*c.Char, 3)
args[0] = c.Str("-x")
args[1] = c.Str("c++")
args[2] = c.Str("-std=c++11")
unit := index.ParseTranslationUnit(
filename,
unsafe.SliceData(args), 3,
nil, 0,
clang.TranslationUnit_None,
)
if unit == nil {
println("Unable to parse translation unit. Quitting.")
c.Exit(1)
}
cursor := unit.Cursor()
clang.VisitChildren(cursor, visit, nil)
unit.Dispose()
index.Dispose()
}
func main() {
if c.Argc != 2 {
fmt.Fprintln(os.Stderr, "Usage: <C++ header file>\n")
return
} else {
sourceFile := *c.Advance(c.Argv, 1)
parse(sourceFile)
}
}

View File

@@ -0,0 +1,40 @@
#ifndef ZOO_H
#define ZOO_H
namespace forest
{
class Bear
{
public:
void roar();
int eat(int berries, int fish);
void sleep(const char *where);
};
} // namespace forest
namespace ocean
{
class Shark
{
public:
void roar();
int eat(int fish, int seals);
void sleep(const char *where);
};
} // namespace ocean
class Eagle
{
public:
void roar();
int eat(int mice, int fish);
void sleep(const char *where);
};
void zookeeper(int money);
#endif // ZOO_H

View File

@@ -1,29 +1,67 @@
#include <stdio.h>
#include <clang-c/Index.h>
#include <stdio.h>
typedef enum CXChildVisitResult(* wrap_CXCursorVisitor) (CXCursor *cursor, CXCursor *parent, CXClientData client_data);
typedef enum CXChildVisitResult (*wrap_CXCursorVisitor)(CXCursor *cursor, CXCursor *parent, CXClientData client_data);
typedef struct {
CXClientData data;
typedef struct
{
CXClientData data;
wrap_CXCursorVisitor visitor;
} wrap_data;
CXChildVisitResult wrap_visitor(CXCursor cursor, CXCursor parent, CXClientData data) {
wrap_data *d = (wrap_data*)(data);
return d->visitor(&cursor,&parent,d->data);
CXChildVisitResult wrap_visitor(CXCursor cursor, CXCursor parent, CXClientData data)
{
wrap_data *d = (wrap_data *)(data);
return d->visitor(&cursor, &parent, d->data);
}
extern "C" {
extern "C"
{
CXString wrap_clang_getCursorSpelling(CXCursor *cur) {
return clang_getCursorSpelling(*cur);
}
CXString wrap_clang_getCursorSpelling(CXCursor *cur)
{
return clang_getCursorSpelling(*cur);
}
unsigned wrap_clang_visitChildren(CXCursor *parent,
wrap_CXCursorVisitor visitor,
CXClientData client_data) {
wrap_data data = {client_data,visitor};
return clang_visitChildren(*parent,wrap_visitor,CXClientData(&data));
}
CXString wrap_clang_Cursor_getMangling(CXCursor *cur)
{
return clang_Cursor_getMangling(*cur);
}
int wrap_clang_Cursor_getNumArguments(CXCursor *cur)
{
return clang_Cursor_getNumArguments(*cur);
}
void wrap_clang_Cursor_getArgument(CXCursor *C, unsigned i, CXCursor *argCur)
{
*argCur = clang_Cursor_getArgument(*C, i);
}
void wrap_clang_getTranslationUnitCursor(CXTranslationUnit uint, CXCursor *cur)
{
*cur = clang_getTranslationUnitCursor(uint);
}
void wrap_clang_getCursorType(CXCursor *cur, CXType *typ)
{
*typ = clang_getCursorType(*cur);
}
void wrap_clang_getCursorResultType(CXCursor *cur, CXType *typ)
{
*typ = clang_getCursorResultType(*cur);
}
CXString wrap_clang_getTypeSpelling(CXType *typ)
{
return clang_getTypeSpelling(*typ);
}
unsigned wrap_clang_visitChildren(CXCursor *parent, wrap_CXCursorVisitor visitor, CXClientData client_data)
{
wrap_data data = {client_data, visitor};
return clang_visitChildren(*parent, wrap_visitor, CXClientData(&data));
}
} // extern "C"

File diff suppressed because it is too large Load Diff