aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Burgess IV <gbiv@google.com>2020-07-20 16:53:39 -0700
committerGeorge Burgess <gbiv@chromium.org>2020-07-22 16:43:35 +0000
commitcb46500d29085ee65b524981f0fbf4af3badc0bb (patch)
treeb7286ea46ca78cfa7cb79a718fe13d0f111ea4f9
parent6c2e5c4448ade8e7764d3ebfb8a168441f59cf92 (diff)
downloadtoolchain-utils-cb46500d29085ee65b524981f0fbf4af3badc0bb.tar.gz
compiler_wrapper: add -clang-tidy-flag support
This CL adds support for specifying compiler flags that're meant to be passed only to clang-tidy. This allows for easier local experimentation with clang-tidy by users. BUG=chromium:982944 TEST=`WITH_TIDY=1 emerge-amd64-generic biod` with custom cflags; cq+1 on crrev.com/c/2308774 Change-Id: I654559d14a78ade4920fe37757fb5b249a997290 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/toolchain-utils/+/2309152 Reviewed-by: Caroline Tice <cmtice@chromium.org> Tested-by: George Burgess <gbiv@chromium.org>
-rw-r--r--compiler_wrapper/clang_tidy_flag.go30
-rw-r--r--compiler_wrapper/clang_tidy_flag_test.go53
-rw-r--r--compiler_wrapper/compiler_wrapper.go80
3 files changed, 115 insertions, 48 deletions
diff --git a/compiler_wrapper/clang_tidy_flag.go b/compiler_wrapper/clang_tidy_flag.go
index edbbb412..2d97ddd3 100644
--- a/compiler_wrapper/clang_tidy_flag.go
+++ b/compiler_wrapper/clang_tidy_flag.go
@@ -21,10 +21,20 @@ const (
tidyModeTricium
)
-func processClangTidyFlags(builder *commandBuilder) (cSrcFile string, mode useTidyMode) {
+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 ""
+ })
+
withTidy, _ := builder.env.getenv("WITH_TIDY")
if withTidy == "" {
- return "", tidyModeNone
+ return "", clangTidyFlags, tidyModeNone
}
srcFileSuffixes := []string{
".c",
@@ -51,7 +61,7 @@ func processClangTidyFlags(builder *commandBuilder) (cSrcFile string, mode useTi
}
if cSrcFile == "" {
- return "", tidyModeNone
+ return "", clangTidyFlags, tidyModeNone
}
if withTidy == "tricium" {
@@ -65,7 +75,7 @@ func processClangTidyFlags(builder *commandBuilder) (cSrcFile string, mode useTi
} else {
mode = tidyModeAll
}
- return cSrcFile, mode
+ return cSrcFile, clangTidyFlags, mode
}
func calcClangTidyInvocation(env env, clangCmd *command, cSrcFile string, tidyFlags ...string) (*command, error) {
@@ -85,7 +95,7 @@ func calcClangTidyInvocation(env env, clangCmd *command, cSrcFile string, tidyFl
}, nil
}
-func runClangTidyForTricium(env env, clangCmd *command, cSrcFile, fixesDir string) error {
+func runClangTidyForTricium(env env, clangCmd *command, cSrcFile, fixesDir string, extraTidyFlags []string) error {
if err := os.MkdirAll(fixesDir, 0777); err != nil {
return fmt.Errorf("creating fixes directory at %q: %v", fixesDir, err)
}
@@ -103,7 +113,8 @@ func runClangTidyForTricium(env env, clangCmd *command, cSrcFile, fixesDir strin
// 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=*`.
- clangTidyCmd, err := calcClangTidyInvocation(env, clangCmd, cSrcFile, "-checks=*", "--export-fixes="+fixesFilePath)
+ 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)
}
@@ -149,9 +160,9 @@ func runClangTidyForTricium(env env, clangCmd *command, cSrcFile, fixesDir strin
return nil
}
-func runClangTidy(env env, clangCmd *command, cSrcFile string) error {
- clangTidyCmd, err := calcClangTidyInvocation(env, clangCmd, cSrcFile, "-checks="+
- strings.Join([]string{
+func runClangTidy(env env, clangCmd *command, cSrcFile string, extraTidyFlags []string) error {
+ extraTidyFlags = append(extraTidyFlags,
+ "-checks="+strings.Join([]string{
"*",
"-bugprone-narrowing-conversions",
"-cppcoreguidelines-*",
@@ -165,6 +176,7 @@ func runClangTidy(env env, clangCmd *command, cSrcFile string) error {
"-modernize-*",
"-readability-*",
}, ","))
+ clangTidyCmd, err := calcClangTidyInvocation(env, clangCmd, cSrcFile, extraTidyFlags...)
if err != nil {
return fmt.Errorf("calculating clang-tidy invocation: %v", err)
}
diff --git a/compiler_wrapper/clang_tidy_flag_test.go b/compiler_wrapper/clang_tidy_flag_test.go
index d45d1bdd..54159cdc 100644
--- a/compiler_wrapper/clang_tidy_flag_test.go
+++ b/compiler_wrapper/clang_tidy_flag_test.go
@@ -333,6 +333,59 @@ func TestTriciumClangTidySkipsProtobufFiles(t *testing.T) {
})
}
+func testClangTidyFiltersClangTidySpecificFlagsWithPresetEnv(t *testing.T, ctx *testContext) {
+ addedFlag := "--some_clang_tidy=flag"
+ ctx.cmdMock = func(cmd *command, stdin io.Reader, stdout io.Writer, stderr io.Writer) error {
+ switch ctx.cmdCount {
+ case 1:
+ if err := verifyPath(cmd, "usr/bin/clang"); err != nil {
+ t.Error(err)
+ } else if err := verifyArgCount(cmd, 0, addedFlag); err != nil {
+ t.Error(err)
+ }
+ return nil
+ case 2:
+ if err := verifyPath(cmd, "usr/bin/clang-tidy"); err != nil {
+ t.Error(err)
+ } else if verifyArgCount(cmd, 1, addedFlag); err != nil {
+ t.Error(err)
+ }
+ return nil
+ default:
+ return nil
+ }
+ }
+ cmd := ctx.must(callCompiler(ctx, ctx.cfg, ctx.newCommand(clangX86_64, mainCc, "-clang-tidy-flag="+addedFlag)))
+ if ctx.cmdCount != 3 {
+ t.Errorf("expected 3 calls. Got: %d", ctx.cmdCount)
+ }
+ if err := verifyPath(cmd, "usr/bin/clang"); err != nil {
+ t.Error(err)
+ }
+}
+
+func TestClangTidyFiltersClangTidySpecificFlagsForTricium(t *testing.T) {
+ withClangTidyTestContext(t, func(ctx *testContext) {
+ ctx.env = []string{"WITH_TIDY=tricium"}
+ testClangTidyFiltersClangTidySpecificFlagsWithPresetEnv(t, ctx)
+ })
+}
+
+func TestClangTidyFiltersClangTidySpecificFlags(t *testing.T) {
+ withClangTidyTestContext(t, func(ctx *testContext) {
+ testClangTidyFiltersClangTidySpecificFlagsWithPresetEnv(t, ctx)
+ })
+}
+
+func TestClangTidyFlagsAreFilteredFromGccInvocations(t *testing.T) {
+ withTestContext(t, func(ctx *testContext) {
+ cmd := ctx.must(callCompiler(ctx, ctx.cfg, ctx.newCommand(gccX86_64, mainCc, "-clang-tidy-flag=--foo")))
+ if err := verifyArgCount(cmd, 0, ".*--foo.*"); err != nil {
+ t.Error(err)
+ }
+ })
+}
+
func withClangTidyTestContext(t *testing.T, work func(ctx *testContext)) {
withTestContext(t, func(ctx *testContext) {
ctx.env = []string{"WITH_TIDY=1"}
diff --git a/compiler_wrapper/compiler_wrapper.go b/compiler_wrapper/compiler_wrapper.go
index 14de210a..a5d35a2c 100644
--- a/compiler_wrapper/compiler_wrapper.go
+++ b/compiler_wrapper/compiler_wrapper.go
@@ -89,53 +89,55 @@ func callCompilerInternal(env env, cfg *config, inputCmd *command) (exitCode int
default:
return 0, newErrorwithSourceLocf("unsupported compiler: %s", mainBuilder.target.compiler)
}
- } else if mainBuilder.target.compilerType == clangType {
- cSrcFile, tidyMode := processClangTidyFlags(mainBuilder)
- err := prepareClangCommand(mainBuilder)
- if err != nil {
- return 0, err
- }
- allowCCache := true
- if tidyMode != tidyModeNone {
- allowCCache = false
- clangCmdWithoutGomaAndCCache := mainBuilder.build()
- var err error
- switch tidyMode {
- case tidyModeTricium:
- if cfg.triciumNitsDir == "" {
- return 0, newErrorwithSourceLocf("tricium linting was requested, but no nits directory is configured")
- }
- err = runClangTidyForTricium(env, clangCmdWithoutGomaAndCCache, cSrcFile, cfg.triciumNitsDir)
- case tidyModeAll:
- err = runClangTidy(env, clangCmdWithoutGomaAndCCache, cSrcFile)
- default:
- panic(fmt.Sprintf("Unknown tidy mode: %v", tidyMode))
- }
-
+ } else {
+ cSrcFile, tidyFlags, tidyMode := processClangTidyFlags(mainBuilder)
+ if mainBuilder.target.compilerType == clangType {
+ err := prepareClangCommand(mainBuilder)
if err != nil {
return 0, err
}
- }
- if err := processGomaCCacheFlags(allowCCache, mainBuilder); err != nil {
- return 0, err
- }
- compilerCmd = mainBuilder.build()
- } else {
- if clangSyntax {
- allowCCache := false
- clangCmd, err := calcClangCommand(allowCCache, mainBuilder.clone())
- if err != nil {
+ allowCCache := true
+ if tidyMode != tidyModeNone {
+ allowCCache = false
+ clangCmdWithoutGomaAndCCache := mainBuilder.build()
+ var err error
+ switch tidyMode {
+ case tidyModeTricium:
+ if cfg.triciumNitsDir == "" {
+ return 0, newErrorwithSourceLocf("tricium linting was requested, but no nits directory is configured")
+ }
+ err = runClangTidyForTricium(env, clangCmdWithoutGomaAndCCache, cSrcFile, cfg.triciumNitsDir, tidyFlags)
+ case tidyModeAll:
+ err = runClangTidy(env, clangCmdWithoutGomaAndCCache, cSrcFile, tidyFlags)
+ default:
+ panic(fmt.Sprintf("Unknown tidy mode: %v", tidyMode))
+ }
+
+ if err != nil {
+ return 0, err
+ }
+ }
+ if err := processGomaCCacheFlags(allowCCache, mainBuilder); err != nil {
return 0, err
}
- gccCmd, err := calcGccCommand(mainBuilder)
+ compilerCmd = mainBuilder.build()
+ } else {
+ if clangSyntax {
+ allowCCache := false
+ clangCmd, err := calcClangCommand(allowCCache, mainBuilder.clone())
+ if err != nil {
+ return 0, err
+ }
+ gccCmd, err := calcGccCommand(mainBuilder)
+ if err != nil {
+ return 0, err
+ }
+ return checkClangSyntax(env, clangCmd, gccCmd)
+ }
+ compilerCmd, err = calcGccCommand(mainBuilder)
if err != nil {
return 0, err
}
- return checkClangSyntax(env, clangCmd, gccCmd)
- }
- compilerCmd, err = calcGccCommand(mainBuilder)
- if err != nil {
- return 0, err
}
}
rusageLogfileName := getRusageLogFilename(env)