summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/llvmc
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/llvmc')
-rw-r--r--contrib/llvm/tools/llvmc/CMakeLists.txt4
-rw-r--r--contrib/llvm/tools/llvmc/Makefile18
-rw-r--r--contrib/llvm/tools/llvmc/doc/LLVMC-Reference.rst832
-rw-r--r--contrib/llvm/tools/llvmc/doc/LLVMC-Tutorial.rst129
-rw-r--r--contrib/llvm/tools/llvmc/doc/Makefile33
-rw-r--r--contrib/llvm/tools/llvmc/doc/img/lines.gifbin0 -> 91 bytes
-rw-r--r--contrib/llvm/tools/llvmc/driver/Main.cpp14
-rw-r--r--contrib/llvm/tools/llvmc/driver/Makefile13
-rw-r--r--contrib/llvm/tools/llvmc/example/Hello/Hello.cpp33
-rw-r--r--contrib/llvm/tools/llvmc/example/Hello/Makefile14
-rw-r--r--contrib/llvm/tools/llvmc/example/Simple/Makefile15
-rw-r--r--contrib/llvm/tools/llvmc/example/Simple/PluginMain.cpp1
-rw-r--r--contrib/llvm/tools/llvmc/example/Simple/Simple.td37
-rw-r--r--contrib/llvm/tools/llvmc/example/Skeleton/Makefile24
-rw-r--r--contrib/llvm/tools/llvmc/example/Skeleton/README6
-rw-r--r--contrib/llvm/tools/llvmc/example/Skeleton/driver/Main.cpp14
-rw-r--r--contrib/llvm/tools/llvmc/example/Skeleton/driver/Makefile13
-rw-r--r--contrib/llvm/tools/llvmc/example/Skeleton/plugins/Makefile18
-rw-r--r--contrib/llvm/tools/llvmc/example/Skeleton/plugins/Plugin/Makefile17
-rw-r--r--contrib/llvm/tools/llvmc/example/Skeleton/plugins/Plugin/Plugin.td7
-rw-r--r--contrib/llvm/tools/llvmc/example/Skeleton/plugins/Plugin/PluginMain.cpp1
-rw-r--r--contrib/llvm/tools/llvmc/example/mcc16/Makefile18
-rw-r--r--contrib/llvm/tools/llvmc/example/mcc16/README75
-rw-r--r--contrib/llvm/tools/llvmc/example/mcc16/driver/Main.cpp54
-rw-r--r--contrib/llvm/tools/llvmc/example/mcc16/driver/Makefile13
-rw-r--r--contrib/llvm/tools/llvmc/example/mcc16/plugins/Makefile18
-rw-r--r--contrib/llvm/tools/llvmc/example/mcc16/plugins/PIC16Base/Makefile17
-rw-r--r--contrib/llvm/tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td234
-rw-r--r--contrib/llvm/tools/llvmc/example/mcc16/plugins/PIC16Base/PluginMain.cpp106
-rw-r--r--contrib/llvm/tools/llvmc/plugins/Base/Base.td.in373
-rw-r--r--contrib/llvm/tools/llvmc/plugins/Base/Hooks.cpp33
-rw-r--r--contrib/llvm/tools/llvmc/plugins/Base/Makefile15
-rw-r--r--contrib/llvm/tools/llvmc/plugins/Base/PluginMain.cpp1
-rw-r--r--contrib/llvm/tools/llvmc/plugins/Clang/Clang.td101
-rw-r--r--contrib/llvm/tools/llvmc/plugins/Clang/Makefile15
-rw-r--r--contrib/llvm/tools/llvmc/plugins/Clang/PluginMain.cpp1
-rw-r--r--contrib/llvm/tools/llvmc/plugins/Makefile18
37 files changed, 2335 insertions, 0 deletions
diff --git a/contrib/llvm/tools/llvmc/CMakeLists.txt b/contrib/llvm/tools/llvmc/CMakeLists.txt
new file mode 100644
index 0000000..bebaaeb
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/CMakeLists.txt
@@ -0,0 +1,4 @@
+# add_subdirectory(driver)
+
+# TODO: support plugins and user-configured builds.
+# See ./doc/LLVMC-Reference.rst "Customizing LLVMC: the compilation graph"
diff --git a/contrib/llvm/tools/llvmc/Makefile b/contrib/llvm/tools/llvmc/Makefile
new file mode 100644
index 0000000..8f99526
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/Makefile
@@ -0,0 +1,18 @@
+##===- tools/llvmc/Makefile --------------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open
+# Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+
+export LLVMC_BASED_DRIVER_NAME = llvmc
+export LLVMC_BUILTIN_PLUGINS = Base Clang
+REQUIRES_RTTI = 1
+
+DIRS = plugins driver
+
+include $(LEVEL)/Makefile.common
diff --git a/contrib/llvm/tools/llvmc/doc/LLVMC-Reference.rst b/contrib/llvm/tools/llvmc/doc/LLVMC-Reference.rst
new file mode 100644
index 0000000..ca8500d
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/doc/LLVMC-Reference.rst
@@ -0,0 +1,832 @@
+===================================
+Customizing LLVMC: Reference Manual
+===================================
+..
+ This file was automatically generated by rst2html.
+ Please do not edit directly!
+ The ReST source lives in the directory 'tools/llvmc/doc'.
+
+.. contents::
+
+.. raw:: html
+
+ <div class="doc_author">
+ <p>Written by <a href="mailto:foldr@codedgers.com">Mikhail Glushenkov</a></p>
+ </div>
+
+Introduction
+============
+
+LLVMC is a generic compiler driver, designed to be customizable and
+extensible. It plays the same role for LLVM as the ``gcc`` program
+does for GCC - LLVMC's job is essentially to transform a set of input
+files into a set of targets depending on configuration rules and user
+options. What makes LLVMC different is that these transformation rules
+are completely customizable - in fact, LLVMC knows nothing about the
+specifics of transformation (even the command-line options are mostly
+not hard-coded) and regards the transformation structure as an
+abstract graph. The structure of this graph is completely determined
+by plugins, which can be either statically or dynamically linked. This
+makes it possible to easily adapt LLVMC for other purposes - for
+example, as a build tool for game resources.
+
+Because LLVMC employs TableGen_ as its configuration language, you
+need to be familiar with it to customize LLVMC.
+
+.. _TableGen: http://llvm.org/docs/TableGenFundamentals.html
+
+
+Compiling with LLVMC
+====================
+
+LLVMC tries hard to be as compatible with ``gcc`` as possible,
+although there are some small differences. Most of the time, however,
+you shouldn't be able to notice them::
+
+ $ # This works as expected:
+ $ llvmc -O3 -Wall hello.cpp
+ $ ./a.out
+ hello
+
+One nice feature of LLVMC is that one doesn't have to distinguish between
+different compilers for different languages (think ``g++`` vs. ``gcc``) - the
+right toolchain is chosen automatically based on input language names (which
+are, in turn, determined from file extensions). If you want to force files
+ending with ".c" to compile as C++, use the ``-x`` option, just like you would
+do it with ``gcc``::
+
+ $ # hello.c is really a C++ file
+ $ llvmc -x c++ hello.c
+ $ ./a.out
+ hello
+
+On the other hand, when using LLVMC as a linker to combine several C++
+object files you should provide the ``--linker`` option since it's
+impossible for LLVMC to choose the right linker in that case::
+
+ $ llvmc -c hello.cpp
+ $ llvmc hello.o
+ [A lot of link-time errors skipped]
+ $ llvmc --linker=c++ hello.o
+ $ ./a.out
+ hello
+
+By default, LLVMC uses ``llvm-gcc`` to compile the source code. It is also
+possible to choose the ``clang`` compiler with the ``-clang`` option.
+
+
+Predefined options
+==================
+
+LLVMC has some built-in options that can't be overridden in the
+configuration libraries:
+
+* ``-o FILE`` - Output file name.
+
+* ``-x LANGUAGE`` - Specify the language of the following input files
+ until the next -x option.
+
+* ``-load PLUGIN_NAME`` - Load the specified plugin DLL. Example:
+ ``-load $LLVM_DIR/Release/lib/LLVMCSimple.so``.
+
+* ``-v`` - Enable verbose mode, i.e. print out all executed commands.
+
+* ``--save-temps`` - Write temporary files to the current directory and do not
+ delete them on exit. This option can also take an argument: the
+ ``--save-temps=obj`` switch will write files into the directory specified with
+ the ``-o`` option. The ``--save-temps=cwd`` and ``--save-temps`` switches are
+ both synonyms for the default behaviour.
+
+* ``--temp-dir DIRECTORY`` - Store temporary files in the given directory. This
+ directory is deleted on exit unless ``--save-temps`` is specified. If
+ ``--save-temps=obj`` is also specified, ``--temp-dir`` is given the
+ precedence.
+
+* ``--check-graph`` - Check the compilation for common errors like mismatched
+ output/input language names, multiple default edges and cycles. Because of
+ plugins, these checks can't be performed at compile-time. Exit with code zero
+ if no errors were found, and return the number of found errors
+ otherwise. Hidden option, useful for debugging LLVMC plugins.
+
+* ``--view-graph`` - Show a graphical representation of the compilation graph
+ and exit. Requires that you have ``dot`` and ``gv`` programs installed. Hidden
+ option, useful for debugging LLVMC plugins.
+
+* ``--write-graph`` - Write a ``compilation-graph.dot`` file in the current
+ directory with the compilation graph description in Graphviz format (identical
+ to the file used by the ``--view-graph`` option). The ``-o`` option can be
+ used to set the output file name. Hidden option, useful for debugging LLVMC
+ plugins.
+
+* ``--help``, ``--help-hidden``, ``--version`` - These options have
+ their standard meaning.
+
+Compiling LLVMC plugins
+=======================
+
+It's easiest to start working on your own LLVMC plugin by copying the
+skeleton project which lives under ``$LLVMC_DIR/plugins/Simple``::
+
+ $ cd $LLVMC_DIR/plugins
+ $ cp -r Simple MyPlugin
+ $ cd MyPlugin
+ $ ls
+ Makefile PluginMain.cpp Simple.td
+
+As you can see, our basic plugin consists of only two files (not
+counting the build script). ``Simple.td`` contains TableGen
+description of the compilation graph; its format is documented in the
+following sections. ``PluginMain.cpp`` is just a helper file used to
+compile the auto-generated C++ code produced from TableGen source. It
+can also contain hook definitions (see `below`__).
+
+__ hooks_
+
+The first thing that you should do is to change the ``LLVMC_PLUGIN``
+variable in the ``Makefile`` to avoid conflicts (since this variable
+is used to name the resulting library)::
+
+ LLVMC_PLUGIN=MyPlugin
+
+It is also a good idea to rename ``Simple.td`` to something less
+generic::
+
+ $ mv Simple.td MyPlugin.td
+
+To build your plugin as a dynamic library, just ``cd`` to its source
+directory and run ``make``. The resulting file will be called
+``plugin_llvmc_$(LLVMC_PLUGIN).$(DLL_EXTENSION)`` (in our case,
+``plugin_llvmc_MyPlugin.so``). This library can be then loaded in with the
+``-load`` option. Example::
+
+ $ cd $LLVMC_DIR/plugins/Simple
+ $ make
+ $ llvmc -load $LLVM_DIR/Release/lib/plugin_llvmc_Simple.so
+
+Compiling standalone LLVMC-based drivers
+========================================
+
+By default, the ``llvmc`` executable consists of a driver core plus several
+statically linked plugins (``Base`` and ``Clang`` at the moment). You can
+produce a standalone LLVMC-based driver executable by linking the core with your
+own plugins. The recommended way to do this is by starting with the provided
+``Skeleton`` example (``$LLVMC_DIR/example/Skeleton``)::
+
+ $ cd $LLVMC_DIR/example/
+ $ cp -r Skeleton mydriver
+ $ cd mydriver
+ $ vim Makefile
+ [...]
+ $ make
+
+If you're compiling LLVM with different source and object directories, then you
+must perform the following additional steps before running ``make``::
+
+ # LLVMC_SRC_DIR = $LLVM_SRC_DIR/tools/llvmc/
+ # LLVMC_OBJ_DIR = $LLVM_OBJ_DIR/tools/llvmc/
+ $ cp $LLVMC_SRC_DIR/example/mydriver/Makefile \
+ $LLVMC_OBJ_DIR/example/mydriver/
+ $ cd $LLVMC_OBJ_DIR/example/mydriver
+ $ make
+
+Another way to do the same thing is by using the following command::
+
+ $ cd $LLVMC_DIR
+ $ make LLVMC_BUILTIN_PLUGINS=MyPlugin LLVMC_BASED_DRIVER_NAME=mydriver
+
+This works with both srcdir == objdir and srcdir != objdir, but assumes that the
+plugin source directory was placed under ``$LLVMC_DIR/plugins``.
+
+Sometimes, you will want a 'bare-bones' version of LLVMC that has no
+built-in plugins. It can be compiled with the following command::
+
+ $ cd $LLVMC_DIR
+ $ make LLVMC_BUILTIN_PLUGINS=""
+
+
+Customizing LLVMC: the compilation graph
+========================================
+
+Each TableGen configuration file should include the common
+definitions::
+
+ include "llvm/CompilerDriver/Common.td"
+
+Internally, LLVMC stores information about possible source
+transformations in form of a graph. Nodes in this graph represent
+tools, and edges between two nodes represent a transformation path. A
+special "root" node is used to mark entry points for the
+transformations. LLVMC also assigns a weight to each edge (more on
+this later) to choose between several alternative edges.
+
+The definition of the compilation graph (see file
+``plugins/Base/Base.td`` for an example) is just a list of edges::
+
+ def CompilationGraph : CompilationGraph<[
+ Edge<"root", "llvm_gcc_c">,
+ Edge<"root", "llvm_gcc_assembler">,
+ ...
+
+ Edge<"llvm_gcc_c", "llc">,
+ Edge<"llvm_gcc_cpp", "llc">,
+ ...
+
+ OptionalEdge<"llvm_gcc_c", "opt", (case (switch_on "opt"),
+ (inc_weight))>,
+ OptionalEdge<"llvm_gcc_cpp", "opt", (case (switch_on "opt"),
+ (inc_weight))>,
+ ...
+
+ OptionalEdge<"llvm_gcc_assembler", "llvm_gcc_cpp_linker",
+ (case (input_languages_contain "c++"), (inc_weight),
+ (or (parameter_equals "linker", "g++"),
+ (parameter_equals "linker", "c++")), (inc_weight))>,
+ ...
+
+ ]>;
+
+As you can see, the edges can be either default or optional, where
+optional edges are differentiated by an additional ``case`` expression
+used to calculate the weight of this edge. Notice also that we refer
+to tools via their names (as strings). This makes it possible to add
+edges to an existing compilation graph in plugins without having to
+know about all tool definitions used in the graph.
+
+The default edges are assigned a weight of 1, and optional edges get a
+weight of 0 + 2*N where N is the number of tests that evaluated to
+true in the ``case`` expression. It is also possible to provide an
+integer parameter to ``inc_weight`` and ``dec_weight`` - in this case,
+the weight is increased (or decreased) by the provided value instead
+of the default 2. It is also possible to change the default weight of
+an optional edge by using the ``default`` clause of the ``case``
+construct.
+
+When passing an input file through the graph, LLVMC picks the edge
+with the maximum weight. To avoid ambiguity, there should be only one
+default edge between two nodes (with the exception of the root node,
+which gets a special treatment - there you are allowed to specify one
+default edge *per language*).
+
+When multiple plugins are loaded, their compilation graphs are merged
+together. Since multiple edges that have the same end nodes are not
+allowed (i.e. the graph is not a multigraph), an edge defined in
+several plugins will be replaced by the definition from the plugin
+that was loaded last. Plugin load order can be controlled by using the
+plugin priority feature described above.
+
+To get a visual representation of the compilation graph (useful for
+debugging), run ``llvmc --view-graph``. You will need ``dot`` and
+``gsview`` installed for this to work properly.
+
+Describing options
+==================
+
+Command-line options that the plugin supports are defined by using an
+``OptionList``::
+
+ def Options : OptionList<[
+ (switch_option "E", (help "Help string")),
+ (alias_option "quiet", "q")
+ ...
+ ]>;
+
+As you can see, the option list is just a list of DAGs, where each DAG
+is an option description consisting of the option name and some
+properties. A plugin can define more than one option list (they are
+all merged together in the end), which can be handy if one wants to
+separate option groups syntactically.
+
+* Possible option types:
+
+ - ``switch_option`` - a simple boolean switch without arguments, for example
+ ``-O2`` or ``-time``. At most one occurrence is allowed.
+
+ - ``parameter_option`` - option that takes one argument, for example
+ ``-std=c99``. It is also allowed to use spaces instead of the equality
+ sign: ``-std c99``. At most one occurrence is allowed.
+
+ - ``parameter_list_option`` - same as the above, but more than one option
+ occurence is allowed.
+
+ - ``prefix_option`` - same as the parameter_option, but the option name and
+ argument do not have to be separated. Example: ``-ofile``. This can be also
+ specified as ``-o file``; however, ``-o=file`` will be parsed incorrectly
+ (``=file`` will be interpreted as option value). At most one occurrence is
+ allowed.
+
+ - ``prefix_list_option`` - same as the above, but more than one occurence of
+ the option is allowed; example: ``-lm -lpthread``.
+
+ - ``alias_option`` - a special option type for creating aliases. Unlike other
+ option types, aliases are not allowed to have any properties besides the
+ aliased option name. Usage example: ``(alias_option "preprocess", "E")``
+
+
+* Possible option properties:
+
+ - ``help`` - help string associated with this option. Used for ``--help``
+ output.
+
+ - ``required`` - this option must be specified exactly once (or, in case of
+ the list options without the ``multi_val`` property, at least
+ once). Incompatible with ``optional`` and ``one_or_more``.
+
+ - ``optional`` - the option can be specified either zero times or exactly
+ once. The default for switch options. Useful only for list options in
+ conjunction with ``multi_val``. Incompatible with ``required``,
+ ``zero_or_more`` and ``one_or_more``.
+
+ - ``one_or_more`` - the option must be specified at least once. Can be useful
+ to allow switch options be both obligatory and be specified multiple
+ times. For list options is useful only in conjunction with ``multi_val``;
+ for ordinary it is synonymous with ``required``. Incompatible with
+ ``required``, ``optional`` and ``zero_or_more``.
+
+ - ``zero_or_more`` - the option can be specified zero or more times. Useful
+ to allow a single switch option to be specified more than
+ once. Incompatible with ``required``, ``optional`` and ``one_or_more``.
+
+ - ``hidden`` - the description of this option will not appear in
+ the ``--help`` output (but will appear in the ``--help-hidden``
+ output).
+
+ - ``really_hidden`` - the option will not be mentioned in any help
+ output.
+
+ - ``comma_separated`` - Indicates that any commas specified for an option's
+ value should be used to split the value up into multiple values for the
+ option. This property is valid only for list options. In conjunction with
+ ``forward_value`` can be used to implement option forwarding in style of
+ gcc's ``-Wa,``.
+
+ - ``multi_val n`` - this option takes *n* arguments (can be useful in some
+ special cases). Usage example: ``(parameter_list_option "foo", (multi_val
+ 3))``; the command-line syntax is '-foo a b c'. Only list options can have
+ this attribute; you can, however, use the ``one_or_more``, ``optional``
+ and ``required`` properties.
+
+ - ``init`` - this option has a default value, either a string (if it is a
+ parameter), or a boolean (if it is a switch; as in C++, boolean constants
+ are called ``true`` and ``false``). List options can't have ``init``
+ attribute.
+ Usage examples: ``(switch_option "foo", (init true))``; ``(prefix_option
+ "bar", (init "baz"))``.
+
+ - ``extern`` - this option is defined in some other plugin, see `below`__.
+
+ __ extern_
+
+.. _extern:
+
+External options
+----------------
+
+Sometimes, when linking several plugins together, one plugin needs to
+access options defined in some other plugin. Because of the way
+options are implemented, such options must be marked as
+``extern``. This is what the ``extern`` option property is
+for. Example::
+
+ ...
+ (switch_option "E", (extern))
+ ...
+
+If an external option has additional attributes besides 'extern', they are
+ignored. See also the section on plugin `priorities`__.
+
+__ priorities_
+
+.. _case:
+
+Conditional evaluation
+======================
+
+The 'case' construct is the main means by which programmability is
+achieved in LLVMC. It can be used to calculate edge weights, program
+actions and modify the shell commands to be executed. The 'case'
+expression is designed after the similarly-named construct in
+functional languages and takes the form ``(case (test_1), statement_1,
+(test_2), statement_2, ... (test_N), statement_N)``. The statements
+are evaluated only if the corresponding tests evaluate to true.
+
+Examples::
+
+ // Edge weight calculation
+
+ // Increases edge weight by 5 if "-A" is provided on the
+ // command-line, and by 5 more if "-B" is also provided.
+ (case
+ (switch_on "A"), (inc_weight 5),
+ (switch_on "B"), (inc_weight 5))
+
+
+ // Tool command line specification
+
+ // Evaluates to "cmdline1" if the option "-A" is provided on the
+ // command line; to "cmdline2" if "-B" is provided;
+ // otherwise to "cmdline3".
+
+ (case
+ (switch_on "A"), "cmdline1",
+ (switch_on "B"), "cmdline2",
+ (default), "cmdline3")
+
+Note the slight difference in 'case' expression handling in contexts
+of edge weights and command line specification - in the second example
+the value of the ``"B"`` switch is never checked when switch ``"A"`` is
+enabled, and the whole expression always evaluates to ``"cmdline1"`` in
+that case.
+
+Case expressions can also be nested, i.e. the following is legal::
+
+ (case (switch_on "E"), (case (switch_on "o"), ..., (default), ...)
+ (default), ...)
+
+You should, however, try to avoid doing that because it hurts
+readability. It is usually better to split tool descriptions and/or
+use TableGen inheritance instead.
+
+* Possible tests are:
+
+ - ``switch_on`` - Returns true if a given command-line switch is provided by
+ the user. Can be given a list as argument, in that case ``(switch_on ["foo",
+ "bar", "baz"])`` is equivalent to ``(and (switch_on "foo"), (switch_on
+ "bar"), (switch_on "baz"))``.
+ Example: ``(switch_on "opt")``.
+
+ - ``any_switch_on`` - Given a list of switch options, returns true if any of
+ the switches is turned on.
+ Example: ``(any_switch_on ["foo", "bar", "baz"])`` is equivalent to ``(or
+ (switch_on "foo"), (switch_on "bar"), (switch_on "baz"))``.
+
+ - ``parameter_equals`` - Returns true if a command-line parameter equals
+ a given value.
+ Example: ``(parameter_equals "W", "all")``.
+
+ - ``element_in_list`` - Returns true if a command-line parameter
+ list contains a given value.
+ Example: ``(element_in_list "l", "pthread")``.
+
+ - ``input_languages_contain`` - Returns true if a given language
+ belongs to the current input language set.
+ Example: ``(input_languages_contain "c++")``.
+
+ - ``in_language`` - Evaluates to true if the input file language is equal to
+ the argument. At the moment works only with ``cmd_line`` and ``actions`` (on
+ non-join nodes).
+ Example: ``(in_language "c++")``.
+
+ - ``not_empty`` - Returns true if a given option (which should be either a
+ parameter or a parameter list) is set by the user. Like ``switch_on``, can
+ be also given a list as argument.
+ Example: ``(not_empty "o")``.
+
+ - ``any_not_empty`` - Returns true if ``not_empty`` returns true for any of
+ the options in the list.
+ Example: ``(any_not_empty ["foo", "bar", "baz"])`` is equivalent to ``(or
+ (not_empty "foo"), (not_empty "bar"), (not_empty "baz"))``.
+
+ - ``empty`` - The opposite of ``not_empty``. Equivalent to ``(not (not_empty
+ X))``. Provided for convenience. Can be given a list as argument.
+
+ - ``any_not_empty`` - Returns true if ``not_empty`` returns true for any of
+ the options in the list.
+ Example: ``(any_empty ["foo", "bar", "baz"])`` is equivalent to ``(not (and
+ (not_empty "foo"), (not_empty "bar"), (not_empty "baz")))``.
+
+ - ``single_input_file`` - Returns true if there was only one input file
+ provided on the command-line. Used without arguments:
+ ``(single_input_file)``.
+
+ - ``multiple_input_files`` - Equivalent to ``(not (single_input_file))`` (the
+ case of zero input files is considered an error).
+
+ - ``default`` - Always evaluates to true. Should always be the last
+ test in the ``case`` expression.
+
+ - ``and`` - A standard binary logical combinator that returns true iff all of
+ its arguments return true. Used like this: ``(and (test1), (test2),
+ ... (testN))``. Nesting of ``and`` and ``or`` is allowed, but not
+ encouraged.
+
+ - ``or`` - A binary logical combinator that returns true iff any of its
+ arguments returns true. Example: ``(or (test1), (test2), ... (testN))``.
+
+ - ``not`` - Standard unary logical combinator that negates its
+ argument. Example: ``(not (or (test1), (test2), ... (testN)))``.
+
+
+
+Writing a tool description
+==========================
+
+As was said earlier, nodes in the compilation graph represent tools,
+which are described separately. A tool definition looks like this
+(taken from the ``include/llvm/CompilerDriver/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-explanatory. The ``sink``
+property means that this tool should be passed all command-line
+options that aren't mentioned in the option list.
+
+The complete list of all currently implemented tool properties follows.
+
+* Possible tool properties:
+
+ - ``in_language`` - input language name. Can be either a string or a
+ list, in case the tool supports multiple input languages.
+
+ - ``out_language`` - output language name. Multiple output languages are not
+ allowed.
+
+ - ``output_suffix`` - output file suffix. Can also be changed
+ dynamically, see documentation on actions.
+
+ - ``cmd_line`` - the actual command used to run the tool. You can
+ use ``$INFILE`` and ``$OUTFILE`` variables, output redirection
+ with ``>``, hook invocations (``$CALL``), environment variables
+ (via ``$ENV``) and the ``case`` construct.
+
+ - ``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.
+
+ - ``actions`` - A single big ``case`` expression that specifies how
+ this tool reacts on command-line options (described in more detail
+ `below`__).
+
+__ actions_
+
+.. _actions:
+
+Actions
+-------
+
+A tool often needs to react to command-line options, and this is
+precisely what the ``actions`` property is for. The next example
+illustrates this feature::
+
+ def llvm_gcc_linker : Tool<[
+ (in_language "object-code"),
+ (out_language "executable"),
+ (output_suffix "out"),
+ (cmd_line "llvm-gcc $INFILE -o $OUTFILE"),
+ (join),
+ (actions (case (not_empty "L"), (forward "L"),
+ (not_empty "l"), (forward "l"),
+ (not_empty "dummy"),
+ [(append_cmd "-dummy1"), (append_cmd "-dummy2")])
+ ]>;
+
+The ``actions`` tool property is implemented on top of the omnipresent
+``case`` expression. It associates one or more different *actions*
+with given conditions - in the example, the actions are ``forward``,
+which forwards a given option unchanged, and ``append_cmd``, which
+appends a given string to the tool execution command. Multiple actions
+can be associated with a single condition by using a list of actions
+(used in the example to append some dummy options). The same ``case``
+construct can also be used in the ``cmd_line`` property to modify the
+tool command line.
+
+The "join" property used in the example means that this tool behaves
+like a linker.
+
+The list of all possible actions follows.
+
+* Possible actions:
+
+ - ``append_cmd`` - Append a string to the tool invocation command.
+ Example: ``(case (switch_on "pthread"), (append_cmd "-lpthread"))``.
+
+ - ``error`` - Exit with error.
+ Example: ``(error "Mixing -c and -S is not allowed!")``.
+
+ - ``warning`` - Print a warning.
+ Example: ``(warning "Specifying both -O1 and -O2 is meaningless!")``.
+
+ - ``forward`` - Forward the option unchanged.
+ Example: ``(forward "Wall")``.
+
+ - ``forward_as`` - Change the option's name, but forward the argument
+ unchanged.
+ Example: ``(forward_as "O0", "--disable-optimization")``.
+
+ - ``forward_value`` - Forward only option's value. Cannot be used with switch
+ options (since they don't have values), but works fine with lists.
+ Example: ``(forward_value "Wa,")``.
+
+ - ``forward_transformed_value`` - As above, but applies a hook to the
+ option's value before forwarding (see `below`__). When
+ ``forward_transformed_value`` is applied to a list
+ option, the hook must have signature
+ ``std::string hooks::HookName (const std::vector<std::string>&)``.
+ Example: ``(forward_transformed_value "m", "ConvertToMAttr")``.
+
+ __ hooks_
+
+ - ``output_suffix`` - Modify the output suffix of this tool.
+ Example: ``(output_suffix "i")``.
+
+ - ``stop_compilation`` - Stop compilation after this tool processes its
+ input. Used without arguments.
+ Example: ``(stop_compilation)``.
+
+
+Language map
+============
+
+If you are adding support for a new language to LLVMC, you'll need to
+modify the language map, which defines mappings from file extensions
+to language names. It is used to choose the proper toolchain(s) for a
+given input file set. Language map definition looks like this::
+
+ def LanguageMap : LanguageMap<
+ [LangToSuffixes<"c++", ["cc", "cp", "cxx", "cpp", "CPP", "c++", "C"]>,
+ LangToSuffixes<"c", ["c"]>,
+ ...
+ ]>;
+
+For example, without those definitions the following command wouldn't work::
+
+ $ llvmc hello.cpp
+ llvmc: Unknown suffix: cpp
+
+The language map entries are needed only for the tools that are linked from the
+root node. Since a tool can't have multiple output languages, for inner nodes of
+the graph the input and output languages should match. This is enforced at
+compile-time.
+
+Option preprocessor
+===================
+
+It is sometimes useful to run error-checking code before processing the
+compilation graph. For example, if optimization options "-O1" and "-O2" are
+implemented as switches, we might want to output a warning if the user invokes
+the driver with both of these options enabled.
+
+The ``OptionPreprocessor`` feature is reserved specially for these
+occasions. Example (adapted from the built-in Base plugin)::
+
+
+ def Preprocess : OptionPreprocessor<
+ (case (not (any_switch_on ["O0", "O1", "O2", "O3"])),
+ (set_option "O2"),
+ (and (switch_on "O3"), (any_switch_on ["O0", "O1", "O2"])),
+ (unset_option ["O0", "O1", "O2"]),
+ (and (switch_on "O2"), (any_switch_on ["O0", "O1"])),
+ (unset_option ["O0", "O1"]),
+ (and (switch_on "O1"), (switch_on "O0")),
+ (unset_option "O0"))
+ >;
+
+Here, ``OptionPreprocessor`` is used to unset all spurious ``-O`` options so
+that they are not forwarded to the compiler. If no optimization options are
+specified, ``-O2`` is enabled.
+
+``OptionPreprocessor`` is basically a single big ``case`` expression, which is
+evaluated only once right after the plugin is loaded. The only allowed actions
+in ``OptionPreprocessor`` are ``error``, ``warning``, and two special actions:
+``unset_option`` and ``set_option``. As their names suggest, they can be used to
+set or unset a given option. To set an option with ``set_option``, use the
+two-argument form: ``(set_option "parameter", VALUE)``. Here, ``VALUE`` can be
+either a string, a string list, or a boolean constant.
+
+For convenience, ``set_option`` and ``unset_option`` also work on lists. That
+is, instead of ``[(unset_option "A"), (unset_option "B")]`` you can use
+``(unset_option ["A", "B"])``. Obviously, ``(set_option ["A", "B"])`` is valid
+only if both ``A`` and ``B`` are switches.
+
+
+More advanced topics
+====================
+
+.. _hooks:
+
+Hooks and environment variables
+-------------------------------
+
+Normally, LLVMC executes programs from the system ``PATH``. Sometimes,
+this is not sufficient: for example, we may want to specify tool paths
+or names in the configuration file. This can be easily achieved via
+the hooks mechanism. To write your own hooks, just add their
+definitions to the ``PluginMain.cpp`` or drop a ``.cpp`` file into the
+your plugin directory. Hooks should live in the ``hooks`` namespace
+and have the signature ``std::string hooks::MyHookName ([const char*
+Arg0 [ const char* Arg2 [, ...]]])``. They can be used from the
+``cmd_line`` tool property::
+
+ (cmd_line "$CALL(MyHook)/path/to/file -o $CALL(AnotherHook)")
+
+To pass arguments to hooks, use the following syntax::
+
+ (cmd_line "$CALL(MyHook, 'Arg1', 'Arg2', 'Arg # 3')/path/to/file -o1 -o2")
+
+It is also possible to use environment variables in the same manner::
+
+ (cmd_line "$ENV(VAR1)/path/to/file -o $ENV(VAR2)")
+
+To change the command line string based on user-provided options use
+the ``case`` expression (documented `above`__)::
+
+ (cmd_line
+ (case
+ (switch_on "E"),
+ "llvm-g++ -E -x c $INFILE -o $OUTFILE",
+ (default),
+ "llvm-g++ -c -x c $INFILE -o $OUTFILE -emit-llvm"))
+
+__ case_
+
+.. _priorities:
+
+How plugins are loaded
+----------------------
+
+It is possible for LLVMC plugins to depend on each other. For example,
+one can create edges between nodes defined in some other plugin. To
+make this work, however, that plugin should be loaded first. To
+achieve this, the concept of plugin priority was introduced. By
+default, every plugin has priority zero; to specify the priority
+explicitly, put the following line in your plugin's TableGen file::
+
+ def Priority : PluginPriority<$PRIORITY_VALUE>;
+ # Where PRIORITY_VALUE is some integer > 0
+
+Plugins are loaded in order of their (increasing) priority, starting
+with 0. Therefore, the plugin with the highest priority value will be
+loaded last.
+
+Debugging
+---------
+
+When writing LLVMC plugins, it can be useful to get a visual view of
+the resulting compilation graph. This can be achieved via the command
+line option ``--view-graph``. This command assumes that Graphviz_ and
+Ghostview_ are installed. There is also a ``--write-graph`` option that
+creates a Graphviz source file (``compilation-graph.dot``) in the
+current directory.
+
+Another useful ``llvmc`` option is ``--check-graph``. It checks the
+compilation graph for common errors like mismatched output/input
+language names, multiple default edges and cycles. These checks can't
+be performed at compile-time because the plugins can load code
+dynamically. When invoked with ``--check-graph``, ``llvmc`` doesn't
+perform any compilation tasks and returns the number of encountered
+errors as its status code.
+
+.. _Graphviz: http://www.graphviz.org/
+.. _Ghostview: http://pages.cs.wisc.edu/~ghost/
+
+Conditioning on the executable name
+-----------------------------------
+
+For now, the executable name (the value passed to the driver in ``argv[0]``) is
+accessible only in the C++ code (i.e. hooks). Use the following code::
+
+ namespace llvmc {
+ extern const char* ProgramName;
+ }
+
+ namespace hooks {
+
+ std::string MyHook() {
+ //...
+ if (strcmp(ProgramName, "mydriver") == 0) {
+ //...
+
+ }
+
+ } // end namespace hooks
+
+In general, you're encouraged not to make the behaviour dependent on the
+executable file name, and use command-line switches instead. See for example how
+the ``Base`` plugin behaves when it needs to choose the correct linker options
+(think ``g++`` vs. ``gcc``).
+
+.. raw:: html
+
+ <hr />
+ <address>
+ <a href="http://jigsaw.w3.org/css-validator/check/referer">
+ <img src="http://jigsaw.w3.org/css-validator/images/vcss-blue"
+ alt="Valid CSS" /></a>
+ <a href="http://validator.w3.org/check?uri=referer">
+ <img src="http://www.w3.org/Icons/valid-xhtml10-blue"
+ alt="Valid XHTML 1.0 Transitional"/></a>
+
+ <a href="mailto:foldr@codedgers.com">Mikhail Glushenkov</a><br />
+ <a href="http://llvm.org">LLVM Compiler Infrastructure</a><br />
+
+ Last modified: $Date: 2008-12-11 11:34:48 -0600 (Thu, 11 Dec 2008) $
+ </address>
diff --git a/contrib/llvm/tools/llvmc/doc/LLVMC-Tutorial.rst b/contrib/llvm/tools/llvmc/doc/LLVMC-Tutorial.rst
new file mode 100644
index 0000000..e7e8f08
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/doc/LLVMC-Tutorial.rst
@@ -0,0 +1,129 @@
+======================
+Tutorial - Using LLVMC
+======================
+..
+ This file was automatically generated by rst2html.
+ Please do not edit directly!
+ The ReST source lives in the directory 'tools/llvmc/doc'.
+
+.. contents::
+
+.. raw:: html
+
+ <div class="doc_author">
+ <p>Written by <a href="mailto:foldr@codedgers.com">Mikhail Glushenkov</a></p>
+ </div>
+
+Introduction
+============
+
+LLVMC is a generic compiler driver, which plays the same role for LLVM
+as the ``gcc`` program does for GCC - the difference being that LLVMC
+is designed to be more adaptable and easier to customize. Most of
+LLVMC functionality is implemented via plugins, which can be loaded
+dynamically or compiled in. This tutorial describes the basic usage
+and configuration of LLVMC.
+
+
+Compiling with LLVMC
+====================
+
+In general, LLVMC tries to be command-line compatible with ``gcc`` as
+much as possible, so most of the familiar options work::
+
+ $ llvmc -O3 -Wall hello.cpp
+ $ ./a.out
+ hello
+
+This will invoke ``llvm-g++`` under the hood (you can see which
+commands are executed by using the ``-v`` option). For further help on
+command-line LLVMC usage, refer to the ``llvmc --help`` output.
+
+
+Using LLVMC to generate toolchain drivers
+=========================================
+
+LLVMC plugins are written mostly using TableGen_, so you need to
+be familiar with it to get anything done.
+
+.. _TableGen: http://llvm.org/docs/TableGenFundamentals.html
+
+Start by compiling ``example/Simple``, which is a primitive wrapper for
+``gcc``::
+
+ $ cd $LLVM_DIR/tools/llvmc
+ $ cp -r example/Simple plugins/Simple
+
+ # NB: A less verbose way to compile standalone LLVMC-based drivers is
+ # described in the reference manual.
+
+ $ make LLVMC_BASED_DRIVER_NAME=mygcc LLVMC_BUILTIN_PLUGINS=Simple
+ $ cat > hello.c
+ [...]
+ $ mygcc hello.c
+ $ ./hello.out
+ Hello
+
+Here we link our plugin with the LLVMC core statically to form an executable
+file called ``mygcc``. It is also possible to build our plugin as a dynamic
+library to be loaded by the ``llvmc`` executable (or any other LLVMC-based
+standalone driver); this is described in the reference manual.
+
+Contents of the file ``Simple.td`` look like this::
+
+ // Include common definitions
+ include "llvm/CompilerDriver/Common.td"
+
+ // Tool descriptions
+ def gcc : Tool<
+ [(in_language "c"),
+ (out_language "executable"),
+ (output_suffix "out"),
+ (cmd_line "gcc $INFILE -o $OUTFILE"),
+ (sink)
+ ]>;
+
+ // Language map
+ def LanguageMap : LanguageMap<[LangToSuffixes<"c", ["c"]>]>;
+
+ // Compilation graph
+ def CompilationGraph : CompilationGraph<[Edge<"root", "gcc">]>;
+
+As you can see, this file consists of three parts: tool descriptions,
+language map, and the compilation graph definition.
+
+At the heart of LLVMC is the idea of a compilation graph: vertices in
+this graph are tools, and edges represent a transformation path
+between two tools (for example, assembly source produced by the
+compiler can be transformed into executable code by an assembler). The
+compilation graph is basically a list of edges; a special node named
+``root`` is used to mark graph entry points.
+
+Tool descriptions are represented as property lists: most properties
+in the example above should be self-explanatory; the ``sink`` property
+means that all options lacking an explicit description should be
+forwarded to this tool.
+
+The ``LanguageMap`` associates a language name with a list of suffixes
+and is used for deciding which toolchain corresponds to a given input
+file.
+
+To learn more about LLVMC customization, refer to the reference
+manual and plugin source code in the ``plugins`` directory.
+
+.. raw:: html
+
+ <hr />
+ <address>
+ <a href="http://jigsaw.w3.org/css-validator/check/referer">
+ <img src="http://jigsaw.w3.org/css-validator/images/vcss-blue"
+ alt="Valid CSS" /></a>
+ <a href="http://validator.w3.org/check?uri=referer">
+ <img src="http://www.w3.org/Icons/valid-xhtml10-blue"
+ alt="Valid XHTML 1.0 Transitional"/></a>
+
+ <a href="mailto:foldr@codedgers.com">Mikhail Glushenkov</a><br />
+ <a href="http://llvm.org">LLVM Compiler Infrastructure</a><br />
+
+ Last modified: $Date: 2008-12-11 11:34:48 -0600 (Thu, 11 Dec 2008) $
+ </address>
diff --git a/contrib/llvm/tools/llvmc/doc/Makefile b/contrib/llvm/tools/llvmc/doc/Makefile
new file mode 100644
index 0000000..ef98767
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/doc/Makefile
@@ -0,0 +1,33 @@
+##===- tools/llvmc/doc/Makefile ----------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL=../../..
+
+ifneq (,$(strip $(wildcard $(LEVEL)/Makefile.config)))
+include $(LEVEL)/Makefile.config
+else
+CP=cp
+RM=rm
+endif
+
+DOC_DIR=../../../docs
+RST2HTML=rst2html --stylesheet=llvm.css --link-stylesheet
+
+all : LLVMC-Reference.html LLVMC-Tutorial.html
+ $(CP) LLVMC-Reference.html $(DOC_DIR)/CompilerDriver.html
+ $(CP) LLVMC-Tutorial.html $(DOC_DIR)/CompilerDriverTutorial.html
+
+LLVMC-Tutorial.html : LLVMC-Tutorial.rst
+ $(RST2HTML) $< $@
+
+LLVMC-Reference.html : LLVMC-Reference.rst
+ $(RST2HTML) $< $@
+
+clean :
+ $(RM) LLVMC-Tutorial.html LLVMC-Reference.html
diff --git a/contrib/llvm/tools/llvmc/doc/img/lines.gif b/contrib/llvm/tools/llvmc/doc/img/lines.gif
new file mode 100644
index 0000000..88f491e
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/doc/img/lines.gif
Binary files differ
diff --git a/contrib/llvm/tools/llvmc/driver/Main.cpp b/contrib/llvm/tools/llvmc/driver/Main.cpp
new file mode 100644
index 0000000..b1f5b67
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/driver/Main.cpp
@@ -0,0 +1,14 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// Just include CompilerDriver/Main.inc.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CompilerDriver/Main.inc"
diff --git a/contrib/llvm/tools/llvmc/driver/Makefile b/contrib/llvm/tools/llvmc/driver/Makefile
new file mode 100644
index 0000000..2f3104b
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/driver/Makefile
@@ -0,0 +1,13 @@
+##===- tools/llvmc/driver/Makefile -------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open
+# Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../..
+LLVMC_BASED_DRIVER = $(LLVMC_BASED_DRIVER_NAME)
+
+include $(LEVEL)/Makefile.common
diff --git a/contrib/llvm/tools/llvmc/example/Hello/Hello.cpp b/contrib/llvm/tools/llvmc/example/Hello/Hello.cpp
new file mode 100644
index 0000000..a7179ea
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/example/Hello/Hello.cpp
@@ -0,0 +1,33 @@
+//===- Hello.cpp - Example code from "Writing an LLVMC Plugin" ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Test plugin for LLVMC. Shows how to write plugins without using TableGen.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CompilerDriver/CompilationGraph.h"
+#include "llvm/CompilerDriver/Plugin.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace {
+struct MyPlugin : public llvmc::BasePlugin {
+
+ void PreprocessOptions() const
+ {}
+
+ void PopulateLanguageMap(llvmc::LanguageMap&) const
+ { outs() << "Hello!\n"; }
+
+ void PopulateCompilationGraph(llvmc::CompilationGraph&) const
+ {}
+};
+
+static llvmc::RegisterPlugin<MyPlugin> RP("Hello", "Hello World plugin");
+
+}
diff --git a/contrib/llvm/tools/llvmc/example/Hello/Makefile b/contrib/llvm/tools/llvmc/example/Hello/Makefile
new file mode 100644
index 0000000..10325e6
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/example/Hello/Makefile
@@ -0,0 +1,14 @@
+##===- tools/llvmc/plugins/Hello/Makefile ------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../../..
+
+LLVMC_PLUGIN = Hello
+
+include $(LEVEL)/Makefile.common
diff --git a/contrib/llvm/tools/llvmc/example/Simple/Makefile b/contrib/llvm/tools/llvmc/example/Simple/Makefile
new file mode 100644
index 0000000..d7adb5d
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/example/Simple/Makefile
@@ -0,0 +1,15 @@
+##===- tools/llvmc/plugins/Simple/Makefile -----------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../../..
+
+LLVMC_PLUGIN = Simple
+BUILT_SOURCES = AutoGenerated.inc
+
+include $(LEVEL)/Makefile.common
diff --git a/contrib/llvm/tools/llvmc/example/Simple/PluginMain.cpp b/contrib/llvm/tools/llvmc/example/Simple/PluginMain.cpp
new file mode 100644
index 0000000..add8acb
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/example/Simple/PluginMain.cpp
@@ -0,0 +1 @@
+#include "AutoGenerated.inc"
diff --git a/contrib/llvm/tools/llvmc/example/Simple/Simple.td b/contrib/llvm/tools/llvmc/example/Simple/Simple.td
new file mode 100644
index 0000000..87bc385
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/example/Simple/Simple.td
@@ -0,0 +1,37 @@
+//===- Simple.td - A simple plugin for LLVMC ------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// A simple LLVMC-based gcc wrapper that shows how to write LLVMC plugins.
+//
+// To compile, use this command:
+//
+// $ cd $LLVMC_DIR/example/Simple
+// $ make
+//
+// Run as:
+//
+// $ llvmc -load $LLVM_DIR/Release/lib/plugin_llvmc_Simple.so
+//
+// For instructions on how to build your own LLVMC-based driver, see
+// the 'example/Skeleton' directory.
+//===----------------------------------------------------------------------===//
+
+include "llvm/CompilerDriver/Common.td"
+
+def gcc : Tool<
+[(in_language "c"),
+ (out_language "executable"),
+ (output_suffix "out"),
+ (cmd_line "gcc $INFILE -o $OUTFILE"),
+ (sink)
+]>;
+
+def LanguageMap : LanguageMap<[LangToSuffixes<"c", ["c"]>]>;
+
+def CompilationGraph : CompilationGraph<[Edge<"root", "gcc">]>;
diff --git a/contrib/llvm/tools/llvmc/example/Skeleton/Makefile b/contrib/llvm/tools/llvmc/example/Skeleton/Makefile
new file mode 100644
index 0000000..f489abf
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/example/Skeleton/Makefile
@@ -0,0 +1,24 @@
+##===- llvmc/example/Skeleton/Makefile ---------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open
+# Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+# Change this so that $(BASE_LEVEL)/Makefile.common refers to
+# $LLVM_DIR/Makefile.common or $YOUR_LLVM_BASED_PROJECT/Makefile.common.
+export LLVMC_BASE_LEVEL = ../../../..
+
+# Change this to the name of your LLVMC-based driver.
+export LLVMC_BASED_DRIVER_NAME = llvmc-skeleton
+
+# List your plugin names here
+export LLVMC_BUILTIN_PLUGINS = # Plugin
+
+LEVEL = $(LLVMC_BASE_LEVEL)
+
+DIRS = plugins driver
+
+include $(LEVEL)/Makefile.common
diff --git a/contrib/llvm/tools/llvmc/example/Skeleton/README b/contrib/llvm/tools/llvmc/example/Skeleton/README
new file mode 100644
index 0000000..92216ae
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/example/Skeleton/README
@@ -0,0 +1,6 @@
+
+This is a template that can be used to create your own LLVMC-based drivers. Just
+copy the `Skeleton` directory to the location of your preference and edit
+`Skeleton/Makefile` and `Skeleton/plugins/Plugin`.
+
+The build system assumes that your project is based on LLVM.
diff --git a/contrib/llvm/tools/llvmc/example/Skeleton/driver/Main.cpp b/contrib/llvm/tools/llvmc/example/Skeleton/driver/Main.cpp
new file mode 100644
index 0000000..b1f5b67
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/example/Skeleton/driver/Main.cpp
@@ -0,0 +1,14 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// Just include CompilerDriver/Main.inc.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CompilerDriver/Main.inc"
diff --git a/contrib/llvm/tools/llvmc/example/Skeleton/driver/Makefile b/contrib/llvm/tools/llvmc/example/Skeleton/driver/Makefile
new file mode 100644
index 0000000..93e795b
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/example/Skeleton/driver/Makefile
@@ -0,0 +1,13 @@
+##===- llvmc/example/Skeleton/driver/Makefile --------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open
+# Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = $(LLVMC_BASE_LEVEL)/..
+LLVMC_BASED_DRIVER = $(LLVMC_BASED_DRIVER_NAME)
+
+include $(LEVEL)/Makefile.common
diff --git a/contrib/llvm/tools/llvmc/example/Skeleton/plugins/Makefile b/contrib/llvm/tools/llvmc/example/Skeleton/plugins/Makefile
new file mode 100644
index 0000000..fb07f23
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/example/Skeleton/plugins/Makefile
@@ -0,0 +1,18 @@
+##===- llvmc/example/Skeleton/plugins/Makefile -------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open
+# Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = $(LLVMC_BASE_LEVEL)/..
+
+ifneq ($(LLVMC_BUILTIN_PLUGINS),)
+DIRS = $(LLVMC_BUILTIN_PLUGINS)
+endif
+
+export LLVMC_BUILTIN_PLUGIN=1
+
+include $(LEVEL)/Makefile.common
diff --git a/contrib/llvm/tools/llvmc/example/Skeleton/plugins/Plugin/Makefile b/contrib/llvm/tools/llvmc/example/Skeleton/plugins/Plugin/Makefile
new file mode 100644
index 0000000..54f7221
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/example/Skeleton/plugins/Plugin/Makefile
@@ -0,0 +1,17 @@
+##===- llvmc/example/Skeleton/plugins/Plugin/Makefile ------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = $(LLVMC_BASE_LEVEL)/../..
+
+# Change this to the name of your plugin.
+LLVMC_PLUGIN = Plugin
+
+BUILT_SOURCES = AutoGenerated.inc
+
+include $(LEVEL)/Makefile.common
diff --git a/contrib/llvm/tools/llvmc/example/Skeleton/plugins/Plugin/Plugin.td b/contrib/llvm/tools/llvmc/example/Skeleton/plugins/Plugin/Plugin.td
new file mode 100644
index 0000000..febb9ad
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/example/Skeleton/plugins/Plugin/Plugin.td
@@ -0,0 +1,7 @@
+//===- Plugin.td - A skeleton plugin for LLVMC -------------*- tablegen -*-===//
+//
+// Write the code for your plugin here.
+//
+//===----------------------------------------------------------------------===//
+
+include "llvm/CompilerDriver/Common.td"
diff --git a/contrib/llvm/tools/llvmc/example/Skeleton/plugins/Plugin/PluginMain.cpp b/contrib/llvm/tools/llvmc/example/Skeleton/plugins/Plugin/PluginMain.cpp
new file mode 100644
index 0000000..add8acb
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/example/Skeleton/plugins/Plugin/PluginMain.cpp
@@ -0,0 +1 @@
+#include "AutoGenerated.inc"
diff --git a/contrib/llvm/tools/llvmc/example/mcc16/Makefile b/contrib/llvm/tools/llvmc/example/mcc16/Makefile
new file mode 100644
index 0000000..e94bca2
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/example/mcc16/Makefile
@@ -0,0 +1,18 @@
+##===- llvmc/example/mcc16/Makefile ------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open
+# Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+export LLVMC_BASE_LEVEL = ../../../..
+export LLVMC_BASED_DRIVER_NAME = mcc16
+export LLVMC_BUILTIN_PLUGINS = PIC16Base
+
+LEVEL = $(LLVMC_BASE_LEVEL)
+
+DIRS = plugins driver
+
+include $(LEVEL)/Makefile.common
diff --git a/contrib/llvm/tools/llvmc/example/mcc16/README b/contrib/llvm/tools/llvmc/example/mcc16/README
new file mode 100644
index 0000000..eeef6a4
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/example/mcc16/README
@@ -0,0 +1,75 @@
+This is a basic compiler driver for the PIC16 toolchain that shows how to create
+your own llvmc-based drivers. It is based on the example/Skeleton template.
+
+The PIC16 toolchain looks like this:
+
+clang-cc (FE) -> llvm-ld (optimizer) -> llc (codegen) -> native-as -> native-ld
+
+Following features were requested by Sanjiv:
+
+From: Sanjiv Gupta <sanjiv.gupta <at> microchip.com>
+Subject: Re: llvmc for PIC16
+Newsgroups: gmane.comp.compilers.llvm.devel
+Date: 2009-06-05 06:51:14 GMT
+
+The salient features that we want to have in the driver are:
+1. llvm-ld will be used as "The Optimizer".
+2. If the user has specified to generate the final executable, then
+llvm-ld should run on all the .bc files generated by clang and create a
+single optimized .bc file for further tools.
+3. -Wo <options> - pass optimizations to the llvm-ld
+4. mcc16 -Wl <options> - pass options to native linker.
+5. mcc16 -Wa <options> - pass options to native assembler.
+
+Here are some example command lines and sample command invocations as to
+what should be done.
+
+$ mcc16 -S foo.c
+// [clang-cc foo.c] -> foo.bc
+// [llvm-ld foo.bc] -> foo.opt.bc
+// [llc foo.opt.bc] -> foo.s
+
+$ mcc16 -S foo.c bar.c
+// [clang-cc foo.c] -> foo.bc
+// [llvm-ld foo.bc] -> foo.opt.bc
+// [llc foo.opt.bc] -> foo.s
+// [clang-cc bar.c] -> bar.bc
+// [llvm-ld bar.bc] -> bar.opt.bc
+// [llc bar.opt.bc] -> bar.s
+
+** Use of -g causes llvm-ld to run with -disable-opt
+$ mcc16 -S -g foo.c
+// [clang-cc foo.c] -> foo.bc
+// [llvm-ld -disable-opt foo.bc] -> foo.opt.bc
+// [llc foo.opt.bc] -> foo.s
+
+** -I is passed to clang-cc, -pre-RA-sched=list-burr to llc.
+$ mcc16 -S -g -I ../include -pre-RA-sched=list-burr foo.c
+// [clang-cc -I ../include foo.c] -> foo.bc
+// [llvm-ld -disable-opt foo.bc] -> foo.opt.bc
+// [llc -pre-RA-sched=list-burr foo.opt.bc] -> foo.s
+
+** -Wo passes options to llvm-ld
+$ mcc16 -Wo=opt1,opt2 -S -I ../include -pre-RA-sched=list-burr foo.c
+// [clang-cc -I ../include foo.c] -> foo.bc
+// [llvm-ld -opt1 -opt2 foo.bc] -> foo.opt.bc
+// [llc -pre-RA-sched=list-burr foo.opt.bc] -> foo.s
+
+** -Wa passes options to native as.
+$ mcc16 -c foo.c -Wa=opt1
+// [clang-cc foo.c] -> foo.bc
+// [llvm-ld foo.bc] -> foo.opt.bc
+// [llc foo.opt.bc] -> foo.s
+// [native-as -opt1 foo.s] -> foo.o
+
+$ mcc16 -Wo=opt1 -Wl=opt2 -Wa=opt3 foo.c bar.c
+// [clang-cc foo.c] -> foo.bc
+// [clang-cc bar.c] -> bar.bc
+// [llvm-ld -opt1 foo.bc bar.bc] -> a.out.bc
+// [llc a.out.bc] -> a.out.s
+// [native-as -opt3 a.out.s] -> a.out.o
+// [native-ld -opt2 a.out.o] -> a.out
+
+Is this achievable by a tablegen based driver ?
+
+- Sanjiv
diff --git a/contrib/llvm/tools/llvmc/example/mcc16/driver/Main.cpp b/contrib/llvm/tools/llvmc/example/mcc16/driver/Main.cpp
new file mode 100644
index 0000000..e66e2f9
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/example/mcc16/driver/Main.cpp
@@ -0,0 +1,54 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// Usually this file just includes CompilerDriver/Main.inc, but here we apply
+// some trickery to make the built-in '-save-temps' option hidden and enable
+// '--temp-dir' by default.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Config/config.h"
+#include "llvm/CompilerDriver/BuiltinOptions.h"
+#include "llvm/CompilerDriver/ForceLinkage.h"
+#include "llvm/System/Path.h"
+#include <iostream>
+
+namespace llvmc {
+ int Main(int argc, char** argv);
+}
+
+// Modify the PACKAGE_VERSION to use build number in top level configure file.
+void PIC16VersionPrinter(void) {
+ std::cout << "MPLAB C16 1.0 " << PACKAGE_VERSION << "\n";
+}
+
+int main(int argc, char** argv) {
+
+ // HACK
+ SaveTemps.setHiddenFlag(llvm::cl::Hidden);
+ TempDirname.setHiddenFlag(llvm::cl::Hidden);
+ Languages.setHiddenFlag(llvm::cl::Hidden);
+ DryRun.setHiddenFlag(llvm::cl::Hidden);
+
+ llvm::cl::SetVersionPrinter(PIC16VersionPrinter);
+
+ // Ask for a standard temp dir, but just cache its basename., and delete it.
+ llvm::sys::Path tempDir;
+ tempDir = llvm::sys::Path::GetTemporaryDirectory();
+ TempDirname = tempDir.getBasename();
+ tempDir.eraseFromDisk(true);
+
+ // We are creating a temp dir in current dir, with the cached name.
+ // But before that remove if one already exists with that name..
+ tempDir = TempDirname;
+ tempDir.eraseFromDisk(true);
+
+ llvmc::ForceLinkage();
+ return llvmc::Main(argc, argv);
+}
diff --git a/contrib/llvm/tools/llvmc/example/mcc16/driver/Makefile b/contrib/llvm/tools/llvmc/example/mcc16/driver/Makefile
new file mode 100644
index 0000000..670d8bd
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/example/mcc16/driver/Makefile
@@ -0,0 +1,13 @@
+##===- llvmc/example/mcc16/driver/Makefile -----------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open
+# Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = $(LLVMC_BASE_LEVEL)/..
+LLVMC_BASED_DRIVER = $(LLVMC_BASED_DRIVER_NAME)
+
+include $(LEVEL)/Makefile.common
diff --git a/contrib/llvm/tools/llvmc/example/mcc16/plugins/Makefile b/contrib/llvm/tools/llvmc/example/mcc16/plugins/Makefile
new file mode 100644
index 0000000..fb07f23
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/example/mcc16/plugins/Makefile
@@ -0,0 +1,18 @@
+##===- llvmc/example/Skeleton/plugins/Makefile -------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open
+# Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = $(LLVMC_BASE_LEVEL)/..
+
+ifneq ($(LLVMC_BUILTIN_PLUGINS),)
+DIRS = $(LLVMC_BUILTIN_PLUGINS)
+endif
+
+export LLVMC_BUILTIN_PLUGIN=1
+
+include $(LEVEL)/Makefile.common
diff --git a/contrib/llvm/tools/llvmc/example/mcc16/plugins/PIC16Base/Makefile b/contrib/llvm/tools/llvmc/example/mcc16/plugins/PIC16Base/Makefile
new file mode 100644
index 0000000..5d785fd
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/example/mcc16/plugins/PIC16Base/Makefile
@@ -0,0 +1,17 @@
+##===- llvmc/example/Skeleton/plugins/Plugin/Makefile ------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = $(LLVMC_BASE_LEVEL)/../..
+
+# Change this to the name of your plugin.
+LLVMC_PLUGIN = PIC16Base
+
+BUILT_SOURCES = AutoGenerated.inc
+
+include $(LEVEL)/Makefile.common
diff --git a/contrib/llvm/tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td b/contrib/llvm/tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td
new file mode 100644
index 0000000..25149ad
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/example/mcc16/plugins/PIC16Base/PIC16Base.td
@@ -0,0 +1,234 @@
+//===- PIC16Base.td - PIC16 toolchain driver ---------------*- tablegen -*-===//
+//
+// A basic driver for the PIC16 toolchain.
+//
+//===----------------------------------------------------------------------===//
+
+include "llvm/CompilerDriver/Common.td"
+
+// Options
+
+def OptionList : OptionList<[
+ (switch_option "g",
+ (help "Enable Debugging")),
+ (switch_option "E",
+ (help "Stop after preprocessing, do not compile")),
+ (switch_option "S",
+ (help "Stop after compilation, do not assemble")),
+ (switch_option "bc",
+ (help "Stop after b-code generation, do not compile")),
+ (switch_option "c",
+ (help "Stop after assemble, do not link")),
+ (prefix_option "p",
+ (help "Specify part name")),
+ (prefix_list_option "I",
+ (help "Add a directory to include path")),
+ (prefix_list_option "L",
+ (help "Add a directory to library path")),
+ (prefix_list_option "K",
+ (help "Add a directory to linker script search path")),
+ (parameter_option "l",
+ (help "Specify a library to link")),
+ (parameter_option "k",
+ (help "Specify a linker script")),
+ (parameter_option "m",
+ (help "Generate linker map file with the given name")),
+ (prefix_list_option "D",
+ (help "Define a macro")),
+ (switch_option "X",
+ (help "Do not invoke mp2hex to create an output hex file.")),
+ (switch_option "O0",
+ (help "Do not optimize")),
+ (switch_option "O1",
+ (help "Optimization Level 1.")),
+ (switch_option "O2",
+ (help "Optimization Level 2.")),
+ (switch_option "O3",
+ (help "Optimization Level 3.")),
+ (switch_option "Od",
+ (help "Perform Debug-safe Optimizations only.")),
+ (switch_option "w",
+ (help "Disable all warnings.")),
+// (switch_option "O1",
+// (help "Optimization level 1")),
+// (switch_option "O2",
+// (help "Optimization level 2. (Default)")),
+// (parameter_option "pre-RA-sched",
+// (help "Example of an option that is passed to llc")),
+ (parameter_option "regalloc",
+ (help "Register allocator to use (possible values: simple, linearscan, pbqp, local; default=linearscan)")),
+ (prefix_list_option "Wa,", (comma_separated),
+ (help "Pass options to assembler (Run 'gpasm -help' for assembler options)")),
+ (prefix_list_option "Wl,", (comma_separated),
+ (help "Pass options to linker (Run 'mplink -help' for linker options)"))
+// (prefix_list_option "Wllc,",
+// (help "Pass options to llc")),
+// (prefix_list_option "Wo,",
+// (help "Pass options to llvm-ld"))
+]>;
+
+// Tools
+class clang_based<string language, string cmd, string ext_E> : Tool<
+[(in_language language),
+ (out_language "llvm-bitcode"),
+ (output_suffix "bc"),
+ (command cmd),
+ (actions (case
+ (and (multiple_input_files),
+ (or (switch_on "S"), (switch_on "c"))),
+ (error "cannot specify -o with -c or -S with multiple files"),
+ (switch_on "E"), [(forward "E"),
+ (stop_compilation), (output_suffix ext_E)],
+ (and (switch_on "E"), (empty "o")), (no_out_file),
+ (switch_on "bc"),[(stop_compilation), (output_suffix "bc")],
+ (switch_on "g"), (append_cmd "-g"),
+ (switch_on "w"), (append_cmd "-w"),
+ (switch_on "O1"), (append_cmd ""),
+ (switch_on "O2"), (append_cmd ""),
+ (switch_on "O3"), (append_cmd ""),
+ (switch_on "Od"), (append_cmd ""),
+ (not_empty "D"), (forward "D"),
+ (not_empty "I"), (forward "I"),
+ (switch_on "O0"), (append_cmd "-O0"),
+ (default), (append_cmd "-O1")))
+// (sink)
+]>;
+
+def clang_cc : clang_based<"c", "$CALL(GetBinDir)clang -cc1 -I $CALL(GetStdHeadersDir) -D $CALL(GetLowerCasePartDefine) -D $CALL(GetUpperCasePartDefine) -triple=pic16- -emit-llvm-bc ", "i">;
+
+//def clang_cc : Tool<[
+// (in_language "c"),
+// (out_language "llvm-bitcode"),
+// (output_suffix "bc"),
+// (cmd_line "$CALL(GetBinDir)clang-cc -I $CALL(GetStdHeadersDir) -triple=pic16- -emit-llvm-bc "),
+// (cmd_line kkkkk
+// (actions (case
+// (switch_on "g"), (append_cmd "g"),
+// (not_empty "I"), (forward "I"))),
+// (sink)
+//]>;
+
+
+// pre-link-and-lto step.
+def llvm_ld : Tool<[
+ (in_language "llvm-bitcode"),
+ (out_language "llvm-bitcode"),
+ (output_suffix "bc"),
+ (command "$CALL(GetBinDir)llvm-ld -L $CALL(GetStdLibsDir) -disable-licm-promotion -l std"),
+ (out_file_option "-b"),
+ (actions (case
+ (switch_on "O0"), (append_cmd "-disable-opt"),
+ (switch_on "O1"), (append_cmd "-disable-opt"),
+// Whenever O3 is not specified on the command line, default i.e. disable-inlining will always be added.
+ (switch_on "O2"), (append_cmd ""),
+ (switch_on "O3"), (append_cmd ""),
+ (default), (append_cmd "-disable-inlining"))),
+ (join)
+]>;
+
+// optimize single file
+def llvm_ld_optimizer : Tool<[
+ (in_language "llvm-bitcode"),
+ (out_language "llvm-bitcode"),
+ (output_suffix "bc"),
+// FIXME: we are still not disabling licm-promotion.
+// -disable-licm-promotion and building stdn library causes c16-71 to fail.
+ (command "$CALL(GetBinDir)llvm-ld "),
+ (out_file_option "-b"),
+ (actions (case
+ (switch_on "O0"), (append_cmd "-disable-opt"),
+ (switch_on "O1"), (append_cmd "-disable-opt"),
+// Whenever O3 is not specified on the command line, default i.e. disable-inlining will always be added.
+ (switch_on "O2"), (append_cmd ""),
+ (switch_on "O3"), (append_cmd ""),
+ (default), (append_cmd "-disable-inlining")))
+]>;
+
+// optimizer step.
+def pic16passes : Tool<[
+ (in_language "llvm-bitcode"),
+ (out_language "llvm-bitcode"),
+ (output_suffix "obc"),
+ (command "$CALL(GetBinDir)opt -pic16cloner -pic16overlay -f"),
+ (actions (case
+ (switch_on "O0"), (append_cmd "-disable-opt")))
+]>;
+
+def llc : Tool<[
+ (in_language "llvm-bitcode"),
+ (out_language "assembler"),
+ (output_suffix "s"),
+ (command "$CALL(GetBinDir)llc -march=pic16 -disable-jump-tables -pre-RA-sched=list-burr -f"),
+ (actions (case
+ (switch_on "S"), (stop_compilation),
+// (not_empty "Wllc,"), (unpack_values "Wllc,"),
+// (not_empty "pre-RA-sched"), (forward "pre-RA-sched")))
+ (not_empty "regalloc"), (forward "regalloc"),
+ (empty "regalloc"), (append_cmd "-regalloc=linearscan")))
+]>;
+
+def gpasm : Tool<[
+ (in_language "assembler"),
+ (out_language "object-code"),
+ (output_suffix "o"),
+ (command "$CALL(GetBinDir)gpasm -z -r decimal -I $CALL(GetStdAsmHeadersDir) -C -c -w 2"),
+ (actions (case
+ (switch_on "c"), (stop_compilation),
+ (switch_on "g"), (append_cmd "-g"),
+ (not_empty "p"), (forward "p"),
+ (empty "p"), (append_cmd "-p 16f1xxx"),
+ (not_empty "Wa,"), (forward_value "Wa,")))
+]>;
+
+def mplink : Tool<[
+ (in_language "object-code"),
+ (out_language "executable"),
+ (output_suffix "cof"),
+ (command "$CALL(GetBinDir)mplink -e -k $CALL(GetStdLinkerScriptsDir) -l $CALL(GetStdLibsDir) intrinsics.lib stdn.lib"),
+ (actions (case
+ (not_empty "Wl,"), (forward_value "Wl,"),
+ (switch_on "X"), (append_cmd "-x"),
+ (not_empty "L"), (forward_as "L", "-l"),
+ (not_empty "K"), (forward_as "K", "-k"),
+ (not_empty "m"), (forward "m"),
+ (not_empty "p"), [(forward "p"), (append_cmd "-c")],
+ (empty "p"), (append_cmd "-p 16f1xxx -c"),
+// (not_empty "l"), [(unpack_values "l"),(append_cmd ".lib")])),
+ (not_empty "k"), (forward "k"),
+ (not_empty "l"), (forward "l"))),
+ (join)
+]>;
+
+// Language map
+
+def LanguageMap : LanguageMap<[
+ LangToSuffixes<"c", ["c"]>,
+ LangToSuffixes<"c-cpp-output", ["i"]>,
+ LangToSuffixes<"assembler", ["s"]>,
+ LangToSuffixes<"assembler-with-cpp", ["S"]>,
+ LangToSuffixes<"llvm-assembler", ["ll"]>,
+ LangToSuffixes<"llvm-bitcode", ["bc"]>,
+ LangToSuffixes<"object-code", ["o"]>,
+ LangToSuffixes<"executable", ["cof"]>
+]>;
+
+// Compilation graph
+
+def CompilationGraph : CompilationGraph<[
+ Edge<"root", "clang_cc">,
+ Edge<"root", "llvm_ld">,
+ OptionalEdge<"root", "llvm_ld_optimizer", (case
+ (switch_on "S"), (inc_weight),
+ (switch_on "c"), (inc_weight))>,
+ Edge<"root", "gpasm">,
+ Edge<"root", "mplink">,
+ Edge<"clang_cc", "llvm_ld">,
+ OptionalEdge<"clang_cc", "llvm_ld_optimizer", (case
+ (switch_on "S"), (inc_weight),
+ (switch_on "c"), (inc_weight))>,
+ Edge<"llvm_ld", "pic16passes">,
+ Edge<"llvm_ld_optimizer", "pic16passes">,
+ Edge<"pic16passes", "llc">,
+ Edge<"llc", "gpasm">,
+ Edge<"gpasm", "mplink">
+]>;
diff --git a/contrib/llvm/tools/llvmc/example/mcc16/plugins/PIC16Base/PluginMain.cpp b/contrib/llvm/tools/llvmc/example/mcc16/plugins/PIC16Base/PluginMain.cpp
new file mode 100644
index 0000000..9b2f9fc5
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/example/mcc16/plugins/PIC16Base/PluginMain.cpp
@@ -0,0 +1,106 @@
+#include "AutoGenerated.inc"
+
+#include "llvm/System/Path.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+namespace llvmc {
+ extern char *ProgramName;
+}
+
+
+
+// Returns the platform specific directory separator via #ifdefs.
+// FIXME: This currently work on linux and windows only. It does not
+// work on other unices.
+static std::string GetDirSeparator() {
+#if __linux__ || __APPLE__
+ return "/";
+#else
+ return "\\";
+#endif
+}
+
+namespace hooks {
+// Get preprocessor define for the part.
+// It is __partname format in lower case.
+std::string
+GetLowerCasePartDefine(void) {
+ std::string Partname;
+ if (AutoGeneratedParameter_p.empty()) {
+ Partname = "16f1xxx";
+ } else {
+ Partname = AutoGeneratedParameter_p;
+ }
+
+ std::string LowerCase;
+ for (unsigned i = 0; i <= Partname.size(); i++) {
+ LowerCase.push_back(std::tolower(Partname[i]));
+ }
+
+ return "__" + LowerCase;
+}
+
+std::string
+GetUpperCasePartDefine(void) {
+ std::string Partname;
+ if (AutoGeneratedParameter_p.empty()) {
+ Partname = "16f1xxx";
+ } else {
+ Partname = AutoGeneratedParameter_p;
+ }
+
+ std::string UpperCase;
+ for (unsigned i = 0; i <= Partname.size(); i++) {
+ UpperCase.push_back(std::toupper(Partname[i]));
+ }
+
+ return "__" + UpperCase;
+}
+
+
+// Get the dir where c16 executables reside.
+std::string GetBinDir() {
+ // Construct a Path object from the program name.
+ void *P = (void*) (intptr_t) GetBinDir;
+ sys::Path ProgramFullPath
+ = sys::Path::GetMainExecutable(llvmc::ProgramName, P);
+
+ // Get the dir name for the program. It's last component should be 'bin'.
+ std::string BinDir = ProgramFullPath.getDirname();
+
+ // llvm::errs() << "BinDir: " << BinDir << '\n';
+ return BinDir + GetDirSeparator();
+}
+
+// Get the Top-level Installation dir for c16.
+std::string GetInstallDir() {
+ sys::Path BinDirPath = sys::Path(GetBinDir());
+
+ // Go one more level up to get the install dir.
+ std::string InstallDir = BinDirPath.getDirname();
+
+ return InstallDir + GetDirSeparator();
+}
+
+// Get the dir where the c16 header files reside.
+std::string GetStdHeadersDir() {
+ return GetInstallDir() + "include";
+}
+
+// Get the dir where the assembler header files reside.
+std::string GetStdAsmHeadersDir() {
+ return GetInstallDir() + "inc";
+}
+
+// Get the dir where the linker scripts reside.
+std::string GetStdLinkerScriptsDir() {
+ return GetInstallDir() + "lkr";
+}
+
+// Get the dir where startup code, intrinsics and lib reside.
+std::string GetStdLibsDir() {
+ return GetInstallDir() + "lib";
+}
+}
diff --git a/contrib/llvm/tools/llvmc/plugins/Base/Base.td.in b/contrib/llvm/tools/llvmc/plugins/Base/Base.td.in
new file mode 100644
index 0000000..23f46b7
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/plugins/Base/Base.td.in
@@ -0,0 +1,373 @@
+//===- Base.td - LLVMC 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 compilation graph description used by llvmc.
+//
+//===----------------------------------------------------------------------===//
+
+include "llvm/CompilerDriver/Common.td"
+
+// Options
+
+def OptList : OptionList<[
+ (switch_option "emit-llvm",
+ (help "Emit LLVM .ll files instead of native object files")),
+ (switch_option "E",
+ (help "Stop after the preprocessing stage, do not run the compiler")),
+ (switch_option "fsyntax-only",
+ (help "Stop after checking the input for syntax errors")),
+ (switch_option "opt",
+ (help "Enable opt")),
+ (switch_option "O0",
+ (help "Turn off optimization"), (zero_or_more)),
+ (switch_option "O1",
+ (help "Optimization level 1"), (zero_or_more)),
+ (switch_option "O2",
+ (help "Optimization level 2"), (zero_or_more)),
+ (switch_option "O3",
+ (help "Optimization level 3"), (zero_or_more)),
+ (switch_option "S",
+ (help "Stop after compilation, do not assemble")),
+ (switch_option "c",
+ (help "Compile and assemble, but do not link")),
+ (switch_option "pthread",
+ (help "Enable threads")),
+ (switch_option "m32",
+ (help "Generate code for a 32-bit environment"), (hidden)),
+ (switch_option "m64",
+ (help "Generate code for a 64-bit environment"), (hidden)),
+ (switch_option "fPIC",
+ (help "Relocation model: PIC"), (hidden)),
+ (switch_option "mdynamic-no-pic",
+ (help "Relocation model: dynamic-no-pic"), (hidden)),
+ (switch_option "shared",
+ (help "Create a DLL instead of the regular executable")),
+ (parameter_option "linker",
+ (help "Choose linker (possible values: gcc, g++)")),
+ (parameter_option "mtune",
+ (help "Target a specific CPU type"), (hidden), (forward_not_split)),
+
+ // TODO: Add a conditional compilation mechanism to make Darwin-only options
+ // like '-arch' really Darwin-only.
+
+ (parameter_option "arch",
+ (help "Compile for the specified target architecture"), (hidden)),
+ (parameter_option "march",
+ (help "A synonym for -mtune"), (hidden), (forward_not_split)),
+ (parameter_option "mcpu",
+ (help "A deprecated synonym for -mtune"), (hidden), (forward_not_split)),
+ (switch_option "mfix-and-continue",
+ (help "Needed by gdb to load .o files dynamically"), (hidden)),
+ (parameter_option "MF",
+ (help "Specify a file to write dependencies to"), (hidden)),
+ (parameter_list_option "MT",
+ (help "Change the name of the rule emitted by dependency generation"),
+ (hidden)),
+ (parameter_list_option "include",
+ (help "Include the named file prior to preprocessing")),
+ (parameter_list_option "iquote",
+ (help "Search dir only for files requested with #inlcude \"file\""),
+ (hidden)),
+ (parameter_list_option "framework",
+ (help "Specifies a framework to link against")),
+ (parameter_list_option "weak_framework",
+ (help "Specifies a framework to weakly link against"), (hidden)),
+ (parameter_option "filelist", (hidden),
+ (help "Link the files listed in file")),
+ (prefix_list_option "F",
+ (help "Add a directory to framework search path")),
+ (prefix_list_option "I",
+ (help "Add a directory to include path")),
+ (prefix_list_option "D",
+ (help "Define a macro")),
+ (parameter_list_option "Xpreprocessor", (hidden),
+ (help "Pass options to preprocessor")),
+ (prefix_list_option "Wa,", (comma_separated),
+ (help "Pass options to assembler")),
+ (parameter_list_option "Xassembler", (hidden),
+ (help "Pass options to assembler")),
+ (prefix_list_option "Wllc,", (comma_separated),
+ (help "Pass options to llc")),
+ (prefix_list_option "L",
+ (help "Add a directory to link path")),
+ (prefix_list_option "l",
+ (help "Search a library when linking")),
+ (prefix_list_option "Wl,",
+ (help "Pass options to linker")),
+ (parameter_list_option "Xlinker", (hidden),
+ (help "Pass options to linker")),
+ (prefix_list_option "Wo,", (comma_separated),
+ (help "Pass options to opt")),
+ (prefix_list_option "m",
+ (help "Enable or disable various extensions (-mmmx, -msse, etc.)"),
+ (hidden)),
+ (switch_option "dynamiclib", (hidden),
+ (help "Produce a dynamic library")),
+ (switch_option "prebind", (hidden),
+ (help "Prebind all undefined symbols")),
+ (switch_option "dead_strip", (hidden),
+ (help "Remove unreachable blocks of code")),
+ (switch_option "single_module", (hidden),
+ (help "Build the library so it contains only one module")),
+ (parameter_option "install_name", (hidden),
+ (help "File name the library will be installed in")),
+ (parameter_option "compatibility_version", (hidden),
+ (help "Compatibility version number")),
+ (parameter_option "current_version", (hidden),
+ (help "Current version number"))
+]>;
+
+// Option preprocessor.
+
+def Preprocess : OptionPreprocessor<
+(case (not (any_switch_on ["O0", "O1", "O2", "O3"])),
+ (set_option "O2"),
+ (and (switch_on "O3"), (any_switch_on ["O0", "O1", "O2"])),
+ (unset_option ["O0", "O1", "O2"]),
+ (and (switch_on "O2"), (any_switch_on ["O0", "O1"])),
+ (unset_option ["O0", "O1"]),
+ (switch_on ["O1", "O0"]),
+ (unset_option "O0"))
+>;
+
+// Tools
+
+class llvm_gcc_based <string cmd_prefix, string in_lang,
+ string E_ext, string out_lang> : Tool<
+[(in_language in_lang),
+ (out_language "llvm-bitcode"),
+ (output_suffix out_lang),
+ (command cmd_prefix),
+ (actions
+ (case
+ (and (not_empty "o"),
+ (multiple_input_files), (or (switch_on "S"), (switch_on "c"))),
+ (error "cannot specify -o with -c or -S with multiple files"),
+ (switch_on "E"),
+ [(forward "E"), (stop_compilation), (output_suffix E_ext)],
+ (and (switch_on "E"), (empty "o")), (no_out_file),
+ (switch_on ["emit-llvm", "S"]),
+ [(output_suffix "ll"), (stop_compilation)],
+ (switch_on ["emit-llvm", "c"]), (stop_compilation),
+ (switch_on "fsyntax-only"), [(forward "fsyntax-only"),
+ (no_out_file), (stop_compilation)],
+ (switch_on ["S", "emit-llvm"]), [(forward "S"), (forward "emit-llvm")],
+ (not (or (switch_on ["S", "emit-llvm"]), (switch_on "fsyntax-only"))),
+ [(append_cmd "-c"), (append_cmd "-emit-llvm")],
+
+ // Forwards
+ (not_empty "Xpreprocessor"), (forward "Xpreprocessor"),
+ (not_empty "include"), (forward "include"),
+ (not_empty "iquote"), (forward "iquote"),
+ (not_empty "save-temps"), (append_cmd "-save-temps"),
+ (not_empty "I"), (forward "I"),
+ (not_empty "F"), (forward "F"),
+ (not_empty "D"), (forward "D"),
+ (not_empty "arch"), (forward "arch"),
+ (not_empty "march"), (forward "march"),
+ (not_empty "mtune"), (forward "mtune"),
+ (not_empty "mcpu"), (forward "mcpu"),
+ (not_empty "m"), (forward "m"),
+ (switch_on "mfix-and-continue"), (forward "mfix-and-continue"),
+ (switch_on "m32"), (forward "m32"),
+ (switch_on "m64"), (forward "m64"),
+ (switch_on "O0"), (forward "O0"),
+ (switch_on "O1"), (forward "O1"),
+ (switch_on "O2"), (forward "O2"),
+ (switch_on "O3"), (forward "O3"),
+ (switch_on "fPIC"), (forward "fPIC"),
+ (switch_on "mdynamic-no-pic"), (forward "mdynamic-no-pic"),
+ (not_empty "MF"), (forward "MF"),
+ (not_empty "MT"), (forward "MT"))),
+ (sink)
+]>;
+
+def llvm_gcc_c : llvm_gcc_based<"@LLVMGCCCOMMAND@ -x c", "c", "i", "bc">;
+def llvm_gcc_cpp : llvm_gcc_based<"@LLVMGXXCOMMAND@ -x c++", "c++", "i", "bc">;
+def llvm_gcc_m : llvm_gcc_based<"@LLVMGCCCOMMAND@ -x objective-c",
+ "objective-c", "mi", "bc">;
+def llvm_gcc_mxx : llvm_gcc_based<"@LLVMGCCCOMMAND@ -x objective-c++",
+ "objective-c++", "mi", "bc">;
+
+def llvm_gcc_c_pch : llvm_gcc_based<"@LLVMGCCCOMMAND@ -x c-header",
+ "c-header", "i", "gch">;
+def llvm_gcc_cpp_pch : llvm_gcc_based<"@LLVMGXXCOMMAND@ -x c++-header",
+ "c++-header",
+ "i", "gch">;
+def llvm_gcc_m_pch : llvm_gcc_based<"@LLVMGCCCOMMAND@ -x objective-c-header",
+ "objective-c-header",
+ "mi", "gch">;
+def llvm_gcc_mxx_pch
+ : llvm_gcc_based<"@LLVMGCCCOMMAND@ -x objective-c++-header",
+ "objective-c++-header", "mi", "gch">;
+
+def opt : Tool<
+[(in_language "llvm-bitcode"),
+ (out_language "llvm-bitcode"),
+ (output_suffix "bc"),
+ (actions (case (not_empty "Wo,"), (forward_value "Wo,"),
+ (switch_on "O1"), (forward "O1"),
+ (switch_on "O2"), (forward "O2"),
+ (switch_on "O3"), (forward "O3"))),
+ (command "opt -f")
+]>;
+
+def llvm_as : Tool<
+[(in_language "llvm-assembler"),
+ (out_language "llvm-bitcode"),
+ (output_suffix "bc"),
+ (command "llvm-as"),
+ (actions (case (switch_on "emit-llvm"), (stop_compilation)))
+]>;
+
+def llvm_gcc_assembler : Tool<
+[(in_language "assembler"),
+ (out_language "object-code"),
+ (output_suffix "o"),
+ (command "@LLVMGCCCOMMAND@ -c -x assembler"),
+ (actions (case
+ (switch_on "c"), (stop_compilation),
+ (not_empty "arch"), (forward "arch"),
+ (not_empty "Xassembler"), (forward "Xassembler"),
+ (switch_on "m32"), (forward "m32"),
+ (switch_on "m64"), (forward "m64"),
+ (not_empty "Wa,"), (forward "Wa,")))
+]>;
+
+def llc : Tool<
+[(in_language ["llvm-bitcode", "llvm-assembler"]),
+ (out_language "assembler"),
+ (output_suffix "s"),
+ (command "llc"),
+ (actions (case
+ (switch_on "S"), (stop_compilation),
+ (switch_on "O0"), (forward "O0"),
+ (switch_on "O1"), (forward "O1"),
+ (switch_on "O2"), (forward "O2"),
+ (switch_on "O3"), (forward "O3"),
+ (switch_on "fPIC"), (append_cmd "-relocation-model=pic"),
+ (switch_on "mdynamic-no-pic"),
+ (append_cmd "-relocation-model=dynamic-no-pic"),
+ (not_empty "march"), (forward_as "mtune", "-mcpu"),
+ (not_empty "mtune"), (forward_as "mtune", "-mcpu"),
+ (not_empty "mcpu"), (forward "mcpu"),
+ (not_empty "m"), (forward_transformed_value "m", "ConvertToMAttr"),
+ (not_empty "Wllc,"), (forward_value "Wllc,")))
+]>;
+
+// Base class for linkers
+class llvm_gcc_based_linker <string cmd_prefix> : Tool<
+[(in_language ["object-code", "static-library"]),
+ (out_language "executable"),
+ (output_suffix "out"),
+ (command cmd_prefix),
+ (works_on_empty (case (not_empty "filelist"), true,
+ (default), false)),
+ (join),
+ (actions (case
+ (switch_on "pthread"), (append_cmd "-lpthread"),
+ (not_empty "L"), (forward "L"),
+ (not_empty "F"), (forward "F"),
+ (not_empty "arch"), (forward "arch"),
+ (not_empty "framework"), (forward "framework"),
+ (not_empty "weak_framework"), (forward "weak_framework"),
+ (not_empty "filelist"), (forward "filelist"),
+ (switch_on "m32"), (forward "m32"),
+ (switch_on "m64"), (forward "m64"),
+ (not_empty "l"), (forward "l"),
+ (not_empty "Xlinker"), (forward "Xlinker"),
+ (not_empty "Wl,"), (forward "Wl,"),
+ (switch_on "shared"), (forward "shared"),
+ (switch_on "dynamiclib"), (forward "dynamiclib"),
+ (switch_on "prebind"), (forward "prebind"),
+ (switch_on "dead_strip"), (forward "dead_strip"),
+ (switch_on "single_module"), (forward "single_module"),
+ (not_empty "compatibility_version"),
+ (forward "compatibility_version"),
+ (not_empty "current_version"), (forward "current_version"),
+ (not_empty "install_name"), (forward "install_name")))
+]>;
+
+// Default linker
+def llvm_gcc_linker : llvm_gcc_based_linker<"@LLVMGCCCOMMAND@">;
+// Alternative linker for C++
+def llvm_gcc_cpp_linker : llvm_gcc_based_linker<"@LLVMGXXCOMMAND@">;
+
+// Language map
+
+def LanguageMap : LanguageMap<
+ [LangToSuffixes<"c++", ["cc", "cp", "cxx", "cpp", "CPP", "c++", "C"]>,
+ LangToSuffixes<"c++-header", ["hpp"]>,
+ LangToSuffixes<"c", ["c"]>,
+ LangToSuffixes<"c-header", ["h"]>,
+ LangToSuffixes<"c-cpp-output", ["i"]>,
+ LangToSuffixes<"objective-c-cpp-output", ["mi"]>,
+ LangToSuffixes<"objective-c++", ["mm"]>,
+ LangToSuffixes<"objective-c++-header", ["hmm"]>,
+ LangToSuffixes<"objective-c", ["m"]>,
+ LangToSuffixes<"objective-c-header", ["hm"]>,
+ LangToSuffixes<"assembler", ["s"]>,
+ LangToSuffixes<"assembler-with-cpp", ["S"]>,
+ LangToSuffixes<"llvm-assembler", ["ll"]>,
+ LangToSuffixes<"llvm-bitcode", ["bc"]>,
+ LangToSuffixes<"object-code", ["o", "*empty*"]>,
+ LangToSuffixes<"static-library", ["a", "lib"]>,
+ LangToSuffixes<"executable", ["out"]>
+ ]>;
+
+// Compilation graph
+
+def CompilationGraph : CompilationGraph<[
+ Edge<"root", "llvm_gcc_c">,
+ Edge<"root", "llvm_gcc_assembler">,
+ Edge<"root", "llvm_gcc_cpp">,
+ Edge<"root", "llvm_gcc_m">,
+ Edge<"root", "llvm_gcc_mxx">,
+ Edge<"root", "llc">,
+
+ Edge<"root", "llvm_gcc_c_pch">,
+ Edge<"root", "llvm_gcc_cpp_pch">,
+ Edge<"root", "llvm_gcc_m_pch">,
+ Edge<"root", "llvm_gcc_mxx_pch">,
+
+ Edge<"llvm_gcc_c", "llc">,
+ Edge<"llvm_gcc_cpp", "llc">,
+ Edge<"llvm_gcc_m", "llc">,
+ Edge<"llvm_gcc_mxx", "llc">,
+ Edge<"llvm_as", "llc">,
+
+ OptionalEdge<"root", "llvm_as",
+ (case (switch_on "emit-llvm"), (inc_weight))>,
+ OptionalEdge<"llvm_gcc_c", "opt", (case (switch_on "opt"), (inc_weight))>,
+ OptionalEdge<"llvm_gcc_cpp", "opt", (case (switch_on "opt"), (inc_weight))>,
+ OptionalEdge<"llvm_gcc_m", "opt", (case (switch_on "opt"), (inc_weight))>,
+ OptionalEdge<"llvm_gcc_mxx", "opt", (case (switch_on "opt"), (inc_weight))>,
+ OptionalEdge<"llvm_as", "opt", (case (switch_on "opt"), (inc_weight))>,
+ Edge<"opt", "llc">,
+
+ Edge<"llc", "llvm_gcc_assembler">,
+ Edge<"llvm_gcc_assembler", "llvm_gcc_linker">,
+ OptionalEdge<"llvm_gcc_assembler", "llvm_gcc_cpp_linker",
+ (case
+ (or (input_languages_contain "c++"),
+ (input_languages_contain "objective-c++")),
+ (inc_weight),
+ (or (parameter_equals "linker", "g++"),
+ (parameter_equals "linker", "c++")), (inc_weight))>,
+
+
+ Edge<"root", "llvm_gcc_linker">,
+ OptionalEdge<"root", "llvm_gcc_cpp_linker",
+ (case
+ (or (input_languages_contain "c++"),
+ (input_languages_contain "objective-c++")),
+ (inc_weight),
+ (or (parameter_equals "linker", "g++"),
+ (parameter_equals "linker", "c++")), (inc_weight))>
+ ]>;
diff --git a/contrib/llvm/tools/llvmc/plugins/Base/Hooks.cpp b/contrib/llvm/tools/llvmc/plugins/Base/Hooks.cpp
new file mode 100644
index 0000000..661a914
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/plugins/Base/Hooks.cpp
@@ -0,0 +1,33 @@
+#include <string>
+#include <vector>
+
+namespace hooks {
+typedef std::vector<std::string> StrVec;
+
+/// ConvertToMAttr - Convert -m* and -mno-* to -mattr=+*,-*
+std::string ConvertToMAttr(const StrVec& Opts) {
+ std::string out("-mattr=");
+
+ bool firstIter = true;
+ for (StrVec::const_iterator B = Opts.begin(), E = Opts.end(); B!=E; ++B) {
+ const std::string& Arg = *B;
+
+ if (firstIter)
+ firstIter = false;
+ else
+ out += ",";
+
+ if (Arg.find("no-") == 0 && Arg[3] != 0) {
+ out += '-';
+ out += Arg.c_str() + 3;
+ }
+ else {
+ out += '+';
+ out += Arg;
+ }
+ }
+
+ return out;
+}
+
+}
diff --git a/contrib/llvm/tools/llvmc/plugins/Base/Makefile b/contrib/llvm/tools/llvmc/plugins/Base/Makefile
new file mode 100644
index 0000000..ebc4335
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/plugins/Base/Makefile
@@ -0,0 +1,15 @@
+##===- tools/llvmc/plugins/Base/Makefile -------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../../..
+
+LLVMC_PLUGIN = Base
+BUILT_SOURCES = AutoGenerated.inc
+
+include $(LEVEL)/Makefile.common
diff --git a/contrib/llvm/tools/llvmc/plugins/Base/PluginMain.cpp b/contrib/llvm/tools/llvmc/plugins/Base/PluginMain.cpp
new file mode 100644
index 0000000..add8acb
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/plugins/Base/PluginMain.cpp
@@ -0,0 +1 @@
+#include "AutoGenerated.inc"
diff --git a/contrib/llvm/tools/llvmc/plugins/Clang/Clang.td b/contrib/llvm/tools/llvmc/plugins/Clang/Clang.td
new file mode 100644
index 0000000..988d9b1
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/plugins/Clang/Clang.td
@@ -0,0 +1,101 @@
+include "llvm/CompilerDriver/Common.td"
+
+def Priority : PluginPriority<1>;
+
+def Options : OptionList<[
+// Extern options
+(switch_option "E", (extern)),
+(switch_option "S", (extern)),
+(switch_option "c", (extern)),
+(switch_option "fsyntax-only", (extern)),
+(switch_option "emit-llvm", (extern)),
+(switch_option "pthread", (extern)),
+(parameter_list_option "I", (extern)),
+(parameter_list_option "include", (extern)),
+(parameter_list_option "L", (extern)),
+(parameter_list_option "l", (extern)),
+(prefix_list_option "Wa,", (extern)),
+(prefix_list_option "Wl,", (extern)),
+
+(switch_option "clang", (help "Use Clang instead of llvm-gcc"))
+]>;
+
+class clang_based<string language, string cmd, string ext_E> : Tool<
+[(in_language language),
+ (out_language "llvm-bitcode"),
+ (output_suffix "bc"),
+ (command cmd),
+ (actions (case (switch_on "E"),
+ [(forward "E"), (stop_compilation), (output_suffix ext_E)],
+ (and (switch_on "E"), (empty "o")), (no_out_file),
+ (switch_on "fsyntax-only"), (stop_compilation),
+ (switch_on ["S", "emit-llvm"]),
+ [(append_cmd "-emit-llvm"),
+ (stop_compilation), (output_suffix "ll")],
+ (not (switch_on ["S", "emit-llvm"])),
+ (append_cmd "-emit-llvm-bc"),
+ (switch_on ["c", "emit-llvm"]),
+ (stop_compilation),
+ (not_empty "include"), (forward "include"),
+ (not_empty "I"), (forward "I"))),
+ (sink)
+]>;
+
+def clang_c : clang_based<"c", "clang -x c", "i">;
+def clang_cpp : clang_based<"c++", "clang -x c++", "i">;
+def clang_objective_c : clang_based<"objective-c",
+ "clang -x objective-c", "mi">;
+def clang_objective_cpp : clang_based<"objective-c++",
+ "clang -x objective-c++", "mi">;
+
+def as : Tool<
+[(in_language "assembler"),
+ (out_language "object-code"),
+ (output_suffix "o"),
+ (command "as"),
+ (actions (case (not_empty "Wa,"), (forward_value "Wa,"),
+ (switch_on "c"), (stop_compilation)))
+]>;
+
+// Default linker
+def llvm_ld : Tool<
+[(in_language "object-code"),
+ (out_language "executable"),
+ (output_suffix "out"),
+ (command "llvm-ld -native -disable-internalize"),
+ (actions (case
+ (switch_on "pthread"), (append_cmd "-lpthread"),
+ (not_empty "L"), (forward "L"),
+ (not_empty "l"), (forward "l"),
+ (not_empty "Wl,"), (forward_value "Wl,"))),
+ (join)
+]>;
+
+// Language map
+
+def LanguageMap : LanguageMap<[
+ LangToSuffixes<"c++", ["cc", "cp", "cxx", "cpp", "CPP", "c++", "C"]>,
+ LangToSuffixes<"c", ["c"]>,
+ LangToSuffixes<"objective-c", ["m"]>,
+ LangToSuffixes<"c-cpp-output", ["i"]>,
+ LangToSuffixes<"objective-c-cpp-output", ["mi"]>
+]>;
+
+// Compilation graph
+
+def CompilationGraph : CompilationGraph<[
+ OptionalEdge<"root", "clang_c",
+ (case (switch_on "clang"), (inc_weight))>,
+ OptionalEdge<"root", "clang_cpp",
+ (case (switch_on "clang"), (inc_weight))>,
+ OptionalEdge<"root", "clang_objective_c",
+ (case (switch_on "clang"), (inc_weight))>,
+ OptionalEdge<"root", "clang_objective_cpp",
+ (case (switch_on "clang"), (inc_weight))>,
+ Edge<"clang_c", "llc">,
+ Edge<"clang_cpp", "llc">,
+ Edge<"clang_objective_c", "llc">,
+ Edge<"clang_objective_cpp", "llc">,
+ OptionalEdge<"llc", "as", (case (switch_on "clang"), (inc_weight))>,
+ Edge<"as", "llvm_ld">
+]>;
diff --git a/contrib/llvm/tools/llvmc/plugins/Clang/Makefile b/contrib/llvm/tools/llvmc/plugins/Clang/Makefile
new file mode 100644
index 0000000..5e5b88a
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/plugins/Clang/Makefile
@@ -0,0 +1,15 @@
+##===- tools/llvmc/plugins/Clang/Makefile ------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../../..
+
+LLVMC_PLUGIN = Clang
+BUILT_SOURCES = AutoGenerated.inc
+
+include $(LEVEL)/Makefile.common
diff --git a/contrib/llvm/tools/llvmc/plugins/Clang/PluginMain.cpp b/contrib/llvm/tools/llvmc/plugins/Clang/PluginMain.cpp
new file mode 100644
index 0000000..add8acb
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/plugins/Clang/PluginMain.cpp
@@ -0,0 +1 @@
+#include "AutoGenerated.inc"
diff --git a/contrib/llvm/tools/llvmc/plugins/Makefile b/contrib/llvm/tools/llvmc/plugins/Makefile
new file mode 100644
index 0000000..37dac6f
--- /dev/null
+++ b/contrib/llvm/tools/llvmc/plugins/Makefile
@@ -0,0 +1,18 @@
+##===- tools/llvmc/plugins/Makefile ------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open
+# Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../..
+
+ifneq ($(LLVMC_BUILTIN_PLUGINS),)
+DIRS = $(LLVMC_BUILTIN_PLUGINS)
+endif
+
+export LLVMC_BUILTIN_PLUGIN=1
+
+include $(LEVEL)/Makefile.common
OpenPOWER on IntegriCloud