diff options
Diffstat (limited to 'vendor/modernc.org/ccgo/v3/lib/ccgo.go')
-rw-r--r-- | vendor/modernc.org/ccgo/v3/lib/ccgo.go | 369 |
1 files changed, 328 insertions, 41 deletions
diff --git a/vendor/modernc.org/ccgo/v3/lib/ccgo.go b/vendor/modernc.org/ccgo/v3/lib/ccgo.go index 7865ab8f6..0c62d76b2 100644 --- a/vendor/modernc.org/ccgo/v3/lib/ccgo.go +++ b/vendor/modernc.org/ccgo/v3/lib/ccgo.go @@ -18,6 +18,7 @@ import ( "go/parser" "go/token" "io" + "io/ioutil" "os" "os/exec" "path/filepath" @@ -32,17 +33,20 @@ import ( "github.com/kballard/go-shellquote" "golang.org/x/tools/go/packages" "modernc.org/cc/v3" + "modernc.org/libc" "modernc.org/opt" ) const ( - Version = "3.10.0-20210904132603" + Version = "3.12.6-20210922111124" experimentsEnvVar = "CCGO_EXPERIMENT" maxSourceLine = 1 << 20 ) var ( + _ = libc.Xstdin + coverExperiment bool ) @@ -201,9 +205,11 @@ char *__builtin___strncpy_chk(char *dest, char *src, size_t n, size_t os); char *__builtin_strchr(const char *s, int c); char *__builtin_strcpy(char *dest, const char *src); double __builtin_copysign ( double x, double y ); +double __builtin_copysignl (long double x, long double y ); double __builtin_fabs(double x); double __builtin_huge_val (void); double __builtin_inf (void); +double __builtin_nan (const char *str); float __builtin_copysignf ( float x, float y ); float __builtin_huge_valf (void); float __builtin_inff (void); @@ -214,18 +220,23 @@ int __builtin___vsnprintf_chk (char *s, size_t maxlen, int flag, size_t os, cons int __builtin__snprintf_chk(char * str, size_t maxlen, int flag, size_t strlen, const char * format); int __builtin_abs(int j); int __builtin_add_overflow(); +int __builtin_clz (unsigned); +int __builtin_clzl (unsigned long); int __builtin_clzll (unsigned long long); int __builtin_constant_p_impl(int, ...); +int __builtin_getentropy(void*, size_t); int __builtin_isnan(double); int __builtin_memcmp(const void *s1, const void *s2, size_t n); int __builtin_mul_overflow(); int __builtin_popcount (unsigned int x); +int __builtin_popcountl (unsigned long x); int __builtin_printf(const char *format, ...); int __builtin_snprintf(char *str, size_t size, const char *format, ...); int __builtin_sprintf(char *str, const char *format, ...); int __builtin_strcmp(const char *s1, const char *s2); int __builtin_sub_overflow(); long __builtin_expect (long exp, long c); +long double __builtin_nanl (const char *str); long long __builtin_llabs(long long j); size_t __builtin_object_size (void * ptr, int type); size_t __builtin_strlen(const char *s); @@ -243,9 +254,30 @@ void __builtin_free(void *ptr); void __builtin_prefetch (const void *addr, ...); void __builtin_trap (void); void __builtin_unreachable (void); +void __ccgo_dmesg(char*, ...); void __ccgo_va_end(__builtin_va_list ap); void __ccgo_va_start(__builtin_va_list ap); +#define __sync_add_and_fetch(ptr, val) \ + __builtin_choose_expr( \ + __builtin_types_compatible_p(typeof(*ptr), unsigned), \ + __sync_add_and_fetch_uint32(ptr, val), \ + __TODO__ \ + ) + +#define __sync_fetch_and_add(ptr, val) \ + __TODO__ \ + +#define __sync_sub_and_fetch(ptr, val) \ + __builtin_choose_expr( \ + __builtin_types_compatible_p(typeof(*ptr), unsigned), \ + __sync_sub_and_fetch_uint32(ptr, val), \ + __TODO__ \ + ) + +unsigned __sync_add_and_fetch_uint32(unsigned*, unsigned); +unsigned __sync_sub_and_fetch_uint32(unsigned*, unsigned); + ` defaultCrt = "modernc.org/libc" ) @@ -296,8 +328,7 @@ func trc(s string, args ...interface{}) string { //TODO- default: s = fmt.Sprintf(s, args...) } - _, fn, fl, _ := runtime.Caller(1) - r := fmt.Sprintf("%s:%d: TRC %s", fn, fl, s) + r := fmt.Sprintf("%s: TRC %s", origin(2), s) fmt.Fprintf(os.Stdout, "%s\n", r) os.Stdout.Sync() return r @@ -313,6 +344,8 @@ type Task struct { args []string asts []*cc.AST capif string + saveConfig string // -save-config + saveConfigErr error cc string // $CC, default "gcc" ccLookPath string // LookPath(cc) cdb string // foo.json, use compile DB @@ -331,9 +364,14 @@ type Task struct { hide map[string]struct{} // -hide hostConfigCmd string // -host-config-cmd hostConfigOpts string // -host-config-opts - ignoredIncludes string // -ignored-includes + hostIncludes []string + hostPredefined string + hostSysIncludes []string + ignoredIncludes string // -ignored-includes imported []*imported + includedFiles map[string]struct{} l []string // -l + loadConfig string // --load-config o string // -o out io.Writer pkgName string // -pkgname @@ -346,6 +384,7 @@ type Task struct { stderr io.Writer stdout io.Writer symSearchOrder []int // >= 0: asts[i], < 0 : imported[-i-1] + verboseCompiledb bool // -verbose-compiledb volatiles map[cc.StringID]struct{} // -volatile // Path to a binary that will be called instead of executing @@ -359,6 +398,8 @@ type Task struct { E bool // -E allErrors bool // -all-errors compiledbValid bool // -compiledb present + configSaved bool + configured bool // hostPredefined, hostIncludes, hostSysIncludes are valid cover bool // -cover-instrumentation coverC bool // -cover-instrumentation-c defaultUnExport bool // -unexported-by-default @@ -372,6 +413,7 @@ type Task struct { fullPathComments bool // -full-path-comments funcSig bool // -func-sig header bool // -header + ignoreUndefined bool // -ignoreUndefined isScripted bool mingw bool noCapi bool // -nocapi @@ -575,14 +617,23 @@ func (t *Task) capi2(files []string) (pkgName string, exports map[string]struct{ // Main executes task. func (t *Task) Main() (err error) { + // trc("%p: %q", t, t.args) if dmesgs { defer func() { if err != nil { + // trc("FAIL %p: %q: %v", t, t.args, err) dmesg("%v: returning from Task.Main: %v", origin(1), err) } }() } + + defer func() { + if t.saveConfigErr != nil && err == nil { + err = t.saveConfigErr + } + }() + if !t.isScripted && coverExperiment { defer func() { fmt.Fprintf(os.Stderr, "cover report:\n%s\n", coverReport()) @@ -630,24 +681,105 @@ func (t *Task) Main() (err error) { opts.Opt("full-path-comments", func(opt string) error { t.fullPathComments = true; return nil }) opts.Opt("func-sig", func(opt string) error { t.funcSig = true; return nil }) opts.Opt("header", func(opt string) error { t.header = true; return nil }) + opts.Opt("ignore-undefined", func(opt string) error { t.ignoreUndefined = true; return nil }) opts.Opt("nocapi", func(opt string) error { t.noCapi = true; return nil }) opts.Opt("nostdinc", func(opt string) error { t.nostdinc = true; return nil }) opts.Opt("panic-stubs", func(opt string) error { t.panicStubs = true; return nil }) - opts.Opt("trace-translation-units", func(opt string) error { t.traceTranslationUnits = true; return nil }) opts.Opt("trace-pinning", func(opt string) error { t.tracePinning = true; return nil }) + opts.Opt("trace-translation-units", func(opt string) error { t.traceTranslationUnits = true; return nil }) opts.Opt("unexported-by-default", func(opt string) error { t.defaultUnExport = true; return nil }) + opts.Opt("verbose-compiledb", func(opt string) error { t.verboseCompiledb = true; return nil }) opts.Opt("verify-structs", func(opt string) error { t.verifyStructs = true; return nil }) opts.Opt("version", func(opt string) error { t.version = true; return nil }) opts.Opt("watch-instrumentation", func(opt string) error { t.watch = true; return nil }) opts.Opt("windows", func(opt string) error { t.windows = true; return nil }) + opts.Opt("trace-included-files", func(opt string) error { + if t.includedFiles == nil { + t.includedFiles = map[string]struct{}{} + } + prev := t.cfg.IncludeFileHandler + t.cfg.IncludeFileHandler = func(pos token.Position, pathName string) { + if prev != nil { + prev(pos, pathName) + } + if _, ok := t.includedFiles[pathName]; !ok { + t.includedFiles[pathName] = struct{}{} + fmt.Fprintf(os.Stderr, "#include %s\n", pathName) + } + } + return nil + }) + opts.Arg("save-config", false, func(arg, value string) error { + if value == "" { + return nil + } + + abs, err := filepath.Abs(value) + if err != nil { + return err + } + + t.saveConfig = abs + if t.includedFiles == nil { + t.includedFiles = map[string]struct{}{} + } + prev := t.cfg.IncludeFileHandler + t.cfg.IncludeFileHandler = func(pos token.Position, pathName string) { + if prev != nil { + prev(pos, pathName) + } + if _, ok := t.includedFiles[pathName]; !ok { + t.includedFiles[pathName] = struct{}{} + full := filepath.Join(abs, pathName) + switch _, err := os.Stat(full); { + case err != nil && os.IsNotExist(err): + // ok + case err != nil: + t.saveConfigErr = err + return + default: + return + } + + b, err := ioutil.ReadFile(pathName) + if err != nil { + t.saveConfigErr = err + return + } + + dir, _ := filepath.Split(full) + if err := os.MkdirAll(dir, 0700); err != nil { + t.saveConfigErr = err + return + } + + if err := ioutil.WriteFile(full, b, 0600); err != nil { + t.saveConfigErr = err + } + } + } + return nil + }) + opts.Arg("-load-config", false, func(arg, value string) error { + if value == "" { + return nil + } + + abs, err := filepath.Abs(value) + if err != nil { + return err + } + + t.loadConfig = abs + return nil + }) opts.Arg("volatile", false, func(arg, value string) error { for _, v := range strings.Split(strings.TrimSpace(value), ",") { t.volatiles[cc.String(v)] = struct{}{} } return nil }) - opts.Opt("nostdlib", func(opt string) error { t.nostdlib = true t.crt = "" @@ -711,6 +843,10 @@ func (t *Task) Main() (err error) { return t.createCompileDB(cmd) case t.cdb != "": // foo.json ..., use DB + if err := t.configure(); err != nil { + return err + } + return t.useCompileDB(t.cdb, x) } @@ -721,6 +857,20 @@ func (t *Task) Main() (err error) { } if t.version { + gobin, err := exec.LookPath("go") + var b []byte + if err == nil { + var bin string + bin, err = exec.LookPath(os.Args[0]) + if err == nil { + b, err = exec.Command(gobin, "version", "-m", bin).CombinedOutput() + } + } + if err == nil { + fmt.Fprintf(t.stdout, "%s", b) + return nil + } + fmt.Fprintf(t.stdout, "%s\n", Version) return nil } @@ -746,7 +896,13 @@ func (t *Task) Main() (err error) { } t.imported[len(t.imported)-1].used = true // crt is always imported } + + if err := t.configure(); err != nil { + return err + } + abi, err := cc.NewABI(t.goos, t.goarch) + abi.Types[cc.LongDouble] = abi.Types[cc.Double] if err != nil { return err } @@ -764,27 +920,19 @@ func (t *Task) Main() (err error) { t.cfg.ReplaceMacroTclIeeeDoubleRounding = t.replaceTclIeeeDoubleRounding t.cfg.Config3.IgnoreInclude = re t.cfg.Config3.NoFieldAndBitfieldOverlap = true - t.cfg.Config3.PreserveWhiteSpace = true + t.cfg.Config3.PreserveWhiteSpace = t.saveConfig == "" t.cfg.Config3.UnsignedEnums = true - hostConfigOpts := strings.Split(t.hostConfigOpts, ",") - if t.hostConfigOpts == "" { - hostConfigOpts = nil - } - hostPredefined, hostIncludes, hostSysIncludes, err := cc.HostConfig(t.hostConfigCmd, hostConfigOpts...) - if err != nil { - return err - } - if t.mingw = detectMingw(hostPredefined); t.mingw { + if t.mingw = detectMingw(t.hostPredefined); t.mingw { t.windows = true } if t.nostdinc { - hostIncludes = nil - hostSysIncludes = nil + t.hostIncludes = nil + t.hostSysIncludes = nil } var sources []cc.Source - if hostPredefined != "" { - sources = append(sources, cc.Source{Name: "<predefined>", Value: hostPredefined}) + if t.hostPredefined != "" { + sources = append(sources, cc.Source{Name: "<predefined>", Value: t.hostPredefined}) } sources = append(sources, cc.Source{Name: "<builtin>", Value: builtin}) if len(t.D) != 0 { @@ -816,12 +964,12 @@ func (t *Task) Main() (err error) { // line, then in directories named in -I options, and last in the usual // places includePaths := append([]string{"@"}, t.I...) - includePaths = append(includePaths, hostIncludes...) - includePaths = append(includePaths, hostSysIncludes...) + includePaths = append(includePaths, t.hostIncludes...) + includePaths = append(includePaths, t.hostSysIncludes...) // For headers whose names are enclosed in angle brackets ( "<>" ), the // header shall be searched for only in directories named in -I options // and then in the usual places. - sysIncludePaths := append(t.I, hostSysIncludes...) + sysIncludePaths := append(t.I, t.hostSysIncludes...) if t.traceTranslationUnits { fmt.Printf("target: %s/%s\n", t.goos, t.goarch) if t.hostConfigCmd != "" { @@ -830,11 +978,17 @@ func (t *Task) Main() (err error) { } for i, v := range t.sources { tuSources := append(sources, v) + out := t.stdout + if t.saveConfig != "" { + out = io.Discard + t.E = true + } if t.E { t.cfg.PreprocessOnly = true - if err := cc.Preprocess(t.cfg, includePaths, sysIncludePaths, tuSources, t.stdout); err != nil { + if err := cc.Preprocess(t.cfg, includePaths, sysIncludePaths, tuSources, out); err != nil { return err } + memGuard(i, t.isScripted) continue } @@ -861,6 +1015,81 @@ func (t *Task) Main() (err error) { return t.link() } +func (t *Task) configure() (err error) { + if t.configured { + return nil + } + + type jsonConfig struct { + Predefined string + IncludePaths []string + SysIncludePaths []string + OS string + Arch string + } + + t.configured = true + if t.loadConfig != "" { + path := filepath.Join(t.loadConfig, "config.json") + // trc("%p: LOAD_CONFIG(%s)", t, path) + b, err := ioutil.ReadFile(path) + if err != nil { + return err + } + + loadConfig := &jsonConfig{} + if err := json.Unmarshal(b, loadConfig); err != nil { + return err + } + + t.goos = loadConfig.OS + t.goarch = loadConfig.Arch + for _, v := range loadConfig.IncludePaths { + t.hostIncludes = append(t.hostIncludes, filepath.Join(t.loadConfig, v)) + } + for _, v := range loadConfig.SysIncludePaths { + t.hostSysIncludes = append(t.hostSysIncludes, filepath.Join(t.loadConfig, v)) + } + t.hostPredefined = loadConfig.Predefined + return nil + } + + hostConfigOpts := strings.Split(t.hostConfigOpts, ",") + if t.hostConfigOpts == "" { + hostConfigOpts = nil + } + if t.hostPredefined, t.hostIncludes, t.hostSysIncludes, err = cc.HostConfig(t.hostConfigCmd, hostConfigOpts...); err != nil { + return err + } + + if t.saveConfig != "" && !t.configSaved { + t.configSaved = true + // trc("%p: SAVE_CONFIG(%s)", t, t.saveConfig) + cfg := &jsonConfig{ + Predefined: t.hostPredefined, + IncludePaths: t.hostIncludes, + SysIncludePaths: t.hostSysIncludes, + OS: t.goos, + Arch: t.goarch, + } + b, err := json.Marshal(cfg) + if err != nil { + return err + } + + full := filepath.Join(t.saveConfig, "config.json") + if err := os.MkdirAll(t.saveConfig, 0700); err != nil { + return err + } + + if err := ioutil.WriteFile(full, b, 0600); err != nil { + return err + } + } + + return nil +} + func (t *Task) setLookPaths() (err error) { if t.ccLookPath, err = exec.LookPath(t.cc); err != nil { return err @@ -955,11 +1184,20 @@ func (t *Task) scriptBuild2(script [][]string) error { fmt.Printf("%s\n", cmd) } t2 := NewTask(append(ccgo, args...), t.stdout, t.stderr) + t2.cfg.IncludeFileHandler = t.cfg.IncludeFileHandler t2.cfg.SharedFunctionDefinitions = t.cfg.SharedFunctionDefinitions + t2.configSaved = t.configSaved + t2.configured = t.configured + t2.hostIncludes = t.hostIncludes + t2.hostPredefined = t.hostPredefined + t2.hostSysIncludes = t.hostSysIncludes + t2.includedFiles = t.includedFiles + t2.isScripted = true + t2.loadConfig = t.loadConfig t2.replaceFdZero = t.replaceFdZero t2.replaceTclDefaultDoubleRounding = t.replaceTclDefaultDoubleRounding t2.replaceTclIeeeDoubleRounding = t.replaceTclIeeeDoubleRounding - t2.isScripted = true + t2.saveConfig = t.saveConfig if err := inDir(dir, t2.Main); err != nil { return err } @@ -982,6 +1220,10 @@ func (t *Task) scriptBuild2(script [][]string) error { } t.imported[len(t.imported)-1].used = true // crt is always imported } + if t.saveConfig != "" { + return nil + } + return t.link() } @@ -990,7 +1232,8 @@ type cdb struct { outputIndex map[string][]*cdbItem } -func (db *cdb) find(obj map[string]*cdbItem, nm string, ver, seqLimit int, trace bool, path []string, cc, ar string) error { +func (db *cdb) find(obj map[string]*cdbItem, nm string, ver, seqLimit int, path []string, cc, ar string) error { + // trc("%v: nm %q ver %v seqLimit %v path %q cc %q ar %q", origin(1), nm, ver, seqLimit, path, cc, ar) var item *cdbItem var k string switch { @@ -1059,7 +1302,7 @@ func (db *cdb) find(obj map[string]*cdbItem, nm string, ver, seqLimit int, trace obj[k] = item var errs []string for _, v := range item.sources(cc, ar) { - if err := db.find(obj, v, -1, item.seq, trace, append(path, nm), cc, ar); err != nil { + if err := db.find(obj, v, -1, item.seq, append(path, nm), cc, ar); err != nil { errs = append(errs, err.Error()) } } @@ -1137,7 +1380,7 @@ func (t *Task) useCompileDB(fn string, args []string) error { notFound := false for _, v := range args { v, ver := suffixNum(v, 0) - if err := cdb.find(obj, v, ver, -1, t.traceTranslationUnits, nil, t.ccLookPath, t.arLookPath); err != nil { + if err := cdb.find(obj, v, ver, -1, nil, t.ccLookPath, t.arLookPath); err != nil { notFound = true fmt.Fprintln(os.Stderr, err) } @@ -1174,6 +1417,13 @@ func (t *Task) cdbBuild(obj map[string]*cdbItem, list []string) error { return err } + for _, v := range t.D { + args = append(args, "-D"+v) + } + for _, v := range t.U { + args = append(args, "-U"+v) + } + line := append([]string{it.Directory}, args...) script = append(script, line) } @@ -1212,9 +1462,12 @@ func (t *Task) createCompileDB(command []string) (rerr error) { var cmd *exec.Cmd var parser func(s string) ([]string, error) out: - switch { - case t.goos == "darwin", t.goos == "freebsd": - if command[0] != "make" { + switch t.goos { + case "darwin", "freebsd", "netbsd": + switch command[0] { + case "make", "gmake": + // ok + default: return fmt.Errorf("usupported build command: %s", command[0]) } @@ -1226,7 +1479,7 @@ out: command = append([]string{sh, "-c"}, join(" ", command[0], "SHELL='sh -x'", command[1:])) cmd = exec.Command(command[0], command[1:]...) parser = makeXParser - case t.goos == "windows": + case "windows": if command[0] != "make" { return fmt.Errorf("usupported build command: %s", command[0]) } @@ -1257,7 +1510,12 @@ out: } cmd.Env = append(os.Environ(), "LC_ALL=C") cw := t.newCdbMakeWriter(cwr, cwd, parser) - cmd.Stdout = io.MultiWriter(cw, os.Stdout) + switch { + case t.verboseCompiledb: + cmd.Stdout = io.MultiWriter(cw, os.Stdout) + default: + cmd.Stdout = cw + } cmd.Stderr = cmd.Stdout if dmesgs { dmesg("%v: %v", origin(1), cmd.Args) @@ -1317,12 +1575,32 @@ func isCreateArchive(s string) bool { return false } -func makeXParser(s string) ([]string, error) { - if !strings.HasPrefix(s, "+ ") { +func hasPlusPrefix(s string) (n int, r string) { + for strings.HasPrefix(s, "+") { + n++ + s = s[1:] + } + return n, s +} + +func makeXParser(s string) (r []string, err error) { + n, s := hasPlusPrefix(s) + if n == 0 { return nil, nil } - return shellquote.Split(s[2:]) + if !strings.HasPrefix(s, " ") { + return nil, nil + } + + s = s[1:] + r, err = shellquote.Split(s) + if err != nil { + if strings.Contains(err.Error(), "Unterminated single-quoted string") { + return nil, nil // ignore + } + } + return r, err } func straceParser(s string) ([]string, error) { @@ -1393,12 +1671,16 @@ func (it *cdbItem) ccgoArgs(cc string) (r []string, err error) { set.Arg("o", true, func(opt, arg string) error { return nil }) set.Arg("std", true, func(opt, arg string) error { return nil }) set.Opt("MD", func(opt string) error { return nil }) + set.Opt("MMD", func(opt string) error { return nil }) set.Opt("MP", func(opt string) error { return nil }) + set.Opt("ansi", func(opt string) error { return nil }) set.Opt("c", func(opt string) error { return nil }) set.Opt("g", func(opt string) error { return nil }) set.Opt("pedantic", func(opt string) error { return nil }) set.Opt("pipe", func(opt string) error { return nil }) set.Opt("pthread", func(opt string) error { return nil }) + set.Opt("s", func(opt string) error { return nil }) + set.Opt("w", func(opt string) error { return nil }) if err := set.Parse(it.Arguments[1:], func(arg string) error { switch { case strings.HasSuffix(arg, ".c"): @@ -1411,7 +1693,7 @@ func (it *cdbItem) ccgoArgs(cc string) (r []string, err error) { // nop default: - return fmt.Errorf("unknown/unsupported option: %s", arg) + return fmt.Errorf("unknown/unsupported CC option: %s", arg) } return nil @@ -1470,7 +1752,7 @@ func (it *cdbItem) sources(cc, ar string) (r []string) { return nil } - switch it.Arguments[0] { + switch arg0 := it.Arguments[0]; arg0 { case "libtool", ar, @@ -1478,8 +1760,13 @@ func (it *cdbItem) sources(cc, ar string) (r []string) { var prev string for _, v := range it.Arguments { - if prev != "-o" && strings.HasSuffix(v, ".o") { - r = append(r, filepath.Join(it.Directory, v)) + switch prev { + case "-o", "-MT", "-MF": + // nop + default: + if strings.HasSuffix(v, ".o") { + r = append(r, filepath.Join(it.Directory, v)) + } } prev = v } @@ -1517,7 +1804,7 @@ func (t *Task) newCdbMakeWriter(w *cdbWriter, dir string, parser func(s string) func (w *cdbMakeWriter) fail(err error) { if w.err == nil { - w.err = err + w.err = fmt.Errorf("%v (%v)", err, origin(2)) } } |