[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