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_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) {
|
||||||
|
|||||||
@@ -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 }
|
||||||
|
|
||||||
|
|||||||
@@ -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--
|
||||||
|
|||||||
Reference in New Issue
Block a user