Skip to content

Commit 781dcf7

Browse files
committed
[AST] Store the TypeReprs of generic arguments used to specialize a decl reference in DeclRefExpr, to impove source fidelity.
Fixes rdar://15034958 Swift SVN r8880
1 parent 883a9ee commit 781dcf7

File tree

7 files changed

+87
-13
lines changed

7 files changed

+87
-13
lines changed

include/swift/AST/Expr.h

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -376,23 +376,53 @@ class DiscardAssignmentExpr : public Expr {
376376

377377
/// DeclRefExpr - A reference to a value, "x".
378378
class DeclRefExpr : public Expr {
379-
/// \brief The declaration pointer and a bit specifying whether it was
379+
/// This is used when the reference is specialized, e.g "GenCls<Int>", to
380+
/// hold information about the generic arguments.
381+
struct SpecializeInfo {
382+
ValueDecl *D = nullptr;
383+
MutableArrayRef<TypeRepr*> GenericArgs;
384+
};
385+
386+
/// \brief The declaration pointer or SpecializeInfo pointer if it was
380387
/// explicitly specialized with <...>.
381-
llvm::PointerIntPair<ValueDecl *, 1, bool> DAndSpecialized;
388+
llvm::PointerUnion<ValueDecl *, SpecializeInfo *> DAndSpecialized;
382389
SourceLoc Loc;
383390

391+
SpecializeInfo *getSpecInfo() const {
392+
return DAndSpecialized.dyn_cast<SpecializeInfo*>();
393+
}
394+
384395
public:
385396
DeclRefExpr(ValueDecl *D, SourceLoc Loc, bool Implicit, Type Ty = Type())
386-
: Expr(ExprKind::DeclRef, Implicit, Ty), DAndSpecialized(D, false), Loc(Loc) {}
397+
: Expr(ExprKind::DeclRef, Implicit, Ty), DAndSpecialized(D), Loc(Loc) {}
387398

388-
ValueDecl *getDecl() const { return DAndSpecialized.getPointer(); }
399+
ValueDecl *getDecl() const {
400+
if (auto Spec = getSpecInfo())
401+
return Spec->D;
402+
return DAndSpecialized.get<ValueDecl*>();
403+
}
389404

390-
void setSpecialized(bool specialized) { DAndSpecialized.setInt(specialized); }
405+
void setSpecialized();
391406

392407
/// \brief Determine whether this declaration reference was immediately
393408
/// specialized by <...>.
394-
bool isSpecialized() const { return DAndSpecialized.getInt(); }
409+
bool isSpecialized() const { return getSpecInfo() != nullptr; }
395410

411+
/// Set the generic arguments.
412+
///
413+
/// This copies the array using ASTContext's allocator.
414+
void setGenericArgs(ArrayRef<TypeRepr*> GenericArgs);
415+
416+
/// Returns the generic arguments if it was specialized or an empty array
417+
/// otherwise.
418+
ArrayRef<TypeRepr *> getGenericArgs() const {
419+
return const_cast<DeclRefExpr*>(this)->getGenericArgs();
420+
}
421+
MutableArrayRef<TypeRepr *> getGenericArgs() {
422+
if (auto Spec = getSpecInfo())
423+
return Spec->GenericArgs;
424+
return MutableArrayRef<TypeRepr *>();
425+
}
396426
SourceRange getSourceRange() const { return Loc; }
397427

398428
static bool classof(const Expr *E) {

lib/AST/ASTDumper.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,7 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
877877
void printRec(Pattern *P) {
878878
PrintPattern(OS, Indent+2).visit(P);
879879
}
880+
void printRec(TypeRepr *T);
880881

881882
void printSubstitutions(ArrayRef<Substitution> Substitutions) {
882883
for (auto S : Substitutions) {
@@ -940,7 +941,13 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
940941
printCommon(E, "declref_expr")
941942
<< " decl=";
942943
E->getDecl()->dumpRef(OS);
943-
OS << " specialized=" << (E->isSpecialized()? "yes" : "no") << ")";
944+
OS << " specialized=" << (E->isSpecialized()? "yes" : "no");
945+
946+
for (auto TR : E->getGenericArgs()) {
947+
OS << '\n';
948+
printRec(TR);
949+
}
950+
OS << ')';
944951
}
945952
void visitSuperRefExpr(SuperRefExpr *E) {
946953
printCommon(E, "super_ref_expr") << ')';
@@ -987,8 +994,7 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
987994
printRec(E->getSubExpr());
988995
for (TypeLoc T : E->getUnresolvedParams()) {
989996
OS << '\n';
990-
OS.indent(Indent+2);
991-
T.getTypeRepr()->print(OS);
997+
printRec(T.getTypeRepr());
992998
}
993999
OS << ')';
9941000
}
@@ -1506,6 +1512,10 @@ void PrintDecl::printRec(TypeRepr *T) {
15061512
PrintTypeRepr(OS, Indent+2).visit(T);
15071513
}
15081514

1515+
void PrintExpr::printRec(TypeRepr *T) {
1516+
PrintTypeRepr(OS, Indent+2).visit(T);
1517+
}
1518+
15091519
void PrintPattern::printRec(TypeRepr *T) {
15101520
PrintTypeRepr(OS, Indent+2).visit(T);
15111521
}

lib/AST/ASTWalker.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
7777
Expr *visitErrorExpr(ErrorExpr *E) { return E; }
7878
Expr *visitLiteralExpr(LiteralExpr *E) { return E; }
7979
Expr *visitDiscardAssignmentExpr(DiscardAssignmentExpr *E) { return E; }
80-
Expr *visitDeclRefExpr(DeclRefExpr *E) { return E; }
8180
Expr *visitSuperRefExpr(SuperRefExpr *E) { return E; }
8281
Expr *visitOtherConstructorDeclRefExpr(OtherConstructorDeclRefExpr *E) {
8382
return E;
@@ -124,6 +123,14 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
124123
}
125124
return nullptr;
126125
}
126+
127+
Expr *visitDeclRefExpr(DeclRefExpr *E) {
128+
for (auto Ty : E->getGenericArgs()) {
129+
if (doIt(Ty))
130+
return nullptr;
131+
}
132+
return E;
133+
}
127134

128135
Expr *visitMemberRefExpr(MemberRefExpr *E) {
129136
if (Expr *Base = doIt(E->getBase())) {

lib/AST/Expr.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,27 @@ llvm::APFloat FloatLiteralExpr::getValue() const {
137137
getType()->castTo<BuiltinFloatType>()->getAPFloatSemantics());
138138
}
139139

140+
void DeclRefExpr::setSpecialized() {
141+
if (isSpecialized())
142+
return;
143+
144+
ValueDecl *D = getDecl();
145+
assert(D);
146+
void *Mem = D->getASTContext().Allocate(sizeof(SpecializeInfo),
147+
alignof(SpecializeInfo));
148+
auto Spec = new (Mem) SpecializeInfo;
149+
Spec->D = D;
150+
DAndSpecialized = Spec;
151+
}
152+
153+
void DeclRefExpr::setGenericArgs(ArrayRef<TypeRepr*> GenericArgs) {
154+
ValueDecl *D = getDecl();
155+
assert(D);
156+
setSpecialized();
157+
getSpecInfo()->GenericArgs = D->getASTContext().AllocateCopy(GenericArgs);
158+
}
159+
160+
140161
MemberRefExpr::MemberRefExpr(Expr *base, SourceLoc dotLoc,
141162
ConcreteDeclRef member, SourceLoc nameLoc,
142163
bool Implicit)

lib/Parse/ParseExpr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1369,7 +1369,7 @@ Expr *Parser::actOnIdentifierExpr(Identifier text, SourceLoc loc) {
13691369
E = unresolved;
13701370
} else {
13711371
auto declRef = new (Context) DeclRefExpr(D, loc, /*Implicit=*/false);
1372-
declRef->setSpecialized(hasGenericArgumentList);
1372+
declRef->setGenericArgs(args);
13731373
E = declRef;
13741374
}
13751375

lib/Sema/TypeCheckConstraintsApply.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1221,7 +1221,12 @@ namespace {
12211221

12221222
Expr *visitUnresolvedSpecializeExpr(UnresolvedSpecializeExpr *expr) {
12231223
// Our specializations should have resolved the subexpr to the right type.
1224-
// FIXME: Should preserve generic argument list for source fidelity
1224+
if (auto DRE = dyn_cast<DeclRefExpr>(expr->getSubExpr())) {
1225+
SmallVector<TypeRepr *, 8> GenArgs;
1226+
for (auto TL : expr->getUnresolvedParams())
1227+
GenArgs.push_back(TL.getTypeRepr());
1228+
DRE->setGenericArgs(GenArgs);
1229+
}
12251230
return expr->getSubExpr();
12261231
}
12271232

lib/Sema/TypeCheckExpr.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,8 @@ Expr *TypeChecker::buildRefExpr(ArrayRef<ValueDecl *> Decls, SourceLoc NameLoc,
408408

409409
if (Decls.size() == 1 && !isa<ProtocolDecl>(Decls[0]->getDeclContext())) {
410410
auto result = new (Context) DeclRefExpr(Decls[0], NameLoc, Implicit);
411-
result->setSpecialized(isSpecialized);
411+
if (isSpecialized)
412+
result->setSpecialized();
412413
return result;
413414
}
414415

0 commit comments

Comments
 (0)