Give the FrontendTool library its own header and allow users

to observe progress through the frontend.
This commit is contained in:
John McCall
2016-04-21 14:58:59 -07:00
parent 39c7ae81d6
commit 23f961bc0a
4 changed files with 137 additions and 22 deletions

View 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

View File

@@ -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

View File

@@ -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) {}

View File

@@ -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"