llcppsigfetch:constructor,destructor,static,override,virtual

This commit is contained in:
luoliwoshang
2024-08-23 19:01:48 +08:00
parent c6336e920f
commit 5e5c975a9c
8 changed files with 599 additions and 33 deletions

View File

@@ -279,6 +279,7 @@ func (ct *Converter) ProcessTypeDefDecl(cursor clang.Cursor) *ast.TypedefDecl {
func (ct *Converter) ProcessFuncDecl(cursor clang.Cursor) *ast.FuncDecl { func (ct *Converter) ProcessFuncDecl(cursor clang.Cursor) *ast.FuncDecl {
name := cursor.String() name := cursor.String()
defer name.Dispose() defer name.Dispose()
// function type will only collect return type // function type will only collect return type
// ProcessType can't get the field names,will collect in follows // ProcessType can't get the field names,will collect in follows
funcType, ok := ct.ProcessType(cursor.Type()).(*ast.FuncType) funcType, ok := ct.ProcessType(cursor.Type()).(*ast.FuncType)
@@ -286,6 +287,7 @@ func (ct *Converter) ProcessFuncDecl(cursor clang.Cursor) *ast.FuncDecl {
fmt.Println("failed to process function type") fmt.Println("failed to process function type")
return nil return nil
} }
params := ct.ProcessFieldList(cursor) params := ct.ProcessFieldList(cursor)
funcType.Params = params funcType.Params = params
fn := &ast.FuncDecl{ fn := &ast.FuncDecl{
@@ -293,6 +295,37 @@ func (ct *Converter) ProcessFuncDecl(cursor clang.Cursor) *ast.FuncDecl {
Name: &ast.Ident{Name: c.GoString(name.CStr())}, Name: &ast.Ident{Name: c.GoString(name.CStr())},
Type: funcType, Type: funcType,
} }
// other info of function&method
if cursor.Kind == clang.CursorDestructor {
fn.IsDestructor = true
}
if cursor.Kind == clang.CursorConstructor {
fn.IsConstructor = true
if cursor.IsExplicit() != 0 {
fn.IsExplicit = true
}
}
if cursor.IsStatic() != 0 {
fn.IsStatic = true
}
// virtual & pure virtual
if cursor.IsVirtual() != 0 || cursor.IsPureVirtual() != 0 {
fn.IsVirtual = true
}
// todo(zzy):inline & const
var numOverridden c.Uint
var overridden *clang.Cursor
cursor.OverriddenCursors(&overridden, &numOverridden)
if numOverridden > 0 {
fn.IsOverride = true
}
return fn return fn
} }
@@ -425,7 +458,7 @@ type visitMethodsContext struct {
func visitMethods(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.ChildVisitResult { func visitMethods(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.ChildVisitResult {
ctx := (*visitMethodsContext)(clientData) ctx := (*visitMethodsContext)(clientData)
if cursor.Kind == clang.CursorCXXMethod { if cursor.Kind == clang.CursorCXXMethod || cursor.Kind == clang.CursorConstructor || cursor.Kind == clang.CursorDestructor {
method := ctx.converter.ProcessFuncDecl(cursor) method := ctx.converter.ProcessFuncDecl(cursor)
if method != nil { if method != nil {
*ctx.methods = append(*ctx.methods, method) *ctx.methods = append(*ctx.methods, method)

View File

@@ -17,6 +17,22 @@ func TestClassDecl() {
int b; int b;
float foo(int a,double b); float foo(int a,double b);
};`, };`,
`class A {
A();
explicit A();
~A();
};`,
`class Base {
Base();
virtual ~Base();
virtual void foo();
};
class Derived : public Base {
Derived();
~Derived() override;
void foo() override;
};
`,
} }
test.RunTest("TestClassDecl", testCases) test.RunTest("TestClassDecl", testCases)
} }

View File

@@ -150,7 +150,357 @@ TestClassDecl Case 2:
"Kind": 8, "Kind": 8,
"Flags": 0 "Flags": 0
} }
},
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": false,
"IsDestructor": false,
"IsVirtual": false,
"IsOverride": false
}]
} }
}],
"includes": [],
"macros": []
}
}
TestClassDecl Case 3:
{
"temp.h": {
"decls": [{
"Loc": {
"File": "temp.h"
},
"Doc": {
"List": []
},
"Parent": null,
"Name": {
"Name": "A"
},
"Type": {
"Tag": 3,
"Fields": {
"List": []
},
"Methods": [{
"Loc": {
"File": "temp.h"
},
"Doc": {
"List": []
},
"Parent": {
"Name": "A"
},
"Name": {
"Name": "A"
},
"Type": {
"Params": {
"List": []
},
"Ret": {
"Kind": 0,
"Flags": 0
}
},
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": true,
"IsDestructor": false,
"IsVirtual": false,
"IsOverride": false
}, {
"Loc": {
"File": "temp.h"
},
"Doc": {
"List": []
},
"Parent": {
"Name": "A"
},
"Name": {
"Name": "A"
},
"Type": {
"Params": {
"List": []
},
"Ret": {
"Kind": 0,
"Flags": 0
}
},
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": true,
"IsConstructor": true,
"IsDestructor": false,
"IsVirtual": false,
"IsOverride": false
}, {
"Loc": {
"File": "temp.h"
},
"Doc": {
"List": []
},
"Parent": {
"Name": "A"
},
"Name": {
"Name": "~A"
},
"Type": {
"Params": {
"List": []
},
"Ret": {
"Kind": 0,
"Flags": 0
}
},
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": false,
"IsDestructor": true,
"IsVirtual": false,
"IsOverride": false
}]
}
}],
"includes": [],
"macros": []
}
}
TestClassDecl Case 4:
{
"temp.h": {
"decls": [{
"Loc": {
"File": "temp.h"
},
"Doc": {
"List": []
},
"Parent": null,
"Name": {
"Name": "Base"
},
"Type": {
"Tag": 3,
"Fields": {
"List": []
},
"Methods": [{
"Loc": {
"File": "temp.h"
},
"Doc": {
"List": []
},
"Parent": {
"Name": "Base"
},
"Name": {
"Name": "Base"
},
"Type": {
"Params": {
"List": []
},
"Ret": {
"Kind": 0,
"Flags": 0
}
},
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": true,
"IsDestructor": false,
"IsVirtual": false,
"IsOverride": false
}, {
"Loc": {
"File": "temp.h"
},
"Doc": {
"List": []
},
"Parent": {
"Name": "Base"
},
"Name": {
"Name": "~Base"
},
"Type": {
"Params": {
"List": []
},
"Ret": {
"Kind": 0,
"Flags": 0
}
},
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": false,
"IsDestructor": true,
"IsVirtual": true,
"IsOverride": false
}, {
"Loc": {
"File": "temp.h"
},
"Doc": {
"List": []
},
"Parent": {
"Name": "Base"
},
"Name": {
"Name": "foo"
},
"Type": {
"Params": {
"List": []
},
"Ret": {
"Kind": 0,
"Flags": 0
}
},
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": false,
"IsDestructor": false,
"IsVirtual": true,
"IsOverride": false
}]
}
}, {
"Loc": {
"File": "temp.h"
},
"Doc": {
"List": []
},
"Parent": null,
"Name": {
"Name": "Derived"
},
"Type": {
"Tag": 3,
"Fields": {
"List": []
},
"Methods": [{
"Loc": {
"File": "temp.h"
},
"Doc": {
"List": []
},
"Parent": {
"Name": "Derived"
},
"Name": {
"Name": "Derived"
},
"Type": {
"Params": {
"List": []
},
"Ret": {
"Kind": 0,
"Flags": 0
}
},
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": true,
"IsDestructor": false,
"IsVirtual": false,
"IsOverride": false
}, {
"Loc": {
"File": "temp.h"
},
"Doc": {
"List": []
},
"Parent": {
"Name": "Derived"
},
"Name": {
"Name": "~Derived"
},
"Type": {
"Params": {
"List": []
},
"Ret": {
"Kind": 0,
"Flags": 0
}
},
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": false,
"IsDestructor": true,
"IsVirtual": true,
"IsOverride": true
}, {
"Loc": {
"File": "temp.h"
},
"Doc": {
"List": []
},
"Parent": {
"Name": "Derived"
},
"Name": {
"Name": "foo"
},
"Type": {
"Params": {
"List": []
},
"Ret": {
"Kind": 0,
"Flags": 0
}
},
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": false,
"IsDestructor": false,
"IsVirtual": true,
"IsOverride": true
}] }]
} }
}], }],

