// Copyright 2019 The Chromium OS Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. package main import ( "fmt" "path/filepath" "strings" ) func processClangTidyFlags(builder *commandBuilder) (cSrcFile string, useClangTidy bool) { withTidy, _ := builder.env.getenv("WITH_TIDY") if withTidy == "" { return "", false } srcFileSuffixes := []string{ ".c", ".cc", ".cpp", ".C", ".cxx", ".c++", } cSrcFile = "" lastArg := "" for _, arg := range builder.args { if hasAtLeastOneSuffix(arg.value, srcFileSuffixes) && lastArg != "-o" { cSrcFile = arg.value } lastArg = arg.value } useClangTidy = cSrcFile != "" return cSrcFile, useClangTidy } 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 err } clangTidyPath := filepath.Join(filepath.Dir(clangCmd.Path), "clang-tidy") clangTidyCmd := &command{ Path: clangTidyPath, Args: append([]string{ "-checks=" + defaultTidyChecks, cSrcFile, "--", "-resource-dir=" + resourceDir, }, clangCmd.Args...), EnvUpdates: clangCmd.EnvUpdates, } // 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, env.stdout(), env.stderr())) if err == nil && exitCode != 0 { // Note: We continue on purpose when clang-tidy fails // to maintain compatibility with the previous wrapper. fmt.Fprint(env.stderr(), "clang-tidy failed") } return err } func hasAtLeastOneSuffix(s string, suffixes []string) bool { for _, suffix := range suffixes { if strings.HasSuffix(s, suffix) { return true } } return false }