Merge "Pass system include dirs to header ABI checker" into main
diff --git a/cc/cc.go b/cc/cc.go
index 6cbf458..a1cae39 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -3325,10 +3325,10 @@
 				// Add these re-exported flags to help header-abi-dumper to infer the abi exported by a library.
 				// Re-exported shared library headers must be included as well since they can help us with type information
 				// about template instantiations (instantiated from their headers).
-				// -isystem headers are not included since for bionic libraries, abi-filtering is taken care of by version
-				// scripts.
 				c.sabi.Properties.ReexportedIncludes = append(
 					c.sabi.Properties.ReexportedIncludes, depExporterInfo.IncludeDirs.Strings()...)
+				c.sabi.Properties.ReexportedSystemIncludes = append(
+					c.sabi.Properties.ReexportedSystemIncludes, depExporterInfo.SystemIncludeDirs.Strings()...)
 			}
 
 			makeLibName := MakeLibName(ctx, c, ccDep, ccDep.BaseModuleName()) + libDepTag.makeSuffix
@@ -3399,6 +3399,7 @@
 
 	if c.sabi != nil {
 		c.sabi.Properties.ReexportedIncludes = android.FirstUniqueStrings(c.sabi.Properties.ReexportedIncludes)
+		c.sabi.Properties.ReexportedSystemIncludes = android.FirstUniqueStrings(c.sabi.Properties.ReexportedSystemIncludes)
 	}
 
 	return depPaths
diff --git a/cc/cc_test.go b/cc/cc_test.go
index d4955c6..3d75bf5 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -958,6 +958,7 @@
 	cc_library_headers {
 		name: "libexternal_llndk_headers",
 		export_include_dirs: ["include_llndk"],
+		export_system_include_dirs: ["include_system_llndk"],
 		llndk: {
 			symbol_file: "libllndk.map.txt",
 		},
@@ -973,6 +974,17 @@
 		},
 		export_include_dirs: ["include"],
 	}
