diff --git a/include/llvm/ADT/IntrusiveRefCntPtr.h b/include/llvm/ADT/IntrusiveRefCntPtr.h index 8804f2b20f7..4709d45b2a5 100644 --- a/include/llvm/ADT/IntrusiveRefCntPtr.h +++ b/include/llvm/ADT/IntrusiveRefCntPtr.h @@ -222,4 +222,4 @@ namespace llvm { } // end namespace llvm -#endif // LLVM_ADT_INTRUSIVE_REF_CNT_PTR \ No newline at end of file +#endif // LLVM_ADT_INTRUSIVE_REF_CNT_PTR diff --git a/tools/Makefile b/tools/Makefile index dc9ac440649..d1491af5bfc 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -16,7 +16,7 @@ PARALLEL_DIRS := llvm-config \ llc llvm-ranlib llvm-ar llvm-nm \ llvm-ld llvmc llvm-prof llvm-link \ lli gccas gccld llvm-extract llvm-db llvm2cpp \ - bugpoint llvm-bcanalyzer llvm-stub + bugpoint llvm-bcanalyzer llvm-stub llvmc2 include $(LEVEL)/Makefile.config diff --git a/tools/llvmc2/Common.td b/tools/llvmc2/Common.td new file mode 100644 index 00000000000..15b9264d88e --- /dev/null +++ b/tools/llvmc2/Common.td @@ -0,0 +1,63 @@ +//===- Tools.td - Common definitions for LLVMCC -----------*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains common definitions used in llvmcc tool description files. +// +//===----------------------------------------------------------------------===// + +class Tool l> { + list properties = l; +} + +// Possible Tool properties + +def in_language; +def out_language; +def output_suffix; +def cmd_line; +def join; +def sink; + +// Possible option types + +def switch_option; +def parameter_option; +def parameter_list_option; +def prefix_option; +def prefix_list_option; + +// Possible option properties + +def append_cmd; +def forward; +def stop_compilation; +def unpack_values; +def help; +def required; + +// Map from suffixes to language names + +class LangToSuffixes lst> { + string lang = str; + list suffixes = lst; +} + +class LanguageMap lst> { + list map = lst; +} + +// Toolchain classes + +class ToolChain lst> { + list tools = lst; +} + +class ToolChains lst> { + list chains = lst; +} diff --git a/tools/llvmc2/Core.cpp b/tools/llvmc2/Core.cpp new file mode 100644 index 00000000000..d08ee7c00fa --- /dev/null +++ b/tools/llvmc2/Core.cpp @@ -0,0 +1,115 @@ +//===--- Core.cpp - The LLVM Compiler Driver --------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open +// Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Core driver abstractions. +// +//===----------------------------------------------------------------------===// + +#include "Core.h" +#include "Utility.h" + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/Support/CommandLine.h" + +#include +#include +#include + +using namespace llvm; +using namespace llvmcc; + +extern cl::list InputFilenames; +extern cl::opt OutputFilename; +extern cl::opt VerboseMode; + +namespace { + void print_string (const std::string& str) { + std::cerr << str << ' '; + } +} + +int llvmcc::Action::Execute() { + if (VerboseMode) { + std::cerr << Command_ << " "; + std::for_each(Args_.begin(), Args_.end(), print_string); + std::cerr << '\n'; + } + return ExecuteProgram(Command_, Args_); +} + +int llvmcc::CompilationGraph::Build (const sys::Path& tempDir) const { + sys::Path In(InputFilenames.at(0)), Out; + + // Find out which language corresponds to the suffix of the first input file + LanguageMap::const_iterator Lang = ExtsToLangs.find(In.getSuffix()); + if (Lang == ExtsToLangs.end()) + throw std::runtime_error("Unknown suffix!"); + + // Find the toolchain corresponding to this language + ToolChainMap::const_iterator ToolsIt = ToolChains.find(Lang->second); + if (ToolsIt == ToolChains.end()) + throw std::runtime_error("Unknown language!"); + ToolChain Tools = ToolsIt->second; + + PathVector JoinList; + + for (cl::list::const_iterator B = InputFilenames.begin(), + E = InputFilenames.end(); B != E; ++B) { + In = sys::Path(*B); + + // Pass input file through the toolchain + for (ToolChain::const_iterator B = Tools.begin(), E = Tools.end(); + B != E; ++B) { + + const Tool* CurTool = B->getPtr(); + + // Is this the last step in the chain? + if (llvm::next(B) == E || CurTool->IsLast()) { + JoinList.push_back(In); + break; + } + else { + Out = tempDir; + Out.appendComponent(In.getBasename()); + Out.appendSuffix(CurTool->OutputSuffix()); + Out.makeUnique(true, NULL); + Out.eraseFromDisk(); + } + + if (CurTool->GenerateAction(In, Out).Execute() != 0) + throw std::runtime_error("Tool returned error code!"); + + In = Out; Out.clear(); + } + } + + // Pass .o files to linker + const Tool* JoinNode = (--Tools.end())->getPtr(); + + // If the final output name is empty, set it to "a.out" + if (!OutputFilename.empty()) { + Out = sys::Path(OutputFilename); + } + else { + Out = sys::Path("a"); + Out.appendSuffix(JoinNode->OutputSuffix()); + } + + if (JoinNode->GenerateAction(JoinList, Out).Execute() != 0) + throw std::runtime_error("Tool returned error code!"); + + return 0; +} + +void llvmcc::Tool::UnpackValues (const std::string& from, + std::vector& to) const { + SplitString(from, to, ","); +} + diff --git a/tools/llvmc2/Core.h b/tools/llvmc2/Core.h new file mode 100644 index 00000000000..f82e0fa98ea --- /dev/null +++ b/tools/llvmc2/Core.h @@ -0,0 +1,83 @@ +//===--- Core.h - The LLVM Compiler Driver ----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open +// Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Core driver abstractions. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_LLVMCC_CORE_H +#define LLVM_TOOLS_LLVMCC_CORE_H + +#include "Utility.h" + +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/System/Path.h" + +#include +#include +#include + +// Core functionality + +namespace llvmcc { + + typedef std::vector PathVector; + typedef llvm::StringMap LanguageMap; + + class Action { + std::string Command_; + std::vector Args_; + public: + Action (std::string const& C, + std::vector const& A) + : Command_(C), Args_(A) + {} + + int Execute(); + }; + + class Tool : public llvm::RefCountedBaseVPTR { + public: + virtual Action GenerateAction (PathVector const& inFiles, + llvm::sys::Path const& outFile) const = 0; + + virtual Action GenerateAction (llvm::sys::Path const& inFile, + llvm::sys::Path const& outFile) const = 0; + + virtual std::string Name() const = 0; + virtual std::string InputLanguage() const = 0; + virtual std::string OutputLanguage() const = 0; + virtual std::string OutputSuffix() const = 0; + + virtual bool IsLast() const = 0; + virtual bool IsJoin() const = 0; + + // Helper function that is called by the auto-generated code + // Splits strings of the form ",-foo,-bar,-baz" + // TOFIX: find a better name + void UnpackValues (std::string const& from, + std::vector& to) const; + + virtual ~Tool() + {} + }; + + typedef std::vector > ToolChain; + typedef llvm::StringMap ToolChainMap; + + struct CompilationGraph { + ToolChainMap ToolChains; + LanguageMap ExtsToLangs; + + int Build(llvm::sys::Path const& tempDir) const; + }; +} + +#endif // LLVM_TOOLS_LLVMCC_CORE_H diff --git a/tools/llvmc2/Example.td b/tools/llvmc2/Example.td new file mode 100644 index 00000000000..68212c30102 --- /dev/null +++ b/tools/llvmc2/Example.td @@ -0,0 +1,24 @@ +//===- Example.td - LLVMCC toolchain descriptions ---------*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains toolchain descriptions used by llvmcc. +// +//===----------------------------------------------------------------------===// + +include "Common.td" +include "Tools.td" + +// Toolchains + +def ToolChains : ToolChains<[ + ToolChain<[llvm_gcc_c, llc, llvm_gcc_assembler, llvm_gcc_linker]>, + ToolChain<[llvm_gcc_cpp, llc, llvm_gcc_assembler, llvm_gcc_linker]>, + ToolChain<[llvm_as, llc, llvm_gcc_assembler, llvm_gcc_linker]>, + ToolChain<[llvm_gcc_assembler, llvm_gcc_linker]> + ]>; diff --git a/tools/llvmc2/ExampleWithOpt.td b/tools/llvmc2/ExampleWithOpt.td new file mode 100644 index 00000000000..9128d311c52 --- /dev/null +++ b/tools/llvmc2/ExampleWithOpt.td @@ -0,0 +1,24 @@ +//===- ExampleWithOpt.td - LLVMCC toolchain descriptions --*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains toolchain descriptions used by llvmcc. +// +//===----------------------------------------------------------------------===// + +include "Common.td" +include "Tools.td" + +// Toolchains + +def ToolChains : ToolChains<[ + ToolChain<[llvm_gcc_c, opt, llc, llvm_gcc_assembler, llvm_gcc_linker]>, + ToolChain<[llvm_gcc_cpp, opt, llc, llvm_gcc_assembler, llvm_gcc_linker]>, + ToolChain<[llvm_as, opt, llc, llvm_gcc_assembler, llvm_gcc_linker]>, + ToolChain<[llvm_gcc_assembler, llvm_gcc_linker]> + ]>; diff --git a/tools/llvmc2/Makefile b/tools/llvmc2/Makefile new file mode 100644 index 00000000000..d0c1588e117 --- /dev/null +++ b/tools/llvmc2/Makefile @@ -0,0 +1,32 @@ +##===- tools/llvmcc/Makefile -------------------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open +# Source License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## +LEVEL = ../.. +TOOLNAME = llvmc2 +BUILT_SOURCES = Tools.inc +LINK_COMPONENTS = support system +REQUIRES_EH := 1 + +include $(LEVEL)/Makefile.common + +TOOLS_TARGET=default +ifeq ($(TOOLS_TARGET), default) + TOOLS_SOURCE=Example.td +else + TOOLS_SOURCE=ExampleWithOpt.td +endif + +# TOFIX: integrate this part into Makefile.rules? +# The degree of horrorshowness in that file is too much for me atm. +$(ObjDir)/Tools.inc.tmp: $(TOOLS_SOURCE) $(ObjDir)/.dir + $(Echo) "Building LLVMCC configuration library with tblgen" + $(Verb) $(TableGen) -gen-llvmcc -o $@ $< + +Tools.inc : $(ObjDir)/Tools.inc.tmp + $(Verb) $(CMP) -s $@ $< || $(CP) $< $@ + diff --git a/tools/llvmc2/Tools.cpp b/tools/llvmc2/Tools.cpp new file mode 100644 index 00000000000..7a9921c54b7 --- /dev/null +++ b/tools/llvmc2/Tools.cpp @@ -0,0 +1,28 @@ +//===--- Tools.cpp - The LLVM Compiler Driver -------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open +// Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Auto-generated tool descriptions. +// +//===----------------------------------------------------------------------===// + +#include "Tools.h" +#include "Core.h" + +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/Support/CommandLine.h" + +#include +#include +#include + +using namespace llvm; +using namespace llvmcc; + +// Include the auto-generated file +#include "Tools.inc" diff --git a/tools/llvmc2/Tools.h b/tools/llvmc2/Tools.h new file mode 100644 index 00000000000..ba8f06dbd6d --- /dev/null +++ b/tools/llvmc2/Tools.h @@ -0,0 +1,26 @@ +//===--- Tools.h - The LLVM Compiler Driver ---------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open +// Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Auto-generated tool descriptions. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_LLVMCC_TOOLS_H +#define LLVM_TOOLS_LLVMCC_TOOLS_H + +#include "Core.h" + +namespace llvmcc { + + void PopulateLanguageMap(LanguageMap& language_map); + void PopulateCompilationGraph(CompilationGraph& tools); + +} + +#endif //LLVM_TOOLS_LLVMCC_TOOLS_H diff --git a/tools/llvmc2/Tools.td b/tools/llvmc2/Tools.td new file mode 100644 index 00000000000..f69c290dff5 --- /dev/null +++ b/tools/llvmc2/Tools.td @@ -0,0 +1,87 @@ +//===- Tools.td - Tools description for the LLVMCC --------*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains descriptions of the various build tools run by llvmcc. +// +//===----------------------------------------------------------------------===// + +// Open issue: should we use DAG lists in Tool specifications +// or change to something like +// def LLVMGccC : < Tool< +// [ InLanguage<"c">, +// PrefixListOption<"Wl", [UnpackValues, PropertyName, ...]> +// ...] ? +// DAG lists look more aesthetically pleasing to me. + +def llvm_gcc_c : Tool< +[(in_language "c"), + (out_language "llvm-assembler"), + (output_suffix "bc"), + (cmd_line "llvm-gcc -c $INFILE -o $OUTFILE -emit-llvm"), + (sink) +]>; + +def llvm_gcc_cpp : Tool< +[(in_language "c++"), + (out_language "llvm-assembler"), + (output_suffix "bc"), + (cmd_line "llvm-g++ -c $INFILE -o $OUTFILE -emit-llvm"), + (sink) +]>; + +def opt : Tool< +[(in_language "llvm-bitcode"), + (out_language "llvm-bitcode"), + (output_suffix "bc"), + (cmd_line "opt $INFILE -o $OUTFILE") +]>; + +def llvm_as : Tool< +[(in_language "llvm-assembler"), + (out_language "llvm-bitcode"), + (output_suffix "bc"), + (cmd_line "llvm-as $INFILE -o $OUTFILE") +]>; + +def llc : Tool< +[(in_language "llvm-bitcode"), + (out_language "assembler"), + (output_suffix "s"), + (cmd_line "llc $INFILE -o $OUTFILE") +]>; + +def llvm_gcc_assembler : Tool< +[(in_language "assembler"), + (out_language "object-code"), + (output_suffix "o"), + (cmd_line "llvm-gcc -c $INFILE -o $OUTFILE"), + (prefix_list_option "Wa", (unpack_values), (help "pass options to assembler")) +]>; + +def llvm_gcc_linker : Tool< +[(in_language "object-code"), + (out_language "executable"), + (output_suffix "out"), + (cmd_line "llvm-gcc $INFILE -o $OUTFILE"), + (join), + (prefix_list_option "L", (forward), (help "add a directory to link path")), + (prefix_list_option "l", (forward), (help "search a library when linking")), + (prefix_list_option "Wl", (unpack_values), (help "pass options to linker")) +]>; + +// Language map + +def LanguageMap : LanguageMap< + [LangToSuffixes<"c++", ["cc", "cp", "cxx", "cpp", "CPP", "c++", "C"]>, + LangToSuffixes<"c", ["c"]>, + LangToSuffixes<"assembler", ["s"]>, + LangToSuffixes<"llvm-assembler", ["ll"]>, + LangToSuffixes<"llvm-bitcode", ["bc"]>, + LangToSuffixes<"object-code", ["o"]>, + LangToSuffixes<"executable", ["out"]>]>; diff --git a/tools/llvmc2/Utility.cpp b/tools/llvmc2/Utility.cpp new file mode 100644 index 00000000000..c53578ad44b --- /dev/null +++ b/tools/llvmc2/Utility.cpp @@ -0,0 +1,39 @@ +//===--- Utility.cpp - The LLVM Compiler Driver -----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open +// Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Various helper and utility functions - implementation. +// +//===----------------------------------------------------------------------===// + +#include "Utility.h" + +#include "llvm/System/Program.h" + +#include + +using namespace llvm; + +int llvmcc::ExecuteProgram(const std::string& name, + const std::vector& args) { + sys::Path prog = sys::Program::FindProgramByName(name); + + if (prog.isEmpty()) + throw std::runtime_error("Can't find program '" + name + "'"); + if (!prog.canExecute()) + throw std::runtime_error("Program '" + name + "' is not executable."); + + // Invoke the program + std::vector argv((args.size()+2)); + argv[0] = name.c_str(); + for (unsigned i = 1; i <= args.size(); ++i) + argv[i] = args[i-1].c_str(); + argv[args.size()+1] = 0; // null terminate list. + + return sys::Program::ExecuteAndWait(prog, &argv[0]); +} diff --git a/tools/llvmc2/Utility.h b/tools/llvmc2/Utility.h new file mode 100644 index 00000000000..3c985a49fc9 --- /dev/null +++ b/tools/llvmc2/Utility.h @@ -0,0 +1,27 @@ +//===--- Utility.h - The LLVM Compiler Driver -------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open +// Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Various helper and utility functions. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_LLVMCC_UTILITY_H +#define LLVM_TOOLS_LLVMCC_UTILITY_H + +#include +#include + +namespace llvmcc { + + int ExecuteProgram (const std::string& name, + const std::vector& arguments); + +} + +#endif // LLVM_TOOLS_LLVMCC_UTILITY_H diff --git a/tools/llvmc2/doc/LLVMC-Enhancements.rst b/tools/llvmc2/doc/LLVMC-Enhancements.rst new file mode 100644 index 00000000000..a831ea06f8b --- /dev/null +++ b/tools/llvmc2/doc/LLVMC-Enhancements.rst @@ -0,0 +1,270 @@ +Introduction +============ + +A complete rewrite of the LLVMC compiler driver is proposed, aimed at +making it more configurable and useful. + +Motivation +========== + +As it stands, current version of LLVMC does not meet its stated goals +of configurability and extensibility and is therefore not used +much. The need for enhancements in LLVMC is also reflected in [1]_. The +proposed rewrite will fix the aforementioned deficiences and provide +an extensible, future-proof solution. + +Design +====== + +A compiler driver's job is essentially to find a way how to transform +a set of input files into a set of targets, depending on the +user-provided options. Since several ways of transformation can exist +potentially, it's natural to use a directed graph to represent all of +them. In this graph, nodes are tools (for example, ``gcc -S`` is a tool +that generates assembly from C language files) and edges between them +mean that the output of one tool can be given as input to another (as +in ``gcc -S -o - file.c | as``). We'll call this graph the compilation +graph. + +The proposed design revolves around the compilation graph and the +following core abstractions: + +- Target - An (intermediate) compilation target. + +- Action - A shell command template that represents basic compilation + transformation(example: ``gcc -S $INPUT_FILE -o $OUTPUT_FILE``). + +- Tool - Encapsulates information about a concrete tool used in the + compilation process, produces Actions. Operation depends on + command-line options provided by the user. + +- GraphBuilder - Constructs the compilation graph, operation depends + on command-line options. + +- GraphTraverser - Traverses the compilation graph and constructs a + sequence of Actions needed to build the target file, operation + depends on command-line options. + +A high-level view of the compilation process: + + 1. Configuration libraries (see below) are loaded in and the + compilation graph is constructed from the tool descriptions. + + 2. Information about possible options is gathered from (the nodes of) + the compilation graph. + + 3. Options are parsed based on data gathered in step 2. + + 4. A sequence of Actions needed to build the target is constructed + using the compilation graph and provided options. + + 5. The resulting action sequence is executed. + +Extensibility +============== + +To make this design extensible, TableGen [2]_ will be used for +automatic generation of the Tool classes. Users wanting to customize +LLVMC will need to write a configuration library consisting of a set +of TableGen descriptions of compilation tools plus a number of hooks +that influence compilation graph construction and traversal. LLVMC +will have the ability to load user configuration libraries at runtime; +in fact, its own basic functionality will be implemented as a +configuration library. + +TableGen specification example +------------------------------ + +This small example specifies a Tool that converts C source to object +files. Note that it is only a mock-up of inteded functionality, not a +final specification:: + + def GCC : Tool< + GCCProperties, // Properties of this tool + GCCOptions // Options description for this tool + >; + + def GCCProperties : ToolProperties<[ + ToolName<"GCC">, + InputLanguageName<"C">, + OutputLanguageName<"Object-Code"> + InputFileExtension<"c">, + OutputFileExtension<"o">, + CommandFormat<"gcc -c $OPTIONS $FILES"> + ]>; + + def GCCOptions : ToolOptions<[ + Option< + "-Wall", // Option name + [None], // Allowed values + [AddOption<"-Wall">]>, // Action + + Option< + "-Wextra", // Option name + [None], // Allowed values + [AddOption<"-Wextra">]>, // Action + + Option< + "-W", // Option name + [None], // Allowed values + [AddOption<"-W">]>, // Action + + Option< + "-D", // Option name + [AnyString], // Allowed values + + [AddOptionWithArgument<"-D",GetOptionArgument<"-D">>] + // Action: + // If the driver was given option "-D", add + // option "-D" with the same argument to the invocation string of + // this tool. + > + + ]>; + +Example of generated code +------------------------- + +The specification above compiles to the following code (again, it's a +mock-up):: + + class GCC : public Tool { + + public: + + GCC() { //... } + + // Properties + + static const char* ToolName = "GCC"; + static const char* InputLanguageName = "C"; + static const char* OutputLanguageName = "Object-Code"; + static const char* InputFileExtension = "c"; + static const char* OutputFileExtension = "o"; + static const char* CommandFormat = "gcc -c $OPTIONS $FILES"; + + // Options + + OptionsDescription SupportedOptions() { + OptionsDescription supportedOptions; + + supportedOptions.Add(Option("-Wall")); + supportedOptions.Add(Option("-Wextra")); + supportedOptions.Add(Option("-W")); + supportedOptions.Add(Option("-D", AllowedArgs::ANY_STRING)); + + return supportedOptions; + } + + Action GenerateAction(Options providedOptions) { + Action generatedAction(CommandFormat); Option curOpt; + + curOpt = providedOptions.Get("-D"); + if (curOpt) { + assert(curOpt.HasArgument()); + generatedAction.AddOption(Option("-D", curOpt.GetArgument())); + } + + curOpt = providedOptions.Get("-Wall"); + if (curOpt) + generatedAction.AddOption(Option("-Wall")); + + curOpt = providedOptions.Get("-Wextra"); + if (curOpt) + generatedAction.AddOption(Option("-Wall")); + + curOpt = providedOptions.Get("-W"); + if (curOpt) + generatedAction.AddOption(Option("-Wall")); } + + return generatedAction; + } + + }; + + // defined somewhere... + + class Action { public: void AddOption(const Option& opt) {...} + int Run(const Filenames& fnms) {...} + + } + +Option handling +=============== + +Since one of the main tasks of the compiler driver is to correctly +handle user-provided options, it is important to define this process +in exact way. The intent of the proposed scheme is to function as a +drop-in replacement for GCC. + +Option syntax +------------- + +Option syntax is specified by the following formal grammar:: + + ::=