Skip to content

Commit 47f9d78

Browse files
committed
ClangImporter: add support for Android API Notes
Introduce the first APINotes injection for the Android platform. This follows the VCRuntime pattern of permitting the SDK to provide API Notes that augment the system SDK. This adds a workaround for incorrect nullability on the `fts_open` function in bionic. The system library itself is fixed at: https://android-review.googlesource.com/c/platform/bionic/+/3151616
1 parent fb0a1b9 commit 47f9d78

File tree

3 files changed

+56
-7
lines changed

3 files changed

+56
-7
lines changed

lib/ClangImporter/ClangIncludePaths.cpp

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -396,25 +396,49 @@ static void getLibStdCxxFileMapping(
396396

397397
namespace {
398398
std::string
399-
GetWindowsAuxiliaryFile(StringRef modulemap, const SearchPathOptions &Options) {
399+
GetPlatformAuxiliaryFile(StringRef Platform, StringRef File,
400+
const SearchPathOptions &Options) {
400401
StringRef SDKPath = Options.getSDKPath();
401402
if (!SDKPath.empty()) {
402403
llvm::SmallString<261> path{SDKPath};
403-
llvm::sys::path::append(path, "usr", "share", modulemap);
404+
llvm::sys::path::append(path, "usr", "share", File);
404405
if (llvm::sys::fs::exists(path))
405406
return path.str().str();
406407
}
407408

408409
if (!Options.RuntimeResourcePath.empty()) {
409410
llvm::SmallString<261> path{Options.RuntimeResourcePath};
410-
llvm::sys::path::append(path, "windows", modulemap);
411+
llvm::sys::path::append(path, Platform, File);
411412
if (llvm::sys::fs::exists(path))
412413
return path.str().str();
413414
}
414415

415416
return "";
416417
}
417418

419+
SmallVector<std::pair<std::string, std::string>, 2>
420+
GetAndroidFileMappings(
421+
ASTContext &Context, const std::string &sysroot,
422+
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &VFS) {
423+
const llvm::Triple &Triple = Context.LangOpts.Target;
424+
const SearchPathOptions &SearchPathOpts = Context.SearchPathOpts;
425+
SmallVector<std::pair<std::string, std::string>, 2> Mappings;
426+
std::string AuxiliaryFile;
427+
428+
if (!Triple.isAndroid()) return Mappings;
429+
430+
llvm::SmallString<261> NDKInjection{sysroot};
431+
llvm::sys::path::append(NDKInjection, "posix_filesystem.apinotes");
432+
433+
AuxiliaryFile =
434+
GetPlatformAuxiliaryFile("android", "posix_filesystem.apinotes",
435+
SearchPathOpts);
436+
if (!AuxiliaryFile.empty())
437+
Mappings.emplace_back(std::string(NDKInjection), AuxiliaryFile);
438+
439+
return Mappings;
440+
}
441+
418442
SmallVector<std::pair<std::string, std::string>, 2> GetWindowsFileMappings(
419443
ASTContext &Context,
420444
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &driverVFS,
@@ -449,7 +473,8 @@ SmallVector<std::pair<std::string, std::string>, 2> GetWindowsFileMappings(
449473
llvm::sys::path::append(WinSDKInjection, WindowsSDK.IncludeVersion, "um");
450474
llvm::sys::path::append(WinSDKInjection, "module.modulemap");
451475

452-
AuxiliaryFile = GetWindowsAuxiliaryFile("winsdk.modulemap", SearchPathOpts);
476+
AuxiliaryFile =
477+
GetPlatformAuxiliaryFile("windows", "winsdk.modulemap", SearchPathOpts);
453478
if (!AuxiliaryFile.empty())
454479
Mappings.emplace_back(std::string(WinSDKInjection), AuxiliaryFile);
455480
}
@@ -465,7 +490,8 @@ SmallVector<std::pair<std::string, std::string>, 2> GetWindowsFileMappings(
465490
llvm::sys::path::append(UCRTInjection, "Include", UCRTSDK.Version, "ucrt");
466491
llvm::sys::path::append(UCRTInjection, "module.modulemap");
467492

468-
AuxiliaryFile = GetWindowsAuxiliaryFile("ucrt.modulemap", SearchPathOpts);
493+
AuxiliaryFile =
494+
GetPlatformAuxiliaryFile("windows", "ucrt.modulemap", SearchPathOpts);
469495
if (!AuxiliaryFile.empty()) {
470496
// The ucrt module map has the C standard library headers all together.
471497
// That leads to module cycles with the clang _Builtin_ modules. e.g.
@@ -502,14 +528,16 @@ SmallVector<std::pair<std::string, std::string>, 2> GetWindowsFileMappings(
502528

503529
llvm::sys::path::append(VCToolsInjection, "module.modulemap");
504530
AuxiliaryFile =
505-
GetWindowsAuxiliaryFile("vcruntime.modulemap", SearchPathOpts);
531+
GetPlatformAuxiliaryFile("windows", "vcruntime.modulemap",
532+
SearchPathOpts);
506533
if (!AuxiliaryFile.empty())
507534
Mappings.emplace_back(std::string(VCToolsInjection), AuxiliaryFile);
508535

509536
llvm::sys::path::remove_filename(VCToolsInjection);
510537
llvm::sys::path::append(VCToolsInjection, "vcruntime.apinotes");
511538
AuxiliaryFile =
512-
GetWindowsAuxiliaryFile("vcruntime.apinotes", SearchPathOpts);
539+
GetPlatformAuxiliaryFile("windows", "vcruntime.apinotes",
540+
SearchPathOpts);
513541
if (!AuxiliaryFile.empty())
514542
Mappings.emplace_back(std::string(VCToolsInjection), AuxiliaryFile);
515543
}
@@ -525,6 +553,7 @@ ClangInvocationFileMapping swift::getClangInvocationFileMapping(
525553
vfs = llvm::vfs::getRealFileSystem();
526554

527555
const llvm::Triple &triple = ctx.LangOpts.Target;
556+
llvm::SmallString<256> sysroot;
528557

529558
// For modulemaps that have all the C standard library headers together in
530559
// a single module, we end up with module cycles with the clang _Builtin_
@@ -560,6 +589,11 @@ ClangInvocationFileMapping swift::getClangInvocationFileMapping(
560589
StringRef headerFiles[] = {"SwiftAndroidNDK.h", "SwiftBionic.h"};
561590
libcFileMapping =
562591
getLibcFileMapping(ctx, "android.modulemap", headerFiles, vfs);
592+
593+
if (!libcFileMapping.empty()) {
594+
sysroot = libcFileMapping[0].first;
595+
llvm::sys::path::remove_filename(sysroot);
596+
}
563597
} else if (triple.isOSGlibc() || triple.isOSOpenBSD() ||
564598
triple.isOSFreeBSD()) {
565599
// BSD/Linux Mappings
@@ -577,5 +611,8 @@ ClangInvocationFileMapping swift::getClangInvocationFileMapping(
577611
result.redirectedFiles.append(GetWindowsFileMappings(
578612
ctx, vfs, result.requiresBuiltinHeadersInSystemModules));
579613

614+
result.redirectedFiles.append(GetAndroidFileMappings(ctx, sysroot.str().str(),
615+
vfs));
616+
580617
return result;
581618
}

stdlib/public/Platform/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,11 @@ if("ANDROID" IN_LIST SWIFT_SDKS)
473473
COMPONENT sdk-overlay)
474474
endif()
475475
endforeach()
476+
477+
swift_install_in_component(FILES
478+
posix_filesystem.apinotes
479+
DESTINATION "share"
480+
COMPONENT sdk-overlay)
476481
endif()
477482
add_custom_target(android_modulemap DEPENDS ${android_modulemap_target_list})
478483
set_property(TARGET android_modulemap PROPERTY FOLDER "Miscellaneous")
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
Name: bionic
3+
Functions:
4+
- Name: fts_open
5+
Parameters:
6+
- Position: 0
7+
Type: "char * const _Nullable * _Nonnull"

0 commit comments

Comments
 (0)