Skip to content

Commit fb9bee7

Browse files
authored
Merge pull request #28173 from CodaFi/gradual-typing
[NFC] Centralize TypeChecker Flags With TypeCheckerOptions
2 parents 9cf908c + 8ff60ab commit fb9bee7

37 files changed

+235
-401
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/Basic/LangOptions.h

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ namespace swift {
5656

5757
/// A collection of options that affect the language dialect and
5858
/// provide compiler debugging facilities.
59-
class LangOptions {
59+
class LangOptions final {
6060
public:
6161

6262
/// The target we are building for.
@@ -456,6 +456,54 @@ namespace swift {
456456
PlatformConditionValues;
457457
llvm::SmallVector<std::string, 2> CustomConditionalCompilationFlags;
458458
};
459+
460+
class TypeCheckerOptions final {
461+
public:
462+
/// If non-zero, warn when a function body takes longer than this many
463+
/// milliseconds to type-check.
464+
///
465+
/// Intended for debugging purposes only.
466+
unsigned WarnLongFunctionBodies = 0;
467+
468+
/// If non-zero, warn when type-checking an expression takes longer
469+
/// than this many milliseconds.
470+
///
471+
/// Intended for debugging purposes only.
472+
unsigned WarnLongExpressionTypeChecking = 0;
473+
474+
/// If non-zero, abort the expression type checker if it takes more
475+
/// than this many seconds.
476+
unsigned ExpressionTimeoutThreshold = 600;
477+
478+
/// If non-zero, abort the switch statement exhaustiveness checker if
479+
/// the Space::minus function is called more than this many times.
480+
///
481+
/// Why this number? Times out in about a second on a 2017 iMac, Retina 5K,
482+
/// 4.2 GHz Intel Core i7.
483+
/// (It's arbitrary, but will keep the compiler from taking too much time.)
484+
unsigned SwitchCheckingInvocationThreshold = 200000;
485+
486+
/// Whether to delay checking that benefits from having the entire
487+
/// module parsed, e.g., Objective-C method override checking.
488+
bool DelayWholeModuleChecking = false;
489+
490+
/// If true, the time it takes to type-check each function will be dumped
491+
/// to llvm::errs().
492+
bool DebugTimeFunctionBodies = false;
493+
494+
/// If true, the time it takes to type-check each expression will be
495+
/// dumped to llvm::errs().
496+
bool DebugTimeExpressions = false;
497+
498+
/// Indicate that the type checker is checking code that will be
499+
/// immediately executed. This will suppress certain warnings
500+
/// when executing scripts.
501+
bool InImmediateMode = false;
502+
503+
/// Indicate that the type checker should skip type-checking non-inlinable
504+
/// function bodies.
505+
bool SkipNonInlinableFunctionBodies = false;
506+
};
459507
} // end namespace swift
460508

461509
#endif // SWIFT_BASIC_LANGOPTIONS_H

include/swift/Frontend/Frontend.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ struct ModuleBuffers {
8383
/// which manages the actual compiler execution.
8484
class CompilerInvocation {
8585
LangOptions LangOpts;
86+
TypeCheckerOptions TypeCheckerOpts;
8687
FrontendOptions FrontendOpts;
8788
ClangImporterOptions ClangImporterOpts;
8889
SearchPathOptions SearchPathOpts;
@@ -215,6 +216,11 @@ class CompilerInvocation {
215216
return LangOpts;
216217
}
217218

219+
TypeCheckerOptions &getTypeCheckerOptions() { return TypeCheckerOpts; }
220+
const TypeCheckerOptions &getTypeCheckerOptions() const {
221+
return TypeCheckerOpts;
222+
}
223+
218224
FrontendOptions &getFrontendOptions() { return FrontendOpts; }
219225
const FrontendOptions &getFrontendOptions() const { return FrontendOpts; }
220226

@@ -648,14 +654,11 @@ class CompilerInstance {
648654
bool
649655
parsePartialModulesAndLibraryFiles(const ImplicitImports &implicitImports);
650656

651-
OptionSet<TypeCheckingFlags> computeTypeCheckingOptions();
652-
653657
void forEachFileToTypeCheck(llvm::function_ref<void(SourceFile &)> fn);
654658

655-
void parseAndTypeCheckMainFileUpTo(SourceFile::ASTStage_t LimitStage,
656-
OptionSet<TypeCheckingFlags> TypeCheckOptions);
659+
void parseAndTypeCheckMainFileUpTo(SourceFile::ASTStage_t LimitStage);
657660

658-
void finishTypeChecking(OptionSet<TypeCheckingFlags> TypeCheckOptions);
661+
void finishTypeChecking();
659662

660663
public:
661664
const PrimarySpecificPaths &

include/swift/Frontend/FrontendOptions.h

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -82,28 +82,6 @@ class FrontendOptions {
8282
/// Emit index data for imported serialized swift system modules.
8383
bool IndexSystemModules = false;
8484

85-
/// If non-zero, warn when a function body takes longer than this many
86-
/// milliseconds to type-check.
87-
///
88-
/// Intended for debugging purposes only.
89-
unsigned WarnLongFunctionBodies = 0;
90-
91-
/// If non-zero, warn when type-checking an expression takes longer
92-
/// than this many milliseconds.
93-
///
94-
/// Intended for debugging purposes only.
95-
unsigned WarnLongExpressionTypeChecking = 0;
96-
97-
/// If non-zero, overrides the default threshold for how long we let
98-
/// the expression type checker run before we consider an expression
99-
/// too complex.
100-
unsigned SolverExpressionTimeThreshold = 0;
101-
102-
/// If non-zero, overrides the default threshold for how many times
103-
/// the Space::minus function is called before we consider switch statement
104-
/// exhaustiveness checking to be too complex.
105-
unsigned SwitchCheckingInvocationThreshold = 0;
106-
10785
/// The module for which we should verify all of the generic signatures.
10886
std::string VerifyGenericSignaturesInModule;
10987

@@ -183,8 +161,6 @@ class FrontendOptions {
183161
/// \sa swift::SharedTimer
184162
bool DebugTimeCompilation = false;
185163

186-
bool SkipNonInlinableFunctionBodies = false;
187-
188164
/// The path to which we should output statistics files.
189165
std::string StatsOutputDir;
190166

include/swift/Subsystems.h

Lines changed: 4 additions & 34 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;
@@ -168,30 +169,6 @@ namespace swift {
168169
/// to add calls to externally provided functions that simulate
169170
/// "program counter"-like debugging events.
170171
void performPCMacro(SourceFile &SF, TopLevelContext &TLC);
171-
172-
/// Flags used to control type checking.
173-
enum class TypeCheckingFlags : unsigned {
174-
/// Whether to delay checking that benefits from having the entire
175-
/// module parsed, e.g., Objective-C method override checking.
176-
DelayWholeModuleChecking = 1 << 0,
177-
178-
/// If set, dumps wall time taken to check each function body to
179-
/// llvm::errs().
180-
DebugTimeFunctionBodies = 1 << 1,
181-
182-
/// Indicates that the type checker is checking code that will be
183-
/// immediately executed.
184-
ForImmediateMode = 1 << 2,
185-
186-
/// If set, dumps wall time taken to type check each expression to
187-
/// llvm::errs().
188-
DebugTimeExpressions = 1 << 3,
189-
190-
/// If set, the typechecker will skip typechecking non-inlinable function
191-
/// bodies. Set this if you're trying to quickly emit a module or module
192-
/// interface without a full compilation.
193-
SkipNonInlinableFunctionBodies = 1 << 4,
194-
};
195172

196173
/// Creates a type checker instance on the given AST context, if it
197174
/// doesn't already have one.
@@ -207,16 +184,8 @@ namespace swift {
207184
///
208185
/// \param StartElem Where to start for incremental type-checking in the main
209186
/// source file.
210-
///
211-
/// \param WarnLongFunctionBodies If non-zero, warn when a function body takes
212-
/// longer than this many milliseconds to type-check
213187
void performTypeChecking(SourceFile &SF, TopLevelContext &TLC,
214-
OptionSet<TypeCheckingFlags> Options,
215-
unsigned StartElem = 0,
216-
unsigned WarnLongFunctionBodies = 0,
217-
unsigned WarnLongExpressionTypeChecking = 0,
218-
unsigned ExpressionTimeoutThreshold = 0,
219-
unsigned SwitchCheckingInvocationThreshold = 0);
188+
unsigned StartElem = 0);
220189

221190
/// Now that we have type-checked an entire module, perform any type
222191
/// checking that requires the full module, e.g., Objective-C method
@@ -372,7 +341,8 @@ namespace swift {
372341
class ParserUnit {
373342
public:
374343
ParserUnit(SourceManager &SM, SourceFileKind SFKind, unsigned BufferID,
375-
const LangOptions &LangOpts, StringRef ModuleName,
344+
const LangOptions &LangOpts, const TypeCheckerOptions &TyOpts,
345+
StringRef ModuleName,
376346
std::shared_ptr<SyntaxParseActions> spActions = nullptr,
377347
SyntaxParsingCache *SyntaxCache = nullptr);
378348
ParserUnit(SourceManager &SM, SourceFileKind SFKind, unsigned BufferID);

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/ArgsToFrontendOptionsConverter.cpp

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,6 @@ bool ArgsToFrontendOptionsConverter::convert(
9090
computeDebugTimeOptions();
9191
computeTBDOptions();
9292

93-
setUnsignedIntegerArgument(OPT_warn_long_function_bodies, 10,
94-
Opts.WarnLongFunctionBodies);
95-
setUnsignedIntegerArgument(OPT_warn_long_expression_type_checking, 10,
96-
Opts.WarnLongExpressionTypeChecking);
97-
setUnsignedIntegerArgument(OPT_solver_expression_time_threshold_EQ, 10,
98-
Opts.SolverExpressionTimeThreshold);
99-
setUnsignedIntegerArgument(OPT_switch_checking_invocation_threshold_EQ, 10,
100-
Opts.SwitchCheckingInvocationThreshold);
101-
10293
Opts.CheckOnoneSupportCompleteness = Args.hasArg(OPT_check_onone_completeness);
10394

10495
Opts.DebuggerTestingTransform = Args.hasArg(OPT_debugger_testing_transform);
@@ -163,7 +154,7 @@ bool ArgsToFrontendOptionsConverter::convert(
163154
return true;
164155

165156
if (FrontendOptions::doesActionGenerateIR(Opts.RequestedAction)
166-
&& Opts.SkipNonInlinableFunctionBodies) {
157+
&& Args.hasArg(OPT_experimental_skip_non_inlinable_function_bodies)) {
167158
Diags.diagnose(SourceLoc(), diag::cannot_emit_ir_skipping_function_bodies);
168159
return true;
169160
}
@@ -222,17 +213,7 @@ void ArgsToFrontendOptionsConverter::computePrintStatsOptions() {
222213

223214
void ArgsToFrontendOptionsConverter::computeDebugTimeOptions() {
224215
using namespace options;
225-
Opts.DebugTimeFunctionBodies |= Args.hasArg(OPT_debug_time_function_bodies);
226-
Opts.DebugTimeExpressionTypeChecking |=
227-
Args.hasArg(OPT_debug_time_expression_type_checking);
228216
Opts.DebugTimeCompilation |= Args.hasArg(OPT_debug_time_compilation);
229-
Opts.SkipNonInlinableFunctionBodies |=
230-
Args.hasArg(OPT_experimental_skip_non_inlinable_function_bodies);
231-
232-
// If asked to perform InstallAPI, go ahead and enable non-inlinable function
233-
// body skipping.
234-
Opts.SkipNonInlinableFunctionBodies |=
235-
Args.hasArg(OPT_tbd_is_installapi);
236217

237218
if (const Arg *A = Args.getLastArg(OPT_stats_output_dir)) {
238219
Opts.StatsOutputDir = A->getValue();
@@ -266,19 +247,6 @@ void ArgsToFrontendOptionsConverter::computeTBDOptions() {
266247
}
267248
}
268249

269-
void ArgsToFrontendOptionsConverter::setUnsignedIntegerArgument(
270-
options::ID optionID, unsigned radix, unsigned &valueToSet) {
271-
if (const Arg *A = Args.getLastArg(optionID)) {
272-
unsigned attempt;
273-
if (StringRef(A->getValue()).getAsInteger(radix, attempt)) {
274-
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
275-
A->getAsString(Args), A->getValue());
276-
} else {
277-
valueToSet = attempt;
278-
}
279-
}
280-
}
281-
282250
void ArgsToFrontendOptionsConverter::computePlaygroundOptions() {
283251
using namespace options;
284252
Opts.PlaygroundTransform |= Args.hasArg(OPT_playground);

lib/Frontend/ArgsToFrontendOptionsConverter.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,6 @@ class ArgsToFrontendOptionsConverter {
4747
void computePrintStatsOptions();
4848
void computeTBDOptions();
4949

50-
void setUnsignedIntegerArgument(options::ID optionID, unsigned radix,
51-
unsigned &valueToSet);
52-
5350
bool setUpInputKindAndImmediateArgs();
5451

5552
bool checkUnusedSupplementaryOutputPaths() const;

0 commit comments

Comments
 (0)