Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 0 additions & 73 deletions _xtool/internal/clang/clang_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,11 @@ package clang_test
import (
"fmt"
"os"
"path"
"path/filepath"
"strings"
"testing"

"github.com/goplus/lib/c"
"github.com/goplus/lib/c/clang"
clangutils "github.com/goplus/llcppg/_xtool/internal/clang"
"github.com/goplus/llcppg/_xtool/internal/clangtool"
)

func TestClangUtil(t *testing.T) {
Expand Down Expand Up @@ -179,75 +175,6 @@ cursorRange 11:1 -> 11:11
compareOutput(t, expect, str.String())
}

func TestPreprocess(t *testing.T) {
outfile, err := os.CreateTemp("", "compose_*.h")
if err != nil {
panic(err)
}
absPath, err := filepath.Abs("./testdata/hfile")
if err != nil {
panic(err)
}
clangtool.ComposeIncludes([]string{"main.h", "compat.h"}, outfile.Name())

efile, err := os.CreateTemp("", "temp_*.i")
if err != nil {
panic(err)
}
defer os.Remove(efile.Name())

cfg := &clangtool.PreprocessConfig{
File: outfile.Name(),
IsCpp: true,
Args: []string{"-I" + absPath},
OutFile: efile.Name(),
}
err = clangtool.Preprocess(cfg)
if err != nil {
panic(err)
}
config := &clangutils.Config{
File: efile.Name(),
Temp: false,
IsCpp: false,
}

var str strings.Builder

visit(config, func(cursor, parent clang.Cursor) clang.ChildVisitResult {
switch cursor.Kind {
case clang.CursorEnumDecl, clang.CursorStructDecl, clang.CursorUnionDecl, clang.CursorTypedefDecl:
var filename clang.String
var line, column c.Uint
cursor.Location().PresumedLocation(&filename, &line, &column)
str.WriteString("TypeKind: ")
str.WriteString(clang.GoString(cursor.Kind.String()))
str.WriteString(" Name: ")
str.WriteString(clang.GoString(cursor.String()))
str.WriteString("\n")
str.WriteString("Location: ")
str.WriteString(fmt.Sprintf("%s:%d:%d\n", path.Base(c.GoString(filename.CStr())), line, column))
}
return clang.ChildVisit_Continue
})

expect := `
TypeKind: StructDecl Name: A
Location: main.h:3:16
TypeKind: TypedefDecl Name: A
Location: main.h:6:3
TypeKind: TypedefDecl Name: B
Location: compat.h:3:11
TypeKind: TypedefDecl Name: C
Location: main.h:8:11
`

compareOutput(t, expect, str.String())

outfile.Close()
os.Remove(outfile.Name())
}

