Black-list for clang LibTooling Cflags.

Add a list of flags which are not understood by clang LibTooling tools
and filter them out of the Cflags the tools are invoked with.

Test: In frameworks/av, make libmedia vendor_available (this invokes
header-abi-dumper on this module), mm -j64.

Bug: 62447349

Change-Id: I46f017212b89f4331145c999103d0ed44da0abaf
diff --git a/cc/builder.go b/cc/builder.go
index 51c4ce9..61c0572 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -206,26 +206,27 @@
 }
 
 type builderFlags struct {
-	globalFlags string
-	arFlags     string
-	asFlags     string
-	cFlags      string
-	conlyFlags  string
-	cppFlags    string
-	ldFlags     string
-	libFlags    string
-	yaccFlags   string
-	protoFlags  string
-	tidyFlags   string
-	sAbiFlags   string
-	yasmFlags   string
-	aidlFlags   string
-	rsFlags     string
-	toolchain   config.Toolchain
-	clang       bool
-	tidy        bool
-	coverage    bool
-	sAbiDump    bool
+	globalFlags   string
+	arFlags       string
+	asFlags       string
+	cFlags        string
+	toolingCFlags string // Seperate set of Cflags for clang LibTooling tools
+	conlyFlags    string
+	cppFlags      string
+	ldFlags       string
+	libFlags      string
+	yaccFlags     string
+	protoFlags    string
+	tidyFlags     string
+	sAbiFlags     string
+	yasmFlags     string
+	aidlFlags     string
+	rsFlags       string
+	toolchain     config.Toolchain
+	clang         bool
+	tidy          bool
+	coverage      bool
+	sAbiDump      bool
 
 	systemIncludeFlags string
 
@@ -275,25 +276,40 @@
 		coverageFiles = make(android.Paths, 0, len(srcFiles))
 	}
 
-	cflags := strings.Join([]string{
+	commonFlags := strings.Join([]string{
 		flags.globalFlags,
 		flags.systemIncludeFlags,
+	}, " ")
+
+	toolingCflags := strings.Join([]string{
+		commonFlags,
+		flags.toolingCFlags,
+		flags.conlyFlags,
+	}, " ")
+
+	cflags := strings.Join([]string{
+		commonFlags,
 		flags.cFlags,
 		flags.conlyFlags,
 	}, " ")
 
+	toolingCppflags := strings.Join([]string{
+		commonFlags,
+		flags.toolingCFlags,
+		flags.cppFlags,
+	}, " ")
+
 	cppflags := strings.Join([]string{
-		flags.globalFlags,
-		flags.systemIncludeFlags,
+		commonFlags,
 		flags.cFlags,
 		flags.cppFlags,
 	}, " ")
 
 	asflags := strings.Join([]string{
-		flags.globalFlags,
-		flags.systemIncludeFlags,
+		commonFlags,
 		flags.asFlags,
 	}, " ")
+
 	var sAbiDumpFiles android.Paths
 	if flags.sAbiDump && flags.clang {
 		sAbiDumpFiles = make(android.Paths, 0, len(srcFiles))
@@ -301,7 +317,9 @@
 
 	if flags.clang {
 		cflags += " ${config.NoOverrideClangGlobalCflags}"
+		toolingCflags += " ${config.NoOverrideClangGlobalCflags}"
 		cppflags += " ${config.NoOverrideClangGlobalCflags}"
+		toolingCppflags += " ${config.NoOverrideClangGlobalCflags}"
 	} else {
 		cflags += " ${config.NoOverrideGlobalCflags}"
 		cppflags += " ${config.NoOverrideGlobalCflags}"
@@ -327,6 +345,7 @@
 		}
 
 		var moduleCflags string
+		var moduleToolingCflags string
 		var ccCmd string
 		tidy := flags.tidy && flags.clang
 		coverage := flags.coverage
@@ -342,9 +361,11 @@
 		case ".c":
 			ccCmd = "gcc"
 			moduleCflags = cflags
+			moduleToolingCflags = toolingCflags
 		case ".cpp", ".cc", ".mm":
 			ccCmd = "g++"
 			moduleCflags = cppflags
+			moduleToolingCflags = toolingCppflags
 		default:
 			ctx.ModuleErrorf("File %s has unknown extension", srcFile)
 			continue
@@ -402,7 +423,7 @@
 				// support exporting dependencies.
 				Implicit: objFile,
 				Args: map[string]string{
-					"cFlags":    moduleCflags,
+					"cFlags":    moduleToolingCflags,
 					"tidyFlags": flags.tidyFlags,
 				},
 			})
@@ -419,7 +440,7 @@
 				Input:       srcFile,
 				Implicit:    objFile,
 				Args: map[string]string{
-					"cFlags":     moduleCflags,
+					"cFlags":     moduleToolingCflags,
 					"exportDirs": flags.sAbiFlags,
 				},
 			})
