Skip to content

Commit

Permalink
Merge pull request #5926 from rintaro/ast-tupletyperepr-tail
Browse files Browse the repository at this point in the history
[AST] Tail allocate TupleTypeRepr elements and names. Eliminate NamedTypeRepr
  • Loading branch information
rintaro authored Nov 26, 2016
2 parents 436f197 + 0281b23 commit da36a13
Show file tree
Hide file tree
Showing 12 changed files with 270 additions and 187 deletions.
176 changes: 108 additions & 68 deletions include/swift/AST/TypeRepr.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TrailingObjects.h"

namespace swift {
class ASTWalker;
class DeclContext;
class IdentTypeRepr;
class ValueDecl;
class NamedTypeRepr;

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

void *operator new(size_t bytes, void *data) {
assert(data);
return data;
}

// Make placement new and vanilla new/delete illegal for TypeReprs.
void *operator new(size_t bytes) = delete;
void operator delete(void *data) = delete;
void *operator new(size_t bytes, void *data) = delete;

void print(raw_ostream &OS, const PrintOptions &Opts = PrintOptions()) const;
void print(ASTPrinter &Printer, const PrintOptions &Opts) const;
Expand Down Expand Up @@ -536,96 +540,133 @@ class ImplicitlyUnwrappedOptionalTypeRepr : public TypeRepr {
/// \brief A tuple type.
/// \code
/// (Foo, Bar)
/// (x: Foo)
/// (_ x: Foo)
/// \endcode
class TupleTypeRepr : public TypeRepr {
ArrayRef<TypeRepr *> Elements;
class TupleTypeRepr final : public TypeRepr,
private llvm::TrailingObjects<TupleTypeRepr, TypeRepr*, Identifier,
SourceLoc, std::pair<SourceLoc, unsigned>> {
friend TrailingObjects;
typedef std::pair<SourceLoc, unsigned> SourceLocAndIdx;

unsigned NumElements;
SourceRange Parens;
// FIXME: Tail allocation.
SourceLoc Ellipsis;
unsigned EllipsisIdx;

public:
enum {
NotNamed = 0,
HasNames = 1,
HasLabels = 2
} NameStatus : 2;
bool HasEllipsis : 1;

size_t numTrailingObjects(OverloadToken<TypeRepr *>) const {
return NumElements;
}
size_t numTrailingObjects(OverloadToken<Identifier>) const {
return NameStatus >= HasNames ? NumElements : 0;
}
size_t numTrailingObjects(OverloadToken<SourceLoc>) const {
switch (NameStatus) {
case NotNamed: return 0;
case HasNames: return NumElements;
case HasLabels: return NumElements + NumElements;
}
}

TupleTypeRepr(ArrayRef<TypeRepr *> Elements, SourceRange Parens,
SourceLoc Ellipsis, unsigned EllipsisIdx)
: TypeRepr(TypeReprKind::Tuple), Elements(Elements),
Parens(Parens), Ellipsis(Ellipsis), EllipsisIdx(EllipsisIdx) {
ArrayRef<Identifier> ElementNames,
ArrayRef<SourceLoc> ElementNameLocs,
ArrayRef<SourceLoc> underscoreLocs,
SourceLoc Ellipsis, unsigned EllipsisIdx);
public:

unsigned getNumElements() const { return NumElements; }
bool hasElementNames() const { return NameStatus >= HasNames; }
bool hasUnderscoreLocs() const { return NameStatus == HasLabels; }

ArrayRef<TypeRepr *> getElements() const {
return { getTrailingObjects<TypeRepr *>(), NumElements };
}

ArrayRef<TypeRepr *> getElements() const { return Elements; }
TypeRepr *getElement(unsigned i) const { return Elements[i]; }
SourceRange getParens() const { return Parens; }
SourceLoc getEllipsisLoc() const { return Ellipsis; }
unsigned getEllipsisIndex() const { return EllipsisIdx; }
bool hasEllipsis() const { return Ellipsis.isValid(); }
ArrayRef<Identifier> getElementNames() const {
if (!hasElementNames()) return {};
return { getTrailingObjects<Identifier>(), NumElements };
}

void removeEllipsis() {
Ellipsis = SourceLoc();
EllipsisIdx = Elements.size();
ArrayRef<SourceLoc> getElementNameLocs() const {
if (!hasElementNames()) return {};
return { getTrailingObjects<SourceLoc>(), NumElements };
}

bool isParenType() const {
return Elements.size() == 1 && !isa<NamedTypeRepr>(Elements[0]) &&
!hasEllipsis();
ArrayRef<SourceLoc> getUnderscoreLocs() const {
if (!hasUnderscoreLocs()) return {};
return { getTrailingObjects<SourceLoc>() + NumElements, NumElements };
}

static TupleTypeRepr *create(ASTContext &C, ArrayRef<TypeRepr *> Elements,
SourceRange Parens, SourceLoc Ellipsis,
unsigned EllipsisIdx);
TypeRepr *getElement(unsigned i) const { return getElements()[i]; }

static bool classof(const TypeRepr *T) {
return T->getKind() == TypeReprKind::Tuple;
Identifier getElementName(unsigned i) const {
return hasElementNames() ? getElementNames()[i] : Identifier();
}
static bool classof(const TupleTypeRepr *T) { return true; }

private:
SourceLoc getStartLocImpl() const { return Parens.Start; }
SourceLoc getEndLocImpl() const { return Parens.End; }
void printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const;
friend class TypeRepr;
};
SourceLoc getElementNameLoc(unsigned i) const {
return hasElementNames() ? getElementNameLocs()[i] : SourceLoc();
}

/// \brief A named element of a tuple type or a named parameter of a function
/// type.
/// \code
/// (x: Foo)
/// (_ x: Foo) -> ()
/// \endcode
class NamedTypeRepr : public TypeRepr {
Identifier Id;
TypeRepr *Ty;
SourceLoc IdLoc;
SourceLoc UnderscoreLoc;
SourceLoc getUnderscoreLoc(unsigned i) const {
return hasElementNames() ? getElementNameLocs()[i] : SourceLoc();
}

public:
/// Used for a named element of a tuple type.
NamedTypeRepr(Identifier Id, TypeRepr *Ty, SourceLoc IdLoc)
: TypeRepr(TypeReprKind::Named), Id(Id), Ty(Ty), IdLoc(IdLoc) {
bool isNamedParameter(unsigned i) const {
return hasUnderscoreLocs() ? getUnderscoreLocs()[i].isValid() : false;
}

SourceRange getParens() const { return Parens; }
SourceLoc getEllipsisLoc() const {
return HasEllipsis ?
getTrailingObjects<SourceLocAndIdx>()[0].first : SourceLoc();
}
/// Used for a named parameter of a function type.
NamedTypeRepr(Identifier Id, TypeRepr *Ty, SourceLoc IdLoc,
SourceLoc underscoreLoc)
: TypeRepr(TypeReprKind::Named), Id(Id), Ty(Ty), IdLoc(IdLoc),
UnderscoreLoc(underscoreLoc) {
unsigned getEllipsisIndex() const {
return HasEllipsis ?
getTrailingObjects<SourceLocAndIdx>()[0].second : NumElements;
}
bool hasEllipsis() const { return HasEllipsis; }

bool hasName() const { return !Id.empty(); }
Identifier getName() const { return Id; }
TypeRepr *getTypeRepr() const { return Ty; }
SourceLoc getNameLoc() const { return IdLoc; }
SourceLoc getUnderscoreLoc() const { return UnderscoreLoc; }
void removeEllipsis() {
if (HasEllipsis) {
HasEllipsis = false;
getTrailingObjects<SourceLocAndIdx>()[0] = {SourceLoc(), NumElements};
}
}

bool isParenType() const {
return NumElements == 1 && getElementNameLoc(0).isInvalid() &&
!hasEllipsis();
}

bool isNamedParameter() const { return UnderscoreLoc.isValid(); }
static TupleTypeRepr *create(const ASTContext &C,
ArrayRef<TypeRepr *> Elements,
SourceRange Parens,
ArrayRef<Identifier> ElementNames,
ArrayRef<SourceLoc> ElementNameLocs,
ArrayRef<SourceLoc> underscoreLocs,
SourceLoc Ellipsis, unsigned EllipsisIdx);
static TupleTypeRepr *create(const ASTContext &C,
ArrayRef<TypeRepr *> Elements,
SourceRange Parens) {
return create(C, Elements, Parens, {}, {}, {},
SourceLoc(), Elements.size());
}
static TupleTypeRepr *createEmpty(const ASTContext &C, SourceRange Parens);

static bool classof(const TypeRepr *T) {
return T->getKind() == TypeReprKind::Named;
return T->getKind() == TypeReprKind::Tuple;
}
static bool classof(const NamedTypeRepr *T) { return true; }
static bool classof(const TupleTypeRepr *T) { return true; }

private:
SourceLoc getStartLocImpl() const {
return UnderscoreLoc.isValid() ? UnderscoreLoc : IdLoc;
}
SourceLoc getEndLocImpl() const { return Ty->getEndLoc(); }
SourceLoc getStartLocImpl() const { return Parens.Start; }
SourceLoc getEndLocImpl() const { return Parens.End; }
void printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const;
friend class TypeRepr;
};
Expand Down Expand Up @@ -804,7 +845,6 @@ inline bool TypeRepr::isSimple() const {
case TypeReprKind::CompoundIdent:
case TypeReprKind::Metatype:
case TypeReprKind::Protocol:
case TypeReprKind::Named:
case TypeReprKind::Dictionary:
case TypeReprKind::Optional:
case TypeReprKind::ImplicitlyUnwrappedOptional:
Expand Down
1 change: 0 additions & 1 deletion include/swift/AST/TypeReprNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ TYPEREPR(Dictionary, TypeRepr)
TYPEREPR(Optional, TypeRepr)
TYPEREPR(ImplicitlyUnwrappedOptional, TypeRepr)
TYPEREPR(Tuple, TypeRepr)
TYPEREPR(Named, TypeRepr)
TYPEREPR(Composition, TypeRepr)
TYPEREPR(Metatype, TypeRepr)
TYPEREPR(Protocol, TypeRepr)
Expand Down
24 changes: 13 additions & 11 deletions lib/AST/ASTDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2420,20 +2420,22 @@ class PrintTypeRepr : public TypeReprVisitor<PrintTypeRepr> {

void visitTupleTypeRepr(TupleTypeRepr *T) {
printCommon(T, "type_tuple");
for (auto elem : T->getElements()) {
OS << '\n';
printRec(elem);

if (T->hasElementNames()) {
OS << " names=";
for (unsigned i = 0, end = T->getNumElements(); i != end; ++i) {
if (i) OS << ",";
auto name = T->getElementName(i);
if (T->isNamedParameter(i))
OS << (name.empty() ? "_" : "_ " + name.str());
else
OS << (name.empty() ? "''" : name.str());
}
}
OS << ')';
}

void visitNamedTypeRepr(NamedTypeRepr *T) {
printCommon(T, "type_named");
if (T->hasName())
OS << " id=" << T->getName();
if (T->getTypeRepr()) {
for (auto elem : T->getElements()) {
OS << '\n';
printRec(T->getTypeRepr());
printRec(elem);
}
OS << ')';
}
Expand Down
8 changes: 0 additions & 8 deletions lib/AST/ASTWalker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1532,14 +1532,6 @@ bool Traversal::visitTupleTypeRepr(TupleTypeRepr *T) {
return false;
}

bool Traversal::visitNamedTypeRepr(NamedTypeRepr *T) {
if (T->getTypeRepr()) {
if (doIt(T->getTypeRepr()))
return true;
}
return false;
}

bool Traversal::visitCompositionTypeRepr(CompositionTypeRepr *T) {
for (auto elem : T->getTypes()) {
if (doIt(elem))
Expand Down
Loading

0 comments on commit da36a13

Please sign in to comment.