Skip to content

Commit

Permalink
castdump:full ast dump
Browse files Browse the repository at this point in the history
  • Loading branch information
luoliwoshang committed Aug 6, 2024
1 parent 6a05aa4 commit 81cfc73
Show file tree
Hide file tree
Showing 2 changed files with 166 additions and 61 deletions.
61 changes: 0 additions & 61 deletions c/clang/_demo/castdump/astdump.go

This file was deleted.

166 changes: 166 additions & 0 deletions chore/_xtool/castdump/castdump.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package main

import (
"fmt"
"os"
"unsafe"

"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/clang"
)

type Data struct {
Depth c.Uint
Unit *clang.TranslationUnit
}

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"
}
}

func visit(cursor, parent clang.Cursor, ClientData c.Pointer) clang.ChildVisitResult {
data := (*Data)(ClientData)
printAST(cursor, data)
return clang.ChildVisit_Continue
}

func printLocation(cursor clang.Cursor) {
loc := cursor.Location()
var file clang.File
var line, column c.Uint

loc.SpellingLocation(&file, &line, &column, nil)
filename := file.FileName()
defer filename.Dispose()

c.Printf(c.Str("(Loc:%s:%d:%d)\n"), filename.CStr(), line, column)
}

func printAccess(cursor clang.Cursor) {
kind := cursor.Kind.String()
spell := cursor.String()
defer kind.Dispose()
defer spell.Dispose()

c.Printf(c.Str("%s: %s %s\n"), kind.CStr(), spell.CStr(), c.AllocaCStr(accessToString(cursor.CXXAccessSpecifier())))
}

func printMacro(cursor clang.Cursor, unit *clang.TranslationUnit) {
kind := cursor.Kind.String()
defer kind.Dispose()

c.Printf(c.Str("%s: "), kind.CStr())
ran := cursor.Extent()
var numTokens c.Uint
var tokens *clang.Token
unit.Tokenize(ran, &tokens, &numTokens)
tokensSlice := unsafe.Slice(tokens, int(numTokens))
for _, tok := range tokensSlice {
tokStr := unit.Token(tok)
c.Printf(c.Str("%s "), tokStr.CStr())
tokStr.Dispose()
}
c.Printf(c.Str("\n"))
}

func printFunc(cursor clang.Cursor) {
kind := cursor.Kind.String()
spell := cursor.String()
symbol := cursor.Mangling()
defer symbol.Dispose()
defer kind.Dispose()
defer spell.Dispose()

c.Printf(c.Str("%s: %s (Symbol: %s)"), kind.CStr(), spell.CStr(), symbol.CStr())
}

func printDefault(cursor clang.Cursor) {
kind := cursor.Kind.String()
spell := cursor.String()
defer kind.Dispose()
defer spell.Dispose()

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())
}
}

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)
}

switch cursor.Kind {
case clang.CursorCXXAccessSpecifier:
printAccess(cursor)
case clang.CursorMacroDefinition:
printMacro(cursor, data.Unit)
case clang.CursorFunctionDecl, clang.CursorCXXMethod, clang.CursorConstructor, clang.CursorDestructor:
printFunc(cursor)
default:
printDefault(cursor)
}

printLocation(cursor)

data.Depth++
clang.VisitChildren(cursor, visit, c.Pointer(data))
data.Depth--

kind.Dispose()
spell.Dispose()
}

func main() {
if c.Argc != 2 {
fmt.Fprintln(os.Stderr, "Usage: castdump <headerFile>")
return
}

args := make([]*c.Char, 3)
args[0] = c.Str("-x")
args[1] = c.Str("c++")
args[2] = c.Str("-std=c++11")

sourceFile := *c.Advance(c.Argv, 1)
index := clang.CreateIndex(0, 0)
unit := index.ParseTranslationUnit(
sourceFile,
unsafe.SliceData(args), 3,
nil, 0,
clang.DetailedPreprocessingRecord,
)
defer index.Dispose()
defer unit.Dispose()

if unit == nil {
println("Unable to parse translation unit. Quitting.")
c.Exit(1)
}

cursor := unit.Cursor()

Data := &Data{
Depth: 0,
Unit: unit,
}
printAST(cursor, Data)
}

0 comments on commit 81cfc73

Please sign in to comment.