mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Give ASTContext TypeCheckerOptions
Strip TypeChecker of all of this state.
This commit is contained in:
@@ -201,8 +201,9 @@ class ASTContext final {
|
|||||||
ASTContext(const ASTContext&) = delete;
|
ASTContext(const ASTContext&) = delete;
|
||||||
void operator=(const ASTContext&) = delete;
|
void operator=(const ASTContext&) = delete;
|
||||||
|
|
||||||
ASTContext(LangOptions &langOpts, SearchPathOptions &SearchPathOpts,
|
ASTContext(LangOptions &langOpts, TypeCheckerOptions &typeckOpts,
|
||||||
SourceManager &SourceMgr, DiagnosticEngine &Diags);
|
SearchPathOptions &SearchPathOpts, SourceManager &SourceMgr,
|
||||||
|
DiagnosticEngine &Diags);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Members that should only be used by ASTContext.cpp.
|
// Members that should only be used by ASTContext.cpp.
|
||||||
@@ -213,10 +214,9 @@ public:
|
|||||||
|
|
||||||
void operator delete(void *Data) throw();
|
void operator delete(void *Data) throw();
|
||||||
|
|
||||||
static ASTContext *get(LangOptions &langOpts,
|
static ASTContext *get(LangOptions &langOpts, TypeCheckerOptions &typeckOpts,
|
||||||
SearchPathOptions &SearchPathOpts,
|
SearchPathOptions &SearchPathOpts,
|
||||||
SourceManager &SourceMgr,
|
SourceManager &SourceMgr, DiagnosticEngine &Diags);
|
||||||
DiagnosticEngine &Diags);
|
|
||||||
~ASTContext();
|
~ASTContext();
|
||||||
|
|
||||||
/// Optional table of counters to report, nullptr when not collecting.
|
/// Optional table of counters to report, nullptr when not collecting.
|
||||||
@@ -228,6 +228,9 @@ public:
|
|||||||
/// The language options used for translation.
|
/// The language options used for translation.
|
||||||
LangOptions &LangOpts;
|
LangOptions &LangOpts;
|
||||||
|
|
||||||
|
/// The type checker options.
|
||||||
|
TypeCheckerOptions &TypeCheckerOpts;
|
||||||
|
|
||||||
/// The search path options used by this AST context.
|
/// The search path options used by this AST context.
|
||||||
SearchPathOptions &SearchPathOpts;
|
SearchPathOptions &SearchPathOpts;
|
||||||
|
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ namespace swift {
|
|||||||
class Token;
|
class Token;
|
||||||
class TopLevelContext;
|
class TopLevelContext;
|
||||||
class TypeChecker;
|
class TypeChecker;
|
||||||
|
class TypeCheckerOptions;
|
||||||
struct TypeLoc;
|
struct TypeLoc;
|
||||||
class UnifiedStatsReporter;
|
class UnifiedStatsReporter;
|
||||||
enum class SourceFileKind;
|
enum class SourceFileKind;
|
||||||
@@ -183,16 +184,8 @@ namespace swift {
|
|||||||
///
|
///
|
||||||
/// \param StartElem Where to start for incremental type-checking in the main
|
/// \param StartElem Where to start for incremental type-checking in the main
|
||||||
/// source file.
|
/// source file.
|
||||||
///
|
|
||||||
/// \param WarnLongFunctionBodies If non-zero, warn when a function body takes
|
|
||||||
/// longer than this many milliseconds to type-check
|
|
||||||
void performTypeChecking(SourceFile &SF, TopLevelContext &TLC,
|
void performTypeChecking(SourceFile &SF, TopLevelContext &TLC,
|
||||||
OptionSet<TypeCheckingFlags> Options,
|
unsigned StartElem = 0);
|
||||||
unsigned StartElem = 0,
|
|
||||||
unsigned WarnLongFunctionBodies = 0,
|
|
||||||
unsigned WarnLongExpressionTypeChecking = 0,
|
|
||||||
unsigned ExpressionTimeoutThreshold = 0,
|
|
||||||
unsigned SwitchCheckingInvocationThreshold = 0);
|
|
||||||
|
|
||||||
/// Now that we have type-checked an entire module, perform any type
|
/// Now that we have type-checked an entire module, perform any type
|
||||||
/// checking that requires the full module, e.g., Objective-C method
|
/// checking that requires the full module, e.g., Objective-C method
|
||||||
|
|||||||
@@ -504,6 +504,7 @@ void ASTContext::operator delete(void *Data) throw() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ASTContext *ASTContext::get(LangOptions &langOpts,
|
ASTContext *ASTContext::get(LangOptions &langOpts,
|
||||||
|
TypeCheckerOptions &typeckOpts,
|
||||||
SearchPathOptions &SearchPathOpts,
|
SearchPathOptions &SearchPathOpts,
|
||||||
SourceManager &SourceMgr,
|
SourceManager &SourceMgr,
|
||||||
DiagnosticEngine &Diags) {
|
DiagnosticEngine &Diags) {
|
||||||
@@ -516,15 +517,16 @@ ASTContext *ASTContext::get(LangOptions &langOpts,
|
|||||||
auto impl = reinterpret_cast<void*>((char*)mem + sizeof(ASTContext));
|
auto impl = reinterpret_cast<void*>((char*)mem + sizeof(ASTContext));
|
||||||
impl = reinterpret_cast<void*>(llvm::alignAddr(impl,alignof(Implementation)));
|
impl = reinterpret_cast<void*>(llvm::alignAddr(impl,alignof(Implementation)));
|
||||||
new (impl) Implementation();
|
new (impl) Implementation();
|
||||||
return new (mem) ASTContext(langOpts, SearchPathOpts, SourceMgr, Diags);
|
return new (mem)
|
||||||
|
ASTContext(langOpts, typeckOpts, SearchPathOpts, SourceMgr, Diags);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTContext::ASTContext(LangOptions &langOpts, SearchPathOptions &SearchPathOpts,
|
ASTContext::ASTContext(LangOptions &langOpts, TypeCheckerOptions &typeckOpts,
|
||||||
|
SearchPathOptions &SearchPathOpts,
|
||||||
SourceManager &SourceMgr, DiagnosticEngine &Diags)
|
SourceManager &SourceMgr, DiagnosticEngine &Diags)
|
||||||
: LangOpts(langOpts),
|
: LangOpts(langOpts),
|
||||||
SearchPathOpts(SearchPathOpts),
|
TypeCheckerOpts(typeckOpts),
|
||||||
SourceMgr(SourceMgr),
|
SearchPathOpts(SearchPathOpts), SourceMgr(SourceMgr), Diags(Diags),
|
||||||
Diags(Diags),
|
|
||||||
evaluator(Diags, langOpts.DebugDumpCycles),
|
evaluator(Diags, langOpts.DebugDumpCycles),
|
||||||
TheBuiltinModule(createBuiltinModule(*this)),
|
TheBuiltinModule(createBuiltinModule(*this)),
|
||||||
StdlibModuleName(getIdentifier(STDLIB_NAME)),
|
StdlibModuleName(getIdentifier(STDLIB_NAME)),
|
||||||
|
|||||||
@@ -190,9 +190,9 @@ bool CompilerInstance::setUpASTContextIfNeeded() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Context.reset(ASTContext::get(Invocation.getLangOptions(),
|
Context.reset(ASTContext::get(
|
||||||
Invocation.getSearchPathOptions(), SourceMgr,
|
Invocation.getLangOptions(), Invocation.getTypeCheckerOptions(),
|
||||||
Diagnostics));
|
Invocation.getSearchPathOptions(), SourceMgr, Diagnostics));
|
||||||
registerParseRequestFunctions(Context->evaluator);
|
registerParseRequestFunctions(Context->evaluator);
|
||||||
registerTypeCheckerRequestFunctions(Context->evaluator);
|
registerTypeCheckerRequestFunctions(Context->evaluator);
|
||||||
|
|
||||||
@@ -222,17 +222,28 @@ bool CompilerInstance::setup(const CompilerInvocation &Invok) {
|
|||||||
setUpLLVMArguments();
|
setUpLLVMArguments();
|
||||||
setUpDiagnosticOptions();
|
setUpDiagnosticOptions();
|
||||||
|
|
||||||
|
const auto &frontendOpts = Invocation.getFrontendOptions();
|
||||||
|
|
||||||
// If we are asked to emit a module documentation file, configure lexing and
|
// If we are asked to emit a module documentation file, configure lexing and
|
||||||
// parsing to remember comments.
|
// parsing to remember comments.
|
||||||
if (Invocation.getFrontendOptions().InputsAndOutputs.hasModuleDocOutputPath())
|
if (frontendOpts.InputsAndOutputs.hasModuleDocOutputPath())
|
||||||
Invocation.getLangOptions().AttachCommentsToDecls = true;
|
Invocation.getLangOptions().AttachCommentsToDecls = true;
|
||||||
|
|
||||||
// If we are doing index-while-building, configure lexing and parsing to
|
// If we are doing index-while-building, configure lexing and parsing to
|
||||||
// remember comments.
|
// remember comments.
|
||||||
if (!Invocation.getFrontendOptions().IndexStorePath.empty()) {
|
if (!frontendOpts.IndexStorePath.empty()) {
|
||||||
Invocation.getLangOptions().AttachCommentsToDecls = true;
|
Invocation.getLangOptions().AttachCommentsToDecls = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set up the type checker options.
|
||||||
|
auto &typeCkOpts = Invocation.getTypeCheckerOptions();
|
||||||
|
if (isWholeModuleCompilation()) {
|
||||||
|
typeCkOpts.DelayWholeModuleChecking = true;
|
||||||
|
}
|
||||||
|
if (FrontendOptions::isActionImmediate(frontendOpts.RequestedAction)) {
|
||||||
|
typeCkOpts.InImmediateMode = true;
|
||||||
|
}
|
||||||
|
|
||||||
assert(Lexer::isIdentifier(Invocation.getModuleName()));
|
assert(Lexer::isIdentifier(Invocation.getModuleName()));
|
||||||
|
|
||||||
if (isInSILMode())
|
if (isInSILMode())
|
||||||
@@ -825,14 +836,12 @@ void CompilerInstance::parseAndCheckTypesUpTo(
|
|||||||
if (hadLoadError)
|
if (hadLoadError)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
OptionSet<TypeCheckingFlags> TypeCheckOptions = computeTypeCheckingOptions();
|
|
||||||
|
|
||||||
// Type-check main file after parsing all other files so that
|
// Type-check main file after parsing all other files so that
|
||||||
// it can use declarations from other files.
|
// it can use declarations from other files.
|
||||||
// In addition, the main file has parsing and type-checking
|
// In addition, the main file has parsing and type-checking
|
||||||
// interwined.
|
// interwined.
|
||||||
if (MainBufferID != NO_SUCH_BUFFER) {
|
if (MainBufferID != NO_SUCH_BUFFER) {
|
||||||
parseAndTypeCheckMainFileUpTo(limitStage, TypeCheckOptions);
|
parseAndTypeCheckMainFileUpTo(limitStage);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(llvm::all_of(MainModule->getFiles(), [](const FileUnit *File) -> bool {
|
assert(llvm::all_of(MainModule->getFiles(), [](const FileUnit *File) -> bool {
|
||||||
@@ -843,19 +852,13 @@ void CompilerInstance::parseAndCheckTypesUpTo(
|
|||||||
}) && "some files have not yet had their imports resolved");
|
}) && "some files have not yet had their imports resolved");
|
||||||
MainModule->setHasResolvedImports();
|
MainModule->setHasResolvedImports();
|
||||||
|
|
||||||
const auto &options = Invocation.getFrontendOptions();
|
// If the limiting AST stage is name binding, we're done.
|
||||||
forEachFileToTypeCheck([&](SourceFile &SF) {
|
if (limitStage <= SourceFile::NameBound) {
|
||||||
if (limitStage == SourceFile::NameBound) {
|
|
||||||
bindExtensions(SF);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
performTypeChecking(SF, PersistentState->getTopLevelContext(),
|
forEachFileToTypeCheck([&](SourceFile &SF) {
|
||||||
TypeCheckOptions, /*curElem*/ 0,
|
performTypeChecking(SF, PersistentState->getTopLevelContext());
|
||||||
options.WarnLongFunctionBodies,
|
|
||||||
options.WarnLongExpressionTypeChecking,
|
|
||||||
options.SolverExpressionTimeThreshold,
|
|
||||||
options.SwitchCheckingInvocationThreshold);
|
|
||||||
|
|
||||||
if (!Context->hadError() && Invocation.getFrontendOptions().PCMacro) {
|
if (!Context->hadError() && Invocation.getFrontendOptions().PCMacro) {
|
||||||
performPCMacro(SF, PersistentState->getTopLevelContext());
|
performPCMacro(SF, PersistentState->getTopLevelContext());
|
||||||
@@ -871,17 +874,10 @@ void CompilerInstance::parseAndCheckTypesUpTo(
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (Invocation.isCodeCompletion()) {
|
if (Invocation.isCodeCompletion()) {
|
||||||
assert(limitStage == SourceFile::NameBound);
|
|
||||||
performCodeCompletionSecondPass(*PersistentState.get(),
|
performCodeCompletionSecondPass(*PersistentState.get(),
|
||||||
*Invocation.getCodeCompletionFactory());
|
*Invocation.getCodeCompletionFactory());
|
||||||
}
|
}
|
||||||
|
finishTypeChecking();
|
||||||
// If the limiting AST stage is name binding, we're done.
|
|
||||||
if (limitStage <= SourceFile::NameBound) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
finishTypeChecking(TypeCheckOptions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerInstance::parseLibraryFile(
|
void CompilerInstance::parseLibraryFile(
|
||||||
@@ -937,8 +933,7 @@ bool CompilerInstance::parsePartialModulesAndLibraryFiles(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CompilerInstance::parseAndTypeCheckMainFileUpTo(
|
void CompilerInstance::parseAndTypeCheckMainFileUpTo(
|
||||||
SourceFile::ASTStage_t LimitStage,
|
SourceFile::ASTStage_t LimitStage) {
|
||||||
OptionSet<TypeCheckingFlags> TypeCheckOptions) {
|
|
||||||
FrontendStatsTracer tracer(Context->Stats,
|
FrontendStatsTracer tracer(Context->Stats,
|
||||||
"parse-and-typecheck-main-file");
|
"parse-and-typecheck-main-file");
|
||||||
bool mainIsPrimary =
|
bool mainIsPrimary =
|
||||||
@@ -971,16 +966,10 @@ void CompilerInstance::parseAndTypeCheckMainFileUpTo(
|
|||||||
llvm_unreachable("invalid limit stage");
|
llvm_unreachable("invalid limit stage");
|
||||||
case SourceFile::NameBound:
|
case SourceFile::NameBound:
|
||||||
performNameBinding(MainFile, CurTUElem);
|
performNameBinding(MainFile, CurTUElem);
|
||||||
bindExtensions(MainFile);
|
|
||||||
break;
|
break;
|
||||||
case SourceFile::TypeChecked:
|
case SourceFile::TypeChecked:
|
||||||
const auto &options = Invocation.getFrontendOptions();
|
|
||||||
performTypeChecking(MainFile, PersistentState->getTopLevelContext(),
|
performTypeChecking(MainFile, PersistentState->getTopLevelContext(),
|
||||||
TypeCheckOptions, CurTUElem,
|
CurTUElem);
|
||||||
options.WarnLongFunctionBodies,
|
|
||||||
options.WarnLongExpressionTypeChecking,
|
|
||||||
options.SolverExpressionTimeThreshold,
|
|
||||||
options.SwitchCheckingInvocationThreshold);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1020,9 +1009,8 @@ void CompilerInstance::forEachFileToTypeCheck(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerInstance::finishTypeChecking(
|
void CompilerInstance::finishTypeChecking() {
|
||||||
OptionSet<TypeCheckingFlags> TypeCheckOptions) {
|
if (getASTContext().TypeCheckerOpts.DelayWholeModuleChecking) {
|
||||||
if (TypeCheckOptions & TypeCheckingFlags::DelayWholeModuleChecking) {
|
|
||||||
forEachSourceFileIn(MainModule, [&](SourceFile &SF) {
|
forEachSourceFileIn(MainModule, [&](SourceFile &SF) {
|
||||||
performWholeModuleTypeChecking(SF);
|
performWholeModuleTypeChecking(SF);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -212,7 +212,8 @@ doCodeCompletion(SourceFile &SF, StringRef EnteredCode, unsigned *BufferID,
|
|||||||
do {
|
do {
|
||||||
parseIntoSourceFile(SF, *BufferID, &Done, nullptr, &PersistentState);
|
parseIntoSourceFile(SF, *BufferID, &Done, nullptr, &PersistentState);
|
||||||
} while (!Done);
|
} while (!Done);
|
||||||
performTypeChecking(SF, PersistentState.getTopLevelContext(), None,
|
llvm::SaveAndRestore<TypeCheckerOptions> clearTyOpts(Ctx.TypeCheckerOpts, {});
|
||||||
|
performTypeChecking(SF, PersistentState.getTopLevelContext(),
|
||||||
OriginalDeclCount);
|
OriginalDeclCount);
|
||||||
|
|
||||||
performCodeCompletionSecondPass(PersistentState, *CompletionCallbacksFactory);
|
performCodeCompletionSecondPass(PersistentState, *CompletionCallbacksFactory);
|
||||||
|
|||||||
@@ -193,8 +193,8 @@ typeCheckREPLInput(ModuleDecl *MostRecentModule, StringRef Name,
|
|||||||
parseIntoSourceFile(REPLInputFile, BufferID, &Done, nullptr,
|
parseIntoSourceFile(REPLInputFile, BufferID, &Done, nullptr,
|
||||||
&PersistentState);
|
&PersistentState);
|
||||||
} while (!Done);
|
} while (!Done);
|
||||||
performTypeChecking(REPLInputFile, PersistentState.getTopLevelContext(),
|
llvm::SaveAndRestore<TypeCheckerOptions> clearTyOpts(Ctx.TypeCheckerOpts, {});
|
||||||
/*Options*/None);
|
performTypeChecking(REPLInputFile, PersistentState.getTopLevelContext());
|
||||||
return REPLModule;
|
return REPLModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1087,6 +1087,7 @@ Parser::getStringLiteralIfNotInterpolated(SourceLoc Loc,
|
|||||||
struct ParserUnit::Implementation {
|
struct ParserUnit::Implementation {
|
||||||
std::shared_ptr<SyntaxParseActions> SPActions;
|
std::shared_ptr<SyntaxParseActions> SPActions;
|
||||||
LangOptions LangOpts;
|
LangOptions LangOpts;
|
||||||
|
TypeCheckerOptions TypeCheckerOpts;
|
||||||
SearchPathOptions SearchPathOpts;
|
SearchPathOptions SearchPathOpts;
|
||||||
DiagnosticEngine Diags;
|
DiagnosticEngine Diags;
|
||||||
ASTContext &Ctx;
|
ASTContext &Ctx;
|
||||||
@@ -1094,19 +1095,16 @@ struct ParserUnit::Implementation {
|
|||||||
std::unique_ptr<Parser> TheParser;
|
std::unique_ptr<Parser> TheParser;
|
||||||
|
|
||||||
Implementation(SourceManager &SM, SourceFileKind SFKind, unsigned BufferID,
|
Implementation(SourceManager &SM, SourceFileKind SFKind, unsigned BufferID,
|
||||||
const LangOptions &Opts, StringRef ModuleName,
|
const LangOptions &Opts, const TypeCheckerOptions &TyOpts,
|
||||||
|
StringRef ModuleName,
|
||||||
std::shared_ptr<SyntaxParseActions> spActions)
|
std::shared_ptr<SyntaxParseActions> spActions)
|
||||||
: SPActions(std::move(spActions)),
|
: SPActions(std::move(spActions)),
|
||||||
LangOpts(Opts),
|
LangOpts(Opts), TypeCheckerOpts(TyOpts), Diags(SM),
|
||||||
Diags(SM),
|
Ctx(*ASTContext::get(LangOpts, TypeCheckerOpts, SearchPathOpts, SM, Diags)),
|
||||||
Ctx(*ASTContext::get(LangOpts, SearchPathOpts, SM, Diags)),
|
|
||||||
SF(new (Ctx) SourceFile(
|
SF(new (Ctx) SourceFile(
|
||||||
*ModuleDecl::create(Ctx.getIdentifier(ModuleName), Ctx),
|
*ModuleDecl::create(Ctx.getIdentifier(ModuleName), Ctx), SFKind,
|
||||||
SFKind, BufferID,
|
BufferID, SourceFile::ImplicitModuleImportKind::None,
|
||||||
SourceFile::ImplicitModuleImportKind::None,
|
Opts.CollectParsedToken, Opts.BuildSyntaxTree)) {}
|
||||||
Opts.CollectParsedToken,
|
|
||||||
Opts.BuildSyntaxTree)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
~Implementation() {
|
~Implementation() {
|
||||||
// We need to delete the parser before the context so that it can finalize
|
// We need to delete the parser before the context so that it can finalize
|
||||||
@@ -1117,15 +1115,18 @@ struct ParserUnit::Implementation {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ParserUnit::ParserUnit(SourceManager &SM, SourceFileKind SFKind, unsigned BufferID)
|
ParserUnit::ParserUnit(SourceManager &SM, SourceFileKind SFKind, unsigned BufferID)
|
||||||
: ParserUnit(SM, SFKind, BufferID, LangOptions(), "input") {
|
: ParserUnit(SM, SFKind, BufferID,
|
||||||
|
LangOptions(), TypeCheckerOptions(), "input") {
|
||||||
}
|
}
|
||||||
|
|
||||||
ParserUnit::ParserUnit(SourceManager &SM, SourceFileKind SFKind, unsigned BufferID,
|
ParserUnit::ParserUnit(SourceManager &SM, SourceFileKind SFKind, unsigned BufferID,
|
||||||
const LangOptions &LangOpts, StringRef ModuleName,
|
const LangOptions &LangOpts,
|
||||||
|
const TypeCheckerOptions &TypeCheckOpts,
|
||||||
|
StringRef ModuleName,
|
||||||
std::shared_ptr<SyntaxParseActions> spActions,
|
std::shared_ptr<SyntaxParseActions> spActions,
|
||||||
SyntaxParsingCache *SyntaxCache)
|
SyntaxParsingCache *SyntaxCache)
|
||||||
: Impl(*new Implementation(SM, SFKind, BufferID, LangOpts, ModuleName,
|
: Impl(*new Implementation(SM, SFKind, BufferID, LangOpts, TypeCheckOpts,
|
||||||
std::move(spActions))) {
|
ModuleName, std::move(spActions))) {
|
||||||
|
|
||||||
Impl.SF->SyntaxParsingCache = SyntaxCache;
|
Impl.SF->SyntaxParsingCache = SyntaxCache;
|
||||||
Impl.TheParser.reset(new Parser(BufferID, *Impl.SF, /*SIL=*/nullptr,
|
Impl.TheParser.reset(new Parser(BufferID, *Impl.SF, /*SIL=*/nullptr,
|
||||||
@@ -1135,8 +1136,8 @@ ParserUnit::ParserUnit(SourceManager &SM, SourceFileKind SFKind, unsigned Buffer
|
|||||||
|
|
||||||
ParserUnit::ParserUnit(SourceManager &SM, SourceFileKind SFKind, unsigned BufferID,
|
ParserUnit::ParserUnit(SourceManager &SM, SourceFileKind SFKind, unsigned BufferID,
|
||||||
unsigned Offset, unsigned EndOffset)
|
unsigned Offset, unsigned EndOffset)
|
||||||
: Impl(*new Implementation(SM, SFKind, BufferID, LangOptions(), "input",
|
: Impl(*new Implementation(SM, SFKind, BufferID, LangOptions(),
|
||||||
nullptr)) {
|
TypeCheckerOptions(), "input", nullptr)) {
|
||||||
|
|
||||||
std::unique_ptr<Lexer> Lex;
|
std::unique_ptr<Lexer> Lex;
|
||||||
Lex.reset(new Lexer(Impl.LangOpts, SM,
|
Lex.reset(new Lexer(Impl.LangOpts, SM,
|
||||||
|
|||||||
@@ -35,10 +35,10 @@ using namespace constraints;
|
|||||||
#define DEBUG_TYPE "ConstraintSystem"
|
#define DEBUG_TYPE "ConstraintSystem"
|
||||||
|
|
||||||
ExpressionTimer::ExpressionTimer(Expr *E, ConstraintSystem &CS)
|
ExpressionTimer::ExpressionTimer(Expr *E, ConstraintSystem &CS)
|
||||||
: E(E), WarnLimit(CS.getTypeChecker().getWarnLongExpressionTypeChecking()),
|
: E(E),
|
||||||
Context(CS.getASTContext()),
|
Context(CS.getASTContext()),
|
||||||
StartTime(llvm::TimeRecord::getCurrentTime()),
|
StartTime(llvm::TimeRecord::getCurrentTime()),
|
||||||
PrintDebugTiming(CS.getTypeChecker().getDebugTimeExpressions()),
|
PrintDebugTiming(CS.getASTContext().TypeCheckerOpts.DebugTimeExpressions),
|
||||||
PrintWarning(true) {
|
PrintWarning(true) {
|
||||||
if (auto *baseCS = CS.baseCS) {
|
if (auto *baseCS = CS.baseCS) {
|
||||||
// If we already have a timer in the base constraint
|
// If we already have a timer in the base constraint
|
||||||
@@ -66,6 +66,7 @@ ExpressionTimer::~ExpressionTimer() {
|
|||||||
if (!PrintWarning)
|
if (!PrintWarning)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
const auto WarnLimit = getWarnLimit();
|
||||||
if (WarnLimit != 0 && elapsedMS >= WarnLimit && E->getLoc().isValid())
|
if (WarnLimit != 0 && elapsedMS >= WarnLimit && E->getLoc().isValid())
|
||||||
Context.Diags.diagnose(E->getLoc(), diag::debug_long_expression,
|
Context.Diags.diagnose(E->getLoc(), diag::debug_long_expression,
|
||||||
elapsedMS, WarnLimit)
|
elapsedMS, WarnLimit)
|
||||||
|
|||||||
@@ -124,7 +124,6 @@ public:
|
|||||||
|
|
||||||
class ExpressionTimer {
|
class ExpressionTimer {
|
||||||
Expr* E;
|
Expr* E;
|
||||||
unsigned WarnLimit;
|
|
||||||
ASTContext &Context;
|
ASTContext &Context;
|
||||||
llvm::TimeRecord StartTime;
|
llvm::TimeRecord StartTime;
|
||||||
|
|
||||||
@@ -136,6 +135,9 @@ public:
|
|||||||
|
|
||||||
~ExpressionTimer();
|
~ExpressionTimer();
|
||||||
|
|
||||||
|
unsigned getWarnLimit() const {
|
||||||
|
return Context.TypeCheckerOpts.WarnLongExpressionTypeChecking;
|
||||||
|
}
|
||||||
llvm::TimeRecord startedAt() const { return StartTime; }
|
llvm::TimeRecord startedAt() const { return StartTime; }
|
||||||
|
|
||||||
/// Return the elapsed process time (including fractional seconds)
|
/// Return the elapsed process time (including fractional seconds)
|
||||||
@@ -3723,7 +3725,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto timeoutThresholdInMillis =
|
const auto timeoutThresholdInMillis =
|
||||||
getTypeChecker().getExpressionTimeoutThresholdInSeconds();
|
getASTContext().TypeCheckerOpts.ExpressionTimeoutThreshold;
|
||||||
if (Timer && Timer->isExpired(timeoutThresholdInMillis)) {
|
if (Timer && Timer->isExpired(timeoutThresholdInMillis)) {
|
||||||
// Disable warnings about expressions that go over the warning
|
// Disable warnings about expressions that go over the warning
|
||||||
// threshold since we're arbitrarily ending evaluation and
|
// threshold since we're arbitrarily ending evaluation and
|
||||||
|
|||||||
@@ -3184,7 +3184,7 @@ public:
|
|||||||
auto &TC = *Ctx.getLegacyGlobalTypeChecker();
|
auto &TC = *Ctx.getLegacyGlobalTypeChecker();
|
||||||
|
|
||||||
// Make sure we're in the mode that's skipping function bodies.
|
// Make sure we're in the mode that's skipping function bodies.
|
||||||
if (!TC.canSkipNonInlinableBodies())
|
if (!getASTContext().TypeCheckerOpts.SkipNonInlinableFunctionBodies)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Make sure there even _is_ a body that we can skip.
|
// Make sure there even _is_ a body that we can skip.
|
||||||
|
|||||||
@@ -327,12 +327,7 @@ void swift::typeCheckExternalDefinitions(SourceFile &SF) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void swift::performTypeChecking(SourceFile &SF, TopLevelContext &TLC,
|
void swift::performTypeChecking(SourceFile &SF, TopLevelContext &TLC,
|
||||||
OptionSet<TypeCheckingFlags> Options,
|
unsigned StartElem) {
|
||||||
unsigned StartElem,
|
|
||||||
unsigned WarnLongFunctionBodies,
|
|
||||||
unsigned WarnLongExpressionTypeChecking,
|
|
||||||
unsigned ExpressionTimeoutThreshold,
|
|
||||||
unsigned SwitchCheckingInvocationThreshold) {
|
|
||||||
if (SF.ASTStage == SourceFile::TypeChecked)
|
if (SF.ASTStage == SourceFile::TypeChecked)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -340,12 +335,11 @@ void swift::performTypeChecking(SourceFile &SF, TopLevelContext &TLC,
|
|||||||
// because type-checking expressions mutates the AST and that throws off the
|
// because type-checking expressions mutates the AST and that throws off the
|
||||||
// scope-based lookups. Only the top-level scopes because extensions have not
|
// scope-based lookups. Only the top-level scopes because extensions have not
|
||||||
// been bound yet.
|
// been bound yet.
|
||||||
if (SF.getASTContext().LangOpts.EnableASTScopeLookup &&
|
auto &Ctx = SF.getASTContext();
|
||||||
SF.isSuitableForASTScopes())
|
if (Ctx.LangOpts.EnableASTScopeLookup && SF.isSuitableForASTScopes())
|
||||||
SF.getScope()
|
SF.getScope()
|
||||||
.buildEnoughOfTreeForTopLevelExpressionsButDontRequestGenericsOrExtendedNominals();
|
.buildEnoughOfTreeForTopLevelExpressionsButDontRequestGenericsOrExtendedNominals();
|
||||||
|
|
||||||
auto &Ctx = SF.getASTContext();
|
|
||||||
BufferIndirectlyCausingDiagnosticRAII cpr(SF);
|
BufferIndirectlyCausingDiagnosticRAII cpr(SF);
|
||||||
|
|
||||||
// Make sure we have a type checker.
|
// Make sure we have a type checker.
|
||||||
@@ -360,30 +354,12 @@ void swift::performTypeChecking(SourceFile &SF, TopLevelContext &TLC,
|
|||||||
{
|
{
|
||||||
SharedTimer timer("Type checking and Semantic analysis");
|
SharedTimer timer("Type checking and Semantic analysis");
|
||||||
|
|
||||||
TC.setWarnLongFunctionBodies(WarnLongFunctionBodies);
|
if (Ctx.TypeCheckerOpts.SkipNonInlinableFunctionBodies)
|
||||||
TC.setWarnLongExpressionTypeChecking(WarnLongExpressionTypeChecking);
|
|
||||||
if (ExpressionTimeoutThreshold != 0)
|
|
||||||
TC.setExpressionTimeoutThreshold(ExpressionTimeoutThreshold);
|
|
||||||
|
|
||||||
if (SwitchCheckingInvocationThreshold != 0)
|
|
||||||
TC.setSwitchCheckingInvocationThreshold(
|
|
||||||
SwitchCheckingInvocationThreshold);
|
|
||||||
|
|
||||||
if (Options.contains(TypeCheckingFlags::DebugTimeFunctionBodies))
|
|
||||||
TC.enableDebugTimeFunctionBodies();
|
|
||||||
|
|
||||||
if (Options.contains(TypeCheckingFlags::DebugTimeExpressions))
|
|
||||||
TC.enableDebugTimeExpressions();
|
|
||||||
|
|
||||||
if (Options.contains(TypeCheckingFlags::ForImmediateMode))
|
|
||||||
TC.setInImmediateMode(true);
|
|
||||||
|
|
||||||
if (Options.contains(TypeCheckingFlags::SkipNonInlinableFunctionBodies))
|
|
||||||
// Disable this optimization if we're compiling SwiftOnoneSupport, because
|
// Disable this optimization if we're compiling SwiftOnoneSupport, because
|
||||||
// we _definitely_ need to look inside every declaration to figure out
|
// we _definitely_ need to look inside every declaration to figure out
|
||||||
// what gets prespecialized.
|
// what gets prespecialized.
|
||||||
if (!SF.getParentModule()->isOnoneSupportModule())
|
if (SF.getParentModule()->isOnoneSupportModule())
|
||||||
TC.setSkipNonInlinableBodies(true);
|
Ctx.TypeCheckerOpts.SkipNonInlinableFunctionBodies = false;
|
||||||
|
|
||||||
if (!Ctx.LangOpts.DisableAvailabilityChecking) {
|
if (!Ctx.LangOpts.DisableAvailabilityChecking) {
|
||||||
// Build the type refinement hierarchy for the primary
|
// Build the type refinement hierarchy for the primary
|
||||||
@@ -416,7 +392,7 @@ void swift::performTypeChecking(SourceFile &SF, TopLevelContext &TLC,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Checking that benefits from having the whole module available.
|
// Checking that benefits from having the whole module available.
|
||||||
if (!(Options & TypeCheckingFlags::DelayWholeModuleChecking)) {
|
if (!Ctx.TypeCheckerOpts.DelayWholeModuleChecking) {
|
||||||
performWholeModuleTypeChecking(SF);
|
performWholeModuleTypeChecking(SF);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -439,7 +415,7 @@ void swift::performTypeChecking(SourceFile &SF, TopLevelContext &TLC,
|
|||||||
// been cached, it will never be added to the ASTContext. The solution is to
|
// been cached, it will never be added to the ASTContext. The solution is to
|
||||||
// skip verification and avoid caching it.
|
// skip verification and avoid caching it.
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if (!(Options & TypeCheckingFlags::DelayWholeModuleChecking) &&
|
if (!Ctx.TypeCheckerOpts.DelayWholeModuleChecking &&
|
||||||
SF.Kind != SourceFileKind::REPL &&
|
SF.Kind != SourceFileKind::REPL &&
|
||||||
SF.Kind != SourceFileKind::SIL &&
|
SF.Kind != SourceFileKind::SIL &&
|
||||||
!Ctx.LangOpts.DebuggerSupport) {
|
!Ctx.LangOpts.DebuggerSupport) {
|
||||||
|
|||||||
@@ -700,6 +700,7 @@ public:
|
|||||||
Parser.reset(
|
Parser.reset(
|
||||||
new ParserUnit(SM, SourceFileKind::Main, BufferID,
|
new ParserUnit(SM, SourceFileKind::Main, BufferID,
|
||||||
CompInv.getLangOptions(),
|
CompInv.getLangOptions(),
|
||||||
|
CompInv.getTypeCheckerOptions(),
|
||||||
CompInv.getModuleName(),
|
CompInv.getModuleName(),
|
||||||
SynTreeCreator,
|
SynTreeCreator,
|
||||||
CompInv.getMainFileSyntaxParsingCache())
|
CompInv.getMainFileSyntaxParsingCache())
|
||||||
|
|||||||
@@ -166,10 +166,11 @@ int modulewrap_main(ArrayRef<const char *> Args, const char *Argv0,
|
|||||||
SearchPathOpts.RuntimeResourcePath = RuntimeResourcePath.str();
|
SearchPathOpts.RuntimeResourcePath = RuntimeResourcePath.str();
|
||||||
|
|
||||||
SourceManager SrcMgr;
|
SourceManager SrcMgr;
|
||||||
|
TypeCheckerOptions TypeCheckOpts;
|
||||||
LangOptions LangOpts;
|
LangOptions LangOpts;
|
||||||
LangOpts.Target = Invocation.getTargetTriple();
|
LangOpts.Target = Invocation.getTargetTriple();
|
||||||
ASTContext &ASTCtx = *ASTContext::get(LangOpts, SearchPathOpts, SrcMgr,
|
ASTContext &ASTCtx = *ASTContext::get(LangOpts, TypeCheckOpts, SearchPathOpts,
|
||||||
Instance.getDiags());
|
SrcMgr, Instance.getDiags());
|
||||||
registerParseRequestFunctions(ASTCtx.evaluator);
|
registerParseRequestFunctions(ASTCtx.evaluator);
|
||||||
registerTypeCheckerRequestFunctions(ASTCtx.evaluator);
|
registerTypeCheckerRequestFunctions(ASTCtx.evaluator);
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ public:
|
|||||||
BufferID = SM.addNewSourceBuffer(std::move(Buffer));
|
BufferID = SM.addNewSourceBuffer(std::move(Buffer));
|
||||||
Parser.reset(new ParserUnit(SM, SourceFileKind::Main,
|
Parser.reset(new ParserUnit(SM, SourceFileKind::Main,
|
||||||
BufferID, CompInv.getLangOptions(),
|
BufferID, CompInv.getLangOptions(),
|
||||||
|
CompInv.getTypeCheckerOptions(),
|
||||||
CompInv.getModuleName()));
|
CompInv.getModuleName()));
|
||||||
Parser->getDiagnosticEngine().addConsumer(DiagConsumer);
|
Parser->getDiagnosticEngine().addConsumer(DiagConsumer);
|
||||||
Parser->parse();
|
Parser->parse();
|
||||||
|
|||||||
@@ -274,6 +274,7 @@ swiftparse_client_node_t SynParser::parse(const char *source) {
|
|||||||
SourceManager SM;
|
SourceManager SM;
|
||||||
unsigned bufID = SM.addNewSourceBuffer(
|
unsigned bufID = SM.addNewSourceBuffer(
|
||||||
llvm::MemoryBuffer::getMemBuffer(source, "syntax_parse_source"));
|
llvm::MemoryBuffer::getMemBuffer(source, "syntax_parse_source"));
|
||||||
|
TypeCheckerOptions tyckOpts;
|
||||||
LangOptions langOpts;
|
LangOptions langOpts;
|
||||||
langOpts.BuildSyntaxTree = true;
|
langOpts.BuildSyntaxTree = true;
|
||||||
langOpts.CollectParsedToken = false;
|
langOpts.CollectParsedToken = false;
|
||||||
@@ -285,7 +286,7 @@ swiftparse_client_node_t SynParser::parse(const char *source) {
|
|||||||
std::make_shared<CLibParseActions>(*this, SM, bufID);
|
std::make_shared<CLibParseActions>(*this, SM, bufID);
|
||||||
// We have to use SourceFileKind::Main to avoid diagnostics like
|
// We have to use SourceFileKind::Main to avoid diagnostics like
|
||||||
// illegal_top_level_expr
|
// illegal_top_level_expr
|
||||||
ParserUnit PU(SM, SourceFileKind::Main, bufID, langOpts,
|
ParserUnit PU(SM, SourceFileKind::Main, bufID, langOpts, tyckOpts,
|
||||||
"syntax_parse_module", std::move(parseActions),
|
"syntax_parse_module", std::move(parseActions),
|
||||||
/*SyntaxCache=*/nullptr);
|
/*SyntaxCache=*/nullptr);
|
||||||
// Evaluating pound conditions may lead to unknown syntax.
|
// Evaluating pound conditions may lead to unknown syntax.
|
||||||
|
|||||||
@@ -34,7 +34,8 @@ static void declareOptionalType(ASTContext &ctx, SourceFile *fileForLookups,
|
|||||||
}
|
}
|
||||||
|
|
||||||
TestContext::TestContext(ShouldDeclareOptionalTypes optionals)
|
TestContext::TestContext(ShouldDeclareOptionalTypes optionals)
|
||||||
: Ctx(*ASTContext::get(LangOpts, SearchPathOpts, SourceMgr, Diags)) {
|
: Ctx(*ASTContext::get(LangOpts, TypeCheckerOpts, SearchPathOpts, SourceMgr,
|
||||||
|
Diags)) {
|
||||||
registerParseRequestFunctions(Ctx.evaluator);
|
registerParseRequestFunctions(Ctx.evaluator);
|
||||||
registerTypeCheckerRequestFunctions(Ctx.evaluator);
|
registerTypeCheckerRequestFunctions(Ctx.evaluator);
|
||||||
auto stdlibID = Ctx.getIdentifier(STDLIB_NAME);
|
auto stdlibID = Ctx.getIdentifier(STDLIB_NAME);
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ namespace unittest {
|
|||||||
class TestContextBase {
|
class TestContextBase {
|
||||||
public:
|
public:
|
||||||
LangOptions LangOpts;
|
LangOptions LangOpts;
|
||||||
|
TypeCheckerOptions TypeCheckerOpts;
|
||||||
SearchPathOptions SearchPathOpts;
|
SearchPathOptions SearchPathOpts;
|
||||||
SourceManager SourceMgr;
|
SourceManager SourceMgr;
|
||||||
DiagnosticEngine Diags;
|
DiagnosticEngine Diags;
|
||||||
|
|||||||
@@ -69,12 +69,13 @@ TEST(ClangImporterTest, emitPCHInMemory) {
|
|||||||
// Set up the importer and emit a bridging PCH.
|
// Set up the importer and emit a bridging PCH.
|
||||||
swift::LangOptions langOpts;
|
swift::LangOptions langOpts;
|
||||||
langOpts.Target = llvm::Triple("x86_64", "apple", "darwin");
|
langOpts.Target = llvm::Triple("x86_64", "apple", "darwin");
|
||||||
|
swift::TypeCheckerOptions typeckOpts;
|
||||||
INITIALIZE_LLVM();
|
INITIALIZE_LLVM();
|
||||||
swift::SearchPathOptions searchPathOpts;
|
swift::SearchPathOptions searchPathOpts;
|
||||||
swift::SourceManager sourceMgr;
|
swift::SourceManager sourceMgr;
|
||||||
swift::DiagnosticEngine diags(sourceMgr);
|
swift::DiagnosticEngine diags(sourceMgr);
|
||||||
std::unique_ptr<ASTContext> context(
|
std::unique_ptr<ASTContext> context(
|
||||||
ASTContext::get(langOpts, searchPathOpts, sourceMgr, diags));
|
ASTContext::get(langOpts, typeckOpts, searchPathOpts, sourceMgr, diags));
|
||||||
auto importer = ClangImporter::create(*context, options);
|
auto importer = ClangImporter::create(*context, options);
|
||||||
|
|
||||||
std::string PCH = createFilename(cache, "bridging.h.pch");
|
std::string PCH = createFilename(cache, "bridging.h.pch");
|
||||||
|
|||||||
@@ -94,10 +94,12 @@ protected:
|
|||||||
PrintingDiagnosticConsumer printingConsumer;
|
PrintingDiagnosticConsumer printingConsumer;
|
||||||
DiagnosticEngine diags(sourceMgr);
|
DiagnosticEngine diags(sourceMgr);
|
||||||
diags.addConsumer(printingConsumer);
|
diags.addConsumer(printingConsumer);
|
||||||
|
TypeCheckerOptions typeckOpts;
|
||||||
LangOptions langOpts;
|
LangOptions langOpts;
|
||||||
langOpts.Target = llvm::Triple(llvm::sys::getDefaultTargetTriple());
|
langOpts.Target = llvm::Triple(llvm::sys::getDefaultTargetTriple());
|
||||||
SearchPathOptions searchPathOpts;
|
SearchPathOptions searchPathOpts;
|
||||||
auto ctx = ASTContext::get(langOpts, searchPathOpts, sourceMgr, diags);
|
auto ctx =
|
||||||
|
ASTContext::get(langOpts, typeckOpts, searchPathOpts, sourceMgr, diags);
|
||||||
|
|
||||||
auto loader = ModuleInterfaceLoader::create(
|
auto loader = ModuleInterfaceLoader::create(
|
||||||
*ctx, cacheDir, prebuiltCacheDir,
|
*ctx, cacheDir, prebuiltCacheDir,
|
||||||
|
|||||||
@@ -82,7 +82,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Token> parseAndGetSplitTokens(unsigned BufID) {
|
std::vector<Token> parseAndGetSplitTokens(unsigned BufID) {
|
||||||
swift::ParserUnit PU(SM, SourceFileKind::Main, BufID, LangOpts, "unknown");
|
swift::ParserUnit PU(SM, SourceFileKind::Main, BufID,
|
||||||
|
LangOpts, TypeCheckerOptions(), "unknown");
|
||||||
|
|
||||||
bool Done = false;
|
bool Done = false;
|
||||||
while (!Done) {
|
while (!Done) {
|
||||||
|
|||||||
Reference in New Issue
Block a user