1// Copyright 2016 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package config 16 17import ( 18 "android/soong/android" 19 "strings" 20) 21 22func init() { 23 // Many clang-tidy checks like altera-*, llvm-*, modernize-* 24 // are not designed for Android source code or creating too 25 // many (false-positive) warnings. The global default tidy checks 26 // should include only tested groups and exclude known noisy checks. 27 // See https://clang.llvm.org/extra/clang-tidy/checks/list.html 28 pctx.VariableFunc("TidyDefaultGlobalChecks", func(ctx android.PackageVarContext) string { 29 if override := ctx.Config().Getenv("DEFAULT_GLOBAL_TIDY_CHECKS"); override != "" { 30 return override 31 } 32 checks := strings.Join([]string{ 33 "-*", 34 "android-*", 35 "bugprone-*", 36 "cert-*", 37 "clang-diagnostic-unused-command-line-argument", 38 "google-*", 39 "misc-*", 40 "performance-*", 41 "portability-*", 42 "-bugprone-easily-swappable-parameters", 43 "-bugprone-narrowing-conversions", 44 "-google-readability*", 45 "-google-runtime-references", 46 "-misc-no-recursion", 47 "-misc-non-private-member-variables-in-classes", 48 "-misc-unused-parameters", 49 // the following groups are excluded by -* 50 // -altera-* 51 // -cppcoreguidelines-* 52 // -darwin-* 53 // -fuchsia-* 54 // -hicpp-* 55 // -llvm-* 56 // -llvmlibc-* 57 // -modernize-* 58 // -mpi-* 59 // -objc-* 60 // -readability-* 61 // -zircon-* 62 }, ",") 63 // clang-analyzer-* checks are too slow to be in the default for WITH_TIDY=1. 64 // nightly builds add CLANG_ANALYZER_CHECKS=1 to run those checks. 65 // The insecureAPI.DeprecatedOrUnsafeBufferHandling warning does not apply to Android. 66 if ctx.Config().IsEnvTrue("CLANG_ANALYZER_CHECKS") { 67 checks += ",clang-analyzer-*,-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling" 68 } 69 return checks 70 }) 71 72 // There are too many clang-tidy warnings in external and vendor projects. 73 // Enable only some google checks for these projects. 74 pctx.VariableFunc("TidyExternalVendorChecks", func(ctx android.PackageVarContext) string { 75 if override := ctx.Config().Getenv("DEFAULT_EXTERNAL_VENDOR_TIDY_CHECKS"); override != "" { 76 return override 77 } 78 return strings.Join([]string{ 79 "-*", 80 "clang-diagnostic-unused-command-line-argument", 81 "google*", 82 "-google-build-using-namespace", 83 "-google-default-arguments", 84 "-google-explicit-constructor", 85 "-google-readability*", 86 "-google-runtime-int", 87 "-google-runtime-references", 88 }, ",") 89 }) 90 91 // To reduce duplicate warnings from the same header files, 92 // header-filter will contain only the module directory and 93 // those specified by DEFAULT_TIDY_HEADER_DIRS. 94 pctx.VariableFunc("TidyDefaultHeaderDirs", func(ctx android.PackageVarContext) string { 95 return ctx.Config().Getenv("DEFAULT_TIDY_HEADER_DIRS") 96 }) 97 98 // Use WTIH_TIDY_FLAGS to pass extra global default clang-tidy flags. 99 pctx.VariableFunc("TidyWithTidyFlags", func(ctx android.PackageVarContext) string { 100 return ctx.Config().Getenv("WITH_TIDY_FLAGS") 101 }) 102} 103 104type PathBasedTidyCheck struct { 105 PathPrefix string 106 Checks string 107} 108 109const tidyDefault = "${config.TidyDefaultGlobalChecks}" 110const tidyExternalVendor = "${config.TidyExternalVendorChecks}" 111const tidyDefaultNoAnalyzer = "${config.TidyDefaultGlobalChecks},-clang-analyzer-*" 112 113// This is a map of local path prefixes to the set of default clang-tidy checks 114// to be used. 115// The last matched local_path_prefix should be the most specific to be used. 116var DefaultLocalTidyChecks = []PathBasedTidyCheck{ 117 {"external/", tidyExternalVendor}, 118 {"external/google", tidyDefault}, 119 {"external/webrtc", tidyDefault}, 120 {"external/googletest/", tidyExternalVendor}, 121 {"frameworks/compile/mclinker/", tidyExternalVendor}, 122 {"hardware/qcom", tidyExternalVendor}, 123 {"vendor/", tidyExternalVendor}, 124 {"vendor/google", tidyDefault}, 125 {"vendor/google_devices", tidyExternalVendor}, 126} 127 128var reversedDefaultLocalTidyChecks = reverseTidyChecks(DefaultLocalTidyChecks) 129 130func reverseTidyChecks(in []PathBasedTidyCheck) []PathBasedTidyCheck { 131 ret := make([]PathBasedTidyCheck, len(in)) 132 for i, check := range in { 133 ret[len(in)-i-1] = check 134 } 135 return ret 136} 137 138func TidyChecksForDir(dir string) string { 139 dir = dir + "/" 140 for _, pathCheck := range reversedDefaultLocalTidyChecks { 141 if strings.HasPrefix(dir, pathCheck.PathPrefix) { 142 return pathCheck.Checks 143 } 144 } 145 return tidyDefault 146} 147 148func TidyFlagsForSrcFile(srcFile android.Path, flags string) string { 149 // Disable clang-analyzer-* checks globally for generated source files 150 // because some of them are too huge. Local .bp files can add wanted 151 // clang-analyzer checks through the tidy_checks property. 152 // Need to do this patch per source file, because some modules 153 // have both generated and organic source files. 154 if _, ok := srcFile.(android.WritablePath); ok { 155 if strings.Contains(flags, tidyDefault) { 156 return strings.ReplaceAll(flags, tidyDefault, tidyDefaultNoAnalyzer) 157 } 158 } 159 return flags 160} 161