|
15 | 15 | #include "PrimitiveTypeMapping.h" |
16 | 16 | #include "PrintClangFunction.h" |
17 | 17 | #include "PrintClangValueType.h" |
| 18 | +#include "SwiftToClangInteropContext.h" |
18 | 19 |
|
19 | 20 | #include "swift/AST/ASTContext.h" |
20 | 21 | #include "swift/AST/ASTMangler.h" |
|
31 | 32 | #include "swift/AST/TypeCheckRequests.h" |
32 | 33 | #include "swift/AST/TypeVisitor.h" |
33 | 34 | #include "swift/IDE/CommentConversion.h" |
| 35 | +#include "swift/IRGen/IRABIDetailsProvider.h" |
34 | 36 | #include "swift/IRGen/Linking.h" |
35 | 37 | #include "swift/Parse/Lexer.h" |
36 | 38 | #include "swift/Parse/Parser.h" |
@@ -384,30 +386,67 @@ class DeclAndTypePrinter::Implementation |
384 | 386 | os << "@end\n"; |
385 | 387 | } |
386 | 388 |
|
| 389 | + void visitEnumDeclCxx(EnumDecl *ED) { |
| 390 | + // FIXME: Print enum's availability |
| 391 | + ClangValueTypePrinter printer(os, owningPrinter.prologueOS, |
| 392 | + owningPrinter.typeMapping, |
| 393 | + owningPrinter.interopContext); |
| 394 | + printer.printValueTypeDecl(ED, /*bodyPrinter=*/[&]() { |
| 395 | + ClangSyntaxPrinter syntaxPrinter(os); |
| 396 | + auto elementTagMapping = |
| 397 | + owningPrinter.interopContext.getIrABIDetails().getEnumTagMapping(ED); |
| 398 | + // Sort cases based on their assigned tag indices |
| 399 | + llvm::stable_sort(elementTagMapping, [](const auto &p1, const auto &p2) { |
| 400 | + return p1.second < p2.second; |
| 401 | + }); |
| 402 | + |
| 403 | + if (elementTagMapping.empty()) { |
| 404 | + os << "\n"; |
| 405 | + return; |
| 406 | + } |
| 407 | + |
| 408 | + os << " enum class cases {\n"; |
| 409 | + for (const auto &pair : elementTagMapping) { |
| 410 | + os << " "; |
| 411 | + syntaxPrinter.printIdentifier(pair.first->getNameStr()); |
| 412 | + os << ",\n"; |
| 413 | + } |
| 414 | + os << " };\n"; // enum class cases' closing bracket |
| 415 | + |
| 416 | + // Printing operator cases() |
| 417 | + os << " inline operator cases() const {\n"; |
| 418 | + os << " switch (_getEnumTag()) {\n"; |
| 419 | + for (const auto &pair : elementTagMapping) { |
| 420 | + os << " case " << pair.second << ": return cases::"; |
| 421 | + syntaxPrinter.printIdentifier(pair.first->getNameStr()); |
| 422 | + os << ";\n"; |
| 423 | + } |
| 424 | + // TODO: change to Swift's fatalError when it's available in C++ |
| 425 | + os << " default: abort();\n"; |
| 426 | + os << " }\n"; // switch's closing bracket |
| 427 | + os << " }\n"; // operator cases()'s closing bracket |
| 428 | + |
| 429 | + // Printing predicates |
| 430 | + for (const auto &pair : elementTagMapping) { |
| 431 | + os << " inline bool is"; |
| 432 | + auto name = pair.first->getNameStr().str(); |
| 433 | + name[0] = std::toupper(name[0]); |
| 434 | + os << name << "() const {\n"; |
| 435 | + os << " return *this == cases::"; |
| 436 | + syntaxPrinter.printIdentifier(pair.first->getNameStr()); |
| 437 | + os << ";\n }\n"; |
| 438 | + } |
| 439 | + os << "\n"; |
| 440 | + }); |
| 441 | + os << outOfLineDefinitions; |
| 442 | + outOfLineDefinitions.clear(); |
| 443 | + } |
| 444 | + |
387 | 445 | void visitEnumDecl(EnumDecl *ED) { |
388 | 446 | printDocumentationComment(ED); |
389 | 447 |
|
390 | 448 | if (outputLang == OutputLanguageMode::Cxx) { |
391 | | - // FIXME: Print enum's availability |
392 | | - ClangValueTypePrinter printer(os, owningPrinter.prologueOS, |
393 | | - owningPrinter.typeMapping, |
394 | | - owningPrinter.interopContext); |
395 | | - printer.printValueTypeDecl(ED, /*bodyPrinter=*/[&]() { |
396 | | - ClangSyntaxPrinter syntaxPrinter(os); |
397 | | - os << " enum class cases {"; |
398 | | - llvm::interleaveComma( |
399 | | - ED->getAllCases(), os, [&](const EnumCaseDecl *caseDecl) { |
400 | | - llvm::interleaveComma(caseDecl->getElements(), os, |
401 | | - [&](const EnumElementDecl *elementDecl) { |
402 | | - os << "\n "; |
403 | | - syntaxPrinter.printIdentifier( |
404 | | - elementDecl->getNameStr()); |
405 | | - }); |
406 | | - }); |
407 | | - os << "\n };\n"; |
408 | | - }); |
409 | | - os << outOfLineDefinitions; |
410 | | - outOfLineDefinitions.clear(); |
| 449 | + visitEnumDeclCxx(ED); |
411 | 450 | return; |
412 | 451 | } |
413 | 452 |
|
|
0 commit comments