+
+	cc_library {
+		name: "libllndk_with_system_headers",
+		llndk: {
+			symbol_file: "libllndk.map.txt",
+			export_llndk_headers: ["libexternal_llndk_headers"],
+			export_headers_as_system: true,
+		},
+		export_include_dirs: ["include"],
+		export_system_include_dirs: ["include_system"],
+	}
 	`)
 	actual := result.ModuleVariantsForTests("libllndk")
 	for i := 0; i < len(actual); i++ {
@@ -990,20 +1002,26 @@
 	params := result.ModuleForTests("libllndk", "android_vendor_arm_armv7-a-neon_shared").Description("generate stub")
 	android.AssertSame(t, "use Vendor API level for default stubs", "202404", params.Args["apiLevel"])
 
-	checkExportedIncludeDirs := func(module, variant string, expectedDirs ...string) {
+	checkExportedIncludeDirs := func(module, variant string, expectedSystemDirs []string, expectedDirs ...string) {
 		t.Helper()
 		m := result.ModuleForTests(module, variant).Module()
 		f, _ := android.SingletonModuleProvider(result, m, FlagExporterInfoProvider)
 		android.AssertPathsRelativeToTopEquals(t, "exported include dirs for "+module+"["+variant+"]",
 			expectedDirs, f.IncludeDirs)
+		android.AssertPathsRelativeToTopEquals(t, "exported include dirs for "+module+"["+variant+"]",
+			expectedSystemDirs, f.SystemIncludeDirs)
 	}
 
-	checkExportedIncludeDirs("libllndk", coreVariant, "include")
-	checkExportedIncludeDirs("libllndk", vendorVariant, "include")
-	checkExportedIncludeDirs("libllndk_with_external_headers", coreVariant, "include")
-	checkExportedIncludeDirs("libllndk_with_external_headers", vendorVariant, "include_llndk")
-	checkExportedIncludeDirs("libllndk_with_override_headers", coreVariant, "include")
-	checkExportedIncludeDirs("libllndk_with_override_headers", vendorVariant, "include_llndk")
+	checkExportedIncludeDirs("libllndk", coreVariant, nil, "include")
+	checkExportedIncludeDirs("libllndk", vendorVariant, nil, "include")
+	checkExportedIncludeDirs("libllndk_with_external_headers", coreVariant, nil, "include")
+	checkExportedIncludeDirs("libllndk_with_external_headers", vendorVariant,
+		[]string{"include_system_llndk"}, "include_llndk")
+	checkExportedIncludeDirs("libllndk_with_override_headers", coreVariant, nil, "include")
+	checkExportedIncludeDirs("libllndk_with_override_headers", vendorVariant, nil, "include_llndk")
+	checkExportedIncludeDirs("libllndk_with_system_headers", coreVariant, []string{"include_system"}, "include")
+	checkExportedIncludeDirs("libllndk_with_system_headers", vendorVariant,
+		[]string{"include_system", "include", "include_system_llndk"}, "include_llndk")
 
 	checkAbiLinkerIncludeDirs := func(module string) {
 		t.Helper()
@@ -1016,12 +1034,14 @@
 		}
 		vendorModule := result.ModuleForTests(module, vendorVariant).Module()
 		vendorInfo, _ := android.SingletonModuleProvider(result, vendorModule, FlagExporterInfoProvider)
+		vendorDirs := android.Concat(vendorInfo.IncludeDirs, vendorInfo.SystemIncludeDirs)
 		android.AssertStringEquals(t, module+" has different exported include dirs for vendor variant and ABI check",
-			android.JoinPathsWithPrefix(vendorInfo.IncludeDirs, "-I"), abiCheckFlags)
+			android.JoinPathsWithPrefix(vendorDirs, "-I"), abiCheckFlags)
 	}
 	checkAbiLinkerIncludeDirs("libllndk")
 	checkAbiLinkerIncludeDirs("libllndk_with_override_headers")
 	checkAbiLinkerIncludeDirs("libllndk_with_external_headers")
+	checkAbiLinkerIncludeDirs("libllndk_with_system_headers")
 }
 
 func TestLlndkHeaders(t *testing.T) {
diff --git a/cc/library.go b/cc/library.go
index d9754df..5b24809 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -294,6 +294,10 @@
 	return android.PathsForModuleSrc(ctx, f.Properties.Export_include_dirs)
 }
 
+func (f *flagExporter) exportedSystemIncludes(ctx ModuleContext) android.Paths {
+	return android.PathsForModuleSrc(ctx, f.Properties.Export_system_include_dirs)
+}
+
 // exportIncludes registers the include directories and system include directories to be exported
 // transitively to modules depending on this module.
 func (f *flagExporter) exportIncludes(ctx ModuleContext) {
@@ -1204,12 +1208,22 @@
 func (library *libraryDecorator) exportedIncludeDirsForAbiCheck(ctx ModuleContext) []string {
 	exportIncludeDirs := library.flagExporter.exportedIncludes(ctx).Strings()
 	exportIncludeDirs = append(exportIncludeDirs, library.sabi.Properties.ReexportedIncludes...)
-	return exportIncludeDirs
+	exportSystemIncludeDirs := library.flagExporter.exportedSystemIncludes(ctx).Strings()
+	exportSystemIncludeDirs = append(exportSystemIncludeDirs, library.sabi.Properties.ReexportedSystemIncludes...)
+	// The ABI checker does not distinguish normal and system headers.
+	return append(exportIncludeDirs, exportSystemIncludeDirs...)
 }
 
 func (library *libraryDecorator) llndkIncludeDirsForAbiCheck(ctx ModuleContext, deps PathDeps) []string {
+	var includeDirs, systemIncludeDirs []string
+
 	// The ABI checker does not need the preprocess which adds macro guards to function declarations.
-	includeDirs := android.PathsForModuleSrc(ctx, library.Properties.Llndk.Export_preprocessed_headers).Strings()
+	preprocessedDirs := android.PathsForModuleSrc(ctx, library.Properties.Llndk.Export_preprocessed_headers).Strings()
+	if Bool(library.Properties.Llndk.Export_headers_as_system) {
+		systemIncludeDirs = append(systemIncludeDirs, preprocessedDirs...)
+	} else {
+		includeDirs = append(includeDirs, preprocessedDirs...)
+	}
 
 	if library.Properties.Llndk.Override_export_include_dirs != nil {
 		includeDirs = append(includeDirs, android.PathsForModuleSrc(
@@ -1220,7 +1234,8 @@
 		// LLNDK does not reexport the implementation's dependencies, such as export_header_libs.
 	}
 
-	systemIncludeDirs := []string{}
+	systemIncludeDirs = append(systemIncludeDirs,
+		library.flagExporter.exportedSystemIncludes(ctx).Strings()...)
 	if Bool(library.Properties.Llndk.Export_headers_as_system) {
 		systemIncludeDirs = append(systemIncludeDirs, includeDirs...)
 		includeDirs = nil
diff --git a/cc/sabi.go b/cc/sabi.go
index af26726..ef43c8d 100644
--- a/cc/sabi.go
+++ b/cc/sabi.go
@@ -92,7 +92,8 @@
 
 	// Include directories that may contain ABI information exported by a library.
 	// These directories are passed to the header-abi-dumper.
-	ReexportedIncludes []string `blueprint:"mutated"`
+	ReexportedIncludes       []string `blueprint:"mutated"`
+	ReexportedSystemIncludes []string `blueprint:"mutated"`
 }
 
 type sabi struct {