Skip to content

Commit 7ae40f4

Browse files
hamishknightetcwilde
authored andcommitted
[SIL] Allow SILDeclRef to store a FileUnit
This will be used to represent the entry-point for a main SourceFile.
1 parent c925246 commit 7ae40f4

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.
@@ -150,7 +158,7 @@ struct SILDeclRef {
150158
EntryPoint,
151159
};
152160

153-
/// The ValueDecl or AbstractClosureExpr represented by this SILDeclRef.
161+
/// The AST node represented by this SILDeclRef.
154162
Loc loc;
155163
/// The Kind of this SILDeclRef.
156164
Kind kind : 4;
@@ -163,6 +171,17 @@ struct SILDeclRef {
163171
const GenericSignatureImpl *>
164172
pointer;
165173

174+
/// Returns the type of AST node location being stored by the SILDeclRef.
175+
LocKind getLocKind() const {
176+
if (loc.is<ValueDecl *>())
177+
return LocKind::Decl;
178+
if (loc.is<AbstractClosureExpr *>())
179+
return LocKind::Closure;
180+
if (loc.is<FileUnit *>())
181+
return LocKind::File;
182+
llvm_unreachable("Unhandled location kind!");
183+
}
184+
166185
/// The derivative function identifier.
167186
AutoDiffDerivativeFunctionIdentifier * getDerivativeFunctionIdentifier() const {
168187
if (!pointer.is<AutoDiffDerivativeFunctionIdentifier *>())

lib/SIL/IR/SILDeclRef.cpp

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

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

184187
ASTContext &SILDeclRef::getASTContext() const {
@@ -239,9 +242,16 @@ bool SILDeclRef::isClangGenerated(ClangNode node) {
239242
}
240243

241244
bool SILDeclRef::isImplicit() const {
242-
if (hasDecl())
245+
switch (getLocKind()) {
246+
case LocKind::Decl:
243247
return getDecl()->isImplicit();
244-
return getAbstractClosureExpr()->isImplicit();
248+
case LocKind::Closure:
249+
return getAbstractClosureExpr()->isImplicit();
250+
case LocKind::File:
251+
// Files are currently never considered implicit.
252+
return false;
253+
}
254+
llvm_unreachable("Unhandled case in switch");
245255
}
246256

247257
SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
@@ -718,17 +728,23 @@ bool SILDeclRef::isNativeToForeignThunk() const {
718728
if (!isForeign)
719729
return false;
720730

721-
// We can have native-to-foreign thunks over closures.
722-
if (!hasDecl())
723-
return true;
731+
switch (getLocKind()) {
732+
case LocKind::Decl:
733+
// A decl with a clang node doesn't have a native entry-point to forward
734+
// onto.
735+
if (getDecl()->hasClangNode())
736+
return false;
724737

725-
// A decl with a clang node doesn't have a native entry-point to forward onto.
726-
if (getDecl()->hasClangNode())
738+
// Only certain kinds of SILDeclRef can expose native-to-foreign thunks.
739+
return kind == Kind::Func || kind == Kind::Initializer ||
740+
kind == Kind::Deallocator;
741+
case LocKind::Closure:
742+
// We can have native-to-foreign thunks over closures.
743+
return true;
744+
case LocKind::File:
727745
return false;
728-
729-
// Only certain kinds of SILDeclRef can expose native-to-foreign thunks.
730-
return kind == Kind::Func || kind == Kind::Initializer ||
731-
kind == Kind::Deallocator;
746+
}
747+
llvm_unreachable("Unhandled case in switch");
732748
}
733749

734750
/// Use the Clang importer to mangle a Clang declaration.
@@ -821,8 +837,8 @@ std::string SILDeclRef::mangle(ManglingKind MKind) const {
821837

822838
switch (kind) {
823839
case SILDeclRef::Kind::Func:
824-
if (!hasDecl())
825-
return mangler.mangleClosureEntity(getAbstractClosureExpr(), SKind);
840+
if (auto *ACE = getAbstractClosureExpr())
841+
return mangler.mangleClosureEntity(ACE, SKind);
826842

827843
// As a special case, functions can have manually mangled names.
828844
// Use the SILGen name only for the original non-thunked, non-curried entry
@@ -1100,9 +1116,15 @@ SILDeclRef SILDeclRef::getOverriddenVTableEntry() const {
11001116
}
11011117

11021118
SILLocation SILDeclRef::getAsRegularLocation() const {
1103-
if (hasDecl())
1119+
switch (getLocKind()) {
1120+
case LocKind::Decl:
11041121
return RegularLocation(getDecl());
1105-
return RegularLocation(getAbstractClosureExpr());
1122+
case LocKind::Closure:
1123+
return RegularLocation(getAbstractClosureExpr());
1124+
case LocKind::File:
1125+
return RegularLocation::getModuleLocation();
1126+
}
1127+
llvm_unreachable("Unhandled case in switch");
11061128
}
11071129

11081130
SubclassScope SILDeclRef::getSubclassScope() const {

lib/SIL/IR/SILFunctionType.cpp

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

32533253
// Anonymous functions currently always have Freestanding CC.
3254-
if (!c.hasDecl())
3254+
if (c.getAbstractClosureExpr())
32553255
return SILFunctionTypeRepresentation::Thin;
32563256

32573257
// FIXME: Assert that there is a native entry point
32583258
// available. There's no great way to do this.
32593259

32603260
// Protocol witnesses are called using the witness calling convention.
3261-
if (auto proto = dyn_cast<ProtocolDecl>(c.getDecl()->getDeclContext())) {
3262-
// Use the regular method convention for foreign-to-native thunks.
3263-
if (c.isForeignToNativeThunk())
3264-
return SILFunctionTypeRepresentation::Method;
3265-
assert(!c.isNativeToForeignThunk() && "shouldn't be possible");
3266-
return getProtocolWitnessRepresentation(proto);
3261+
if (c.hasDecl()) {
3262+
if (auto proto = dyn_cast<ProtocolDecl>(c.getDecl()->getDeclContext())) {
3263+
// Use the regular method convention for foreign-to-native thunks.
3264+
if (c.isForeignToNativeThunk())
3265+
return SILFunctionTypeRepresentation::Method;
3266+
assert(!c.isNativeToForeignThunk() && "shouldn't be possible");
3267+
return getProtocolWitnessRepresentation(proto);
3268+
}
32673269
}
32683270

32693271
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
case SILDeclRef::Kind::EntryPoint:

0 commit comments

Comments
 (0)