Skip to content

Commit da36a13

Browse files
authored
Merge pull request swiftlang#5926 from rintaro/ast-tupletyperepr-tail
[AST] Tail allocate TupleTypeRepr elements and names. Eliminate NamedTypeRepr
2 parents 436f197 + 0281b23 commit da36a13

File tree

12 files changed

+270
-187
lines changed

12 files changed

+270
-187
lines changed

include/swift/AST/TypeRepr.h

+108-68
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@
2727
#include "llvm/ADT/PointerUnion.h"
2828
#include "llvm/ADT/STLExtras.h"
2929
#include "llvm/Support/ErrorHandling.h"
30+
#include "llvm/Support/TrailingObjects.h"
3031

3132
namespace swift {
3233
class ASTWalker;
3334
class DeclContext;
3435
class IdentTypeRepr;
3536
class ValueDecl;
36-
class NamedTypeRepr;
3737

3838
enum class TypeReprKind : uint8_t {
3939
#define TYPEREPR(ID, PARENT) ID,
@@ -100,10 +100,14 @@ class alignas(8) TypeRepr {
100100
void *operator new(size_t bytes, const ASTContext &C,
101101
unsigned Alignment = alignof(TypeRepr));
102102

103+
void *operator new(size_t bytes, void *data) {
104+
assert(data);
105+
return data;
106+
}
107+
103108
// Make placement new and vanilla new/delete illegal for TypeReprs.
104109
void *operator new(size_t bytes) = delete;
105110
void operator delete(void *data) = delete;
106-
void *operator new(size_t bytes, void *data) = delete;
107111

108112
void print(raw_ostream &OS, const PrintOptions &Opts = PrintOptions()) const;
109113
void print(ASTPrinter &Printer, const PrintOptions &Opts) const;
@@ -536,96 +540,133 @@ class ImplicitlyUnwrappedOptionalTypeRepr : public TypeRepr {
536540
/// \brief A tuple type.
537541
/// \code
538542
/// (Foo, Bar)
543+
/// (x: Foo)
544+
/// (_ x: Foo)
539545
/// \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;
542553
SourceRange Parens;
543-
// FIXME: Tail allocation.
544-
SourceLoc Ellipsis;
545-
unsigned EllipsisIdx;
546554

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+
548576
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 };
552589
}
553590

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+
}
560595

561-
void removeEllipsis() {
562-
Ellipsis = SourceLoc();
563-
EllipsisIdx = Elements.size();
596+
ArrayRef<SourceLoc> getElementNameLocs() const {
597+
if (!hasElementNames()) return {};
598+
return { getTrailingObjects<SourceLoc>(), NumElements };
564599
}
565600

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 };
569604
}
570605

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]; }
574607

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();
577610
}
578-
static bool classof(const TupleTypeRepr *T) { return true; }
579611

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+
}
586615

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+
}
598619

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();
603628
}
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;
609632
}
633+
bool hasEllipsis() const { return HasEllipsis; }
610634

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+
}
616646

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);
618661

619662
static bool classof(const TypeRepr *T) {
620-
return T->getKind() == TypeReprKind::Named;
663+
return T->getKind() == TypeReprKind::Tuple;
621664
}
622-
static bool classof(const NamedTypeRepr *T) { return true; }
665+
static bool classof(const TupleTypeRepr *T) { return true; }
623666

624667
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; }
629670
void printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const;
630671
friend class TypeRepr;
631672
};
@@ -804,7 +845,6 @@ inline bool TypeRepr::isSimple() const {
804845
case TypeReprKind::CompoundIdent:
805846
case TypeReprKind::Metatype:
806847
case TypeReprKind::Protocol:
807-
case TypeReprKind::Named:
808848
case TypeReprKind::Dictionary:
809849
case TypeReprKind::Optional:
810850
case TypeReprKind::ImplicitlyUnwrappedOptional:

include/swift/AST/TypeReprNodes.def

-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ TYPEREPR(Dictionary, TypeRepr)
4646
TYPEREPR(Optional, TypeRepr)
4747
TYPEREPR(ImplicitlyUnwrappedOptional, TypeRepr)
4848
TYPEREPR(Tuple, TypeRepr)
49-
TYPEREPR(Named, TypeRepr)
5049
TYPEREPR(Composition, TypeRepr)
5150
TYPEREPR(Metatype, TypeRepr)
5251
TYPEREPR(Protocol, TypeRepr)

lib/AST/ASTDumper.cpp

+13-11
Original file line numberDiff line numberDiff line change
@@ -2420,20 +2420,22 @@ class PrintTypeRepr : public TypeReprVisitor<PrintTypeRepr> {
24202420

24212421
void visitTupleTypeRepr(TupleTypeRepr *T) {
24222422
printCommon(T, "type_tuple");
2423-
for (auto elem : T->getElements()) {
2424-
OS << '\n';
2425-
printRec(elem);
2423+
2424+
if (T->hasElementNames()) {
2425+
OS << " names=";
2426+
for (unsigned i = 0, end = T->getNumElements(); i != end; ++i) {
2427+
if (i) OS << ",";
2428+
auto name = T->getElementName(i);
2429+
if (T->isNamedParameter(i))
2430+
OS << (name.empty() ? "_" : "_ " + name.str());
2431+
else
2432+
OS << (name.empty() ? "''" : name.str());
2433+
}
24262434
}
2427-
OS << ')';
2428-
}
24292435

2430-
void visitNamedTypeRepr(NamedTypeRepr *T) {
2431-
printCommon(T, "type_named");
2432-
if (T->hasName())
2433-
OS << " id=" << T->getName();
2434-
if (T->getTypeRepr()) {
2436+
for (auto elem : T->getElements()) {
24352437
OS << '\n';
2436-
printRec(T->getTypeRepr());
2438+
printRec(elem);
24372439
}
24382440
OS << ')';
24392441
}

lib/AST/ASTWalker.cpp

-8
Original file line numberDiff line numberDiff line change
@@ -1532,14 +1532,6 @@ bool Traversal::visitTupleTypeRepr(TupleTypeRepr *T) {
15321532
return false;
15331533
}
15341534

1535-
bool Traversal::visitNamedTypeRepr(NamedTypeRepr *T) {
1536-
if (T->getTypeRepr()) {
1537-
if (doIt(T->getTypeRepr()))
1538-
return true;
1539-
}
1540-
return false;
1541-
}
1542-
15431535
bool Traversal::visitCompositionTypeRepr(CompositionTypeRepr *T) {
15441536
for (auto elem : T->getTypes()) {
15451537
if (doIt(elem))

0 commit comments

Comments
 (0)