mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Merge pull request #61359 from hyp/eng/stdlib-overlay
[interop][SwiftToCxx] add a Swift stdlib overlay header
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
set(datafiles
|
||||
_SwiftCxxInteroperability.h
|
||||
_SwiftStdlibCxxOverlay.h
|
||||
)
|
||||
|
||||
set(SWIFTLIB_DIR
|
||||
|
||||
@@ -333,3 +333,24 @@ void ClangSyntaxPrinter::printPrimaryCxxTypeName(
|
||||
// FIXME: Print class qualifiers for nested class references.
|
||||
printBaseName(type);
|
||||
}
|
||||
|
||||
void ClangSyntaxPrinter::printIncludeForShimHeader(StringRef headerName) {
|
||||
os << "// Look for the C++ interop support header relative to clang's "
|
||||
"resource dir:\n";
|
||||
os << "// "
|
||||
"'<toolchain>/usr/lib/clang/<version>/include/../../../swift/"
|
||||
"swiftToCxx'.\n";
|
||||
os << "#if __has_include(<../../../swift/swiftToCxx/" << headerName << ">)\n";
|
||||
os << "#include <../../../swift/swiftToCxx/" << headerName << ">\n";
|
||||
os << "#elif __has_include(<../../../../lib/swift/swiftToCxx/" << headerName
|
||||
<< ">)\n";
|
||||
os << "// "
|
||||
"'<toolchain>/usr/local/lib/clang/<version>/include/../../../../lib/"
|
||||
"swift/swiftToCxx'.\n";
|
||||
os << "#include <../../../../lib/swift/swiftToCxx/" << headerName << ">\n";
|
||||
os << "// Alternatively, allow user to find the header using additional "
|
||||
"include path into '<toolchain>/lib/swift'.\n";
|
||||
os << "#elif __has_include(<swiftToCxx/" << headerName << ">)\n";
|
||||
os << "#include <swiftToCxx/" << headerName << ">\n";
|
||||
os << "#endif\n";
|
||||
}
|
||||
|
||||
@@ -184,6 +184,9 @@ public:
|
||||
void printPrimaryCxxTypeName(const NominalTypeDecl *type,
|
||||
const ModuleDecl *moduleContext);
|
||||
|
||||
// Print the #include sequence for the specified C++ interop shim header.
|
||||
void printIncludeForShimHeader(StringRef headerName);
|
||||
|
||||
protected:
|
||||
raw_ostream &os;
|
||||
};
|
||||
|
||||
@@ -759,6 +759,11 @@ EmittedClangHeaderDependencyInfo swift::printModuleContentsAsCxx(
|
||||
OutputLanguageMode::Cxx);
|
||||
writer.write();
|
||||
info.dependsOnStandardLibrary = writer.isStdlibRequired();
|
||||
if (M.isStdlibModule()) {
|
||||
// Embed an overlay for the standard library.
|
||||
ClangSyntaxPrinter(moduleOS).printIncludeForShimHeader(
|
||||
"_SwiftStdlibCxxOverlay.h");
|
||||
}
|
||||
|
||||
os << "#ifndef SWIFT_PRINTED_CORE\n";
|
||||
os << "#define SWIFT_PRINTED_CORE\n";
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "swift/PrintAsClang/PrintAsClang.h"
|
||||
|
||||
#include "ClangSyntaxPrinter.h"
|
||||
#include "ModuleContentsWriter.h"
|
||||
#include "SwiftToClangInteropContext.h"
|
||||
|
||||
@@ -107,17 +108,8 @@ static void writePrologue(raw_ostream &out, ASTContext &ctx,
|
||||
out << "#include <stdlib.h>\n";
|
||||
out << "#include <new>\n";
|
||||
out << "#include <type_traits>\n";
|
||||
out << "// Look for the C++ interop support header relative to clang's resource dir:\n";
|
||||
out << "// '<toolchain>/usr/lib/clang/<version>/include/../../../swift/swiftToCxx'.\n";
|
||||
out << "#if __has_include(<../../../swift/swiftToCxx/_SwiftCxxInteroperability.h>)\n";
|
||||
out << "#include <../../../swift/swiftToCxx/_SwiftCxxInteroperability.h>\n";
|
||||
out << "#elif __has_include(<../../../../lib/swift/swiftToCxx/_SwiftCxxInteroperability.h>)\n";
|
||||
out << "// '<toolchain>/usr/local/lib/clang/<version>/include/../../../../lib/swift/swiftToCxx'.\n";
|
||||
out << "#include <../../../../lib/swift/swiftToCxx/_SwiftCxxInteroperability.h>\n";
|
||||
out << "// Alternatively, allow user to find the header using additional include path into '<toolchain>/lib/swift'.\n";
|
||||
out << "#elif __has_include(<swiftToCxx/_SwiftCxxInteroperability.h>)\n";
|
||||
out << "#include <swiftToCxx/_SwiftCxxInteroperability.h>\n";
|
||||
out << "#endif\n";
|
||||
ClangSyntaxPrinter(out).printIncludeForShimHeader(
|
||||
"_SwiftCxxInteroperability.h");
|
||||
},
|
||||
[&] {
|
||||
out << "#include <stdint.h>\n"
|
||||
|
||||
72
lib/PrintAsClang/_SwiftStdlibCxxOverlay.h
Normal file
72
lib/PrintAsClang/_SwiftStdlibCxxOverlay.h
Normal file
@@ -0,0 +1,72 @@
|
||||
//===--- _SwiftStlibCxxOverlay.h - Additions for Stdlib ---------*- C++ -*-===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2022 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See https://swift.org/LICENSE.txt for license information
|
||||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error "no C++"
|
||||
#endif
|
||||
|
||||
static_assert(sizeof(_impl::_impl_String) >= 0,
|
||||
"included outside of stdlib bindings");
|
||||
|
||||
namespace cxxOverlay {
|
||||
|
||||
class IterationEndSentinel;
|
||||
|
||||
/// Abstract Swift collection iterator.
|
||||
template <class Collection, class T> class CollectionIterator {
|
||||
public:
|
||||
using Index =
|
||||
decltype(reinterpret_cast<Collection *>(0x123)->getStartIndex());
|
||||
|
||||
inline CollectionIterator(const Collection &collection)
|
||||
: collection(collection) {
|
||||
index = collection.getStartIndex();
|
||||
endIndex = collection.getEndIndex();
|
||||
// FIXME: Begin read access.
|
||||
}
|
||||
|
||||
inline ~CollectionIterator() {
|
||||
// FIXME: End read access.
|
||||
}
|
||||
|
||||
inline T operator*() const { return collection[index]; }
|
||||
inline void operator++() {
|
||||
++index;
|
||||
// FIXME: assert(index <= endIndex); // No need to go past the end.
|
||||
}
|
||||
|
||||
inline bool operator!=(const IterationEndSentinel &) const {
|
||||
return index != endIndex;
|
||||
}
|
||||
|
||||
private:
|
||||
Index index, endIndex;
|
||||
const Collection &collection;
|
||||
};
|
||||
|
||||
class IterationEndSentinel {};
|
||||
|
||||
template <class T> using ArrayIterator = CollectionIterator<Array<T>, T>;
|
||||
|
||||
} // namespace cxxOverlay
|
||||
|
||||
// FIXME: This should apply to more than the Array type.
|
||||
template <class T>
|
||||
inline cxxOverlay::ArrayIterator<T> begin(const Array<T> &array
|
||||
[[clang::lifetimebound]]) {
|
||||
return cxxOverlay::ArrayIterator<T>(array);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline cxxOverlay::IterationEndSentinel end(const Array<T> &) {
|
||||
return {};
|
||||
}
|
||||
@@ -37,6 +37,12 @@ int main() {
|
||||
{
|
||||
Array<int> val = UseArray::createArray(2);
|
||||
UseArray::printArray(UseArray::passthroughArray(val));
|
||||
int count = 2;
|
||||
for (int x: val) {
|
||||
assert(x == 2);
|
||||
--count;
|
||||
}
|
||||
assert(count == 0);
|
||||
}
|
||||
// CHECK: [2, 2]
|
||||
{
|
||||
|
||||
@@ -69,4 +69,14 @@
|
||||
// CHECK-NEXT: #endif
|
||||
// CHECK-NEXT: private:
|
||||
|
||||
// CHECK: #if __has_include(<../../../swift/swiftToCxx/_SwiftStdlibCxxOverlay.h>)
|
||||
// CHECK-NEXT: #include <../../../swift/swiftToCxx/_SwiftStdlibCxxOverlay.h>
|
||||
// CHECK-NEXT: #elif __has_include(<../../../../lib/swift/swiftToCxx/_SwiftStdlibCxxOverlay.h>)
|
||||
// CHECK-NEXT: // '<toolchain>/usr/local/lib/clang/<version>/include/../../../../lib/swift/swiftToCxx'.
|
||||
// CHECK-NEXT: #include <../../../../lib/swift/swiftToCxx/_SwiftStdlibCxxOverlay.h>
|
||||
// CHECK-NEXT: // Alternatively, allow user to find the header using additional include path into '<toolchain>/lib/swift'.
|
||||
// CHECK-NEXT: #elif __has_include(<swiftToCxx/_SwiftStdlibCxxOverlay.h>)
|
||||
// CHECK-NEXT: #include <swiftToCxx/_SwiftStdlibCxxOverlay.h>
|
||||
// CHECK-NEXT: #endif
|
||||
|
||||
// CHECK: } // namespace Swift
|
||||
|
||||
Reference in New Issue
Block a user