aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/Makefile2
-rw-r--r--tools/llvmc2/Common.td63
-rw-r--r--tools/llvmc2/Core.cpp115
-rw-r--r--tools/llvmc2/Core.h83
-rw-r--r--tools/llvmc2/Example.td24
-rw-r--r--tools/llvmc2/ExampleWithOpt.td24
-rw-r--r--tools/llvmc2/Makefile32
-rw-r--r--tools/llvmc2/Tools.cpp28
-rw-r--r--tools/llvmc2/Tools.h26
-rw-r--r--tools/llvmc2/Tools.td87
-rw-r--r--tools/llvmc2/Utility.cpp39
-rw-r--r--tools/llvmc2/Utility.h27
-rw-r--r--tools/llvmc2/doc/LLVMC-Enhancements.rst270
-rw-r--r--tools/llvmc2/doc/LLVMCC-Tutorial.rst153
-rw-r--r--tools/llvmc2/llvmcc.cpp73
15 files changed, 1045 insertions, 1 deletions
diff --git a/tools/Makefile b/tools/Makefile
index dc9ac44..d1491af 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -16,7 +16,7 @@ PARALLEL_DIRS := llvm-config \
llc llvm-ranlib llvm-ar llvm-nm \
llvm-ld llvmc llvm-prof llvm-link \
lli gccas gccld llvm-extract llvm-db llvm2cpp \
- bugpoint llvm-bcanalyzer llvm-stub
+ bugpoint llvm-bcanalyzer llvm-stub llvmc2
include $(LEVEL)/Makefile.config
diff --git a/tools/llvmc2/Common.td b/tools/llvmc2/Common.td
new file mode 100644
index 0000000..15b9264
--- /dev/null
+++ b/tools/llvmc2/Common.td
@@ -0,0 +1,63 @@
+//===- Tools.td - Common definitions for LLVMCC -----------*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains common definitions used in llvmcc tool description files.
+//
+//===----------------------------------------------------------------------===//
+
+class Tool<list<dag> l> {
+ list<dag> properties = l;
+}
+
+// Possible Tool properties
+
+def in_language;
+def out_language;
+def output_suffix;
+def cmd_line;
+def join;
+def sink;
+
+// Possible option types
+
+def switch_option;
+def parameter_option;
+def parameter_list_option;
+def prefix_option;
+def prefix_list_option;
+
+// Possible option properties
+
+def append_cmd;
+def forward;
+def stop_compilation;
+def unpack_values;
+def help;
+def required;
+
+// Map from suffixes to language names
+
+class LangToSuffixes<string str, list<string> lst> {
+ string lang = str;
+ list<string> suffixes = lst;
+}
+
+class LanguageMap<list<LangToSuffixes> lst> {
+ list<LangToSuffixes> map = lst;
+}
+
+// Toolchain classes
+
+class ToolChain <list<Tool> lst> {
+ list <Tool> tools = lst;
+}
+
+class ToolChains <list<ToolChain> lst> {
+ list<ToolChain> chains = lst;
+}
diff --git a/tools/llvmc2/Core.cpp b/tools/llvmc2/Core.cpp
new file mode 100644
index 0000000..d08ee7c
--- /dev/null
+++ b/tools/llvmc2/Core.cpp
@@ -0,0 +1,115 @@
+//===--- Core.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.
+//
+//===----------------------------------------------------------------------===//
+//
+// Core driver abstractions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Core.h"
+#include "Utility.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/CommandLine.h"
+
+#include <algorithm>
+#include <iostream>
+#include <stdexcept>
+
+using namespace llvm;
+using namespace llvmcc;
+
+extern cl::list<std::string> InputFilenames;
+extern cl::opt<std::string> OutputFilename;
+extern cl::opt<bool> VerboseMode;
+
+namespace {
+ void print_string (const std::string& str) {
+ std::cerr << str << ' ';
+ }
+}
+
+int llvmcc::Action::Execute() {
+ if (VerboseMode) {
+ std::cerr << Command_ << " ";
+ std::for_each(Args_.begin(), Args_.end(), print_string);
+ std::cerr << '\n';
+ }
+ return ExecuteProgram(Command_, Args_);
+}
+
+int llvmcc::CompilationGraph::Build (const sys::Path& tempDir) const {
+ sys::Path In(InputFilenames.at(0)), Out;
+
+ // Find out which language corresponds to the suffix of the first input file
+ LanguageMap::const_iterator Lang = ExtsToLangs.find(In.getSuffix());
+ if (Lang == ExtsToLangs.end())
+ throw std::runtime_error("Unknown suffix!");
+
+ // Find the toolchain corresponding to this language
+ ToolChainMap::const_iterator ToolsIt = ToolChains.find(Lang->second);
+ if (ToolsIt == ToolChains.end())
+ throw std::runtime_error("Unknown language!");
+ ToolChain Tools = ToolsIt->second;
+
+ PathVector JoinList;
+
+ for (cl::list<std::string>::const_iterator B = InputFilenames.begin(),
+ E = InputFilenames.end(); B != E; ++B) {
+ In = sys::Path(*B);
+
+ // Pass input file through the toolchain
+ for (ToolChain::const_iterator B = Tools.begin(), E = Tools.end();
+ B != E; ++B) {
+
+ const Tool* CurTool = B->getPtr();
+
+ // Is this the last step in the chain?
+ if (llvm::next(B) == E || CurTool->IsLast()) {
+ JoinList.push_back(In);
+ break;
+ }
+ else {
+ Out = tempDir;
+ Out.appendComponent(In.getBasename());
+ Out.appendSuffix(CurTool->OutputSuffix());
+ Out.makeUnique(true, NULL);
+ Out.eraseFromDisk();
+ }
+
+ if (CurTool->GenerateAction(In, Out).Execute() != 0)
+ throw std::runtime_error("Tool returned error code!");
+
+ In = Out; Out.clear();
+ }
+ }
+
+ // Pass .o files to linker
+ const Tool* JoinNode = (--Tools.end())->getPtr();
+
+ // If the final output name is empty, set it to "a.out"
+ if (!OutputFilename.empty()) {
+ Out = sys::Path(OutputFilename);
+ }
+ else {
+ Out = sys::Path("a");
+ Out.appendSuffix(JoinNode->OutputSuffix());
+ }
+
+ if (JoinNode->GenerateAction(JoinList, Out).Execute() != 0)
+ throw std::runtime_error("Tool returned error code!");
+
+ return 0;
+}
+
+void llvmcc::Tool::UnpackValues (const std::string& from,
+ std::vector<std::string>& to) const {
+ SplitString(from, to, ",");
+}
+
diff --git a/tools/llvmc2/Core.h b/tools/llvmc2/Core.h
new file mode 100644
index 0000000..f82e0fa9
--- /dev/null
+++ b/tools/llvmc2/Core.h
@@ -0,0 +1,83 @@
+//===--- Core.h - 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// Core driver abstractions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVMCC_CORE_H
+#define LLVM_TOOLS_LLVMCC_CORE_H
+
+#include "Utility.h"
+
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/System/Path.h"
+
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+// Core functionality
+
+namespace llvmcc {
+
+ typedef std::vector<llvm::sys::Path> PathVector;
+ typedef llvm::StringMap<std::string> LanguageMap;
+
+ class Action {
+ std::string Command_;
+ std::vector<std::string> Args_;
+ public:
+ Action (std::string const& C,
+ std::vector<std::string> const& A)
+ : Command_(C), Args_(A)
+ {}
+
+ int Execute();
+ };
+
+ class Tool : public llvm::RefCountedBaseVPTR<Tool> {
+ public:
+ virtual Action GenerateAction (PathVector const& inFiles,
+ llvm::sys::Path const& outFile) const = 0;
+
+ virtual Action GenerateAction (llvm::sys::Path const& inFile,
+ llvm::sys::Path const& outFile) const = 0;
+
+ virtual std::string Name() const = 0;
+ virtual std::string InputLanguage() const = 0;
+ virtual std::string OutputLanguage() const = 0;
+ virtual std::string OutputSuffix() const = 0;
+
+ virtual bool IsLast() const = 0;
+ virtual bool IsJoin() const = 0;
+
+ // Helper function that is called by the auto-generated code
+ // Splits strings of the form ",-foo,-bar,-baz"
+ // TOFIX: find a better name
+ void UnpackValues (std::string const& from,
+ std::vector<std::string>& to) const;
+
+ virtual ~Tool()
+ {}
+ };
+
+ typedef std::vector<llvm::IntrusiveRefCntPtr<Tool> > ToolChain;
+ typedef llvm::StringMap<ToolChain> ToolChainMap;
+
+ struct CompilationGraph {
+ ToolChainMap ToolChains;
+ LanguageMap ExtsToLangs;
+
+ int Build(llvm::sys::Path const& tempDir) const;
+ };
+}
+
+#endif // LLVM_TOOLS_LLVMCC_CORE_H
diff --git a/tools/llvmc2/Example.td b/tools/llvmc2/Example.td
new file mode 100644
index 0000000..68212c3
--- /dev/null
+++ b/tools/llvmc2/Example.td
@@ -0,0 +1,24 @@
+//===- Example.td - LLVMCC toolchain descriptions ---------*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains toolchain descriptions used by llvmcc.
+//
+//===----------------------------------------------------------------------===//
+
+include "Common.td"
+include "Tools.td"
+
+// Toolchains
+
+def ToolChains : ToolChains<[
+ ToolChain<[llvm_gcc_c, llc, llvm_gcc_assembler, llvm_gcc_linker]>,
+ ToolChain<[llvm_gcc_cpp, llc, llvm_gcc_assembler, llvm_gcc_linker]>,
+ ToolChain<[llvm_as, llc, llvm_gcc_assembler, llvm_gcc_linker]>,
+ ToolChain<[llvm_gcc_assembler, llvm_gcc_linker]>
+ ]>;
diff --git a/tools/llvmc2/ExampleWithOpt.td b/tools/llvmc2/ExampleWithOpt.td
new file mode 100644
index 0000000..9128d31
--- /dev/null
+++ b/tools/llvmc2/ExampleWithOpt.td
@@ -0,0 +1,24 @@
+//===- ExampleWithOpt.td - LLVMCC toolchain descriptions --*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains toolchain descriptions used by llvmcc.
+//
+//===----------------------------------------------------------------------===//
+
+include "Common.td"
+include "Tools.td"
+
+// Toolchains
+
+def ToolChains : ToolChains<[
+ ToolChain<[llvm_gcc_c, opt, llc, llvm_gcc_assembler, llvm_gcc_linker]>,
+ ToolChain<[llvm_gcc_cpp, opt, llc, llvm_gcc_assembler, llvm_gcc_linker]>,
+ ToolChain<[llvm_as, opt, llc, llvm_gcc_assembler, llvm_gcc_linker]>,
+ ToolChain<[llvm_gcc_assembler, llvm_gcc_linker]>
+ ]>;
diff --git a/tools/llvmc2/Makefile b/tools/llvmc2/Makefile
new file mode 100644
index 0000000..d0c1588
--- /dev/null
+++ b/tools/llvmc2/Makefile
@@ -0,0 +1,32 @@
+##===- tools/llvmcc/Makefile -------------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open
+# Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+LEVEL = ../..
+TOOLNAME = llvmc2
+BUILT_SOURCES = Tools.inc
+LINK_COMPONENTS = support system
+REQUIRES_EH := 1
+
+include $(LEVEL)/Makefile.common
+
+TOOLS_TARGET=default
+ifeq ($(TOOLS_TARGET), default)
+ TOOLS_SOURCE=Example.td
+else
+ TOOLS_SOURCE=ExampleWithOpt.td
+endif
+
+# TOFIX: integrate this part into Makefile.rules?
+# The degree of horrorshowness in that file is too much for me atm.
+$(ObjDir)/Tools.inc.tmp: $(TOOLS_SOURCE) $(ObjDir)/.dir
+ $(Echo) "Building LLVMCC configuration library with tblgen"
+ $(Verb) $(TableGen) -gen-llvmcc -o $@ $<
+
+Tools.inc : $(ObjDir)/Tools.inc.tmp
+ $(Verb) $(CMP) -s $@ $< || $(CP) $< $@
+
diff --git a/tools/llvmc2/Tools.cpp b/tools/llvmc2/Tools.cpp
new file mode 100644
index 0000000..7a9921c
--- /dev/null
+++ b/tools/llvmc2/Tools.cpp
@@ -0,0 +1,28 @@
+//===--- Tools.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.
+//
+//===----------------------------------------------------------------------===//
+//
+// Auto-generated tool descriptions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Tools.h"
+#include "Core.h"
+
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/Support/CommandLine.h"
+
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+using namespace llvm;
+using namespace llvmcc;
+
+// Include the auto-generated file
+#include "Tools.inc"
diff --git a/tools/llvmc2/Tools.h b/tools/llvmc2/Tools.h
new file mode 100644
index 0000000..ba8f06d
--- /dev/null
+++ b/tools/llvmc2/Tools.h
@@ -0,0 +1,26 @@
+//===--- Tools.h - 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// Auto-generated tool descriptions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVMCC_TOOLS_H
+#define LLVM_TOOLS_LLVMCC_TOOLS_H
+
+#include "Core.h"
+
+namespace llvmcc {
+
+ void PopulateLanguageMap(LanguageMap& language_map);
+ void PopulateCompilationGraph(CompilationGraph& tools);
+
+}
+
+#endif //LLVM_TOOLS_LLVMCC_TOOLS_H
diff --git a/tools/llvmc2/Tools.td b/tools/llvmc2/Tools.td
new file mode 100644
index 0000000..f69c290
--- /dev/null
+++ b/tools/llvmc2/Tools.td
@@ -0,0 +1,87 @@
+//===- Tools.td - Tools description for the LLVMCC --------*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains descriptions of the various build tools run by llvmcc.
+//
+//===----------------------------------------------------------------------===//
+
+// Open issue: should we use DAG lists in Tool specifications
+// or change to something like
+// def LLVMGccC : < Tool<
+// [ InLanguage<"c">,
+// PrefixListOption<"Wl", [UnpackValues, PropertyName<Arg>, ...]>
+// ...] ?
+// DAG lists look more aesthetically pleasing to me.
+
+def llvm_gcc_c : Tool<
+[(in_language "c"),
+ (out_language "llvm-assembler"),
+ (output_suffix "bc"),
+ (cmd_line "llvm-gcc -c $INFILE -o $OUTFILE -emit-llvm"),
+ (sink)
+]>;
+
+def llvm_gcc_cpp : Tool<
+[(in_language "c++"),
+ (out_language "llvm-assembler"),
+ (output_suffix "bc"),
+ (cmd_line "llvm-g++ -c $INFILE -o $OUTFILE -emit-llvm"),
+ (sink)
+]>;
+
+def opt : Tool<
+[(in_language "llvm-bitcode"),
+ (out_language "llvm-bitcode"),
+ (output_suffix "bc"),
+ (cmd_line "opt $INFILE -o $OUTFILE")
+]>;
+
+def llvm_as : Tool<
+[(in_language "llvm-assembler"),
+ (out_language "llvm-bitcode"),
+ (output_suffix "bc"),
+ (cmd_line "llvm-as $INFILE -o $OUTFILE")
+]>;
+
+def llc : Tool<
+[(in_language "llvm-bitcode"),
+ (out_language "assembler"),
+ (output_suffix "s"),
+ (cmd_line "llc $INFILE -o $OUTFILE")
+]>;
+
+def llvm_gcc_assembler : Tool<
+[(in_language "assembler"),
+ (out_language "object-code"),
+ (output_suffix "o"),
+ (cmd_line "llvm-gcc -c $INFILE -o $OUTFILE"),
+ (prefix_list_option "Wa", (unpack_values), (help "pass options to assembler"))
+]>;
+
+def llvm_gcc_linker : Tool<
+[(in_language "object-code"),
+ (out_language "executable"),
+ (output_suffix "out"),
+ (cmd_line "llvm-gcc $INFILE -o $OUTFILE"),
+ (join),
+ (prefix_list_option "L", (forward), (help "add a directory to link path")),
+ (prefix_list_option "l", (forward), (help "search a library when linking")),
+ (prefix_list_option "Wl", (unpack_values), (help "pass options to linker"))
+]>;
+
+// Language map
+
+def LanguageMap : LanguageMap<
+ [LangToSuffixes<"c++", ["cc", "cp", "cxx", "cpp", "CPP", "c++", "C"]>,
+ LangToSuffixes<"c", ["c"]>,
+ LangToSuffixes<"assembler", ["s"]>,
+ LangToSuffixes<"llvm-assembler", ["ll"]>,
+ LangToSuffixes<"llvm-bitcode", ["bc"]>,
+ LangToSuffixes<"object-code", ["o"]>,
+ LangToSuffixes<"executable", ["out"]>]>;
diff --git a/tools/llvmc2/Utility.cpp b/tools/llvmc2/Utility.cpp
new file mode 100644
index 0000000..c53578a
--- /dev/null
+++ b/tools/llvmc2/Utility.cpp
@@ -0,0 +1,39 @@
+//===--- Utility.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.
+//
+//===----------------------------------------------------------------------===//
+//
+// Various helper and utility functions - implementation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Utility.h"
+
+#include "llvm/System/Program.h"
+
+#include <stdexcept>
+
+using namespace llvm;
+
+int llvmcc::ExecuteProgram(const std::string& name,
+ const std::vector<std::string>& args) {
+ sys::Path prog = sys::Program::FindProgramByName(name);
+
+ if (prog.isEmpty())
+ throw std::runtime_error("Can't find program '" + name + "'");
+ if (!prog.canExecute())
+ throw std::runtime_error("Program '" + name + "' is not executable.");
+
+ // Invoke the program
+ std::vector<const char*> argv((args.size()+2));
+ argv[0] = name.c_str();
+ for (unsigned i = 1; i <= args.size(); ++i)
+ argv[i] = args[i-1].c_str();
+ argv[args.size()+1] = 0; // null terminate list.
+
+ return sys::Program::ExecuteAndWait(prog, &argv[0]);
+}
diff --git a/tools/llvmc2/Utility.h b/tools/llvmc2/Utility.h
new file mode 100644
index 0000000..3c985a4
--- /dev/null
+++ b/tools/llvmc2/Utility.h
@@ -0,0 +1,27 @@
+//===--- Utility.h - 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// Various helper and utility functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVMCC_UTILITY_H
+#define LLVM_TOOLS_LLVMCC_UTILITY_H
+
+#include <string>
+#include <vector>
+
+namespace llvmcc {
+
+ int ExecuteProgram (const std::string& name,
+ const std::vector<std::string>& arguments);
+
+}
+
+#endif // LLVM_TOOLS_LLVMCC_UTILITY_H
diff --git a/tools/llvmc2/doc/LLVMC-Enhancements.rst b/tools/llvmc2/doc/LLVMC-Enhancements.rst
new file mode 100644
index 0000000..a831ea0
--- /dev/null
+++ b/tools/llvmc2/doc/LLVMC-Enhancements.rst
@@ -0,0 +1,270 @@
+Introduction
+============
+
+A complete rewrite of the LLVMC compiler driver is proposed, aimed at
+making it more configurable and useful.
+
+Motivation
+==========
+
+As it stands, current version of LLVMC does not meet its stated goals
+of configurability and extensibility and is therefore not used
+much. The need for enhancements in LLVMC is also reflected in [1]_. The
+proposed rewrite will fix the aforementioned deficiences and provide
+an extensible, future-proof solution.
+
+Design
+======
+
+A compiler driver's job is essentially to find a way how to transform
+a set of input files into a set of targets, depending on the
+user-provided options. Since several ways of transformation can exist
+potentially, it's natural to use a directed graph to represent all of
+them. In this graph, nodes are tools (for example, ``gcc -S`` is a tool
+that generates assembly from C language files) and edges between them
+mean that the output of one tool can be given as input to another (as
+in ``gcc -S -o - file.c | as``). We'll call this graph the compilation
+graph.
+
+The proposed design revolves around the compilation graph and the
+following core abstractions:
+
+- Target - An (intermediate) compilation target.
+
+- Action - A shell command template that represents basic compilation
+ transformation(example: ``gcc -S $INPUT_FILE -o $OUTPUT_FILE``).
+
+- Tool - Encapsulates information about a concrete tool used in the
+ compilation process, produces Actions. Operation depends on
+ command-line options provided by the user.
+
+- GraphBuilder - Constructs the compilation graph, operation depends
+ on command-line options.
+
+- GraphTraverser - Traverses the compilation graph and constructs a
+ sequence of Actions needed to build the target file, operation
+ depends on command-line options.
+
+A high-level view of the compilation process:
+
+ 1. Configuration libraries (see below) are loaded in and the
+ compilation graph is constructed from the tool descriptions.
+
+ 2. Information about possible options is gathered from (the nodes of)
+ the compilation graph.
+
+ 3. Options are parsed based on data gathered in step 2.
+
+ 4. A sequence of Actions needed to build the target is constructed
+ using the compilation graph and provided options.
+
+ 5. The resulting action sequence is executed.
+
+Extensibility
+==============
+
+To make this design extensible, TableGen [2]_ will be used for
+automatic generation of the Tool classes. Users wanting to customize
+LLVMC will need to write a configuration library consisting of a set
+of TableGen descriptions of compilation tools plus a number of hooks
+that influence compilation graph construction and traversal. LLVMC
+will have the ability to load user configuration libraries at runtime;
+in fact, its own basic functionality will be implemented as a
+configuration library.
+
+TableGen specification example
+------------------------------
+
+This small example specifies a Tool that converts C source to object
+files. Note that it is only a mock-up of inteded functionality, not a
+final specification::
+
+ def GCC : Tool<
+ GCCProperties, // Properties of this tool
+ GCCOptions // Options description for this tool
+ >;
+
+ def GCCProperties : ToolProperties<[
+ ToolName<"GCC">,
+ InputLanguageName<"C">,
+ OutputLanguageName<"Object-Code">
+ InputFileExtension<"c">,
+ OutputFileExtension<"o">,
+ CommandFormat<"gcc -c $OPTIONS $FILES">
+ ]>;
+
+ def GCCOptions : ToolOptions<[
+ Option<
+ "-Wall", // Option name
+ [None], // Allowed values
+ [AddOption<"-Wall">]>, // Action
+
+ Option<
+ "-Wextra", // Option name
+ [None], // Allowed values
+ [AddOption<"-Wextra">]>, // Action
+
+ Option<
+ "-W", // Option name
+ [None], // Allowed values
+ [AddOption<"-W">]>, // Action
+
+ Option<
+ "-D", // Option name
+ [AnyString], // Allowed values
+
+ [AddOptionWithArgument<"-D",GetOptionArgument<"-D">>]
+ // Action:
+ // If the driver was given option "-D<argument>", add
+ // option "-D" with the same argument to the invocation string of
+ // this tool.
+ >
+
+ ]>;
+
+Example of generated code
+-------------------------
+
+The specification above compiles to the following code (again, it's a
+mock-up)::
+
+ class GCC : public Tool {
+
+ public:
+
+ GCC() { //... }
+
+ // Properties
+
+ static const char* ToolName = "GCC";
+ static const char* InputLanguageName = "C";
+ static const char* OutputLanguageName = "Object-Code";
+ static const char* InputFileExtension = "c";
+ static const char* OutputFileExtension = "o";
+ static const char* CommandFormat = "gcc -c $OPTIONS $FILES";
+
+ // Options
+
+ OptionsDescription SupportedOptions() {
+ OptionsDescription supportedOptions;
+
+ supportedOptions.Add(Option("-Wall"));
+ supportedOptions.Add(Option("-Wextra"));
+ supportedOptions.Add(Option("-W"));
+ supportedOptions.Add(Option("-D", AllowedArgs::ANY_STRING));
+
+ return supportedOptions;
+ }
+
+ Action GenerateAction(Options providedOptions) {
+ Action generatedAction(CommandFormat); Option curOpt;
+
+ curOpt = providedOptions.Get("-D");
+ if (curOpt) {
+ assert(curOpt.HasArgument());
+ generatedAction.AddOption(Option("-D", curOpt.GetArgument()));
+ }
+
+ curOpt = providedOptions.Get("-Wall");
+ if (curOpt)
+ generatedAction.AddOption(Option("-Wall"));
+
+ curOpt = providedOptions.Get("-Wextra");
+ if (curOpt)
+ generatedAction.AddOption(Option("-Wall"));
+
+ curOpt = providedOptions.Get("-W");
+ if (curOpt)
+ generatedAction.AddOption(Option("-Wall")); }
+
+ return generatedAction;
+ }
+
+ };
+
+ // defined somewhere...
+
+ class Action { public: void AddOption(const Option& opt) {...}
+ int Run(const Filenames& fnms) {...}
+
+ }
+
+Option handling
+===============
+
+Since one of the main tasks of the compiler driver is to correctly
+handle user-provided options, it is important to define this process
+in exact way. The intent of the proposed scheme is to function as a
+drop-in replacement for GCC.
+
+Option syntax
+-------------
+
+Option syntax is specified by the following formal grammar::
+
+ <command-line> ::= <option>*
+ <option> ::= <positional-option> | <named-option>
+ <named-option> ::= -[-]<option-name>[<delimeter><option-argument>]
+ <delimeter> ::= ',' | '=' | ' '
+ <positional-option> ::= <string>
+ <option-name> ::= <string>
+ <option-argument> ::= <string>
+
+This roughly corresponds to the GCC option syntax. Note that grouping
+of short options(as in ``ls -la``) is forbidden.
+
+Example::
+
+ llvmc -O3 -Wa,-foo,-bar -pedantic -std=c++0x a.c b.c c.c
+
+Option arguments can also have special forms: for example, an argument
+can be a comma-separated list (like in -Wa,-foo,-bar). In such cases,
+it's up to the option handler to parse the argument.
+
+Option semantics
+----------------
+
+According to their meaning, options are classified into following
+categories:
+
+- Global options - Options that influence compilation graph
+ construction/traversal. Example: -E (stop after preprocessing).
+
+- Local options - Options that influence one or several Actions in
+ the generated action sequence. Example: -O3 (turn on optimization).
+
+- Prefix options - Options that influence meaning of the following
+ command-line arguments. Example: -x language (specify language for
+ the input files explicitly). Prefix options can be local or global.
+
+- Built-in options - Options that are hard-coded into
+ driver. Examples: --help, -o file/-pipe (redirect output). Can be
+ local or global.
+
+Naming
+======
+
+Since the compiler driver, as a single point of access to the LLVM
+tool set, is a very often used tool, it would be desirable to make its name
+as short and easy to type as possible. Some possible names are 'llcc' or
+'lcc', by analogy with gcc.
+
+
+Issues
+======
+
+1. Should global-options-influencing hooks be written by hand or
+ auto-generated from TableGen specifications?
+
+2. More?
+
+References
+==========
+
+.. [1] LLVM Bug#686
+
+ http://llvm.org/bugs/show_bug.cgi?id=686
+
+.. [2] TableGen Fundamentals
+
+ http://llvm.org/docs/TableGenFundamentals.html
diff --git a/tools/llvmc2/doc/LLVMCC-Tutorial.rst b/tools/llvmc2/doc/LLVMCC-Tutorial.rst
new file mode 100644
index 0000000..8374cad
--- /dev/null
+++ b/tools/llvmc2/doc/LLVMCC-Tutorial.rst
@@ -0,0 +1,153 @@
+Tutorial - Writing LLVMCC Configuration files
+=============================================
+
+LLVMCC is a generic compiler driver(just like ``gcc``), designed to be
+customizable and extensible. Its job is essentially to transform a set
+of input files into a set of targets, depending on configuration rules
+and user options. This tutorial describes how one can write
+configuration files for ``llvmcc``.
+
+Since LLVMCC uses TableGen [1]_ as the language of its configuration
+files, you need to be familiar with it.
+
+Describing a toolchain
+----------------------
+
+The main concept that ``llvmcc`` operates with is a *toolchain*, which
+is just a list of tools that process input files in a pipeline-like
+fashion. Toolchain definitions look like this::
+
+ def ToolChains : ToolChains<[
+ ToolChain<[llvm_gcc_c, llc, llvm_gcc_assembler, llvm_gcc_linker]>,
+ ToolChain<[llvm_gcc_cpp, llc, llvm_gcc_assembler, llvm_gcc_linker]>,
+ ...
+ ]>;
+
+Every configuration file should have a single toolchains list called
+``ToolChains``.
+
+At the time of writing, ``llvmcc`` does not support mixing various
+toolchains together - in other words, all input files should be in the
+same language.
+
+Another temporary limitation is that every toolchain should end with a
+"join" node - a linker-like program that combines its inputs into a
+single output file.
+
+Describing a tool
+-----------------
+
+A single element of a toolchain is a tool. A tool definition looks
+like this (taken from the Tools.td file)::
+
+ def llvm_gcc_cpp : Tool<[
+ (in_language "c++"),
+ (out_language "llvm-assembler"),
+ (output_suffix "bc"),
+ (cmd_line "llvm-g++ -c $INFILE -o $OUTFILE -emit-llvm"),
+ (sink)
+ ]>;
+
+This defines a new tool called ``llvm_gcc_cpp``, which is an alias for
+``llvm-g++``. As you can see, a tool definition is just a list of
+properties; most of them should be self-evident. The ``sink`` property
+means that this tool should be passed all command-line options that
+aren't handled by the other tools.
+
+The complete list of the currently implemented tool properties follows:
+
+* Possible tool properties:
+ - in_language - input language name.
+
+ - out_language - output language name.
+
+ - output_suffix - output file suffix.
+
+ - cmd_line - the actual command used to run the tool. You can use
+ ``$INFILE`` and ``$OUTFILE`` variables.
+
+ - join - this tool is a "join node" in the graph, i.e. it gets a
+ list of input files and joins them together. Used for linkers.
+
+ - sink - all command-line options that are not handled by other
+ tools are passed to this tool.
+
+The next tool definition is slightly more complex::
+
+ def llvm_gcc_linker : Tool<[
+ (in_language "object-code"),
+ (out_language "executable"),
+ (output_suffix "out"),
+ (cmd_line "llvm-gcc $INFILE -o $OUTFILE"),
+ (join),
+ (prefix_list_option "L", (forward), (help "add a directory to link path")),
+ (prefix_list_option "l", (forward), (help "search a library when linking")),
+ (prefix_list_option "Wl", (unpack_values), (help "pass options to linker"))
+ ]>;
+
+This tool has a "join" property, which means that it behaves like a
+linker (because of that this tool should be the last in the
+toolchain). This tool also defines several command-line options: ``-l``,
+``-L`` and ``-Wl`` which have their usual meaning. An option has two
+attributes: a name and a (possibly empty) list of properties. All
+currently implemented option types and properties are described below:
+
+* Possible option types:
+ - switch_option - a simple boolean switch, for example ``-time``.
+
+ - parameter_option - option that takes an argument, for example ``-std=c99``;
+
+ - parameter_list_option - same as the above, but more than one
+ occurence of the option is allowed.
+
+ - prefix_option - same as the parameter_option, but the option name
+ and parameter value are not separated.
+
+ - prefix_list_option - same as the above, but more than one
+ occurence of the option is allowed; example: ``-lm -lpthread``.
+
+* Possible option properties:
+ - append_cmd - append a string to the tool invocation command.
+
+ - forward - forward this option unchanged.
+
+ - stop_compilation - stop compilation after this phase.
+
+ - unpack_values - used for for splitting and forwarding
+ comma-separated lists of options, e.g. ``-Wa,-foo=bar,-baz`` is
+ converted to ``-foo=bar -baz`` and appended to the tool invocation
+ command.
+
+ - help - help string associated with this option.
+
+ - required - this option is obligatory.
+
+Language map
+------------
+
+One last bit that you probably should change is the language map,
+which defines mappings between language names and file extensions. It
+is used internally to choose the proper toolchain based on the names
+of the input files. Language map definition is located in the file
+``Tools.td`` and looks like this::
+
+ def LanguageMap : LanguageMap<
+ [LangToSuffixes<"c++", ["cc", "cp", "cxx", "cpp", "CPP", "c++", "C"]>,
+ LangToSuffixes<"c", ["c"]>,
+ ...
+ ]>;
+
+
+Putting it all together
+-----------------------
+
+Since at the time of writing LLVMCC does not support on-the-fly
+reloading of the configuration, the only way to test your changes is
+to recompile the program. To do this, ``cd`` to the source code
+directory and run ``make``.
+
+References
+==========
+
+.. [1] TableGen Fundamentals
+ http://llvm.cs.uiuc.edu/docs/TableGenFundamentals.html
diff --git a/tools/llvmc2/llvmcc.cpp b/tools/llvmc2/llvmcc.cpp
new file mode 100644
index 0000000..c5edac9
--- /dev/null
+++ b/tools/llvmc2/llvmcc.cpp
@@ -0,0 +1,73 @@
+//===--- llvmcc.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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tool provides a single point of access to the LLVM
+// compilation tools. It has many options. To discover the options
+// supported please refer to the tools' manual page or run the tool
+// with the --help option.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Core.h"
+#include "Utility.h"
+#include "Tools.h"
+
+#include "llvm/System/Path.h"
+#include "llvm/Support/CommandLine.h"
+
+#include <iostream>
+#include <stdexcept>
+#include <string>
+
+using namespace llvm;
+using namespace llvmcc;
+
+// These variables are also used in Core.cpp,
+// so they should have external linkage.
+cl::list<std::string> InputFilenames(cl::Positional,
+ cl::desc("<input file>"), cl::OneOrMore);
+cl::opt<std::string> OutputFilename("o", cl::desc("Output file name"),
+ cl::value_desc("file"));
+cl::opt<bool> VerboseMode("v", cl::desc("Enable verbose mode"));
+
+
+namespace {
+ int BuildTargets(const CompilationGraph& graph) {
+ int ret;
+ sys::Path tempDir(sys::Path::GetTemporaryDirectory());
+
+ try {
+ ret = graph.Build(tempDir);
+ }
+ catch(...) {
+ tempDir.eraseFromDisk(true);
+ throw;
+ }
+
+ tempDir.eraseFromDisk(true);
+ return ret;
+ }
+}
+
+int main(int argc, char** argv) {
+ try {
+ CompilationGraph graph;
+
+ cl::ParseCommandLineOptions(argc, argv,
+ "LLVM Compiler Driver(Work In Progress)");
+ PopulateCompilationGraph(graph);
+ return BuildTargets(graph);
+ }
+ catch(const std::exception& ex) {
+ std::cerr << ex.what() << '\n';
+ }
+ catch(...) {
+ std::cerr << "Unknown error!\n";
+ }
+}