diff --git a/cc/cc.go b/cc/cc.go
index 43825ca..867b196 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -97,21 +97,23 @@
 }
 
 type Flags struct {
-	GlobalFlags []string // Flags that apply to C, C++, and assembly source files
-	ArFlags     []string // Flags that apply to ar
-	AsFlags     []string // Flags that apply to assembly source files
-	CFlags      []string // Flags that apply to C and C++ source files
-	ConlyFlags  []string // Flags that apply to C source files
-	CppFlags    []string // Flags that apply to C++ source files
-	YaccFlags   []string // Flags that apply to Yacc source files
-	protoFlags  []string // Flags that apply to proto source files
-	aidlFlags   []string // Flags that apply to aidl source files
-	rsFlags     []string // Flags that apply to renderscript source files
-	LdFlags     []string // Flags that apply to linker command lines
-	libFlags    []string // Flags to add libraries early to the link order
-	TidyFlags   []string // Flags that apply to clang-tidy
-	SAbiFlags   []string // Flags that apply to header-abi-dumper
-	YasmFlags   []string // Flags that apply to yasm assembly source files
+	GlobalFlags     []string // Flags that apply to C, C++, and assembly source files
+	ArFlags         []string // Flags that apply to ar
+	AsFlags         []string // Flags that apply to assembly source files
+	CFlags          []string // Flags that apply to C and C++ source files
+	ToolingCFlags   []string // Flags that apply to C and C++ source files parsed by clang LibTooling tools
+	ConlyFlags      []string // Flags that apply to C source files
+	CppFlags        []string // Flags that apply to C++ source files
+	ToolingCppFlags []string // Flags that apply to C++ source files parsed by clang LibTooling tools
+	YaccFlags       []string // Flags that apply to Yacc source files
+	protoFlags      []string // Flags that apply to proto source files
+	aidlFlags       []string // Flags that apply to aidl source files
+	rsFlags         []string // Flags that apply to renderscript source files
+	LdFlags         []string // Flags that apply to linker command lines
+	libFlags        []string // Flags to add libraries early to the link order
+	TidyFlags       []string // Flags that apply to clang-tidy
+	SAbiFlags       []string // Flags that apply to header-abi-dumper
+	YasmFlags       []string // Flags that apply to yasm assembly source files
 
 	// Global include flags that apply to C, C++, and assembly source files
 	// These must be after any module include flags, which will be in GlobalFlags.
@@ -507,9 +509,6 @@
 	if c.coverage != nil {
 		flags = c.coverage.flags(ctx, flags)
 	}
-	if c.sabi != nil {
-		flags = c.sabi.flags(ctx, flags)
-	}
 	for _, feature := range c.features {
 		flags = feature.flags(ctx, flags)
 	}
@@ -527,7 +526,10 @@
 	}
 	flags.GlobalFlags = append(flags.GlobalFlags, deps.Flags...)
 	c.flags = flags
-
+	// We need access to all the flags seen by a source file.
+	if c.sabi != nil {
+		flags = c.sabi.flags(ctx, flags)
+	}
 	// Optimization to reduce size of build.ninja
 	// Replace the long list of flags for each file with a module-local variable
 	ctx.Variable(pctx, "cflags", strings.Join(flags.CFlags, " "))
diff --git a/cc/config/clang.go b/cc/config/clang.go
index 3ff6b1b..977afe1 100644
--- a/cc/config/clang.go
+++ b/cc/config/clang.go
@@ -65,6 +65,11 @@
 	"-mbionic",
 })
 
