|
19 | 19 | #ifndef SWIFT_DEMANGLING_DEMANGLE_H
|
20 | 20 | #define SWIFT_DEMANGLING_DEMANGLE_H
|
21 | 21 |
|
22 |
| -#include <memory> |
23 |
| -#include <string> |
| 22 | +#include "swift/Demangling/NamespaceMacros.h" |
| 23 | +#include "swift/Runtime/Config.h" |
| 24 | +#include "llvm/ADT/StringRef.h" |
24 | 25 | #include <cassert>
|
25 | 26 | #include <cstdint>
|
26 |
| -#include "llvm/ADT/StringRef.h" |
27 |
| -#include "swift/Demangling/NamespaceMacros.h" |
| 27 | +#include <memory> |
| 28 | +#include <string> |
28 | 29 |
|
29 | 30 | namespace llvm {
|
30 | 31 | class raw_ostream;
|
@@ -512,42 +513,113 @@ enum class OperatorKind {
|
512 | 513 | Infix,
|
513 | 514 | };
|
514 | 515 |
|
| 516 | +/// A mangling error, which consists of an error code and a Node pointer |
| 517 | +struct SWIFT_NODISCARD ManglingError { |
| 518 | + enum Code { |
| 519 | + Success = 0, |
| 520 | + AssertionFailed, |
| 521 | + Uninitialized, |
| 522 | + TooComplex, |
| 523 | + BadNodeKind, |
| 524 | + BadNominalTypeKind, |
| 525 | + NotAStorageNode, |
| 526 | + UnsupportedNodeKind, |
| 527 | + UnexpectedBuiltinVectorType, |
| 528 | + UnexpectedBuiltinType, |
| 529 | + MultipleChildNodes, |
| 530 | + WrongNodeType, |
| 531 | + WrongDependentMemberType, |
| 532 | + BadDirectness, |
| 533 | + UnknownEncoding, |
| 534 | + InvalidImplCalleeConvention, |
| 535 | + InvalidImplDifferentiability, |
| 536 | + InvalidImplFunctionAttribute, |
| 537 | + InvalidImplParameterConvention, |
| 538 | + InvalidMetatypeRepresentation, |
| 539 | + MultiByteRelatedEntity, |
| 540 | + BadValueWitnessKind, |
| 541 | + NotAContextNode, |
| 542 | + }; |
| 543 | + |
| 544 | + Code code; |
| 545 | + NodePointer node; |
| 546 | + unsigned line; |
| 547 | + |
| 548 | + ManglingError() : code(Uninitialized), node(nullptr) {} |
| 549 | + ManglingError(Code c) : code(c), node(nullptr), line(0) {} |
| 550 | + ManglingError(Code c, NodePointer n, unsigned l) : code(c), node(n), line(l) {} |
| 551 | + |
| 552 | + bool isSuccess() const { return code == Success; } |
| 553 | +}; |
| 554 | + |
| 555 | +#define MANGLING_ERROR(c,n) ManglingError((c), (n), __LINE__) |
| 556 | + |
| 557 | +/// Used as a return type for mangling functions that may fail |
| 558 | +template <typename T> |
| 559 | +class SWIFT_NODISCARD ManglingErrorOr { |
| 560 | +private: |
| 561 | + ManglingError err_; |
| 562 | + T value_; |
| 563 | + |
| 564 | +public: |
| 565 | + ManglingErrorOr() : err_() {} |
| 566 | + ManglingErrorOr(ManglingError::Code code, |
| 567 | + NodePointer node = nullptr, |
| 568 | + unsigned line = 0) |
| 569 | + : err_(code, node, line) {} |
| 570 | + ManglingErrorOr(const ManglingError &err) : err_(err) {} |
| 571 | + ManglingErrorOr(const T &t) : err_(ManglingError::Success), value_(t) {} |
| 572 | + ManglingErrorOr(T &&t) : err_(ManglingError::Success), value_(std::move(t)) {} |
| 573 | + |
| 574 | + bool isSuccess() const { return err_.code == ManglingError::Success; } |
| 575 | + |
| 576 | + const ManglingError &error() const { return err_; } |
| 577 | + |
| 578 | + const T &result() const { |
| 579 | + assert(isSuccess()); |
| 580 | + return value_; |
| 581 | + } |
| 582 | +}; |
| 583 | + |
515 | 584 | /// Remangle a demangled parse tree.
|
516 |
| -std::string mangleNode(NodePointer root); |
| 585 | +ManglingErrorOr<std::string> mangleNode(NodePointer root); |
517 | 586 |
|
518 | 587 | using SymbolicResolver =
|
519 | 588 | llvm::function_ref<Demangle::NodePointer (SymbolicReferenceKind,
|
520 | 589 | const void *)>;
|
521 | 590 |
|
522 | 591 | /// Remangle a demangled parse tree, using a callback to resolve
|
523 | 592 | /// symbolic references.
|
524 |
| -std::string mangleNode(NodePointer root, SymbolicResolver resolver); |
| 593 | +ManglingErrorOr<std::string> mangleNode(NodePointer root, SymbolicResolver resolver); |
525 | 594 |
|
526 | 595 | /// Remangle a demangled parse tree, using a callback to resolve
|
527 | 596 | /// symbolic references.
|
528 | 597 | ///
|
529 | 598 | /// The returned string is owned by \p Factory. This means \p Factory must stay
|
530 | 599 | /// alive as long as the returned string is used.
|
531 |
| -llvm::StringRef mangleNode(NodePointer root, SymbolicResolver resolver, |
532 |
| - NodeFactory &Factory); |
| 600 | +ManglingErrorOr<llvm::StringRef> mangleNode(NodePointer root, |
| 601 | + SymbolicResolver resolver, |
| 602 | + NodeFactory &Factory); |
533 | 603 |
|
534 | 604 | /// Remangle in the old mangling scheme.
|
535 | 605 | ///
|
536 | 606 | /// This is only used for objc-runtime names.
|
537 |
| -std::string mangleNodeOld(NodePointer root); |
| 607 | +ManglingErrorOr<std::string> mangleNodeOld(NodePointer root); |
538 | 608 |
|
539 | 609 | /// Remangle in the old mangling scheme.
|
540 | 610 | ///
|
541 | 611 | /// This is only used for objc-runtime names.
|
542 | 612 | /// The returned string is owned by \p Factory. This means \p Factory must stay
|
543 | 613 | /// alive as long as the returned string is used.
|
544 |
| -llvm::StringRef mangleNodeOld(NodePointer node, NodeFactory &Factory); |
| 614 | +ManglingErrorOr<llvm::StringRef> mangleNodeOld(NodePointer node, |
| 615 | + NodeFactory &Factory); |
545 | 616 |
|
546 | 617 | /// Remangle in the old mangling scheme and embed the name in "_Tt<name>_".
|
547 | 618 | ///
|
548 | 619 | /// The returned string is null terminated and owned by \p Factory. This means
|
549 | 620 | /// \p Factory must stay alive as long as the returned string is used.
|
550 |
| -const char *mangleNodeAsObjcCString(NodePointer node, NodeFactory &Factory); |
| 621 | +ManglingErrorOr<const char *> mangleNodeAsObjcCString(NodePointer node, |
| 622 | + NodeFactory &Factory); |
551 | 623 |
|
552 | 624 | /// Transform the node structure to a string.
|
553 | 625 | ///
|
@@ -626,7 +698,7 @@ bool nodeConsumesGenericArgs(Node *node);
|
626 | 698 |
|
627 | 699 | bool isSpecialized(Node *node);
|
628 | 700 |
|
629 |
| -NodePointer getUnspecialized(Node *node, NodeFactory &Factory); |
| 701 | +ManglingErrorOr<NodePointer> getUnspecialized(Node *node, NodeFactory &Factory); |
630 | 702 |
|
631 | 703 | /// Returns true if the node \p kind refers to a context node, e.g. a nominal
|
632 | 704 | /// type or a function.
|
|
0 commit comments