|
27 | 27 | #include "llvm/ADT/PointerUnion.h"
|
28 | 28 | #include "llvm/ADT/STLExtras.h"
|
29 | 29 | #include "llvm/Support/ErrorHandling.h"
|
| 30 | +#include "llvm/Support/TrailingObjects.h" |
30 | 31 |
|
31 | 32 | namespace swift {
|
32 | 33 | class ASTWalker;
|
33 | 34 | class DeclContext;
|
34 | 35 | class IdentTypeRepr;
|
35 | 36 | class ValueDecl;
|
36 |
| - class NamedTypeRepr; |
37 | 37 |
|
38 | 38 | enum class TypeReprKind : uint8_t {
|
39 | 39 | #define TYPEREPR(ID, PARENT) ID,
|
@@ -100,10 +100,14 @@ class alignas(8) TypeRepr {
|
100 | 100 | void *operator new(size_t bytes, const ASTContext &C,
|
101 | 101 | unsigned Alignment = alignof(TypeRepr));
|
102 | 102 |
|
| 103 | + void *operator new(size_t bytes, void *data) { |
| 104 | + assert(data); |
| 105 | + return data; |
| 106 | + } |
| 107 | + |
103 | 108 | // Make placement new and vanilla new/delete illegal for TypeReprs.
|
104 | 109 | void *operator new(size_t bytes) = delete;
|
105 | 110 | void operator delete(void *data) = delete;
|
106 |
| - void *operator new(size_t bytes, void *data) = delete; |
107 | 111 |
|
108 | 112 | void print(raw_ostream &OS, const PrintOptions &Opts = PrintOptions()) const;
|
109 | 113 | void print(ASTPrinter &Printer, const PrintOptions &Opts) const;
|
@@ -536,96 +540,133 @@ class ImplicitlyUnwrappedOptionalTypeRepr : public TypeRepr {
|
536 | 540 | /// \brief A tuple type.
|
537 | 541 | /// \code
|
538 | 542 | /// (Foo, Bar)
|
| 543 | +/// (x: Foo) |
| 544 | +/// (_ x: Foo) |
539 | 545 | /// \endcode
|
540 |
| -class TupleTypeRepr : public TypeRepr { |
541 |
| - ArrayRef<TypeRepr *> Elements; |
| 546 | +class TupleTypeRepr final : public TypeRepr, |
| 547 | + private llvm::TrailingObjects<TupleTypeRepr, TypeRepr*, Identifier, |
| 548 | + SourceLoc, std::pair<SourceLoc, unsigned>> { |
| 549 | + friend TrailingObjects; |
| 550 | + typedef std::pair<SourceLoc, unsigned> SourceLocAndIdx; |
| 551 | + |
| 552 | + unsigned NumElements; |
542 | 553 | SourceRange Parens;
|
543 |
| - // FIXME: Tail allocation. |
544 |
| - SourceLoc Ellipsis; |
545 |
| - unsigned EllipsisIdx; |
546 | 554 |
|
547 |
| -public: |
| 555 | + enum { |
| 556 | + NotNamed = 0, |
| 557 | + HasNames = 1, |
| 558 | + HasLabels = 2 |
| 559 | + } NameStatus : 2; |
| 560 | + bool HasEllipsis : 1; |
| 561 | + |
| 562 | + size_t numTrailingObjects(OverloadToken<TypeRepr *>) const { |
| 563 | + return NumElements; |
| 564 | + } |
| 565 | + size_t numTrailingObjects(OverloadToken<Identifier>) const { |
| 566 | + return NameStatus >= HasNames ? NumElements : 0; |
| 567 | + } |
| 568 | + size_t numTrailingObjects(OverloadToken<SourceLoc>) const { |
| 569 | + switch (NameStatus) { |
| 570 | + case NotNamed: return 0; |
| 571 | + case HasNames: return NumElements; |
| 572 | + case HasLabels: return NumElements + NumElements; |
| 573 | + } |
| 574 | + } |
| 575 | + |
548 | 576 | TupleTypeRepr(ArrayRef<TypeRepr *> Elements, SourceRange Parens,
|
549 |
| - SourceLoc Ellipsis, unsigned EllipsisIdx) |
550 |
| - : TypeRepr(TypeReprKind::Tuple), Elements(Elements), |
551 |
| - Parens(Parens), Ellipsis(Ellipsis), EllipsisIdx(EllipsisIdx) { |
| 577 | + ArrayRef<Identifier> ElementNames, |
| 578 | + ArrayRef<SourceLoc> ElementNameLocs, |
| 579 | + ArrayRef<SourceLoc> underscoreLocs, |
| 580 | + SourceLoc Ellipsis, unsigned EllipsisIdx); |
| 581 | +public: |
| 582 | + |
| 583 | + unsigned getNumElements() const { return NumElements; } |
| 584 | + bool hasElementNames() const { return NameStatus >= HasNames; } |
| 585 | + bool hasUnderscoreLocs() const { return NameStatus == HasLabels; } |
| 586 | + |
| 587 | + ArrayRef<TypeRepr *> getElements() const { |
| 588 | + return { getTrailingObjects<TypeRepr *>(), NumElements }; |
552 | 589 | }
|
553 | 590 |
|
554 |
| - ArrayRef<TypeRepr *> getElements() const { return Elements; } |
555 |
| - TypeRepr *getElement(unsigned i) const { return Elements[i]; } |
556 |
| - SourceRange getParens() const { return Parens; } |
557 |
| - SourceLoc getEllipsisLoc() const { return Ellipsis; } |
558 |
| - unsigned getEllipsisIndex() const { return EllipsisIdx; } |
559 |
| - bool hasEllipsis() const { return Ellipsis.isValid(); } |
| 591 | + ArrayRef<Identifier> getElementNames() const { |
| 592 | + if (!hasElementNames()) return {}; |
| 593 | + return { getTrailingObjects<Identifier>(), NumElements }; |
| 594 | + } |
560 | 595 |
|
561 |
| - void removeEllipsis() { |
562 |
| - Ellipsis = SourceLoc(); |
563 |
| - EllipsisIdx = Elements.size(); |
| 596 | + ArrayRef<SourceLoc> getElementNameLocs() const { |
| 597 | + if (!hasElementNames()) return {}; |
| 598 | + return { getTrailingObjects<SourceLoc>(), NumElements }; |
564 | 599 | }
|
565 | 600 |
|
566 |
| - bool isParenType() const { |
567 |
| - return Elements.size() == 1 && !isa<NamedTypeRepr>(Elements[0]) && |
568 |
| - !hasEllipsis(); |
| 601 | + ArrayRef<SourceLoc> getUnderscoreLocs() const { |
| 602 | + if (!hasUnderscoreLocs()) return {}; |
| 603 | + return { getTrailingObjects<SourceLoc>() + NumElements, NumElements }; |
569 | 604 | }
|
570 | 605 |
|
571 |
| - static TupleTypeRepr *create(ASTContext &C, ArrayRef<TypeRepr *> Elements, |
572 |
| - SourceRange Parens, SourceLoc Ellipsis, |
573 |
| - unsigned EllipsisIdx); |
| 606 | + TypeRepr *getElement(unsigned i) const { return getElements()[i]; } |
574 | 607 |
|
575 |
| - static bool classof(const TypeRepr *T) { |
576 |
| - return T->getKind() == TypeReprKind::Tuple; |
| 608 | + Identifier getElementName(unsigned i) const { |
| 609 | + return hasElementNames() ? getElementNames()[i] : Identifier(); |
577 | 610 | }
|
578 |
| - static bool classof(const TupleTypeRepr *T) { return true; } |
579 | 611 |
|
580 |
| -private: |
581 |
| - SourceLoc getStartLocImpl() const { return Parens.Start; } |
582 |
| - SourceLoc getEndLocImpl() const { return Parens.End; } |
583 |
| - void printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const; |
584 |
| - friend class TypeRepr; |
585 |
| -}; |
| 612 | + SourceLoc getElementNameLoc(unsigned i) const { |
| 613 | + return hasElementNames() ? getElementNameLocs()[i] : SourceLoc(); |
| 614 | + } |
586 | 615 |
|
587 |
| -/// \brief A named element of a tuple type or a named parameter of a function |
588 |
| -/// type. |
589 |
| -/// \code |
590 |
| -/// (x: Foo) |
591 |
| -/// (_ x: Foo) -> () |
592 |
| -/// \endcode |
593 |
| -class NamedTypeRepr : public TypeRepr { |
594 |
| - Identifier Id; |
595 |
| - TypeRepr *Ty; |
596 |
| - SourceLoc IdLoc; |
597 |
| - SourceLoc UnderscoreLoc; |
| 616 | + SourceLoc getUnderscoreLoc(unsigned i) const { |
| 617 | + return hasElementNames() ? getElementNameLocs()[i] : SourceLoc(); |
| 618 | + } |
598 | 619 |
|
599 |
| -public: |
600 |
| - /// Used for a named element of a tuple type. |
601 |
| - NamedTypeRepr(Identifier Id, TypeRepr *Ty, SourceLoc IdLoc) |
602 |
| - : TypeRepr(TypeReprKind::Named), Id(Id), Ty(Ty), IdLoc(IdLoc) { |
| 620 | + bool isNamedParameter(unsigned i) const { |
| 621 | + return hasUnderscoreLocs() ? getUnderscoreLocs()[i].isValid() : false; |
| 622 | + } |
| 623 | + |
| 624 | + SourceRange getParens() const { return Parens; } |
| 625 | + SourceLoc getEllipsisLoc() const { |
| 626 | + return HasEllipsis ? |
| 627 | + getTrailingObjects<SourceLocAndIdx>()[0].first : SourceLoc(); |
603 | 628 | }
|
604 |
| - /// Used for a named parameter of a function type. |
605 |
| - NamedTypeRepr(Identifier Id, TypeRepr *Ty, SourceLoc IdLoc, |
606 |
| - SourceLoc underscoreLoc) |
607 |
| - : TypeRepr(TypeReprKind::Named), Id(Id), Ty(Ty), IdLoc(IdLoc), |
608 |
| - UnderscoreLoc(underscoreLoc) { |
| 629 | + unsigned getEllipsisIndex() const { |
| 630 | + return HasEllipsis ? |
| 631 | + getTrailingObjects<SourceLocAndIdx>()[0].second : NumElements; |
609 | 632 | }
|
| 633 | + bool hasEllipsis() const { return HasEllipsis; } |
610 | 634 |
|
611 |
| - bool hasName() const { return !Id.empty(); } |
612 |
| - Identifier getName() const { return Id; } |
613 |
| - TypeRepr *getTypeRepr() const { return Ty; } |
614 |
| - SourceLoc getNameLoc() const { return IdLoc; } |
615 |
| - SourceLoc getUnderscoreLoc() const { return UnderscoreLoc; } |
| 635 | + void removeEllipsis() { |
| 636 | + if (HasEllipsis) { |
| 637 | + HasEllipsis = false; |
| 638 | + getTrailingObjects<SourceLocAndIdx>()[0] = {SourceLoc(), NumElements}; |
| 639 | + } |
| 640 | + } |
| 641 | + |
| 642 | + bool isParenType() const { |
| 643 | + return NumElements == 1 && getElementNameLoc(0).isInvalid() && |
| 644 | + !hasEllipsis(); |
| 645 | + } |
616 | 646 |
|
617 |
| - bool isNamedParameter() const { return UnderscoreLoc.isValid(); } |
| 647 | + static TupleTypeRepr *create(const ASTContext &C, |
| 648 | + ArrayRef<TypeRepr *> Elements, |
| 649 | + SourceRange Parens, |
| 650 | + ArrayRef<Identifier> ElementNames, |
| 651 | + ArrayRef<SourceLoc> ElementNameLocs, |
| 652 | + ArrayRef<SourceLoc> underscoreLocs, |
| 653 | + SourceLoc Ellipsis, unsigned EllipsisIdx); |
| 654 | + static TupleTypeRepr *create(const ASTContext &C, |
| 655 | + ArrayRef<TypeRepr *> Elements, |
| 656 | + SourceRange Parens) { |
| 657 | + return create(C, Elements, Parens, {}, {}, {}, |
| 658 | + SourceLoc(), Elements.size()); |
| 659 | + } |
| 660 | + static TupleTypeRepr *createEmpty(const ASTContext &C, SourceRange Parens); |
618 | 661 |
|
619 | 662 | static bool classof(const TypeRepr *T) {
|
620 |
| - return T->getKind() == TypeReprKind::Named; |
| 663 | + return T->getKind() == TypeReprKind::Tuple; |
621 | 664 | }
|
622 |
| - static bool classof(const NamedTypeRepr *T) { return true; } |
| 665 | + static bool classof(const TupleTypeRepr *T) { return true; } |
623 | 666 |
|
624 | 667 | private:
|
625 |
| - SourceLoc getStartLocImpl() const { |
626 |
| - return UnderscoreLoc.isValid() ? UnderscoreLoc : IdLoc; |
627 |
| - } |
628 |
| - SourceLoc getEndLocImpl() const { return Ty->getEndLoc(); } |
| 668 | + SourceLoc getStartLocImpl() const { return Parens.Start; } |
| 669 | + SourceLoc getEndLocImpl() const { return Parens.End; } |
629 | 670 | void printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const;
|
630 | 671 | friend class TypeRepr;
|
631 | 672 | };
|
@@ -804,7 +845,6 @@ inline bool TypeRepr::isSimple() const {
|
804 | 845 | case TypeReprKind::CompoundIdent:
|
805 | 846 | case TypeReprKind::Metatype:
|
806 | 847 | case TypeReprKind::Protocol:
|
807 |
| - case TypeReprKind::Named: |
808 | 848 | case TypeReprKind::Dictionary:
|
809 | 849 | case TypeReprKind::Optional:
|
810 | 850 | case TypeReprKind::ImplicitlyUnwrappedOptional:
|
|
0 commit comments