View File

@@ -21,7 +21,15 @@ TestDoc Case 1:
"Kind": 0, "Kind": 0,
"Flags": 0 "Flags": 0
} }
} },
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": false,
"IsDestructor": false,
"IsVirtual": false,
"IsOverride": false
}], }],
"includes": [], "includes": [],
"macros": [] "macros": []
@@ -50,7 +58,15 @@ TestDoc Case 2:
"Kind": 0, "Kind": 0,
"Flags": 0 "Flags": 0
} }
} },
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": false,
"IsDestructor": false,
"IsVirtual": false,
"IsOverride": false
}], }],
"includes": [], "includes": [],
"macros": [] "macros": []
@@ -81,7 +97,15 @@ TestDoc Case 3:
"Kind": 0, "Kind": 0,
"Flags": 0 "Flags": 0
} }
} },
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": false,
"IsDestructor": false,
"IsVirtual": false,
"IsOverride": false
}], }],
"includes": [], "includes": [],
"macros": [] "macros": []
@@ -112,7 +136,15 @@ TestDoc Case 4:
"Kind": 0, "Kind": 0,
"Flags": 0 "Flags": 0
} }
} },
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": false,
"IsDestructor": false,
"IsVirtual": false,
"IsOverride": false
}], }],
"includes": [], "includes": [],
"macros": [] "macros": []
@@ -143,7 +175,15 @@ TestDoc Case 5:
"Kind": 0, "Kind": 0,
"Flags": 0 "Flags": 0
} }
} },
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": false,
"IsDestructor": false,
"IsVirtual": false,
"IsOverride": false
}], }],
"includes": [], "includes": [],
"macros": [] "macros": []
@@ -176,7 +216,15 @@ TestDoc Case 6:
"Kind": 0, "Kind": 0,
"Flags": 0 "Flags": 0
} }
} },
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": false,
"IsDestructor": false,
"IsVirtual": false,
"IsOverride": false
}], }],
"includes": [], "includes": [],
"macros": [] "macros": []
@@ -209,7 +257,15 @@ TestDoc Case 7:
"Kind": 0, "Kind": 0,
"Flags": 0 "Flags": 0
} }
} },
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": false,
"IsDestructor": false,
"IsVirtual": false,
"IsOverride": false
}], }],
"includes": [], "includes": [],
"macros": [] "macros": []
@@ -242,7 +298,15 @@ TestDoc Case 8:
"Kind": 0, "Kind": 0,
"Flags": 0 "Flags": 0
} }
} },
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": false,
"IsDestructor": false,
"IsVirtual": false,
"IsOverride": false
}], }],
"includes": [], "includes": [],
"macros": [] "macros": []
@@ -279,7 +343,15 @@ TestDoc Case 9:
"Kind": 0, "Kind": 0,
"Flags": 0 "Flags": 0
} }
} },
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": false,
"IsDestructor": false,
"IsVirtual": false,
"IsOverride": false
}], }],
"includes": [], "includes": [],
"macros": [] "macros": []

