Merge pull request #61359 from hyp/eng/stdlib-overlay

[interop][SwiftToCxx] add a Swift stdlib overlay header
This commit is contained in:
Alex Lorenz
2022-09-29 19:12:05 -07:00
committed by GitHub
8 changed files with 121 additions and 11 deletions

View File

@@ -1,5 +1,6 @@
set(datafiles
_SwiftCxxInteroperability.h
_SwiftStdlibCxxOverlay.h
)
set(SWIFTLIB_DIR

View File

@@ -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";
}

View File

@@ -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;
};

View File

@@ -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";

View File

@@ -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"

View 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 {};
}

View File

@@ -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]
{

View File

@@ -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