mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
Drop llvmc also, it will be replaced by shiny new llvmc2
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50615 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a9d9ca469f
commit
cae8ccd12d
@ -1,431 +0,0 @@
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
llvmc - The LLVM Compiler Driver (experimental)
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<llvmc> [I<options>] [I<filenames>...]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<llvmc> is a configurable driver for invoking other LLVM (and non-LLVM) tools
|
||||
in order to compile, optimize and link software for multiple languages. For
|
||||
those familiar with FSF's B<gcc> tool, it is very similar. Please note that
|
||||
B<llvmc> is considered an experimental tool. B<llvmc> has the following goals:
|
||||
|
||||
=over
|
||||
|
||||
=item * provide a single point of access to the LLVM tool set,
|
||||
|
||||
=item * hide the complexities of the LLVM tools through a single interface,
|
||||
|
||||
=item * make integration of existing non-LLVM tools simple,
|
||||
|
||||
=item * extend the capabilities of minimal front ends, and
|
||||
|
||||
=item * make the interface for compiling consistent for all languages.
|
||||
|
||||
=back
|
||||
|
||||
The tool itself does nothing with a user's program. It merely invokes other
|
||||
tools to get the compilation tasks done.
|
||||
|
||||
The options supported by B<llvmc> generalize the compilation process and
|
||||
provide a consistent and simple interface for multiple programming languages.
|
||||
This makes it easier for developers to get their software compiled with LLVM.
|
||||
Without B<llvmc>, developers would need to understand how to invoke the
|
||||
front-end compiler, optimizer, assembler, and linker in order to compile their
|
||||
programs. B<llvmc>'s sole mission is to trivialize that process.
|
||||
|
||||
=head2 Basic Operation
|
||||
|
||||
B<llvmc> always takes the following basic actions:
|
||||
|
||||
=over
|
||||
|
||||
=item * Command line options and filenames are collected.
|
||||
|
||||
The command line options provide the marching orders to B<llvmc> on what actions
|
||||
it should perform. This is the I<request> the user is making of B<llvmc> and it
|
||||
is interpreted first.
|
||||
|
||||
=item * Configuration files are read.
|
||||
|
||||
Based on the options and the suffixes of the filenames presented, a set of
|
||||
configuration files are read to configure the actions B<llvmc> will take.
|
||||
Configuration files are provided by either LLVM or the front end compiler tools
|
||||
that B<llvmc> invokes. Users generally don't need to be concerned with the
|
||||
contents of the configuration files.
|
||||
|
||||
=item * Determine actions to take.
|
||||
|
||||
The tool chain needed to complete the task is determined. This is the primary
|
||||
work of B<llvmc>. It breaks the request specified by the command line options
|
||||
into a set of basic actions to be done:
|
||||
|
||||
=over
|
||||
|
||||
=item * Pre-processing: gathering/filtering compiler input (optional).
|
||||
|
||||
=item * Translation: source language to bitcode conversion.
|
||||
|
||||
=item * Assembly: bitcode to native code conversion.
|
||||
|
||||
=item * Optimization: conversion of bitcode to something that runs faster.
|
||||
|
||||
=item * Linking: combining multiple bitcode files to produce executable program.
|
||||
|
||||
=back
|
||||
|
||||
=item * Execute actions.
|
||||
|
||||
The actions determined previously are executed sequentially and then
|
||||
B<llvmc> terminates.
|
||||
|
||||
=back
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
=head2 Control Options
|
||||
|
||||
Control options tell B<llvmc> what to do at a high level. The
|
||||
following control options are defined:
|
||||
|
||||
=over
|
||||
|
||||
=item B<-c> or B<--compile>
|
||||
|
||||
This option specifies that the linking phase is not to be run. All
|
||||
previous phases, if applicable will run. This is generally how a given
|
||||
bitcode file is compiled and optimized for a source language module.
|
||||
|
||||
=item B<-k> or B<--link> or default
|
||||
|
||||
This option (or the lack of any control option) specifies that all stages
|
||||
of compilation, optimization, and linking should be attempted. Source files
|
||||
specified on the command line will be compiled and linked with objects and
|
||||
libraries also specified.
|
||||
|
||||
=item B<-S>
|
||||
|
||||
This option specifies that compilation should end in the creation of
|
||||
an LLVM assembly file that can be later converted to an LLVM object
|
||||
file.
|
||||
|
||||
=item B<-E>
|
||||
|
||||
This option specifies that no compilation or linking should be
|
||||
performed. Only pre-processing, if applicable to the language being
|
||||
compiled, is performed. For languages that support it, this will
|
||||
result in the output containing the raw input to the compiler.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Optimization Options
|
||||
|
||||
Optimization with B<llvmc> is based on goals and specified with
|
||||
the following -O options. The specific details of which
|
||||
optimizations run is controlled by the configuration files because
|
||||
each source language will have different needs.
|
||||
|
||||
=over
|
||||
|
||||
=item B<-O1> or B<-O0> (default, fast compilation)
|
||||
|
||||
Only those optimizations that will hasten the compilation (mostly by reducing
|
||||
the output) are applied. In general these are extremely fast and simple
|
||||
optimizations that reduce emitted code size. The goal here is not to make the
|
||||
resulting program fast but to make the compilation fast. If not specified,
|
||||
this is the default level of optimization.
|
||||
|
||||
=item B<-O2> (basic optimization)
|
||||
|
||||
This level of optimization specifies a balance between generating good code
|
||||
that will execute reasonably quickly and not spending too much time optimizing
|
||||
the code to get there. For example, this level of optimization may include
|
||||
things like global common sub-expression elimination, aggressive dead code
|
||||
elimination, and scalar replication.
|
||||
|
||||
=item B<-O3> (aggressive optimization)
|
||||
|
||||
This level of optimization aggressively optimizes each set of files compiled
|
||||
together. However, no link-time inter-procedural optimization is performed.
|
||||
This level implies all the optimizations of the B<-O1> and B<-O2> optimization
|
||||
levels, and should also provide loop optimizations and compile time
|
||||
inter-procedural optimizations. Essentially, this level tries to do as much
|
||||
as it can with the input it is given but doesn't do any link time IPO.
|
||||
|
||||
=item B<-O4> (link time optimization)
|
||||
|
||||
In addition to the previous three levels of optimization, this level of
|
||||
optimization aggressively optimizes each program at link time. It employs
|
||||
basic analysis and basic link-time inter-procedural optimizations,
|
||||
considering the program as a whole.
|
||||
|
||||
=item B<-O5> (aggressive link time optimization)
|
||||
|
||||
This is the same as B<-O4> except it employs aggressive analyses and
|
||||
aggressive inter-procedural optimization.
|
||||
|
||||
=item B<-O6> (profile guided optimization: not implemented)
|
||||
|
||||
This is the same as B<-O5> except that it employs profile-guided
|
||||
re-optimization of the program after it has executed. Note that this implies
|
||||
a single level of re-optimization based on run time profile analysis. Once
|
||||
the re-optimization has completed, the profiling instrumentation is
|
||||
removed and final optimizations are employed.
|
||||
|
||||
=item B<-O7> (lifelong optimization: not implemented)
|
||||
|
||||
This is the same as B<-O5> and similar to B<-O6> except that re-optimization
|
||||
is performed through the life of the program. That is, each run will update
|
||||
the profile by which future re-optimizations are directed.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Input Options
|
||||
|
||||
=over
|
||||
|
||||
=item B<-l> I<LIBRARY>
|
||||
|
||||
This option instructs B<llvmc> to locate a library named I<LIBRARY> and search
|
||||
it for unresolved symbols when linking the program.
|
||||
|
||||
=item B<-L> F<path>
|
||||
|
||||
This option instructs B<llvmc> to add F<path> to the list of places in which
|
||||
the linker will
|
||||
|
||||
=item B<-x> I<LANGUAGE>
|
||||
|
||||
This option instructs B<llvmc> to regard the following input files as
|
||||
containing programs in the language I<LANGUAGE>. Normally, input file languages
|
||||
are identified by their suffix but this option will override that default
|
||||
behavior. The B<-x> option stays in effect until the end of the options or
|
||||
a new B<-x> option is encountered.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Output Options
|
||||
|
||||
=over
|
||||
|
||||
=item B<-m>I<arch>
|
||||
|
||||
This option selects the back end code generator to use. The I<arch> portion
|
||||
of the option names the back end to use.
|
||||
|
||||
=item B<--native>
|
||||
|
||||
Normally, B<llvmc> produces bitcode files at most stages of compilation.
|
||||
With this option, B<llvmc> will arrange for native object files to be
|
||||
generated with the B<-c> option, native assembly files to be generated
|
||||
with the B<-S> option, and native executables to be generated with the
|
||||
B<--link> option. In the case of the B<-E> option, the output will not
|
||||
differ as there is no I<native> version of pre-processed output.
|
||||
|
||||
=item B<-o> F<filename>
|
||||
|
||||
Specify the output file name. The contents of the file depend on other
|
||||
options.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Information Options
|
||||
|
||||
=over
|
||||
|
||||
=item B<-n> or B<--no-op>
|
||||
|
||||
This option tells B<llvmc> to do everything but actually execute the
|
||||
resulting tools. In combination with the B<-v> option, this causes B<llvmc>
|
||||
to merely print out what it would have done.
|
||||
|
||||
=item B<-v> or B<--verbose>
|
||||
|
||||
This option will cause B<llvmc> to print out (on standard output) each of the
|
||||
actions it takes to accomplish the objective. The output will immediately
|
||||
precede the invocation of other tools.
|
||||
|
||||
=item B<--stats>
|
||||
|
||||
Print all statistics gathered during the compilation to the standard error.
|
||||
Note that this option is merely passed through to the sub-tools to do with
|
||||
as they please.
|
||||
|
||||
=item B<--time-passes>
|
||||
|
||||
Record the amount of time needed for each optimization pass and print it
|
||||
to standard error. Like B<--stats> this option is just passed through to
|
||||
the sub-tools to do with as they please.
|
||||
|
||||
=item B<--time-programs>
|
||||
|
||||
Record the amount of time each program (compilation tool) takes and print
|
||||
it to the standard error.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Language Specific Options
|
||||
|
||||
=over
|
||||
|
||||
=item B<-T,pre>=I<options>
|
||||
|
||||
Pass an arbitrary option to the pre-processor.
|
||||
|
||||
=item B<-T,opt>=I<options>
|
||||
|
||||
Pass an arbitrary option to the optimizer.
|
||||
|
||||
=item B<-T,lnk>=I<options>
|
||||
|
||||
Pass an arbitrary option to the linker.
|
||||
|
||||
=item B<-T,asm>=I<options>
|
||||
|
||||
Pass an arbitrary option to the code generator.
|
||||
|
||||
=back
|
||||
|
||||
=head2 C/C++ Specific Options
|
||||
|
||||
=over
|
||||
|
||||
=item B<-I>F<path>
|
||||
|
||||
This option is just passed through to a C or C++ front end compiler to tell it
|
||||
where include files can be found.
|
||||
|
||||
=item B<-D>F<symbol>
|
||||
|
||||
This option is just passed through to a C or C++ front end compiler to tell it
|
||||
to define a symbol.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Miscellaneous Options
|
||||
|
||||
=over
|
||||
|
||||
=item B<--help>
|
||||
|
||||
Print a summary of command line options.
|
||||
|
||||
=item B<--version>
|
||||
|
||||
This option will cause B<llvmc> to print out its version number and terminate.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Advanced Options
|
||||
|
||||
You better know what you're doing if you use these options. Improper use
|
||||
of these options can produce drastically wrong results.
|
||||
|
||||
=over
|
||||
|
||||
=item B<--config-dir> F<dirname>
|
||||
|
||||
This option tells B<llvmc> to read configuration data from the I<directory>
|
||||
named F<dirname>. Data from such directories will be read in the order
|
||||
specified on the command line after all other standard configuration files have
|
||||
been read. This allows users or groups of users to conveniently create
|
||||
their own configuration directories in addition to the standard ones to which
|
||||
they may not have write access.
|
||||
|
||||
=back
|
||||
|
||||
|
||||
=head2 Unimplemented Options
|
||||
|
||||
The options below are not currently implemented in B<llvmc> but will be
|
||||
eventually. They are documented here as "future design".
|
||||
|
||||
=over
|
||||
|
||||
=item B<--show-config> I<[suffixes...]>
|
||||
|
||||
When this option is given, the only action taken by B<llvmc> is to show its
|
||||
final configuration state in the form of a configuration file. No compilation
|
||||
tasks will be conducted when this option is given; processing will stop once
|
||||
the configuration has been printed. The optional (comma separated) list of
|
||||
suffixes controls what is printed. Without any suffixes, the configuration
|
||||
for all languages is printed. With suffixes, only the languages pertaining
|
||||
to those file suffixes will be printed. The configuration information is
|
||||
printed after all command line options and configuration files have been
|
||||
read and processed. This allows the user to verify that the correct
|
||||
configuration data has been read by B<llvmc>.
|
||||
|
||||
=item B<--config> :I<section>:I<name>=I<value>
|
||||
|
||||
This option instructs B<llvmc> to accept I<value> as the value for configuration
|
||||
item I<name> in the section named I<section>. This is a quick way to override
|
||||
a configuration item on the command line without resorting to changing the
|
||||
configuration files.
|
||||
|
||||
=item B<--config-only-from> F<dirname>
|
||||
|
||||
This option tells B<llvmc> to skip the normal processing of configuration
|
||||
files and only configure from the contents of the F<dirname> directory. Multiple
|
||||
B<--config-only-from> options may be given in which case the directories are
|
||||
read in the order given on the command line.
|
||||
|
||||
=item B<--emit-raw-code>
|
||||
|
||||
No optimization is done whatsoever. The compilers invoked by B<llvmc> with
|
||||
this option given will be instructed to produce raw, unoptimized code. This
|
||||
option is useful only to front end language developers and therefore does not
|
||||
participate in the list of B<-O> options. This is distinctly different from
|
||||
the B<-O0> option (a synonym for B<-O1>) because those optimizations will
|
||||
reduce code size to make compilation faster. With B<--emit-raw-code>, only
|
||||
the full raw code produced by the compiler will be generated.
|
||||
|
||||
=back
|
||||
|
||||
|
||||
=head1 EXIT STATUS
|
||||
|
||||
If B<llvmc> succeeds, it will exit with 0. Otherwise, if an error
|
||||
occurs, it will exit with a non-zero value and no compilation actions
|
||||
will be taken. If one of the compilation tools returns a non-zero
|
||||
status, pending actions will be discarded and B<llvmc> will return the
|
||||
same result code as the failing compilation tool.
|
||||
|
||||
=head1 DEFICIENCIES
|
||||
|
||||
B<llvmc> is considered an experimental LLVM tool because it has these
|
||||
deficiencies:
|
||||
|
||||
=over
|
||||
|
||||
=item Insufficient support for native linking
|
||||
|
||||
Because B<llvm-ld> doesn't handle native linking, neither can B<llvmc>
|
||||
|
||||
=item Poor configuration support
|
||||
|
||||
The support for configuring new languages, etc. is weak. There are many
|
||||
command line configurations that cannot be achieved with the current
|
||||
support. Furthermore the grammar is cumbersome for configuration files.
|
||||
Please see L<http://llvm.org/PR686> for further details.
|
||||
|
||||
=item Does not handle target specific configurations
|
||||
|
||||
This is one of the major deficiencies, also addressed in
|
||||
L<http://llvm.org/PR686>
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<llvm-as|llvm-as>, L<llvm-dis|llvm-dis>, L<llc|llc>, L<llvm-link|llvm-link>
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Maintained by the LLVM Team (L<http://llvm.org>).
|
||||
|
||||
=cut
|
File diff suppressed because it is too large
Load Diff
@ -1,206 +0,0 @@
|
||||
//===- CompilerDriver.h - Compiler Driver -----------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the CompilerDriver class which implements the bulk of the
|
||||
// LLVM Compiler Driver program (llvmc).
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_TOOLS_LLVMC_COMPILERDRIVER_H
|
||||
#define LLVM_TOOLS_LLVMC_COMPILERDRIVER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "llvm/System/Program.h"
|
||||
|
||||
namespace llvm {
|
||||
/// This class provides the high level interface to the LLVM Compiler Driver.
|
||||
/// The driver's purpose is to make it easier for compiler writers and users
|
||||
/// of LLVM to utilize the compiler toolkits and LLVM toolset by learning only
|
||||
/// the interface of one program (llvmc).
|
||||
///
|
||||
/// @see llvmc.cpp
|
||||
/// @brief The interface to the LLVM Compiler Driver.
|
||||
class CompilerDriver {
|
||||
/// @name Types
|
||||
/// @{
|
||||
public:
|
||||
/// @brief A vector of strings, used for argument lists
|
||||
typedef std::vector<std::string> StringVector;
|
||||
|
||||
/// @brief A vector of sys::Path, used for path lists
|
||||
typedef std::vector<sys::Path> PathVector;
|
||||
|
||||
/// @brief A table of strings, indexed typically by Phases
|
||||
typedef std::vector<StringVector> StringTable;
|
||||
|
||||
/// @brief The phases of processing that llvmc understands
|
||||
enum Phases {
|
||||
PREPROCESSING, ///< Source language combining, filtering, substitution
|
||||
TRANSLATION, ///< Translate source -> LLVM bitcode/assembly
|
||||
OPTIMIZATION, ///< Optimize translation result
|
||||
ASSEMBLY, ///< Convert program to executable
|
||||
LINKING, ///< Link bitcode and native code
|
||||
NUM_PHASES ///< Always last!
|
||||
};
|
||||
|
||||
/// @brief The levels of optimization llvmc understands
|
||||
enum OptimizationLevels {
|
||||
OPT_FAST_COMPILE, ///< Optimize to make >compile< go faster
|
||||
OPT_SIMPLE, ///< Standard/simple optimizations
|
||||
OPT_AGGRESSIVE, ///< Aggressive optimizations
|
||||
OPT_LINK_TIME, ///< Aggressive + LinkTime optimizations
|
||||
OPT_AGGRESSIVE_LINK_TIME, ///< Make it go way fast!
|
||||
OPT_NONE ///< No optimizations. Keep this at the end!
|
||||
};
|
||||
|
||||
/// @brief Action specific flags
|
||||
enum ConfigurationFlags {
|
||||
REQUIRED_FLAG = 0x0001, ///< Should the action always be run?
|
||||
PREPROCESSES_FLAG = 0x0002, ///< Does this action preprocess?
|
||||
TRANSLATES_FLAG = 0x0004, ///< Does this action translate?
|
||||
OUTPUT_IS_ASM_FLAG = 0x0008, ///< Action produces .ll files?
|
||||
FLAGS_MASK = 0x000F ///< Union of all flags
|
||||
};
|
||||
|
||||
/// This type is the input list to the CompilerDriver. It provides
|
||||
/// a vector of pathname/filetype pairs. The filetype is used to look up
|
||||
/// the configuration of the actions to be taken by the driver.
|
||||
/// @brief The Input Data to the execute method
|
||||
typedef std::vector<std::pair<sys::Path,std::string> > InputList;
|
||||
|
||||
/// This type is read from configuration files or otherwise provided to
|
||||
/// the CompilerDriver through a "ConfigDataProvider". It serves as both
|
||||
/// the template of what to do and the actual Action to be executed.
|
||||
/// @brief A structure to hold the action data for a given source
|
||||
/// language.
|
||||
struct Action {
|
||||
Action() : flags(0) {}
|
||||
sys::Path program; ///< The program to execve
|
||||
StringVector args; ///< Arguments to the program
|
||||
unsigned flags; ///< Action specific flags
|
||||
void set(unsigned fl ) { flags |= fl; }
|
||||
void clear(unsigned fl) { flags &= (FLAGS_MASK ^ fl); }
|
||||
bool isSet(unsigned fl) { return (flags&fl) != 0; }
|
||||
};
|
||||
|
||||
struct ConfigData {
|
||||
ConfigData();
|
||||
std::string version; ///< The version number.
|
||||
std::string langName; ///< The name of the source language
|
||||
StringTable opts; ///< The o10n options for each level
|
||||
StringVector libpaths; ///< The library paths
|
||||
Action PreProcessor; ///< PreProcessor command line
|
||||
Action Translator; ///< Translator command line
|
||||
Action Optimizer; ///< Optimizer command line
|
||||
Action Assembler; ///< Assembler command line
|
||||
Action Linker; ///< Linker command line
|
||||
};
|
||||
|
||||
/// This pure virtual interface class defines the interface between the
|
||||
/// CompilerDriver and other software that provides ConfigData objects to
|
||||
/// it. The CompilerDriver must be configured to use an object of this
|
||||
/// type so it can obtain the configuration data.
|
||||
/// @see setConfigDataProvider
|
||||
/// @brief Configuration Data Provider interface
|
||||
class ConfigDataProvider {
|
||||
public:
|
||||
virtual ~ConfigDataProvider();
|
||||
virtual ConfigData* ProvideConfigData(const std::string& filetype) = 0;
|
||||
virtual void setConfigDir(const sys::Path& dirName) = 0;
|
||||
};
|
||||
|
||||
/// These flags control various actions of the compiler driver. They are
|
||||
/// used by adding the needed flag values together and passing them to the
|
||||
/// compiler driver's setDriverFlags method.
|
||||
/// @see setDriverFlags
|
||||
/// @brief Driver specific flags
|
||||
enum DriverFlags {
|
||||
DRY_RUN_FLAG = 0x0001, ///< Do everything but execute actions
|
||||
VERBOSE_FLAG = 0x0002, ///< Print each action
|
||||
DEBUG_FLAG = 0x0004, ///< Print debug information
|
||||
TIME_PASSES_FLAG = 0x0008, ///< Time the passes as they execute
|
||||
TIME_ACTIONS_FLAG = 0x0010, ///< Time the actions as they execute
|
||||
SHOW_STATS_FLAG = 0x0020, ///< Show pass statistics
|
||||
EMIT_NATIVE_FLAG = 0x0040, ///< Emit native code instead of bc
|
||||
EMIT_RAW_FLAG = 0x0080, ///< Emit raw, unoptimized bitcode
|
||||
KEEP_TEMPS_FLAG = 0x0100, ///< Don't delete temporary files
|
||||
STRIP_OUTPUT_FLAG = 0x0200, ///< Strip symbols from linked output
|
||||
DRIVER_FLAGS_MASK = 0x03FF ///< Union of the above flags
|
||||
};
|
||||
|
||||
/// @}
|
||||
/// @name Constructors
|
||||
/// @{
|
||||
public:
|
||||
/// @brief Static Constructor
|
||||
static CompilerDriver* Get(ConfigDataProvider& CDP);
|
||||
|
||||
/// @brief Virtual destructor
|
||||
virtual ~CompilerDriver();
|
||||
|
||||
/// @}
|
||||
/// @name Methods
|
||||
/// @{
|
||||
public:
|
||||
/// @brief Execute the actions requested for the given input list.
|
||||
virtual int execute(
|
||||
const InputList& list, const sys::Path& output, std::string& ErrMsg) =0;
|
||||
|
||||
/// @brief Set the final phase at which compilation terminates
|
||||
virtual void setFinalPhase(Phases phase) = 0;
|
||||
|
||||
/// @brief Set the optimization level for the compilation
|
||||
virtual void setOptimization(OptimizationLevels level) = 0;
|
||||
|
||||
/// @brief Set the driver flags.
|
||||
virtual void setDriverFlags(unsigned flags) = 0;
|
||||
|
||||
/// @brief Set the output machine name.
|
||||
virtual void setOutputMachine(const std::string& machineName) = 0;
|
||||
|
||||
/// @brief Set the options for a given phase.
|
||||
virtual void setPhaseArgs(Phases phase, const StringVector& opts) = 0;
|
||||
|
||||
/// @brief Set Library Paths
|
||||
virtual void setIncludePaths(const StringVector& paths) = 0;
|
||||
|
||||
/// @brief Set Library Paths
|
||||
virtual void setSymbolDefines(const StringVector& paths) = 0;
|
||||
|
||||
/// @brief Set Library Paths
|
||||
virtual void setLibraryPaths(const StringVector& paths) = 0;
|
||||
|
||||
/// @brief Add a path to the list of library paths
|
||||
virtual void addLibraryPath( const sys::Path& libPath ) = 0;
|
||||
|
||||
/// @brief Add a path to the list of paths in which to find tools
|
||||
virtual void addToolPath( const sys::Path& toolPath) = 0;
|
||||
|
||||
/// @brief Set the list of -f options to be passed through
|
||||
virtual void setfPassThrough(const StringVector& fOpts) = 0;
|
||||
|
||||
/// @brief Set the list of -M options to be passed through
|
||||
virtual void setMPassThrough(const StringVector& fOpts) = 0;
|
||||
|
||||
/// @brief Set the list of -W options to be passed through
|
||||
virtual void setWPassThrough(const StringVector& fOpts) = 0;
|
||||
|
||||
/// @brief Determine where a linkage file is located in the file system
|
||||
virtual sys::Path GetPathForLinkageItem(
|
||||
const std::string& link_item, ///< Item to be sought
|
||||
bool native = false ///< Looking for native?
|
||||
) = 0;
|
||||
|
||||
/// @}
|
||||
};
|
||||
}
|
||||
|
||||
// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,113 +0,0 @@
|
||||
//===- ConfigLexer.h - ConfigLexer Declarations -----------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the types and data needed by ConfigLexer.l
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_TOOLS_LLVMC_CONFIGLEXER_H
|
||||
#define LLVM_TOOLS_LLVMC_CONFIGLEXER_H
|
||||
|
||||
#include <string>
|
||||
#include <istream>
|
||||
#include <cassert>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
struct ConfigLexerInfo
|
||||
{
|
||||
int64_t IntegerVal;
|
||||
std::string StringVal;
|
||||
bool in_value;
|
||||
unsigned lineNum;
|
||||
};
|
||||
|
||||
extern ConfigLexerInfo ConfigLexerState;
|
||||
|
||||
class InputProvider {
|
||||
public:
|
||||
InputProvider(const std::string& nm) {
|
||||
name = nm;
|
||||
errCount = 0;
|
||||
}
|
||||
virtual ~InputProvider();
|
||||
virtual unsigned read(char *buf, unsigned max_size) = 0;
|
||||
virtual void error(const std::string& msg);
|
||||
virtual void checkErrors();
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
unsigned errCount;
|
||||
};
|
||||
|
||||
extern InputProvider* ConfigLexerInput;
|
||||
|
||||
enum ConfigLexerTokens {
|
||||
EOFTOK = 0, ///< Returned by Configlex when we hit end of file
|
||||
EOLTOK, ///< End of line
|
||||
ERRORTOK, ///< Error token
|
||||
ARGS_SUBST, ///< The substitution item %args%
|
||||
BINDIR_SUBST, ///< The substitution item %bindir%
|
||||
ASSEMBLY, ///< The value "assembly" (and variants)
|
||||
ASSEMBLER, ///< The name "assembler" (and variants)
|
||||
BITCODE, ///< The value "bitcode" (and variants)
|
||||
COMMAND, ///< The name "command" (and variants)
|
||||
DEFS_SUBST, ///< The substitution item %defs%
|
||||
EQUALS, ///< The equals sign, =
|
||||
FALSETOK, ///< A boolean false value (false/no/off)
|
||||
FOPTS_SUBST, ///< The substitution item %fOpts%
|
||||
IN_SUBST, ///< The substitution item %in%
|
||||
INCLS_SUBST, ///< The substitution item %incls%
|
||||
INTEGER, ///< An integer
|
||||
LANG, ///< The name "lang" (and variants)
|
||||
LIBDIR_SUBST, ///< The substitution item %libdir%
|
||||
LIBPATHS, ///< The name "libpaths" (and variants)
|
||||
LIBS, ///< The name "libs" (and variants)
|
||||
LIBS_SUBST, ///< The substitution item %libs%
|
||||
LINKER, ///< The name "linker" (and variants)
|
||||
LLVMGCCDIR_SUBST, ///< The substitution item %llvmgccdir%
|
||||
LLVMGCCARCH_SUBST, ///< The substitution item %llvmgccarch%
|
||||
LLVMGCC_SUBST, ///< The substitution item %llvmgcc%
|
||||
LLVMGXX_SUBST, ///< The substitution item %llvmgxx%
|
||||
LLVMCC1_SUBST, ///< The substitution item %llvmcc1%
|
||||
LLVMCC1PLUS_SUBST, ///< The substitution item %llvmcc1plus%
|
||||
MOPTS_SUBST, ///< The substitution item %Mopts%
|
||||
NAME, ///< The name "name" (and variants)
|
||||
OPT_SUBST, ///< The substitution item %opt%
|
||||
OPTIMIZER, ///< The name "optimizer" (and variants)
|
||||
OPTION, ///< A command line option
|
||||
OPT1, ///< The name "opt1" (and variants)
|
||||
OPT2, ///< The name "opt2" (and variants)
|
||||
OPT3, ///< The name "opt3" (and variants)
|
||||
OPT4, ///< The name "opt4" (and variants)
|
||||
OPT5, ///< The name "opt5" (and variants)
|
||||
OUT_SUBST, ///< The output substitution item %out%
|
||||
OUTPUT, ///< The name "output" (and variants)
|
||||
PREPROCESSES, ///< The name "preprocesses" (and variants)
|
||||
PREPROCESSOR, ///< The name "preprocessor" (and variants)
|
||||
REQUIRED, ///< The name "required" (and variants)
|
||||
SEPARATOR, ///< A configuration item separator
|
||||
SPACE, ///< Space between options
|
||||
STATS_SUBST, ///< The stats substitution item %stats%
|
||||
STRING, ///< A quoted string
|
||||
TARGET_SUBST, ///< The substitition item %target%
|
||||
TIME_SUBST, ///< The substitution item %time%
|
||||
TRANSLATES, ///< The name "translates" (and variants)
|
||||
TRANSLATOR, ///< The name "translator" (and variants)
|
||||
TRUETOK, ///< A boolean true value (true/yes/on)
|
||||
VERBOSE_SUBST, ///< The substitution item %verbose%
|
||||
VERSION_TOK, ///< The name "version" (and variants)
|
||||
WOPTS_SUBST ///< The %WOpts% substitution
|
||||
};
|
||||
|
||||
extern ConfigLexerTokens Configlex();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,201 +0,0 @@
|
||||
/*===- ConfigLexer.l - Scanner for CompilerDriver Config Files -*- C++ -*--===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the flex scanner for configuration files for the
|
||||
// llvmc CompilerDriver.
|
||||
//
|
||||
//===----------------------------------------------------------------------===*/
|
||||
|
||||
|
||||
%option prefix="Config"
|
||||
%option nostdinit
|
||||
%option never-interactive
|
||||
%option batch
|
||||
%option noyywrap
|
||||
%option 8bit
|
||||
%option outfile="ConfigLexer.cpp"
|
||||
%option ecs
|
||||
%option noyymore
|
||||
%option noreject
|
||||
%pointer
|
||||
|
||||
%{
|
||||
|
||||
#include "ConfigLexer.h"
|
||||
|
||||
#define YY_INPUT(buf,result,max_size) \
|
||||
{ \
|
||||
assert(ConfigLexerInput != 0 && "Oops"); \
|
||||
result = ConfigLexerInput->read(buf,max_size); \
|
||||
if (result == 0 ) result = YY_NULL; \
|
||||
}
|
||||
|
||||
#define YY_FATAL_ERROR(msg) \
|
||||
{ \
|
||||
assert(ConfigLexerInput != 0 && "Oops"); \
|
||||
ConfigLexerInput->error(msg); \
|
||||
}
|
||||
|
||||
#define YY_DECL ConfigLexerTokens llvm::Configlex()
|
||||
|
||||
#define yyterminate() { return EOFTOK; }
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
inline llvm::ConfigLexerTokens
|
||||
handleNameContext(llvm::ConfigLexerTokens token) {
|
||||
ConfigLexerState.StringVal = yytext;
|
||||
if (ConfigLexerState.in_value)
|
||||
return OPTION;
|
||||
return token;
|
||||
}
|
||||
|
||||
inline llvm::ConfigLexerTokens
|
||||
handleSubstitution(llvm::ConfigLexerTokens token) {
|
||||
if (ConfigLexerState.in_value) {
|
||||
ConfigLexerState.StringVal = yytext;
|
||||
return token;
|
||||
}
|
||||
YY_FATAL_ERROR("Substitition tokens not allowed in names" );
|
||||
return ERRORTOK;
|
||||
}
|
||||
|
||||
inline llvm::ConfigLexerTokens handleValueContext(llvm::ConfigLexerTokens token) {
|
||||
ConfigLexerState.StringVal = yytext;
|
||||
if (ConfigLexerState.in_value)
|
||||
return token;
|
||||
return OPTION;
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
ASSEMBLER assembler|Assembler|ASSEMBLER
|
||||
COMMAND command|Command|COMMAND
|
||||
LANG lang|Lang|LANG
|
||||
LIBS libs|Libs|LIBS
|
||||
LINKER linker|Linker|LINKER
|
||||
NAME name|Name|NAME
|
||||
OPT1 opt1|Opt1|OPT1
|
||||
OPT2 opt2|Opt2|OPT2
|
||||
OPT3 opt3|Opt3|OPT3
|
||||
OPT4 opt4|Opt4|OPT4
|
||||
OPT5 opt5|Opt5|OPT5
|
||||
OPTIMIZER optimizer|Optimizer|OPTIMIZER
|
||||
OUTPUT output|Output|OUTPUT
|
||||
PREPROCESSES preprocesses|PreProcesses|PREPROCESSES
|
||||
PREPROCESSOR preprocessor|PreProcessor|PREPROCESSOR
|
||||
REQUIRED required|Required|REQUIRED
|
||||
TRANSLATES translates|Translates|TRANSLATES
|
||||
TRANSLATOR translator|Translator|TRANSLATOR
|
||||
VERSION version|Version|VERSION
|
||||
|
||||
True true|True|TRUE|on|On|ON|yes|Yes|YES
|
||||
False false|False|FALSE|off|Off|OFF|no|No|NO
|
||||
Bitcode bc|BC|bitcode|Bitcode|BITCODE
|
||||
Assembly asm|ASM|assembly|Assembly|ASSEMBLY
|
||||
|
||||
BadSubst \%[a-zA-Z]*\%
|
||||
Comment \#[^\r\n]*\r?\n
|
||||
NewLine \r?\n
|
||||
Eq \=
|
||||
EscNewLine \\\r?\n
|
||||
Option [-A-Za-z0-9_:%+/\\|,][-A-Za-z0-9_:+/\\|,@]*
|
||||
Sep \.
|
||||
String \"[^\"]*\"
|
||||
White [ \t]*
|
||||
|
||||
|
||||
%%
|
||||
|
||||
{White} { if (ConfigLexerState.in_value) return SPACE; }
|
||||
|
||||
{Comment} { /* Ignore comments */
|
||||
ConfigLexerState.in_value = false;
|
||||
ConfigLexerState.lineNum++;
|
||||
return EOLTOK;
|
||||
}
|
||||
|
||||
{EscNewLine} { ConfigLexerState.lineNum++;
|
||||
/* Don't return EOLTOK! */
|
||||
}
|
||||
|
||||
{NewLine} { ConfigLexerState.in_value = false;
|
||||
ConfigLexerState.lineNum++;
|
||||
return EOLTOK;
|
||||
}
|
||||
|
||||
{Eq} { ConfigLexerState.in_value = true;
|
||||
return EQUALS;
|
||||
}
|
||||
|
||||
{Sep} { return SEPARATOR; }
|
||||
|
||||
{VERSION} { return handleNameContext(VERSION_TOK); }
|
||||
|
||||
{LANG} { return handleNameContext(LANG); }
|
||||
{LIBS} { return handleNameContext(LIBS); }
|
||||
{NAME} { return handleNameContext(NAME); }
|
||||
{OPT1} { return handleNameContext(OPT1); }
|
||||
{OPT2} { return handleNameContext(OPT2); }
|
||||
{OPT3} { return handleNameContext(OPT3); }
|
||||
{OPT4} { return handleNameContext(OPT4); }
|
||||
{OPT5} { return handleNameContext(OPT5); }
|
||||
|
||||
{PREPROCESSOR} { return handleNameContext(PREPROCESSOR); }
|
||||
{COMMAND} { return handleNameContext(COMMAND); }
|
||||
{REQUIRED} { return handleNameContext(REQUIRED); }
|
||||
|
||||
{TRANSLATOR} { return handleNameContext(TRANSLATOR); }
|
||||
{PREPROCESSES} { return handleNameContext(PREPROCESSES); }
|
||||
{OUTPUT} { return handleNameContext(OUTPUT); }
|
||||
|
||||
{OPTIMIZER} { return handleNameContext(OPTIMIZER); }
|
||||
{TRANSLATES} { return handleNameContext(TRANSLATES); }
|
||||
|
||||
{ASSEMBLER} { return handleNameContext(ASSEMBLER); }
|
||||
|
||||
{LINKER} { return handleNameContext(LINKER); }
|
||||
|
||||
%args% { return handleSubstitution(ARGS_SUBST); }
|
||||
%bindir% { return handleSubstitution(BINDIR_SUBST); }
|
||||
%defs% { return handleSubstitution(DEFS_SUBST); }
|
||||
%in% { return handleSubstitution(IN_SUBST); }
|
||||
%incls% { return handleSubstitution(INCLS_SUBST); }
|
||||
%libdir% { return handleSubstitution(LIBDIR_SUBST); }
|
||||
%libs% { return handleSubstitution(LIBS_SUBST); }
|
||||
%llvmgccdir% { return handleSubstitution(LLVMGCCDIR_SUBST); }
|
||||
%llvmgccarch% { return handleSubstitution(LLVMGCCARCH_SUBST); }
|
||||
%llvmgcc% { return handleSubstitution(LLVMGCC_SUBST); }
|
||||
%llvmgxx% { return handleSubstitution(LLVMGXX_SUBST); }
|
||||
%llvmcc1% { return handleSubstitution(LLVMCC1_SUBST); }
|
||||
%llvmcc1plus% { return handleSubstitution(LLVMCC1PLUS_SUBST); }
|
||||
%opt% { return handleSubstitution(OPT_SUBST); }
|
||||
%out% { return handleSubstitution(OUT_SUBST); }
|
||||
%stats% { return handleSubstitution(STATS_SUBST); }
|
||||
%target% { return handleSubstitution(TARGET_SUBST); }
|
||||
%time% { return handleSubstitution(TIME_SUBST); }
|
||||
%verbose% { return handleSubstitution(VERBOSE_SUBST); }
|
||||
%fOpts% { return handleSubstitution(FOPTS_SUBST); }
|
||||
%MOpts% { return handleSubstitution(MOPTS_SUBST); }
|
||||
%WOpts% { return handleSubstitution(WOPTS_SUBST); }
|
||||
|
||||
{Assembly} { return handleValueContext(ASSEMBLY); }
|
||||
{Bitcode} { return handleValueContext(BITCODE); }
|
||||
{True} { return handleValueContext(TRUETOK); }
|
||||
{False} { return handleValueContext(FALSETOK); }
|
||||
|
||||
{Option} { ConfigLexerState.StringVal = yytext; return OPTION; }
|
||||
{String} { ConfigLexerState.StringVal = yytext+1; // Nuke start quote
|
||||
ConfigLexerState.StringVal.erase(
|
||||
--ConfigLexerState.StringVal.end());
|
||||
return STRING;
|
||||
}
|
||||
{BadSubst} { YY_FATAL_ERROR("Invalid substitution token"); }
|
||||
|
||||
%%
|
@ -1,201 +0,0 @@
|
||||
/*===- ConfigLexer.l - Scanner for CompilerDriver Config Files -*- C++ -*--===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the flex scanner for configuration files for the
|
||||
// llvmc CompilerDriver.
|
||||
//
|
||||
//===----------------------------------------------------------------------===*/
|
||||
|
||||
|
||||
%option prefix="Config"
|
||||
%option nostdinit
|
||||
%option never-interactive
|
||||
%option batch
|
||||
%option noyywrap
|
||||
%option 8bit
|
||||
%option outfile="ConfigLexer.cpp"
|
||||
%option ecs
|
||||
%option noyymore
|
||||
%option noreject
|
||||
%pointer
|
||||
|
||||
%{
|
||||
|
||||
#include "ConfigLexer.h"
|
||||
|
||||
#define YY_INPUT(buf,result,max_size) \
|
||||
{ \
|
||||
assert(ConfigLexerInput != 0 && "Oops"); \
|
||||
result = ConfigLexerInput->read(buf,max_size); \
|
||||
if (result == 0 ) result = YY_NULL; \
|
||||
}
|
||||
|
||||
#define YY_FATAL_ERROR(msg) \
|
||||
{ \
|
||||
assert(ConfigLexerInput != 0 && "Oops"); \
|
||||
ConfigLexerInput->error(msg); \
|
||||
}
|
||||
|
||||
#define YY_DECL ConfigLexerTokens llvm::Configlex()
|
||||
|
||||
#define yyterminate() { return EOFTOK; }
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
inline llvm::ConfigLexerTokens
|
||||
handleNameContext(llvm::ConfigLexerTokens token) {
|
||||
ConfigLexerState.StringVal = yytext;
|
||||
if (ConfigLexerState.in_value)
|
||||
return OPTION;
|
||||
return token;
|
||||
}
|
||||
|
||||
inline llvm::ConfigLexerTokens
|
||||
handleSubstitution(llvm::ConfigLexerTokens token) {
|
||||
if (ConfigLexerState.in_value) {
|
||||
ConfigLexerState.StringVal = yytext;
|
||||
return token;
|
||||
}
|
||||
YY_FATAL_ERROR("Substitition tokens not allowed in names" );
|
||||
return ERRORTOK;
|
||||
}
|
||||
|
||||
inline llvm::ConfigLexerTokens handleValueContext(llvm::ConfigLexerTokens token) {
|
||||
ConfigLexerState.StringVal = yytext;
|
||||
if (ConfigLexerState.in_value)
|
||||
return token;
|
||||
return OPTION;
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
ASSEMBLER assembler|Assembler|ASSEMBLER
|
||||
COMMAND command|Command|COMMAND
|
||||
LANG lang|Lang|LANG
|
||||
LIBS libs|Libs|LIBS
|
||||
LINKER linker|Linker|LINKER
|
||||
NAME name|Name|NAME
|
||||
OPT1 opt1|Opt1|OPT1
|
||||
OPT2 opt2|Opt2|OPT2
|
||||
OPT3 opt3|Opt3|OPT3
|
||||
OPT4 opt4|Opt4|OPT4
|
||||
OPT5 opt5|Opt5|OPT5
|
||||
OPTIMIZER optimizer|Optimizer|OPTIMIZER
|
||||
OUTPUT output|Output|OUTPUT
|
||||
PREPROCESSES preprocesses|PreProcesses|PREPROCESSES
|
||||
PREPROCESSOR preprocessor|PreProcessor|PREPROCESSOR
|
||||
REQUIRED required|Required|REQUIRED
|
||||
TRANSLATES translates|Translates|TRANSLATES
|
||||
TRANSLATOR translator|Translator|TRANSLATOR
|
||||
VERSION version|Version|VERSION
|
||||
|
||||
True true|True|TRUE|on|On|ON|yes|Yes|YES
|
||||
False false|False|FALSE|off|Off|OFF|no|No|NO
|
||||
Bitcode bc|BC|bitcode|Bitcode|BITCODE
|
||||
Assembly asm|ASM|assembly|Assembly|ASSEMBLY
|
||||
|
||||
BadSubst \%[a-zA-Z]*\%
|
||||
Comment \#[^\r\n]*\r?\n
|
||||
NewLine \r?\n
|
||||
Eq \=
|
||||
EscNewLine \\\r?\n
|
||||
Option [-A-Za-z0-9_:%+/\\|,][-A-Za-z0-9_:+/\\|,@]*
|
||||
Sep \.
|
||||
String \"[^\"]*\"
|
||||
White [ \t]*
|
||||
|
||||
|
||||
%%
|
||||
|
||||
{White} { if (ConfigLexerState.in_value) return SPACE; }
|
||||
|
||||
{Comment} { /* Ignore comments */
|
||||
ConfigLexerState.in_value = false;
|
||||
ConfigLexerState.lineNum++;
|
||||
return EOLTOK;
|
||||
}
|
||||
|
||||
{EscNewLine} { ConfigLexerState.lineNum++;
|
||||
/* Don't return EOLTOK! */
|
||||
}
|
||||
|
||||
{NewLine} { ConfigLexerState.in_value = false;
|
||||
ConfigLexerState.lineNum++;
|
||||
return EOLTOK;
|
||||
}
|
||||
|
||||
{Eq} { ConfigLexerState.in_value = true;
|
||||
return EQUALS;
|
||||
}
|
||||
|
||||
{Sep} { return SEPARATOR; }
|
||||
|
||||
{VERSION} { return handleNameContext(VERSION_TOK); }
|
||||
|
||||
{LANG} { return handleNameContext(LANG); }
|
||||
{LIBS} { return handleNameContext(LIBS); }
|
||||
{NAME} { return handleNameContext(NAME); }
|
||||
{OPT1} { return handleNameContext(OPT1); }
|
||||
{OPT2} { return handleNameContext(OPT2); }
|
||||
{OPT3} { return handleNameContext(OPT3); }
|
||||
{OPT4} { return handleNameContext(OPT4); }
|
||||
{OPT5} { return handleNameContext(OPT5); }
|
||||
|
||||
{PREPROCESSOR} { return handleNameContext(PREPROCESSOR); }
|
||||
{COMMAND} { return handleNameContext(COMMAND); }
|
||||
{REQUIRED} { return handleNameContext(REQUIRED); }
|
||||
|
||||
{TRANSLATOR} { return handleNameContext(TRANSLATOR); }
|
||||
{PREPROCESSES} { return handleNameContext(PREPROCESSES); }
|
||||
{OUTPUT} { return handleNameContext(OUTPUT); }
|
||||
|
||||
{OPTIMIZER} { return handleNameContext(OPTIMIZER); }
|
||||
{TRANSLATES} { return handleNameContext(TRANSLATES); }
|
||||
|
||||
{ASSEMBLER} { return handleNameContext(ASSEMBLER); }
|
||||
|
||||
{LINKER} { return handleNameContext(LINKER); }
|
||||
|
||||
%args% { return handleSubstitution(ARGS_SUBST); }
|
||||
%bindir% { return handleSubstitution(BINDIR_SUBST); }
|
||||
%defs% { return handleSubstitution(DEFS_SUBST); }
|
||||
%in% { return handleSubstitution(IN_SUBST); }
|
||||
%incls% { return handleSubstitution(INCLS_SUBST); }
|
||||
%libdir% { return handleSubstitution(LIBDIR_SUBST); }
|
||||
%libs% { return handleSubstitution(LIBS_SUBST); }
|
||||
%llvmgccdir% { return handleSubstitution(LLVMGCCDIR_SUBST); }
|
||||
%llvmgccarch% { return handleSubstitution(LLVMGCCARCH_SUBST); }
|
||||
%llvmgcc% { return handleSubstitution(LLVMGCC_SUBST); }
|
||||
%llvmgxx% { return handleSubstitution(LLVMGXX_SUBST); }
|
||||
%llvmcc1% { return handleSubstitution(LLVMCC1_SUBST); }
|
||||
%llvmcc1plus% { return handleSubstitution(LLVMCC1PLUS_SUBST); }
|
||||
%opt% { return handleSubstitution(OPT_SUBST); }
|
||||
%out% { return handleSubstitution(OUT_SUBST); }
|
||||
%stats% { return handleSubstitution(STATS_SUBST); }
|
||||
%target% { return handleSubstitution(TARGET_SUBST); }
|
||||
%time% { return handleSubstitution(TIME_SUBST); }
|
||||
%verbose% { return handleSubstitution(VERBOSE_SUBST); }
|
||||
%fOpts% { return handleSubstitution(FOPTS_SUBST); }
|
||||
%MOpts% { return handleSubstitution(MOPTS_SUBST); }
|
||||
%WOpts% { return handleSubstitution(WOPTS_SUBST); }
|
||||
|
||||
{Assembly} { return handleValueContext(ASSEMBLY); }
|
||||
{Bitcode} { return handleValueContext(BITCODE); }
|
||||
{True} { return handleValueContext(TRUETOK); }
|
||||
{False} { return handleValueContext(FALSETOK); }
|
||||
|
||||
{Option} { ConfigLexerState.StringVal = yytext; return OPTION; }
|
||||
{String} { ConfigLexerState.StringVal = yytext+1; // Nuke start quote
|
||||
ConfigLexerState.StringVal.erase(
|
||||
--ConfigLexerState.StringVal.end());
|
||||
return STRING;
|
||||
}
|
||||
{BadSubst} { YY_FATAL_ERROR("Invalid substitution token"); }
|
||||
|
||||
%%
|
@ -1,632 +0,0 @@
|
||||
//===- Configuration.cpp - Configuration Data Mgmt --------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the parsing of configuration files for the LLVM Compiler
|
||||
// Driver (llvmc).
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Configuration.h"
|
||||
#include "ConfigLexer.h"
|
||||
#include "CompilerDriver.h"
|
||||
#include "llvm/Config/config.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace sys {
|
||||
// From CompilerDriver.cpp (for now)
|
||||
extern bool FileIsReadable(const std::string& fname);
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
ConfigLexerInfo ConfigLexerState;
|
||||
InputProvider* ConfigLexerInput = 0;
|
||||
|
||||
InputProvider::~InputProvider() {}
|
||||
void InputProvider::error(const std::string& msg) {
|
||||
std::cerr << name << ":" << ConfigLexerState.lineNum << ": Error: " <<
|
||||
msg << "\n";
|
||||
errCount++;
|
||||
}
|
||||
|
||||
void InputProvider::checkErrors() {
|
||||
if (errCount > 0) {
|
||||
std::cerr << name << " had " << errCount << " errors. Terminating.\n";
|
||||
exit(errCount);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class FileInputProvider : public InputProvider {
|
||||
public:
|
||||
FileInputProvider(const std::string & fname)
|
||||
: InputProvider(fname)
|
||||
, F(fname.c_str()) {
|
||||
ConfigLexerInput = this;
|
||||
}
|
||||
virtual ~FileInputProvider() { F.close(); ConfigLexerInput = 0; }
|
||||
virtual unsigned read(char *buffer, unsigned max_size) {
|
||||
if (F.good()) {
|
||||
F.read(buffer,max_size);
|
||||
if ( F.gcount() ) return F.gcount() - 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool okay() { return F.good(); }
|
||||
private:
|
||||
std::ifstream F;
|
||||
};
|
||||
|
||||
cl::opt<bool> DumpTokens("dump-tokens", cl::Optional, cl::Hidden,
|
||||
cl::init(false), cl::desc("Dump lexical tokens (debug use only)."));
|
||||
|
||||
struct Parser
|
||||
{
|
||||
Parser() {
|
||||
token = EOFTOK;
|
||||
provider = 0;
|
||||
confDat = 0;
|
||||
ConfigLexerState.lineNum = 1;
|
||||
ConfigLexerState.in_value = false;
|
||||
ConfigLexerState.StringVal.clear();
|
||||
ConfigLexerState.IntegerVal = 0;
|
||||
};
|
||||
|
||||
ConfigLexerTokens token;
|
||||
InputProvider* provider;
|
||||
CompilerDriver::ConfigData* confDat;
|
||||
|
||||
inline int next() {
|
||||
token = Configlex();
|
||||
if (DumpTokens)
|
||||
std::cerr << token << "\n";
|
||||
return token;
|
||||
}
|
||||
|
||||
inline bool next_is_real() {
|
||||
next();
|
||||
return (token != EOLTOK) && (token != ERRORTOK) && (token != 0);
|
||||
}
|
||||
|
||||
inline void eatLineRemnant() {
|
||||
while (next_is_real()) ;
|
||||
}
|
||||
|
||||
void error(const std::string& msg, bool skip = true) {
|
||||
provider->error(msg);
|
||||
if (skip)
|
||||
eatLineRemnant();
|
||||
}
|
||||
|
||||
bool parseCompleteItem(std::string& result) {
|
||||
result.clear();
|
||||
while (next_is_real()) {
|
||||
switch (token ) {
|
||||
case LLVMGCCDIR_SUBST:
|
||||
case LLVMGCCARCH_SUBST:
|
||||
case STRING :
|
||||
case OPTION :
|
||||
result += ConfigLexerState.StringVal;
|
||||
break;
|
||||
case SEPARATOR:
|
||||
result += ".";
|
||||
break;
|
||||
case SPACE:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string parseName() {
|
||||
std::string result;
|
||||
if (next() == EQUALS) {
|
||||
if (parseCompleteItem(result))
|
||||
eatLineRemnant();
|
||||
if (result.empty())
|
||||
error("Name exepected");
|
||||
} else
|
||||
error("Expecting '='");
|
||||
return result;
|
||||
}
|
||||
|
||||
bool parseBoolean() {
|
||||
bool result = true;
|
||||
if (next() == EQUALS) {
|
||||
if (next() == SPACE)
|
||||
next();
|
||||
if (token == FALSETOK) {
|
||||
result = false;
|
||||
} else if (token != TRUETOK) {
|
||||
error("Expecting boolean value");
|
||||
return false;
|
||||
}
|
||||
if (next() != EOLTOK && token != 0) {
|
||||
error("Extraneous tokens after boolean");
|
||||
}
|
||||
}
|
||||
else
|
||||
error("Expecting '='");
|
||||
return result;
|
||||
}
|
||||
|
||||
bool parseSubstitution(CompilerDriver::StringVector& optList) {
|
||||
switch (token) {
|
||||
case ARGS_SUBST: optList.push_back("%args%"); break;
|
||||
case BINDIR_SUBST: optList.push_back("%bindir%"); break;
|
||||
case DEFS_SUBST: optList.push_back("%defs%"); break;
|
||||
case IN_SUBST: optList.push_back("%in%"); break;
|
||||
case INCLS_SUBST: optList.push_back("%incls%"); break;
|
||||
case LIBDIR_SUBST: optList.push_back("%libdir%"); break;
|
||||
case LIBS_SUBST: optList.push_back("%libs%"); break;
|
||||
case OPT_SUBST: optList.push_back("%opt%"); break;
|
||||
case OUT_SUBST: optList.push_back("%out%"); break;
|
||||
case TARGET_SUBST: optList.push_back("%target%"); break;
|
||||
case STATS_SUBST: optList.push_back("%stats%"); break;
|
||||
case TIME_SUBST: optList.push_back("%time%"); break;
|
||||
case VERBOSE_SUBST: optList.push_back("%verbose%"); break;
|
||||
case FOPTS_SUBST: optList.push_back("%fOpts%"); break;
|
||||
case MOPTS_SUBST: optList.push_back("%Mopts%"); break;
|
||||
case WOPTS_SUBST: optList.push_back("%Wopts%"); break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void parseOptionList(CompilerDriver::StringVector& optList ) {
|
||||
if (next() == EQUALS) {
|
||||
while (next_is_real()) {
|
||||
if (token == STRING || token == OPTION)
|
||||
optList.push_back(ConfigLexerState.StringVal);
|
||||
else if (!parseSubstitution(optList)) {
|
||||
error("Expecting a program argument or substitution", false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else
|
||||
error("Expecting '='");
|
||||
}
|
||||
|
||||
void parseVersion() {
|
||||
if (next() != EQUALS)
|
||||
error("Expecting '='");
|
||||
while (next_is_real()) {
|
||||
if (token == STRING || token == OPTION)
|
||||
confDat->version = ConfigLexerState.StringVal;
|
||||
else
|
||||
error("Expecting a version string");
|
||||
}
|
||||
}
|
||||
|
||||
void parseLibs() {
|
||||
if (next() != EQUALS)
|
||||
error("Expecting '='");
|
||||
std::string lib;
|
||||
while (parseCompleteItem(lib)) {
|
||||
if (!lib.empty()) {
|
||||
confDat->libpaths.push_back(lib);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void parseLang() {
|
||||
if (next() != SEPARATOR)
|
||||
error("Expecting '.'");
|
||||
switch (next() ) {
|
||||
case LIBS:
|
||||
parseLibs();
|
||||
break;
|
||||
case NAME:
|
||||
confDat->langName = parseName();
|
||||
break;
|
||||
case OPT1:
|
||||
parseOptionList(confDat->opts[CompilerDriver::OPT_FAST_COMPILE]);
|
||||
break;
|
||||
case OPT2:
|
||||
parseOptionList(confDat->opts[CompilerDriver::OPT_SIMPLE]);
|
||||
break;
|
||||
case OPT3:
|
||||
parseOptionList(confDat->opts[CompilerDriver::OPT_AGGRESSIVE]);
|
||||
break;
|
||||
case OPT4:
|
||||
parseOptionList(confDat->opts[CompilerDriver::OPT_LINK_TIME]);
|
||||
break;
|
||||
case OPT5:
|
||||
parseOptionList(
|
||||
confDat->opts[CompilerDriver::OPT_AGGRESSIVE_LINK_TIME]);
|
||||
break;
|
||||
default:
|
||||
error("Expecting 'name' or 'optN' after 'lang.'");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool parseProgramName(std::string& str) {
|
||||
str.clear();
|
||||
do {
|
||||
switch (token) {
|
||||
case BINDIR_SUBST:
|
||||
case LLVMGCC_SUBST:
|
||||
case LLVMGXX_SUBST:
|
||||
case LLVMCC1_SUBST:
|
||||
case LLVMCC1PLUS_SUBST:
|
||||
case OPTION:
|
||||
case STRING:
|
||||
case ARGS_SUBST:
|
||||
case DEFS_SUBST:
|
||||
case IN_SUBST:
|
||||
case INCLS_SUBST:
|
||||
case LIBS_SUBST:
|
||||
case OPT_SUBST:
|
||||
case OUT_SUBST:
|
||||
case STATS_SUBST:
|
||||
case TARGET_SUBST:
|
||||
case TIME_SUBST:
|
||||
case VERBOSE_SUBST:
|
||||
case FOPTS_SUBST:
|
||||
case MOPTS_SUBST:
|
||||
case WOPTS_SUBST:
|
||||
str += ConfigLexerState.StringVal;
|
||||
break;
|
||||
case SEPARATOR:
|
||||
str += ".";
|
||||
break;
|
||||
case ASSEMBLY:
|
||||
str += "assembly";
|
||||
break;
|
||||
case BITCODE:
|
||||
str += "bitcode";
|
||||
break;
|
||||
case TRUETOK:
|
||||
str += "true";
|
||||
break;
|
||||
case FALSETOK:
|
||||
str += "false";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
next();
|
||||
} while (token != SPACE && token != EOFTOK && token != EOLTOK &&
|
||||
token != ERRORTOK);
|
||||
return !str.empty();
|
||||
}
|
||||
|
||||
void parseCommand(CompilerDriver::Action& action) {
|
||||
if (next() != EQUALS)
|
||||
error("Expecting '='");
|
||||
switch (next()) {
|
||||
case EOLTOK:
|
||||
// no value (valid)
|
||||
action.program.clear();
|
||||
action.args.clear();
|
||||
break;
|
||||
case SPACE:
|
||||
next();
|
||||
/* FALL THROUGH */
|
||||
default:
|
||||
{
|
||||
std::string progname;
|
||||
if (parseProgramName(progname))
|
||||
action.program.set(progname);
|
||||
else
|
||||
error("Expecting a program name");
|
||||
|
||||
// Get the options
|
||||
std::string anOption;
|
||||
while (next_is_real()) {
|
||||
switch (token) {
|
||||
case STRING:
|
||||
case OPTION:
|
||||
anOption += ConfigLexerState.StringVal;
|
||||
break;
|
||||
case ASSEMBLY:
|
||||
anOption += "assembly";
|
||||
break;
|
||||
case BITCODE:
|
||||
anOption += "bitcode";
|
||||
break;
|
||||
case TRUETOK:
|
||||
anOption += "true";
|
||||
break;
|
||||
case FALSETOK:
|
||||
anOption += "false";
|
||||
break;
|
||||
case SEPARATOR:
|
||||
anOption += ".";
|
||||
break;
|
||||
case SPACE:
|
||||
action.args.push_back(anOption);
|
||||
anOption.clear();
|
||||
break;
|
||||
default:
|
||||
if (!parseSubstitution(action.args))
|
||||
error("Expecting a program argument or substitution", false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void parsePreprocessor() {
|
||||
if (next() != SEPARATOR)
|
||||
error("Expecting '.'");
|
||||
switch (next()) {
|
||||
case COMMAND:
|
||||
parseCommand(confDat->PreProcessor);
|
||||
break;
|
||||
case REQUIRED:
|
||||
if (parseBoolean())
|
||||
confDat->PreProcessor.set(CompilerDriver::REQUIRED_FLAG);
|
||||
else
|
||||
confDat->PreProcessor.clear(CompilerDriver::REQUIRED_FLAG);
|
||||
break;
|
||||
default:
|
||||
error("Expecting 'command' or 'required' but found '" +
|
||||
ConfigLexerState.StringVal);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool parseOutputFlag() {
|
||||
if (next() == EQUALS) {
|
||||
if (next() == SPACE)
|
||||
next();
|
||||
if (token == ASSEMBLY) {
|
||||
return true;
|
||||
} else if (token == BITCODE) {
|
||||
return false;
|
||||
} else {
|
||||
error("Expecting output type value");
|
||||
return false;
|
||||
}
|
||||
if (next() != EOLTOK && token != 0) {
|
||||
error("Extraneous tokens after output value");
|
||||
}
|
||||
}
|
||||
else
|
||||
error("Expecting '='");
|
||||
return false;
|
||||
}
|
||||
|
||||
void parseTranslator() {
|
||||
if (next() != SEPARATOR)
|
||||
error("Expecting '.'");
|
||||
switch (next()) {
|
||||
case COMMAND:
|
||||
parseCommand(confDat->Translator);
|
||||
break;
|
||||
case REQUIRED:
|
||||
if (parseBoolean())
|
||||
confDat->Translator.set(CompilerDriver::REQUIRED_FLAG);
|
||||
else
|
||||
confDat->Translator.clear(CompilerDriver::REQUIRED_FLAG);
|
||||
break;
|
||||
case PREPROCESSES:
|
||||
if (parseBoolean())
|
||||
confDat->Translator.set(CompilerDriver::PREPROCESSES_FLAG);
|
||||
else
|
||||
confDat->Translator.clear(CompilerDriver::PREPROCESSES_FLAG);
|
||||
break;
|
||||
case OUTPUT:
|
||||
if (parseOutputFlag())
|
||||
confDat->Translator.set(CompilerDriver::OUTPUT_IS_ASM_FLAG);
|
||||
else
|
||||
confDat->Translator.clear(CompilerDriver::OUTPUT_IS_ASM_FLAG);
|
||||
break;
|
||||
|
||||
default:
|
||||
error("Expecting 'command', 'required', 'preprocesses', or "
|
||||
"'output' but found '" + ConfigLexerState.StringVal +
|
||||
"' instead");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void parseOptimizer() {
|
||||
if (next() != SEPARATOR)
|
||||
error("Expecting '.'");
|
||||
switch (next()) {
|
||||
case COMMAND:
|
||||
parseCommand(confDat->Optimizer);
|
||||
break;
|
||||
case PREPROCESSES:
|
||||
if (parseBoolean())
|
||||
confDat->Optimizer.set(CompilerDriver::PREPROCESSES_FLAG);
|
||||
else
|
||||
confDat->Optimizer.clear(CompilerDriver::PREPROCESSES_FLAG);
|
||||
break;
|
||||
case TRANSLATES:
|
||||
if (parseBoolean())
|
||||
confDat->Optimizer.set(CompilerDriver::TRANSLATES_FLAG);
|
||||
else
|
||||
confDat->Optimizer.clear(CompilerDriver::TRANSLATES_FLAG);
|
||||
break;
|
||||
case REQUIRED:
|
||||
if (parseBoolean())
|
||||
confDat->Optimizer.set(CompilerDriver::REQUIRED_FLAG);
|
||||
else
|
||||
confDat->Optimizer.clear(CompilerDriver::REQUIRED_FLAG);
|
||||
break;
|
||||
case OUTPUT:
|
||||
if (parseOutputFlag())
|
||||
confDat->Translator.set(CompilerDriver::OUTPUT_IS_ASM_FLAG);
|
||||
else
|
||||
confDat->Translator.clear(CompilerDriver::OUTPUT_IS_ASM_FLAG);
|
||||
break;
|
||||
default:
|
||||
error(std::string("Expecting 'command', 'preprocesses', "
|
||||
"'translates' or 'output' but found '") +
|
||||
ConfigLexerState.StringVal + "' instead");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void parseAssembler() {
|
||||
if (next() != SEPARATOR)
|
||||
error("Expecting '.'");
|
||||
switch(next()) {
|
||||
case COMMAND:
|
||||
parseCommand(confDat->Assembler);
|
||||
break;
|
||||
default:
|
||||
error("Expecting 'command'");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void parseLinker() {
|
||||
if (next() != SEPARATOR)
|
||||
error("Expecting '.'");
|
||||
switch(next()) {
|
||||
case LIBS:
|
||||
break; //FIXME
|
||||
case LIBPATHS:
|
||||
break; //FIXME
|
||||
default:
|
||||
error("Expecting 'libs' or 'libpaths'");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void parseAssignment() {
|
||||
switch (token) {
|
||||
case VERSION_TOK: parseVersion(); break;
|
||||
case LANG: parseLang(); break;
|
||||
case PREPROCESSOR: parsePreprocessor(); break;
|
||||
case TRANSLATOR: parseTranslator(); break;
|
||||
case OPTIMIZER: parseOptimizer(); break;
|
||||
case ASSEMBLER: parseAssembler(); break;
|
||||
case LINKER: parseLinker(); break;
|
||||
case EOLTOK: break; // just ignore
|
||||
case ERRORTOK:
|
||||
default:
|
||||
error("Invalid top level configuration item");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void parseFile() {
|
||||
while ( next() != EOFTOK ) {
|
||||
if (token == ERRORTOK)
|
||||
error("Invalid token");
|
||||
else if (token != EOLTOK)
|
||||
parseAssignment();
|
||||
}
|
||||
provider->checkErrors();
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
ParseConfigData(InputProvider& provider, CompilerDriver::ConfigData& confDat) {
|
||||
Parser p;
|
||||
p.token = EOFTOK;
|
||||
p.provider = &provider;
|
||||
p.confDat = &confDat;
|
||||
p.parseFile();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CompilerDriver::ConfigData*
|
||||
LLVMC_ConfigDataProvider::ReadConfigData(const std::string& ftype) {
|
||||
CompilerDriver::ConfigData* result = 0;
|
||||
sys::Path confFile;
|
||||
if (configDir.isEmpty()) {
|
||||
// Try the environment variable
|
||||
const char* conf = getenv("LLVM_CONFIG_DIR");
|
||||
if (conf) {
|
||||
confFile.set(conf);
|
||||
confFile.appendComponent(ftype);
|
||||
if (!confFile.canRead())
|
||||
throw std::string("Configuration file for '") + ftype +
|
||||
"' is not available.";
|
||||
} else {
|
||||
// Try the user's home directory
|
||||
confFile = sys::Path::GetUserHomeDirectory();
|
||||
if (!confFile.isEmpty()) {
|
||||
confFile.appendComponent(".llvm");
|
||||
confFile.appendComponent("etc");
|
||||
confFile.appendComponent(ftype);
|
||||
if (!confFile.canRead())
|
||||
confFile.clear();
|
||||
}
|
||||
if (confFile.isEmpty()) {
|
||||
// Okay, try the LLVM installation directory
|
||||
confFile = sys::Path::GetLLVMConfigDir();
|
||||
confFile.appendComponent(ftype);
|
||||
if (!confFile.canRead()) {
|
||||
// Okay, try the "standard" place
|
||||
confFile = sys::Path::GetLLVMDefaultConfigDir();
|
||||
confFile.appendComponent(ftype);
|
||||
if (!confFile.canRead()) {
|
||||
throw std::string("Configuration file for '") + ftype +
|
||||
"' is not available.";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
confFile = configDir;
|
||||
confFile.appendComponent(ftype);
|
||||
if (!confFile.canRead())
|
||||
throw std::string("Configuration file for '") + ftype +
|
||||
"' is not available.";
|
||||
}
|
||||
FileInputProvider fip( confFile.toString() );
|
||||
if (!fip.okay()) {
|
||||
throw std::string("Configuration file for '") + ftype +
|
||||
"' is not available.";
|
||||
}
|
||||
result = new CompilerDriver::ConfigData();
|
||||
ParseConfigData(fip,*result);
|
||||
return result;
|
||||
}
|
||||
|
||||
LLVMC_ConfigDataProvider::~LLVMC_ConfigDataProvider()
|
||||
{
|
||||
ConfigDataMap::iterator cIt = Configurations.begin();
|
||||
while (cIt != Configurations.end()) {
|
||||
CompilerDriver::ConfigData* cd = cIt->second;
|
||||
++cIt;
|
||||
delete cd;
|
||||
}
|
||||
}
|
||||
|
||||
CompilerDriver::ConfigData*
|
||||
LLVMC_ConfigDataProvider::ProvideConfigData(const std::string& filetype) {
|
||||
CompilerDriver::ConfigData* result = 0;
|
||||
if (!Configurations.empty()) {
|
||||
ConfigDataMap::iterator cIt = Configurations.find(filetype);
|
||||
if ( cIt != Configurations.end() ) {
|
||||
// We found one in the case, return it.
|
||||
result = cIt->second;
|
||||
}
|
||||
}
|
||||
if (result == 0) {
|
||||
// The configuration data doesn't exist, we have to go read it.
|
||||
result = ReadConfigData(filetype);
|
||||
// If we got one, cache it
|
||||
if (result != 0)
|
||||
Configurations[filetype] = result;
|
||||
}
|
||||
return result; // Might return 0
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
//===- Configuration.h - Configuration Data Mgmt ----------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the LLVMC_ConfigDataProvider class which implements the
|
||||
// generation of ConfigData objects for the CompilerDriver.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_TOOLS_LLVMC_CONFIGDATA_H
|
||||
#define LLVM_TOOLS_LLVMC_CONFIGDATA_H
|
||||
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "CompilerDriver.h"
|
||||
|
||||
namespace llvm {
|
||||
/// This class provides the high level interface to the LLVM Compiler Driver.
|
||||
/// The driver's purpose is to make it easier for compiler writers and users
|
||||
/// of LLVM to utilize the compiler toolkits and LLVM toolset by learning only
|
||||
/// the interface of one program (llvmc).
|
||||
///
|
||||
/// @see llvmc.cpp
|
||||
/// @brief The interface to the LLVM Compiler Driver.
|
||||
class LLVMC_ConfigDataProvider : public CompilerDriver::ConfigDataProvider {
|
||||
/// @name Constructor
|
||||
/// @{
|
||||
public:
|
||||
virtual ~LLVMC_ConfigDataProvider();
|
||||
|
||||
/// @name Methods
|
||||
/// @{
|
||||
public:
|
||||
/// @brief Provide the configuration data to the CompilerDriver.
|
||||
virtual CompilerDriver::ConfigData*
|
||||
ProvideConfigData(const std::string& filetype);
|
||||
|
||||
/// @brief Allow the configuration directory to be set
|
||||
virtual void setConfigDir(const sys::Path& dirName) {
|
||||
configDir = dirName;
|
||||
}
|
||||
|
||||
private:
|
||||
CompilerDriver::ConfigData* ReadConfigData(const std::string& ftype);
|
||||
|
||||
/// @}
|
||||
/// @name Data
|
||||
/// @{
|
||||
private:
|
||||
/// @brief This type is used internally to hold the configuration data.
|
||||
typedef StringMap<CompilerDriver::ConfigData*> ConfigDataMap;
|
||||
ConfigDataMap Configurations; ///< The cache of configurations
|
||||
sys::Path configDir;
|
||||
/// @}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -1,6 +0,0 @@
|
||||
LLVM Compiler Driver (llvmc)
|
||||
-------------------------------------------------------------------------------
|
||||
The LLVM Compiler Driver (llvmc) is licensed under the Illinois Open Source
|
||||
License and has the following additional copyright:
|
||||
|
||||
Copyright (C) 2004 eXtensible Systems, Inc.
|
@ -1,34 +0,0 @@
|
||||
##===- 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 = ../..
|
||||
TOOLNAME = llvmc
|
||||
LINK_COMPONENTS = support system core bitreader
|
||||
CONFIG_FILES = c cpp ll st
|
||||
EXTRA_DIST = c cpp ll ConfigLexer.cpp.cvs ConfigLexer.l.cvs
|
||||
REQUIRES_EH := 1
|
||||
|
||||
# The CompilerDriver needs to know the locations of several configured
|
||||
# directories and paths. We define these as preprocessor symbols so they can
|
||||
# be hard coded into the process based on the configuration. Only those
|
||||
# configuration values not available in llvm/include/Config/config.h need to be
|
||||
# specified here. These values are used as the replacements for the
|
||||
# configuration file substitution variables such as %llvmgccdir%
|
||||
CPPFLAGS = -DLLVMGCCDIR="\"$(LLVMGCCDIR)\"" \
|
||||
-DLLVMGCCARCH="\"$(LLVMGCCARCH)\"" \
|
||||
-DLLVMGCC="\"$(LLVMGCC)\"" \
|
||||
-DLLVMGXX="\"$(LLVMGXX)\"" \
|
||||
-DLLVMCC1="\"$(LLVMCC1)\"" \
|
||||
-DLLVMCC1PLUS="\"$(LLVMCC1PLUS)\""
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
||||
install::
|
||||
$(Echo) Installing additional C++ configuration clones
|
||||
$(Verb)$(DataInstall) $(PROJ_SRC_DIR)/cpp $(PROJ_etcdir)/c++
|
||||
$(Verb)$(DataInstall) $(PROJ_SRC_DIR)/cpp $(PROJ_etcdir)/cxx
|
@ -1,60 +0,0 @@
|
||||
# C configuration file for llvmc
|
||||
|
||||
##########################################################
|
||||
# Language definitions
|
||||
##########################################################
|
||||
lang.name=C
|
||||
lang.opt1=-O1
|
||||
lang.opt2=-O2
|
||||
lang.opt3=-O3
|
||||
lang.opt4=-O3
|
||||
lang.opt5=-O3
|
||||
lang.libs=%llvmgccdir%/lib %llvmgccdir%/lib %llvmgccdir%/lib/gcc/%llvmgccarch%
|
||||
|
||||
##########################################################
|
||||
# Pre-processor definitions
|
||||
##########################################################
|
||||
|
||||
# We use gcc as our pre-processor
|
||||
preprocessor.command=gcc -E %in% -o %out% %incls% %defs%
|
||||
preprocessor.required=true
|
||||
|
||||
##########################################################
|
||||
# Translator definitions
|
||||
##########################################################
|
||||
|
||||
# To compile C source, just use llvm-gcc's cc1
|
||||
translator.command=%llvmcc1% -quiet %in% -o %out% \
|
||||
%opt% %incls% %defs% %WOpts% %fOpts% %MOpts% %args% \
|
||||
-D_GNU_SOURCE
|
||||
|
||||
# llvm-gcc does not pre-process
|
||||
translator.preprocesses=false
|
||||
|
||||
# The translator is required to run.
|
||||
translator.required=true
|
||||
|
||||
# Output of the translator is assembly
|
||||
translator.output=assembly
|
||||
|
||||
##########################################################
|
||||
# Optimizer definitions
|
||||
##########################################################
|
||||
|
||||
# Use gccas to clean up the generated code
|
||||
optimizer.command=%bindir%/gccas %in% -o %out% %args%
|
||||
optimizer.required = true
|
||||
|
||||
# gccas doesn't translate
|
||||
optimizer.translates = false
|
||||
|
||||
# gccas doesn't preprocess
|
||||
optimizer.preprocesses=false
|
||||
|
||||
# gccas produces bytecode
|
||||
optimizer.output = bytecode
|
||||
|
||||
##########################################################
|
||||
# Assembler definitions
|
||||
##########################################################
|
||||
assembler.command=%bindir%/llc %in% -o %out% %target% %time% %stats%
|
@ -1,61 +0,0 @@
|
||||
# C++ configuration file for llvmc
|
||||
|
||||
##########################################################
|
||||
# Language definitions
|
||||
##########################################################
|
||||
lang.name=C++
|
||||
lang.opt1=-O1
|
||||
lang.opt2=-O2
|
||||
lang.opt3=-O3
|
||||
lang.opt4=-O3
|
||||
lang.opt5=-O3
|
||||
lang.libs=%llvmgccdir%/lib %llvmgccdir%/lib \
|
||||
%llvmgccdir%/lib/gcc/%llvmgccarch%
|
||||
|
||||
##########################################################
|
||||
# Pre-processor definitions
|
||||
##########################################################
|
||||
|
||||
# We use g++ as our pre-processor
|
||||
preprocessor.command=g++ -E %in% -o %out% %incls% %defs%
|
||||
preprocessor.required=true
|
||||
|
||||
##########################################################
|
||||
# Translator definitions
|
||||
##########################################################
|
||||
|
||||
# To compile C++ source, just use llvm-g++'s cc1
|
||||
translator.command=%llvmcc1plus% -quiet %in% -o %out% \
|
||||
%opt% %incls% %defs% %WOpts% %fOpts% %MOpts% %args% \
|
||||
-D_GNU_SOURCE
|
||||
|
||||
# llvm-g++ does not pre-process
|
||||
translator.preprocesses=false
|
||||
|
||||
# The translator is required to run.
|
||||
translator.required=true
|
||||
|
||||
# Output of translator is assembly
|
||||
translator.output=assembly
|
||||
|
||||
##########################################################
|
||||
# Optimizer definitions
|
||||
##########################################################
|
||||
|
||||
# Use gccas to clean up the generated code
|
||||
optimizer.command=%bindir%/gccas %in% -o %out% %args%
|
||||
optimizer.required = true
|
||||
|
||||
# gccas doesn't translate
|
||||
optimizer.translates = false
|
||||
|
||||
# gccas doesn't preprocess
|
||||
optimizer.preprocesses=false
|
||||
|
||||
# gccas produces bytecode
|
||||
optimizer.output = bytecode
|
||||
|
||||
##########################################################
|
||||
# Assembler definitions
|
||||
##########################################################
|
||||
assembler.command=%bindir%/llc %in% -o %out% %target% %time% %stats%
|
@ -1,11 +0,0 @@
|
||||
# LLVM Assembly Config File For llvmc
|
||||
version="1.0"
|
||||
lang.name=LLVM Assembly
|
||||
preprocessor.command=
|
||||
preprocessor.required=false
|
||||
translator.command=%bindir%/llvm-as %in% -o %out%
|
||||
translator.preprocesses=true
|
||||
translator.required=TRUE
|
||||
optimizer.command=%bindir%/opt %in% -o %out% %opt% %args%
|
||||
optimizer.translates=no
|
||||
assembler.command=%bindir%/llc %in% -o %out%
|
@ -1,374 +0,0 @@
|
||||
//===--- llvmc.cpp - The LLVM Compiler Driver -------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This tool provides a single point of access to the LLVM compilation tools.
|
||||
// It has many options. To discover the options supported please refer to the
|
||||
// tools' manual page (docs/CommandGuide/html/llvmc.html) or run the tool with
|
||||
// the --help option.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "CompilerDriver.h"
|
||||
#include "Configuration.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
#include "llvm/System/Signals.h"
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
using namespace llvm;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//=== PHASE OPTIONS
|
||||
//===----------------------------------------------------------------------===//
|
||||
static cl::opt<CompilerDriver::Phases> FinalPhase(cl::Optional,
|
||||
cl::desc("Choose final phase of compilation:"),
|
||||
cl::init(CompilerDriver::LINKING),
|
||||
cl::values(
|
||||
clEnumValN(CompilerDriver::PREPROCESSING,"E",
|
||||
"Stop compilation after pre-processing phase"),
|
||||
clEnumValN(CompilerDriver::TRANSLATION, "t",
|
||||
"Stop compilation after translation phase"),
|
||||
clEnumValN(CompilerDriver::OPTIMIZATION,"c",
|
||||
"Stop compilation after optimization phase"),
|
||||
clEnumValN(CompilerDriver::ASSEMBLY,"S",
|
||||
"Stop compilation after assembly phase"),
|
||||
clEnumValEnd
|
||||
)
|
||||
);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//=== OPTIMIZATION OPTIONS
|
||||
//===----------------------------------------------------------------------===//
|
||||
static cl::opt<CompilerDriver::OptimizationLevels> OptLevel(cl::ZeroOrMore,
|
||||
cl::desc("Choose level of optimization to apply:"),
|
||||
cl::init(CompilerDriver::OPT_FAST_COMPILE),
|
||||
cl::values(
|
||||
clEnumValN(CompilerDriver::OPT_FAST_COMPILE,"O0",
|
||||
"An alias for the -O1 option"),
|
||||
clEnumValN(CompilerDriver::OPT_FAST_COMPILE,"O1",
|
||||
"Optimize for compilation speed, not execution speed"),
|
||||
clEnumValN(CompilerDriver::OPT_SIMPLE,"O2",
|
||||
"Perform simple translation time optimizations"),
|
||||
clEnumValN(CompilerDriver::OPT_AGGRESSIVE,"O3",
|
||||
"Perform aggressive translation time optimizations"),
|
||||
clEnumValN(CompilerDriver::OPT_LINK_TIME,"O4",
|
||||
"Perform link time optimizations"),
|
||||
clEnumValN(CompilerDriver::OPT_AGGRESSIVE_LINK_TIME,"O5",
|
||||
"Perform aggressive link time optimizations"),
|
||||
clEnumValEnd
|
||||
)
|
||||
);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//=== TOOL OPTIONS
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static cl::list<std::string> PreprocessorToolOpts("Tpre", cl::ZeroOrMore,
|
||||
cl::desc("Pass specific options to the pre-processor"),
|
||||
cl::value_desc("option"));
|
||||
|
||||
static cl::alias PreprocessorToolOptsAlias("Wp,", cl::ZeroOrMore,
|
||||
cl::desc("Alias for -Tpre"), cl::aliasopt(PreprocessorToolOpts));
|
||||
|
||||
static cl::list<std::string> TranslatorToolOpts("Ttrn", cl::ZeroOrMore,
|
||||
cl::desc("Pass specific options to the assembler"),
|
||||
cl::value_desc("option"));
|
||||
|
||||
static cl::list<std::string> AssemblerToolOpts("Tasm", cl::ZeroOrMore,
|
||||
cl::desc("Pass specific options to the assembler"),
|
||||
cl::value_desc("option"));
|
||||
|
||||
static cl::alias AssemblerToolOptsAlias("Wa,", cl::ZeroOrMore,
|
||||
cl::desc("Alias for -Tasm"), cl::aliasopt(AssemblerToolOpts));
|
||||
|
||||
static cl::list<std::string> OptimizerToolOpts("Topt", cl::ZeroOrMore,
|
||||
cl::desc("Pass specific options to the optimizer"),
|
||||
cl::value_desc("option"));
|
||||
|
||||
static cl::list<std::string> LinkerToolOpts("Tlnk", cl::ZeroOrMore,
|
||||
cl::desc("Pass specific options to the linker"),
|
||||
cl::value_desc("option"));
|
||||
|
||||
static cl::alias LinkerToolOptsAlias("Wl,", cl::ZeroOrMore,
|
||||
cl::desc("Alias for -Tlnk"), cl::aliasopt(LinkerToolOpts));
|
||||
|
||||
static cl::list<std::string> fOpts("f", cl::ZeroOrMore, cl::Prefix,
|
||||
cl::desc("Pass through -f options to compiler tools"),
|
||||
cl::value_desc("option"));
|
||||
|
||||
static cl::list<std::string> MOpts("M", cl::ZeroOrMore, cl::Prefix,
|
||||
cl::desc("Pass through -M options to compiler tools"),
|
||||
cl::value_desc("option"));
|
||||
|
||||
static cl::list<std::string> WOpts("W", cl::ZeroOrMore, cl::Prefix,
|
||||
cl::desc("Pass through -W options to compiler tools"),
|
||||
cl::value_desc("option"));
|
||||
|
||||
static cl::list<std::string> BOpt("B", cl::ZeroOrMore, cl::Prefix,
|
||||
cl::desc("Specify path to find llvmc sub-tools"),
|
||||
cl::value_desc("dir"));
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//=== INPUT OPTIONS
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static cl::list<std::string> LibPaths("L", cl::Prefix,
|
||||
cl::desc("Specify a library search path"), cl::value_desc("dir"));
|
||||
|
||||
static cl::list<std::string> Libraries("l", cl::Prefix,
|
||||
cl::desc("Specify base name of libraries to link to"), cl::value_desc("lib"));
|
||||
|
||||
static cl::list<std::string> Includes("I", cl::Prefix,
|
||||
cl::desc("Specify location to search for included source"),
|
||||
cl::value_desc("dir"));
|
||||
|
||||
static cl::list<std::string> Defines("D", cl::Prefix,
|
||||
cl::desc("Specify a pre-processor symbol to define"),
|
||||
cl::value_desc("symbol"));
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//=== OUTPUT OPTIONS
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static cl::opt<std::string> OutputFilename("o",
|
||||
cl::desc("Override output filename"), cl::value_desc("file"));
|
||||
|
||||
static cl::opt<std::string> OutputMachine("m", cl::Prefix,
|
||||
cl::desc("Specify a target machine"), cl::value_desc("machine"));
|
||||
|
||||
static cl::opt<bool> Native("native", cl::init(false),
|
||||
cl::desc("Generative native code instead of bitcode"));
|
||||
|
||||
static cl::opt<bool> DebugOutput("g", cl::init(false),
|
||||
cl::desc("Generate objects that include debug symbols"));
|
||||
|
||||
static cl::opt<bool> StripOutput("strip", cl::init(false),
|
||||
cl::desc("Strip all symbols from linked output file"));
|
||||
|
||||
static cl::opt<std::string> PrintFileName("print-fname", cl::Optional,
|
||||
cl::value_desc("file"),
|
||||
cl::desc("Print the full path for the option's value"));
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//=== INFORMATION OPTIONS
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static cl::opt<bool> DryRun("dry-run", cl::Optional, cl::init(false),
|
||||
cl::desc("Do everything but perform the compilation actions"));
|
||||
|
||||
static cl::alias DryRunAlias("y", cl::Optional,
|
||||
cl::desc("Alias for -dry-run"), cl::aliasopt(DryRun));
|
||||
|
||||
static cl::opt<bool> Verbose("verbose", cl::Optional, cl::init(false),
|
||||
cl::desc("Print out each action taken"));
|
||||
|
||||
static cl::alias VerboseAlias("v", cl::Optional,
|
||||
cl::desc("Alias for -verbose"), cl::aliasopt(Verbose));
|
||||
|
||||
static cl::opt<bool> Debug("debug", cl::Optional, cl::init(false),
|
||||
cl::Hidden, cl::desc("Print out debugging information"));
|
||||
|
||||
static cl::alias DebugAlias("d", cl::Optional,
|
||||
cl::desc("Alias for -debug"), cl::aliasopt(Debug));
|
||||
|
||||
static cl::opt<bool> TimeActions("time-actions", cl::Optional, cl::init(false),
|
||||
cl::desc("Print execution time for each action taken"));
|
||||
|
||||
static cl::opt<bool> ShowStats("stats", cl::Optional, cl::init(false),
|
||||
cl::desc("Print statistics accumulated during optimization"));
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//=== ADVANCED OPTIONS
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static cl::opt<std::string> ConfigDir("config-dir", cl::Optional,
|
||||
cl::desc("Specify configuration directory to override defaults"),
|
||||
cl::value_desc("dir"));
|
||||
|
||||
static cl::opt<bool> EmitRawCode("emit-raw-code", cl::Hidden, cl::Optional,
|
||||
cl::desc("Emit raw, unoptimized code"));
|
||||
|
||||
static cl::opt<bool> PipeCommands("pipe", cl::Optional,
|
||||
cl::desc("Invoke sub-commands by linking input/output with pipes"));
|
||||
|
||||
static cl::opt<bool> KeepTemps("keep-temps", cl::Optional,
|
||||
cl::desc("Don't delete temporary files created by llvmc"));
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//=== POSITIONAL OPTIONS
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static cl::list<std::string> Files(cl::Positional, cl::ZeroOrMore,
|
||||
cl::desc("[Sources/objects/libraries]"));
|
||||
|
||||
static cl::list<std::string> Languages("x", cl::ZeroOrMore,
|
||||
cl::desc("Specify the source language for subsequent files"),
|
||||
cl::value_desc("language"));
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//=== GetFileType - determine type of a file
|
||||
//===----------------------------------------------------------------------===//
|
||||
static const std::string GetFileType(const std::string& fname, unsigned pos) {
|
||||
static std::vector<std::string>::iterator langIt = Languages.begin();
|
||||
static std::string CurrLang = "";
|
||||
|
||||
// If a -x LANG option has been specified ..
|
||||
if (langIt != Languages.end())
|
||||
// If the -x LANG option came before the current file on command line
|
||||
if (Languages.getPosition( langIt - Languages.begin() ) < pos) {
|
||||
// use that language
|
||||
CurrLang = *langIt++;
|
||||
return CurrLang;
|
||||
}
|
||||
|
||||
// If there's a current language in effect
|
||||
if (!CurrLang.empty())
|
||||
return CurrLang; // use that language
|
||||
|
||||
// otherwise just determine lang from the filename's suffix
|
||||
return fname.substr(fname.rfind('.', fname.size()) + 1);
|
||||
}
|
||||
|
||||
static void handleTerminatingOptions(CompilerDriver* CD) {
|
||||
if (!PrintFileName.empty()) {
|
||||
sys::Path path = CD->GetPathForLinkageItem(PrintFileName, false);
|
||||
std::string p = path.toString();
|
||||
if (p.empty())
|
||||
std::cout << "Can't locate `" << PrintFileName << "'.\n";
|
||||
else
|
||||
std::cout << p << '\n';
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief The main program for llvmc
|
||||
int main(int argc, char **argv) {
|
||||
llvm_shutdown_obj X; // Call llvm_shutdown() on exit.
|
||||
// Make sure we print stack trace if we get bad signals
|
||||
sys::PrintStackTraceOnErrorSignal();
|
||||
|
||||
std::cout << "NOTE: llvmc is highly experimental and mostly useless right "
|
||||
"now.\nPlease use llvm-gcc directly instead.\n\n";
|
||||
|
||||
try {
|
||||
|
||||
// Parse the command line options
|
||||
cl::ParseCommandLineOptions(argc, argv,
|
||||
"LLVM Compiler Driver (llvmc)\n\n"
|
||||
" This program provides easy invocation of the LLVM tool set\n"
|
||||
" and other compiler tools.\n"
|
||||
);
|
||||
|
||||
// Deal with unimplemented options.
|
||||
if (PipeCommands)
|
||||
throw std::string("Not implemented yet: -pipe");
|
||||
|
||||
if (OutputFilename.empty())
|
||||
if (OptLevel == CompilerDriver::LINKING)
|
||||
OutputFilename = "a.out";
|
||||
|
||||
// Construct the ConfigDataProvider object
|
||||
LLVMC_ConfigDataProvider Provider;
|
||||
Provider.setConfigDir(sys::Path(ConfigDir));
|
||||
|
||||
// Construct the CompilerDriver object
|
||||
CompilerDriver* CD = CompilerDriver::Get(Provider);
|
||||
|
||||
// If the LLVM_LIB_SEARCH_PATH environment variable is
|
||||
// set, append it to the list of places to search for libraries
|
||||
char *srchPath = getenv("LLVM_LIB_SEARCH_PATH");
|
||||
if (srchPath != NULL && strlen(srchPath) != 0)
|
||||
LibPaths.push_back(std::string(srchPath));
|
||||
|
||||
// Set the driver flags based on command line options
|
||||
unsigned flags = 0;
|
||||
if (Verbose) flags |= CompilerDriver::VERBOSE_FLAG;
|
||||
if (Debug) flags |= CompilerDriver::DEBUG_FLAG;
|
||||
if (DryRun) flags |= CompilerDriver::DRY_RUN_FLAG;
|
||||
if (Native) flags |= CompilerDriver::EMIT_NATIVE_FLAG;
|
||||
if (EmitRawCode) flags |= CompilerDriver::EMIT_RAW_FLAG;
|
||||
if (KeepTemps) flags |= CompilerDriver::KEEP_TEMPS_FLAG;
|
||||
if (ShowStats) flags |= CompilerDriver::SHOW_STATS_FLAG;
|
||||
if (TimeActions) flags |= CompilerDriver::TIME_ACTIONS_FLAG;
|
||||
if (StripOutput) flags |= CompilerDriver::STRIP_OUTPUT_FLAG;
|
||||
CD->setDriverFlags(flags);
|
||||
|
||||
// Specify required parameters
|
||||
CD->setFinalPhase(FinalPhase);
|
||||
CD->setOptimization(OptLevel);
|
||||
CD->setOutputMachine(OutputMachine);
|
||||
CD->setIncludePaths(Includes);
|
||||
CD->setSymbolDefines(Defines);
|
||||
CD->setLibraryPaths(LibPaths);
|
||||
CD->setfPassThrough(fOpts);
|
||||
CD->setMPassThrough(MOpts);
|
||||
CD->setWPassThrough(WOpts);
|
||||
|
||||
// Provide additional tool arguments
|
||||
if (!PreprocessorToolOpts.empty())
|
||||
CD->setPhaseArgs(CompilerDriver::PREPROCESSING, PreprocessorToolOpts);
|
||||
if (!TranslatorToolOpts.empty())
|
||||
CD->setPhaseArgs(CompilerDriver::TRANSLATION, TranslatorToolOpts);
|
||||
if (!OptimizerToolOpts.empty())
|
||||
CD->setPhaseArgs(CompilerDriver::OPTIMIZATION, OptimizerToolOpts);
|
||||
if (!AssemblerToolOpts.empty())
|
||||
CD->setPhaseArgs(CompilerDriver::ASSEMBLY,AssemblerToolOpts);
|
||||
if (!LinkerToolOpts.empty())
|
||||
CD->setPhaseArgs(CompilerDriver::LINKING, LinkerToolOpts);
|
||||
|
||||
// Check for options that cause us to terminate before any significant work
|
||||
// is done.
|
||||
handleTerminatingOptions(CD);
|
||||
|
||||
// Prepare the list of files to be compiled by the CompilerDriver.
|
||||
CompilerDriver::InputList InpList;
|
||||
std::vector<std::string>::iterator fileIt = Files.begin();
|
||||
std::vector<std::string>::iterator libIt = Libraries.begin();
|
||||
unsigned libPos = 0, filePos = 0;
|
||||
while ( 1 ) {
|
||||
if (libIt != Libraries.end())
|
||||
libPos = Libraries.getPosition( libIt - Libraries.begin() );
|
||||
else
|
||||
libPos = 0;
|
||||
if (fileIt != Files.end())
|
||||
filePos = Files.getPosition(fileIt - Files.begin());
|
||||
else
|
||||
filePos = 0;
|
||||
|
||||
if (filePos != 0 && (libPos == 0 || filePos < libPos)) {
|
||||
// Add a source file
|
||||
InpList.push_back(std::make_pair(*fileIt,
|
||||
GetFileType(*fileIt, filePos)));
|
||||
++fileIt;
|
||||
} else if ( libPos != 0 && (filePos == 0 || libPos < filePos) ) {
|
||||
// Add a library
|
||||
InpList.push_back(std::make_pair(*libIt++, ""));
|
||||
}
|
||||
else
|
||||
break; // we're done with the list
|
||||
}
|
||||
|
||||
// Tell the driver to do its thing
|
||||
std::string ErrMsg;
|
||||
int result = CD->execute(InpList, sys::Path(OutputFilename), ErrMsg);
|
||||
if (result != 0) {
|
||||
std::cerr << argv[0] << ": " << ErrMsg << '\n';
|
||||
return result;
|
||||
}
|
||||
|
||||
// All is good, return success
|
||||
return 0;
|
||||
} catch (const std::string& msg) {
|
||||
std::cerr << argv[0] << ": " << msg << '\n';
|
||||
} catch (...) {
|
||||
std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
|
||||
}
|
||||
return 1;
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
# Stacker Configuration File For llvmc
|
||||
|
||||
##########################################################
|
||||
# Language definitions
|
||||
##########################################################
|
||||
lang.name=Stacker
|
||||
lang.opt1=-O1
|
||||
lang.opt2=-O2
|
||||
lang.opt3=-O3
|
||||
lang.opt4=-O4
|
||||
lang.opt5=-O5
|
||||
|
||||
##########################################################
|
||||
# Pre-processor definitions
|
||||
##########################################################
|
||||
|
||||
# Stacker doesn't have a preprocessor but the following
|
||||
# allows the -E option to be supported
|
||||
preprocessor.command=cp %in% %out%
|
||||
preprocessor.required=false
|
||||
|
||||
##########################################################
|
||||
# Translator definitions
|
||||
##########################################################
|
||||
|
||||
# To compile stacker source, we just run the stacker
|
||||
# compiler with a default stack size of 2048 entries.
|
||||
translator.command=stkrc -s 2048 %in% -f -o %out% %opt% \
|
||||
%time% %stats% %args%
|
||||
|
||||
# stkrc doesn't preprocess but we set this to true so
|
||||
# that we don't run the cp command by default.
|
||||
translator.preprocesses=true
|
||||
|
||||
# The translator is required to run.
|
||||
translator.required=false
|
||||
|
||||
# stkrc doesn't handle the -On options
|
||||
translator.output=bytecode
|
||||
|
||||
##########################################################
|
||||
# Optimizer definitions
|
||||
##########################################################
|
||||
|
||||
# For optimization, we use the LLVM "opt" program
|
||||
optimizer.command=stkrc -s 2048 %in% -f -o %out% %opt% \
|
||||
%time% %stats% %args%
|
||||
|
||||
optimizer.required = yes
|
||||
|
||||
# opt doesn't translate
|
||||
optimizer.translates = yes
|
||||
|
||||
# opt doesn't preprocess
|
||||
optimizer.preprocesses=yes
|
||||
|
||||
# opt produces bytecode
|
||||
optimizer.output = bc
|
||||
|
||||
##########################################################
|
||||
# Assembler definitions
|
||||
##########################################################
|
||||
assembler.command=llc %in% -o %out% %target% %time% %stats%
|
Loading…
Reference in New Issue
Block a user