func visit(config *clangutils.Config, visitFunc func(cursor, parent clang.Cursor) clang.ChildVisitResult) {
index, unit, err := clangutils.CreateTranslationUnit(config)
if err != nil {
Expand Down
19 changes: 0 additions & 19 deletions _xtool/internal/clangtool/clangtool.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,6 @@ var _sysRootDirOnce = sync.OnceValues(sysRoot)

var _matchISysrootRegex = regexp.MustCompile(`-(resource-dir|internal-isystem|isysroot|internal-externc-isystem)\s(\S+)`)

type PreprocessConfig struct {
File string
IsCpp bool
Args []string
OutFile string
}

func Preprocess(cfg *PreprocessConfig) error {
args := []string{"-E"}
args = append(args, defaultArgs(cfg.IsCpp)...)
args = append(args, cfg.Args...)
args = append(args, cfg.File)
args = append(args, "-o", cfg.OutFile)
cmd := exec.Command("clang", args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}

// ComposeIncludes create Include list
// #include <file1.h>
// #include <file2.h>
Expand Down
87 changes: 86 additions & 1 deletion _xtool/internal/parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@ import (
"encoding/json"
"fmt"
"os"
"path"
"path/filepath"
"reflect"
"strings"
"testing"

"github.com/goplus/lib/c"
"github.com/goplus/lib/c/clang"
clangutils "github.com/goplus/llcppg/_xtool/internal/clang"
"github.com/goplus/llcppg/_xtool/internal/clangtool"
"github.com/goplus/llcppg/_xtool/internal/parser"

"github.com/goplus/llcppg/ast"
"github.com/goplus/llgo/xtool/clang/preprocessor"
)

func TestParser(t *testing.T) {
Expand Down Expand Up @@ -533,3 +536,85 @@ func getComplexType(flag ast.TypeFlag) clang.Type {

return typ
}

func TestPreprocess(t *testing.T) {
combinedFile, err := os.CreateTemp("./", "compose_*.h")
if err != nil {
panic(err)
}
defer os.Remove(combinedFile.Name())

clangtool.ComposeIncludes([]string{"main.h", "compat.h"}, combinedFile.Name())

efile, err := os.CreateTemp("", "temp_*.i")
if err != nil {
panic(err)
}
defer os.Remove(efile.Name())

ppconf := &preprocessor.Config{
Compiler: "clang",
Flags: []string{"-I./_testdata/hfile"},
}
err = preprocessor.Do(combinedFile.Name(), efile.Name(), ppconf)
if err != nil {
t.Fatal(err)
}

config := &clangutils.Config{
File: efile.Name(),
Temp: false,
IsCpp: false,
}

var str strings.Builder

visit(config, func(cursor, parent clang.Cursor) clang.ChildVisitResult {
switch cursor.Kind {
case clang.CursorEnumDecl, clang.CursorStructDecl, clang.CursorUnionDecl, clang.CursorTypedefDecl:
var filename clang.String
var line, column c.Uint
cursor.Location().PresumedLocation(&filename, &line, &column)
str.WriteString("TypeKind: ")
str.WriteString(clang.GoString(cursor.Kind.String()))
str.WriteString(" Name: ")
str.WriteString(clang.GoString(cursor.String()))
str.WriteString("\n")
str.WriteString("Location: ")
str.WriteString(fmt.Sprintf("%s:%d:%d\n", path.Base(c.GoString(filename.CStr())), line, column))
}
return clang.ChildVisit_Continue
})

expect := `
TypeKind: StructDecl Name: A
Location: main.h:3:16
TypeKind: TypedefDecl Name: A
Location: main.h:6:3
TypeKind: TypedefDecl Name: B
Location: compat.h:3:11
TypeKind: TypedefDecl Name: C
Location: main.h:8:11
`

compareOutput(t, expect, str.String())
}

func visit(config *clangutils.Config, visitFunc func(cursor, parent clang.Cursor) clang.ChildVisitResult) {
index, unit, err := clangutils.CreateTranslationUnit(config)
if err != nil {
panic(err)
}
cursor := unit.Cursor()
clangutils.VisitChildren(cursor, visitFunc)
index.Dispose()
unit.Dispose()
}

func compareOutput(t *testing.T, expected, actual string) {
expected = strings.TrimSpace(expected)
actual = strings.TrimSpace(actual)
if expected != actual {
t.Fatalf("Test failed: expected \n%s \ngot \n%s", expected, actual)
}
}
29 changes: 23 additions & 6 deletions _xtool/llcppsigfetch/internal/parse/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/goplus/llcppg/_xtool/internal/config"
"github.com/goplus/llcppg/_xtool/internal/parser"
llcppg "github.com/goplus/llcppg/config"
"github.com/goplus/llgo/xtool/clang/preprocessor"
)

type dbgFlags = int
Expand Down Expand Up @@ -79,16 +80,32 @@ func Do(conf *Config) error {

// prepare clang flags to preprocess the combined file
clangFlags := strings.Fields(conf.Conf.CFlags)
if !isCpp {
clangFlags = append(clangFlags, "-x", "c")
} else {
clangFlags = append(clangFlags, "-x", "c++")
}
clangFlags = append(clangFlags, "-C") // keep comment
clangFlags = append(clangFlags, "-dD") // keep macro
clangFlags = append(clangFlags, "-fparse-all-comments")

err = clangtool.Preprocess(&clangtool.PreprocessConfig{
File: conf.CombinedFile,
IsCpp: isCpp,
Args: clangFlags,
OutFile: conf.PreprocessedFile,
})
pwd, err := os.Getwd()
if err != nil {
return err
}

ppconf := &preprocessor.Config{
Compiler: "clang",
Flags: clangFlags,
BaseDir: pwd,
}

fmt.Fprintln(os.Stderr, "pwd", pwd)
fmt.Fprintln(os.Stderr, "clangFlags", clangFlags)
fmt.Fprintln(os.Stderr, "conf.CombinedFile", conf.CombinedFile)
fmt.Fprintln(os.Stderr, "conf.PreprocessedFile", conf.PreprocessedFile)

err = preprocessor.Do(conf.CombinedFile, conf.PreprocessedFile, ppconf)
if err != nil {
return err
}
Expand Down
23 changes: 23 additions & 0 deletions _xtool/llcppsigfetch/internal/parse/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"strings"
"testing"

"github.com/goplus/llcppg/_xtool/internal/clangtool"
"github.com/goplus/llcppg/_xtool/internal/parser"
"github.com/goplus/llcppg/_xtool/llcppsigfetch/internal/parse"
llcppg "github.com/goplus/llcppg/config"
Expand All @@ -27,7 +28,11 @@ func TestInclusionMap(t *testing.T) {
t.Fatalf("sys/types.h not found")
}
}

combinedFile := createCombineFile([]string{"sys.h"})
defer os.Remove(combinedFile)
err := parse.Do(&parse.Config{
CombinedFile: combinedFile,
Conf: &llcppg.Config{
Include: []string{"sys.h"},
CFlags: "-I./testdata/sysinc/hfile",
Expand All @@ -48,7 +53,10 @@ func TestSystemHeader(t *testing.T) {
}
}
}
combinedFile := createCombineFile([]string{"inc.h"})
defer os.Remove(combinedFile)
err := parse.Do(&parse.Config{
CombinedFile: combinedFile,
Conf: &llcppg.Config{
Include: []string{"inc.h"},
CFlags: "-I./testdata/sysinc/hfile",
Expand All @@ -61,7 +69,10 @@ func TestSystemHeader(t *testing.T) {
}

func TestMacroExpansionOtherFile(t *testing.T) {
combinedFile := createCombineFile([]string{"ref.h"})
defer os.Remove(combinedFile)
conf := &parse.Config{
CombinedFile: combinedFile,
Conf: &llcppg.Config{
Include: []string{"ref.h"},
CFlags: "-I./testdata/macroexpan/hfile",
Expand Down Expand Up @@ -125,3 +136,15 @@ func marshalFileMap(fmap map[string]*llcppg.FileInfo) map[string]any {
}
return root
}

func createCombineFile(includes []string) string {
combinedFile, err := os.CreateTemp("./", "compose_*.h")
if err != nil {
panic(err)
}
err = clangtool.ComposeIncludes(includes, combinedFile.Name())
if err != nil {
panic(err)
}
return combinedFile.Name()
}
Loading