Home | History | Annotate | Download | only in cc
      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 
     15 package cc
     16 
     17 import (
     18 	"strings"
     19 
     20 	"github.com/google/blueprint/proptools"
     21 
     22 	"android/soong/cc/config"
     23 )
     24 
     25 type 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 
     36 type tidyFeature struct {
     37 	Properties TidyProperties
     38 }
     39 
     40 func (tidy *tidyFeature) props() []interface{} {
     41 	return []interface{}{&tidy.Properties}
     42 }
     43 
     44 func (tidy *tidyFeature) begin(ctx BaseModuleContext) {
     45 }
     46 
     47 func (tidy *tidyFeature) deps(ctx DepsContext, deps Deps) Deps {
     48 	return deps
     49 }
     50 
     51 func (tidy *tidyFeature) flags(ctx ModuleContext, flags Flags) Flags {
     52 	CheckBadTidyFlags(ctx, "tidy_flags", tidy.Properties.Tidy_flags)
     53 	CheckBadTidyChecks(ctx, "tidy_checks", tidy.Properties.Tidy_checks)
     54 
     55 	// Check if tidy is explicitly disabled for this module
     56 	if tidy.Properties.Tidy != nil && !*tidy.Properties.Tidy {
     57 		return flags
     58 	}
     59 
     60 	// If not explicitly set, check the global tidy flag
     61 	if tidy.Properties.Tidy == nil && !ctx.Config().ClangTidy() {
     62 		return flags
     63 	}
     64 
     65 	// Clang-tidy requires clang
     66 	if !flags.Clang {
     67 		return flags
     68 	}
     69 
     70 	flags.Tidy = true
     71 
     72 	esc := proptools.NinjaAndShellEscape
     73 
     74 	flags.TidyFlags = append(flags.TidyFlags, esc(tidy.Properties.Tidy_flags)...)
     75 	if len(flags.TidyFlags) == 0 {
     76 		headerFilter := "-header-filter=\"(" + ctx.ModuleDir() + "|${config.TidyDefaultHeaderDirs})\""
     77 		flags.TidyFlags = append(flags.TidyFlags, headerFilter)
     78 	}
     79 
     80 	// If clang-tidy is not enabled globally, add the -quiet flag.
     81 	if !ctx.Config().ClangTidy() {
     82 		flags.TidyFlags = append(flags.TidyFlags, "-quiet")
     83 		flags.TidyFlags = append(flags.TidyFlags, "-extra-arg-before=-fno-caret-diagnostics")
     84 	}
     85 
     86 	// We might be using the static analyzer through clang tidy.
     87 	// https://bugs.llvm.org/show_bug.cgi?id=32914
     88 	flags.TidyFlags = append(flags.TidyFlags, "-extra-arg-before=-D__clang_analyzer__")
     89 
     90 	tidyChecks := "-checks="
     91 	if checks := ctx.Config().TidyChecks(); len(checks) > 0 {
     92 		tidyChecks += checks
     93 	} else {
     94 		tidyChecks += config.TidyChecksForDir(ctx.ModuleDir())
     95 	}
     96 	if len(tidy.Properties.Tidy_checks) > 0 {
     97 		tidyChecks = tidyChecks + "," + strings.Join(esc(tidy.Properties.Tidy_checks), ",")
     98 	}
     99 	flags.TidyFlags = append(flags.TidyFlags, tidyChecks)
    100 
    101 	return flags
    102 }
    103