c/clang: wrap cursor

This commit is contained in:
visualfc
2024-07-15 13:14:47 +08:00
parent 607e3bbc11
commit 70b017fb72
3 changed files with 62 additions and 20 deletions

View File

@@ -16,21 +16,14 @@ func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitRe
func printAST(cursor clang.Cursor, depth c.Uint) { func printAST(cursor clang.Cursor, depth c.Uint) {
cursorKind := cursor.Kind.String() cursorKind := cursor.Kind.String()
println("cursor.Kind.String done")
c.Printf(c.Str("cursorKind = %s\n"), cursorKind.CStr())
cursorSpelling := clang.GetCursorSpelling(cursor) // cursor.String() cursorSpelling := cursor.String()
println("clang.GetCursorSpelling done")
for i := c.Uint(0); i < depth; i++ { for i := c.Uint(0); i < depth; i++ {
println("c.Fputs start")
c.Fputs(c.Str(" "), c.Stdout) 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()) c.Printf(c.Str("%s: %s\n"), cursorKind.CStr(), cursorSpelling.CStr())
println("c.Printf end")
cursorKind.Dispose() cursorKind.Dispose()
cursorSpelling.Dispose() cursorSpelling.Dispose()
@@ -46,7 +39,6 @@ func main() {
sourceFile := *c.Advance(c.Argv, 1) sourceFile := *c.Advance(c.Argv, 1)
index := clang.CreateIndex(0, 0) index := clang.CreateIndex(0, 0)
println("clang.CreateIndex done")
unit := index.ParseTranslationUnit( unit := index.ParseTranslationUnit(
sourceFile, sourceFile,
@@ -54,7 +46,6 @@ func main() {
nil, 0, nil, 0,
clang.TranslationUnit_None, clang.TranslationUnit_None,
) )
println("index.ParseTranslationUnit done")
if unit == nil { if unit == nil {
println("Unable to parse translation unit. Quitting.") println("Unable to parse translation unit. Quitting.")
@@ -62,7 +53,6 @@ func main() {
} }
cursor := unit.Cursor() cursor := unit.Cursor()
println("unit.Cursor done")
printAST(cursor, 0) printAST(cursor, 0)

29
c/clang/_wrap/cursor.cpp Normal file
View File

@@ -0,0 +1,29 @@
#include <stdio.h>
#include <clang-c/Index.h>
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"

View File

@@ -17,12 +17,13 @@
package clang package clang
import ( import (
_ "unsafe" "unsafe"
"github.com/goplus/llgo/c" "github.com/goplus/llgo/c"
) )
const ( const (
LLGoFiles = "$(llvm-config --cflags): _wrap/cursor.cpp"
LLGoPackage = "link: -L$(llvm-config --libdir) -lclang; -lclang" 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. * Retrieve a name for the entity referenced by this cursor.
*/ */
// llgo:link Cursor.String C.clang_getCursorSpelling // llgo:link (*Cursor).wrapString C.wrap_clang_getCursorSpelling
func (Cursor) String() (ret String) { func (*Cursor) wrapString() (ret String) {
return return
} }
//go:linkname GetCursorSpelling C.clang_getCursorSpelling func (c Cursor) String() (ret String) {
func GetCursorSpelling(cursor Cursor) String return c.wrapString()
}
/** /**
* Describes how the traversal of the children of a particular * 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 * \returns a non-zero value if the traversal was terminated
* prematurely by the visitor returning \c CXChildVisit_Break. * prematurely by the visitor returning \c CXChildVisit_Break.
*/ */
//go:linkname VisitChildren C.clang_visitChildren //go:linkname wrapVisitChildren C.wrap_clang_visitChildren
func VisitChildren( func wrapVisitChildren(
cusor Cursor, cusor *Cursor,
visitor func(cursor, parent Cursor, clientData ClientData) ChildVisitResult, fn wrapVisitor,
clientData ClientData) c.Uint { clientData ClientData) c.Uint {
return 0 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