Skip to content

Commit 50632d2

Browse files
committed
Sema: Add a request to synthesize the main function
1 parent 56a0b82 commit 50632d2

File tree

5 files changed

+51
-11
lines changed

5 files changed

+51
-11
lines changed

include/swift/AST/ASTTypeIDZone.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ SWIFT_TYPEID_NAMED(ConstructorDecl *, ConstructorDecl)
4040
SWIFT_TYPEID_NAMED(CustomAttr *, CustomAttr)
4141
SWIFT_TYPEID_NAMED(Decl *, Decl)
4242
SWIFT_TYPEID_NAMED(EnumDecl *, EnumDecl)
43+
SWIFT_TYPEID_NAMED(FuncDecl *, FuncDecl)
4344
SWIFT_TYPEID_NAMED(GenericParamList *, GenericParamList)
4445
SWIFT_TYPEID_NAMED(GenericTypeParamType *, GenericTypeParamType)
4546
SWIFT_TYPEID_NAMED(InfixOperatorDecl *, InfixOperatorDecl)

include/swift/AST/ASTTypeIDs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class ConstructorDecl;
3030
class CustomAttr;
3131
class Decl;
3232
class EnumDecl;
33+
class FuncDecl;
3334
enum class FunctionBuilderBodyPreCheck : uint8_t;
3435
class GenericParamList;
3536
class GenericSignature;

include/swift/AST/TypeCheckRequests.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2564,6 +2564,23 @@ class CustomAttrTypeRequest
25642564
void cacheResult(Type value) const;
25652565
};
25662566

2567+
class SynthesizeMainFunctionRequest
2568+
: public SimpleRequest<SynthesizeMainFunctionRequest,
2569+
FuncDecl *(Decl *),
2570+
RequestFlags::Cached> {
2571+
public:
2572+
using SimpleRequest::SimpleRequest;
2573+
2574+
private:
2575+
friend SimpleRequest;
2576+
2577+
// Evaluation.
2578+
FuncDecl *evaluate(Evaluator &evaluator, Decl *) const;
2579+
2580+
public:
2581+
bool isCached() const { return true; }
2582+
};
2583+
25672584
// Allow AnyValue to compare two Type values, even though Type doesn't
25682585
// support ==.
25692586
template<>

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,3 +274,5 @@ SWIFT_REQUEST(TypeChecker, LookupAllConformancesInContextRequest,
274274
Uncached, NoLocationInfo)
275275
SWIFT_REQUEST(TypeChecker, SimpleDidSetRequest,
276276
bool(AccessorDecl *), Cached, NoLocationInfo)
277+
SWIFT_REQUEST(TypeChecker, SynthesizeMainFunctionRequest,
278+
FuncDecl *(Decl *), Cached, NoLocationInfo)

lib/Sema/TypeCheckAttr.cpp

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1843,7 +1843,15 @@ synthesizeMainBody(AbstractFunctionDecl *fn, void *arg) {
18431843
return std::make_pair(body, /*typechecked=*/false);
18441844
}
18451845

1846-
void AttributeChecker::visitMainTypeAttr(MainTypeAttr *attr) {
1846+
FuncDecl *
1847+
SynthesizeMainFunctionRequest::evaluate(Evaluator &evaluator,
1848+
Decl *D) const {
1849+
auto &context = D->getASTContext();
1850+
1851+
MainTypeAttr *attr = D->getAttrs().getAttribute<MainTypeAttr>();
1852+
if (attr == nullptr)
1853+
return nullptr;
1854+
18471855
auto *extension = dyn_cast<ExtensionDecl>(D);
18481856

18491857
IterableDeclContext *iterableDeclContext;
@@ -1870,10 +1878,10 @@ void AttributeChecker::visitMainTypeAttr(MainTypeAttr *attr) {
18701878

18711879
// The type cannot be generic.
18721880
if (nominal->isGenericContext()) {
1873-
diagnose(attr->getLocation(),
1874-
diag::attr_generic_ApplicationMain_not_supported, 2);
1881+
context.Diags.diagnose(attr->getLocation(),
1882+
diag::attr_generic_ApplicationMain_not_supported, 2);
18751883
attr->setInvalid();
1876-
return;
1884+
return nullptr;
18771885
}
18781886

18791887
SourceFile *file = cast<SourceFile>(declContext->getModuleScopeContext());
@@ -1890,7 +1898,6 @@ void AttributeChecker::visitMainTypeAttr(MainTypeAttr *attr) {
18901898
// usual type-checking. The alternative would be to directly call
18911899
// mainType.main() from the entry point, and that would require fully
18921900
// type-checking the call to mainType.main().
1893-
auto &context = D->getASTContext();
18941901

18951902
auto resolution = resolveValueMember(
18961903
*declContext, nominal->getInterfaceType(), context.Id_main);
@@ -1918,10 +1925,11 @@ void AttributeChecker::visitMainTypeAttr(MainTypeAttr *attr) {
19181925
}
19191926

19201927
if (viableCandidates.size() != 1) {
1921-
diagnose(attr->getLocation(), diag::attr_MainType_without_main,
1922-
nominal->getBaseName());
1928+
context.Diags.diagnose(attr->getLocation(),
1929+
diag::attr_MainType_without_main,
1930+
nominal->getBaseName());
19231931
attr->setInvalid();
1924-
return;
1932+
return nullptr;
19251933
}
19261934
mainFunction = viableCandidates[0];
19271935
}
@@ -1968,12 +1976,23 @@ void AttributeChecker::visitMainTypeAttr(MainTypeAttr *attr) {
19681976
// Of course, this function's body does not type-check.
19691977
file->DelayedFunctions.push_back(func);
19701978

1979+
return func;
1980+
}
1981+
1982+
void AttributeChecker::visitMainTypeAttr(MainTypeAttr *attr) {
1983+
auto &context = D->getASTContext();
1984+
1985+
SourceFile *file = D->getDeclContext()->getParentSourceFile();
1986+
assert(file);
1987+
1988+
auto *func = evaluateOrDefault(context.evaluator,
1989+
SynthesizeMainFunctionRequest{D},
1990+
nullptr);
1991+
19711992
// Register the func as the main decl in the module. If there are multiples
19721993
// they will be diagnosed.
1973-
if (file->registerMainDecl(func, attr->getLocation())) {
1994+
if (file->registerMainDecl(func, attr->getLocation()))
19741995
attr->setInvalid();
1975-
return;
1976-
}
19771996
}
19781997

19791998
/// Determine whether the given context is an extension to an Objective-C class

0 commit comments

Comments
 (0)