View File

@@ -21,7 +21,15 @@ TestFuncDecl Case 1:
"Kind": 0, "Kind": 0,
"Flags": 0 "Flags": 0
} }
} },
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": false,
"IsDestructor": false,
"IsVirtual": false,
"IsOverride": false
}], }],
"includes": [], "includes": [],
"macros": [] "macros": []
@@ -64,7 +72,15 @@ TestFuncDecl Case 2:
"Kind": 0, "Kind": 0,
"Flags": 0 "Flags": 0
} }
} },
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": false,
"IsDestructor": false,
"IsVirtual": false,
"IsOverride": false
}], }],
"includes": [], "includes": [],
"macros": [] "macros": []
@@ -123,7 +139,15 @@ TestFuncDecl Case 3:
"Flags": 0 "Flags": 0
} }
} }
} },
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": false,
"IsDestructor": false,
"IsVirtual": false,
"IsOverride": false
}], }],
"includes": [], "includes": [],
"macros": [] "macros": []

View File

@@ -21,7 +21,15 @@ TestScope Case 1:
"Kind": 0, "Kind": 0,
"Flags": 0 "Flags": 0
} }
} },
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": false,
"IsDestructor": false,
"IsVirtual": false,
"IsOverride": false
}], }],
"includes": [], "includes": [],
"macros": [] "macros": []
@@ -52,7 +60,15 @@ TestScope Case 2:
"Kind": 0, "Kind": 0,
"Flags": 0 "Flags": 0
} }
} },
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": false,
"IsDestructor": false,
"IsVirtual": false,
"IsOverride": false
}], }],
"includes": [], "includes": [],
"macros": [] "macros": []
@@ -88,7 +104,15 @@ TestScope Case 3:
"Kind": 0, "Kind": 0,
"Flags": 0 "Flags": 0
} }
} },
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": false,
"IsDestructor": false,
"IsVirtual": false,
"IsOverride": false
}], }],
"includes": [], "includes": [],
"macros": [] "macros": []
@@ -135,7 +159,15 @@ TestScope Case 4:
"Kind": 0, "Kind": 0,
"Flags": 0 "Flags": 0
} }
} },
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": false,
"IsDestructor": false,
"IsVirtual": false,
"IsOverride": false
}] }]
} }
}], }],
@@ -191,7 +223,15 @@ TestScope Case 5:
"Kind": 0, "Kind": 0,
"Flags": 0 "Flags": 0
} }
} },
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": false,
"IsDestructor": false,
"IsVirtual": false,
"IsOverride": false
}] }]
} }
}], }],

