mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Give the FrontendTool library its own header and allow users
to observe progress through the frontend.
This commit is contained in:
84
include/swift/FrontendTool/FrontendTool.h
Normal file
84
include/swift/FrontendTool/FrontendTool.h
Normal file
@@ -0,0 +1,84 @@
|
||||
//===--- FrontendTool.h - Frontend control ----------------------*- C++ -*-===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See http://swift.org/LICENSE.txt for license information
|
||||
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file provides a high-level API for interacting with the basic
|
||||
// frontend tool operation.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SWIFT_FRONTENDTOOL_H
|
||||
#define SWIFT_FRONTENDTOOL_H
|
||||
|
||||
#include "swift/Basic/LLVM.h"
|
||||
|
||||
namespace llvm {
|
||||
class Module;
|
||||
}
|
||||
|
||||
namespace swift {
|
||||
class CompilerInvocation;
|
||||
class CompilerInstance;
|
||||
class SILModule;
|
||||
|
||||
/// A simple observer of frontend activity.
|
||||
///
|
||||
/// Don't let this interface block enhancements to the frontend pipeline.
|
||||
class FrontendObserver {
|
||||
public:
|
||||
FrontendObserver() = default;
|
||||
virtual ~FrontendObserver() = default;
|
||||
|
||||
/// The frontend has parsed the command line.
|
||||
virtual void parsedArgs(CompilerInvocation &invocation);
|
||||
|
||||
/// The frontend has configured the compiler instance.
|
||||
virtual void configuredCompiler(CompilerInstance &instance);
|
||||
|
||||
/// The frontend has performed semantic analysis.
|
||||
virtual void performedSemanticAnalysis(CompilerInstance &instance);
|
||||
|
||||
/// The frontend has performed basic SIL generation.
|
||||
/// SIL diagnostic passes have not yet been applied.
|
||||
virtual void performedSILGeneration(SILModule &module);
|
||||
|
||||
/// The frontend has executed the SIL diagnostic passes.
|
||||
virtual void performedSILDiagnostics(SILModule &module);
|
||||
|
||||
/// The frontend has executed the SIL optimization pipeline.
|
||||
virtual void performedSILOptimization(SILModule &module);
|
||||
|
||||
/// The frontend is about to run the program as an immediate script.
|
||||
virtual void aboutToRunImmediately(CompilerInstance &instance);
|
||||
|
||||
// TODO: maybe enhance this interface to hear about IRGen and LLVM
|
||||
// progress.
|
||||
};
|
||||
|
||||
/// Perform all the operations of the frontend, exactly as if invoked
|
||||
/// with -frontend.
|
||||
///
|
||||
/// \param args the arguments to use as the arguments to the frontend
|
||||
/// \param argv0 the name used as the frontend executable
|
||||
/// \param mainAddr an address from the main executable
|
||||
///
|
||||
/// \return the exit value of the frontend: 0 or 1 on success unless
|
||||
/// the frontend executes in immediate mode, in which case this will be
|
||||
/// the exit value of the script, assuming it exits normally
|
||||
int performFrontend(ArrayRef<const char *> args,
|
||||
const char *argv0,
|
||||
void *mainAddr,
|
||||
FrontendObserver *observer = nullptr);
|
||||
|
||||
|
||||
} // namespace swift
|
||||
|
||||
#endif
|
||||
@@ -88,20 +88,6 @@ namespace swift {
|
||||
|
||||
/// @}
|
||||
|
||||
/// Perform all the operations of the frontend, exactly as if invoked
|
||||
/// with -frontend.
|
||||
///
|
||||
/// \param args the arguments to use as the arguments to the frontend
|
||||
/// \param argv0 the name used as the frontend executable
|
||||
/// \param mainAddr an address from the main executable
|
||||
///
|
||||
/// \return the exit value of the frontend: 0 or 1 on success unless
|
||||
/// the frontend executes in immediate mode, in which case this will be
|
||||
/// the exit value of the script, assuming it exits normally
|
||||
int performFrontend(ArrayRef<const char *> args,
|
||||
const char *argv0,
|
||||
void *mainAddr);
|
||||
|
||||
/// \brief Parse a single buffer into the given source file.
|
||||
///
|
||||
/// If the source file is the main file, stop parsing after the next
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "swift/FrontendTool/FrontendTool.h"
|
||||
|
||||
#include "swift/Subsystems.h"
|
||||
#include "swift/AST/DiagnosticsFrontend.h"
|
||||
#include "swift/AST/DiagnosticsSema.h"
|
||||
@@ -614,7 +616,8 @@ static void debugFailWithCrash() {
|
||||
static bool performCompile(CompilerInstance &Instance,
|
||||
CompilerInvocation &Invocation,
|
||||
ArrayRef<const char *> Args,
|
||||
int &ReturnValue) {
|
||||
int &ReturnValue,
|
||||
FrontendObserver *observer) {
|
||||
FrontendOptions opts = Invocation.getFrontendOptions();
|
||||
FrontendOptions::ActionType Action = opts.RequestedAction;
|
||||
|
||||
@@ -669,6 +672,10 @@ static bool performCompile(CompilerInstance &Instance,
|
||||
else
|
||||
Instance.performSema();
|
||||
|
||||
if (observer) {
|
||||
observer->performedSemanticAnalysis(Instance);
|
||||
}
|
||||
|
||||
FrontendOptions::DebugCrashMode CrashMode = opts.CrashMode;
|
||||
if (CrashMode == FrontendOptions::DebugCrashMode::AssertAfterParse)
|
||||
debugFailWithAssertion();
|
||||
@@ -759,6 +766,10 @@ static bool performCompile(CompilerInstance &Instance,
|
||||
}
|
||||
}
|
||||
|
||||
if (observer) {
|
||||
observer->performedSILGeneration(*SM);
|
||||
}
|
||||
|
||||
// We've been told to emit SIL after SILGen, so write it now.
|
||||
if (Action == FrontendOptions::EmitSILGen) {
|
||||
// If we are asked to link all, link all.
|
||||
@@ -787,10 +798,15 @@ static bool performCompile(CompilerInstance &Instance,
|
||||
}
|
||||
|
||||
// Perform "stable" optimizations that are invariant across compiler versions.
|
||||
if (!Invocation.getDiagnosticOptions().SkipDiagnosticPasses &&
|
||||
runSILDiagnosticPasses(*SM))
|
||||
if (!Invocation.getDiagnosticOptions().SkipDiagnosticPasses) {
|
||||
if (runSILDiagnosticPasses(*SM))
|
||||
return true;
|
||||
|
||||
if (observer) {
|
||||
observer->performedSILDiagnostics(*SM);
|
||||
}
|
||||
}
|
||||
|
||||
// Now if we are asked to link all, link all.
|
||||
if (Invocation.getSILOptions().LinkMode == SILOptions::LinkAll)
|
||||
performSILLinking(SM.get(), true);
|
||||
@@ -818,6 +834,10 @@ static bool performCompile(CompilerInstance &Instance,
|
||||
}
|
||||
}
|
||||
|
||||
if (observer) {
|
||||
observer->performedSILOptimization(*SM);
|
||||
}
|
||||
|
||||
{
|
||||
SharedTimer timer("SIL verification (post-optimization)");
|
||||
SM->verify();
|
||||
@@ -915,6 +935,11 @@ static bool performCompile(CompilerInstance &Instance,
|
||||
const ProcessCmdLine &CmdLine = ProcessCmdLine(opts.ImmediateArgv.begin(),
|
||||
opts.ImmediateArgv.end());
|
||||
Instance.setSILModule(std::move(SM));
|
||||
|
||||
if (observer) {
|
||||
observer->aboutToRunImmediately(Instance);
|
||||
}
|
||||
|
||||
ReturnValue =
|
||||
RunImmediately(Instance, CmdLine, IRGenOpts, Invocation.getSILOptions());
|
||||
return false;
|
||||
@@ -997,7 +1022,8 @@ static bool dumpAPI(Module *Mod, StringRef OutDir) {
|
||||
}
|
||||
|
||||
int swift::performFrontend(ArrayRef<const char *> Args,
|
||||
const char *Argv0, void *MainAddr) {
|
||||
const char *Argv0, void *MainAddr,
|
||||
FrontendObserver *observer) {
|
||||
llvm::InitializeAllTargets();
|
||||
llvm::InitializeAllTargetMCs();
|
||||
llvm::InitializeAllAsmPrinters();
|
||||
@@ -1031,6 +1057,11 @@ int swift::performFrontend(ArrayRef<const char *> Args,
|
||||
if (Invocation.getLangOptions().Target.isWindowsCygwinEnvironment())
|
||||
IRGenOpts.DWARFVersion = swift::CygwinDWARFVersion;
|
||||
|
||||
// The compiler invocation is now fully configured; notify our observer.
|
||||
if (observer) {
|
||||
observer->parsedArgs(Invocation);
|
||||
}
|
||||
|
||||
if (Invocation.getFrontendOptions().PrintHelp ||
|
||||
Invocation.getFrontendOptions().PrintHelpHidden) {
|
||||
unsigned IncludedFlagsBitmask = options::FrontendOption;
|
||||
@@ -1125,8 +1156,14 @@ int swift::performFrontend(ArrayRef<const char *> Args,
|
||||
return 1;
|
||||
}
|
||||
|
||||
// The compiler instance has been configured; notify our observer.
|
||||
if (observer) {
|
||||
observer->configuredCompiler(Instance);
|
||||
}
|
||||
|
||||
int ReturnValue = 0;
|
||||
bool HadError = performCompile(Instance, Invocation, Args, ReturnValue) ||
|
||||
bool HadError =
|
||||
performCompile(Instance, Invocation, Args, ReturnValue, observer) ||
|
||||
Instance.getASTContext().hadError();
|
||||
|
||||
if (!HadError && !Invocation.getFrontendOptions().DumpAPIPath.empty()) {
|
||||
@@ -1148,3 +1185,11 @@ int swift::performFrontend(ArrayRef<const char *> Args,
|
||||
|
||||
return (HadError ? 1 : ReturnValue);
|
||||
}
|
||||
|
||||
void FrontendObserver::parsedArgs(CompilerInvocation &invocation) {}
|
||||
void FrontendObserver::configuredCompiler(CompilerInstance &instance) {}
|
||||
void FrontendObserver::performedSemanticAnalysis(CompilerInstance &instance) {}
|
||||
void FrontendObserver::performedSILGeneration(SILModule &module) {}
|
||||
void FrontendObserver::performedSILDiagnostics(SILModule &module) {}
|
||||
void FrontendObserver::performedSILOptimization(SILModule &module) {}
|
||||
void FrontendObserver::aboutToRunImmediately(CompilerInstance &instance) {}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "swift/Driver/Job.h"
|
||||
#include "swift/Frontend/Frontend.h"
|
||||
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
|
||||
#include "swift/Subsystems.h"
|
||||
#include "swift/FrontendTool/FrontendTool.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Errno.h"
|
||||
|
||||
Reference in New Issue
Block a user