Skip to content

Commit ca72891

Browse files
authored
Merge pull request swiftlang#32138 from AnthonyLatsis/eliminate-typeloc
Sema: Remove TypeLoc from ExplicitCastExpr (via TypeExpr)
2 parents 28fba4f + 4b46341 commit ca72891

26 files changed

+322
-266
lines changed

include/swift/AST/ASTNode.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ namespace swift {
3030
class Stmt;
3131
class Decl;
3232
class Pattern;
33-
class TypeLoc;
33+
class TypeRepr;
3434
class DeclContext;
3535
class SourceLoc;
3636
class SourceRange;
@@ -41,7 +41,7 @@ namespace swift {
4141
enum class StmtKind;
4242

4343
struct ASTNode : public llvm::PointerUnion<Expr *, Stmt *, Decl *, Pattern *,
44-
TypeLoc *> {
44+
TypeRepr *> {
4545
// Inherit the constructors from PointerUnion.
4646
using PointerUnion::PointerUnion;
4747

include/swift/AST/Expr.h

Lines changed: 57 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
#include "swift/AST/ProtocolConformanceRef.h"
2626
#include "swift/AST/TrailingCallArguments.h"
2727
#include "swift/AST/TypeAlignments.h"
28-
#include "swift/AST/TypeLoc.h"
2928
#include "swift/AST/Availability.h"
3029
#include "swift/Basic/Debug.h"
3130
#include "swift/Basic/InlineBitfield.h"
@@ -555,7 +554,7 @@ class alignas(8) Expr {
555554
SWIFT_DEBUG_DUMP;
556555
void dump(raw_ostream &OS, unsigned Indent = 0) const;
557556
void dump(raw_ostream &OS, llvm::function_ref<Type(Expr *)> getType,
558-
llvm::function_ref<Type(TypeLoc &)> getTypeOfTypeLoc,
557+
llvm::function_ref<Type(TypeRepr *)> getTypeOfTypeRepr,
559558
llvm::function_ref<Type(KeyPathExpr *E, unsigned index)>
560559
getTypeOfKeyPathComponent,
561560
unsigned Indent = 0) const;
@@ -4587,23 +4586,22 @@ class DotSyntaxBaseIgnoredExpr : public Expr {
45874586
class ExplicitCastExpr : public Expr {
45884587
Expr *SubExpr;
45894588
SourceLoc AsLoc;
4590-
TypeLoc CastTy;
4589+
TypeExpr *const CastTy;
45914590

45924591
protected:
4593-
ExplicitCastExpr(ExprKind kind, Expr *sub, SourceLoc AsLoc, TypeLoc castTy)
4594-
: Expr(kind, /*Implicit=*/false), SubExpr(sub), AsLoc(AsLoc), CastTy(castTy)
4595-
{}
4592+
ExplicitCastExpr(ExprKind kind, Expr *sub, SourceLoc AsLoc, TypeExpr *castTy)
4593+
: Expr(kind, /*Implicit=*/false), SubExpr(sub), AsLoc(AsLoc),
4594+
CastTy(castTy) {}
45964595

45974596
public:
45984597
Expr *getSubExpr() const { return SubExpr; }
4599-
4600-
/// Get the type syntactically spelled in the cast. For some forms of checked
4601-
/// cast this is different from the result type of the expression.
4602-
TypeLoc &getCastTypeLoc() { return CastTy; }
46034598

46044599
/// Get the type syntactically spelled in the cast. For some forms of checked
46054600
/// cast this is different from the result type of the expression.
4606-
TypeLoc getCastTypeLoc() const { return CastTy; }
4601+
Type getCastType() const { return CastTy->getInstanceType(); }
4602+
void setCastType(Type type);
4603+
4604+
TypeRepr *getCastTypeRepr() const { return CastTy->getTypeRepr(); }
46074605

46084606
void setSubExpr(Expr *E) { SubExpr = E; }
46094607

@@ -4619,7 +4617,7 @@ class ExplicitCastExpr : public Expr {
46194617
}
46204618

46214619
SourceRange getSourceRange() const {
4622-
SourceRange castTyRange = CastTy.getSourceRange();
4620+
const SourceRange castTyRange = CastTy->getSourceRange();
46234621
if (castTyRange.isInvalid())
46244622
return SubExpr->getSourceRange();
46254623

@@ -4644,14 +4642,13 @@ StringRef getCheckedCastKindName(CheckedCastKind kind);
46444642
/// Abstract base class for checked casts 'as' and 'is'. These represent
46454643
/// casts that can dynamically fail.
46464644
class CheckedCastExpr : public ExplicitCastExpr {
4647-
public:
4648-
CheckedCastExpr(ExprKind kind,
4649-
Expr *sub, SourceLoc asLoc, TypeLoc castTy)
4650-
: ExplicitCastExpr(kind, sub, asLoc, castTy)
4651-
{
4645+
protected:
4646+
CheckedCastExpr(ExprKind kind, Expr *sub, SourceLoc asLoc, TypeExpr *castTy)
4647+
: ExplicitCastExpr(kind, sub, asLoc, castTy) {
46524648
Bits.CheckedCastExpr.CastKind = unsigned(CheckedCastKind::Unresolved);
46534649
}
4654-
4650+
4651+
public:
46554652
/// Return the semantic kind of cast performed.
46564653
CheckedCastKind getCastKind() const {
46574654
return CheckedCastKind(Bits.CheckedCastExpr.CastKind);
@@ -4675,22 +4672,20 @@ class CheckedCastExpr : public ExplicitCastExpr {
46754672
/// from a value of some type to some specified subtype and fails dynamically
46764673
/// if the value does not have that type.
46774674
/// Spelled 'a as! T' and produces a value of type 'T'.
4678-
class ForcedCheckedCastExpr : public CheckedCastExpr {
4675+
class ForcedCheckedCastExpr final : public CheckedCastExpr {
46794676
SourceLoc ExclaimLoc;
46804677

4681-
public:
46824678
ForcedCheckedCastExpr(Expr *sub, SourceLoc asLoc, SourceLoc exclaimLoc,
4683-
TypeLoc type)
4684-
: CheckedCastExpr(ExprKind::ForcedCheckedCast,
4685-
sub, asLoc, type),
4686-
ExclaimLoc(exclaimLoc)
4687-
{
4688-
}
4679+
TypeExpr *type)
4680+
: CheckedCastExpr(ExprKind::ForcedCheckedCast, sub, asLoc, type),
4681+
ExclaimLoc(exclaimLoc) {}
46894682

4690-
ForcedCheckedCastExpr(SourceLoc asLoc, SourceLoc exclaimLoc, TypeLoc type)
4691-
: ForcedCheckedCastExpr(nullptr, asLoc, exclaimLoc, type)
4692-
{
4693-
}
4683+
public:
4684+
static ForcedCheckedCastExpr *create(ASTContext &ctx, SourceLoc asLoc,
4685+
SourceLoc exclaimLoc, TypeRepr *tyRepr);
4686+
4687+
static ForcedCheckedCastExpr *createImplicit(ASTContext &ctx, Expr *sub,
4688+
Type castTy);
46944689

46954690
/// Retrieve the location of the '!' that follows 'as'.
46964691
SourceLoc getExclaimLoc() const { return ExclaimLoc; }
@@ -4704,21 +4699,24 @@ class ForcedCheckedCastExpr : public CheckedCastExpr {
47044699
/// from a type to some subtype and produces an Optional value, which will be
47054700
/// .Some(x) if the cast succeeds, or .None if the cast fails.
47064701
/// Spelled 'a as? T' and produces a value of type 'T?'.
4707-
class ConditionalCheckedCastExpr : public CheckedCastExpr {
4702+
class ConditionalCheckedCastExpr final : public CheckedCastExpr {
47084703
SourceLoc QuestionLoc;
47094704

4710-
public:
47114705
ConditionalCheckedCastExpr(Expr *sub, SourceLoc asLoc, SourceLoc questionLoc,
4712-
TypeLoc type)
4713-
: CheckedCastExpr(ExprKind::ConditionalCheckedCast,
4714-
sub, asLoc, type),
4715-
QuestionLoc(questionLoc)
4716-
{ }
4717-
4718-
ConditionalCheckedCastExpr(SourceLoc asLoc, SourceLoc questionLoc,
4719-
TypeLoc type)
4720-
: ConditionalCheckedCastExpr(nullptr, asLoc, questionLoc, type)
4721-
{}
4706+
TypeExpr *type)
4707+
: CheckedCastExpr(ExprKind::ConditionalCheckedCast, sub, asLoc, type),
4708+
QuestionLoc(questionLoc) {}
4709+
4710+
public:
4711+
static ConditionalCheckedCastExpr *create(ASTContext &ctx, SourceLoc asLoc,
4712+
SourceLoc questionLoc,
4713+
TypeRepr *tyRepr);
4714+
4715+
static ConditionalCheckedCastExpr *createImplicit(ASTContext &ctx, Expr *sub,
4716+
Type castTy);
4717+
4718+
static ConditionalCheckedCastExpr *
4719+
createImplicit(ASTContext &ctx, Expr *sub, TypeRepr *tyRepr, Type castTy);
47224720

47234721
/// Retrieve the location of the '?' that follows 'as'.
47244722
SourceLoc getQuestionLoc() const { return QuestionLoc; }
@@ -4733,16 +4731,13 @@ class ConditionalCheckedCastExpr : public CheckedCastExpr {
47334731
/// of the type and 'a as T' would succeed, false otherwise.
47344732
///
47354733
/// FIXME: We should support type queries with a runtime metatype value too.
4736-
class IsExpr : public CheckedCastExpr {
4734+
class IsExpr final : public CheckedCastExpr {
4735+
IsExpr(Expr *sub, SourceLoc isLoc, TypeExpr *type)
4736+
: CheckedCastExpr(ExprKind::Is, sub, isLoc, type) {}
4737+
47374738
public:
4738-
IsExpr(Expr *sub, SourceLoc isLoc, TypeLoc type)
4739-
: CheckedCastExpr(ExprKind::Is, sub, isLoc, type)
4740-
{}
4741-
4742-
IsExpr(SourceLoc isLoc, TypeLoc type)
4743-
: IsExpr(nullptr, isLoc, type)
4744-
{}
4745-
4739+
static IsExpr *create(ASTContext &ctx, SourceLoc isLoc, TypeRepr *tyRepr);
4740+
47464741
static bool classof(const Expr *E) {
47474742
return E->getKind() == ExprKind::Is;
47484743
}
@@ -4751,35 +4746,29 @@ class IsExpr : public CheckedCastExpr {
47514746
/// Represents an explicit coercion from a value to a specific type.
47524747
///
47534748
/// Spelled 'a as T' and produces a value of type 'T'.
4754-
class CoerceExpr : public ExplicitCastExpr {
4749+
class CoerceExpr final : public ExplicitCastExpr {
47554750
/// Since there is already `asLoc` location,
47564751
/// we use it to store `start` of the initializer
47574752
/// call source range to save some storage.
47584753
SourceLoc InitRangeEnd;
47594754

4760-
public:
4761-
CoerceExpr(Expr *sub, SourceLoc asLoc, TypeLoc type)
4762-
: ExplicitCastExpr(ExprKind::Coerce, sub, asLoc, type)
4763-
{ }
4755+
CoerceExpr(Expr *sub, SourceLoc asLoc, TypeExpr *type)
4756+
: ExplicitCastExpr(ExprKind::Coerce, sub, asLoc, type) {}
47644757

4765-
CoerceExpr(SourceLoc asLoc, TypeLoc type)
4766-
: CoerceExpr(nullptr, asLoc, type)
4767-
{ }
4768-
4769-
private:
4770-
CoerceExpr(SourceRange initRange, Expr *literal, TypeLoc type)
4771-
: ExplicitCastExpr(ExprKind::Coerce, literal, initRange.Start,
4772-
type), InitRangeEnd(initRange.End)
4773-
{ setImplicit(); }
4758+
CoerceExpr(SourceRange initRange, Expr *literal, TypeExpr *type)
4759+
: ExplicitCastExpr(ExprKind::Coerce, literal, initRange.Start, type),
4760+
InitRangeEnd(initRange.End) {}
47744761

47754762
public:
4763+
static CoerceExpr *create(ASTContext &ctx, SourceLoc asLoc, TypeRepr *tyRepr);
4764+
4765+
static CoerceExpr *createImplicit(ASTContext &ctx, Expr *sub, Type castTy);
4766+
47764767
/// Create an implicit coercion expression for literal initialization
47774768
/// preserving original source information, this way original call
47784769
/// could be recreated if needed.
47794770
static CoerceExpr *forLiteralInit(ASTContext &ctx, Expr *literal,
4780-
SourceRange range, TypeLoc literalType) {
4781-
return new (ctx) CoerceExpr(range, literal, literalType);
4782-
}
4771+
SourceRange range, TypeRepr *literalTyRepr);
47834772

47844773
bool isLiteralInit() const { return InitRangeEnd.isValid(); }
47854774

include/swift/AST/TypeAlignments.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ namespace swift {
5151
class TypeVariableType;
5252
class TypeBase;
5353
class TypeDecl;
54-
class TypeLoc;
54+
class TypeRepr;
5555
class ValueDecl;
5656

5757
/// We frequently use three tag bits on all of these types.
@@ -64,7 +64,7 @@ namespace swift {
6464
constexpr size_t PatternAlignInBits = 3;
6565
constexpr size_t SILFunctionAlignInBits = 2;
6666
constexpr size_t TypeVariableAlignInBits = 4;
67-
constexpr size_t TypeLocAlignInBits = 3;
67+
constexpr size_t TypeReprAlignInBits = 3;
6868
}
6969

7070
namespace llvm {
@@ -126,7 +126,7 @@ LLVM_DECLARE_TYPE_ALIGNMENT(swift::SILFunction,
126126

127127
LLVM_DECLARE_TYPE_ALIGNMENT(swift::AttributeBase, swift::AttrAlignInBits)
128128

129-
LLVM_DECLARE_TYPE_ALIGNMENT(swift::TypeLoc, swift::TypeLocAlignInBits)
129+
LLVM_DECLARE_TYPE_ALIGNMENT(swift::TypeRepr, swift::TypeReprAlignInBits)
130130

131131
static_assert(alignof(void*) >= 2, "pointer alignment is too small");
132132

include/swift/AST/TypeLoc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class TypeRepr;
2929

3030
/// TypeLoc - Provides source location information for a parsed type.
3131
/// A TypeLoc is stored in AST nodes which use an explicitly written type.
32-
class alignas(1 << TypeLocAlignInBits) TypeLoc {
32+
class alignas(1 << TypeReprAlignInBits) TypeLoc final {
3333
Type Ty;
3434
TypeRepr *TyR = nullptr;
3535

include/swift/AST/TypeRepr.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ enum : unsigned { NumTypeReprKindBits =
4848
countBitsUsed(static_cast<unsigned>(TypeReprKind::Last_TypeRepr)) };
4949

5050
/// Representation of a type as written in source.
51-
class alignas(8) TypeRepr {
51+
class alignas(1 << TypeReprAlignInBits) TypeRepr {
5252
TypeRepr(const TypeRepr&) = delete;
5353
void operator=(const TypeRepr&) = delete;
5454

lib/AST/ASTDumper.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1781,18 +1781,18 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
17811781
public:
17821782
raw_ostream &OS;
17831783
llvm::function_ref<Type(Expr *)> GetTypeOfExpr;
1784-
llvm::function_ref<Type(TypeLoc &)> GetTypeOfTypeLoc;
1784+
llvm::function_ref<Type(TypeRepr *)> GetTypeOfTypeRepr;
17851785
llvm::function_ref<Type(KeyPathExpr *E, unsigned index)>
17861786
GetTypeOfKeyPathComponent;
17871787
unsigned Indent;
17881788

17891789
PrintExpr(raw_ostream &os, llvm::function_ref<Type(Expr *)> getTypeOfExpr,
1790-
llvm::function_ref<Type(TypeLoc &)> getTypeOfTypeLoc,
1790+
llvm::function_ref<Type(TypeRepr *)> getTypeOfTypeRepr,
17911791
llvm::function_ref<Type(KeyPathExpr *E, unsigned index)>
17921792
getTypeOfKeyPathComponent,
17931793
unsigned indent)
17941794
: OS(os), GetTypeOfExpr(getTypeOfExpr),
1795-
GetTypeOfTypeLoc(getTypeOfTypeLoc),
1795+
GetTypeOfTypeRepr(getTypeOfTypeRepr),
17961796
GetTypeOfKeyPathComponent(getTypeOfKeyPathComponent), Indent(indent) {}
17971797

17981798
void printRec(Expr *E) {
@@ -2607,7 +2607,10 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
26072607
if (auto checkedCast = dyn_cast<CheckedCastExpr>(E))
26082608
OS << getCheckedCastKindName(checkedCast->getCastKind()) << ' ';
26092609
OS << "writtenType='";
2610-
GetTypeOfTypeLoc(E->getCastTypeLoc()).print(OS);
2610+
if (GetTypeOfTypeRepr)
2611+
GetTypeOfTypeRepr(E->getCastTypeRepr()).print(OS);
2612+
else
2613+
E->getCastType().print(OS);
26112614
OS << "'\n";
26122615
printRec(E->getSubExpr());
26132616
PrintWithColorRAII(OS, ParenthesisColor) << ')';
@@ -2872,21 +2875,22 @@ void Expr::dump() const {
28722875
}
28732876

28742877
void Expr::dump(raw_ostream &OS, llvm::function_ref<Type(Expr *)> getTypeOfExpr,
2875-
llvm::function_ref<Type(TypeLoc &)> getTypeOfTypeLoc,
2878+
llvm::function_ref<Type(TypeRepr *)> getTypeOfTypeRepr,
28762879
llvm::function_ref<Type(KeyPathExpr *E, unsigned index)>
28772880
getTypeOfKeyPathComponent,
28782881
unsigned Indent) const {
2879-
PrintExpr(OS, getTypeOfExpr, getTypeOfTypeLoc, getTypeOfKeyPathComponent, Indent)
2882+
PrintExpr(OS, getTypeOfExpr, getTypeOfTypeRepr, getTypeOfKeyPathComponent,
2883+
Indent)
28802884
.visit(const_cast<Expr *>(this));
28812885
}
28822886

28832887
void Expr::dump(raw_ostream &OS, unsigned Indent) const {
28842888
auto getTypeOfExpr = [](Expr *E) -> Type { return E->getType(); };
2885-
auto getTypeOfTypeLoc = [](TypeLoc &TL) -> Type { return TL.getType(); };
28862889
auto getTypeOfKeyPathComponent = [](KeyPathExpr *E, unsigned index) -> Type {
28872890
return E->getComponents()[index].getComponentType();
28882891
};
2889-
dump(OS, getTypeOfExpr, getTypeOfTypeLoc, getTypeOfKeyPathComponent, Indent);
2892+
dump(OS, getTypeOfExpr, /*getTypeOfTypeRepr*/ nullptr,
2893+
getTypeOfKeyPathComponent, Indent);
28902894
}
28912895

28922896
void Expr::print(ASTPrinter &Printer, const PrintOptions &Opts) const {

lib/AST/ASTNode.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#include "swift/AST/Expr.h"
2020
#include "swift/AST/Stmt.h"
2121
#include "swift/AST/Pattern.h"
22-
#include "swift/AST/TypeLoc.h"
22+
#include "swift/AST/TypeRepr.h"
2323
#include "swift/Basic/SourceLoc.h"
2424

2525
using namespace swift;
@@ -33,8 +33,8 @@ SourceRange ASTNode::getSourceRange() const {
3333
return D->getSourceRange();
3434
if (const auto *P = this->dyn_cast<Pattern*>())
3535
return P->getSourceRange();
36-
if (const auto *L = this->dyn_cast<TypeLoc *>())
37-
return L->getSourceRange();
36+
if (const auto *T = this->dyn_cast<TypeRepr *>())
37+
return T->getSourceRange();
3838
llvm_unreachable("unsupported AST node");
3939
}
4040

@@ -71,7 +71,7 @@ bool ASTNode::isImplicit() const {
7171
return D->isImplicit();
7272
if (const auto *P = this->dyn_cast<Pattern*>())
7373
return P->isImplicit();
74-
if (const auto *L = this->dyn_cast<TypeLoc*>())
74+
if (const auto *T = this->dyn_cast<TypeRepr*>())
7575
return false;
7676
llvm_unreachable("unsupported AST node");
7777
}
@@ -85,6 +85,8 @@ void ASTNode::walk(ASTWalker &Walker) {
8585
D->walk(Walker);
8686
else if (auto *P = this->dyn_cast<Pattern*>())
8787
P->walk(Walker);
88+
else if (auto *T = this->dyn_cast<TypeRepr*>())
89+
T->walk(Walker);
8890
else
8991
llvm_unreachable("unsupported AST node");
9092
}
@@ -98,8 +100,10 @@ void ASTNode::dump(raw_ostream &OS, unsigned Indent) const {
98100
D->dump(OS, Indent);
99101
else if (auto P = dyn_cast<Pattern*>())
100102
P->dump(OS, Indent);
103+
else if (auto T = dyn_cast<TypeRepr*>())
104+
T->print(OS);
101105
else
102-
OS << "<null>";
106+
llvm_unreachable("unsupported AST node");
103107
}
104108

105109
void ASTNode::dump() const {

0 commit comments

Comments
 (0)