aboutsummaryrefslogtreecommitdiff
path: root/compiler_wrapper/clang_tidy_flag.go
diff options
context:
space:
mode:
Diffstat (limited to 'compiler_wrapper/clang_tidy_flag.go')
-rw-r--r--compiler_wrapper/clang_tidy_flag.go225
1 files changed, 41 insertions, 184 deletions
diff --git a/compiler_wrapper/clang_tidy_flag.go b/compiler_wrapper/clang_tidy_flag.go
index 01387fd6..40a5bdbe 100644
--- a/compiler_wrapper/clang_tidy_flag.go
+++ b/compiler_wrapper/clang_tidy_flag.go
@@ -5,39 +5,15 @@
package main
import (
- "encoding/json"
"fmt"
- "io/ioutil"
- "os"
- "path"
"path/filepath"
"strings"
)
-type useTidyMode int
-
-const clangTidyCrashSubstring = "PLEASE submit a bug report"
-
-const (
- tidyModeNone useTidyMode = iota
- tidyModeAll
- tidyModeTricium
-)
-
-func processClangTidyFlags(builder *commandBuilder) (cSrcFile string, clangTidyFlags []string, mode useTidyMode) {
- builder.transformArgs(func(arg builderArg) string {
- const prefix = "-clang-tidy-flag="
- if !strings.HasPrefix(arg.value, prefix) {
- return arg.value
- }
-
- clangTidyFlags = append(clangTidyFlags, arg.value[len(prefix):])
- return ""
- })
-
+func processClangTidyFlags(builder *commandBuilder) (cSrcFile string, useClangTidy bool) {
withTidy, _ := builder.env.getenv("WITH_TIDY")
if withTidy == "" {
- return "", clangTidyFlags, tidyModeNone
+ return "", false
}
srcFileSuffixes := []string{
".c",
@@ -48,177 +24,58 @@ func processClangTidyFlags(builder *commandBuilder) (cSrcFile string, clangTidyF
".c++",
}
cSrcFile = ""
- srcSuffix := ""
lastArg := ""
for _, arg := range builder.args {
- if lastArg != "-o" {
- for _, suffix := range srcFileSuffixes {
- if strings.HasSuffix(arg.value, suffix) {
- srcSuffix = suffix
- cSrcFile = arg.value
- break
- }
- }
+ if hasAtLeastOneSuffix(arg.value, srcFileSuffixes) && lastArg != "-o" {
+ cSrcFile = arg.value
}
lastArg = arg.value
}
-
- if cSrcFile == "" {
- return "", clangTidyFlags, tidyModeNone
- }
-
- if withTidy == "tricium" {
- // Files generated from protobufs can result in _many_ clang-tidy complaints, and aren't
- // worth linting in general. Don't.
- if strings.HasSuffix(cSrcFile, ".pb"+srcSuffix) {
- mode = tidyModeNone
- } else {
- mode = tidyModeTricium
- }
- } else {
- mode = tidyModeAll
- }
- return cSrcFile, clangTidyFlags, mode
+ useClangTidy = cSrcFile != ""
+ return cSrcFile, useClangTidy
}
-func calcClangTidyInvocation(env env, clangCmd *command, cSrcFile string, tidyFlags ...string) (*command, error) {
+func runClangTidy(env env, clangCmd *command, cSrcFile string) error {
+ defaultTidyChecks := strings.Join([]string{
+ "*",
+ "google*",
+ "-bugprone-narrowing-conversions",
+ "-cppcoreguidelines-*",
+ "-fuchsia-*",
+ "-google-build-using-namespace",
+ "-google-default-arguments",
+ "-google-explicit-constructor",
+ "-google-readability*",
+ "-google-runtime-int",
+ "-google-runtime-references",
+ "-hicpp-avoid-c-arrays",
+ "-hicpp-braces-around-statements",
+ "-hicpp-no-array-decay",
+ "-hicpp-signed-bitwise",
+ "-hicpp-uppercase-literal-suffix",
+ "-hicpp-use-auto",
+ "-llvm-namespace-comment",
+ "-misc-non-private-member-variables-in-classes",
+ "-misc-unused-parameters",
+ "-modernize-*",
+ "-readability-*",
+ }, ",")
+
resourceDir, err := getClangResourceDir(env, clangCmd.Path)
if err != nil {
- return nil, err
+ return err
}
clangTidyPath := filepath.Join(filepath.Dir(clangCmd.Path), "clang-tidy")
- args := append([]string{}, tidyFlags...)
- args = append(args, cSrcFile, "--", "-resource-dir="+resourceDir)
- args = append(args, clangCmd.Args...)
- return &command{
- Path: clangTidyPath,
- Args: args,
+ clangTidyCmd := &command{
+ Path: clangTidyPath,
+ Args: append([]string{
+ "-checks=" + defaultTidyChecks,
+ cSrcFile,
+ "--",
+ "-resource-dir=" + resourceDir,
+ }, clangCmd.Args...),
EnvUpdates: clangCmd.EnvUpdates,
- }, nil
-}
-
-func runClangTidyForTricium(env env, clangCmd *command, cSrcFile, fixesDir string, extraTidyFlags []string, crashArtifactsDir string) error {
- if err := os.MkdirAll(fixesDir, 0777); err != nil {
- return fmt.Errorf("creating fixes directory at %q: %v", fixesDir, err)
- }
-
- f, err := ioutil.TempFile(fixesDir, "lints-")
- if err != nil {
- return fmt.Errorf("making tempfile for tidy: %v", err)
- }
- f.Close()
-
- // `f` is an 'anchor'; it ensures we won't create a similarly-named file in the future.
- // Hence, we can't delete it.
- fixesFilePath := f.Name() + ".yaml"
- fixesMetadataPath := f.Name() + ".json"
-
- // FIXME(gbiv): Remove `-checks=*` when testing is complete; we should defer to .clang-tidy
- // files, which are both more expressive and more approachable than `-checks=*`.
- extraTidyFlags = append(extraTidyFlags, "-checks=*", "--export-fixes="+fixesFilePath)
- clangTidyCmd, err := calcClangTidyInvocation(env, clangCmd, cSrcFile, extraTidyFlags...)
- if err != nil {
- return fmt.Errorf("calculating tidy invocation: %v", err)
- }
-
- stdstreams := &strings.Builder{}
- // Note: We pass nil as stdin as we checked before that the compiler
- // was invoked with a source file argument.
- exitCode, err := wrapSubprocessErrorWithSourceLoc(clangTidyCmd,
- env.run(clangTidyCmd, nil, stdstreams, stdstreams))
- if err != nil {
- return err
- }
-
- type crashOutput struct {
- CrashReproducerPath string `json:"crash_reproducer_path"`
- Stdstreams string `json:"stdstreams"`
- }
-
- type metadata struct {
- Args []string `json:"args"`
- CrashOutput *crashOutput `json:"crash_output"`
- Executable string `json:"executable"`
- ExitCode int `json:"exit_code"`
- LintTarget string `json:"lint_target"`
- Stdstreams string `json:"stdstreams"`
- Wd string `json:"wd"`
- }
-
- meta := &metadata{
- Args: clangTidyCmd.Args,
- CrashOutput: nil,
- Executable: clangTidyCmd.Path,
- ExitCode: exitCode,
- LintTarget: cSrcFile,
- Stdstreams: stdstreams.String(),
- Wd: env.getwd(),
- }
-
- // Sometimes, clang-tidy crashes. Unfortunately, these don't get funnelled through the
- // standard clang crash machinery. :(. Try to work with our own.
- if crashArtifactsDir != "" && strings.Contains(meta.Stdstreams, clangTidyCrashSubstring) {
- tidyCrashArtifacts := path.Join(crashArtifactsDir, "clang-tidy")
- if err := os.MkdirAll(tidyCrashArtifacts, 0777); err != nil {
- return fmt.Errorf("creating crash artifacts directory at %q: %v", tidyCrashArtifacts, err)
- }
-
- f, err := ioutil.TempFile(tidyCrashArtifacts, "crash-")
- if err != nil {
- return fmt.Errorf("making tempfile for crash output: %v", err)
- }
- f.Close()
-
- reproCmd := &command{}
- *reproCmd = *clangCmd
- reproCmd.Args = append(reproCmd.Args, "-E", "-o", f.Name())
-
- reproOut := &strings.Builder{}
- _, err = wrapSubprocessErrorWithSourceLoc(reproCmd, env.run(reproCmd, nil, reproOut, reproOut))
- if err != nil {
- return fmt.Errorf("attempting to produce a clang-tidy crash reproducer: %v", err)
- }
- meta.CrashOutput = &crashOutput{
- CrashReproducerPath: f.Name(),
- Stdstreams: reproOut.String(),
- }
- }
-
- f, err = os.Create(fixesMetadataPath)
- if err != nil {
- return fmt.Errorf("creating fixes metadata: %v", err)
- }
-
- if err := json.NewEncoder(f).Encode(meta); err != nil {
- return fmt.Errorf("writing fixes metadata: %v", err)
- }
-
- if err := f.Close(); err != nil {
- return fmt.Errorf("finalizing fixes metadata: %v", err)
- }
- return nil
-}
-
-func runClangTidy(env env, clangCmd *command, cSrcFile string, extraTidyFlags []string) error {
- extraTidyFlags = append(extraTidyFlags,
- "-checks="+strings.Join([]string{
- "*",
- "-bugprone-narrowing-conversions",
- "-cppcoreguidelines-*",
- "-fuchsia-*",
- "-google-readability*",
- "-google-runtime-references",
- "-hicpp-*",
- "-llvm-*",
- "-misc-non-private-member-variables-in-classes",
- "-misc-unused-parameters",
- "-modernize-*",
- "-readability-*",
- }, ","))
- clangTidyCmd, err := calcClangTidyInvocation(env, clangCmd, cSrcFile, extraTidyFlags...)
- if err != nil {
- return fmt.Errorf("calculating clang-tidy invocation: %v", err)
}
// Note: We pass nil as stdin as we checked before that the compiler