llcppsymg:translation unit util
This commit is contained in:
72
chore/_xtool/llcppsymg/clangutils/clangutils.go
Normal file
72
chore/_xtool/llcppsymg/clangutils/clangutils.go
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
package clangutils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/clang"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
File string
|
||||||
|
Temp bool
|
||||||
|
Args []string
|
||||||
|
IsCpp bool
|
||||||
|
Index *clang.Index
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateTranslationUnit(config *Config) (*clang.Index, *clang.TranslationUnit, error) {
|
||||||
|
// default use the c/c++ standard of clang; c:gnu17 c++:gnu++17
|
||||||
|
// https://clang.llvm.org/docs/CommandGuide/clang.html
|
||||||
|
defaultArgs := []string{"-x", "c"}
|
||||||
|
if config.IsCpp {
|
||||||
|
defaultArgs = []string{"-x", "c++"}
|
||||||
|
}
|
||||||
|
allArgs := append(defaultArgs, config.Args...)
|
||||||
|
|
||||||
|
cArgs := make([]*c.Char, len(allArgs))
|
||||||
|
for i, arg := range allArgs {
|
||||||
|
cArgs[i] = c.AllocaCStr(arg)
|
||||||
|
}
|
||||||
|
|
||||||
|
var index *clang.Index
|
||||||
|
if config.Index != nil {
|
||||||
|
index = config.Index
|
||||||
|
} else {
|
||||||
|
index = clang.CreateIndex(0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
var unit *clang.TranslationUnit
|
||||||
|
|
||||||
|
if config.Temp {
|
||||||
|
content := c.AllocaCStr(config.File)
|
||||||
|
tempFile := &clang.UnsavedFile{
|
||||||
|
Filename: c.Str("temp.h"),
|
||||||
|
Contents: content,
|
||||||
|
Length: c.Ulong(c.Strlen(content)),
|
||||||
|
}
|
||||||
|
|
||||||
|
unit = index.ParseTranslationUnit(
|
||||||
|
tempFile.Filename,
|
||||||
|
unsafe.SliceData(cArgs), c.Int(len(cArgs)),
|
||||||
|
tempFile, 1,
|
||||||
|
clang.DetailedPreprocessingRecord,
|
||||||
|
)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
cFile := c.AllocaCStr(config.File)
|
||||||
|
unit = index.ParseTranslationUnit(
|
||||||
|
cFile,
|
||||||
|
unsafe.SliceData(cArgs), c.Int(len(cArgs)),
|
||||||
|
nil, 0,
|
||||||
|
clang.DetailedPreprocessingRecord,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if unit == nil {
|
||||||
|
return nil, nil, errors.New("failed to parse translation unit")
|
||||||
|
}
|
||||||
|
|
||||||
|
return index, unit, nil
|
||||||
|
}
|
||||||
@@ -4,10 +4,10 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
"github.com/goplus/llgo/c"
|
||||||
"github.com/goplus/llgo/c/clang"
|
"github.com/goplus/llgo/c/clang"
|
||||||
|
"github.com/goplus/llgo/chore/_xtool/llcppsymg/clangutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Context struct {
|
type Context struct {
|
||||||
@@ -133,35 +133,25 @@ func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitRe
|
|||||||
return clang.ChildVisit_Continue
|
return clang.ChildVisit_Continue
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseHeaderFile(filepaths []string, prefixes []string) (map[string]string, error) {
|
func ParseHeaderFile(filepaths []string, prefixes []string, isCpp bool) (map[string]string, error) {
|
||||||
index := clang.CreateIndex(0, 0)
|
|
||||||
args := make([]*c.Char, 3)
|
|
||||||
args[0] = c.Str("-x")
|
|
||||||
args[1] = c.Str("c++")
|
|
||||||
args[2] = c.Str("-std=c++11")
|
|
||||||
context = newContext(prefixes)
|
context = newContext(prefixes)
|
||||||
|
|
||||||
for _, filename := range filepaths {
|
for _, filename := range filepaths {
|
||||||
unit := index.ParseTranslationUnit(
|
index, unit, err := clangutils.CreateTranslationUnit(&clangutils.Config{
|
||||||
c.AllocaCStr(filename),
|
File: filename,
|
||||||
unsafe.SliceData(args), 3,
|
Temp: false,
|
||||||
nil, 0,
|
IsCpp: isCpp,
|
||||||
clang.TranslationUnit_None,
|
})
|
||||||
)
|
if err != nil {
|
||||||
|
|
||||||
if unit == nil {
|
|
||||||
return nil, errors.New("Unable to parse translation unit for file " + filename)
|
return nil, errors.New("Unable to parse translation unit for file " + filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor := unit.Cursor()
|
cursor := unit.Cursor()
|
||||||
context.setCurrentFile(filename)
|
context.setCurrentFile(filename)
|
||||||
|
|
||||||
clang.VisitChildren(cursor, visit, nil)
|
clang.VisitChildren(cursor, visit, nil)
|
||||||
|
|
||||||
unit.Dispose()
|
unit.Dispose()
|
||||||
|
index.Dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
index.Dispose()
|
|
||||||
|
|
||||||
return context.symbolMap, nil
|
return context.symbolMap, nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user