Skip to content

Commit 48805b1

Browse files
committed
Give ASTContext TypeCheckerOptions
Strip TypeChecker of all of this state.
1 parent 422bb37 commit 48805b1

File tree

20 files changed

+101
-124
lines changed

20 files changed

+101
-124
lines changed

include/swift/AST/ASTContext.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,9 @@ class ASTContext final {
201201
ASTContext(const ASTContext&) = delete;
202202
void operator=(const ASTContext&) = delete;
203203

204-
ASTContext(LangOptions &langOpts, SearchPathOptions &SearchPathOpts,
205-
SourceManager &SourceMgr, DiagnosticEngine &Diags);
204+
ASTContext(LangOptions &langOpts, TypeCheckerOptions &typeckOpts,
205+
SearchPathOptions &SearchPathOpts, SourceManager &SourceMgr,
206+
DiagnosticEngine &Diags);
206207

207208
public:
208209
// Members that should only be used by ASTContext.cpp.
@@ -213,10 +214,9 @@ class ASTContext final {
213214

214215
void operator delete(void *Data) throw();
215216

216-
static ASTContext *get(LangOptions &langOpts,
217+
static ASTContext *get(LangOptions &langOpts, TypeCheckerOptions &typeckOpts,
217218
SearchPathOptions &SearchPathOpts,
218-
SourceManager &SourceMgr,
219-
DiagnosticEngine &Diags);
219+
SourceManager &SourceMgr, DiagnosticEngine &Diags);
220220
~ASTContext();
221221

222222
/// Optional table of counters to report, nullptr when not collecting.
@@ -228,6 +228,9 @@ class ASTContext final {
228228
/// The language options used for translation.
229229
LangOptions &LangOpts;
230230

231+
/// The type checker options.
232+
TypeCheckerOptions &TypeCheckerOpts;
233+
231234
/// The search path options used by this AST context.
232235
SearchPathOptions &SearchPathOpts;
233236

include/swift/Subsystems.h

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ namespace swift {
6666
class Token;
6767
class TopLevelContext;
6868
class TypeChecker;
69+
class TypeCheckerOptions;
6970
struct TypeLoc;
7071
class UnifiedStatsReporter;
7172
enum class SourceFileKind;
@@ -183,16 +184,8 @@ namespace swift {
183184
///
184185
/// \param StartElem Where to start for incremental type-checking in the main
185186
/// source file.
186-
///
187-
/// \param WarnLongFunctionBodies If non-zero, warn when a function body takes
188-
/// longer than this many milliseconds to type-check
189187
void performTypeChecking(SourceFile &SF, TopLevelContext &TLC,
190-
OptionSet<TypeCheckingFlags> Options,
191-
unsigned StartElem = 0,
192-
unsigned WarnLongFunctionBodies = 0,
193-
unsigned WarnLongExpressionTypeChecking = 0,
194-
unsigned ExpressionTimeoutThreshold = 0,
195-
unsigned SwitchCheckingInvocationThreshold = 0);
188+
unsigned StartElem = 0);
196189

197190
/// Now that we have type-checked an entire module, perform any type
198191
/// checking that requires the full module, e.g., Objective-C method

lib/AST/ASTContext.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,7 @@ void ASTContext::operator delete(void *Data) throw() {
504504
}
505505

506506
ASTContext *ASTContext::get(LangOptions &langOpts,
507+
TypeCheckerOptions &typeckOpts,
507508
SearchPathOptions &SearchPathOpts,
508509
SourceManager &SourceMgr,
509510
DiagnosticEngine &Diags) {
@@ -516,15 +517,16 @@ ASTContext *ASTContext::get(LangOptions &langOpts,
516517
auto impl = reinterpret_cast<void*>((char*)mem + sizeof(ASTContext));
517518
impl = reinterpret_cast<void*>(llvm::alignAddr(impl,alignof(Implementation)));
518519
new (impl) Implementation();
519-
return new (mem) ASTContext(langOpts, SearchPathOpts, SourceMgr, Diags);
520+
return new (mem)
521+
ASTContext(langOpts, typeckOpts, SearchPathOpts, SourceMgr, Diags);
520522
}
521523

522-
ASTContext::ASTContext(LangOptions &langOpts, SearchPathOptions &SearchPathOpts,
524+
ASTContext::ASTContext(LangOptions &langOpts, TypeCheckerOptions &typeckOpts,
525+
SearchPathOptions &SearchPathOpts,
523526
SourceManager &SourceMgr, DiagnosticEngine &Diags)
524527
: LangOpts(langOpts),
525-
SearchPathOpts(SearchPathOpts),
526-
SourceMgr(SourceMgr),
527-
Diags(Diags),
528+
TypeCheckerOpts(typeckOpts),
529+
SearchPathOpts(SearchPathOpts), SourceMgr(SourceMgr), Diags(Diags),
528530
evaluator(Diags, langOpts.DebugDumpCycles),
529531
TheBuiltinModule(createBuiltinModule(*this)),
530532
StdlibModuleName(getIdentifier(STDLIB_NAME)),

lib/Frontend/Frontend.cpp

Lines changed: 28 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,9 @@ bool CompilerInstance::setUpASTContextIfNeeded() {
190190
return false;
191191
}
192192

193-
Context.reset(ASTContext::get(Invocation.getLangOptions(),
194-
Invocation.getSearchPathOptions(), SourceMgr,
195-
Diagnostics));
193+
Context.reset(ASTContext::get(
194+
Invocation.getLangOptions(), Invocation.getTypeCheckerOptions(),
195+
Invocation.getSearchPathOptions(), SourceMgr, Diagnostics));
196196
registerParseRequestFunctions(Context->evaluator);
197197
registerTypeCheckerRequestFunctions(Context->evaluator);
198198

@@ -222,17 +222,28 @@ bool CompilerInstance::setup(const CompilerInvocation &Invok) {
222222
setUpLLVMArguments();
223223
setUpDiagnosticOptions();
224224

225+
const auto &frontendOpts = Invocation.getFrontendOptions();
226+
225227
// If we are asked to emit a module documentation file, configure lexing and
226228
// parsing to remember comments.
227-
if (Invocation.getFrontendOptions().InputsAndOutputs.hasModuleDocOutputPath())
229+
if (frontendOpts.InputsAndOutputs.hasModuleDocOutputPath())
228230
Invocation.getLangOptions().AttachCommentsToDecls = true;
229231

230232
// If we are doing index-while-building, configure lexing and parsing to
231233
// remember comments.
232-
if (!Invocation.getFrontendOptions().IndexStorePath.empty()) {
234+
if (!frontendOpts.IndexStorePath.empty()) {
233235
Invocation.getLangOptions().AttachCommentsToDecls = true;
234236
}
235237

238+
// Set up the type checker options.
239+
auto &typeCkOpts = Invocation.getTypeCheckerOptions();
240+
if (isWholeModuleCompilation()) {
241+
typeCkOpts.DelayWholeModuleChecking = true;
242+
}
243+
if (FrontendOptions::isActionImmediate(frontendOpts.RequestedAction)) {
244+
typeCkOpts.InImmediateMode = true;
245+
}
246+
236247
assert(Lexer::isIdentifier(Invocation.getModuleName()));
237248

238249
if (isInSILMode())
@@ -825,14 +836,12 @@ void CompilerInstance::parseAndCheckTypesUpTo(
825836
if (hadLoadError)
826837
return;
827838

828-
OptionSet<TypeCheckingFlags> TypeCheckOptions = computeTypeCheckingOptions();
829-
830839
// Type-check main file after parsing all other files so that
831840
// it can use declarations from other files.
832841
// In addition, the main file has parsing and type-checking
833842
// interwined.
834843
if (MainBufferID != NO_SUCH_BUFFER) {
835-
parseAndTypeCheckMainFileUpTo(limitStage, TypeCheckOptions);
844+
parseAndTypeCheckMainFileUpTo(limitStage);
836845
}
837846

838847
assert(llvm::all_of(MainModule->getFiles(), [](const FileUnit *File) -> bool {
@@ -843,19 +852,13 @@ void CompilerInstance::parseAndCheckTypesUpTo(
843852
}) && "some files have not yet had their imports resolved");
844853
MainModule->setHasResolvedImports();
845854

846-
const auto &options = Invocation.getFrontendOptions();
847-
forEachFileToTypeCheck([&](SourceFile &SF) {
848-
if (limitStage == SourceFile::NameBound) {
849-
bindExtensions(SF);
850-
return;
851-
}
855+
// If the limiting AST stage is name binding, we're done.
856+
if (limitStage <= SourceFile::NameBound) {
857+
return;
858+
}
852859

853-
performTypeChecking(SF, PersistentState->getTopLevelContext(),
854-
TypeCheckOptions, /*curElem*/ 0,
855-
options.WarnLongFunctionBodies,
856-
options.WarnLongExpressionTypeChecking,
857-
options.SolverExpressionTimeThreshold,
858-
options.SwitchCheckingInvocationThreshold);
860+
forEachFileToTypeCheck([&](SourceFile &SF) {
861+
performTypeChecking(SF, PersistentState->getTopLevelContext());
859862

860863
if (!Context->hadError() && Invocation.getFrontendOptions().PCMacro) {
861864
performPCMacro(SF, PersistentState->getTopLevelContext());
@@ -871,17 +874,10 @@ void CompilerInstance::parseAndCheckTypesUpTo(
871874
});
872875

873876
if (Invocation.isCodeCompletion()) {
874-
assert(limitStage == SourceFile::NameBound);
875877
performCodeCompletionSecondPass(*PersistentState.get(),
876878
*Invocation.getCodeCompletionFactory());
877879
}
878-
879-
// If the limiting AST stage is name binding, we're done.
880-
if (limitStage <= SourceFile::NameBound) {
881-
return;
882-
}
883-
884-
finishTypeChecking(TypeCheckOptions);
880+
finishTypeChecking();
885881
}
886882

887883
void CompilerInstance::parseLibraryFile(
@@ -937,8 +933,7 @@ bool CompilerInstance::parsePartialModulesAndLibraryFiles(
937933
}
938934

939935
void CompilerInstance::parseAndTypeCheckMainFileUpTo(
940-
SourceFile::ASTStage_t LimitStage,
941-
OptionSet<TypeCheckingFlags> TypeCheckOptions) {
936+
SourceFile::ASTStage_t LimitStage) {
942937
FrontendStatsTracer tracer(Context->Stats,
943938
"parse-and-typecheck-main-file");
944939
bool mainIsPrimary =
@@ -971,16 +966,10 @@ void CompilerInstance::parseAndTypeCheckMainFileUpTo(
971966
llvm_unreachable("invalid limit stage");
972967
case SourceFile::NameBound:
973968
performNameBinding(MainFile, CurTUElem);
974-
bindExtensions(MainFile);
975969
break;
976970
case SourceFile::TypeChecked:
977-
const auto &options = Invocation.getFrontendOptions();
978971
performTypeChecking(MainFile, PersistentState->getTopLevelContext(),
979-
TypeCheckOptions, CurTUElem,
980-
options.WarnLongFunctionBodies,
981-
options.WarnLongExpressionTypeChecking,
982-
options.SolverExpressionTimeThreshold,
983-
options.SwitchCheckingInvocationThreshold);
972+
CurTUElem);
984973
break;
985974
}
986975
}
@@ -1020,9 +1009,8 @@ void CompilerInstance::forEachFileToTypeCheck(
10201009
}
10211010
}
10221011

1023-
void CompilerInstance::finishTypeChecking(
1024-
OptionSet<TypeCheckingFlags> TypeCheckOptions) {
1025-
if (TypeCheckOptions & TypeCheckingFlags::DelayWholeModuleChecking) {
1012+
void CompilerInstance::finishTypeChecking() {
1013+
if (getASTContext().TypeCheckerOpts.DelayWholeModuleChecking) {
10261014
forEachSourceFileIn(MainModule, [&](SourceFile &SF) {
10271015
performWholeModuleTypeChecking(SF);
10281016
});

lib/IDE/REPLCodeCompletion.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,8 @@ doCodeCompletion(SourceFile &SF, StringRef EnteredCode, unsigned *BufferID,
212212
do {
213213
parseIntoSourceFile(SF, *BufferID, &Done, nullptr, &PersistentState);
214214
} while (!Done);
215-
performTypeChecking(SF, PersistentState.getTopLevelContext(), None,
215+
llvm::SaveAndRestore<TypeCheckerOptions> clearTyOpts(Ctx.TypeCheckerOpts, {});
216+
performTypeChecking(SF, PersistentState.getTopLevelContext(),
216217
OriginalDeclCount);
217218

218219
performCodeCompletionSecondPass(PersistentState, *CompletionCallbacksFactory);

lib/Immediate/REPL.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,8 @@ typeCheckREPLInput(ModuleDecl *MostRecentModule, StringRef Name,
193193
parseIntoSourceFile(REPLInputFile, BufferID, &Done, nullptr,
194194
&PersistentState);
195195
} while (!Done);
196-
performTypeChecking(REPLInputFile, PersistentState.getTopLevelContext(),
197-
/*Options*/None);
196+
llvm::SaveAndRestore<TypeCheckerOptions> clearTyOpts(Ctx.TypeCheckerOpts, {});
197+
performTypeChecking(REPLInputFile, PersistentState.getTopLevelContext());
198198
return REPLModule;
199199
}
200200

lib/Parse/Parser.cpp

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,26 +1087,24 @@ Parser::getStringLiteralIfNotInterpolated(SourceLoc Loc,
10871087
struct ParserUnit::Implementation {
10881088
std::shared_ptr<SyntaxParseActions> SPActions;
10891089
LangOptions LangOpts;
1090+
TypeCheckerOptions TypeCheckerOpts;
10901091
SearchPathOptions SearchPathOpts;
10911092
DiagnosticEngine Diags;
10921093
ASTContext &Ctx;
10931094
SourceFile *SF;
10941095
std::unique_ptr<Parser> TheParser;
10951096

10961097
Implementation(SourceManager &SM, SourceFileKind SFKind, unsigned BufferID,
1097-
const LangOptions &Opts, StringRef ModuleName,
1098+
const LangOptions &Opts, const TypeCheckerOptions &TyOpts,
1099+
StringRef ModuleName,
10981100
std::shared_ptr<SyntaxParseActions> spActions)
1099-
: SPActions(std::move(spActions)),
1100-
LangOpts(Opts),
1101-
Diags(SM),
1102-
Ctx(*ASTContext::get(LangOpts, SearchPathOpts, SM, Diags)),
1103-
SF(new (Ctx) SourceFile(
1104-
*ModuleDecl::create(Ctx.getIdentifier(ModuleName), Ctx),
1105-
SFKind, BufferID,
1106-
SourceFile::ImplicitModuleImportKind::None,
1107-
Opts.CollectParsedToken,
1108-
Opts.BuildSyntaxTree)) {
1109-
}
1101+
: SPActions(std::move(spActions)),
1102+
LangOpts(Opts), TypeCheckerOpts(TyOpts), Diags(SM),
1103+
Ctx(*ASTContext::get(LangOpts, TypeCheckerOpts, SearchPathOpts, SM, Diags)),
1104+
SF(new (Ctx) SourceFile(
1105+
*ModuleDecl::create(Ctx.getIdentifier(ModuleName), Ctx), SFKind,
1106+
BufferID, SourceFile::ImplicitModuleImportKind::None,
1107+
Opts.CollectParsedToken, Opts.BuildSyntaxTree)) {}
11101108

11111109
~Implementation() {
11121110
// We need to delete the parser before the context so that it can finalize
@@ -1117,15 +1115,18 @@ struct ParserUnit::Implementation {
11171115
};
11181116

11191117
ParserUnit::ParserUnit(SourceManager &SM, SourceFileKind SFKind, unsigned BufferID)
1120-
: ParserUnit(SM, SFKind, BufferID, LangOptions(), "input") {
1118+
: ParserUnit(SM, SFKind, BufferID,
1119+
LangOptions(), TypeCheckerOptions(), "input") {
11211120
}
11221121

11231122
ParserUnit::ParserUnit(SourceManager &SM, SourceFileKind SFKind, unsigned BufferID,
1124-
const LangOptions &LangOpts, StringRef ModuleName,
1123+
const LangOptions &LangOpts,
1124+
const TypeCheckerOptions &TypeCheckOpts,
1125+
StringRef ModuleName,
11251126
std::shared_ptr<SyntaxParseActions> spActions,
11261127
SyntaxParsingCache *SyntaxCache)
1127-
: Impl(*new Implementation(SM, SFKind, BufferID, LangOpts, ModuleName,
1128-
std::move(spActions))) {
1128+
: Impl(*new Implementation(SM, SFKind, BufferID, LangOpts, TypeCheckOpts,
1129+
ModuleName, std::move(spActions))) {
11291130

11301131
Impl.SF->SyntaxParsingCache = SyntaxCache;
11311132
Impl.TheParser.reset(new Parser(BufferID, *Impl.SF, /*SIL=*/nullptr,
@@ -1135,8 +1136,8 @@ ParserUnit::ParserUnit(SourceManager &SM, SourceFileKind SFKind, unsigned Buffer
11351136

11361137
ParserUnit::ParserUnit(SourceManager &SM, SourceFileKind SFKind, unsigned BufferID,
11371138
unsigned Offset, unsigned EndOffset)
1138-
: Impl(*new Implementation(SM, SFKind, BufferID, LangOptions(), "input",
1139-
nullptr)) {
1139+
: Impl(*new Implementation(SM, SFKind, BufferID, LangOptions(),
1140+
TypeCheckerOptions(), "input", nullptr)) {
11401141

11411142
std::unique_ptr<Lexer> Lex;
11421143
Lex.reset(new Lexer(Impl.LangOpts, SM,

lib/Sema/ConstraintSystem.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ using namespace constraints;
3535
#define DEBUG_TYPE "ConstraintSystem"
3636

3737
ExpressionTimer::ExpressionTimer(Expr *E, ConstraintSystem &CS)
38-
: E(E), WarnLimit(CS.getTypeChecker().getWarnLongExpressionTypeChecking()),
38+
: E(E),
3939
Context(CS.getASTContext()),
4040
StartTime(llvm::TimeRecord::getCurrentTime()),
41-
PrintDebugTiming(CS.getTypeChecker().getDebugTimeExpressions()),
41+
PrintDebugTiming(CS.getASTContext().TypeCheckerOpts.DebugTimeExpressions),
4242
PrintWarning(true) {
4343
if (auto *baseCS = CS.baseCS) {
4444
// If we already have a timer in the base constraint
@@ -66,6 +66,7 @@ ExpressionTimer::~ExpressionTimer() {
6666
if (!PrintWarning)
6767
return;
6868

69+
const auto WarnLimit = getWarnLimit();
6970
if (WarnLimit != 0 && elapsedMS >= WarnLimit && E->getLoc().isValid())
7071
Context.Diags.diagnose(E->getLoc(), diag::debug_long_expression,
7172
elapsedMS, WarnLimit)

lib/Sema/ConstraintSystem.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ struct RestrictionOrFix {
124124

125125
class ExpressionTimer {
126126
Expr* E;
127-
unsigned WarnLimit;
128127
ASTContext &Context;
129128
llvm::TimeRecord StartTime;
130129

@@ -136,6 +135,9 @@ class ExpressionTimer {
136135

137136
~ExpressionTimer();
138137

138+
unsigned getWarnLimit() const {
139+
return Context.TypeCheckerOpts.WarnLongExpressionTypeChecking;
140+
}
139141
llvm::TimeRecord startedAt() const { return StartTime; }
140142

141143
/// Return the elapsed process time (including fractional seconds)
@@ -3723,7 +3725,7 @@ class ConstraintSystem {
37233725
}
37243726

37253727
const auto timeoutThresholdInMillis =
3726-
getTypeChecker().getExpressionTimeoutThresholdInSeconds();
3728+
getASTContext().TypeCheckerOpts.ExpressionTimeoutThreshold;
37273729
if (Timer && Timer->isExpired(timeoutThresholdInMillis)) {
37283730
// Disable warnings about expressions that go over the warning
37293731
// threshold since we're arbitrarily ending evaluation and

lib/Sema/TypeCheckDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3184,7 +3184,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
31843184
auto &TC = *Ctx.getLegacyGlobalTypeChecker();
31853185

31863186
// Make sure we're in the mode that's skipping function bodies.
3187-
if (!TC.canSkipNonInlinableBodies())
3187+
if (!getASTContext().TypeCheckerOpts.SkipNonInlinableFunctionBodies)
31883188
return false;
31893189

31903190
// Make sure there even _is_ a body that we can skip.

0 commit comments

Comments
 (0)