aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2008-03-23 08:57:20 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2008-03-23 08:57:20 +0000
commitac67b7ea8fcd530995d7aefd2ad0f04543789855 (patch)
treeed9601b834e843e454707c7b07595ce91e27acbd /tools
parentd59c517a8309faac030d98b37459ca18a204da5a (diff)
downloadexternal_llvm-ac67b7ea8fcd530995d7aefd2ad0f04543789855.zip
external_llvm-ac67b7ea8fcd530995d7aefd2ad0f04543789855.tar.gz
external_llvm-ac67b7ea8fcd530995d7aefd2ad0f04543789855.tar.bz2
Add first proof-of-concept universal compiler driver framework based
on ideas mentioned in PR686. Written by Mikhail Glushenkov and contributed by Codedgers, Inc. Old llvmc will be removed soon after new one will have all its properties. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48699 91177308-0d34-0410-b5e6-96231b3b80d8
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";
+ }
+}