Skip to content

Commit e4624aa

Browse files
committed
[SIL] Allow SILDeclRef to store a FileUnit
This will be used to represent the entry-point for a main SourceFile.
1 parent 2720907 commit e4624aa

File tree

5 files changed

+121
-72
lines changed

5 files changed

+121
-72
lines changed

include/swift/AST/TypeAlignments.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ namespace swift {
3838
class DifferentiableAttr;
3939
class Expr;
4040
class ExtensionDecl;
41+
class FileUnit;
4142
class GenericEnvironment;
4243
class GenericParamList;
4344
class GenericTypeParamDecl;
@@ -123,6 +124,7 @@ LLVM_DECLARE_TYPE_ALIGNMENT(swift::BraceStmt, swift::StmtAlignInBits)
123124

124125
LLVM_DECLARE_TYPE_ALIGNMENT(swift::ASTContext, swift::ASTContextAlignInBits);
125126
LLVM_DECLARE_TYPE_ALIGNMENT(swift::DeclContext, swift::DeclContextAlignInBits)
127+
LLVM_DECLARE_TYPE_ALIGNMENT(swift::FileUnit, swift::DeclContextAlignInBits)
126128
LLVM_DECLARE_TYPE_ALIGNMENT(swift::DifferentiableAttr, swift::PointerAlignInBits)
127129
LLVM_DECLARE_TYPE_ALIGNMENT(swift::Expr, swift::ExprAlignInBits)
128130
LLVM_DECLARE_TYPE_ALIGNMENT(swift::CaptureListExpr, swift::ExprAlignInBits)

include/swift/SIL/SILDeclRef.h

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ namespace swift {
4242
class AutoClosureExpr;
4343
class ASTContext;
4444
class ClassDecl;
45+
class FileUnit;
4546
class SILFunctionType;
4647
enum IsSerialized_t : unsigned char;
4748
enum class SubclassScope : unsigned char;
@@ -83,7 +84,14 @@ enum ForDefinition_t : bool {
8384
/// declaration, such as uncurry levels of a function, the allocating and
8485
/// initializing entry points of a constructor, etc.
8586
struct SILDeclRef {
86-
using Loc = llvm::PointerUnion<ValueDecl *, AbstractClosureExpr *>;
87+
/// The type of AST node location being stored.
88+
enum LocKind {
89+
Decl,
90+
Closure,
91+
File
92+
};
93+
using Loc = llvm::PointerUnion<ValueDecl *, AbstractClosureExpr *,
94+
FileUnit *>;
8795

8896
/// Represents the "kind" of the SILDeclRef. For some Swift decls there
8997
/// are multiple SIL entry points, and the kind is used to distinguish them.
@@ -146,7 +154,7 @@ struct SILDeclRef {
146154
PropertyWrapperInitFromProjectedValue,
147155
};
148156

149-
/// The ValueDecl or AbstractClosureExpr represented by this SILDeclRef.
157+
/// The AST node represented by this SILDeclRef.
150158
Loc loc;
151159
/// The Kind of this SILDeclRef.
152160
Kind kind : 4;
@@ -159,6 +167,17 @@ struct SILDeclRef {
159167
const GenericSignatureImpl *>
160168
pointer;
161169

170+
/// Returns the type of AST node location being stored by the SILDeclRef.
171+
LocKind getLocKind() const {
172+
if (loc.is<ValueDecl *>())
173+
return LocKind::Decl;
174+
if (loc.is<AbstractClosureExpr *>())
175+
return LocKind::Closure;
176+
if (loc.is<FileUnit *>())
177+
return LocKind::File;
178+
llvm_unreachable("Unhandled location kind!");
179+
}
180+
162181
/// The derivative function identifier.
163182
AutoDiffDerivativeFunctionIdentifier * getDerivativeFunctionIdentifier() const {
164183
if (!pointer.is<AutoDiffDerivativeFunctionIdentifier *>())

lib/SIL/IR/SILDeclRef.cpp

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -170,14 +170,17 @@ SILDeclRef::SILDeclRef(SILDeclRef::Loc baseLoc,
170170
}
171171

172172
Optional<AnyFunctionRef> SILDeclRef::getAnyFunctionRef() const {
173-
if (auto vd = loc.dyn_cast<ValueDecl*>()) {
174-
if (auto afd = dyn_cast<AbstractFunctionDecl>(vd)) {
173+
switch (getLocKind()) {
174+
case LocKind::Decl:
175+
if (auto *afd = getAbstractFunctionDecl())
175176
return AnyFunctionRef(afd);
176-
} else {
177-
return None;
178-
}
177+
return None;
178+
case LocKind::Closure:
179+
return AnyFunctionRef(getAbstractClosureExpr());
180+
case LocKind::File:
181+
return None;
179182
}
180-
return AnyFunctionRef(loc.get<AbstractClosureExpr*>());
183+
llvm_unreachable("Unhandled case in switch");
181184
}
182185

183186
bool SILDeclRef::isThunk() const {
@@ -226,9 +229,16 @@ bool SILDeclRef::isClangGenerated(ClangNode node) {
226229
}
227230

228231
bool SILDeclRef::isImplicit() const {
229-
if (hasDecl())
232+
switch (getLocKind()) {
233+
case LocKind::Decl:
230234
return getDecl()->isImplicit();
231-
return getAbstractClosureExpr()->isImplicit();
235+
case LocKind::Closure:
236+
return getAbstractClosureExpr()->isImplicit();
237+
case LocKind::File:
238+
// Files are currently never considered implicit.
239+
return false;
240+
}
241+
llvm_unreachable("Unhandled case in switch");
232242
}
233243

234244
SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
@@ -681,17 +691,23 @@ bool SILDeclRef::isNativeToForeignThunk() const {
681691
if (!isForeign)
682692
return false;
683693

684-
// We can have native-to-foreign thunks over closures.
685-
if (!hasDecl())
686-
return true;
694+
switch (getLocKind()) {
695+
case LocKind::Decl:
696+
// A decl with a clang node doesn't have a native entry-point to forward
697+
// onto.
698+
if (getDecl()->hasClangNode())
699+
return false;
687700

688-
// A decl with a clang node doesn't have a native entry-point to forward onto.
689-
if (getDecl()->hasClangNode())
701+
// Only certain kinds of SILDeclRef can expose native-to-foreign thunks.
702+
return kind == Kind::Func || kind == Kind::Initializer ||
703+
kind == Kind::Deallocator;
704+
case LocKind::Closure:
705+
// We can have native-to-foreign thunks over closures.
706+
return true;
707+
case LocKind::File:
690708
return false;
691-
692-
// Only certain kinds of SILDeclRef can expose native-to-foreign thunks.
693-
return kind == Kind::Func || kind == Kind::Initializer ||
694-
kind == Kind::Deallocator;
709+
}
710+
llvm_unreachable("Unhandled case in switch");
695711
}
696712

697713
/// Use the Clang importer to mangle a Clang declaration.
@@ -784,8 +800,8 @@ std::string SILDeclRef::mangle(ManglingKind MKind) const {
784800

785801
switch (kind) {
786802
case SILDeclRef::Kind::Func:
787-
if (!hasDecl())
788-
return mangler.mangleClosureEntity(getAbstractClosureExpr(), SKind);
803+
if (auto *ACE = getAbstractClosureExpr())
804+
return mangler.mangleClosureEntity(ACE, SKind);
789805

790806
// As a special case, functions can have manually mangled names.
791807
// Use the SILGen name only for the original non-thunked, non-curried entry
@@ -1059,9 +1075,15 @@ SILDeclRef SILDeclRef::getOverriddenVTableEntry() const {
10591075
}
10601076

10611077
SILLocation SILDeclRef::getAsRegularLocation() const {
1062-
if (hasDecl())
1078+
switch (getLocKind()) {
1079+
case LocKind::Decl:
10631080
return RegularLocation(getDecl());
1064-
return RegularLocation(getAbstractClosureExpr());
1081+
case LocKind::Closure:
1082+
return RegularLocation(getAbstractClosureExpr());
1083+
case LocKind::File:
1084+
return RegularLocation::getModuleLocation();
1085+
}
1086+
llvm_unreachable("Unhandled case in switch");
10651087
}
10661088

10671089
SubclassScope SILDeclRef::getSubclassScope() const {

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3262,19 +3262,21 @@ TypeConverter::getDeclRefRepresentation(SILDeclRef c) {
32623262
}
32633263

32643264
// Anonymous functions currently always have Freestanding CC.
3265-
if (!c.hasDecl())
3265+
if (c.getAbstractClosureExpr())
32663266
return SILFunctionTypeRepresentation::Thin;
32673267

32683268
// FIXME: Assert that there is a native entry point
32693269
// available. There's no great way to do this.
32703270

32713271
// Protocol witnesses are called using the witness calling convention.
3272-
if (auto proto = dyn_cast<ProtocolDecl>(c.getDecl()->getDeclContext())) {
3273-
// Use the regular method convention for foreign-to-native thunks.
3274-
if (c.isForeignToNativeThunk())
3275-
return SILFunctionTypeRepresentation::Method;
3276-
assert(!c.isNativeToForeignThunk() && "shouldn't be possible");
3277-
return getProtocolWitnessRepresentation(proto);
3272+
if (c.hasDecl()) {
3273+
if (auto proto = dyn_cast<ProtocolDecl>(c.getDecl()->getDeclContext())) {
3274+
// Use the regular method convention for foreign-to-native thunks.
3275+
if (c.isForeignToNativeThunk())
3276+
return SILFunctionTypeRepresentation::Method;
3277+
assert(!c.isNativeToForeignThunk() && "shouldn't be possible");
3278+
return getProtocolWitnessRepresentation(proto);
3279+
}
32783280
}
32793281

32803282
switch (c.kind) {

lib/SIL/IR/SILPrinter.cpp

Lines changed: 46 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -262,53 +262,57 @@ void SILDeclRef::print(raw_ostream &OS) const {
262262
}
263263

264264
bool isDot = true;
265-
if (!hasDecl()) {
265+
switch (getLocKind()) {
266+
case LocKind::Closure:
266267
OS << "<anonymous function>";
267-
} else if (kind == SILDeclRef::Kind::Func) {
268-
auto *FD = cast<FuncDecl>(getDecl());
269-
auto accessor = dyn_cast<AccessorDecl>(FD);
268+
break;
269+
case LocKind::File:
270+
OS << "<file>";
271+
break;
272+
case LocKind::Decl: {
273+
if (kind != Kind::Func) {
274+
printValueDecl(getDecl(), OS);
275+
break;
276+
}
277+
278+
auto *accessor = dyn_cast<AccessorDecl>(getDecl());
270279
if (!accessor) {
271-
printValueDecl(FD, OS);
280+
printValueDecl(getDecl(), OS);
272281
isDot = false;
273-
} else {
274-
switch (accessor->getAccessorKind()) {
275-
case AccessorKind::WillSet:
276-
printValueDecl(accessor->getStorage(), OS);
277-
OS << "!willSet";
278-
break;
279-
case AccessorKind::DidSet:
280-
printValueDecl(accessor->getStorage(), OS);
281-
OS << "!didSet";
282-
break;
283-
case AccessorKind::Get:
284-
printValueDecl(accessor->getStorage(), OS);
285-
OS << "!getter";
286-
break;
287-
case AccessorKind::Set:
288-
printValueDecl(accessor->getStorage(), OS);
289-
OS << "!setter";
290-
break;
291-
case AccessorKind::Address:
292-
printValueDecl(accessor->getStorage(), OS);
293-
OS << "!addressor";
294-
break;
295-
case AccessorKind::MutableAddress:
296-
printValueDecl(accessor->getStorage(), OS);
297-
OS << "!mutableAddressor";
298-
break;
299-
case AccessorKind::Read:
300-
printValueDecl(accessor->getStorage(), OS);
301-
OS << "!read";
302-
break;
303-
case AccessorKind::Modify:
304-
printValueDecl(accessor->getStorage(), OS);
305-
OS << "!modify";
306-
break;
307-
}
282+
break;
308283
}
309-
} else {
310-
printValueDecl(getDecl(), OS);
284+
285+
printValueDecl(accessor->getStorage(), OS);
286+
switch (accessor->getAccessorKind()) {
287+
case AccessorKind::WillSet:
288+
OS << "!willSet";
289+
break;
290+
case AccessorKind::DidSet:
291+
OS << "!didSet";
292+
break;
293+
case AccessorKind::Get:
294+
OS << "!getter";
295+
break;
296+
case AccessorKind::Set:
297+
OS << "!setter";
298+
break;
299+
case AccessorKind::Address:
300+
OS << "!addressor";
301+
break;
302+
case AccessorKind::MutableAddress:
303+
OS << "!mutableAddressor";
304+
break;
305+
case AccessorKind::Read:
306+
OS << "!read";
307+
break;
308+
case AccessorKind::Modify:
309+
OS << "!modify";
310+
break;
311+
}
312+
break;
313+
}
311314
}
315+
312316
switch (kind) {
313317
case SILDeclRef::Kind::Func:
314318
break;

0 commit comments

Comments
 (0)