summaryrefslogtreecommitdiffstats
path: root/lib/CompilerDriver
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CompilerDriver')
-rw-r--r--lib/CompilerDriver/Action.cpp10
-rw-r--r--lib/CompilerDriver/BuiltinOptions.cpp55
-rw-r--r--lib/CompilerDriver/CompilationGraph.cpp33
-rw-r--r--lib/CompilerDriver/Main.cpp130
-rw-r--r--lib/CompilerDriver/Makefile32
-rw-r--r--lib/CompilerDriver/Tool.cpp6
6 files changed, 241 insertions, 25 deletions
diff --git a/lib/CompilerDriver/Action.cpp b/lib/CompilerDriver/Action.cpp
index 816f793..5fd63ee 100644
--- a/lib/CompilerDriver/Action.cpp
+++ b/lib/CompilerDriver/Action.cpp
@@ -13,10 +13,8 @@
#include "llvm/CompilerDriver/Action.h"
#include "llvm/CompilerDriver/BuiltinOptions.h"
-
+#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Program.h"
-
-#include <iostream>
#include <stdexcept>
using namespace llvm;
@@ -58,15 +56,15 @@ namespace {
}
void print_string (const std::string& str) {
- std::cerr << str << ' ';
+ errs() << str << ' ';
}
}
int llvmc::Action::Execute() const {
if (DryRun || VerboseMode) {
- std::cerr << Command_ << " ";
+ errs() << Command_ << " ";
std::for_each(Args_.begin(), Args_.end(), print_string);
- std::cerr << '\n';
+ errs() << '\n';
}
if (DryRun)
return 0;
diff --git a/lib/CompilerDriver/BuiltinOptions.cpp b/lib/CompilerDriver/BuiltinOptions.cpp
new file mode 100644
index 0000000..a3364e8
--- /dev/null
+++ b/lib/CompilerDriver/BuiltinOptions.cpp
@@ -0,0 +1,55 @@
+//===--- BuiltinOptions.cpp - The LLVM Compiler Driver ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open
+// Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Definitions of all global command-line option variables.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CompilerDriver/BuiltinOptions.h"
+
+#ifdef ENABLE_LLVMC_DYNAMIC_PLUGINS
+#include "llvm/Support/PluginLoader.h"
+#endif
+
+namespace cl = llvm::cl;
+
+// External linkage here is intentional.
+
+cl::list<std::string> InputFilenames(cl::Positional, cl::desc("<input file>"),
+ cl::ZeroOrMore);
+cl::opt<std::string> OutputFilename("o", cl::desc("Output file name"),
+ cl::value_desc("file"), cl::Prefix);
+cl::list<std::string> Languages("x",
+ cl::desc("Specify the language of the following input files"),
+ cl::ZeroOrMore);
+cl::opt<bool> DryRun("dry-run",
+ cl::desc("Only pretend to run commands"));
+cl::opt<bool> VerboseMode("v",
+ cl::desc("Enable verbose mode"));
+
+cl::opt<bool> CheckGraph("check-graph",
+ cl::desc("Check the compilation graph for errors"),
+ cl::Hidden);
+cl::opt<bool> WriteGraph("write-graph",
+ cl::desc("Write compilation-graph.dot file"),
+ cl::Hidden);
+cl::opt<bool> ViewGraph("view-graph",
+ cl::desc("Show compilation graph in GhostView"),
+ cl::Hidden);
+
+cl::opt<SaveTempsEnum::Values> SaveTemps
+("save-temps", cl::desc("Keep temporary files"),
+ cl::init(SaveTempsEnum::Unset),
+ cl::values(clEnumValN(SaveTempsEnum::Obj, "obj",
+ "Save files in the directory specified with -o"),
+ clEnumValN(SaveTempsEnum::Cwd, "cwd",
+ "Use current working directory"),
+ clEnumValN(SaveTempsEnum::Obj, "", "Same as 'cwd'"),
+ clEnumValEnd),
+ cl::ValueOptional);
diff --git a/lib/CompilerDriver/CompilationGraph.cpp b/lib/CompilerDriver/CompilationGraph.cpp
index 1212a21..f303943 100644
--- a/lib/CompilerDriver/CompilationGraph.cpp
+++ b/lib/CompilerDriver/CompilationGraph.cpp
@@ -18,10 +18,10 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/DOTGraphTraits.h"
#include "llvm/Support/GraphWriter.h"
+#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cstring>
-#include <iostream>
#include <iterator>
#include <limits>
#include <queue>
@@ -346,8 +346,8 @@ int CompilationGraph::CheckLanguageNames() const {
if (!N2.ToolPtr) {
++ret;
- std::cerr << "Error: there is an edge from '" << N1.ToolPtr->Name()
- << "' back to the root!\n\n";
+ errs() << "Error: there is an edge from '" << N1.ToolPtr->Name()
+ << "' back to the root!\n\n";
continue;
}
@@ -363,17 +363,17 @@ int CompilationGraph::CheckLanguageNames() const {
if (!eq) {
++ret;
- std::cerr << "Error: Output->input language mismatch in the edge '" <<
- N1.ToolPtr->Name() << "' -> '" << N2.ToolPtr->Name() << "'!\n";
-
- std::cerr << "Expected one of { ";
+ errs() << "Error: Output->input language mismatch in the edge '"
+ << N1.ToolPtr->Name() << "' -> '" << N2.ToolPtr->Name()
+ << "'!\n"
+ << "Expected one of { ";
InLangs = N2.ToolPtr->InputLanguages();
for (;*InLangs; ++InLangs) {
- std::cerr << '\'' << *InLangs << (*(InLangs+1) ? "', " : "'");
+ errs() << '\'' << *InLangs << (*(InLangs+1) ? "', " : "'");
}
- std::cerr << " }, but got '" << OutLang << "'!\n\n";
+ errs() << " }, but got '" << OutLang << "'!\n\n";
}
}
@@ -406,9 +406,8 @@ int CompilationGraph::CheckMultipleDefaultEdges() const {
}
else if (EdgeWeight == MaxWeight) {
++ret;
- std::cerr
- << "Error: there are multiple maximal edges stemming from the '"
- << N.ToolPtr->Name() << "' node!\n\n";
+ errs() << "Error: there are multiple maximal edges stemming from the '"
+ << N.ToolPtr->Name() << "' node!\n\n";
break;
}
}
@@ -440,9 +439,9 @@ int CompilationGraph::CheckCycles() {
}
if (deleted != NodesMap.size()) {
- std::cerr << "Error: there are cycles in the compilation graph!\n"
- << "Try inspecting the diagram produced by "
- "'llvmc --view-graph'.\n\n";
+ errs() << "Error: there are cycles in the compilation graph!\n"
+ << "Try inspecting the diagram produced by "
+ << "'llvmc --view-graph'.\n\n";
return 1;
}
@@ -518,9 +517,9 @@ void CompilationGraph::writeGraph(const std::string& OutputFilename) {
std::ofstream O(OutputFilename.c_str());
if (O.good()) {
- std::cerr << "Writing '"<< OutputFilename << "' file...";
+ errs() << "Writing '"<< OutputFilename << "' file...";
llvm::WriteGraph(O, this);
- std::cerr << "done.\n";
+ errs() << "done.\n";
O.close();
}
else {
diff --git a/lib/CompilerDriver/Main.cpp b/lib/CompilerDriver/Main.cpp
new file mode 100644
index 0000000..c9c0413
--- /dev/null
+++ b/lib/CompilerDriver/Main.cpp
@@ -0,0 +1,130 @@
+//===--- Main.cpp - The LLVM Compiler Driver --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open
+// Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// llvmc::Main function - driver entry point.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CompilerDriver/BuiltinOptions.h"
+#include "llvm/CompilerDriver/CompilationGraph.h"
+#include "llvm/CompilerDriver/Error.h"
+#include "llvm/CompilerDriver/Plugin.h"
+
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Path.h"
+
+#include <stdexcept>
+#include <string>
+
+namespace cl = llvm::cl;
+namespace sys = llvm::sys;
+using namespace llvmc;
+
+namespace {
+
+ sys::Path getTempDir() {
+ sys::Path tempDir;
+
+ // GCC 4.5-style -save-temps handling.
+ if (SaveTemps == SaveTempsEnum::Unset) {
+ tempDir = sys::Path::GetTemporaryDirectory();
+ }
+ else if (SaveTemps == SaveTempsEnum::Obj && !OutputFilename.empty()) {
+ tempDir = OutputFilename;
+
+ if (!tempDir.exists()) {
+ std::string ErrMsg;
+ if (tempDir.createDirectoryOnDisk(true, &ErrMsg))
+ throw std::runtime_error(ErrMsg);
+ }
+ }
+ // else if (SaveTemps == Cwd) -> use current dir (leave tempDir empty)
+
+ return tempDir;
+ }
+
+ /// BuildTargets - A small wrapper for CompilationGraph::Build.
+ int BuildTargets(CompilationGraph& graph, const LanguageMap& langMap) {
+ int ret;
+ const sys::Path& tempDir = getTempDir();
+
+ try {
+ ret = graph.Build(tempDir, langMap);
+ }
+ catch(...) {
+ if (SaveTemps == SaveTempsEnum::Unset)
+ tempDir.eraseFromDisk(true);
+ throw;
+ }
+
+ if (SaveTemps == SaveTempsEnum::Unset)
+ tempDir.eraseFromDisk(true);
+ return ret;
+ }
+}
+
+namespace llvmc {
+
+// Sometimes plugins want to condition on the value in argv[0].
+const char* ProgramName;
+
+int Main(int argc, char** argv) {
+ try {
+ LanguageMap langMap;
+ CompilationGraph graph;
+
+ ProgramName = argv[0];
+
+ cl::ParseCommandLineOptions
+ (argc, argv, "LLVM Compiler Driver (Work In Progress)", true);
+
+ PluginLoader Plugins;
+ Plugins.PopulateLanguageMap(langMap);
+ Plugins.PopulateCompilationGraph(graph);
+
+ if (CheckGraph) {
+ int ret = graph.Check();
+ if (!ret)
+ llvm::errs() << "check-graph: no errors found.\n";
+
+ return ret;
+ }
+
+ if (ViewGraph) {
+ graph.viewGraph();
+ if (!WriteGraph)
+ return 0;
+ }
+
+ if (WriteGraph) {
+ graph.writeGraph(OutputFilename.empty()
+ ? std::string("compilation-graph.dot")
+ : OutputFilename);
+ return 0;
+ }
+
+ if (InputFilenames.empty()) {
+ throw std::runtime_error("no input files");
+ }
+
+ return BuildTargets(graph, langMap);
+ }
+ catch(llvmc::error_code& ec) {
+ return ec.code();
+ }
+ catch(const std::exception& ex) {
+ llvm::errs() << argv[0] << ": " << ex.what() << '\n';
+ }
+ catch(...) {
+ llvm::errs() << argv[0] << ": unknown error!\n";
+ }
+ return 1;
+}
+
+} // end namespace llvmc
diff --git a/lib/CompilerDriver/Makefile b/lib/CompilerDriver/Makefile
index e5bf3e1..a5ecfd5 100644
--- a/lib/CompilerDriver/Makefile
+++ b/lib/CompilerDriver/Makefile
@@ -12,8 +12,36 @@ LEVEL = ../..
# We don't want this library to appear in `llvm-config --libs` output, so its
# name doesn't start with "LLVM".
-LIBRARYNAME = CompilerDriver
-LINK_COMPONENTS = support system
+ifeq ($(ENABLE_LLVMC_DYNAMIC),1)
+ LIBRARYNAME = libCompilerDriver
+ LLVMLIBS = LLVMSupport.a LLVMSystem.a
+ LOADABLE_MODULE := 1
+else
+ LIBRARYNAME = CompilerDriver
+ LINK_COMPONENTS = support system
+endif
+
REQUIRES_EH := 1
include $(LEVEL)/Makefile.common
+
+ifeq ($(ENABLE_LLVMC_DYNAMIC_PLUGINS), 1)
+ CPP.Flags += -DENABLE_LLVMC_DYNAMIC_PLUGINS
+endif
+
+# Copy libCompilerDriver to the bin dir so that llvmc can find it.
+ifeq ($(ENABLE_LLVMC_DYNAMIC),1)
+
+FullLibName = $(LIBRARYNAME)$(SHLIBEXT)
+
+all-local:: $(ToolDir)/$(FullLibName)
+
+$(ToolDir)/$(FullLibName): $(LibDir)/$(FullLibName) $(ToolDir)/.dir
+ $(Echo) Copying $(BuildMode) Shared Library $(FullLibName) to $@
+ -$(Verb) $(CP) $< $@
+
+clean-local::
+ $(Echo) Removing $(BuildMode) Shared Library $(FullLibName) \
+ from $(ToolDir)
+ -$(Verb) $(RM) -f $(ToolDir)/$(FullLibName)
+endif
diff --git a/lib/CompilerDriver/Tool.cpp b/lib/CompilerDriver/Tool.cpp
index e704dd9..7953dd2 100644
--- a/lib/CompilerDriver/Tool.cpp
+++ b/lib/CompilerDriver/Tool.cpp
@@ -14,11 +14,17 @@
#include "llvm/CompilerDriver/BuiltinOptions.h"
#include "llvm/CompilerDriver/Tool.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/System/Path.h"
using namespace llvm;
using namespace llvmc;
+// SplitString is used by derived Tool classes.
+typedef void (*SplitStringFunPtr)(const std::string&,
+ std::vector<std::string>&, const char*);
+SplitStringFunPtr ForceLinkageSplitString = &llvm::SplitString;
+
namespace {
sys::Path MakeTempFile(const sys::Path& TempDir, const std::string& BaseName,
const std::string& Suffix) {
OpenPOWER on IntegriCloud