Skip to content

Commit ed104a8

Browse files
authored
Merge pull request #37014 from hamishknight/entry-sign
2 parents 41e3332 + 9020c13 commit ed104a8

File tree

17 files changed

+310
-189
lines changed

17 files changed

+310
-189
lines changed

include/swift/AST/FileUnit.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ class FileUnit : public DeclContext {
273273
return dyn_cast_or_null<ClassDecl>(getMainDecl());
274274
}
275275
bool hasMainDecl() const { return getMainDecl(); }
276-
virtual Decl *getMainDecl() const { return nullptr; }
276+
virtual ValueDecl *getMainDecl() const { return nullptr; }
277277
FuncDecl *getMainFunc() const {
278278
return dyn_cast_or_null<FuncDecl>(getMainDecl());
279279
}

include/swift/AST/SourceFile.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ class SourceFile final : public FileUnit {
9999

100100
/// Either the class marked \@NS/UIApplicationMain or the synthesized FuncDecl
101101
/// that calls main on the type marked @main.
102-
Decl *MainDecl = nullptr;
102+
ValueDecl *MainDecl = nullptr;
103103

104104
/// The source location of the main type.
105105
SourceLoc MainDeclDiagLoc;
@@ -480,7 +480,7 @@ class SourceFile final : public FileUnit {
480480
llvm_unreachable("bad SourceFileKind");
481481
}
482482

483-
Decl *getMainDecl() const override { return MainDecl; }
483+
ValueDecl *getMainDecl() const override { return MainDecl; }
484484
SourceLoc getMainDeclDiagLoc() const {
485485
assert(hasMainDecl());
486486
return MainDeclDiagLoc;
@@ -494,7 +494,7 @@ class SourceFile final : public FileUnit {
494494
/// one.
495495
///
496496
/// Should only be called during type-checking.
497-
bool registerMainDecl(Decl *mainDecl, SourceLoc diagLoc);
497+
bool registerMainDecl(ValueDecl *mainDecl, SourceLoc diagLoc);
498498

499499
/// True if this source file has an application entry point.
500500
///

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: 38 additions & 3 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.
@@ -144,9 +152,13 @@ struct SILDeclRef {
144152
/// References the function used to initialize a property wrapper storage
145153
/// instance from a projected value.
146154
PropertyWrapperInitFromProjectedValue,
155+
156+
/// The main entry-point function. This may reference a SourceFile for a
157+
/// top-level main, or a decl for e.g an @main decl.
158+
EntryPoint,
147159
};
148160

149-
/// The ValueDecl or AbstractClosureExpr represented by this SILDeclRef.
161+
/// The AST node represented by this SILDeclRef.
150162
Loc loc;
151163
/// The Kind of this SILDeclRef.
152164
Kind kind : 4;
@@ -159,6 +171,17 @@ struct SILDeclRef {
159171
const GenericSignatureImpl *>
160172
pointer;
161173

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+
162185
/// The derivative function identifier.
163186
AutoDiffDerivativeFunctionIdentifier * getDerivativeFunctionIdentifier() const {
164187
if (!pointer.is<AutoDiffDerivativeFunctionIdentifier *>())
@@ -201,6 +224,12 @@ struct SILDeclRef {
201224
/// Produce a SIL constant for a default argument generator.
202225
static SILDeclRef getDefaultArgGenerator(Loc loc, unsigned defaultArgIndex);
203226

227+
/// Produces a SILDeclRef for a synthetic main entry-point such as @main.
228+
static SILDeclRef getMainDeclEntryPoint(ValueDecl *decl);
229+
230+
/// Produces a SILDeclRef for the entry-point of a main FileUnit.
231+
static SILDeclRef getMainFileEntryPoint(FileUnit *file);
232+
204233
bool isNull() const { return loc.isNull(); }
205234
explicit operator bool() const { return !isNull(); }
206235

@@ -217,7 +246,13 @@ struct SILDeclRef {
217246
AutoClosureExpr *getAutoClosureExpr() const;
218247
FuncDecl *getFuncDecl() const;
219248
AbstractFunctionDecl *getAbstractFunctionDecl() const;
220-
249+
FileUnit *getFileUnit() const {
250+
return loc.get<FileUnit *>();
251+
}
252+
253+
/// Retrieves the ASTContext from the underlying AST node being stored.
254+
ASTContext &getASTContext() const;
255+
221256
llvm::Optional<AnyFunctionRef> getAnyFunctionRef() const;
222257

223258
SILLocation getAsRegularLocation() const;

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ class SerializedASTFile final : public LoadedFile {
443443

444444
virtual StringRef getModuleDefiningPath() const override;
445445

446-
Decl *getMainDecl() const override;
446+
ValueDecl *getMainDecl() const override;
447447

448448
bool hasEntryPoint() const override;
449449

lib/AST/Module.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1423,7 +1423,7 @@ bool ModuleDecl::isBuiltinModule() const {
14231423
return this == getASTContext().TheBuiltinModule;
14241424
}
14251425

1426-
bool SourceFile::registerMainDecl(Decl *mainDecl, SourceLoc diagLoc) {
1426+
bool SourceFile::registerMainDecl(ValueDecl *mainDecl, SourceLoc diagLoc) {
14271427
assert(mainDecl);
14281428
if (mainDecl == MainDecl)
14291429
return false;

lib/IRGen/GenObjC.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,7 @@ namespace {
473473
case SILDeclRef::Kind::GlobalAccessor:
474474
case SILDeclRef::Kind::PropertyWrapperBackingInitializer:
475475
case SILDeclRef::Kind::PropertyWrapperInitFromProjectedValue:
476+
case SILDeclRef::Kind::EntryPoint:
476477
llvm_unreachable("Method does not have a selector");
477478

478479
case SILDeclRef::Kind::Destroyer:

lib/SIL/IR/SILDeclRef.cpp

Lines changed: 90 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "swift/AST/AnyFunctionRef.h"
1717
#include "swift/AST/Initializer.h"
1818
#include "swift/AST/ParameterList.h"
19+
#include "swift/AST/SourceFile.h"
1920
#include "swift/ClangImporter/ClangImporter.h"
2021
#include "swift/ClangImporter/ClangModule.h"
2122
#include "swift/SIL/SILLinkage.h"
@@ -170,14 +171,29 @@ SILDeclRef::SILDeclRef(SILDeclRef::Loc baseLoc,
170171
}
171172

172173
Optional<AnyFunctionRef> SILDeclRef::getAnyFunctionRef() const {
173-
if (auto vd = loc.dyn_cast<ValueDecl*>()) {
174-
if (auto afd = dyn_cast<AbstractFunctionDecl>(vd)) {
174+
switch (getLocKind()) {
175+
case LocKind::Decl:
176+
if (auto *afd = getAbstractFunctionDecl())
175177
return AnyFunctionRef(afd);
176-
} else {
177-
return None;
178-
}
178+
return None;
179+
case LocKind::Closure:
180+
return AnyFunctionRef(getAbstractClosureExpr());
181+
case LocKind::File:
182+
return None;
183+
}
184+
llvm_unreachable("Unhandled case in switch");
185+
}
186+
187+
ASTContext &SILDeclRef::getASTContext() const {
188+
switch (getLocKind()) {
189+
case LocKind::Decl:
190+
return getDecl()->getASTContext();
191+
case LocKind::Closure:
192+
return getAbstractClosureExpr()->getASTContext();
193+
case LocKind::File:
194+
return getFileUnit()->getASTContext();
179195
}
180-
return AnyFunctionRef(loc.get<AbstractClosureExpr*>());
196+
llvm_unreachable("Unhandled case in switch");
181197
}
182198

183199
bool SILDeclRef::isThunk() const {
@@ -226,9 +242,16 @@ bool SILDeclRef::isClangGenerated(ClangNode node) {
226242
}
227243

228244
bool SILDeclRef::isImplicit() const {
229-
if (hasDecl())
245+
switch (getLocKind()) {
246+
case LocKind::Decl:
230247
return getDecl()->isImplicit();
231-
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");
232255
}
233256

234257
SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
@@ -242,6 +265,10 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
242265
return isSerialized() ? SILLinkage::Shared : SILLinkage::Private;
243266
}
244267

268+
// The main entry-point is public.
269+
if (kind == Kind::EntryPoint)
270+
return SILLinkage::Public;
271+
245272
// Add External to the linkage (e.g. Public -> PublicExternal) if this is a
246273
// declaration not a definition.
247274
auto maybeAddExternal = [&](SILLinkage linkage) {
@@ -407,6 +434,23 @@ SILDeclRef SILDeclRef::getDefaultArgGenerator(Loc loc,
407434
return result;
408435
}
409436

437+
SILDeclRef SILDeclRef::getMainDeclEntryPoint(ValueDecl *decl) {
438+
auto *file = cast<FileUnit>(decl->getDeclContext()->getModuleScopeContext());
439+
assert(file->getMainDecl() == decl);
440+
SILDeclRef result;
441+
result.loc = decl;
442+
result.kind = Kind::EntryPoint;
443+
return result;
444+
}
445+
446+
SILDeclRef SILDeclRef::getMainFileEntryPoint(FileUnit *file) {
447+
assert(file->hasEntryPoint() && !file->getMainDecl());
448+
SILDeclRef result;
449+
result.loc = file;
450+
result.kind = Kind::EntryPoint;
451+
return result;
452+
}
453+
410454
bool SILDeclRef::hasClosureExpr() const {
411455
return loc.is<AbstractClosureExpr *>()
412456
&& isa<ClosureExpr>(getAbstractClosureExpr());
@@ -490,6 +534,9 @@ IsSerialized_t SILDeclRef::isSerialized() const {
490534
return IsNotSerialized;
491535
}
492536

537+
if (kind == Kind::EntryPoint)
538+
return IsNotSerialized;
539+
493540
if (isIVarInitializerOrDestroyer())
494541
return IsNotSerialized;
495542

@@ -681,17 +728,23 @@ bool SILDeclRef::isNativeToForeignThunk() const {
681728
if (!isForeign)
682729
return false;
683730

684-
// We can have native-to-foreign thunks over closures.
685-
if (!hasDecl())
686-
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;
687737

688-
// A decl with a clang node doesn't have a native entry-point to forward onto.
689-
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:
690745
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;
746+
}
747+
llvm_unreachable("Unhandled case in switch");
695748
}
696749

697750
/// Use the Clang importer to mangle a Clang declaration.
@@ -781,8 +834,8 @@ std::string SILDeclRef::mangle(ManglingKind MKind) const {
781834

782835
switch (kind) {
783836
case SILDeclRef::Kind::Func:
784-
if (!hasDecl())
785-
return mangler.mangleClosureEntity(getAbstractClosureExpr(), SKind);
837+
if (auto *ACE = getAbstractClosureExpr())
838+
return mangler.mangleClosureEntity(ACE, SKind);
786839

787840
// As a special case, functions can have manually mangled names.
788841
// Use the SILGen name only for the original non-thunked, non-curried entry
@@ -853,6 +906,10 @@ std::string SILDeclRef::mangle(ManglingKind MKind) const {
853906
case SILDeclRef::Kind::PropertyWrapperInitFromProjectedValue:
854907
return mangler.mangleInitFromProjectedValueEntity(cast<VarDecl>(getDecl()),
855908
SKind);
909+
910+
case SILDeclRef::Kind::EntryPoint: {
911+
return getASTContext().getEntryPointFunctionName();
912+
}
856913
}
857914

858915
llvm_unreachable("bad entity kind!");
@@ -1056,9 +1113,15 @@ SILDeclRef SILDeclRef::getOverriddenVTableEntry() const {
10561113
}
10571114

10581115
SILLocation SILDeclRef::getAsRegularLocation() const {
1059-
if (hasDecl())
1116+
switch (getLocKind()) {
1117+
case LocKind::Decl:
10601118
return RegularLocation(getDecl());
1061-
return RegularLocation(getAbstractClosureExpr());
1119+
case LocKind::Closure:
1120+
return RegularLocation(getAbstractClosureExpr());
1121+
case LocKind::File:
1122+
return RegularLocation::getModuleLocation();
1123+
}
1124+
llvm_unreachable("Unhandled case in switch");
10621125
}
10631126

10641127
SubclassScope SILDeclRef::getSubclassScope() const {
@@ -1165,7 +1228,12 @@ SubclassScope SILDeclRef::getSubclassScope() const {
11651228
}
11661229

11671230
unsigned SILDeclRef::getParameterListCount() const {
1168-
if (!hasDecl() || kind == Kind::DefaultArgGenerator)
1231+
// Only decls can introduce currying.
1232+
if (!hasDecl())
1233+
return 1;
1234+
1235+
// Always uncurried even if the underlying function is curried.
1236+
if (kind == Kind::DefaultArgGenerator || kind == Kind::EntryPoint)
11691237
return 1;
11701238

11711239
auto *vd = getDecl();

0 commit comments

Comments
 (0)