[cfe-commits] r93282 - in /cfe/trunk: include/clang/Frontend/CompilerInstance.h lib/Frontend/CompilerInstance.cpp tools/driver/cc1_main.cpp
Daniel Dunbar
daniel at zuster.org
Tue Jan 12 16:48:06 PST 2010
Author: ddunbar
Date: Tue Jan 12 18:48:06 2010
New Revision: 93282
URL: http://llvm.org/viewvc/llvm-project?rev=93282&view=rev
Log:
cc1: Factor out CompilerInstance::ExecuteAction which has the majority of the
clang -cc1 logic for running an action against a set of options.
- This should make it easier to build tools that have a clang -cc1 like
interface, but aren't actually part of clang -cc1.
Modified:
cfe/trunk/include/clang/Frontend/CompilerInstance.h
cfe/trunk/lib/Frontend/CompilerInstance.cpp
cfe/trunk/tools/driver/cc1_main.cpp
Modified: cfe/trunk/include/clang/Frontend/CompilerInstance.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CompilerInstance.h?rev=93282&r1=93281&r2=93282&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/CompilerInstance.h (original)
+++ cfe/trunk/include/clang/Frontend/CompilerInstance.h Tue Jan 12 18:48:06 2010
@@ -32,6 +32,7 @@
class DiagnosticClient;
class ExternalASTSource;
class FileManager;
+class FrontendAction;
class Preprocessor;
class Source;
class SourceManager;
@@ -103,6 +104,42 @@
bool _OwnsLLVMContext = true);
~CompilerInstance();
+ /// @name High-Level Operations
+ /// {
+
+ /// ExecuteAction - Execute the provided action against the compiler's
+ /// CompilerInvocation object.
+ ///
+ /// This function makes the following assumptions:
+ ///
+ /// - The invocation options should be initialized. This function does not
+ /// handle the '-help' or '-version' options, clients should handle those
+ /// directly.
+ ///
+ /// - The diagnostics engine should have already been created by the client.
+ ///
+ /// - No other CompilerInstance state should have been initialized (this is
+ /// an unchecked error).
+ ///
+ /// - Clients should have initialized any LLVM target features that may be
+ /// required.
+ ///
+ /// - Clients should eventually call llvm_shutdown() upon the completion of
+ /// this routine to ensure that any managed objects are properly destroyed.
+ ///
+ /// Note that this routine may write output to 'stderr'.
+ ///
+ /// \param Act - The action to execute.
+ /// \return - True on success.
+ //
+ // FIXME: This function should take the stream to write any debugging /
+ // verbose output to as an argument.
+ //
+ // FIXME: Eliminate the llvm_shutdown requirement, that should either be part
+ // of the context or else not CompilerInstance specific.
+ bool ExecuteAction(FrontendAction &Act);
+
+ /// }
/// @name LLVM Context
/// {
Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=93282&r1=93281&r2=93282&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Tue Jan 12 18:48:06 2010
@@ -14,10 +14,12 @@
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/Version.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/PTHManager.h"
#include "clang/Frontend/ChainedDiagnosticClient.h"
+#include "clang/Frontend/FrontendAction.h"
#include "clang/Frontend/PCHReader.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
@@ -28,6 +30,7 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Timer.h"
+#include "llvm/System/Host.h"
#include "llvm/System/Path.h"
#include "llvm/System/Program.h"
using namespace clang;
@@ -409,3 +412,87 @@
return true;
}
+
+// High-Level Operations
+
+bool CompilerInstance::ExecuteAction(FrontendAction &Act) {
+ assert(hasDiagnostics() && "Diagnostics engine is not initialized!");
+ assert(!getFrontendOpts().ShowHelp && "Client must handle '-help'!");
+ assert(!getFrontendOpts().ShowVersion && "Client must handle '-version'!");
+
+ // FIXME: Take this as an argument, once all the APIs we used have moved to
+ // taking it as an input instead of hard-coding llvm::errs.
+ llvm::raw_ostream &OS = llvm::errs();
+
+ // Create the target instance.
+ setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), getTargetOpts()));
+ if (!hasTarget())
+ return false;
+
+ // Inform the target of the language options.
+ //
+ // FIXME: We shouldn't need to do this, the target should be immutable once
+ // created. This complexity should be lifted elsewhere.
+ getTarget().setForcedLangOptions(getLangOpts());
+
+ // Validate/process some options.
+ if (getHeaderSearchOpts().Verbose)
+ OS << "clang -cc1 version " CLANG_VERSION_STRING
+ << " based upon " << PACKAGE_STRING
+ << " hosted on " << llvm::sys::getHostTriple() << "\n";
+
+ if (getFrontendOpts().ShowTimers)
+ createFrontendTimer();
+
+ for (unsigned i = 0, e = getFrontendOpts().Inputs.size(); i != e; ++i) {
+ const std::string &InFile = getFrontendOpts().Inputs[i].second;
+
+ // If we aren't using an AST file, setup the file and source managers and
+ // the preprocessor.
+ bool IsAST = getFrontendOpts().Inputs[i].first == FrontendOptions::IK_AST;
+ if (!IsAST) {
+ if (!i) {
+ // Create a file manager object to provide access to and cache the
+ // filesystem.
+ createFileManager();
+
+ // Create the source manager.
+ createSourceManager();
+ } else {
+ // Reset the ID tables if we are reusing the SourceManager.
+ getSourceManager().clearIDTables();
+ }
+
+ // Create the preprocessor.
+ createPreprocessor();
+ }
+
+ if (Act.BeginSourceFile(*this, InFile, IsAST)) {
+ Act.Execute();
+ Act.EndSourceFile();
+ }
+ }
+
+ if (getDiagnosticOpts().ShowCarets)
+ if (unsigned NumDiagnostics = getDiagnostics().getNumDiagnostics())
+ OS << NumDiagnostics << " diagnostic"
+ << (NumDiagnostics == 1 ? "" : "s")
+ << " generated.\n";
+
+ if (getFrontendOpts().ShowStats) {
+ getFileManager().PrintStats();
+ OS << "\n";
+ }
+
+ // Return the appropriate status when verifying diagnostics.
+ //
+ // FIXME: If we could make getNumErrors() do the right thing, we wouldn't need
+ // this.
+ if (getDiagnosticOpts().VerifyDiagnostics)
+ return !static_cast<VerifyDiagnosticsClient&>(
+ getDiagnosticClient()).HadErrors();
+
+ return !getDiagnostics().getNumErrors();
+}
+
+
Modified: cfe/trunk/tools/driver/cc1_main.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/driver/cc1_main.cpp?rev=93282&r1=93281&r2=93282&view=diff
==============================================================================
--- cfe/trunk/tools/driver/cc1_main.cpp (original)
+++ cfe/trunk/tools/driver/cc1_main.cpp Tue Jan 12 18:48:06 2010
@@ -14,10 +14,6 @@
//===----------------------------------------------------------------------===//
#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/TargetInfo.h"
-#include "clang/Basic/Version.h"
#include "clang/Driver/Arg.h"
#include "clang/Driver/ArgList.h"
#include "clang/Driver/CC1Options.h"
@@ -30,7 +26,6 @@
#include "clang/Frontend/FrontendPluginRegistry.h"
#include "clang/Frontend/TextDiagnosticBuffer.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
-#include "clang/Frontend/VerifyDiagnosticsClient.h"
#include "llvm/LLVMContext.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/ErrorHandling.h"
@@ -38,8 +33,6 @@
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/DynamicLibrary.h"
-#include "llvm/System/Host.h"
-#include "llvm/System/Path.h"
#include "llvm/System/Signals.h"
#include "llvm/Target/TargetSelect.h"
#include <cstdio>
@@ -207,13 +200,13 @@
Diags);
// Infer the builtin include path if unspecified.
- if (Clang.getInvocation().getHeaderSearchOpts().UseBuiltinIncludes &&
- Clang.getInvocation().getHeaderSearchOpts().ResourceDir.empty())
- Clang.getInvocation().getHeaderSearchOpts().ResourceDir =
+ if (Clang.getHeaderSearchOpts().UseBuiltinIncludes &&
+ Clang.getHeaderSearchOpts().ResourceDir.empty())
+ Clang.getHeaderSearchOpts().ResourceDir =
CompilerInvocation::GetResourcesPath(Argv0, MainAddr);
// Honor -help.
- if (Clang.getInvocation().getFrontendOpts().ShowHelp) {
+ if (Clang.getFrontendOpts().ShowHelp) {
llvm::OwningPtr<driver::OptTable> Opts(driver::createCC1OptTable());
Opts->PrintHelp(llvm::outs(), "clang -cc1",
"LLVM 'Clang' Compiler: http://clang.llvm.org");
@@ -223,7 +216,7 @@
// Honor -version.
//
// FIXME: Use a better -version message?
- if (Clang.getInvocation().getFrontendOpts().ShowVersion) {
+ if (Clang.getFrontendOpts().ShowVersion) {
llvm::cl::PrintVersionMessage();
return 0;
}
@@ -249,85 +242,18 @@
Diags.Report(diag::err_fe_unable_to_load_plugin) << Path << Error;
}
- // Create the frontend action.
- llvm::OwningPtr<FrontendAction> Act(CreateFrontendAction(Clang));
-
- // If there were any errors in processing arguments, exit now.
- if (!Act || Clang.getDiagnostics().getNumErrors())
- return 1;
-
- // Create the target instance.
- Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(),
- Clang.getTargetOpts()));
- if (!Clang.hasTarget())
- return 1;
-
- // Inform the target of the language options.
- //
- // FIXME: We shouldn't need to do this, the target should be immutable once
- // created. This complexity should be lifted elsewhere.
- Clang.getTarget().setForcedLangOptions(Clang.getLangOpts());
-
- // Validate/process some options.
- if (Clang.getHeaderSearchOpts().Verbose)
- llvm::errs() << "clang -cc1 version " CLANG_VERSION_STRING
- << " based upon " << PACKAGE_STRING
- << " hosted on " << llvm::sys::getHostTriple() << "\n";
-
- if (Clang.getFrontendOpts().ShowTimers)
- Clang.createFrontendTimer();
-
- for (unsigned i = 0, e = Clang.getFrontendOpts().Inputs.size(); i != e; ++i) {
- const std::string &InFile = Clang.getFrontendOpts().Inputs[i].second;
-
- // If we aren't using an AST file, setup the file and source managers and
- // the preprocessor.
- bool IsAST =
- Clang.getFrontendOpts().Inputs[i].first == FrontendOptions::IK_AST;
- if (!IsAST) {
- if (!i) {
- // Create a file manager object to provide access to and cache the
- // filesystem.
- Clang.createFileManager();
-
- // Create the source manager.
- Clang.createSourceManager();
- } else {
- // Reset the ID tables if we are reusing the SourceManager.
- Clang.getSourceManager().clearIDTables();
- }
-
- // Create the preprocessor.
- Clang.createPreprocessor();
- }
-
- if (Act->BeginSourceFile(Clang, InFile, IsAST)) {
- Act->Execute();
- Act->EndSourceFile();
- }
+ // If there were errors in processing arguments, don't do anything else.
+ bool Success = false;
+ if (!Clang.getDiagnostics().getNumErrors()) {
+ // Create and execute the frontend action.
+ llvm::OwningPtr<FrontendAction> Act(CreateFrontendAction(Clang));
+ if (Act)
+ Success = Clang.ExecuteAction(*Act);
}
- if (Clang.getDiagnosticOpts().ShowCarets)
- if (unsigned NumDiagnostics = Clang.getDiagnostics().getNumDiagnostics())
- fprintf(stderr, "%d diagnostic%s generated.\n", NumDiagnostics,
- (NumDiagnostics == 1 ? "" : "s"));
-
- if (Clang.getFrontendOpts().ShowStats) {
- Clang.getFileManager().PrintStats();
- fprintf(stderr, "\n");
- }
-
- // Return the appropriate status when verifying diagnostics.
- //
- // FIXME: If we could make getNumErrors() do the right thing, we wouldn't need
- // this.
- if (Clang.getDiagnosticOpts().VerifyDiagnostics)
- return static_cast<VerifyDiagnosticsClient&>(
- Clang.getDiagnosticClient()).HadErrors();
-
// Managed static deconstruction. Useful for making things like
// -time-passes usable.
llvm::llvm_shutdown();
- return (Clang.getDiagnostics().getNumErrors() != 0);
+ return !Success;
}
More information about the cfe-commits
mailing list