aboutsummaryrefslogtreecommitdiff
path: root/compiler_wrapper/clang_tidy_flag.go
blob: 40a5bdbe62b334a1204677858b0e819753cb85bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// 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
}