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 cc 16 17import ( 18 "strings" 19 20 "github.com/google/blueprint/proptools" 21 22 "android/soong/cc/config" 23) 24 25type TidyProperties struct { 26 // whether to run clang-tidy over C-like sources. 27 Tidy *bool 28 29 // Extra flags to pass to clang-tidy 30 Tidy_flags []string 31 32 // Extra checks to enable or disable in clang-tidy 33 Tidy_checks []string 34 35 // Checks that should be treated as errors. 36 Tidy_checks_as_errors []string 37} 38 39type tidyFeature struct { 40 Properties TidyProperties 41} 42 43func (tidy *tidyFeature) props() []interface{} { 44 return []interface{}{&tidy.Properties} 45} 46 47func (tidy *tidyFeature) begin(ctx BaseModuleContext) { 48} 49 50func (tidy *tidyFeature) deps(ctx DepsContext, deps Deps) Deps { 51 return deps 52} 53 54func (tidy *tidyFeature) flags(ctx ModuleContext, flags Flags) Flags { 55 CheckBadTidyFlags(ctx, "tidy_flags", tidy.Properties.Tidy_flags) 56 CheckBadTidyChecks(ctx, "tidy_checks", tidy.Properties.Tidy_checks) 57 58 // Check if tidy is explicitly disabled for this module 59 if tidy.Properties.Tidy != nil && !*tidy.Properties.Tidy { 60 return flags 61 } 62 63 // If not explicitly set, check the global tidy flag 64 if tidy.Properties.Tidy == nil && !ctx.Config().ClangTidy() { 65 return flags 66 } 67 68 flags.Tidy = true 69 70 // Add global WITH_TIDY_FLAGS and local tidy_flags. 71 withTidyFlags := ctx.Config().Getenv("WITH_TIDY_FLAGS") 72 if len(withTidyFlags) > 0 { 73 flags.TidyFlags = append(flags.TidyFlags, withTidyFlags) 74 } 75 esc := proptools.NinjaAndShellEscapeList 76 flags.TidyFlags = append(flags.TidyFlags, esc(tidy.Properties.Tidy_flags)...) 77 // If TidyFlags is empty, add default header filter. 78 if len(flags.TidyFlags) == 0 { 79 headerFilter := "-header-filter=\"(" + ctx.ModuleDir() + "|${config.TidyDefaultHeaderDirs})\"" 80 flags.TidyFlags = append(flags.TidyFlags, headerFilter) 81 } 82 83 // If clang-tidy is not enabled globally, add the -quiet flag. 84 if !ctx.Config().ClangTidy() { 85 flags.TidyFlags = append(flags.TidyFlags, "-quiet") 86 flags.TidyFlags = append(flags.TidyFlags, "-extra-arg-before=-fno-caret-diagnostics") 87 } 88 89 extraArgFlags := []string{ 90 // We might be using the static analyzer through clang tidy. 91 // https://bugs.llvm.org/show_bug.cgi?id=32914 92 "-D__clang_analyzer__", 93 94 // A recent change in clang-tidy (r328258) enabled destructor inlining, which 95 // appears to cause a number of false positives. Until that's resolved, this turns 96 // off the effects of r328258. 97 // https://bugs.llvm.org/show_bug.cgi?id=37459 98 "-Xclang", "-analyzer-config", "-Xclang", "c++-temp-dtor-inlining=false", 99 } 100 101 for _, f := range extraArgFlags { 102 flags.TidyFlags = append(flags.TidyFlags, "-extra-arg-before="+f) 103 } 104 105 tidyChecks := "-checks=" 106 if checks := ctx.Config().TidyChecks(); len(checks) > 0 { 107 tidyChecks += checks 108 } else { 109 tidyChecks += config.TidyChecksForDir(ctx.ModuleDir()) 110 } 111 if len(tidy.Properties.Tidy_checks) > 0 { 112 tidyChecks = tidyChecks + "," + strings.Join(esc(tidy.Properties.Tidy_checks), ",") 113 } 114 if ctx.Windows() { 115 // https://b.corp.google.com/issues/120614316 116 // mingw32 has cert-dcl16-c warning in NO_ERROR, 117 // which is used in many Android files. 118 tidyChecks = tidyChecks + ",-cert-dcl16-c" 119 } 120 // https://b.corp.google.com/issues/153464409 121 // many local projects enable cert-* checks, which 122 // trigger bugprone-reserved-identifier. 123 tidyChecks = tidyChecks + ",-bugprone-reserved-identifier*,-cert-dcl51-cpp,-cert-dcl37-c" 124 // http://b/153757728 125 tidyChecks = tidyChecks + ",-readability-qualified-auto" 126 // http://b/155034563 127 tidyChecks = tidyChecks + ",-bugprone-signed-char-misuse" 128 // http://b/155034972 129 tidyChecks = tidyChecks + ",-bugprone-branch-clone" 130 flags.TidyFlags = append(flags.TidyFlags, tidyChecks) 131 132 if len(tidy.Properties.Tidy_checks_as_errors) > 0 { 133 tidyChecksAsErrors := "-warnings-as-errors=" + strings.Join(esc(tidy.Properties.Tidy_checks_as_errors), ",") 134 flags.TidyFlags = append(flags.TidyFlags, tidyChecksAsErrors) 135 } 136 return flags 137} 138