+var ClangLibToolingUnknownCflags = []string{
+	"-flto",
+	"-fsanitize*",
+}
+
 func init() {
 	pctx.StaticVariable("ClangExtraCflags", strings.Join([]string{
 		"-D__compiler_offsetof=__builtin_offsetof",
diff --git a/cc/makevars.go b/cc/makevars.go
index a1e97a5..2a5c813 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -59,12 +59,12 @@
 		ctx.Strict("BOARD_VNDK_VERSION", "")
 	}
 
-	ctx.Strict("ADDRESS_SANITIZER_CONFIG_EXTRA_CFLAGS", asanCflags)
-	ctx.Strict("ADDRESS_SANITIZER_CONFIG_EXTRA_LDFLAGS", asanLdflags)
-	ctx.Strict("ADDRESS_SANITIZER_CONFIG_EXTRA_STATIC_LIBRARIES", asanLibs)
+	ctx.Strict("ADDRESS_SANITIZER_CONFIG_EXTRA_CFLAGS", strings.Join(asanCflags, " "))
+	ctx.Strict("ADDRESS_SANITIZER_CONFIG_EXTRA_LDFLAGS", strings.Join(asanLdflags, " "))
+	ctx.Strict("ADDRESS_SANITIZER_CONFIG_EXTRA_STATIC_LIBRARIES", strings.Join(asanLibs, " "))
 
-	ctx.Strict("CFI_EXTRA_CFLAGS", cfiCflags)
-	ctx.Strict("CFI_EXTRA_LDFLAGS", cfiLdflags)
+	ctx.Strict("CFI_EXTRA_CFLAGS", strings.Join(cfiCflags, " "))
+	ctx.Strict("CFI_EXTRA_LDFLAGS", strings.Join(cfiLdflags, " "))
 
 	ctx.Strict("DEFAULT_C_STD_VERSION", config.CStdVersion)
 	ctx.Strict("DEFAULT_CPP_STD_VERSION", config.CppStdVersion)
diff --git a/cc/sabi.go b/cc/sabi.go
index 01ef737..92fc7cf 100644
--- a/cc/sabi.go
+++ b/cc/sabi.go
@@ -15,6 +15,8 @@
 package cc
 
 import (
+	"strings"
+
 	"android/soong/android"
 	"github.com/google/blueprint"
 
@@ -40,7 +42,31 @@
 	return deps
 }
 
+func inListWithPrefixSearch(flag string, filter []string) bool {
+	// Assuming the filter is small enough.
+	// If the suffix of a filter element is *, try matching prefixes as well.
+	for _, f := range filter {
+		if (f == flag) || (strings.HasSuffix(f, "*") && strings.HasPrefix(flag, strings.TrimSuffix(f, "*"))) {
+			return true
+		}
+	}
+	return false
+}
+
+func filterOutWithPrefix(list []string, filter []string) (remainder []string) {
+	// Go through the filter, matching and optionally doing a prefix search for list elements.
+	for _, l := range list {
+		if !inListWithPrefixSearch(l, filter) {
+			remainder = append(remainder, l)
+		}
+	}
+	return
+}
+
 func (sabimod *sabi) flags(ctx ModuleContext, flags Flags) Flags {
+	// Assuming that the cflags which clang LibTooling tools cannot
+	// understand have not been converted to ninja variables yet.
+	flags.ToolingCFlags = filterOutWithPrefix(flags.CFlags, config.ClangLibToolingUnknownCflags)
 	return flags
 }
 
diff --git a/cc/sanitize.go b/cc/sanitize.go
index dfd86f0..b847c6f 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -25,17 +25,21 @@
 	"android/soong/cc/config"
 )
 
-const (
-	asanCflags  = "-fno-omit-frame-pointer"
-	asanLdflags = "-Wl,-u,__asan_preinit"
-	asanLibs    = "libasan"
+var (
+	// Any C flags added by sanitizer which libTooling tools may not
+	// understand also need to be added to ClangLibToolingUnknownCflags in
+	// cc/config/clang.go
 
-	cfiCflags = "-flto -fsanitize-cfi-cross-dso -fvisibility=default " +
-		"-fsanitize-blacklist=external/compiler-rt/lib/cfi/cfi_blacklist.txt"
+	asanCflags  = []string{"-fno-omit-frame-pointer"}
+	asanLdflags = []string{"-Wl,-u,__asan_preinit"}
+	asanLibs    = []string{"libasan"}
+
+	cfiCflags = []string{"-flto", "-fsanitize-cfi-cross-dso", "-fvisibility=default",
+		"-fsanitize-blacklist=external/compiler-rt/lib/cfi/cfi_blacklist.txt"}
 	// FIXME: revert the __cfi_check flag when clang is updated to r280031.
-	cfiLdflags = "-flto -fsanitize-cfi-cross-dso -fsanitize=cfi " +
-		"-Wl,-plugin-opt,O1 -Wl,-export-dynamic-symbol=__cfi_check"
-	cfiArflags = "--plugin ${config.ClangBin}/../lib64/LLVMgold.so"
+	cfiLdflags = []string{"-flto", "-fsanitize-cfi-cross-dso", "-fsanitize=cfi",
+		"-Wl,-plugin-opt,O1 -Wl,-export-dynamic-symbol=__cfi_check"}
+	cfiArflags = []string{"--plugin ${config.ClangBin}/../lib64/LLVMgold.so"}
 )
 
 type sanitizerType int
@@ -232,7 +236,7 @@
 
 	if ctx.Device() {
 		if Bool(sanitize.Properties.Sanitize.Address) {
-			deps.StaticLibs = append(deps.StaticLibs, asanLibs)
+			deps.StaticLibs = append(deps.StaticLibs, asanLibs...)
 		}
 		if Bool(sanitize.Properties.Sanitize.Address) || Bool(sanitize.Properties.Sanitize.Thread) {
 			deps.SharedLibs = append(deps.SharedLibs, "libdl")
@@ -300,8 +304,8 @@
 			// TODO: put in flags?
 			flags.RequiredInstructionSet = "arm"
 		}
-		flags.CFlags = append(flags.CFlags, asanCflags)
-		flags.LdFlags = append(flags.LdFlags, asanLdflags)
+		flags.CFlags = append(flags.CFlags, asanCflags...)
+		flags.LdFlags = append(flags.LdFlags, asanLdflags...)
 
 		if ctx.Host() {
 			// -nodefaultlibs (provided with libc++) prevents the driver from linking
@@ -337,9 +341,9 @@
 			flags.LdFlags = append(flags.LdFlags, "-march=armv7-a")
 		}
 		sanitizers = append(sanitizers, "cfi")
-		flags.CFlags = append(flags.CFlags, cfiCflags)
-		flags.LdFlags = append(flags.LdFlags, cfiLdflags)
-		flags.ArFlags = append(flags.ArFlags, cfiArflags)
+		flags.CFlags = append(flags.CFlags, cfiCflags...)
+		flags.LdFlags = append(flags.LdFlags, cfiLdflags...)
+		flags.ArFlags = append(flags.ArFlags, cfiArflags...)
 		if Bool(sanitize.Properties.Sanitize.Diag.Cfi) {
 			diagSanitizers = append(diagSanitizers, "cfi")
 		}
diff --git a/cc/util.go b/cc/util.go
index 2febb57..d9cd6f7 100644
--- a/cc/util.go
+++ b/cc/util.go
@@ -87,26 +87,27 @@
 
 func flagsToBuilderFlags(in Flags) builderFlags {
 	return builderFlags{
-		globalFlags: strings.Join(in.GlobalFlags, " "),
-		arFlags:     strings.Join(in.ArFlags, " "),
-		asFlags:     strings.Join(in.AsFlags, " "),
-		cFlags:      strings.Join(in.CFlags, " "),
-		conlyFlags:  strings.Join(in.ConlyFlags, " "),
-		cppFlags:    strings.Join(in.CppFlags, " "),
-		yaccFlags:   strings.Join(in.YaccFlags, " "),
-		protoFlags:  strings.Join(in.protoFlags, " "),
-		aidlFlags:   strings.Join(in.aidlFlags, " "),
-		rsFlags:     strings.Join(in.rsFlags, " "),
-		ldFlags:     strings.Join(in.LdFlags, " "),
-		libFlags:    strings.Join(in.libFlags, " "),
-		tidyFlags:   strings.Join(in.TidyFlags, " "),
-		sAbiFlags:   strings.Join(in.SAbiFlags, " "),
-		yasmFlags:   strings.Join(in.YasmFlags, " "),
-		toolchain:   in.Toolchain,
-		clang:       in.Clang,
-		coverage:    in.Coverage,
-		tidy:        in.Tidy,
-		sAbiDump:    in.SAbiDump,
+		globalFlags:   strings.Join(in.GlobalFlags, " "),
+		arFlags:       strings.Join(in.ArFlags, " "),
+		asFlags:       strings.Join(in.AsFlags, " "),
+		cFlags:        strings.Join(in.CFlags, " "),
+		toolingCFlags: strings.Join(in.ToolingCFlags, " "),
+		conlyFlags:    strings.Join(in.ConlyFlags, " "),
+		cppFlags:      strings.Join(in.CppFlags, " "),
+		yaccFlags:     strings.Join(in.YaccFlags, " "),
+		protoFlags:    strings.Join(in.protoFlags, " "),
+		aidlFlags:     strings.Join(in.aidlFlags, " "),
+		rsFlags:       strings.Join(in.rsFlags, " "),
+		ldFlags:       strings.Join(in.LdFlags, " "),
+		libFlags:      strings.Join(in.libFlags, " "),
+		tidyFlags:     strings.Join(in.TidyFlags, " "),
+		sAbiFlags:     strings.Join(in.SAbiFlags, " "),
+		yasmFlags:     strings.Join(in.YasmFlags, " "),
+		toolchain:     in.Toolchain,
+		clang:         in.Clang,
+		coverage:      in.Coverage,
+		tidy:          in.Tidy,
+		sAbiDump:      in.SAbiDump,
 
 		systemIncludeFlags: strings.Join(in.SystemIncludeFlags, " "),