View File

@@ -242,7 +242,15 @@ TestStructDecl Case 4:
"Kind": 8, "Kind": 8,
"Flags": 0 "Flags": 0
} }
} },
"IsInline": false,
"IsStatic": false,
"IsConst": false,
"IsExplicit": false,
"IsConstructor": false,
"IsDestructor": false,
"IsVirtual": false,
"IsOverride": false
}] }]
} }
}], }],

View File

@@ -29,7 +29,7 @@ func MarshalASTFile(file *ast.File) *cjson.JSON {
includes := cjson.Array() includes := cjson.Array()
for _, i := range file.Includes { for _, i := range file.Includes {
include := cjson.Object() include := cjson.Object()
include.SetItem(c.Str("Path"), cjson.String(c.AllocaCStr(i.Path))) include.SetItem(c.Str("Path"), stringField(i.Path))
includes.AddItem(include) includes.AddItem(include)
} }
root.SetItem(c.Str("includes"), includes) root.SetItem(c.Str("includes"), includes)
@@ -40,7 +40,7 @@ func MarshalASTFile(file *ast.File) *cjson.JSON {
macros := cjson.Array() macros := cjson.Array()
for _, m := range file.Macros { for _, m := range file.Macros {
marco := cjson.Object() marco := cjson.Object()
marco.SetItem(c.Str("Name"), cjson.String(c.AllocaCStr(m.Name))) marco.SetItem(c.Str("Name"), stringField(m.Name))
tokens := cjson.Array() tokens := cjson.Array()
for _, tok := range m.Tokens { for _, tok := range m.Tokens {
tokens.AddItem(Token(tok)) tokens.AddItem(Token(tok))
@@ -54,8 +54,8 @@ func MarshalASTFile(file *ast.File) *cjson.JSON {
} }
func Token(tok *ast.Token) *cjson.JSON { func Token(tok *ast.Token) *cjson.JSON {
root := cjson.Object() root := cjson.Object()
root.SetItem(c.Str("Token"), cjson.Number(float64(tok.Token))) root.SetItem(c.Str("Token"), numberField(uint(tok.Token)))
root.SetItem(c.Str("Lit"), cjson.String(c.AllocaCStr(tok.Lit))) root.SetItem(c.Str("Lit"), stringField(tok.Lit))
return root return root
} }
@@ -77,6 +77,14 @@ func MarshalASTDecl(decl ast.Decl) *cjson.JSON {
MarshalASTDeclBase(d.DeclBase, root) MarshalASTDeclBase(d.DeclBase, root)
root.SetItem(c.Str("Name"), MarshalASTExpr(d.Name)) root.SetItem(c.Str("Name"), MarshalASTExpr(d.Name))
root.SetItem(c.Str("Type"), MarshalASTExpr(d.Type)) root.SetItem(c.Str("Type"), MarshalASTExpr(d.Type))
root.SetItem(c.Str("IsInline"), boolField(d.IsInline))
root.SetItem(c.Str("IsStatic"), boolField(d.IsStatic))
root.SetItem(c.Str("IsConst"), boolField(d.IsConst))
root.SetItem(c.Str("IsExplicit"), boolField(d.IsExplicit))
root.SetItem(c.Str("IsConstructor"), boolField(d.IsConstructor))
root.SetItem(c.Str("IsDestructor"), boolField(d.IsDestructor))
root.SetItem(c.Str("IsVirtual"), boolField(d.IsVirtual))
root.SetItem(c.Str("IsOverride"), boolField(d.IsOverride))
case *ast.TypeDecl: case *ast.TypeDecl:
MarshalASTDeclBase(d.DeclBase, root) MarshalASTDeclBase(d.DeclBase, root)
root.SetItem(c.Str("Name"), MarshalASTExpr(d.Name)) root.SetItem(c.Str("Name"), MarshalASTExpr(d.Name))
@@ -87,7 +95,7 @@ func MarshalASTDecl(decl ast.Decl) *cjson.JSON {
func MarshalASTDeclBase(decl ast.DeclBase, root *cjson.JSON) { func MarshalASTDeclBase(decl ast.DeclBase, root *cjson.JSON) {
loc := cjson.Object() loc := cjson.Object()
loc.SetItem(c.Str("File"), cjson.String(c.AllocaCStr(decl.Loc.File))) loc.SetItem(c.Str("File"), stringField(decl.Loc.File))
root.SetItem(c.Str("Loc"), loc) root.SetItem(c.Str("Loc"), loc)
root.SetItem(c.Str("Doc"), MarshalASTExpr(decl.Doc)) root.SetItem(c.Str("Doc"), MarshalASTExpr(decl.Doc))
@@ -112,7 +120,7 @@ func MarshalASTExpr(t ast.Expr) *cjson.JSON {
root.SetItem(c.Str("Name"), MarshalASTExpr(d.Name)) root.SetItem(c.Str("Name"), MarshalASTExpr(d.Name))
root.SetItem(c.Str("Value"), MarshalASTExpr(d.Value)) root.SetItem(c.Str("Value"), MarshalASTExpr(d.Value))
case *ast.RecordType: case *ast.RecordType:
root.SetItem(c.Str("Tag"), cjson.Number(float64(d.Tag))) root.SetItem(c.Str("Tag"), numberField(uint(d.Tag)))
root.SetItem(c.Str("Fields"), MarshalASTExpr(d.Fields)) root.SetItem(c.Str("Fields"), MarshalASTExpr(d.Fields))
methods := cjson.Array() methods := cjson.Array()
for _, m := range d.Methods { for _, m := range d.Methods {
@@ -144,13 +152,13 @@ func MarshalASTExpr(t ast.Expr) *cjson.JSON {
if d == nil { if d == nil {
return cjson.Null() return cjson.Null()
} }
root.SetItem(c.Str("Name"), cjson.String(c.AllocaCStr(d.Name))) root.SetItem(c.Str("Name"), stringField(d.Name))
case *ast.TagExpr: case *ast.TagExpr:
root.SetItem(c.Str("Name"), MarshalASTExpr(d.Name)) root.SetItem(c.Str("Name"), MarshalASTExpr(d.Name))
root.SetItem(c.Str("Tag"), cjson.Number(float64(d.Tag))) root.SetItem(c.Str("Tag"), numberField(uint(d.Tag)))
case *ast.BasicLit: case *ast.BasicLit:
root.SetItem(c.Str("Kind"), cjson.Number(float64(d.Kind))) root.SetItem(c.Str("Kind"), numberField(uint(d.Kind)))
root.SetItem(c.Str("Value"), cjson.String(c.AllocaCStr(d.Value))) root.SetItem(c.Str("Value"), stringField(d.Value))
case *ast.LvalueRefType: case *ast.LvalueRefType:
root.SetItem(c.Str("X"), MarshalASTExpr(d.X)) root.SetItem(c.Str("X"), MarshalASTExpr(d.X))
case *ast.RvalueRefType: case *ast.RvalueRefType:
@@ -161,13 +169,13 @@ func MarshalASTExpr(t ast.Expr) *cjson.JSON {
root.SetItem(c.Str("Elt"), MarshalASTExpr(d.Elt)) root.SetItem(c.Str("Elt"), MarshalASTExpr(d.Elt))
root.SetItem(c.Str("Len"), MarshalASTExpr(d.Len)) root.SetItem(c.Str("Len"), MarshalASTExpr(d.Len))
case *ast.BuiltinType: case *ast.BuiltinType:
root.SetItem(c.Str("Kind"), cjson.Number(float64(d.Kind))) root.SetItem(c.Str("Kind"), numberField(uint(d.Kind)))
root.SetItem(c.Str("Flags"), cjson.Number(float64(d.Flags))) root.SetItem(c.Str("Flags"), numberField(uint(d.Flags)))
case *ast.Comment: case *ast.Comment:
if d == nil { if d == nil {
return cjson.Null() return cjson.Null()
} }
root.SetItem(c.Str("Text"), cjson.String(c.AllocaCStr(d.Text))) root.SetItem(c.Str("Text"), stringField(d.Text))
case *ast.CommentGroup: case *ast.CommentGroup:
if d == nil { if d == nil {
return cjson.Null() return cjson.Null()
@@ -185,3 +193,18 @@ func MarshalASTExpr(t ast.Expr) *cjson.JSON {
} }
return root return root
} }
func stringField(s string) *cjson.JSON {
return cjson.String(c.AllocaCStr(s))
}
func numberField(n uint) *cjson.JSON {
return cjson.Number(float64(n))
}
func boolField(b bool) *cjson.JSON {
if b {
return cjson.True()
}
return cjson.False()
}