diff --git a/c/clang/_demo/castdump/astdump.go b/c/clang/_demo/castdump/astdump.go index 91f3ee5f..401c8a9b 100644 --- a/c/clang/_demo/castdump/astdump.go +++ b/c/clang/_demo/castdump/astdump.go @@ -16,21 +16,14 @@ func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitRe func printAST(cursor clang.Cursor, depth c.Uint) { cursorKind := cursor.Kind.String() - println("cursor.Kind.String done") - c.Printf(c.Str("cursorKind = %s\n"), cursorKind.CStr()) - cursorSpelling := clang.GetCursorSpelling(cursor) // cursor.String() - println("clang.GetCursorSpelling done") + cursorSpelling := cursor.String() for i := c.Uint(0); i < depth; i++ { - println("c.Fputs start") c.Fputs(c.Str(" "), c.Stdout) - println("c.Fputs end") } - println("c.Printf start") c.Printf(c.Str("%s: %s\n"), cursorKind.CStr(), cursorSpelling.CStr()) - println("c.Printf end") cursorKind.Dispose() cursorSpelling.Dispose() @@ -46,7 +39,6 @@ func main() { sourceFile := *c.Advance(c.Argv, 1) index := clang.CreateIndex(0, 0) - println("clang.CreateIndex done") unit := index.ParseTranslationUnit( sourceFile, @@ -54,7 +46,6 @@ func main() { nil, 0, clang.TranslationUnit_None, ) - println("index.ParseTranslationUnit done") if unit == nil { println("Unable to parse translation unit. Quitting.") @@ -62,7 +53,6 @@ func main() { } cursor := unit.Cursor() - println("unit.Cursor done") printAST(cursor, 0) diff --git a/c/clang/_wrap/cursor.cpp b/c/clang/_wrap/cursor.cpp new file mode 100644 index 00000000..f757fe3d --- /dev/null +++ b/c/clang/_wrap/cursor.cpp @@ -0,0 +1,29 @@ +#include +#include + +typedef enum CXChildVisitResult(* wrap_CXCursorVisitor) (CXCursor *cursor, CXCursor *parent, CXClientData client_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); +} + +extern "C" { + +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)); +} + +} // extern "C" diff --git a/c/clang/clang.go b/c/clang/clang.go index f0a3ccd3..fe905e92 100644 --- a/c/clang/clang.go +++ b/c/clang/clang.go @@ -17,12 +17,13 @@ package clang import ( - _ "unsafe" + "unsafe" "github.com/goplus/llgo/c" ) const ( + LLGoFiles = "$(llvm-config --cflags): _wrap/cursor.cpp" LLGoPackage = "link: -L$(llvm-config --libdir) -lclang; -lclang" ) @@ -204,13 +205,14 @@ type Cursor struct { /** * Retrieve a name for the entity referenced by this cursor. */ -// llgo:link Cursor.String C.clang_getCursorSpelling -func (Cursor) String() (ret String) { +// llgo:link (*Cursor).wrapString C.wrap_clang_getCursorSpelling +func (*Cursor) wrapString() (ret String) { return } -//go:linkname GetCursorSpelling C.clang_getCursorSpelling -func GetCursorSpelling(cursor Cursor) String +func (c Cursor) String() (ret String) { + return c.wrapString() +} /** * Describes how the traversal of the children of a particular @@ -260,10 +262,31 @@ const ( * \returns a non-zero value if the traversal was terminated * prematurely by the visitor returning \c CXChildVisit_Break. */ -//go:linkname VisitChildren C.clang_visitChildren -func VisitChildren( - cusor Cursor, - visitor func(cursor, parent Cursor, clientData ClientData) ChildVisitResult, +//go:linkname wrapVisitChildren C.wrap_clang_visitChildren +func wrapVisitChildren( + cusor *Cursor, + fn wrapVisitor, clientData ClientData) c.Uint { return 0 } + +//llgo:type C +type wrapVisitor func(cursor, parent *Cursor, clientData ClientData) ChildVisitResult + +type wrapData struct { + data ClientData + fn Visitor +} + +func VisitChildren( + root Cursor, + fn Visitor, + clientData ClientData) c.Uint { + return wrapVisitChildren(&root, func(cursor, parent *Cursor, data ClientData) ChildVisitResult { + p := (*wrapData)(data) + return p.fn(*cursor, *parent, p.data) + }, unsafe.Pointer(&wrapData{clientData, fn})) +} + +//llgo:type C +type Visitor func(cursor, parent Cursor, clientData ClientData) ChildVisitResult