Merge pull request #672 from luoliwoshang/c/clang/type-tree

castdump:array,typedef,pointer,funcproto,enum & builtin type
This commit is contained in:
xushiwei
2024-08-07 19:15:37 +08:00
committed by GitHub
3 changed files with 111 additions and 23 deletions

View File

@@ -31,8 +31,18 @@ void wrap_clang_getTranslationUnitCursor(CXTranslationUnit uint, CXCursor *cur)
void wrap_clang_getCursorType(CXCursor *cur, CXType *typ) { *typ = clang_getCursorType(*cur); } void wrap_clang_getCursorType(CXCursor *cur, CXType *typ) { *typ = clang_getCursorType(*cur); }
void wrap_clang_getPointeeType(CXType *pointerTyp, CXType *pointeeTyp) {
*pointeeTyp = clang_getPointeeType(*pointerTyp);
}
void wrap_clang_getArrayElementType(CXType *arrayTyp, CXType *elemTyp) {
*elemTyp = clang_getArrayElementType(*arrayTyp);
}
void wrap_clang_getCursorResultType(CXCursor *cur, CXType *typ) { *typ = clang_getCursorResultType(*cur); } void wrap_clang_getCursorResultType(CXCursor *cur, CXType *typ) { *typ = clang_getCursorResultType(*cur); }
void wrap_clang_getCanonicalType(CXType *typ, CXType *canonicalType) { *canonicalType = clang_getCanonicalType(*typ); }
CXString wrap_clang_getTypeSpelling(CXType *typ) { return clang_getTypeSpelling(*typ); } CXString wrap_clang_getTypeSpelling(CXType *typ) { return clang_getTypeSpelling(*typ); }
CXString wrap_clang_getTokenSpelling(CXTranslationUnit unit, CXToken *token) { CXString wrap_clang_getTokenSpelling(CXTranslationUnit unit, CXToken *token) {

View File

@@ -1321,6 +1321,14 @@ type Cursor struct {
type TypeKind c.Int type TypeKind c.Int
/**
* Retrieve the spelling of a given CXTypeKind.
*/
// llgo:link TypeKind.String C.clang_getTypeKindSpelling
func (TypeKind) String() (ret String) {
return
}
/** /**
* Describes the kind of type * Describes the kind of type
*/ */
@@ -1780,6 +1788,44 @@ func (t Type) String() (ret String) {
return t.wrapString() return t.wrapString()
} }
/**
* For pointer types, returns the type of the pointee.
*/
// llgo:link (*Type).wrapPointeeType C.wrap_clang_getPointeeType
func (t *Type) wrapPointeeType(ret *Type) { return }
func (t Type) PointeeType() (ret Type) {
t.wrapPointeeType(&ret)
return
}
/**
* Return the element type of an array type.
*
* If a non-array type is passed in, an invalid type is returned.
*/
// llgo:link (*Type).wrapArrayElementType C.wrap_clang_getArrayElementType
func (t *Type) wrapArrayElementType(ret *Type) { return }
func (t Type) ArrayElementType() (ret Type) {
t.wrapArrayElementType(&ret)
return
}
/**
* Return the canonical type for a CXType.
*
* Clang's type system explicitly models typedefs and all the ways
* a specific type can be represented. The canonical type is the underlying
* type with all the "sugar" removed. For example, if 'T' is a typedef
* for 'int', the canonical type for 'T' would be 'int'.
*/
// llgo:link (*Type).wrapCanonicalType C.wrap_clang_getCanonicalType
func (t *Type) wrapCanonicalType(ret *Type) { return }
func (t Type) CanonicalType() (ret Type) {
t.wrapCanonicalType(&ret)
return
}
//llgo:link File.FileName C.clang_getFileName //llgo:link File.FileName C.clang_getFileName
func (File) FileName() (ret String) { return } func (File) FileName() (ret String) { return }

View File

@@ -3,6 +3,7 @@ package main
import ( import (
"fmt" "fmt"
"os" "os"
"strings"
"unsafe" "unsafe"
"github.com/goplus/llgo/c" "github.com/goplus/llgo/c"
@@ -14,19 +15,22 @@ type Data struct {
Unit *clang.TranslationUnit Unit *clang.TranslationUnit
} }
var accessMap = map[clang.CXXAccessSpecifier]string{
clang.CXXInvalidAccessSpecifier: "invalid",
clang.CXXPublic: "public",
clang.CXXProtected: "protected",
clang.CXXPrivate: "private",
}
func printIndent(depth c.Uint) {
fmt.Print(strings.Repeat(" ", int(depth)))
}
func accessToString(spec clang.CXXAccessSpecifier) string { func accessToString(spec clang.CXXAccessSpecifier) string {
switch spec { if str, ok := accessMap[spec]; ok {
case clang.CXXInvalidAccessSpecifier: return str
return "invalid"
case clang.CXXPublic:
return "public"
case clang.CXXProtected:
return "protected"
case clang.CXXPrivate:
return "private"
default:
return "unkown"
} }
return "unknown"
} }
func visit(cursor, parent clang.Cursor, ClientData c.Pointer) clang.ChildVisitResult { func visit(cursor, parent clang.Cursor, ClientData c.Pointer) clang.ChildVisitResult {
@@ -35,6 +39,32 @@ func visit(cursor, parent clang.Cursor, ClientData c.Pointer) clang.ChildVisitRe
return clang.ChildVisit_Continue return clang.ChildVisit_Continue
} }
func printType(t clang.Type, data *Data) {
printIndent(data.Depth)
typeSpell := t.String()
typeKind := t.Kind.String()
if t.Kind > clang.TypeFirstBuiltin && t.Kind < clang.TypeLastBuiltin {
c.Printf(c.Str("<BuiltinType|%s>: %s\n"), typeKind.CStr(), typeSpell.CStr())
} else if t.Kind > clang.TypeComplex {
c.Printf(c.Str("<ComplexType|%s>: %s\n"), typeKind.CStr(), typeSpell.CStr())
}
data.Depth++
switch t.Kind {
case clang.TypePointer:
printType(t.PointeeType(), data)
case clang.TypeIncompleteArray, clang.TypeVariableArray, clang.TypeDependentSizedArray, clang.TypeConstantArray:
printType(t.ArrayElementType(), data)
case clang.TypeTypedef:
printType(t.CanonicalType(), data)
}
data.Depth--
typeKind.Dispose()
typeSpell.Dispose()
}
func printLocation(cursor clang.Cursor) { func printLocation(cursor clang.Cursor) {
loc := cursor.Location() loc := cursor.Location()
var file clang.File var file clang.File
@@ -78,25 +108,28 @@ func printFunc(cursor clang.Cursor) {
kind := cursor.Kind.String() kind := cursor.Kind.String()
spell := cursor.String() spell := cursor.String()
symbol := cursor.Mangling() symbol := cursor.Mangling()
typ := cursor.Type().String()
defer symbol.Dispose() defer symbol.Dispose()
defer kind.Dispose() defer kind.Dispose()
defer spell.Dispose() defer spell.Dispose()
defer typ.Dispose()
c.Printf(c.Str("%s: %s (Symbol: %s)"), kind.CStr(), spell.CStr(), symbol.CStr()) c.Printf(c.Str("%s: %s (Type: %s)(Symbol: %s)"), kind.CStr(), spell.CStr(), typ.CStr(), symbol.CStr())
} }
func printDefault(cursor clang.Cursor) { func printDefault(cursor clang.Cursor, data *Data) {
kind := cursor.Kind.String() kind := cursor.Kind.String()
spell := cursor.String() spell := cursor.String()
defer kind.Dispose() defer kind.Dispose()
defer spell.Dispose() defer spell.Dispose()
// node which has type
if cursor.Type().Kind != clang.TypeInvalid { if cursor.Type().Kind != clang.TypeInvalid {
typeSpell := cursor.Type().String()
c.Printf(c.Str("%s: %s (Type: %s)"), kind.CStr(), spell.CStr(), typeSpell.CStr())
typeSpell.Dispose()
} else {
c.Printf(c.Str("%s: %s"), kind.CStr(), spell.CStr()) c.Printf(c.Str("%s: %s"), kind.CStr(), spell.CStr())
printLocation(cursor)
printType(cursor.Type(), data)
} else {
c.Printf(c.Str("%s: %s\n"), kind.CStr(), spell.CStr())
} }
} }
@@ -104,23 +137,22 @@ func printAST(cursor clang.Cursor, data *Data) {
kind := cursor.Kind.String() kind := cursor.Kind.String()
spell := cursor.String() spell := cursor.String()
for i := c.Uint(0); i < data.Depth; i++ { printIndent(data.Depth)
c.Fputs(c.Str(" "), c.Stdout)
}
switch cursor.Kind { switch cursor.Kind {
case clang.CursorCXXAccessSpecifier: case clang.CursorCXXAccessSpecifier:
printAccess(cursor) printAccess(cursor)
printLocation(cursor)
case clang.CursorMacroDefinition: case clang.CursorMacroDefinition:
printMacro(cursor, data.Unit) printMacro(cursor, data.Unit)
printLocation(cursor)
case clang.CursorFunctionDecl, clang.CursorCXXMethod, clang.CursorConstructor, clang.CursorDestructor: case clang.CursorFunctionDecl, clang.CursorCXXMethod, clang.CursorConstructor, clang.CursorDestructor:
printFunc(cursor) printFunc(cursor)
printLocation(cursor)
default: default:
printDefault(cursor) printDefault(cursor, data)
} }
printLocation(cursor)
data.Depth++ data.Depth++
clang.VisitChildren(cursor, visit, c.Pointer(data)) clang.VisitChildren(cursor, visit, c.Pointer(data))
data.Depth-- data.Depth--