Merge pull request #672 from luoliwoshang/c/clang/type-tree
castdump:array,typedef,pointer,funcproto,enum & builtin type
This commit is contained in:
@@ -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_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_getCanonicalType(CXType *typ, CXType *canonicalType) { *canonicalType = clang_getCanonicalType(*typ); }
|
||||
|
||||
CXString wrap_clang_getTypeSpelling(CXType *typ) { return clang_getTypeSpelling(*typ); }
|
||||
|
||||
CXString wrap_clang_getTokenSpelling(CXTranslationUnit unit, CXToken *token) {
|
||||
|
||||
@@ -1321,6 +1321,14 @@ type Cursor struct {
|
||||
|
||||
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
|
||||
*/
|
||||
@@ -1780,6 +1788,44 @@ func (t Type) String() (ret String) {
|
||||
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
|
||||
func (File) FileName() (ret String) { return }
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goplus/llgo/c"
|
||||
@@ -14,19 +15,22 @@ type Data struct {
|
||||
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 {
|
||||
switch spec {
|
||||
case clang.CXXInvalidAccessSpecifier:
|
||||
return "invalid"
|
||||
case clang.CXXPublic:
|
||||
return "public"
|
||||
case clang.CXXProtected:
|
||||
return "protected"
|
||||
case clang.CXXPrivate:
|
||||
return "private"
|
||||
default:
|
||||
return "unkown"
|
||||
if str, ok := accessMap[spec]; ok {
|
||||
return str
|
||||
}
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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) {
|
||||
loc := cursor.Location()
|
||||
var file clang.File
|
||||
@@ -78,25 +108,28 @@ func printFunc(cursor clang.Cursor) {
|
||||
kind := cursor.Kind.String()
|
||||
spell := cursor.String()
|
||||
symbol := cursor.Mangling()
|
||||
typ := cursor.Type().String()
|
||||
defer symbol.Dispose()
|
||||
defer kind.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()
|
||||
spell := cursor.String()
|
||||
defer kind.Dispose()
|
||||
defer spell.Dispose()
|
||||
|
||||
// node which has type
|
||||
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())
|
||||
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()
|
||||
spell := cursor.String()
|
||||
|
||||
for i := c.Uint(0); i < data.Depth; i++ {
|
||||
c.Fputs(c.Str(" "), c.Stdout)
|
||||
}
|
||||
printIndent(data.Depth)
|
||||
|
||||
switch cursor.Kind {
|
||||
case clang.CursorCXXAccessSpecifier:
|
||||
printAccess(cursor)
|
||||
printLocation(cursor)
|
||||
case clang.CursorMacroDefinition:
|
||||
printMacro(cursor, data.Unit)
|
||||
printLocation(cursor)
|
||||
case clang.CursorFunctionDecl, clang.CursorCXXMethod, clang.CursorConstructor, clang.CursorDestructor:
|
||||
printFunc(cursor)
|
||||
printLocation(cursor)
|
||||
default:
|
||||
printDefault(cursor)
|
||||
printDefault(cursor, data)
|
||||
}
|
||||
|
||||
printLocation(cursor)
|
||||
|
||||
data.Depth++
|
||||
clang.VisitChildren(cursor, visit, c.Pointer(data))
|
||||
data.Depth--
|
||||
|
||||
Reference in New Issue
Block a user