c/clang:symbol dump demo
This commit is contained in:
121
c/clang/_demo/symboldump/symboldump.go
Normal file
121
c/clang/_demo/symboldump/symboldump.go
Normal 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)
|
||||
}
|
||||
}
|
||||
40
c/clang/_demo/symboldump/test.h
Normal file
40
c/clang/_demo/symboldump/test.h
Normal 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
|
||||
@@ -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"
|
||||
|
||||
1196
c/clang/clang.go
1196
c/clang/clang.go
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user