Add clang_verify property for cc.

This property is to support cflags "-Xclang -verify" build pass in Soong. The behaviors of clang_verify:
- append cflags "-Xclang -verify"
- append "&& touch $out" to the clang command line

Bug: 311284462
Test: go test -run TestClangVerify

Change-Id: Ic5825e2d649da4c3c5ed6da916e9804d7e3c03da
diff --git a/cc/builder.go b/cc/builder.go
index 42aa4b6..d817d82 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -46,18 +46,18 @@
 		blueprint.RuleParams{
 			Depfile:     "${out}.d",
 			Deps:        blueprint.DepsGCC,
-			Command:     "$relPwd ${config.CcWrapper}$ccCmd -c $cFlags -MD -MF ${out}.d -o $out $in",
+			Command:     "$relPwd ${config.CcWrapper}$ccCmd -c $cFlags -MD -MF ${out}.d -o $out $in$postCmd",
 			CommandDeps: []string{"$ccCmd"},
 		},
-		"ccCmd", "cFlags")
+		"ccCmd", "cFlags", "postCmd")
 
 	// Rule to invoke gcc with given command and flags, but no dependencies.
 	ccNoDeps = pctx.AndroidStaticRule("ccNoDeps",
 		blueprint.RuleParams{
-			Command:     "$relPwd $ccCmd -c $cFlags -o $out $in",
+			Command:     "$relPwd $ccCmd -c $cFlags -o $out $in$postCmd",
 			CommandDeps: []string{"$ccCmd"},
 		},
-		"ccCmd", "cFlags")
+		"ccCmd", "cFlags", "postCmd")
 
 	// Rules to invoke ld to link binaries. Uses a .rsp file to list dependencies, as there may
 	// be many.
@@ -400,6 +400,7 @@
 	gcovCoverage  bool
 	sAbiDump      bool
 	emitXrefs     bool
+	clangVerify   bool
 
 	assemblerWithCpp bool // True if .s files should be processed with the c preprocessor.
 
@@ -591,6 +592,7 @@
 		var moduleToolingFlags string
 
 		var ccCmd string
+		var postCmd string
 		tidy := flags.tidy
 		coverage := flags.gcovCoverage
 		dump := flags.sAbiDump
@@ -635,6 +637,10 @@
 
 		ccCmd = "${config.ClangBin}/" + ccCmd
 
+		if flags.clangVerify {
+			postCmd = " && touch $$out"
+		}
+
 		var implicitOutputs android.WritablePaths
 		if coverage {
 			gcnoFile := android.ObjPathWithExt(ctx, subdir, srcFile, "gcno")
@@ -651,8 +657,9 @@
 			Implicits:       cFlagsDeps,
 			OrderOnly:       pathDeps,
 			Args: map[string]string{
-				"cFlags": shareFlags("cFlags", moduleFlags),
-				"ccCmd":  ccCmd, // short and not shared
+				"cFlags":  shareFlags("cFlags", moduleFlags),
+				"ccCmd":   ccCmd, // short and not shared
+				"postCmd": postCmd,
 			},
 		})
 
diff --git a/cc/cc.go b/cc/cc.go
index 89cf093..a64775d 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -260,6 +260,7 @@
 	GcovCoverage  bool // True if coverage files should be generated.
 	SAbiDump      bool // True if header abi dumps should be generated.
 	EmitXrefs     bool // If true, generate Ninja rules to generate emitXrefs input files for Kythe
+	ClangVerify   bool // If true, append cflags "-Xclang -verify" and append "&& touch $out" to the clang command line.
 
 	// The instruction set required for clang ("arm" or "thumb").
 	RequiredInstructionSet string
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 3d75bf5..026d291 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -3218,3 +3218,32 @@
 	testSdkVersionFlag("libfoo", "30")
 	testSdkVersionFlag("libbar", "29")
 }
+
+func TestClangVerify(t *testing.T) {
+	t.Parallel()
+
+	ctx := testCc(t, `
+		cc_library {
+			name: "lib_no_clang_verify",
+			srcs: ["libnocv.cc"],
+		}
+
+		cc_library {
+			name: "lib_clang_verify",
+			srcs: ["libcv.cc"],
+			clang_verify: true,
+		}
+	`)
+
+	module := ctx.ModuleForTests("lib_no_clang_verify", "android_arm64_armv8-a_shared")
+
+	cFlags_no_cv := module.Rule("cc").Args["cFlags"]
+	if strings.Contains(cFlags_no_cv, "-Xclang") || strings.Contains(cFlags_no_cv, "-verify") {
+		t.Errorf("expected %q not in cflags, got %q", "-Xclang -verify", cFlags_no_cv)
+	}
+
+	cFlags_cv := ctx.ModuleForTests("lib_clang_verify", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
+	if strings.Contains(cFlags_cv, "-Xclang") && strings.Contains(cFlags_cv, "-verify") {
+		t.Errorf("expected %q in cflags, got %q", "-Xclang -verify", cFlags_cv)
+	}
+}
diff --git a/cc/compiler.go b/cc/compiler.go
index 21b8f2e..34d98c0 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -120,6 +120,10 @@
 	// ban targeting bpf in cc rules instead use bpf_rules. (b/323415017)
 	Bpf_target *bool
 
+	// Add "-Xclang -verify" to the cflags and appends "touch $out" to
+	// the clang command line.
+	Clang_verify bool
+
 	Yacc *YaccProperties
 	Lex  *LexProperties
 
@@ -390,6 +394,11 @@
 	flags.Yacc = compiler.Properties.Yacc
 	flags.Lex = compiler.Properties.Lex
 
+	flags.ClangVerify = compiler.Properties.Clang_verify
+	if compiler.Properties.Clang_verify {
+		flags.Local.CFlags = append(flags.Local.CFlags, "-Xclang", "-verify")
+	}
+
 	// Include dir cflags
 	localIncludeDirs := android.PathsForModuleSrc(ctx, compiler.Properties.Local_include_dirs)
 	if len(localIncludeDirs) > 0 {
diff --git a/cc/util.go b/cc/util.go
index 3ede8ff..8ffacae 100644
--- a/cc/util.go
+++ b/cc/util.go
@@ -68,6 +68,7 @@
 		needTidyFiles:   in.NeedTidyFiles,
 		sAbiDump:        in.SAbiDump,
 		emitXrefs:       in.EmitXrefs,
+		clangVerify:     in.ClangVerify,
 
 		systemIncludeFlags: strings.Join(in.SystemIncludeFlags, " "),