mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[interop][SwiftToCxx] print availability attributes for Swift decls in C++
This commit is contained in:
@@ -243,7 +243,8 @@ private:
|
||||
}
|
||||
|
||||
/// Prints an encoded string, escaped properly for C.
|
||||
void printEncodedString(StringRef str, bool includeQuotes = true) {
|
||||
void printEncodedString(raw_ostream &os, StringRef str,
|
||||
bool includeQuotes = true) {
|
||||
// NB: We don't use raw_ostream::write_escaped() because it does hex escapes
|
||||
// for non-ASCII chars.
|
||||
|
||||
@@ -296,11 +297,10 @@ private:
|
||||
|
||||
if (outputLang == OutputLanguageMode::Cxx) {
|
||||
// FIXME: Non objc class.
|
||||
// FIXME: Print availability.
|
||||
// FIXME: forward decl should be handled by ModuleWriter.
|
||||
ClangValueTypePrinter::forwardDeclType(os, CD);
|
||||
ClangValueTypePrinter::forwardDeclType(os, CD, owningPrinter);
|
||||
ClangClassTypePrinter(os).printClassTypeDecl(
|
||||
CD, [&]() { printMembers(CD->getMembers()); });
|
||||
CD, [&]() { printMembers(CD->getMembers()); }, owningPrinter);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -347,20 +347,22 @@ private:
|
||||
if (outputLang != OutputLanguageMode::Cxx)
|
||||
return;
|
||||
// FIXME: Print struct's doc comment.
|
||||
// FIXME: Print struct's availability.
|
||||
ClangValueTypePrinter printer(os, owningPrinter.prologueOS,
|
||||
owningPrinter.interopContext);
|
||||
printer.printValueTypeDecl(SD, /*bodyPrinter=*/[&]() {
|
||||
printMembers(SD->getMembers());
|
||||
for (const auto *ed :
|
||||
owningPrinter.interopContext.getExtensionsForNominalType(SD)) {
|
||||
auto sign = ed->getGenericSignature();
|
||||
// FIXME: support requirements.
|
||||
if (!sign.getRequirements().empty())
|
||||
continue;
|
||||
printMembers(ed->getMembers());
|
||||
}
|
||||
});
|
||||
printer.printValueTypeDecl(
|
||||
SD, /*bodyPrinter=*/
|
||||
[&]() {
|
||||
printMembers(SD->getMembers());
|
||||
for (const auto *ed :
|
||||
owningPrinter.interopContext.getExtensionsForNominalType(SD)) {
|
||||
auto sign = ed->getGenericSignature();
|
||||
// FIXME: support requirements.
|
||||
if (!sign.getRequirements().empty())
|
||||
continue;
|
||||
printMembers(ed->getMembers());
|
||||
}
|
||||
},
|
||||
owningPrinter);
|
||||
}
|
||||
|
||||
void visitExtensionDecl(ExtensionDecl *ED) {
|
||||
@@ -760,81 +762,88 @@ private:
|
||||
os << ";\n";
|
||||
};
|
||||
|
||||
valueTypePrinter.printValueTypeDecl(ED, /*bodyPrinter=*/[&]() {
|
||||
os << '\n';
|
||||
os << " enum class cases {";
|
||||
llvm::interleave(
|
||||
elementTagMapping, os,
|
||||
[&](const auto &pair) {
|
||||
os << "\n ";
|
||||
syntaxPrinter.printIdentifier(pair.first->getNameStr());
|
||||
syntaxPrinter.printSymbolUSRAttribute(pair.first);
|
||||
},
|
||||
",");
|
||||
// TODO: allow custom name for this special case
|
||||
auto resilientUnknownDefaultCaseName = "unknownDefault";
|
||||
if (ED->isResilient()) {
|
||||
os << (ED->getNumElements() > 0 ? ",\n " : "\n ")
|
||||
<< resilientUnknownDefaultCaseName;
|
||||
}
|
||||
os << "\n };\n\n"; // enum class cases' closing bracket
|
||||
valueTypePrinter.printValueTypeDecl(
|
||||
ED, /*bodyPrinter=*/
|
||||
[&]() {
|
||||
os << '\n';
|
||||
os << " enum class cases {";
|
||||
llvm::interleave(
|
||||
elementTagMapping, os,
|
||||
[&](const auto &pair) {
|
||||
os << "\n ";
|
||||
syntaxPrinter.printIdentifier(pair.first->getNameStr());
|
||||
syntaxPrinter.printSymbolUSRAttribute(pair.first);
|
||||
},
|
||||
",");
|
||||
// TODO: allow custom name for this special case
|
||||
auto resilientUnknownDefaultCaseName = "unknownDefault";
|
||||
if (ED->isResilient()) {
|
||||
os << (ED->getNumElements() > 0 ? ",\n " : "\n ")
|
||||
<< resilientUnknownDefaultCaseName;
|
||||
}
|
||||
os << "\n };\n\n"; // enum class cases' closing bracket
|
||||
|
||||
os << "#pragma clang diagnostic push\n";
|
||||
os << "#pragma clang diagnostic ignored \"-Wc++17-extensions\" "
|
||||
<< "// allow use of inline static data member\n";
|
||||
for (const auto &pair : elementTagMapping) {
|
||||
// Printing struct
|
||||
printStruct(pair.first->getNameStr(), pair.first, pair.second);
|
||||
// Printing `is` function
|
||||
printIsFunction(pair.first->getNameStr(), ED);
|
||||
if (pair.first->hasAssociatedValues()) {
|
||||
// Printing `get` function
|
||||
printGetFunction(pair.first);
|
||||
}
|
||||
os << '\n';
|
||||
}
|
||||
os << "#pragma clang diagnostic push\n";
|
||||
os << "#pragma clang diagnostic ignored \"-Wc++17-extensions\" "
|
||||
<< "// allow use of inline static data member\n";
|
||||
for (const auto &pair : elementTagMapping) {
|
||||
// Printing struct
|
||||
printStruct(pair.first->getNameStr(), pair.first, pair.second);
|
||||
// Printing `is` function
|
||||
printIsFunction(pair.first->getNameStr(), ED);
|
||||
if (pair.first->hasAssociatedValues()) {
|
||||
// Printing `get` function
|
||||
printGetFunction(pair.first);
|
||||
}
|
||||
os << '\n';
|
||||
}
|
||||
|
||||
if (ED->isResilient()) {
|
||||
// Printing struct for unknownDefault
|
||||
printStruct(resilientUnknownDefaultCaseName, /* elementDecl */ nullptr,
|
||||
/* elementInfo */ None);
|
||||
// Printing isUnknownDefault
|
||||
printIsFunction(resilientUnknownDefaultCaseName, ED);
|
||||
os << '\n';
|
||||
}
|
||||
os << "#pragma clang diagnostic pop\n";
|
||||
if (ED->isResilient()) {
|
||||
// Printing struct for unknownDefault
|
||||
printStruct(resilientUnknownDefaultCaseName,
|
||||
/* elementDecl */ nullptr,
|
||||
/* elementInfo */ None);
|
||||
// Printing isUnknownDefault
|
||||
printIsFunction(resilientUnknownDefaultCaseName, ED);
|
||||
os << '\n';
|
||||
}
|
||||
os << "#pragma clang diagnostic pop\n";
|
||||
|
||||
// Printing operator cases()
|
||||
os << " ";
|
||||
ClangSyntaxPrinter(os).printInlineForThunk();
|
||||
os << "operator cases() const {\n";
|
||||
if (ED->isResilient()) {
|
||||
if (!elementTagMapping.empty()) {
|
||||
os << " auto tag = _getEnumTag();\n";
|
||||
}
|
||||
for (const auto &pair : elementTagMapping) {
|
||||
os << " if (tag == " << cxx_synthesis::getCxxImplNamespaceName();
|
||||
os << "::" << pair.second.globalVariableName << ") return cases::";
|
||||
syntaxPrinter.printIdentifier(pair.first->getNameStr());
|
||||
os << ";\n";
|
||||
}
|
||||
os << " return cases::" << resilientUnknownDefaultCaseName << ";\n";
|
||||
} else { // non-resilient enum
|
||||
os << " switch (_getEnumTag()) {\n";
|
||||
for (const auto &pair : elementTagMapping) {
|
||||
os << " case " << pair.second.tag << ": return cases::";
|
||||
syntaxPrinter.printIdentifier(pair.first->getNameStr());
|
||||
os << ";\n";
|
||||
}
|
||||
// TODO: change to Swift's fatalError when it's available in C++
|
||||
os << " default: abort();\n";
|
||||
os << " }\n"; // switch's closing bracket
|
||||
}
|
||||
os << " }\n"; // operator cases()'s closing bracket
|
||||
os << "\n";
|
||||
|
||||
printMembers(ED->getMembers());
|
||||
});
|
||||
// Printing operator cases()
|
||||
os << " ";
|
||||
ClangSyntaxPrinter(os).printInlineForThunk();
|
||||
os << "operator cases() const {\n";
|
||||
if (ED->isResilient()) {
|
||||
if (!elementTagMapping.empty()) {
|
||||
os << " auto tag = _getEnumTag();\n";
|
||||
}
|
||||
for (const auto &pair : elementTagMapping) {
|
||||
os << " if (tag == "
|
||||
<< cxx_synthesis::getCxxImplNamespaceName();
|
||||
os << "::" << pair.second.globalVariableName
|
||||
<< ") return cases::";
|
||||
syntaxPrinter.printIdentifier(pair.first->getNameStr());
|
||||
os << ";\n";
|
||||
}
|
||||
os << " return cases::" << resilientUnknownDefaultCaseName
|
||||
<< ";\n";
|
||||
} else { // non-resilient enum
|
||||
os << " switch (_getEnumTag()) {\n";
|
||||
for (const auto &pair : elementTagMapping) {
|
||||
os << " case " << pair.second.tag << ": return cases::";
|
||||
syntaxPrinter.printIdentifier(pair.first->getNameStr());
|
||||
os << ";\n";
|
||||
}
|
||||
// TODO: change to Swift's fatalError when it's available in C++
|
||||
os << " default: abort();\n";
|
||||
os << " }\n"; // switch's closing bracket
|
||||
}
|
||||
os << " }\n"; // operator cases()'s closing bracket
|
||||
os << "\n";
|
||||
|
||||
printMembers(ED->getMembers());
|
||||
},
|
||||
owningPrinter);
|
||||
}
|
||||
|
||||
void visitEnumDecl(EnumDecl *ED) {
|
||||
@@ -1024,17 +1033,17 @@ private:
|
||||
if (auto *accessor = dyn_cast<AccessorDecl>(AFD)) {
|
||||
if (SD)
|
||||
declPrinter.printCxxSubscriptAccessorMethod(
|
||||
typeDeclContext, accessor, funcABI->getSignature(),
|
||||
owningPrinter, typeDeclContext, accessor, funcABI->getSignature(),
|
||||
funcABI->getSymbolName(), resultTy,
|
||||
/*isDefinition=*/false, dispatchInfo);
|
||||
else
|
||||
declPrinter.printCxxPropertyAccessorMethod(
|
||||
typeDeclContext, accessor, funcABI->getSignature(),
|
||||
owningPrinter, typeDeclContext, accessor, funcABI->getSignature(),
|
||||
funcABI->getSymbolName(), resultTy,
|
||||
/*isStatic=*/isClassMethod,
|
||||
/*isDefinition=*/false, dispatchInfo);
|
||||
} else {
|
||||
declPrinter.printCxxMethod(typeDeclContext, AFD,
|
||||
declPrinter.printCxxMethod(owningPrinter, typeDeclContext, AFD,
|
||||
funcABI->getSignature(),
|
||||
funcABI->getSymbolName(), resultTy,
|
||||
/*isStatic=*/isClassMethod,
|
||||
@@ -1049,24 +1058,24 @@ private:
|
||||
if (auto *accessor = dyn_cast<AccessorDecl>(AFD)) {
|
||||
if (SD)
|
||||
defPrinter.printCxxSubscriptAccessorMethod(
|
||||
typeDeclContext, accessor, funcABI->getSignature(),
|
||||
owningPrinter, typeDeclContext, accessor, funcABI->getSignature(),
|
||||
funcABI->getSymbolName(), resultTy, /*isDefinition=*/true,
|
||||
dispatchInfo);
|
||||
else
|
||||
defPrinter.printCxxPropertyAccessorMethod(
|
||||
typeDeclContext, accessor, funcABI->getSignature(),
|
||||
owningPrinter, typeDeclContext, accessor, funcABI->getSignature(),
|
||||
funcABI->getSymbolName(), resultTy,
|
||||
/*isStatic=*/isClassMethod,
|
||||
/*isDefinition=*/true, dispatchInfo);
|
||||
} else {
|
||||
defPrinter.printCxxMethod(typeDeclContext, AFD, funcABI->getSignature(),
|
||||
defPrinter.printCxxMethod(owningPrinter, typeDeclContext, AFD,
|
||||
funcABI->getSignature(),
|
||||
funcABI->getSymbolName(), resultTy,
|
||||
/*isStatic=*/isClassMethod,
|
||||
/*isDefinition=*/true, dispatchInfo);
|
||||
}
|
||||
|
||||
// FIXME: SWIFT_WARN_UNUSED_RESULT
|
||||
// FIXME: availability
|
||||
return;
|
||||
}
|
||||
printDocumentationComment(AFD);
|
||||
@@ -1522,9 +1531,16 @@ private:
|
||||
Yes = true
|
||||
};
|
||||
|
||||
/// Returns \c true if anything was printed.
|
||||
bool printAvailability(const Decl *D, PrintLeadingSpace printLeadingSpace =
|
||||
PrintLeadingSpace::Yes) {
|
||||
return printAvailability(os, D, printLeadingSpace);
|
||||
}
|
||||
|
||||
public:
|
||||
/// Returns \c true if anything was printed.
|
||||
bool printAvailability(
|
||||
raw_ostream &os, const Decl *D,
|
||||
PrintLeadingSpace printLeadingSpace = PrintLeadingSpace::Yes) {
|
||||
bool hasPrintedAnything = false;
|
||||
auto maybePrintLeadingSpace = [&] {
|
||||
if (printLeadingSpace == PrintLeadingSpace::Yes || hasPrintedAnything)
|
||||
@@ -1543,17 +1559,17 @@ private:
|
||||
os << "SWIFT_UNAVAILABLE_MSG(\"'"
|
||||
<< cast<ValueDecl>(D)->getBaseName()
|
||||
<< "' has been renamed to '";
|
||||
printRenameForDecl(AvAttr, cast<ValueDecl>(D), false);
|
||||
printRenameForDecl(os, AvAttr, cast<ValueDecl>(D), false);
|
||||
os << '\'';
|
||||
if (!AvAttr->Message.empty()) {
|
||||
os << ": ";
|
||||
printEncodedString(AvAttr->Message, false);
|
||||
printEncodedString(os, AvAttr->Message, false);
|
||||
}
|
||||
os << "\")";
|
||||
} else if (!AvAttr->Message.empty()) {
|
||||
maybePrintLeadingSpace();
|
||||
os << "SWIFT_UNAVAILABLE_MSG(";
|
||||
printEncodedString(AvAttr->Message);
|
||||
printEncodedString(os, AvAttr->Message);
|
||||
os << ")";
|
||||
} else {
|
||||
maybePrintLeadingSpace();
|
||||
@@ -1565,10 +1581,10 @@ private:
|
||||
if (!AvAttr->Rename.empty() || !AvAttr->Message.empty()) {
|
||||
maybePrintLeadingSpace();
|
||||
os << "SWIFT_DEPRECATED_MSG(";
|
||||
printEncodedString(AvAttr->Message);
|
||||
printEncodedString(os, AvAttr->Message);
|
||||
if (!AvAttr->Rename.empty()) {
|
||||
os << ", ";
|
||||
printRenameForDecl(AvAttr, cast<ValueDecl>(D), true);
|
||||
printRenameForDecl(os, AvAttr, cast<ValueDecl>(D), true);
|
||||
}
|
||||
os << ")";
|
||||
} else {
|
||||
@@ -1655,24 +1671,25 @@ private:
|
||||
if (!AvAttr->Rename.empty() && isa<ValueDecl>(D)) {
|
||||
os << ",message=\"'" << cast<ValueDecl>(D)->getBaseName()
|
||||
<< "' has been renamed to '";
|
||||
printRenameForDecl(AvAttr, cast<ValueDecl>(D), false);
|
||||
printRenameForDecl(os, AvAttr, cast<ValueDecl>(D), false);
|
||||
os << '\'';
|
||||
if (!AvAttr->Message.empty()) {
|
||||
os << ": ";
|
||||
printEncodedString(AvAttr->Message, false);
|
||||
printEncodedString(os, AvAttr->Message, false);
|
||||
}
|
||||
os << "\"";
|
||||
} else if (!AvAttr->Message.empty()) {
|
||||
os << ",message=";
|
||||
printEncodedString(AvAttr->Message);
|
||||
printEncodedString(os, AvAttr->Message);
|
||||
}
|
||||
os << ")";
|
||||
}
|
||||
return hasPrintedAnything;
|
||||
}
|
||||
|
||||
void printRenameForDecl(const AvailableAttr *AvAttr, const ValueDecl *D,
|
||||
bool includeQuotes) {
|
||||
private:
|
||||
void printRenameForDecl(raw_ostream &os, const AvailableAttr *AvAttr,
|
||||
const ValueDecl *D, bool includeQuotes) {
|
||||
assert(!AvAttr->Rename.empty());
|
||||
|
||||
auto *renamedDecl = evaluateOrDefault(
|
||||
@@ -1683,9 +1700,9 @@ private:
|
||||
SmallString<128> scratch;
|
||||
auto renamedObjCRuntimeName =
|
||||
renamedDecl->getObjCRuntimeName()->getString(scratch);
|
||||
printEncodedString(renamedObjCRuntimeName, includeQuotes);
|
||||
printEncodedString(os, renamedObjCRuntimeName, includeQuotes);
|
||||
} else {
|
||||
printEncodedString(AvAttr->Rename, includeQuotes);
|
||||
printEncodedString(os, AvAttr->Rename, includeQuotes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1710,10 +1727,10 @@ private:
|
||||
os << "method";
|
||||
os << " '";
|
||||
auto nominal = VD->getDeclContext()->getSelfNominalTypeDecl();
|
||||
printEncodedString(nominal->getName().str(), /*includeQuotes=*/false);
|
||||
printEncodedString(os, nominal->getName().str(), /*includeQuotes=*/false);
|
||||
os << ".";
|
||||
SmallString<32> scratch;
|
||||
printEncodedString(VD->getName().getString(scratch),
|
||||
printEncodedString(os, VD->getName().getString(scratch),
|
||||
/*includeQuotes=*/false);
|
||||
os << "' uses '@objc' inference deprecated in Swift 4; add '@objc' to "
|
||||
<< "provide an Objective-C entrypoint\")";
|
||||
@@ -1812,7 +1829,6 @@ private:
|
||||
|
||||
if (outputLang == OutputLanguageMode::Cxx) {
|
||||
// FIXME: Documentation.
|
||||
// FIXME: availability.
|
||||
auto *getter = VD->getOpaqueAccessor(AccessorKind::Get);
|
||||
printAbstractFunctionAsMethod(getter, /*isStatic=*/VD->isStatic());
|
||||
if (auto *setter = VD->getOpaqueAccessor(AccessorKind::Set))
|
||||
@@ -2785,6 +2801,10 @@ void DeclAndTypePrinter::print(Type ty) {
|
||||
getImpl().print(ty, /*overridingOptionality*/None);
|
||||
}
|
||||
|
||||
void DeclAndTypePrinter::printAvailability(raw_ostream &os, const Decl *D) {
|
||||
getImpl().printAvailability(os, D);
|
||||
}
|
||||
|
||||
void DeclAndTypePrinter::printAdHocCategory(
|
||||
iterator_range<const ValueDecl * const *> members) {
|
||||
getImpl().printAdHocCategory(members);
|
||||
|
||||
@@ -81,6 +81,8 @@ public:
|
||||
void print(const Decl *D);
|
||||
void print(Type ty);
|
||||
|
||||
void printAvailability(raw_ostream &os, const Decl *D);
|
||||
|
||||
/// Is \p ED empty of members and protocol conformances to include?
|
||||
bool isEmptyExtensionDecl(const ExtensionDecl *ED);
|
||||
|
||||
|
||||
@@ -289,12 +289,14 @@ public:
|
||||
return;
|
||||
auto it = seenClangTypes.insert(clangType.getTypePtr());
|
||||
if (it.second)
|
||||
ClangValueTypePrinter::printClangTypeSwiftGenericTraits(os, typeDecl, &M);
|
||||
ClangValueTypePrinter::printClangTypeSwiftGenericTraits(os, typeDecl, &M,
|
||||
printer);
|
||||
}
|
||||
|
||||
void forwardDeclareCxxValueTypeIfNeeded(const NominalTypeDecl *NTD) {
|
||||
forwardDeclare(NTD,
|
||||
[&]() { ClangValueTypePrinter::forwardDeclType(os, NTD); });
|
||||
forwardDeclare(NTD, [&]() {
|
||||
ClangValueTypePrinter::forwardDeclType(os, NTD, printer);
|
||||
});
|
||||
}
|
||||
|
||||
void forwardDeclareType(const TypeDecl *TD) {
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "PrintClangClassType.h"
|
||||
#include "ClangSyntaxPrinter.h"
|
||||
#include "DeclAndTypePrinter.h"
|
||||
#include "PrintClangValueType.h"
|
||||
#include "swift/AST/Decl.h"
|
||||
#include "swift/IRGen/Linking.h"
|
||||
@@ -19,7 +20,8 @@
|
||||
using namespace swift;
|
||||
|
||||
void ClangClassTypePrinter::printClassTypeDecl(
|
||||
const ClassDecl *typeDecl, llvm::function_ref<void(void)> bodyPrinter) {
|
||||
const ClassDecl *typeDecl, llvm::function_ref<void(void)> bodyPrinter,
|
||||
DeclAndTypePrinter &declAndTypePrinter) {
|
||||
auto printCxxImplClassName = ClangValueTypePrinter::printCxxImplClassName;
|
||||
|
||||
ClangSyntaxPrinter printer(os);
|
||||
@@ -31,7 +33,9 @@ void ClangClassTypePrinter::printClassTypeDecl(
|
||||
// Print out a forward declaration of the "hidden" _impl class.
|
||||
printer.printNamespace(cxx_synthesis::getCxxImplNamespaceName(),
|
||||
[&](raw_ostream &os) {
|
||||
os << "class ";
|
||||
os << "class";
|
||||
declAndTypePrinter.printAvailability(os, typeDecl);
|
||||
os << ' ';
|
||||
printCxxImplClassName(os, typeDecl);
|
||||
os << ";\n";
|
||||
// Print out special functions, like functions that
|
||||
@@ -57,6 +61,7 @@ void ClangClassTypePrinter::printClassTypeDecl(
|
||||
}
|
||||
|
||||
os << "class";
|
||||
declAndTypePrinter.printAvailability(os, typeDecl);
|
||||
ClangSyntaxPrinter(os).printSymbolUSRAttribute(typeDecl);
|
||||
os << ' ';
|
||||
printer.printBaseName(typeDecl);
|
||||
@@ -83,7 +88,9 @@ void ClangClassTypePrinter::printClassTypeDecl(
|
||||
// Print out the "hidden" _impl class.
|
||||
printer.printNamespace(
|
||||
cxx_synthesis::getCxxImplNamespaceName(), [&](raw_ostream &os) {
|
||||
os << "class ";
|
||||
os << "class";
|
||||
declAndTypePrinter.printAvailability(os, typeDecl);
|
||||
os << ' ';
|
||||
printCxxImplClassName(os, typeDecl);
|
||||
os << " {\n";
|
||||
os << "public:\n";
|
||||
@@ -98,7 +105,7 @@ void ClangClassTypePrinter::printClassTypeDecl(
|
||||
|
||||
ClangValueTypePrinter::printTypeGenericTraits(
|
||||
os, typeDecl, typeMetadataFuncName, /*genericRequirements=*/{},
|
||||
typeDecl->getModuleContext());
|
||||
typeDecl->getModuleContext(), declAndTypePrinter);
|
||||
}
|
||||
|
||||
void ClangClassTypePrinter::printClassTypeReturnScaffold(
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace swift {
|
||||
|
||||
class ClassDecl;
|
||||
class ModuleDecl;
|
||||
class DeclAndTypePrinter;
|
||||
|
||||
/// Responsible for printing a Swift class decl or in C or C++ mode, to
|
||||
/// be included in a Swift module's generated clang header.
|
||||
@@ -30,7 +31,8 @@ public:
|
||||
|
||||
/// Print the C++ class definition that corresponds to the given Swift class.
|
||||
void printClassTypeDecl(const ClassDecl *typeDecl,
|
||||
llvm::function_ref<void(void)> bodyPrinter);
|
||||
llvm::function_ref<void(void)> bodyPrinter,
|
||||
DeclAndTypePrinter &declAndTypePrinter);
|
||||
|
||||
static void
|
||||
printClassTypeReturnScaffold(raw_ostream &os, const ClassDecl *type,
|
||||
|
||||
@@ -1377,6 +1377,7 @@ static StringRef getConstructorName(const AbstractFunctionDecl *FD) {
|
||||
}
|
||||
|
||||
void DeclAndTypeClangFunctionPrinter::printCxxMethod(
|
||||
DeclAndTypePrinter &declAndTypePrinter,
|
||||
const NominalTypeDecl *typeDeclContext, const AbstractFunctionDecl *FD,
|
||||
const LoweredFunctionSignature &signature, StringRef swiftSymbolName,
|
||||
Type resultTy, bool isStatic, bool isDefinition,
|
||||
@@ -1401,6 +1402,7 @@ void DeclAndTypeClangFunctionPrinter::printCxxMethod(
|
||||
resultTy, FunctionSignatureKind::CxxInlineThunk, modifiers);
|
||||
assert(!result.isUnsupported() && "C signature should be unsupported too");
|
||||
|
||||
declAndTypePrinter.printAvailability(os, FD);
|
||||
if (!isDefinition) {
|
||||
os << ";\n";
|
||||
return;
|
||||
@@ -1446,6 +1448,7 @@ static std::string remapPropertyName(const AccessorDecl *accessor,
|
||||
}
|
||||
|
||||
void DeclAndTypeClangFunctionPrinter::printCxxPropertyAccessorMethod(
|
||||
DeclAndTypePrinter &declAndTypePrinter,
|
||||
const NominalTypeDecl *typeDeclContext, const AccessorDecl *accessor,
|
||||
const LoweredFunctionSignature &signature, StringRef swiftSymbolName,
|
||||
Type resultTy, bool isStatic, bool isDefinition,
|
||||
@@ -1466,6 +1469,7 @@ void DeclAndTypeClangFunctionPrinter::printCxxPropertyAccessorMethod(
|
||||
accessor, signature, remapPropertyName(accessor, resultTy), resultTy,
|
||||
FunctionSignatureKind::CxxInlineThunk, modifiers);
|
||||
assert(!result.isUnsupported() && "C signature should be unsupported too!");
|
||||
declAndTypePrinter.printAvailability(os, accessor->getStorage());
|
||||
if (!isDefinition) {
|
||||
os << ";\n";
|
||||
return;
|
||||
@@ -1480,6 +1484,7 @@ void DeclAndTypeClangFunctionPrinter::printCxxPropertyAccessorMethod(
|
||||
}
|
||||
|
||||
void DeclAndTypeClangFunctionPrinter::printCxxSubscriptAccessorMethod(
|
||||
DeclAndTypePrinter &declAndTypePrinter,
|
||||
const NominalTypeDecl *typeDeclContext, const AccessorDecl *accessor,
|
||||
const LoweredFunctionSignature &signature, StringRef swiftSymbolName,
|
||||
Type resultTy, bool isDefinition,
|
||||
@@ -1494,6 +1499,7 @@ void DeclAndTypeClangFunctionPrinter::printCxxSubscriptAccessorMethod(
|
||||
printFunctionSignature(accessor, signature, "operator []", resultTy,
|
||||
FunctionSignatureKind::CxxInlineThunk, modifiers);
|
||||
assert(!result.isUnsupported() && "C signature should be unsupported too!");
|
||||
declAndTypePrinter.printAvailability(os, accessor->getStorage());
|
||||
if (!isDefinition) {
|
||||
os << ";\n";
|
||||
return;
|
||||
|
||||
@@ -119,6 +119,7 @@ public:
|
||||
/// Print the Swift method as C++ method declaration/definition, including
|
||||
/// constructors.
|
||||
void printCxxMethod(
|
||||
DeclAndTypePrinter &declAndTypePrinter,
|
||||
const NominalTypeDecl *typeDeclContext, const AbstractFunctionDecl *FD,
|
||||
const LoweredFunctionSignature &signature, StringRef swiftSymbolName,
|
||||
Type resultTy, bool isStatic, bool isDefinition,
|
||||
@@ -126,6 +127,7 @@ public:
|
||||
|
||||
/// Print the C++ getter/setter method signature.
|
||||
void printCxxPropertyAccessorMethod(
|
||||
DeclAndTypePrinter &declAndTypePrinter,
|
||||
const NominalTypeDecl *typeDeclContext, const AccessorDecl *accessor,
|
||||
const LoweredFunctionSignature &signature, StringRef swiftSymbolName,
|
||||
Type resultTy, bool isStatic, bool isDefinition,
|
||||
@@ -133,6 +135,7 @@ public:
|
||||
|
||||
/// Print the C++ subscript method.
|
||||
void printCxxSubscriptAccessorMethod(
|
||||
DeclAndTypePrinter &declAndTypePrinter,
|
||||
const NominalTypeDecl *typeDeclContext, const AccessorDecl *accessor,
|
||||
const LoweredFunctionSignature &signature, StringRef swiftSymbolName,
|
||||
Type resultTy, bool isDefinition,
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "PrintClangValueType.h"
|
||||
#include "ClangSyntaxPrinter.h"
|
||||
#include "DeclAndTypePrinter.h"
|
||||
#include "OutputLanguageMode.h"
|
||||
#include "PrimitiveTypeMapping.h"
|
||||
#include "SwiftToClangInteropContext.h"
|
||||
@@ -81,14 +82,16 @@ printCValueTypeStorageStruct(raw_ostream &os, const NominalTypeDecl *typeDecl,
|
||||
os << "};\n\n";
|
||||
}
|
||||
|
||||
void ClangValueTypePrinter::forwardDeclType(raw_ostream &os,
|
||||
const NominalTypeDecl *typeDecl) {
|
||||
void ClangValueTypePrinter::forwardDeclType(
|
||||
raw_ostream &os, const NominalTypeDecl *typeDecl,
|
||||
DeclAndTypePrinter &declAndTypePrinter) {
|
||||
if (typeDecl->isGeneric()) {
|
||||
auto genericSignature =
|
||||
typeDecl->getGenericSignature().getCanonicalSignature();
|
||||
ClangSyntaxPrinter(os).printGenericSignature(genericSignature);
|
||||
}
|
||||
os << "class";
|
||||
declAndTypePrinter.printAvailability(os, typeDecl);
|
||||
ClangSyntaxPrinter(os).printSymbolUSRAttribute(typeDecl);
|
||||
os << ' ';
|
||||
ClangSyntaxPrinter(os).printBaseName(typeDecl);
|
||||
@@ -173,8 +176,8 @@ static void addCppExtensionsToStdlibType(const NominalTypeDecl *typeDecl,
|
||||
}
|
||||
|
||||
void ClangValueTypePrinter::printValueTypeDecl(
|
||||
const NominalTypeDecl *typeDecl,
|
||||
llvm::function_ref<void(void)> bodyPrinter) {
|
||||
const NominalTypeDecl *typeDecl, llvm::function_ref<void(void)> bodyPrinter,
|
||||
DeclAndTypePrinter &declAndTypePrinter) {
|
||||
// FIXME: Add support for generic structs.
|
||||
llvm::Optional<IRABIDetailsProvider::SizeAndAlignment> typeSizeAlign;
|
||||
Optional<CanGenericSignature> genericSignature;
|
||||
@@ -221,7 +224,9 @@ void ClangValueTypePrinter::printValueTypeDecl(
|
||||
printer.printNamespace(cxx_synthesis::getCxxImplNamespaceName(),
|
||||
[&](raw_ostream &os) {
|
||||
printGenericSignature(os);
|
||||
os << "class ";
|
||||
os << "class";
|
||||
declAndTypePrinter.printAvailability(os, typeDecl);
|
||||
os << ' ';
|
||||
printCxxImplClassName(os, typeDecl);
|
||||
os << ";\n\n";
|
||||
|
||||
@@ -263,6 +268,7 @@ void ClangValueTypePrinter::printValueTypeDecl(
|
||||
// Print out the C++ class itself.
|
||||
printGenericSignature(os);
|
||||
os << "class";
|
||||
declAndTypePrinter.printAvailability(os, typeDecl);
|
||||
ClangSyntaxPrinter(os).printSymbolUSRAttribute(typeDecl);
|
||||
os << ' ';
|
||||
ClangSyntaxPrinter(os).printBaseName(typeDecl);
|
||||
@@ -408,7 +414,9 @@ void ClangValueTypePrinter::printValueTypeDecl(
|
||||
printer.printNamespace(
|
||||
cxx_synthesis::getCxxImplNamespaceName(), [&](raw_ostream &os) {
|
||||
printGenericSignature(os);
|
||||
os << "class ";
|
||||
os << "class";
|
||||
declAndTypePrinter.printAvailability(os, typeDecl);
|
||||
os << ' ';
|
||||
printCxxImplClassName(os, typeDecl);
|
||||
os << " {\n";
|
||||
os << "public:\n";
|
||||
@@ -461,7 +469,7 @@ void ClangValueTypePrinter::printValueTypeDecl(
|
||||
|
||||
printTypeGenericTraits(os, typeDecl, typeMetadataFuncName,
|
||||
typeMetadataFuncGenericParams,
|
||||
typeDecl->getModuleContext());
|
||||
typeDecl->getModuleContext(), declAndTypePrinter);
|
||||
}
|
||||
|
||||
void ClangValueTypePrinter::printParameterCxxToCUseScaffold(
|
||||
@@ -512,8 +520,8 @@ void ClangValueTypePrinter::printValueTypeReturnScaffold(
|
||||
}
|
||||
|
||||
void ClangValueTypePrinter::printClangTypeSwiftGenericTraits(
|
||||
raw_ostream &os, const TypeDecl *typeDecl,
|
||||
const ModuleDecl *moduleContext) {
|
||||
raw_ostream &os, const TypeDecl *typeDecl, const ModuleDecl *moduleContext,
|
||||
DeclAndTypePrinter &declAndTypePrinter) {
|
||||
assert(typeDecl->hasClangNode());
|
||||
// Do not reference unspecialized templates.
|
||||
if (isa<clang::ClassTemplateDecl>(typeDecl->getClangDecl()))
|
||||
@@ -522,7 +530,8 @@ void ClangValueTypePrinter::printClangTypeSwiftGenericTraits(
|
||||
typeDecl->getDeclaredInterfaceType()->getCanonicalType());
|
||||
std::string typeMetadataFuncName = typeMetadataFunc.mangleAsString();
|
||||
printTypeGenericTraits(os, typeDecl, typeMetadataFuncName,
|
||||
/*typeMetadataFuncRequirements=*/{}, moduleContext);
|
||||
/*typeMetadataFuncRequirements=*/{}, moduleContext,
|
||||
declAndTypePrinter);
|
||||
}
|
||||
|
||||
void ClangValueTypePrinter::printTypePrecedingGenericTraits(
|
||||
@@ -553,7 +562,7 @@ void ClangValueTypePrinter::printTypePrecedingGenericTraits(
|
||||
void ClangValueTypePrinter::printTypeGenericTraits(
|
||||
raw_ostream &os, const TypeDecl *typeDecl, StringRef typeMetadataFuncName,
|
||||
ArrayRef<GenericRequirement> typeMetadataFuncRequirements,
|
||||
const ModuleDecl *moduleContext) {
|
||||
const ModuleDecl *moduleContext, DeclAndTypePrinter &declAndTypePrinter) {
|
||||
auto *NTD = dyn_cast<NominalTypeDecl>(typeDecl);
|
||||
ClangSyntaxPrinter printer(os);
|
||||
// FIXME: avoid popping out of the module's namespace here.
|
||||
@@ -580,7 +589,9 @@ void ClangValueTypePrinter::printTypeGenericTraits(
|
||||
}
|
||||
if (!NTD || printer.printNominalTypeOutsideMemberDeclTemplateSpecifiers(NTD))
|
||||
os << "template<>\n";
|
||||
os << "struct TypeMetadataTrait<";
|
||||
os << "struct";
|
||||
declAndTypePrinter.printAvailability(os, typeDecl);
|
||||
os << " TypeMetadataTrait<";
|
||||
if (typeDecl->hasClangNode()) {
|
||||
printer.printClangTypeReference(typeDecl->getClangDecl());
|
||||
} else {
|
||||
@@ -635,7 +646,9 @@ void ClangValueTypePrinter::printTypeGenericTraits(
|
||||
if (!typeDecl->hasClangNode() && typeMetadataFuncRequirements.empty()) {
|
||||
assert(NTD);
|
||||
os << "template<>\n";
|
||||
os << "struct implClassFor<";
|
||||
os << "struct";
|
||||
declAndTypePrinter.printAvailability(os, typeDecl);
|
||||
os << " implClassFor<";
|
||||
printer.printBaseName(typeDecl->getModuleContext());
|
||||
os << "::";
|
||||
printer.printBaseName(typeDecl);
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
namespace swift {
|
||||
|
||||
class DeclAndTypePrinter;
|
||||
class ModuleDecl;
|
||||
class NominalTypeDecl;
|
||||
class PrimitiveTypeMapping;
|
||||
@@ -39,7 +40,9 @@ public:
|
||||
/// Print the C++ class definition that
|
||||
/// corresponds to the given structure or enum declaration.
|
||||
void printValueTypeDecl(const NominalTypeDecl *typeDecl,
|
||||
llvm::function_ref<void(void)> bodyPrinter);
|
||||
llvm::function_ref<void(void)> bodyPrinter,
|
||||
|
||||
DeclAndTypePrinter &declAndTypePrinter);
|
||||
|
||||
/// Print the use of a C++ struct/enum parameter value as it's passed to the
|
||||
/// underlying C function that represents the native Swift function.
|
||||
@@ -93,19 +96,21 @@ public:
|
||||
static void printTypeGenericTraits(
|
||||
raw_ostream &os, const TypeDecl *typeDecl, StringRef typeMetadataFuncName,
|
||||
ArrayRef<GenericRequirement> typeMetadataFuncRequirements,
|
||||
const ModuleDecl *moduleContext);
|
||||
const ModuleDecl *moduleContext, DeclAndTypePrinter &declAndTypePrinter);
|
||||
|
||||
static void printTypePrecedingGenericTraits(raw_ostream &os,
|
||||
const NominalTypeDecl *typeDecl,
|
||||
const ModuleDecl *moduleContext);
|
||||
|
||||
static void forwardDeclType(raw_ostream &os, const NominalTypeDecl *typeDecl);
|
||||
static void forwardDeclType(raw_ostream &os, const NominalTypeDecl *typeDecl,
|
||||
DeclAndTypePrinter &declAndTypePrinter);
|
||||
|
||||
/// Print out the type traits that allow a C++ type be used a Swift generic
|
||||
/// context.
|
||||
static void printClangTypeSwiftGenericTraits(raw_ostream &os,
|
||||
const TypeDecl *typeDecl,
|
||||
const ModuleDecl *moduleContext);
|
||||
static void
|
||||
printClangTypeSwiftGenericTraits(raw_ostream &os, const TypeDecl *typeDecl,
|
||||
const ModuleDecl *moduleContext,
|
||||
DeclAndTypePrinter &declAndTypePrinter);
|
||||
|
||||
private:
|
||||
raw_ostream &os;
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-swift-frontend %s -typecheck -module-name Class -clang-header-expose-decls=all-public -emit-clang-header-path %t/class.h
|
||||
// RUN: %FileCheck %s < %t/class.h
|
||||
|
||||
// RUN: %check-interop-cxx-header-in-clang(%t/class.h)
|
||||
|
||||
@available(macOS 11, *)
|
||||
public final class ClassWithMacAvailability {
|
||||
var field: Int64
|
||||
|
||||
init() {
|
||||
field = 0
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: class SWIFT_AVAILABILITY(macos,introduced=11) _impl_ClassWithMacAvailability;
|
||||
// CHECK: class SWIFT_AVAILABILITY(macos,introduced=11) SWIFT_SYMBOL("s:5Class0A19WithMacAvailabilityC") ClassWithMacAvailability final
|
||||
// CHECK: class SWIFT_AVAILABILITY(macos,introduced=11) _impl_ClassWithMacAvailability {
|
||||
// CHECK: struct SWIFT_AVAILABILITY(macos,introduced=11) TypeMetadataTrait<Class::ClassWithMacAvailability> {
|
||||
// CHECK: struct SWIFT_AVAILABILITY(macos,introduced=11) implClassFor<Class::ClassWithMacAvailability>
|
||||
|
||||
@available(*, unavailable, message: "stuff happened")
|
||||
public final class ClassWithUnavailable {
|
||||
var field: Int64
|
||||
|
||||
init() {
|
||||
field = 0
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: class SWIFT_UNAVAILABLE_MSG("stuff happened") _impl_ClassWithUnavailable;
|
||||
// CHECK: class SWIFT_UNAVAILABLE_MSG("stuff happened") SWIFT_SYMBOL("s:5Class0A15WithUnavailableC") ClassWithUnavailable final
|
||||
// CHECK: class SWIFT_UNAVAILABLE_MSG("stuff happened") _impl_ClassWithUnavailable {
|
||||
// CHECK: struct SWIFT_UNAVAILABLE_MSG("stuff happened") TypeMetadataTrait<Class::ClassWithUnavailable> {
|
||||
// CHECK: struct SWIFT_UNAVAILABLE_MSG("stuff happened") implClassFor<Class::ClassWithUnavailable>
|
||||
@@ -0,0 +1,23 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-swift-frontend %s -typecheck -module-name Methods -clang-header-expose-decls=all-public -emit-clang-header-path %t/methods.h
|
||||
// RUN: %FileCheck %s < %t/methods.h
|
||||
|
||||
// RUN: %check-interop-cxx-header-in-clang(%t/methods.h)
|
||||
|
||||
public struct Struct {
|
||||
var field: Int16
|
||||
|
||||
init() {
|
||||
field = 0
|
||||
}
|
||||
|
||||
|
||||
@available(macOS 11, *)
|
||||
public init(_ field: Int16) {
|
||||
self.field = field
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: static SWIFT_INLINE_THUNK Struct init(int16_t field) SWIFT_SYMBOL("s:7Methods6StructVyACs5Int16Vcfc") SWIFT_AVAILABILITY(macos,introduced=11);
|
||||
|
||||
// CHECK: SWIFT_INLINE_THUNK Struct Struct::init(int16_t field) SWIFT_AVAILABILITY(macos,introduced=11) {
|
||||
@@ -0,0 +1,40 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-swift-frontend %s -typecheck -module-name Methods -clang-header-expose-decls=all-public -emit-clang-header-path %t/methods.h
|
||||
// RUN: %FileCheck %s < %t/methods.h
|
||||
|
||||
// RUN: %check-interop-cxx-header-in-clang(%t/methods.h)
|
||||
|
||||
public struct Struct {
|
||||
var field: Int16
|
||||
|
||||
init() {
|
||||
field = 0
|
||||
}
|
||||
|
||||
@available(macOS 11, *)
|
||||
public func method() {}
|
||||
|
||||
@available(macOS 11, *)
|
||||
public static func staticMethod() {}
|
||||
|
||||
@available(*, unavailable, message: "stuff happened")
|
||||
public func unavailableMethod() {}
|
||||
|
||||
@available(macOS 11, *)
|
||||
public subscript (_ x: Int) -> Int {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: SWIFT_INLINE_THUNK void method() const SWIFT_SYMBOL("s:7Methods6StructV6methodyyF") SWIFT_AVAILABILITY(macos,introduced=11);
|
||||
// CHECK: static SWIFT_INLINE_THUNK void staticMethod() SWIFT_SYMBOL("s:7Methods6StructV12staticMethodyyFZ") SWIFT_AVAILABILITY(macos,introduced=11);
|
||||
// CHECK: SWIFT_INLINE_THUNK void unavailableMethod() const SWIFT_SYMBOL("s:7Methods6StructV17unavailableMethodyyF") SWIFT_UNAVAILABLE_MSG("stuff happened");
|
||||
// CHECK: SWIFT_INLINE_THUNK swift::Int operator [](swift::Int x) const SWIFT_SYMBOL("s:7Methods6StructVyS2icig") SWIFT_AVAILABILITY(macos,introduced=11);
|
||||
|
||||
// CHECK: SWIFT_INLINE_THUNK void Struct::method() const SWIFT_AVAILABILITY(macos,introduced=11) {
|
||||
|
||||
// CHECK: SWIFT_INLINE_THUNK void Struct::staticMethod() SWIFT_AVAILABILITY(macos,introduced=11) {
|
||||
|
||||
// CHECK: SWIFT_INLINE_THUNK void Struct::unavailableMethod() const SWIFT_UNAVAILABLE_MSG("stuff happened") {
|
||||
|
||||
// CHECK: SWIFT_INLINE_THUNK swift::Int Struct::operator [](swift::Int x) const SWIFT_SYMBOL("s:7Methods6StructVyS2icig") SWIFT_AVAILABILITY(macos,introduced=11)
|
||||
@@ -0,0 +1,30 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-swift-frontend %s -typecheck -module-name Methods -clang-header-expose-decls=all-public -emit-clang-header-path %t/methods.h
|
||||
// RUN: %FileCheck %s < %t/methods.h
|
||||
|
||||
// RUN: %check-interop-cxx-header-in-clang(%t/methods.h)
|
||||
|
||||
public struct Struct {
|
||||
public var field: Int16
|
||||
|
||||
init() {
|
||||
field = 0
|
||||
}
|
||||
|
||||
@available(macOS 11, *)
|
||||
public var getterOnly: Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
@available(*, unavailable, message: "stuff happened")
|
||||
public static var staticUnavailableProp: Int {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: SWIFT_INLINE_THUNK swift::Int getGetterOnly() const SWIFT_SYMBOL("s:7Methods6StructV10getterOnlySivp") SWIFT_AVAILABILITY(macos,introduced=11);
|
||||
// CHECK: static SWIFT_INLINE_THUNK swift::Int getStaticUnavailableProp() SWIFT_SYMBOL("s:7Methods6StructV21staticUnavailablePropSivpZ") SWIFT_UNAVAILABLE_MSG("stuff happened");
|
||||
|
||||
// CHECK: SWIFT_INLINE_THUNK swift::Int Struct::getGetterOnly() const SWIFT_AVAILABILITY(macos,introduced=11) {
|
||||
|
||||
// CHECK: SWIFT_INLINE_THUNK swift::Int Struct::getStaticUnavailableProp() SWIFT_UNAVAILABLE_MSG("stuff happened") {
|
||||
@@ -0,0 +1,37 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-swift-frontend %s -typecheck -module-name Struct -clang-header-expose-decls=all-public -emit-clang-header-path %t/struct.h
|
||||
// RUN: %FileCheck %s < %t/struct.h
|
||||
|
||||
// RUN: %check-interop-cxx-header-in-clang(%t/struct.h)
|
||||
|
||||
@available(macOS 11, *)
|
||||
public struct StructWithMacAvailability {
|
||||
var field: Int16
|
||||
|
||||
init() {
|
||||
field = 0
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: class SWIFT_AVAILABILITY(macos,introduced=11) SWIFT_SYMBOL("s:6Struct0A19WithMacAvailabilityV") StructWithMacAvailability;
|
||||
|
||||
// CHECK: class SWIFT_AVAILABILITY(macos,introduced=11) _impl_StructWithMacAvailability;
|
||||
// CHECK: class SWIFT_AVAILABILITY(macos,introduced=11) SWIFT_SYMBOL("s:6Struct0A19WithMacAvailabilityV") StructWithMacAvailability final {
|
||||
// CHECK: class SWIFT_AVAILABILITY(macos,introduced=11) _impl_StructWithMacAvailability {
|
||||
// CHECK: struct SWIFT_AVAILABILITY(macos,introduced=11) TypeMetadataTrait<Struct::StructWithMacAvailability> {
|
||||
// CHECK: struct SWIFT_AVAILABILITY(macos,introduced=11) implClassFor<Struct::StructWithMacAvailability>
|
||||
|
||||
@available(*, unavailable, message: "stuff happened")
|
||||
public struct StructWithUnavailable {
|
||||
var field: Int16
|
||||
|
||||
init() {
|
||||
field = 0
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: class SWIFT_UNAVAILABLE_MSG("stuff happened") _impl_StructWithUnavailable;
|
||||
// CHECK: class SWIFT_UNAVAILABLE_MSG("stuff happened") SWIFT_SYMBOL("s:6Struct0A15WithUnavailableV") StructWithUnavailable final
|
||||
// CHECK: class SWIFT_UNAVAILABLE_MSG("stuff happened") _impl_StructWithUnavailable {
|
||||
// CHECK: struct SWIFT_UNAVAILABLE_MSG("stuff happened") TypeMetadataTrait<Struct::StructWithUnavailable> {
|
||||
// CHECK: struct SWIFT_UNAVAILABLE_MSG("stuff happened") implClassFor<Struct::StructWithUnavailable>
|
||||
Reference in New Issue
Block a user